Chromium Code Reviews| Index: chrome/browser/extensions/active_tab_permission_granter.cc |
| diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc |
| index 4e7383864a1e63706427d5b868767a1dc8504a9e..d1ef903bb6c49c7d1ebaac871fd29c223406a143 100644 |
| --- a/chrome/browser/extensions/active_tab_permission_granter.cc |
| +++ b/chrome/browser/extensions/active_tab_permission_granter.cc |
| @@ -8,9 +8,11 @@ |
| #include "chrome/browser/profiles/profile.h" |
| #include "content/public/browser/navigation_details.h" |
| #include "content/public/browser/navigation_entry.h" |
| +#include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "extensions/browser/extension_registry.h" |
| +#include "extensions/browser/process_manager.h" |
| #include "extensions/common/extension_messages.h" |
| #include "extensions/common/feature_switch.h" |
| #include "extensions/common/permissions/permission_set.h" |
| @@ -18,16 +20,59 @@ |
| #include "extensions/common/user_script.h" |
| #include "url/gurl.h" |
| -using content::RenderProcessHost; |
| -using content::WebContentsObserver; |
| - |
| namespace extensions { |
| +namespace { |
| + |
| +using CreateMessageFunction = base::Callback<IPC::Message*(bool)>; |
| + |
| +// Creates a new IPC message for updating tab-specific permissions. |
| +IPC::Message* CreateUpdateMessage(const GURL& visible_url, |
| + const std::string& extension_id, |
| + const URLPatternSet& new_hosts, |
| + int tab_id, |
| + bool update_whitelist) { |
| + return new ExtensionMsg_UpdateTabSpecificPermissions( |
| + visible_url, extension_id, new_hosts, update_whitelist, tab_id); |
| +} |
| + |
| +// Creates a new IPC message for clearing tab-specific permissions. |
| +IPC::Message* CreateClearMessage(const std::vector<std::string>& ids, |
| + int tab_id, |
| + bool update_whitelist) { |
| + return new ExtensionMsg_ClearTabSpecificPermissions( |
| + ids, update_whitelist, tab_id); |
| +} |
| + |
| +// Sends a message exactly once to each render process host owning one of the |
| +// given |view_hosts|. If |tab_process| does not own one of the |view_hosts|, |
| +// also sends a message to the tab process. |
|
not at google - send to devlin
2015/02/05 00:16:13
So, you could replace the second sentence of this
Devlin
2015/02/05 19:54:49
Done.
|
| +void SendMessageToProcesses( |
| + const std::set<content::RenderViewHost*>& view_hosts, |
| + content::RenderProcessHost* tab_process, |
| + const CreateMessageFunction& create_message) { |
| + std::set<content::RenderProcessHost*> sent_to_hosts; |
| + for (content::RenderViewHost* view_host : view_hosts) { |
| + content::RenderProcessHost* process_host = view_host->GetProcess(); |
| + if (sent_to_hosts.count(process_host) == 0) { |
| + // Extension processes have to update the origin whitelists. |
| + process_host->Send(create_message.Run(true)); |
| + sent_to_hosts.insert(view_host->GetProcess()); |
| + } |
| + } |
| + // If the tab wasn't one of those processes already updated (it likely |
| + // wasn't), update it. Tabs don't need to update the origin whitelist. |
| + if (sent_to_hosts.count(tab_process) == 0) |
| + tab_process->Send(create_message.Run(false)); |
| +} |
| + |
| +} // namespace |
| + |
| ActiveTabPermissionGranter::ActiveTabPermissionGranter( |
| content::WebContents* web_contents, |
| int tab_id, |
| Profile* profile) |
| - : WebContentsObserver(web_contents), |
| + : content::WebContentsObserver(web_contents), |
| tab_id_(tab_id), |
| extension_registry_observer_(this) { |
| extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); |
| @@ -66,13 +111,20 @@ void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { |
| const content::NavigationEntry* navigation_entry = |
| web_contents()->GetController().GetVisibleEntry(); |
| if (navigation_entry) { |
| - content::RenderViewHost* render_view_host = |
| - web_contents()->GetRenderViewHost(); |
| - render_view_host->Send(new ExtensionMsg_UpdateTabSpecificPermissions( |
| - render_view_host->GetRoutingID(), |
| - navigation_entry->GetURL(), |
| - extension->id(), |
| - new_hosts)); |
| + // We update all extension render views with the new tab permissions, and |
| + // also the tab itself. |
| + CreateMessageFunction create_message = |
|
not at google - send to devlin
2015/02/05 00:16:13
call this |update_message|, and below |clear_messa
Devlin
2015/02/05 19:54:50
Done.
|
| + base::Bind(&CreateUpdateMessage, |
| + navigation_entry->GetURL(), |
| + extension->id(), |
| + new_hosts, |
| + tab_id_); |
| + SendMessageToProcesses( |
| + ProcessManager::Get(web_contents()->GetBrowserContext())-> |
| + GetRenderViewHostsForExtension(extension->id()), |
| + web_contents()->GetRenderProcessHost(), |
| + create_message); |
| + |
| // If more things ever need to know about this, we should consider making |
| // an observer class. |
| // It's important that this comes after the IPC is sent to the renderer, |
| @@ -128,18 +180,24 @@ void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() { |
| if (granted_extensions_.is_empty()) |
| return; |
| + std::set<content::RenderViewHost*> view_hosts; |
| std::vector<std::string> extension_ids; |
| - |
| - for (ExtensionSet::const_iterator it = granted_extensions_.begin(); |
| - it != granted_extensions_.end(); ++it) { |
| - it->get()->permissions_data()->ClearTabSpecificPermissions(tab_id_); |
| - extension_ids.push_back((*it)->id()); |
| + ProcessManager* process_manager = |
| + ProcessManager::Get(web_contents()->GetBrowserContext()); |
| + for (const scoped_refptr<const Extension>& extension : granted_extensions_) { |
| + extension->permissions_data()->ClearTabSpecificPermissions(tab_id_); |
| + extension_ids.push_back(extension->id()); |
| + std::set<content::RenderViewHost*> extension_view_hosts = |
| + process_manager->GetRenderViewHostsForExtension(extension->id()); |
| + view_hosts.insert(extension_view_hosts.begin(), extension_view_hosts.end()); |
| } |
| - content::RenderViewHost* render_view_host = |
| - web_contents()->GetRenderViewHost(); |
| - render_view_host->Send(new ExtensionMsg_ClearTabSpecificPermissions( |
| - render_view_host->GetRoutingID(), extension_ids)); |
| + CreateMessageFunction create_message = |
| + base::Bind(&CreateClearMessage, extension_ids, tab_id_); |
| + SendMessageToProcesses(view_hosts, |
| + web_contents()->GetRenderProcessHost(), |
| + create_message); |
| + |
| granted_extensions_.Clear(); |
| } |