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(); |
} |