diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-19 05:09:45 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-19 05:09:45 +0000 |
commit | 7df2dce0eff8466ba16f2b8f0773269ecdd1a3ae (patch) | |
tree | 72771d71b141715469af8c330d0075513971ba95 | |
parent | 934e3459aba8c65ec6a3b69768a8941e99553f36 (diff) | |
download | chromium_src-7df2dce0eff8466ba16f2b8f0773269ecdd1a3ae.zip chromium_src-7df2dce0eff8466ba16f2b8f0773269ecdd1a3ae.tar.gz chromium_src-7df2dce0eff8466ba16f2b8f0773269ecdd1a3ae.tar.bz2 |
Populate ContextInfo::extension_id for all extension-related
contexts. This is going to be used in a subsequent change to
unify the way that renderer_extension_bindings and
extension_process_bindings are initialized. Also remove
ContextInfo::parent_frame since it was only used in one place
and easily derived.
Review URL: http://codereview.chromium.org/7655031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97425 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_message_service.cc | 7 | ||||
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.cc | 19 | ||||
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.h | 22 | ||||
-rw-r--r-- | chrome/renderer/extensions/event_bindings.cc | 72 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_dispatcher.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/extensions/user_script_idle_scheduler.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/extensions/user_script_slave.cc | 19 | ||||
-rw-r--r-- | chrome/renderer/extensions/user_script_slave.h | 13 |
8 files changed, 77 insertions, 80 deletions
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 58400e5..57df12a 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -70,8 +70,11 @@ static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, args.Set(3, Value::CreateStringValue(source_extension_id)); args.Set(4, Value::CreateStringValue(target_extension_id)); CHECK(port.sender); - port.sender->Send(new ExtensionMsg_MessageInvoke(port.routing_id, - "", ExtensionMessageService::kDispatchOnConnect, args, GURL())); + port.sender->Send( + new ExtensionMsg_MessageInvoke( + port.routing_id, + target_extension_id, + ExtensionMessageService::kDispatchOnConnect, args, GURL())); } static void DispatchOnDisconnect( diff --git a/chrome/renderer/extensions/bindings_utils.cc b/chrome/renderer/extensions/bindings_utils.cc index 21663e4..0ed332c 100644 --- a/chrome/renderer/extensions/bindings_utils.cc +++ b/chrome/renderer/extensions/bindings_utils.cc @@ -130,12 +130,10 @@ v8::Handle<v8::Value> ExtensionBase::Print(const v8::Arguments& args) { ContextInfo::ContextInfo(v8::Persistent<v8::Context> context, const std::string& extension_id, - WebKit::WebFrame* parent_frame, - RenderView* render_view) + WebFrame* frame) : context(context), extension_id(extension_id), - parent_frame(parent_frame), - render_view(render_view), + frame(frame), num_connected_events(0) { } @@ -145,19 +143,6 @@ ContextList& GetContexts() { return g_singleton_data.Get().contexts; } -ContextList GetContextsForExtension(const std::string& extension_id) { - ContextList& all_contexts = GetContexts(); - ContextList contexts; - - for (ContextList::iterator it = all_contexts.begin(); - it != all_contexts.end(); ++it) { - if ((*it)->extension_id == extension_id) - contexts.push_back(*it); - } - - return contexts; -} - ContextInfo* GetInfoForCurrentContext() { // This can happen in testing scenarios and v8::Context::GetCurrent() crashes // if there is no JavaScript currently running. diff --git a/chrome/renderer/extensions/bindings_utils.h b/chrome/renderer/extensions/bindings_utils.h index fc1e178..1246a1af 100644 --- a/chrome/renderer/extensions/bindings_utils.h +++ b/chrome/renderer/extensions/bindings_utils.h @@ -78,24 +78,23 @@ class ExtensionBase : public v8::Extension { const char* GetStringResource(int resource_id); -// Contains information about a single javascript context. +// Contains information about a JavaScript context that is hosting extension +// bindings. struct ContextInfo { ContextInfo(v8::Persistent<v8::Context> context, const std::string& extension_id, - WebKit::WebFrame* parent_frame, - RenderView* render_view); + WebKit::WebFrame* frame); ~ContextInfo(); v8::Persistent<v8::Context> context; - std::string extension_id; // empty if the context is not an extension - // If this context is a content script, parent will be the frame that it - // was injected in. This is NULL if the context is not a content script. - WebKit::WebFrame* parent_frame; + // The extension ID this context is associated with. + std::string extension_id; - // The RenderView that this context belongs to. This is not guaranteed to be - // a valid pointer, and is used for comparisons only. Do not dereference. - RenderView* render_view; + // The frame the context is associated with. We can't always get this from + // WebFrame::frameForContext() (in particular as the the frame is navigating + // or being destroyed). + WebKit::WebFrame* frame; // A count of the number of events that are listening in this context. When // this is zero, |context| will be a weak handle. @@ -108,9 +107,6 @@ typedef std::list< linked_ptr<ContextInfo> > ContextList; // on iterators remaining valid between calls to javascript. ContextList& GetContexts(); -// Returns a (copied) list of contexts that have the given extension_id. -ContextList GetContextsForExtension(const std::string& extension_id); - // Returns the ContextInfo item that has the given context. ContextList::iterator FindContext(v8::Handle<v8::Context> context); diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 8de2cef..fbcece5 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -17,6 +17,7 @@ #include "chrome/renderer/extensions/extension_dispatcher.h" #include "chrome/renderer/extensions/extension_process_bindings.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" +#include "chrome/renderer/extensions/user_script_slave.h" #include "content/renderer/render_thread.h" #include "content/renderer/render_view.h" #include "content/renderer/v8_value_converter.h" @@ -298,48 +299,45 @@ void EventBindings::HandleContextCreated( v8::HandleScope handle_scope; ContextList& contexts = GetContexts(); - // Figure out the frame's URL. If the frame is loading, use its provisional - // URL, since we get this notification before commit. - WebDataSource* ds = frame->provisionalDataSource(); - if (!ds) - ds = frame->dataSource(); - GURL url = ds->request().url(); - const ExtensionSet* extensions = extension_dispatcher->extensions(); - std::string extension_id = extensions->GetIdByURL(url); - - if (!extensions->ExtensionBindingsAllowed(url) && - !content_script) { - // This context is a regular non-extension web page or an unprivileged - // chrome app. Ignore it. We only care about content scripts and extension - // frames. - // (Unless we're in unit tests, in which case we don't care what the URL - // is). - if (!in_unit_tests) - return; - - // For tests, we want the dispatchOnLoad to actually setup our bindings, - // so we give a fake extension id; - extension_id = kTestingExtensionId; - } - v8::Persistent<v8::Context> persistent_context = v8::Persistent<v8::Context>::New(context); - WebFrame* parent_frame = NULL; + + std::string extension_id; if (content_script) { - parent_frame = frame; // Content script contexts can get GCed before their frame goes away, so // set up a GC callback. persistent_context.MakeWeak(NULL, &ContextWeakReferenceCallback); + extension_id = + extension_dispatcher->user_script_slave()-> + GetExtensionIdForIsolatedWorld(isolated_world_id); + } else { + // Figure out the frame's URL. If the frame is loading, use its provisional + // URL, since we get this notification before commit. + WebDataSource* ds = frame->provisionalDataSource(); + if (!ds) + ds = frame->dataSource(); + GURL url = ds->request().url(); + const ExtensionSet* extensions = extension_dispatcher->extensions(); + extension_id = extensions->GetIdByURL(url); + + if (!extensions->ExtensionBindingsAllowed(url)) { + // This context is a regular non-extension web page or an unprivileged + // chrome app. Ignore it. We only care about content scripts and extension + // frames. + // (Unless we're in unit tests, in which case we don't care what the URL + // is). + if (!in_unit_tests) + return; + + // For tests, we want the dispatchOnLoad to actually setup our bindings, + // so we give a fake extension id; + extension_id = kTestingExtensionId; + } } - RenderView* render_view = NULL; - if (frame->view()) - render_view = RenderView::FromWebView(frame->view()); - contexts.push_back(linked_ptr<ContextInfo>( - new ContextInfo(persistent_context, extension_id, parent_frame, - render_view))); + new ContextInfo(persistent_context, extension_id, frame))); // Content scripts get initialized in user_script_slave.cc. if (!content_script) { @@ -366,7 +364,7 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) { // itself might not be registered, but can still be a parent frame. for (ContextList::iterator it = GetContexts().begin(); it != GetContexts().end(); ) { - if ((*it)->parent_frame == frame) { + if ((*it)->frame == frame) { UnregisterContext(it, false); // UnregisterContext will remove |it| from the list, but may also // modify the rest of the list as a result of calling into javascript. @@ -393,8 +391,12 @@ void EventBindings::CallFunction(const std::string& extension_id, V8ValueConverter converter; for (ContextList::iterator it = contexts.begin(); it != contexts.end(); ++it) { - if (render_view && render_view != (*it)->render_view) - continue; + if (render_view) { + RenderView* context_render_view = + RenderView::FromWebView((*it)->frame->view()); + if (render_view != context_render_view) + continue; + } if (!extension_id.empty() && extension_id != (*it)->extension_id) continue; diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc index 791ae3a..a21cabf 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -164,7 +164,7 @@ void ExtensionDispatcher::OnUnloaded(const std::string& id) { // If the extension is later reloaded with a different set of permissions, // we'd like it to get a new isolated world ID, so that it can pick up the // changed origin whitelist. - UserScriptSlave::RemoveIsolatedWorld(id); + user_script_slave_->RemoveIsolatedWorld(id); } void ExtensionDispatcher::OnSetScriptingWhitelist( diff --git a/chrome/renderer/extensions/user_script_idle_scheduler.cc b/chrome/renderer/extensions/user_script_idle_scheduler.cc index dc34c4e..2719ce3 100644 --- a/chrome/renderer/extensions/user_script_idle_scheduler.cc +++ b/chrome/renderer/extensions/user_script_idle_scheduler.cc @@ -148,7 +148,8 @@ void UserScriptIdleScheduler::ExecuteCodeImpl( sources.push_back(source); UserScriptSlave::InsertInitExtensionCode(&sources, params.extension_id); frame->executeScriptInIsolatedWorld( - UserScriptSlave::GetIsolatedWorldId(extension, frame), + extension_dispatcher_->user_script_slave()-> + GetIsolatedWorldIdForExtension(extension, frame), &sources.front(), sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS); } } else { diff --git a/chrome/renderer/extensions/user_script_slave.cc b/chrome/renderer/extensions/user_script_slave.cc index ec2de6e..baab395 100644 --- a/chrome/renderer/extensions/user_script_slave.cc +++ b/chrome/renderer/extensions/user_script_slave.cc @@ -49,11 +49,7 @@ static const char kUserScriptTail[] = "\n})(window);"; static const char kInitExtension[] = "if (chrome.initExtension) chrome.initExtension('%s', true, %s);"; -// static -UserScriptSlave::IsolatedWorldMap UserScriptSlave::isolated_world_ids_; - -// static -int UserScriptSlave::GetIsolatedWorldId( +int UserScriptSlave::GetIsolatedWorldIdForExtension( const Extension* extension, WebFrame* frame) { static int g_next_isolated_world_id = 1; @@ -81,6 +77,16 @@ int UserScriptSlave::GetIsolatedWorldId( return new_id; } +std::string UserScriptSlave::GetExtensionIdForIsolatedWorld( + int isolated_world_id) { + for (IsolatedWorldMap::iterator iter = isolated_world_ids_.begin(); + iter != isolated_world_ids_.end(); ++iter) { + if (iter->second == isolated_world_id) + return iter->first; + } + return ""; +} + // static void UserScriptSlave::InitializeIsolatedWorld( int isolated_world_id, @@ -107,7 +113,6 @@ void UserScriptSlave::InitializeIsolatedWorld( } } -// static void UserScriptSlave::RemoveIsolatedWorld(const std::string& extension_id) { isolated_world_ids_.erase(extension_id); } @@ -315,7 +320,7 @@ void UserScriptSlave::InjectScripts(WebFrame* frame, // ID. if (!script->extension_id().empty()) { InsertInitExtensionCode(&sources, script->extension_id()); - isolated_world_id = GetIsolatedWorldId(extension, frame); + isolated_world_id = GetIsolatedWorldIdForExtension(extension, frame); } PerfTimer exec_timer; diff --git a/chrome/renderer/extensions/user_script_slave.h b/chrome/renderer/extensions/user_script_slave.h index 9e73be7..e92b40a 100644 --- a/chrome/renderer/extensions/user_script_slave.h +++ b/chrome/renderer/extensions/user_script_slave.h @@ -47,10 +47,15 @@ class UserScriptSlave { // Gets the isolated world ID to use for the given |extension| in the given // |frame|. If no isolated world has been created for that extension, // one will be created and initialized. - static int GetIsolatedWorldId(const Extension* extension, - WebKit::WebFrame* frame); + int GetIsolatedWorldIdForExtension(const Extension* extension, + WebKit::WebFrame* frame); - static void RemoveIsolatedWorld(const std::string& extension_id); + // Gets the id of the extension running in a given isolated world. If no such + // isolated world exists, or no extension is running in it, returns empty + // string. + std::string GetExtensionIdForIsolatedWorld(int isolated_world_id); + + void RemoveIsolatedWorld(const std::string& extension_id); static void InsertInitExtensionCode(std::vector<WebScriptSource>* sources, const std::string& extension_id); @@ -72,7 +77,7 @@ class UserScriptSlave { const ExtensionSet* extensions_; typedef std::map<std::string, int> IsolatedWorldMap; - static IsolatedWorldMap isolated_world_ids_; + IsolatedWorldMap isolated_world_ids_; DISALLOW_COPY_AND_ASSIGN(UserScriptSlave); }; |