| Index: chrome/renderer/extensions/extension_dispatcher.cc
|
| diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc
|
| index 8226de81f55566ed5a7a4b22761903b17b629b15..f385afbb955dc9bca8fd08790c72dd8d9e77cfd2 100644
|
| --- a/chrome/renderer/extensions/extension_dispatcher.cc
|
| +++ b/chrome/renderer/extensions/extension_dispatcher.cc
|
| @@ -40,6 +40,7 @@
|
| #include "chrome/renderer/extensions/page_capture_custom_bindings.h"
|
| #include "chrome/renderer/extensions/send_request_natives.h"
|
| #include "chrome/renderer/extensions/set_icon_natives.h"
|
| +#include "chrome/renderer/extensions/tab_finder.h"
|
| #include "chrome/renderer/extensions/tabs_custom_bindings.h"
|
| #include "chrome/renderer/extensions/tts_custom_bindings.h"
|
| #include "chrome/renderer/extensions/user_script_slave.h"
|
| @@ -72,6 +73,7 @@ using WebKit::WebString;
|
| using WebKit::WebVector;
|
| using WebKit::WebView;
|
| using content::RenderThread;
|
| +using content::RenderView;
|
| using extensions::ApiDefinitionsNatives;
|
| using extensions::AppWindowCustomBindings;
|
| using extensions::ContextMenusCustomBindings;
|
| @@ -91,6 +93,7 @@ using extensions::PageCaptureCustomBindings;
|
| using extensions::SendRequestNatives;
|
| using extensions::SetIconNatives;
|
| using extensions::TTSCustomBindings;
|
| +using extensions::TabFinder;
|
| using extensions::TabsCustomBindings;
|
| using extensions::UpdatedExtensionPermissionsInfo;
|
| using extensions::WebRequestCustomBindings;
|
| @@ -153,7 +156,7 @@ class LazyBackgroundPageNativeHandler : public ChromeV8Extension {
|
| extension_dispatcher()->v8_context_set().GetCurrent();
|
| if (!context)
|
| return v8::Undefined();
|
| - content::RenderView* render_view = context->GetRenderView();
|
| + RenderView* render_view = context->GetRenderView();
|
| if (IsContextLazyBackgroundPage(render_view, context->extension())) {
|
| render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount(
|
| render_view->GetRoutingID()));
|
| @@ -166,7 +169,7 @@ class LazyBackgroundPageNativeHandler : public ChromeV8Extension {
|
| extension_dispatcher()->v8_context_set().GetCurrent();
|
| if (!context)
|
| return v8::Undefined();
|
| - content::RenderView* render_view = context->GetRenderView();
|
| + RenderView* render_view = context->GetRenderView();
|
| if (IsContextLazyBackgroundPage(render_view, context->extension())) {
|
| render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount(
|
| render_view->GetRoutingID()));
|
| @@ -175,7 +178,7 @@ class LazyBackgroundPageNativeHandler : public ChromeV8Extension {
|
| }
|
|
|
| private:
|
| - bool IsContextLazyBackgroundPage(content::RenderView* render_view,
|
| + bool IsContextLazyBackgroundPage(RenderView* render_view,
|
| const Extension* extension) {
|
| if (!render_view)
|
| return false;
|
| @@ -265,6 +268,10 @@ bool ExtensionDispatcher::OnControlMessageReceived(
|
| OnSetScriptingWhitelist)
|
| IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension)
|
| IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions)
|
| + IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabSpecificPermissions,
|
| + OnSetTabSpecificPermissions)
|
| + IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions,
|
| + OnClearTabSpecificPermissions)
|
| IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
|
| IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI)
|
| IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldUnload, OnShouldUnload)
|
| @@ -346,7 +353,7 @@ void ExtensionDispatcher::OnMessageInvoke(const std::string& extension_id,
|
| const Extension* extension = extensions_.GetByID(extension_id);
|
| if (extension && extension->has_lazy_background_page() &&
|
| function_name == kEventDispatchFunction) {
|
| - content::RenderView* background_view =
|
| + RenderView* background_view =
|
| ExtensionHelper::GetBackgroundPage(extension_id);
|
| if (background_view) {
|
| background_view->Send(new ExtensionHostMsg_EventAck(
|
| @@ -776,12 +783,13 @@ void ExtensionDispatcher::InitOriginPermissions(const Extension* extension) {
|
| false);
|
| }
|
|
|
| - UpdateOriginPermissions(UpdatedExtensionPermissionsInfo::ADDED,
|
| - extension,
|
| - extension->GetActivePermissions()->explicit_hosts());
|
| + AddOrRemoveOriginPermissions(
|
| + UpdatedExtensionPermissionsInfo::ADDED,
|
| + extension,
|
| + *extension->GetActiveHostPermissionsForAllTabs());
|
| }
|
|
|
| -void ExtensionDispatcher::UpdateOriginPermissions(
|
| +void ExtensionDispatcher::AddOrRemoveOriginPermissions(
|
| UpdatedExtensionPermissionsInfo::Reason reason,
|
| const Extension* extension,
|
| const URLPatternSet& origins) {
|
| @@ -817,6 +825,7 @@ void ExtensionDispatcher::OnUpdatePermissions(
|
| if (!extension)
|
| return;
|
|
|
| + // General permissions.
|
| scoped_refptr<const ExtensionPermissionSet> delta =
|
| new ExtensionPermissionSet(apis, explicit_hosts, scriptable_hosts);
|
| scoped_refptr<const ExtensionPermissionSet> old_active =
|
| @@ -825,15 +834,102 @@ void ExtensionDispatcher::OnUpdatePermissions(
|
| static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id);
|
|
|
| const ExtensionPermissionSet* new_active = NULL;
|
| - if (reason == UpdatedExtensionPermissionsInfo::ADDED) {
|
| - new_active = ExtensionPermissionSet::CreateUnion(old_active, delta);
|
| - } else {
|
| - CHECK_EQ(UpdatedExtensionPermissionsInfo::REMOVED, reason);
|
| - new_active = ExtensionPermissionSet::CreateDifference(old_active, delta);
|
| + switch (reason) {
|
| + case UpdatedExtensionPermissionsInfo::ADDED:
|
| + new_active = ExtensionPermissionSet::CreateUnion(old_active, delta);
|
| + break;
|
| + case UpdatedExtensionPermissionsInfo::REMOVED:
|
| + new_active = ExtensionPermissionSet::CreateDifference(old_active, delta);
|
| + break;
|
| }
|
|
|
| + URLPatternSet active_hosts_before =
|
| + *extension->GetActiveHostPermissionsForAllTabs();
|
| +
|
| extension->SetActivePermissions(new_active);
|
| - UpdateOriginPermissions(reason, extension, explicit_hosts);
|
| +
|
| + // Host permissions. These are different from the general permissions because
|
| + // they need to take into account the additional host permissions granted via
|
| + // the activeTab permission for various tabs.
|
| + URLPatternSet added_or_removed;
|
| + switch (reason) {
|
| + case UpdatedExtensionPermissionsInfo::ADDED:
|
| + URLPatternSet::CreateDifference(
|
| + *extension->GetActiveHostPermissionsForAllTabs(),
|
| + active_hosts_before,
|
| + &added_or_removed);
|
| + break;
|
| + case UpdatedExtensionPermissionsInfo::REMOVED:
|
| + URLPatternSet::CreateDifference(
|
| + active_hosts_before,
|
| + *extension->GetActiveHostPermissionsForAllTabs(),
|
| + &added_or_removed);
|
| + break;
|
| + }
|
| +
|
| + AddOrRemoveOriginPermissions(reason, extension, added_or_removed);
|
| +}
|
| +
|
| +void ExtensionDispatcher::OnSetTabSpecificPermissions(
|
| + int page_id,
|
| + int tab_id,
|
| + const std::string& extension_id,
|
| + const URLPatternSet& origin_set) {
|
| + // If this renderer contains the target tab then check against page_id to
|
| + // avoid race conditions. The target tab is a more sensitive target since it
|
| + // has the opportunity to block executeScript calls. It would be nice to also
|
| + // check it on other renderers, but this obviously isn't possible.
|
| + RenderView* view = TabFinder::Find(tab_id);
|
| + if (view && view->GetPageId() != page_id) {
|
| + LOG(WARNING) <<
|
| + "Wrong page ID, wanted " << page_id << " but was " << view->GetPageId();
|
| + return;
|
| + }
|
| +
|
| + const Extension* extension = extensions_.GetByID(extension_id);
|
| + if (!extension)
|
| + return;
|
| +
|
| + URLPatternSet before = *extension->GetActiveHostPermissionsForAllTabs();
|
| +
|
| + extension->SetTabSpecificHostPermissions(tab_id, origin_set);
|
| +
|
| + // The origin permissions for XHR include the the union of host permissions
|
| + // for all tabs, granted via the activeTab permission.
|
| + URLPatternSet added;
|
| + URLPatternSet::CreateDifference(
|
| + *extension->GetActiveHostPermissionsForAllTabs(),
|
| + before,
|
| + &added);
|
| + AddOrRemoveOriginPermissions(UpdatedExtensionPermissionsInfo::ADDED,
|
| + extension,
|
| + added);
|
| +}
|
| +
|
| +void ExtensionDispatcher::OnClearTabSpecificPermissions(
|
| + int tab_id,
|
| + const std::vector<std::string>& extension_ids) {
|
| + for (std::vector<std::string>::const_iterator it = extension_ids.begin();
|
| + it != extension_ids.end(); ++it) {
|
| + const Extension* extension = extensions_.GetByID(*it);
|
| + if (!extension)
|
| + continue;
|
| +
|
| + URLPatternSet before = *extension->GetActiveHostPermissionsForAllTabs();
|
| +
|
| + extension->ClearTabSpecificHostPermissions(tab_id);
|
| +
|
| + // The origin permissions for XHR include the the union of host permissions
|
| + // for all tabs, granted via the activeTab permission.
|
| + URLPatternSet removed;
|
| + URLPatternSet::CreateDifference(
|
| + before,
|
| + *extension->GetActiveHostPermissionsForAllTabs(),
|
| + &removed);
|
| + AddOrRemoveOriginPermissions(UpdatedExtensionPermissionsInfo::REMOVED,
|
| + extension,
|
| + removed);
|
| + }
|
| }
|
|
|
| void ExtensionDispatcher::OnUpdateUserScripts(
|
|
|