summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-07 00:14:31 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-07 00:14:31 +0000
commite916901cd0a8144ca81346d52f2129b3a6e07d67 (patch)
tree572a9d0bc51ba6ecbd52ebc6aca1093fad40ad2c /chrome/browser/extensions
parent1ca24f56fabfb0338afac62c31d7c2de77b081ca (diff)
downloadchromium_src-e916901cd0a8144ca81346d52f2129b3a6e07d67.zip
chromium_src-e916901cd0a8144ca81346d52f2129b3a6e07d67.tar.gz
chromium_src-e916901cd0a8144ca81346d52f2129b3a6e07d67.tar.bz2
Add inspect links for all active views in chrome://extensions.
Also: * Add ID to the information in chrome://extensions. * Call ExtensionMessageService::RegisterExtension() for all RVHs, not just ExtensionHost. * Teach RVHD to be able to return the current URL. * Renamed "background" to "background_page" in the manifest. Review URL: http://codereview.chromium.org/113027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15481 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension.cc2
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc8
-rwxr-xr-xchrome/browser/extensions/extension_host.cc7
-rwxr-xr-xchrome/browser/extensions/extension_host.h5
-rwxr-xr-xchrome/browser/extensions/extension_message_service.cc37
-rwxr-xr-xchrome/browser/extensions/extension_message_service.h8
-rw-r--r--chrome/browser/extensions/extension_ui_unittest.cc23
-rw-r--r--chrome/browser/extensions/extensions_ui.cc79
-rw-r--r--chrome/browser/extensions/extensions_ui.h31
9 files changed, 170 insertions, 30 deletions
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index e35dfff..0f9c24e 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -27,7 +27,7 @@ const wchar_t* Extension::kNameKey = L"name";
const wchar_t* Extension::kPageActionsKey = L"page_actions";
const wchar_t* Extension::kPermissionsKey = L"permissions";
const wchar_t* Extension::kPluginsDirKey = L"plugins_dir";
-const wchar_t* Extension::kBackgroundKey = L"background";
+const wchar_t* Extension::kBackgroundKey = L"background_page";
const wchar_t* Extension::kRunAtKey = L"run_at";
const wchar_t* Extension::kThemeKey = L"theme";
const wchar_t* Extension::kToolstripsKey = L"toolstrips";
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index bb093de..a8d4ac8 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -11,8 +11,10 @@
#include "base/values.h"
#include "chrome/browser/extensions/extension_bookmarks_module.h"
#include "chrome/browser/extensions/extension_function.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_page_actions_module.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/common/result_codes.h"
@@ -121,6 +123,12 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
: render_view_host_(render_view_host),
browser_(browser),
extension_id_(extension_id) {
+ RenderProcessHost* process = render_view_host_->process();
+ ExtensionMessageService* message_service =
+ ExtensionMessageService::GetInstance(profile()->GetRequestContext());
+ DCHECK(process);
+ DCHECK(message_service);
+ message_service->RegisterExtension(extension_id, process->pid());
}
void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 7f6bd01..8e3f723 100755
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -43,6 +43,7 @@ SiteInstance* ExtensionHost::site_instance() const {
void ExtensionHost::CreateRenderView(const GURL& url,
RenderWidgetHostView* host_view) {
+ url_ = url;
render_view_host_->set_view(host_view);
render_view_host_->CreateRenderView();
render_view_host_->NavigateToURL(url);
@@ -53,12 +54,6 @@ void ExtensionHost::DidContentsPreferredWidthChange(const int pref_width) {
view_->DidContentsPreferredWidthChange(pref_width);
}
-void ExtensionHost::RenderViewCreated(RenderViewHost* rvh) {
- URLRequestContext* context = rvh->process()->profile()->GetRequestContext();
- ExtensionMessageService::GetInstance(context)->RegisterExtension(
- extension_->id(), rvh->process()->pid());
-}
-
WebPreferences ExtensionHost::GetWebkitPrefs() {
PrefService* prefs = render_view_host()->process()->profile()->GetPrefs();
const bool kIsDomUI = true;
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 6a80cb4..0e97c91 100755
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -41,7 +41,7 @@ class ExtensionHost : public RenderViewHostDelegate,
// RenderViewHostDelegate
// TODO(mpcomplete): GetProfile is unused.
virtual Profile* GetProfile() const { return NULL; }
- virtual void RenderViewCreated(RenderViewHost* render_view_host);
+ virtual const GURL& GetURL() const { return url_; }
virtual void DidContentsPreferredWidthChange(const int pref_width);
virtual WebPreferences GetWebkitPrefs();
virtual void RunJavaScriptMessage(
@@ -94,6 +94,9 @@ class ExtensionHost : public RenderViewHostDelegate,
// Whether the RenderWidget has reported that it has stopped loading.
bool did_stop_loading_;
+ // The URL being hosted.
+ GURL url_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionHost);
};
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 8c8a3b9..9c4f2b5 100755
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_view.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_util.h"
@@ -112,6 +111,30 @@ void ExtensionMessageService::RemoveEventListener(std::string event_name,
listeners_[event_name].erase(render_process_id);
}
+int ExtensionMessageService::GetProcessIdForExtension(
+ const std::string& extension_id) {
+ AutoLock lock(process_ids_lock_);
+ ProcessIDMap::iterator process_id_it = process_ids_.find(
+ StringToLowerASCII(extension_id));
+ if (process_id_it == process_ids_.end())
+ return -1;
+ return process_id_it->second;
+}
+
+RenderProcessHost* ExtensionMessageService::GetProcessForExtension(
+ const std::string& extension_id) {
+ DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
+
+ int process_id = GetProcessIdForExtension(extension_id);
+ if (process_id == -1)
+ return NULL;
+
+ RenderProcessHost* host = RenderProcessHost::FromID(process_id);
+ DCHECK(host);
+
+ return host;
+}
+
int ExtensionMessageService::OpenChannelToExtension(
int routing_id, const std::string& extension_id,
ResourceMessageFilter* source) {
@@ -119,15 +142,9 @@ int ExtensionMessageService::OpenChannelToExtension(
ChromeThread::GetMessageLoop(ChromeThread::IO));
// Lookup the targeted extension process.
- int process_id;
- {
- AutoLock lock(process_ids_lock_);
- ProcessIDMap::iterator process_id_it = process_ids_.find(
- StringToLowerASCII(extension_id));
- if (process_id_it == process_ids_.end())
- return -1;
- process_id = process_id_it->second;
- }
+ int process_id = GetProcessIdForExtension(extension_id);
+ if (process_id == -1)
+ return -1;
DCHECK(initialized_);
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 343c632..6e949f0 100755
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/lock.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/notification_observer.h"
class MessageLoop;
@@ -36,6 +37,9 @@ class ExtensionMessageService : public NotificationObserver {
// --- UI thread only:
+ // Gets the process for the specified extension.
+ RenderProcessHost* GetProcessForExtension(const std::string& extension_id);
+
// Register an extension and its corresponding renderer process.
void RegisterExtension(const std::string& extension_id,
int render_process_id);
@@ -68,6 +72,10 @@ class ExtensionMessageService : public NotificationObserver {
ResourceMessageFilter* source);
private:
+ // Gets the process ID for the specified etension.
+ // NOTE: this can be called from any thread.
+ int GetProcessIdForExtension(const std::string& extension_id);
+
// The UI message loop, used for posting tasks.
MessageLoop* ui_loop_;
diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc
index c3dbbb0..0449e2a 100644
--- a/chrome/browser/extensions/extension_ui_unittest.cc
+++ b/chrome/browser/extensions/extension_ui_unittest.cc
@@ -21,7 +21,9 @@ namespace {
return static_cast<DictionaryValue*>(value);
}
- static bool CompareExpectedAndActualOutput(const FilePath& extension_path,
+ static bool CompareExpectedAndActualOutput(
+ const FilePath& extension_path,
+ const std::vector<ExtensionPage>& pages,
const FilePath& expected_output_path) {
// TODO(rafaelw): Using the extension_path passed in above, causes this
// unit test to fail on linux. The Values come back valid, but the
@@ -48,7 +50,7 @@ namespace {
// Produce test output.
scoped_ptr<DictionaryValue> actual_output_data(
- ExtensionsDOMHandler::CreateExtensionDetailValue(&extension));
+ ExtensionsDOMHandler::CreateExtensionDetailValue(&extension, pages));
// Compare the outputs.
return expected_output_data->Equals(actual_output_data.get());
@@ -68,12 +70,18 @@ TEST(ExtensionUITest, GenerateExtensionsJSONData) {
.AppendASCII("extension1")
.AppendASCII("1");
+ std::vector<ExtensionPage> pages;
+ pages.push_back(ExtensionPage(GURL("chrome-extension://foo/bar.html"),
+ 42, 88));
+ pages.push_back(ExtensionPage(GURL("chrome-extension://hot/dog.html"),
+ 0, 0));
+
expected_output_path = data_test_dir_path.AppendASCII("extensions")
.AppendASCII("ui")
.AppendASCII("create_extension_detail_value_expected_output")
.AppendASCII("good-extension1.json");
- EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path,
+ EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path, pages,
expected_output_path)) << extension_path.value();
// Test Extension2
@@ -87,7 +95,10 @@ TEST(ExtensionUITest, GenerateExtensionsJSONData) {
.AppendASCII("create_extension_detail_value_expected_output")
.AppendASCII("good-extension2.json");
- EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path,
+ // It's OK to have duplicate URLs, so long as the IDs are different.
+ pages[1].url = pages[0].url;
+
+ EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path, pages,
expected_output_path)) << extension_path.value();
// Test Extension3
@@ -101,6 +112,8 @@ TEST(ExtensionUITest, GenerateExtensionsJSONData) {
.AppendASCII("create_extension_detail_value_expected_output")
.AppendASCII("good-extension3.json");
- EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path,
+ pages.clear();
+
+ EXPECT_TRUE(CompareExpectedAndActualOutput(extension_path, pages,
expected_output_path)) << extension_path.value();
}
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index 3aa0480..d74b802 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -6,11 +6,15 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/url_constants.h"
@@ -59,6 +63,8 @@ ExtensionsDOMHandler::ExtensionsDOMHandler(DOMUI* dom_ui,
: DOMMessageHandler(dom_ui), extensions_service_(extension_service) {
dom_ui_->RegisterMessageCallback("requestExtensionsData",
NewCallback(this, &ExtensionsDOMHandler::HandleRequestExtensionsData));
+ dom_ui_->RegisterMessageCallback("inspect",
+ NewCallback(this, &ExtensionsDOMHandler::HandleInspectMessage));
}
void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) {
@@ -69,7 +75,8 @@ void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) {
const ExtensionList* extensions = extensions_service_->extensions();
for (ExtensionList::const_iterator extension = extensions->begin();
extension != extensions->end(); ++extension) {
- extensions_list->Append(CreateExtensionDetailValue(*extension));
+ extensions_list->Append(CreateExtensionDetailValue(
+ *extension, GetActivePagesForExtension((*extension)->id())));
}
results.Set(L"extensions", extensions_list);
@@ -86,6 +93,28 @@ void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) {
dom_ui_->CallJavascriptFunction(L"returnExtensionsData", results);
}
+void ExtensionsDOMHandler::HandleInspectMessage(const Value* value) {
+ std::string render_process_id_str;
+ std::string render_view_id_str;
+ int render_process_id;
+ int render_view_id;
+ CHECK(value->IsType(Value::TYPE_LIST));
+ const ListValue* list = static_cast<const ListValue*>(value);
+ CHECK(list->GetSize() == 2);
+ CHECK(list->GetString(0, &render_process_id_str));
+ CHECK(list->GetString(1, &render_view_id_str));
+ CHECK(StringToInt(render_process_id_str, &render_process_id));
+ CHECK(StringToInt(render_view_id_str, &render_view_id));
+ RenderViewHost* host = RenderViewHost::FromID(render_process_id,
+ render_view_id);
+ if (!host) {
+ // This can happen if the host has gone away since the page was displayed.
+ return;
+ }
+
+ host->InspectElementAt(0, 0);
+}
+
static void CreateScriptFileDetailValue(
const FilePath& extension_path, const UserScript::FileList& scripts,
const wchar_t* key, DictionaryValue* script_data) {
@@ -132,9 +161,10 @@ DictionaryValue* ExtensionsDOMHandler::CreateContentScriptDetailValue(
// Static
DictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
- const Extension *extension) {
+ const Extension *extension, const std::vector<ExtensionPage>& pages) {
DictionaryValue* extension_data = new DictionaryValue();
+ extension_data->SetString(L"id", extension->id());
extension_data->SetString(L"name", extension->name());
extension_data->SetString(L"description", extension->description());
extension_data->SetString(L"version", extension->version()->GetString());
@@ -159,9 +189,54 @@ DictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
}
extension_data->Set(L"permissions", permission_list);
+ // Add views
+ ListValue* views = new ListValue;
+ for (std::vector<ExtensionPage>::const_iterator iter = pages.begin();
+ iter != pages.end(); ++iter) {
+ DictionaryValue* view_value = new DictionaryValue;
+ view_value->SetString(L"path",
+ iter->url.path().substr(1, std::string::npos)); // no leading slash
+ view_value->SetInteger(L"renderViewId", iter->render_view_id);
+ view_value->SetInteger(L"renderProcessId", iter->render_process_id);
+ views->Append(view_value);
+ }
+ extension_data->Set(L"views", views);
+
return extension_data;
}
+std::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
+ const std::string& extension_id) {
+ std::vector<ExtensionPage> result;
+
+ ExtensionMessageService* ems = ExtensionMessageService::GetInstance(
+ dom_ui_->GetProfile()->GetRequestContext());
+ RenderProcessHost* process_host = ems->GetProcessForExtension(extension_id);
+ if (!process_host)
+ return result;
+
+ RenderProcessHost::listeners_iterator iter;
+ for (iter = process_host->listeners_begin();
+ iter != process_host->listeners_end(); ++iter) {
+ // NOTE: This is a bit dangerous. We know that for now, listeners are
+ // always RenderWidgetHosts. But in theory, they don't have to be.
+ RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second);
+ if (!widget->IsRenderView())
+ continue;
+
+ RenderViewHost* view = static_cast<RenderViewHost*>(widget);
+ ExtensionFunctionDispatcher* efd = view->extension_function_dispatcher();
+ if (efd && efd->extension_id() == extension_id) {
+ ExtensionPage page(view->delegate()->GetURL(),
+ process_host->pid(),
+ view->routing_id());
+ result.push_back(page);
+ }
+ }
+
+ return result;
+}
+
ExtensionsDOMHandler::~ExtensionsDOMHandler() {
}
diff --git a/chrome/browser/extensions/extensions_ui.h b/chrome/browser/extensions/extensions_ui.h
index 3d1ed7b..953cb31e 100644
--- a/chrome/browser/extensions/extensions_ui.h
+++ b/chrome/browser/extensions/extensions_ui.h
@@ -6,15 +6,28 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSIONS_UI_H_
#include <string>
+#include <vector>
#include "base/values.h"
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/dom_ui/dom_ui.h"
#include "chrome/browser/extensions/extensions_service.h"
+#include "googleurl/src/gurl.h"
class GURL;
class UserScript;
+// Information about a page running in an extension, for example a toolstrip,
+// a background page, or a tab contents.
+struct ExtensionPage {
+ ExtensionPage(const GURL& url, int render_process_id, int render_view_id)
+ : url(url), render_process_id(render_process_id),
+ render_view_id(render_view_id) {}
+ GURL url;
+ int render_process_id;
+ int render_view_id;
+};
+
class ExtensionsUIHTMLSource : public ChromeURLDataManager::DataSource {
public:
ExtensionsUIHTMLSource();
@@ -40,18 +53,26 @@ class ExtensionsDOMHandler : public DOMMessageHandler {
void Init();
// Extension Detail JSON Struct for page. (static for ease of testing).
- static DictionaryValue*
- CreateExtensionDetailValue(const Extension *extension);
+ static DictionaryValue* CreateExtensionDetailValue(
+ const Extension *extension,
+ const std::vector<ExtensionPage>&);
// ContentScript JSON Struct for page. (static for ease of testing).
- static DictionaryValue*
- CreateContentScriptDetailValue(const UserScript& script,
- const FilePath& extension_path);
+ static DictionaryValue* CreateContentScriptDetailValue(
+ const UserScript& script,
+ const FilePath& extension_path);
private:
// Callback for "requestExtensionsData" message.
void HandleRequestExtensionsData(const Value* value);
+ // Callback for "inspect" message.
+ void HandleInspectMessage(const Value* value);
+
+ // Helper that lists the current active html pages for an extension.
+ std::vector<ExtensionPage> GetActivePagesForExtension(
+ const std::string& extension_id);
+
// Our model.
scoped_refptr<ExtensionsService> extensions_service_;