summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/extensions/browser
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/extensions/browser')
-rw-r--r--chromium/extensions/browser/DEPS3
-rw-r--r--chromium/extensions/browser/extension_error.cc172
-rw-r--r--chromium/extensions/browser/extension_error.h121
-rw-r--r--chromium/extensions/browser/extension_prefs_scope.h28
-rw-r--r--chromium/extensions/browser/file_reader.cc32
-rw-r--r--chromium/extensions/browser/file_reader.h46
-rw-r--r--chromium/extensions/browser/file_reader_unittest.cc105
-rw-r--r--chromium/extensions/browser/pref_names.cc37
-rw-r--r--chromium/extensions/browser/pref_names.h42
-rw-r--r--chromium/extensions/browser/view_type_utils.cc44
-rw-r--r--chromium/extensions/browser/view_type_utils.h24
11 files changed, 654 insertions, 0 deletions
diff --git a/chromium/extensions/browser/DEPS b/chromium/extensions/browser/DEPS
new file mode 100644
index 00000000000..1c35d9ca694
--- /dev/null
+++ b/chromium/extensions/browser/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+content/public/browser",
+]
diff --git a/chromium/extensions/browser/extension_error.cc b/chromium/extensions/browser/extension_error.cc
new file mode 100644
index 00000000000..8b6196c4200
--- /dev/null
+++ b/chromium/extensions/browser/extension_error.cc
@@ -0,0 +1,172 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/extension_error.h"
+
+#include "base/json/json_reader.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "extensions/common/constants.h"
+#include "url/gurl.h"
+
+using base::string16;
+
+namespace extensions {
+
+namespace {
+
+const char kLineNumberKey[] = "lineNumber";
+const char kColumnNumberKey[] = "columnNumber";
+const char kURLKey[] = "url";
+const char kFunctionNameKey[] = "functionName";
+const char kExecutionContextURLKey[] = "executionContextURL";
+const char kStackTraceKey[] = "stackTrace";
+
+// Try to retrieve an extension ID from a |url|. On success, returns true and
+// populates |extension_id| with the ID. On failure, returns false and leaves
+// extension_id untouched.
+bool GetExtensionIDFromGURL(const GURL& url, std::string* extension_id) {
+ if (url.SchemeIs(kExtensionScheme)) {
+ *extension_id = url.host();
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+ExtensionError::ExtensionError(Type type,
+ const std::string& extension_id,
+ bool from_incognito,
+ const string16& source,
+ const string16& message)
+ : type_(type),
+ extension_id_(extension_id),
+ from_incognito_(from_incognito),
+ source_(source),
+ message_(message) {
+}
+
+ExtensionError::~ExtensionError() {
+}
+
+std::string ExtensionError::PrintForTest() const {
+ return std::string("Extension Error:") +
+ "\n OTR: " + std::string(from_incognito_ ? "true" : "false") +
+ "\n Source: " + base::UTF16ToUTF8(source_) +
+ "\n Message: " + base::UTF16ToUTF8(message_) +
+ "\n ID: " + extension_id_;
+}
+
+ManifestParsingError::ManifestParsingError(const std::string& extension_id,
+ const string16& message)
+ : ExtensionError(ExtensionError::MANIFEST_PARSING_ERROR,
+ extension_id,
+ false, // extensions can't be installed while incognito.
+ base::FilePath(kManifestFilename).AsUTF16Unsafe(),
+ message) {
+}
+
+ManifestParsingError::~ManifestParsingError() {
+}
+
+std::string ManifestParsingError::PrintForTest() const {
+ return ExtensionError::PrintForTest() +
+ "\n Type: ManifestParsingError";
+}
+
+JavascriptRuntimeError::StackFrame::StackFrame() : line_number(-1),
+ column_number(-1) {
+}
+
+JavascriptRuntimeError::StackFrame::StackFrame(size_t frame_line,
+ size_t frame_column,
+ const string16& frame_url,
+ const string16& frame_function)
+ : line_number(frame_line),
+ column_number(frame_column),
+ url(frame_url),
+ function(frame_function) {
+}
+
+JavascriptRuntimeError::StackFrame::~StackFrame() {
+}
+
+JavascriptRuntimeError::JavascriptRuntimeError(bool from_incognito,
+ const string16& source,
+ const string16& message,
+ logging::LogSeverity level,
+ const string16& details)
+ : ExtensionError(ExtensionError::JAVASCRIPT_RUNTIME_ERROR,
+ std::string(), // We don't know the id yet.
+ from_incognito,
+ source,
+ message),
+ level_(level) {
+ ParseDetails(details);
+ DetermineExtensionID();
+}
+
+JavascriptRuntimeError::~JavascriptRuntimeError() {
+}
+
+std::string JavascriptRuntimeError::PrintForTest() const {
+ std::string result = ExtensionError::PrintForTest() +
+ "\n Type: JavascriptRuntimeError"
+ "\n Context: " + base::UTF16ToUTF8(execution_context_url_) +
+ "\n Stack Trace: ";
+ for (StackTrace::const_iterator iter = stack_trace_.begin();
+ iter != stack_trace_.end(); ++iter) {
+ result += "\n {"
+ "\n Line: " + base::IntToString(iter->line_number) +
+ "\n Column: " + base::IntToString(iter->column_number) +
+ "\n URL: " + base::UTF16ToUTF8(iter->url) +
+ "\n Function: " + base::UTF16ToUTF8(iter->function) +
+ "\n }";
+ }
+ return result;
+}
+
+void JavascriptRuntimeError::ParseDetails(const string16& details) {
+ scoped_ptr<base::Value> value(
+ base::JSONReader::Read(base::UTF16ToUTF8(details)));
+ const base::DictionaryValue* details_value;
+ const base::ListValue* trace_value = NULL;
+
+ // The |details| value should contain an execution context url and a stack
+ // trace.
+ if (!value.get() ||
+ !value->GetAsDictionary(&details_value) ||
+ !details_value->GetString(kExecutionContextURLKey,
+ &execution_context_url_) ||
+ !details_value->GetList(kStackTraceKey, &trace_value)) {
+ NOTREACHED();
+ return;
+ }
+
+ int line = 0;
+ int column = 0;
+ string16 url;
+
+ for (size_t i = 0; i < trace_value->GetSize(); ++i) {
+ const base::DictionaryValue* frame_value = NULL;
+ CHECK(trace_value->GetDictionary(i, &frame_value));
+
+ frame_value->GetInteger(kLineNumberKey, &line);
+ frame_value->GetInteger(kColumnNumberKey, &column);
+ frame_value->GetString(kURLKey, &url);
+
+ string16 function;
+ frame_value->GetString(kFunctionNameKey, &function); // This can be empty.
+ stack_trace_.push_back(StackFrame(line, column, url, function));
+ }
+}
+
+void JavascriptRuntimeError::DetermineExtensionID() {
+ if (!GetExtensionIDFromGURL(GURL(source_), &extension_id_))
+ GetExtensionIDFromGURL(GURL(execution_context_url_), &extension_id_);
+}
+
+} // namespace extensions
diff --git a/chromium/extensions/browser/extension_error.h b/chromium/extensions/browser/extension_error.h
new file mode 100644
index 00000000000..1cd4a7b69bf
--- /dev/null
+++ b/chromium/extensions/browser/extension_error.h
@@ -0,0 +1,121 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
+#define EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+
+namespace extensions {
+
+class ExtensionError {
+ public:
+ enum Type {
+ MANIFEST_PARSING_ERROR,
+ JAVASCRIPT_RUNTIME_ERROR
+ };
+
+ virtual ~ExtensionError();
+
+ virtual std::string PrintForTest() const;
+
+ Type type() const { return type_; }
+ const base::string16& source() const { return source_; }
+ const base::string16& message() const { return message_; }
+ const std::string& extension_id() const { return extension_id_; }
+ bool from_incognito() const { return from_incognito_; }
+
+ protected:
+ ExtensionError(Type type,
+ const std::string& extension_id,
+ bool from_incognito,
+ const base::string16& source,
+ const base::string16& message);
+
+ // Which type of error this is.
+ Type type_;
+ // The ID of the extension which caused the error.
+ std::string extension_id_;
+ // Whether or not the error was caused while incognito.
+ bool from_incognito_;
+ // The source for the error; this can be a script, web page, or manifest file.
+ // This is stored as a string (rather than a url) since it can be a Chrome
+ // script file (e.g., event_bindings.js).
+ base::string16 source_;
+ // The error message itself.
+ base::string16 message_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionError);
+};
+
+class ManifestParsingError : public ExtensionError {
+ public:
+ ManifestParsingError(const std::string& extension_id,
+ const base::string16& message);
+ virtual ~ManifestParsingError();
+
+ virtual std::string PrintForTest() const OVERRIDE;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ManifestParsingError);
+};
+
+class JavascriptRuntimeError : public ExtensionError {
+ public:
+ struct StackFrame {
+ size_t line_number;
+ size_t column_number;
+ // This is stored as a string (rather than a url) since it can be a
+ // Chrome script file (e.g., event_bindings.js).
+ base::string16 url;
+ base::string16 function; // optional
+
+ // STL-Required constructor
+ StackFrame();
+
+ StackFrame(size_t frame_line,
+ size_t frame_column,
+ const base::string16& frame_url,
+ const base::string16& frame_function /* can be empty */);
+
+ ~StackFrame();
+ };
+ typedef std::vector<StackFrame> StackTrace;
+
+ JavascriptRuntimeError(bool from_incognito,
+ const base::string16& source,
+ const base::string16& message,
+ logging::LogSeverity level,
+ const base::string16& details);
+ virtual ~JavascriptRuntimeError();
+
+ virtual std::string PrintForTest() const OVERRIDE;
+
+ logging::LogSeverity level() const { return level_; }
+ const base::string16& execution_context_url() const {
+ return execution_context_url_;
+ }
+ const StackTrace& stack_trace() const { return stack_trace_; }
+ private:
+ // Parse the JSON |details| passed to the error. This includes a stack trace
+ // and an execution context url.
+ void ParseDetails(const base::string16& details);
+ // Try to determine the ID of the extension. This may be obtained through the
+ // reported source, or through the execution context url.
+ void DetermineExtensionID();
+
+ logging::LogSeverity level_;
+ base::string16 execution_context_url_;
+ StackTrace stack_trace_;
+
+ DISALLOW_COPY_AND_ASSIGN(JavascriptRuntimeError);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
diff --git a/chromium/extensions/browser/extension_prefs_scope.h b/chromium/extensions/browser/extension_prefs_scope.h
new file mode 100644
index 00000000000..3747ee817fb
--- /dev/null
+++ b/chromium/extensions/browser/extension_prefs_scope.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_EXTENSION_PREFS_SCOPE_H_
+#define EXTENSIONS_BROWSER_EXTENSION_PREFS_SCOPE_H_
+
+#include "base/basictypes.h"
+
+namespace extensions {
+
+// Scope for a preference.
+enum ExtensionPrefsScope {
+ // Regular profile and incognito.
+ kExtensionPrefsScopeRegular,
+ // Regular profile only.
+ kExtensionPrefsScopeRegularOnly,
+ // Incognito profile; preference is persisted to disk and remains active
+ // after a browser restart.
+ kExtensionPrefsScopeIncognitoPersistent,
+ // Incognito profile; preference is kept in memory and deleted when the
+ // incognito session is terminated.
+ kExtensionPrefsScopeIncognitoSessionOnly
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_EXTENSION_PREFS_SCOPE_H_
diff --git a/chromium/extensions/browser/file_reader.cc b/chromium/extensions/browser/file_reader.cc
new file mode 100644
index 00000000000..f1a560016f4
--- /dev/null
+++ b/chromium/extensions/browser/file_reader.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/file_reader.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/message_loop/message_loop.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+FileReader::FileReader(const extensions::ExtensionResource& resource,
+ const Callback& callback)
+ : resource_(resource),
+ callback_(callback),
+ origin_loop_(base::MessageLoop::current()) {}
+
+void FileReader::Start() {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&FileReader::ReadFileOnBackgroundThread, this));
+}
+
+FileReader::~FileReader() {}
+
+void FileReader::ReadFileOnBackgroundThread() {
+ std::string data;
+ bool success = file_util::ReadFileToString(resource_.GetFilePath(), &data);
+ origin_loop_->PostTask(FROM_HERE, base::Bind(callback_, success, data));
+}
diff --git a/chromium/extensions/browser/file_reader.h b/chromium/extensions/browser/file_reader.h
new file mode 100644
index 00000000000..109a97a8b47
--- /dev/null
+++ b/chromium/extensions/browser/file_reader.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_FILE_READER_H_
+#define EXTENSIONS_BROWSER_FILE_READER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "extensions/common/extension_resource.h"
+
+namespace base {
+class MessageLoop;
+}
+
+// This file defines an interface for reading a file asynchronously on a
+// background thread.
+// Consider abstracting out a FilePathProvider (ExtensionResource) and moving
+// back to chrome/browser/net if other subsystems want to use it.
+class FileReader : public base::RefCountedThreadSafe<FileReader> {
+ public:
+ // Reports success or failure and the data of the file upon success.
+ typedef base::Callback<void(bool, const std::string&)> Callback;
+
+ FileReader(const extensions::ExtensionResource& resource,
+ const Callback& callback);
+
+ // Called to start reading the file on a background thread. Upon completion,
+ // the callback will be notified of the results.
+ void Start();
+
+ private:
+ friend class base::RefCountedThreadSafe<FileReader>;
+
+ virtual ~FileReader();
+
+ void ReadFileOnBackgroundThread();
+
+ extensions::ExtensionResource resource_;
+ Callback callback_;
+ base::MessageLoop* origin_loop_;
+};
+
+#endif // EXTENSIONS_BROWSER_FILE_READER_H_
diff --git a/chromium/extensions/browser/file_reader_unittest.cc b/chromium/extensions/browser/file_reader_unittest.cc
new file mode 100644
index 00000000000..17a466ca4c1
--- /dev/null
+++ b/chromium/extensions/browser/file_reader_unittest.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "content/public/test/test_browser_thread.h"
+#include "extensions/browser/file_reader.h"
+#include "extensions/common/extension_paths.h"
+#include "extensions/common/extension_resource.h"
+#include "extensions/common/id_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using content::BrowserThread;
+
+namespace extensions {
+
+class FileReaderTest : public testing::Test {
+ public:
+ FileReaderTest() : file_thread_(BrowserThread::FILE) {
+ file_thread_.Start();
+ }
+ private:
+ base::MessageLoop message_loop_;
+ content::TestBrowserThread file_thread_;
+};
+
+class Receiver {
+ public:
+ Receiver() : succeeded_(false) {
+ }
+
+ FileReader::Callback NewCallback() {
+ return base::Bind(&Receiver::DidReadFile, base::Unretained(this));
+ }
+
+ bool succeeded() const { return succeeded_; }
+ const std::string& data() const { return data_; }
+
+ private:
+ void DidReadFile(bool success, const std::string& data) {
+ succeeded_ = success;
+ data_ = data;
+ base::MessageLoop::current()->Quit();
+ }
+
+ bool succeeded_;
+ std::string data_;
+};
+
+void RunBasicTest(const char* filename) {
+ base::FilePath path;
+ PathService::Get(DIR_TEST_DATA, &path);
+ std::string extension_id = id_util::GenerateId("test");
+ ExtensionResource resource(
+ extension_id, path, base::FilePath().AppendASCII(filename));
+ path = path.AppendASCII(filename);
+
+ std::string file_contents;
+ ASSERT_TRUE(file_util::ReadFileToString(path, &file_contents));
+
+ Receiver receiver;
+
+ scoped_refptr<FileReader> file_reader(
+ new FileReader(resource, receiver.NewCallback()));
+ file_reader->Start();
+
+ base::MessageLoop::current()->Run();
+
+ EXPECT_TRUE(receiver.succeeded());
+ EXPECT_EQ(file_contents, receiver.data());
+}
+
+TEST_F(FileReaderTest, SmallFile) {
+ RunBasicTest("smallfile");
+}
+
+TEST_F(FileReaderTest, BiggerFile) {
+ RunBasicTest("bigfile");
+}
+
+TEST_F(FileReaderTest, NonExistantFile) {
+ base::FilePath path;
+ PathService::Get(DIR_TEST_DATA, &path);
+ std::string extension_id = id_util::GenerateId("test");
+ ExtensionResource resource(extension_id, path, base::FilePath(
+ FILE_PATH_LITERAL("file_that_does_not_exist")));
+ path = path.AppendASCII("file_that_does_not_exist");
+
+ Receiver receiver;
+
+ scoped_refptr<FileReader> file_reader(
+ new FileReader(resource, receiver.NewCallback()));
+ file_reader->Start();
+
+ base::MessageLoop::current()->Run();
+
+ EXPECT_FALSE(receiver.succeeded());
+}
+
+} // namespace extensions
diff --git a/chromium/extensions/browser/pref_names.cc b/chromium/extensions/browser/pref_names.cc
new file mode 100644
index 00000000000..56de3397d9b
--- /dev/null
+++ b/chromium/extensions/browser/pref_names.cc
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/pref_names.h"
+
+#include "base/logging.h"
+
+namespace extensions {
+namespace pref_names {
+
+bool ScopeToPrefName(ExtensionPrefsScope scope, std::string* result) {
+ switch (scope) {
+ case kExtensionPrefsScopeRegular:
+ *result = kPrefPreferences;
+ return true;
+ case kExtensionPrefsScopeRegularOnly:
+ *result = kPrefRegularOnlyPreferences;
+ return true;
+ case kExtensionPrefsScopeIncognitoPersistent:
+ *result = kPrefIncognitoPreferences;
+ return true;
+ case kExtensionPrefsScopeIncognitoSessionOnly:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+const char kPrefPreferences[] = "preferences";
+const char kPrefIncognitoPreferences[] = "incognito_preferences";
+const char kPrefRegularOnlyPreferences[] = "regular_only_preferences";
+const char kPrefContentSettings[] = "content_settings";
+const char kPrefIncognitoContentSettings[] = "incognito_content_settings";
+
+} // namespace pref_names
+} // namespace extensions
diff --git a/chromium/extensions/browser/pref_names.h b/chromium/extensions/browser/pref_names.h
new file mode 100644
index 00000000000..f70b525b15c
--- /dev/null
+++ b/chromium/extensions/browser/pref_names.h
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_PREF_NAMES_H_
+#define EXTENSIONS_BROWSER_PREF_NAMES_H_
+
+#include <string>
+
+#include "extensions/browser/extension_prefs_scope.h"
+
+namespace extensions {
+
+// Preference keys which are needed by both the ExtensionPrefs and by external
+// clients, such as APIs.
+namespace pref_names {
+
+// If the given |scope| is persisted, return true and populate |result| with the
+// appropriate pref name. If |scope| is not persisted, return false, and leave
+// |result| unchanged.
+bool ScopeToPrefName(ExtensionPrefsScope scope, std::string* result);
+
+// A preference that contains any extension-controlled preferences.
+extern const char kPrefPreferences[];
+
+// A preference that contains any extension-controlled incognito preferences.
+extern const char kPrefIncognitoPreferences[];
+
+// A preference that contains any extension-controlled regular-only preferences.
+extern const char kPrefRegularOnlyPreferences[];
+
+// A preference that contains extension-set content settings.
+extern const char kPrefContentSettings[];
+
+// A preference that contains extension-set content settings.
+extern const char kPrefIncognitoContentSettings[];
+
+} // namespace pref_names
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_PREF_NAMES_H_
diff --git a/chromium/extensions/browser/view_type_utils.cc b/chromium/extensions/browser/view_type_utils.cc
new file mode 100644
index 00000000000..a28381f2db0
--- /dev/null
+++ b/chromium/extensions/browser/view_type_utils.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/view_type_utils.h"
+
+#include "base/lazy_instance.h"
+#include "content/public/browser/web_contents.h"
+
+using content::WebContents;
+
+namespace extensions {
+
+namespace {
+
+const char kViewTypeUserDataKey[] = "ViewTypeUserData";
+
+class ViewTypeUserData : public base::SupportsUserData::Data {
+ public:
+ explicit ViewTypeUserData(ViewType type) : type_(type) {}
+ virtual ~ViewTypeUserData() {}
+ ViewType type() { return type_; }
+
+ private:
+ ViewType type_;
+};
+
+} // namespace
+
+ViewType GetViewType(WebContents* tab) {
+ if (!tab)
+ return VIEW_TYPE_INVALID;
+
+ ViewTypeUserData* user_data = static_cast<ViewTypeUserData*>(
+ tab->GetUserData(&kViewTypeUserDataKey));
+
+ return user_data ? user_data->type() : VIEW_TYPE_INVALID;
+}
+
+void SetViewType(WebContents* tab, ViewType type) {
+ tab->SetUserData(&kViewTypeUserDataKey, new ViewTypeUserData(type));
+}
+
+} // namespace chrome
diff --git a/chromium/extensions/browser/view_type_utils.h b/chromium/extensions/browser/view_type_utils.h
new file mode 100644
index 00000000000..4667be438f2
--- /dev/null
+++ b/chromium/extensions/browser/view_type_utils.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_VIEW_TYPE_UTILS_H_
+#define EXTENSIONS_BROWSER_VIEW_TYPE_UTILS_H_
+
+#include "extensions/common/view_type.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace extensions {
+
+// Get/Set the type of a WebContents.
+// GetViewType handles a NULL |tab| for convenience by returning
+// VIEW_TYPE_INVALID.
+ViewType GetViewType(content::WebContents* tab);
+void SetViewType(content::WebContents* tab, ViewType type);
+
+} // namespace chrome
+
+#endif // EXTENSIONS_BROWSER_VIEW_TYPE_UTILS_H_