summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 02:41:28 +0000
committerrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 02:41:28 +0000
commitb68d5ed3f9d1b49b24713431bfe212b7601b75b1 (patch)
tree9d374ca1d7c1f5f8a25fefacde0bcf3396595da6 /chrome/browser/extensions
parentf606747ffb21e9d0c6d55c9b57d42445503728f1 (diff)
downloadchromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.zip
chromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.tar.gz
chromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.tar.bz2
Initial plumbing for sending events from the browser to extension renderers. Implement onTabMoved.
Review URL: http://codereview.chromium.org/73065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13824 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc93
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h55
-rwxr-xr-xchrome/browser/extensions/extension_message_service.cc15
-rwxr-xr-xchrome/browser/extensions/extension_message_service.h2
-rwxr-xr-xchrome/browser/extensions/extension_process_manager.cc21
-rwxr-xr-xchrome/browser/extensions/extension_process_manager.h8
-rw-r--r--chrome/browser/extensions/extension_tabs_module.cc12
-rw-r--r--chrome/browser/extensions/extension_tabs_module.h8
-rw-r--r--chrome/browser/extensions/extensions_service.cc4
9 files changed, 211 insertions, 7 deletions
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
new file mode 100644
index 0000000..a80abea
--- /dev/null
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2009 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 "chrome/browser/extensions/extension_browser_event_router.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/extensions/extension.h"
+#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/common/notification_service.h"
+
+const char* kOnTabMoved = "tab-moved";
+
+ExtensionBrowserEventRouter* ExtensionBrowserEventRouter::GetInstance() {
+ return Singleton<ExtensionBrowserEventRouter>::get();
+}
+
+void ExtensionBrowserEventRouter::Init() {
+ if (initialized_)
+ return;
+
+ NotificationService::current()->AddObserver(this,
+ NotificationType::BROWSER_OPENED, NotificationService::AllSources());
+ NotificationService::current()->AddObserver(this,
+ NotificationType::BROWSER_CLOSED, NotificationService::AllSources());
+
+ initialized_ = true;
+}
+
+ExtensionBrowserEventRouter::ExtensionBrowserEventRouter()
+ : initialized_(false) { }
+
+// NotificationObserver
+void ExtensionBrowserEventRouter::Observe(NotificationType type,
+ const NotificationSource& source, const NotificationDetails& details) {
+ Browser* browser;
+
+ switch (type.value) {
+ case(NotificationType::BROWSER_OPENED) :
+ browser = Source<Browser>(source).ptr();
+ browser->tabstrip_model()->AddObserver(this);
+ break;
+ case(NotificationType::BROWSER_CLOSED) :
+ browser = Source<Browser>(source).ptr();
+ browser->tabstrip_model()->RemoveObserver(this);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground) { }
+
+void ExtensionBrowserEventRouter::TabClosingAt(TabContents* contents,
+ int index) { }
+
+void ExtensionBrowserEventRouter::TabDetachedAt(TabContents* contents,
+ int index) { }
+
+void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture) { }
+
+void ExtensionBrowserEventRouter::TabMoved(TabContents* contents,
+ int from_index,
+ int to_index) {
+ Profile *profile = contents->profile();
+
+ ListValue args;
+ DictionaryValue *object_args = new DictionaryValue();
+
+ object_args->Set(L"tabId", Value::CreateIntegerValue(
+ ExtensionTabUtil::GetTabId(contents)));
+ object_args->Set(L"windowId", Value::CreateIntegerValue(
+ ExtensionTabUtil::GetWindowIdOfTab(contents)));
+ object_args->Set(L"fromIndex", Value::CreateIntegerValue(from_index));
+ object_args->Set(L"toIndex", Value::CreateIntegerValue(to_index));
+
+ args.Append(object_args);
+ ExtensionProcessManager::GetInstance()->DispatchEventToRenderers(profile,
+ kOnTabMoved, args);
+}
+
+void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents,
+ int index,
+ bool loading_only) { }
+
+void ExtensionBrowserEventRouter::TabStripEmpty() { }
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
new file mode 100644
index 0000000..a438e66
--- /dev/null
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2009 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 CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
+
+#include <vector>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/singleton.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/common/notification_observer.h"
+
+// The ExtensionBrowserEventRouter listens to Browser window & tab events
+// and routes them to listeners inside extension process renderers.
+// ExtensionBrowserEventRouter listens to *all* events, but will only route
+// events from windows/tabs within a profile to extension processes in the same
+// profile.
+class ExtensionBrowserEventRouter : public TabStripModelObserver,
+ public NotificationObserver {
+ public:
+ // Get Browser-Global instance
+ static ExtensionBrowserEventRouter* GetInstance();
+
+ // Must be called once. Subsequent calls have no effect.
+ void Init();
+
+ // TabStripModelObserver
+ void TabInsertedAt(TabContents* contents, int index, bool foreground);
+ void TabClosingAt(TabContents* contents, int index);
+ void TabDetachedAt(TabContents* contents, int index);
+ void TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture);
+ void TabMoved(TabContents* contents, int from_index, int to_index);
+ void TabChangedAt(TabContents* contents, int index, bool loading_only);
+ void TabStripEmpty();
+
+ // NotificationObserver
+ void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+ private:
+ ExtensionBrowserEventRouter();
+ friend struct DefaultSingletonTraits<ExtensionBrowserEventRouter>;
+
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserEventRouter);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 74e2757..3c2c1de 100755
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -54,12 +54,20 @@ ExtensionMessageService::ExtensionMessageService()
: next_port_id_(0) {
}
+std::set<int> ExtensionMessageService::GetUniqueProcessIds() {
+ std::set<int> ids;
+ ProcessIDMap::iterator it;
+ AutoLock lock(renderers_lock_);
+
+ for (it = process_ids_.begin(); it != process_ids_.end(); it++) {
+ ids.insert(it->second);
+ }
+ return ids;
+}
+
void ExtensionMessageService::RegisterExtension(
const std::string& extension_id, int render_process_id) {
AutoLock lock(renderers_lock_);
- // TODO(mpcomplete): We need to ensure an extension always ends up in a single
- // process. I think this means having an ExtensionProcessManager which holds
- // a BrowsingContext for each extension.
DCHECK(process_ids_.find(extension_id) == process_ids_.end() ||
process_ids_[extension_id] == render_process_id);
process_ids_[extension_id] = render_process_id;
@@ -174,4 +182,3 @@ void ExtensionMessageService::Observe(NotificationType type,
source);
}
}
-
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 1238338..f938b51 100755
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -61,6 +61,8 @@ class ExtensionMessageService : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
+ std::set<int> GetUniqueProcessIds();
+
private:
// A map of extension ID to the render_process_id that the extension lives in.
typedef std::map<std::string, int> ProcessIDMap;
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index e9d7bc9..b2fb63e 100755
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -4,10 +4,14 @@
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "base/json_writer.h"
#include "base/singleton.h"
+#include "base/values.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extension_view.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/tab_contents/site_instance.h"
+#include "chrome/common/render_messages.h"
// static
ExtensionProcessManager* ExtensionProcessManager::GetInstance() {
@@ -23,7 +27,7 @@ ExtensionProcessManager::~ExtensionProcessManager() {
ExtensionView* ExtensionProcessManager::CreateView(Extension* extension,
const GURL& url,
Browser* browser) {
- return new ExtensionView(extension, url,
+ return new ExtensionView(extension, url,
GetSiteInstanceForURL(url, browser->profile()),
browser);
}
@@ -34,6 +38,21 @@ SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(
return browsing_instance->GetSiteInstanceForURL(url);
}
+void ExtensionProcessManager::DispatchEventToRenderers(Profile *profile,
+ const std::string& event_name, const ListValue& data) {
+ std::string json_data;
+ JSONWriter::Write(&data, false, &json_data);
+
+ std::set<int> process_ids = ExtensionMessageService::GetInstance(
+ profile->GetRequestContext())->GetUniqueProcessIds();
+
+ std::set<int>::iterator id;
+ for (id = process_ids.begin(); id != process_ids.end(); ++id) {
+ RenderProcessHost* rph = RenderProcessHost::FromID(*id);
+ rph->Send(new ViewMsg_ExtensionHandleEvent(event_name, json_data));
+ }
+}
+
BrowsingInstance* ExtensionProcessManager::GetBrowsingInstance(
Profile* profile) {
BrowsingInstance* instance = browsing_instance_map_[profile];
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index fdbff8a..7e56fc8 100755
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -8,12 +8,14 @@
#include "base/ref_counted.h"
#include <map>
+#include <string>
class Browser;
class BrowsingInstance;
class Extension;
class ExtensionView;
class GURL;
+class ListValue;
class Profile;
class SiteInstance;
@@ -41,6 +43,12 @@ class ExtensionProcessManager {
// Returns the SiteInstance that the given URL belongs to in this profile.
SiteInstance* GetSiteInstanceForURL(const GURL& url, Profile* profile);
+
+ // Sends the event to each renderer process within the current profile that
+ // contain at least one extension renderer.
+ void DispatchEventToRenderers(Profile *profile,
+ const std::string& event_name,
+ const ListValue& data);
private:
// Returns our BrowsingInstance for the given profile. Lazily created and
// cached.
diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc
index 811bc97..86fcf49 100644
--- a/chrome/browser/extensions/extension_tabs_module.cc
+++ b/chrome/browser/extensions/extension_tabs_module.cc
@@ -17,6 +17,14 @@ static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model,
static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id,
int* tab_index);
+int ExtensionTabUtil::GetTabId(const TabContents* tab_contents) {
+ return tab_contents->controller()->session_id().id();
+}
+
+int ExtensionTabUtil::GetWindowIdOfTab(const TabContents* tab_contents) {
+ return tab_contents->controller()->window_id().id();
+}
+
bool GetTabsForWindowFunction::RunImpl() {
if (!args_->IsType(Value::TYPE_NULL))
return false;
@@ -198,9 +206,9 @@ static DictionaryValue* CreateTabValue(TabStripModel* tab_strip,
DCHECK(controller); // TODO(aa): Is this a valid assumption?
DictionaryValue* result = new DictionaryValue();
- result->SetInteger(L"id", controller->session_id().id());
+ result->SetInteger(L"id", ExtensionTabUtil::GetTabId(contents));
result->SetInteger(L"index", tab_index);
- result->SetInteger(L"windowId", controller->window_id().id());
+ result->SetInteger(L"windowId", ExtensionTabUtil::GetWindowIdOfTab(contents));
result->SetString(L"url", contents->GetURL().spec());
result->SetString(L"title", UTF16ToWide(contents->GetTitle()));
result->SetBoolean(L"selected", tab_index == tab_strip->selected_index());
diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h
index c358529..3aa4520 100644
--- a/chrome/browser/extensions/extension_tabs_module.h
+++ b/chrome/browser/extensions/extension_tabs_module.h
@@ -7,6 +7,14 @@
#include "chrome/browser/extensions/extension_function.h"
+class TabContents;
+
+class ExtensionTabUtil {
+ public:
+ static int GetTabId(const TabContents* tab_contents);
+ static int GetWindowIdOfTab(const TabContents* tab_contents);
+};
+
class GetTabsForWindowFunction : public SyncExtensionFunction {
virtual bool RunImpl();
};
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 942d23c..ecc69a1 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -14,6 +14,7 @@
#include "base/values.h"
#include "net/base/file_stream.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/extensions/extension_view.h"
@@ -85,6 +86,9 @@ ExtensionsService::~ExtensionsService() {
}
bool ExtensionsService::Init() {
+ // Start up the extension event routers.
+ ExtensionBrowserEventRouter::GetInstance()->Init();
+
#if defined(OS_WIN)
// TODO(port): ExtensionsServiceBackend::CheckForExternalUpdates depends on
// the Windows registry.