diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-07 00:14:31 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-07 00:14:31 +0000 |
commit | e916901cd0a8144ca81346d52f2129b3a6e07d67 (patch) | |
tree | 572a9d0bc51ba6ecbd52ebc6aca1093fad40ad2c /chrome/browser/extensions | |
parent | 1ca24f56fabfb0338afac62c31d7c2de77b081ca (diff) | |
download | chromium_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.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 8 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_host.cc | 7 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_host.h | 5 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_message_service.cc | 37 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_message_service.h | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_ui_unittest.cc | 23 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.cc | 79 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.h | 31 |
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_; |