summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-01 08:46:25 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-01 08:46:25 +0000
commit811bfe371c3518e58664fb5191a6962314f8f05f (patch)
tree6dc3cb4264f9d87c93a2313fa856c1ea7e6e23e8 /chrome/browser/extensions
parent20fdbc31d0e998ba81d8337259b43e57e2ff02b7 (diff)
downloadchromium_src-811bfe371c3518e58664fb5191a6962314f8f05f.zip
chromium_src-811bfe371c3518e58664fb5191a6962314f8f05f.tar.gz
chromium_src-811bfe371c3518e58664fb5191a6962314f8f05f.tar.bz2
In this episode, we implement the DOMUI interface for extension views that are rendered in the main tab contents area. This gets us loaded and unloaded at the right place and removes many special cases for extensions from the RenderViewHost and RenderViewHostDelegate hierarchy.
BUG=13936 Review URL: http://codereview.chromium.org/126137 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19717 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_dom_ui.cc31
-rw-r--r--chrome/browser/extensions/extension_dom_ui.h33
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc14
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h17
-rw-r--r--chrome/browser/extensions/extension_host.cc22
-rw-r--r--chrome/browser/extensions/extension_host.h10
-rw-r--r--chrome/browser/extensions/extension_startup_unittest.cc10
-rw-r--r--chrome/browser/extensions/extensions_ui.cc33
8 files changed, 132 insertions, 38 deletions
diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc
new file mode 100644
index 0000000..0d24345
--- /dev/null
+++ b/chrome/browser/extensions/extension_dom_ui.cc
@@ -0,0 +1,31 @@
+#include "chrome/browser/extensions/extension_dom_ui.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/bindings_policy.h"
+
+ExtensionDOMUI::ExtensionDOMUI(TabContents* tab_contents)
+ : DOMUI(tab_contents) {
+ // TODO(aa): It would be cool to show the extension's icon in here.
+ hide_favicon_ = true;
+ should_hide_url_ = true;
+ bindings_ = BindingsPolicy::EXTENSION;
+}
+
+void ExtensionDOMUI::RenderViewCreated(RenderViewHost* render_view_host) {
+ extension_function_dispatcher_.reset(
+ new ExtensionFunctionDispatcher(render_view_host, this,
+ tab_contents()->GetURL()));
+}
+
+void ExtensionDOMUI::ProcessDOMUIMessage(const std::string& message,
+ const std::string& content,
+ int request_id,
+ bool has_callback) {
+ extension_function_dispatcher_->HandleRequest(message, content, request_id,
+ has_callback);
+}
+
+Browser* ExtensionDOMUI::GetBrowser() {
+ return static_cast<Browser*>(tab_contents()->delegate());
+}
diff --git a/chrome/browser/extensions/extension_dom_ui.h b/chrome/browser/extensions/extension_dom_ui.h
new file mode 100644
index 0000000..2de94cf
--- /dev/null
+++ b/chrome/browser/extensions/extension_dom_ui.h
@@ -0,0 +1,33 @@
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_DOM_UI_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_DOM_UI_H_
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/dom_ui/dom_ui.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
+
+// This class implements DOMUI for extensions and allows extensions to put UI in
+// the main tab contents area.
+class ExtensionDOMUI
+ : public DOMUI,
+ public ExtensionFunctionDispatcher::Delegate {
+ public:
+ explicit ExtensionDOMUI(TabContents* tab_contents);
+ ExtensionFunctionDispatcher* extension_function_dispatcher() const {
+ return extension_function_dispatcher_.get();
+ }
+
+ // DOMUI
+ virtual void RenderViewCreated(RenderViewHost* render_view_host);
+ virtual void ProcessDOMUIMessage(const std::string& message,
+ const std::string& content,
+ int request_id,
+ bool has_callback);
+
+ // ExtensionFunctionDispatcher::Delegate
+ virtual Browser* GetBrowser();
+
+ private:
+ scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_DOM_UI_H_
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 7b873a5..24eacf2 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -168,23 +168,31 @@ void ExtensionFunctionDispatcher::ResetFunctions() {
FactoryRegistry::instance()->ResetFunctions();
}
+std::set<ExtensionFunctionDispatcher*>*
+ ExtensionFunctionDispatcher::all_instances() {
+ static std::set<ExtensionFunctionDispatcher*> instances;
+ return &instances;
+}
+
ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
RenderViewHost* render_view_host,
Delegate* delegate,
- const std::string& extension_id)
+ const GURL& url)
: render_view_host_(render_view_host),
delegate_(delegate),
- extension_id_(extension_id),
+ url_(url),
ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
+ all_instances()->insert(this);
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());
+ message_service->RegisterExtension(extension_id(), process->pid());
}
ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
+ all_instances()->erase(this);
peer_->dispatcher_ = NULL;
}
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index b59e256..0e79882 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -6,9 +6,11 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_DISPATCHER_H_
#include <string>
+#include <set>
#include <vector>
#include "base/ref_counted.h"
+#include "googleurl/src/gurl.h"
class Browser;
class ExtensionFunction;
@@ -47,9 +49,12 @@ class ExtensionFunctionDispatcher {
// Resets all functions to their initial implementation.
static void ResetFunctions();
+ // Retrieves a vector of all EFD instances.
+ static std::set<ExtensionFunctionDispatcher*>* all_instances();
+
ExtensionFunctionDispatcher(RenderViewHost* render_view_host,
Delegate* delegate,
- const std::string& extension_id);
+ const GURL& url);
~ExtensionFunctionDispatcher();
// Handle a request to execute an extension function.
@@ -67,18 +72,24 @@ class ExtensionFunctionDispatcher {
// the renderer.
void HandleBadMessage(ExtensionFunction* api);
+ // Gets the URL for the view we're displaying.
+ const GURL& url() { return url_; }
+
// Gets the ID for this extension.
- std::string extension_id() { return extension_id_; }
+ const std::string extension_id() { return url_.host(); }
// The profile that this dispatcher is associated with.
Profile* profile();
+ // The RenderViewHost this dispatcher is associated with.
+ RenderViewHost* render_view_host() { return render_view_host_; }
+
private:
RenderViewHost* render_view_host_;
Delegate* delegate_;
- std::string extension_id_;
+ GURL url_;
scoped_refptr<Peer> peer_;
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 94b759d..669dbdd 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/common/bindings_policy.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
@@ -84,7 +85,7 @@ ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance,
url_(url) {
render_view_host_ = new RenderViewHost(
site_instance, this, MSG_ROUTING_NONE, NULL);
- render_view_host_->AllowExtensionBindings();
+ render_view_host_->AllowBindings(BindingsPolicy::EXTENSION);
}
ExtensionHost::~ExtensionHost() {
@@ -196,12 +197,6 @@ void ExtensionHost::DidInsertCSS() {
#endif
}
-ExtensionFunctionDispatcher* ExtensionHost::
- CreateExtensionFunctionDispatcher(RenderViewHost *render_view_host,
- const std::string& extension_id) {
- return new ExtensionFunctionDispatcher(render_view_host, this, extension_id);
-}
-
RenderViewHostDelegate::View* ExtensionHost::GetViewDelegate() const {
// TODO(erikkay) this is unfortunate. The interface declares that this method
// must be const (no good reason for it as far as I can tell) which means you
@@ -303,3 +298,16 @@ Browser* ExtensionHost::GetBrowser() {
// is available. http://code.google.com/p/chromium/issues/detail?id=13284
return browser;
}
+
+void ExtensionHost::ProcessDOMUIMessage(const std::string& message,
+ const std::string& content,
+ int request_id,
+ bool has_callback) {
+ extension_function_dispatcher_->HandleRequest(message, content, request_id,
+ has_callback);
+}
+
+void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
+ extension_function_dispatcher_.reset(
+ new ExtensionFunctionDispatcher(render_view_host_, this, url_));
+}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index a7ca899..e54fc39 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/scoped_ptr.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#if defined(TOOLKIT_VIEWS)
@@ -63,6 +64,7 @@ class ExtensionHost : public RenderViewHostDelegate,
// RenderViewHostDelegate
virtual const GURL& GetURL() const { return url_; }
+ virtual void RenderViewCreated(RenderViewHost* render_view_host);
virtual void RenderViewGone(RenderViewHost* render_view_host);
virtual WebPreferences GetWebkitPrefs();
virtual void RunJavaScriptMessage(
@@ -74,9 +76,11 @@ class ExtensionHost : public RenderViewHostDelegate,
bool* did_suppress_message);
virtual void DidStopLoading(RenderViewHost* render_view_host);
virtual RenderViewHostDelegate::View* GetViewDelegate() const;
- virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher(
- RenderViewHost *render_view_host, const std::string& extension_id);
virtual void DidInsertCSS();
+ virtual void ProcessDOMUIMessage(const std::string& message,
+ const std::string& content,
+ int request_id,
+ bool has_callback);
// RenderViewHostDelegate::View
virtual void CreateNewWindow(int route_id,
@@ -129,6 +133,8 @@ class ExtensionHost : public RenderViewHostDelegate,
// The URL being hosted.
GURL url_;
+ scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionHost);
};
diff --git a/chrome/browser/extensions/extension_startup_unittest.cc b/chrome/browser/extensions/extension_startup_unittest.cc
index ce9b885..a9c494a 100644
--- a/chrome/browser/extensions/extension_startup_unittest.cc
+++ b/chrome/browser/extensions/extension_startup_unittest.cc
@@ -152,12 +152,22 @@ IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, Test) {
&result);
EXPECT_TRUE(result);
+ result = false;
ui_test_utils::ExecuteJavaScriptAndExtractBool(
browser()->GetSelectedTabContents(), L"",
L"window.domAutomationController.send(document.title == 'Modified')",
&result);
EXPECT_TRUE(result);
+ // Load an extension page into the tab area to make sure it works.
+ result = false;
+ ui_test_utils::NavigateToURL(
+ browser(),
+ GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html"));
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ browser()->GetSelectedTabContents(), L"", L"testTabsAPI()", &result);
+ EXPECT_TRUE(result);
+
// TODO(aa): Move the stuff in ExtensionBrowserTest here?
}
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index 7ad40cc..62fb559 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -226,29 +226,16 @@ DictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
std::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
const std::string& extension_id) {
std::vector<ExtensionPage> result;
-
- ExtensionMessageService* ems = ExtensionMessageService::GetInstance(
- dom_ui_->GetProfile()->GetOriginalProfile()->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);
+ std::set<ExtensionFunctionDispatcher*>* all_instances =
+ ExtensionFunctionDispatcher::all_instances();
+
+ for (std::set<ExtensionFunctionDispatcher*>::iterator iter =
+ all_instances->begin(); iter != all_instances->end(); ++iter) {
+ RenderViewHost* view = (*iter)->render_view_host();
+ if ((*iter)->extension_id() == extension_id && view) {
+ result.push_back(ExtensionPage((*iter)->url(),
+ view->process()->pid(),
+ view->routing_id()));
}
}