diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 23:24:16 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 23:24:16 +0000 |
commit | a7ab1b782edde4b8558ccba857ea64cb1e8e8d1c (patch) | |
tree | be43e81cd80302d91ed9d0c9ddc4079f0e557b5a /chrome/renderer | |
parent | 3a8d2de3be5629f532f4b26a4ddb7c0961cb25d7 (diff) | |
download | chromium_src-a7ab1b782edde4b8558ccba857ea64cb1e8e8d1c.zip chromium_src-a7ab1b782edde4b8558ccba857ea64cb1e8e8d1c.tar.gz chromium_src-a7ab1b782edde4b8558ccba857ea64cb1e8e8d1c.tar.bz2 |
Part 2 of extension event refactor.
Extension events are no longer broadcast to an entire process. They are
filtered by extension. This allows me to move the cross-incognito check into
the browser, and remove a bunch of cruft associated with that.
BUG=58214
TEST=no functional change
Review URL: http://codereview.chromium.org/3775015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63448 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.h | 4 | ||||
-rw-r--r-- | chrome/renderer/extensions/event_bindings.cc | 65 | ||||
-rw-r--r-- | chrome/renderer/extensions/event_bindings.h | 6 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.cc | 25 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.h | 9 | ||||
-rw-r--r-- | chrome/renderer/extensions/renderer_extension_bindings.cc | 8 | ||||
-rw-r--r-- | chrome/renderer/extensions/renderer_extension_bindings.h | 6 | ||||
-rw-r--r-- | chrome/renderer/render_thread.cc | 14 | ||||
-rw-r--r-- | chrome/renderer/render_thread.h | 8 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 4 | ||||
-rw-r--r-- | chrome/renderer/resources/event_bindings.js | 4 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 9 |
13 files changed, 56 insertions, 112 deletions
diff --git a/chrome/renderer/extensions/bindings_utils.h b/chrome/renderer/extensions/bindings_utils.h index 9432f91..b269ad1 100644 --- a/chrome/renderer/extensions/bindings_utils.h +++ b/chrome/renderer/extensions/bindings_utils.h @@ -78,6 +78,10 @@ struct ContextInfo { // a valid pointer, and is used for comparisons only. Do not dereference. RenderView* render_view; + // A map of event names to the number of listeners for that event. We notify + // the browser about event listeners when we transition between 0 and 1. + std::map<std::string, int> listener_counts; + // A count of the number of events that are listening in this context. When // this is zero, |context| will be a weak handle. int num_connected_events; diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 9c3f421..a451953 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -51,18 +51,6 @@ static bool in_unit_tests = false; // are disabled. static bool bindings_registered = false; -struct ExtensionData { - std::map<std::string, int> listener_count; -}; -int EventIncrementListenerCount(const std::string& event_name) { - ExtensionData *data = Singleton<ExtensionData>::get(); - return ++(data->listener_count[event_name]); -} -int EventDecrementListenerCount(const std::string& event_name) { - ExtensionData *data = Singleton<ExtensionData>::get(); - return --(data->listener_count[event_name]); -} - class ExtensionImpl : public ExtensionBase { public: ExtensionImpl() @@ -89,25 +77,25 @@ class ExtensionImpl : public ExtensionBase { DCHECK(args[0]->IsString() || args[0]->IsUndefined()); if (args[0]->IsString()) { + ContextInfo* context_info = GetInfoForCurrentContext(); std::string event_name(*v8::String::AsciiValue(args[0])); bool has_permission = ExtensionProcessBindings::CurrentContextHasPermission(event_name); - // Increment the count even if the caller doesn't have permission, so that - // refcounts stay balanced. - if (EventIncrementListenerCount(event_name) == 1 && has_permission) { - EventBindings::GetRenderThread()->Send( - new ViewHostMsg_ExtensionAddListener(event_name)); - } - - ContextInfo* current_context_info = GetInfoForCurrentContext(); - if (++current_context_info->num_connected_events == 1) - current_context_info->context.ClearWeak(); - if (!has_permission) { return ExtensionProcessBindings::ThrowPermissionDeniedException( event_name); } + + if (++context_info->listener_counts[event_name] == 1) { + EventBindings::GetRenderThread()->Send( + new ViewHostMsg_ExtensionAddListener(context_info->extension_id, + event_name)); + } + + if (++context_info->num_connected_events == 1) + context_info->context.ClearWeak(); + } return v8::Undefined(); @@ -119,17 +107,19 @@ class ExtensionImpl : public ExtensionBase { DCHECK(args[0]->IsString() || args[0]->IsUndefined()); if (args[0]->IsString()) { + ContextInfo* context_info = GetInfoForCurrentContext(); + if (!context_info) + return v8::Undefined(); + std::string event_name(*v8::String::AsciiValue(args[0])); - if (EventDecrementListenerCount(event_name) == 0) { + if (--context_info->listener_counts[event_name] == 0) { EventBindings::GetRenderThread()->Send( - new ViewHostMsg_ExtensionRemoveListener(event_name)); + new ViewHostMsg_ExtensionRemoveListener(context_info->extension_id, + event_name)); } - ContextInfo* current_context_info = GetInfoForCurrentContext(); - if (current_context_info && - --current_context_info->num_connected_events == 0) { - current_context_info->context.MakeWeak(NULL, - &ContextWeakReferenceCallback); + if (--context_info->num_connected_events == 0) { + context_info->context.MakeWeak(NULL, &ContextWeakReferenceCallback); } } @@ -140,15 +130,9 @@ class ExtensionImpl : public ExtensionBase { // Returns true if the extension running in the given |context| has sufficient // permissions to access the data. static bool HasSufficientPermissions(ContextInfo* context, - bool cross_incognito, const GURL& event_url) { v8::Context::Scope context_scope(context->context); - bool cross_profile_ok = (!cross_incognito || - ExtensionProcessBindings::AllowCrossIncognito(context->extension_id)); - if (!cross_profile_ok) - return false; - // During unit tests, we might be invoked without a v8 context. In these // cases, we only allow empty event_urls and short-circuit before retrieving // the render view from the current context. @@ -335,10 +319,10 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) { } // static -void EventBindings::CallFunction(const std::string& function_name, +void EventBindings::CallFunction(const std::string& extension_id, + const std::string& function_name, int argc, v8::Handle<v8::Value>* argv, RenderView* render_view, - bool cross_incognito, const GURL& event_url) { // We copy the context list, because calling into javascript may modify it // out from under us. We also guard against deleted contexts by checking if @@ -350,10 +334,13 @@ void EventBindings::CallFunction(const std::string& function_name, if (render_view && render_view != (*it)->render_view) continue; + if (!extension_id.empty() && extension_id != (*it)->extension_id) + continue; + if ((*it)->context.IsEmpty()) continue; - if (!HasSufficientPermissions(it->get(), cross_incognito, event_url)) + if (!HasSufficientPermissions(it->get(), event_url)) continue; v8::Handle<v8::Value> retval = CallFunctionInContext((*it)->context, diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index 788a25c..95b049e 100644 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -41,10 +41,10 @@ class EventBindings { // bindings_utils::CallFunctionInContext for more details. // The called javascript function should not return a value other than // v8::Undefined(). A DCHECK is setup to break if it is otherwise. - static void CallFunction(const std::string& function_name, int argc, - v8::Handle<v8::Value>* argv, + static void CallFunction(const std::string& extension_id, + const std::string& function_name, + int argc, v8::Handle<v8::Value>* argv, RenderView* render_view, - bool cross_incognito, const GURL& event_url); }; diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index fed2fe3..bdbb9aa 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -63,10 +63,6 @@ typedef std::set<std::string> PermissionsList; // A map of extension ID to permissions map. typedef std::map<std::string, PermissionsList> ExtensionPermissionsList; -// A map of extension ID to whether this extension can access data from other -// profiles. -typedef std::map<std::string, bool> CrossIncognitoAccessMap; - const char kExtensionName[] = "chrome/ExtensionProcessBindings"; const char* kExtensionDeps[] = { BaseJsV8Extension::kName, @@ -80,7 +76,6 @@ struct SingletonData { std::set<std::string> function_names_; PageActionIdMap page_action_ids_; ExtensionPermissionsList permissions_; - CrossIncognitoAccessMap cross_incognito_access_map_; }; static std::set<std::string>* GetFunctionNameSet() { @@ -95,10 +90,6 @@ static PermissionsList* GetPermissionsList(const std::string& extension_id) { return &Singleton<SingletonData>()->permissions_[extension_id]; } -static CrossIncognitoAccessMap* GetCrossIncognitoAccessMap() { - return &Singleton<SingletonData>()->cross_incognito_access_map_; -} - static void GetActiveExtensionIDs(std::set<std::string>* extension_ids) { ExtensionPermissionsList& permissions = Singleton<SingletonData>()->permissions_; @@ -581,22 +572,6 @@ void ExtensionProcessBindings::SetFunctionNames( ExtensionImpl::SetFunctionNames(names); } -void ExtensionProcessBindings::SetIncognitoEnabled( - const std::string& extension_id, bool enabled, bool incognito_split_mode) { - // We allow the extension to see events and data from another profile iff it - // uses "spanning" behavior and it has incognito access. "split" mode - // extensions only see events for a matching profile. - (*GetCrossIncognitoAccessMap())[extension_id] = - enabled && !incognito_split_mode; -} - -// static -bool ExtensionProcessBindings::AllowCrossIncognito( - const std::string& extension_id) { - return (!extension_id.empty() && - (*GetCrossIncognitoAccessMap())[extension_id]); -} - // static void ExtensionProcessBindings::HandleResponse(int request_id, bool success, const std::string& response, diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h index 251cdd9..4aa4140 100644 --- a/chrome/renderer/extensions/extension_process_bindings.h +++ b/chrome/renderer/extensions/extension_process_bindings.h @@ -47,15 +47,6 @@ class ExtensionProcessBindings { static void SetHostPermissions(const GURL& extension_url, const std::vector<URLPattern>& permissions); - // Sets whether incognito is enabled for a particular extension. - static void SetIncognitoEnabled(const std::string& extension_id, - bool enabled, - bool incognito_split_mode); - - // Checks whether the given extension can see events/data from another - // profile (normal to incognito or vice versa). - static bool AllowCrossIncognito(const std::string& extension_id); - // Check if the extension in the currently running context has permission to // access the given extension function. Must be called with a valid V8 // context in scope. diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc index 2e21c56..b109390 100644 --- a/chrome/renderer/extensions/renderer_extension_bindings.cc +++ b/chrome/renderer/extensions/renderer_extension_bindings.cc @@ -295,17 +295,17 @@ v8::Extension* RendererExtensionBindings::Get() { return extension; } -void RendererExtensionBindings::Invoke(const std::string& function_name, +void RendererExtensionBindings::Invoke(const std::string& extension_id, + const std::string& function_name, const ListValue& args, RenderView* renderview, - bool cross_incognito, const GURL& event_url) { v8::HandleScope handle_scope; std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args); - EventBindings::CallFunction(function_name, + EventBindings::CallFunction(extension_id, + function_name, argv.size(), &argv[0], renderview, - cross_incognito, event_url); } diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h index 7b4280f..194b0c8 100644 --- a/chrome/renderer/extensions/renderer_extension_bindings.h +++ b/chrome/renderer/extensions/renderer_extension_bindings.h @@ -25,8 +25,10 @@ class RendererExtensionBindings { static v8::Extension* Get(); // Call the given javascript function with the specified arguments. - static void Invoke(const std::string& function_name, const ListValue& args, - RenderView* renderview, bool cross_incognito, + static void Invoke(const std::string& extension_id, + const std::string& function_name, + const ListValue& args, + RenderView* renderview, const GURL& event_url); }; diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index ebb8af7..4ce5f7f 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -551,12 +551,6 @@ void RenderThread::OnExtensionSetHostPermissions( ExtensionProcessBindings::SetHostPermissions(extension_url, permissions); } -void RenderThread::OnExtensionSetIncognitoEnabled( - const std::string& extension_id, bool enabled, bool incognito_split_mode) { - ExtensionProcessBindings::SetIncognitoEnabled(extension_id, enabled, - incognito_split_mode); -} - void RenderThread::OnDOMStorageEvent( const ViewMsg_DOMStorageEvent_Params& params) { if (!dom_storage_event_dispatcher_.get()) @@ -617,8 +611,6 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) { OnExtensionSetAPIPermissions) IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetHostPermissions, OnExtensionSetHostPermissions) - IPC_MESSAGE_HANDLER(ViewMsg_Extension_ExtensionSetIncognitoEnabled, - OnExtensionSetIncognitoEnabled) IPC_MESSAGE_HANDLER(ViewMsg_DOMStorageEvent, OnDOMStorageEvent) #if defined(IPC_MESSAGE_LOG_ENABLED) @@ -974,12 +966,12 @@ void RenderThread::ScheduleIdleHandler(double initial_delay_s) { this, &RenderThread::IdleHandler); } -void RenderThread::OnExtensionMessageInvoke(const std::string& function_name, +void RenderThread::OnExtensionMessageInvoke(const std::string& extension_id, + const std::string& function_name, const ListValue& args, - bool cross_incognito, const GURL& event_url) { RendererExtensionBindings::Invoke( - function_name, args, NULL, cross_incognito, event_url); + extension_id, function_name, args, NULL, event_url); // Reset the idle handler each time there's any activity like event or message // dispatch, for which Invoke is the chokepoint. diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 9f2c4c0..a077c3b 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -267,10 +267,6 @@ class RenderThread : public RenderThreadBase, void OnExtensionSetHostPermissions( const GURL& extension_url, const std::vector<URLPattern>& permissions); - void OnExtensionSetIncognitoEnabled( - const std::string& extension_id, - bool enabled, - bool incognito_split_mode); void OnSetNextPageID(int32 next_page_id); void OnSetIsIncognitoProcess(bool is_incognito_process); void OnSetCSSColors(const std::vector<CSSColors::CSSColorMapping>& colors); @@ -289,9 +285,9 @@ class RenderThread : public RenderThreadBase, void OnGetRendererTcmalloc(); void OnGetV8HeapStats(); - void OnExtensionMessageInvoke(const std::string& function_name, + void OnExtensionMessageInvoke(const std::string& extension_id, + const std::string& function_name, const ListValue& args, - bool cross_incognito, const GURL& event_url); void OnPurgeMemory(); void OnPurgePluginListCache(bool reload_pages); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 7b2e0a0..8c2a984 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -4947,12 +4947,12 @@ void RenderView::OnExtensionResponse(int request_id, request_id, success, response, error); } -void RenderView::OnExtensionMessageInvoke(const std::string& function_name, +void RenderView::OnExtensionMessageInvoke(const std::string& extension_id, + const std::string& function_name, const ListValue& args, - bool cross_incognito, const GURL& event_url) { RendererExtensionBindings::Invoke( - function_name, args, this, cross_incognito, event_url); + extension_id, function_name, args, this, event_url); } // Dump all load time histograms. diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 621a68c..57c26ff 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -811,9 +811,9 @@ class RenderView : public RenderWidget, void OnEnableViewSourceMode(); void OnExecuteCode(const ViewMsg_ExecuteCode_Params& params); void OnExecuteEditCommand(const std::string& name, const std::string& value); - void OnExtensionMessageInvoke(const std::string& function_name, + void OnExtensionMessageInvoke(const std::string& extension_id, + const std::string& function_name, const ListValue& args, - bool cross_incognito, const GURL& event_url); void OnFileChooserResponse(const std::vector<FilePath>& paths); void OnFind(int request_id, const string16&, const WebKit::WebFindOptions&); diff --git a/chrome/renderer/resources/event_bindings.js b/chrome/renderer/resources/event_bindings.js index f2a82d9..2b8cce8 100644 --- a/chrome/renderer/resources/event_bindings.js +++ b/chrome/renderer/resources/event_bindings.js @@ -110,10 +110,10 @@ var chrome = chrome || {}; // Registers a callback to be called when this event is dispatched. chrome.Event.prototype.addListener = function(cb) { - this.listeners_.push(cb); - if (this.listeners_.length == 1) { + if (this.listeners_.length == 0) { this.attach_(); } + this.listeners_.push(cb); }; // Unregisters a callback. diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index 8106782..de00b14 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -238,7 +238,7 @@ var chrome = chrome || {}; function setupPageActionEvents(extensionId) { var pageActions = GetCurrentPageActions(extensionId); - var oldStyleEventName = "pageActions/" + extensionId; + var oldStyleEventName = "pageActions"; // TODO(EXTENSIONS_DEPRECATED): only one page action for (var i = 0; i < pageActions.length; ++i) { // Setup events for each extension_id/page_action_id string we find. @@ -264,7 +264,7 @@ var chrome = chrome || {}; chromeHidden.contextMenus = {}; chromeHidden.contextMenus.nextId = 1; chromeHidden.contextMenus.handlers = {}; - var eventName = "contextMenus/" + extensionId; + var eventName = "contextMenus"; chromeHidden.contextMenus.event = new chrome.Event(eventName); chromeHidden.contextMenus.ensureListenerSetup = function() { if (chromeHidden.contextMenus.listening) { @@ -382,8 +382,6 @@ var chrome = chrome || {}; return; var eventName = apiDef.namespace + "." + eventDef.name; - if (eventDef.perExtensionEvent) - eventName = eventName + "/" + extensionId; module[eventDef.name] = new chrome.Event(eventName, eventDef.parameters); }); @@ -422,8 +420,7 @@ var chrome = chrome || {}; if (connectInfo) { name = connectInfo.name || name; } - var portId = OpenChannelToTab( - tabId, chromeHidden.extensionId, name); + var portId = OpenChannelToTab(tabId, chromeHidden.extensionId, name); return chromeHidden.Port.createPort(portId, name); }; |