summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 23:24:16 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 23:24:16 +0000
commita7ab1b782edde4b8558ccba857ea64cb1e8e8d1c (patch)
treebe43e81cd80302d91ed9d0c9ddc4079f0e557b5a /chrome/renderer
parent3a8d2de3be5629f532f4b26a4ddb7c0961cb25d7 (diff)
downloadchromium_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.h4
-rw-r--r--chrome/renderer/extensions/event_bindings.cc65
-rw-r--r--chrome/renderer/extensions/event_bindings.h6
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc25
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.h9
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.cc8
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.h6
-rw-r--r--chrome/renderer/render_thread.cc14
-rw-r--r--chrome/renderer/render_thread.h8
-rw-r--r--chrome/renderer/render_view.cc6
-rw-r--r--chrome/renderer/render_view.h4
-rw-r--r--chrome/renderer/resources/event_bindings.js4
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js9
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);
};