OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/active_tab_permission_granter.h" | 5 #include "chrome/browser/extensions/active_tab_permission_granter.h" |
6 | 6 |
7 #include "chrome/browser/extensions/active_script_controller.h" | 7 #include "chrome/browser/extensions/active_script_controller.h" |
8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
9 #include "content/public/browser/navigation_details.h" | 9 #include "content/public/browser/navigation_details.h" |
10 #include "content/public/browser/navigation_entry.h" | 10 #include "content/public/browser/navigation_entry.h" |
| 11 #include "content/public/browser/render_process_host.h" |
11 #include "content/public/browser/render_view_host.h" | 12 #include "content/public/browser/render_view_host.h" |
12 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
13 #include "extensions/browser/extension_registry.h" | 14 #include "extensions/browser/extension_registry.h" |
| 15 #include "extensions/browser/process_manager.h" |
14 #include "extensions/common/extension_messages.h" | 16 #include "extensions/common/extension_messages.h" |
15 #include "extensions/common/feature_switch.h" | 17 #include "extensions/common/feature_switch.h" |
16 #include "extensions/common/permissions/permission_set.h" | 18 #include "extensions/common/permissions/permission_set.h" |
17 #include "extensions/common/permissions/permissions_data.h" | 19 #include "extensions/common/permissions/permissions_data.h" |
18 #include "extensions/common/user_script.h" | 20 #include "extensions/common/user_script.h" |
19 #include "url/gurl.h" | 21 #include "url/gurl.h" |
20 | 22 |
21 using content::RenderProcessHost; | 23 namespace extensions { |
22 using content::WebContentsObserver; | |
23 | 24 |
24 namespace extensions { | 25 namespace { |
| 26 |
| 27 using CreateMessageFunction = base::Callback<IPC::Message*(bool)>; |
| 28 |
| 29 // Creates a new IPC message for updating tab-specific permissions. |
| 30 IPC::Message* CreateUpdateMessage(const GURL& visible_url, |
| 31 const std::string& extension_id, |
| 32 const URLPatternSet& new_hosts, |
| 33 int tab_id, |
| 34 bool update_whitelist) { |
| 35 return new ExtensionMsg_UpdateTabSpecificPermissions( |
| 36 visible_url, extension_id, new_hosts, update_whitelist, tab_id); |
| 37 } |
| 38 |
| 39 // Creates a new IPC message for clearing tab-specific permissions. |
| 40 IPC::Message* CreateClearMessage(const std::vector<std::string>& ids, |
| 41 int tab_id, |
| 42 bool update_whitelist) { |
| 43 return new ExtensionMsg_ClearTabSpecificPermissions( |
| 44 ids, update_whitelist, tab_id); |
| 45 } |
| 46 |
| 47 // Sends a message exactly once to each render process host owning one of the |
| 48 // given |view_hosts| and |tab_process|. If |tab_process| doesn't own any of the |
| 49 // |view_hosts|, it will not be signaled to update its origin whitelist. |
| 50 void SendMessageToProcesses( |
| 51 const std::set<content::RenderViewHost*>& view_hosts, |
| 52 content::RenderProcessHost* tab_process, |
| 53 const CreateMessageFunction& create_message) { |
| 54 std::set<content::RenderProcessHost*> sent_to_hosts; |
| 55 for (content::RenderViewHost* view_host : view_hosts) { |
| 56 content::RenderProcessHost* process_host = view_host->GetProcess(); |
| 57 if (sent_to_hosts.count(process_host) == 0) { |
| 58 // Extension processes have to update the origin whitelists. |
| 59 process_host->Send(create_message.Run(true)); |
| 60 sent_to_hosts.insert(view_host->GetProcess()); |
| 61 } |
| 62 } |
| 63 // If the tab wasn't one of those processes already updated (it likely |
| 64 // wasn't), update it. Tabs don't need to update the origin whitelist. |
| 65 if (sent_to_hosts.count(tab_process) == 0) |
| 66 tab_process->Send(create_message.Run(false)); |
| 67 } |
| 68 |
| 69 } // namespace |
25 | 70 |
26 ActiveTabPermissionGranter::ActiveTabPermissionGranter( | 71 ActiveTabPermissionGranter::ActiveTabPermissionGranter( |
27 content::WebContents* web_contents, | 72 content::WebContents* web_contents, |
28 int tab_id, | 73 int tab_id, |
29 Profile* profile) | 74 Profile* profile) |
30 : WebContentsObserver(web_contents), | 75 : content::WebContentsObserver(web_contents), |
31 tab_id_(tab_id), | 76 tab_id_(tab_id), |
32 extension_registry_observer_(this) { | 77 extension_registry_observer_(this) { |
33 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); | 78 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); |
34 } | 79 } |
35 | 80 |
36 ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {} | 81 ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {} |
37 | 82 |
38 void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { | 83 void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) { |
39 if (granted_extensions_.Contains(extension->id())) | 84 if (granted_extensions_.Contains(extension->id())) |
40 return; | 85 return; |
(...skipping 18 matching lines...) Expand all Loading... |
59 | 104 |
60 if (!new_apis.empty() || !new_hosts.is_empty()) { | 105 if (!new_apis.empty() || !new_hosts.is_empty()) { |
61 granted_extensions_.Insert(extension); | 106 granted_extensions_.Insert(extension); |
62 scoped_refptr<const PermissionSet> new_permissions = | 107 scoped_refptr<const PermissionSet> new_permissions = |
63 new PermissionSet(new_apis, ManifestPermissionSet(), | 108 new PermissionSet(new_apis, ManifestPermissionSet(), |
64 new_hosts, URLPatternSet()); | 109 new_hosts, URLPatternSet()); |
65 permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions); | 110 permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions); |
66 const content::NavigationEntry* navigation_entry = | 111 const content::NavigationEntry* navigation_entry = |
67 web_contents()->GetController().GetVisibleEntry(); | 112 web_contents()->GetController().GetVisibleEntry(); |
68 if (navigation_entry) { | 113 if (navigation_entry) { |
69 content::RenderViewHost* render_view_host = | 114 // We update all extension render views with the new tab permissions, and |
70 web_contents()->GetRenderViewHost(); | 115 // also the tab itself. |
71 render_view_host->Send(new ExtensionMsg_UpdateTabSpecificPermissions( | 116 CreateMessageFunction update_message = |
72 render_view_host->GetRoutingID(), | 117 base::Bind(&CreateUpdateMessage, |
73 navigation_entry->GetURL(), | 118 navigation_entry->GetURL(), |
74 extension->id(), | 119 extension->id(), |
75 new_hosts)); | 120 new_hosts, |
| 121 tab_id_); |
| 122 SendMessageToProcesses( |
| 123 ProcessManager::Get(web_contents()->GetBrowserContext())-> |
| 124 GetRenderViewHostsForExtension(extension->id()), |
| 125 web_contents()->GetRenderProcessHost(), |
| 126 update_message); |
| 127 |
76 // If more things ever need to know about this, we should consider making | 128 // If more things ever need to know about this, we should consider making |
77 // an observer class. | 129 // an observer class. |
78 // It's important that this comes after the IPC is sent to the renderer, | 130 // It's important that this comes after the IPC is sent to the renderer, |
79 // so that any tasks executing in the renderer occur after it has the | 131 // so that any tasks executing in the renderer occur after it has the |
80 // updated permissions. | 132 // updated permissions. |
81 ActiveScriptController::GetForWebContents(web_contents()) | 133 ActiveScriptController::GetForWebContents(web_contents()) |
82 ->OnActiveTabPermissionGranted(extension); | 134 ->OnActiveTabPermissionGranted(extension); |
83 } | 135 } |
84 } | 136 } |
85 } | 137 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 UnloadedExtensionInfo::Reason reason) { | 173 UnloadedExtensionInfo::Reason reason) { |
122 // Note: don't need to clear the permissions (nor tell the renderer about it) | 174 // Note: don't need to clear the permissions (nor tell the renderer about it) |
123 // because it's being unloaded anyway. | 175 // because it's being unloaded anyway. |
124 granted_extensions_.Remove(extension->id()); | 176 granted_extensions_.Remove(extension->id()); |
125 } | 177 } |
126 | 178 |
127 void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() { | 179 void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() { |
128 if (granted_extensions_.is_empty()) | 180 if (granted_extensions_.is_empty()) |
129 return; | 181 return; |
130 | 182 |
| 183 std::set<content::RenderViewHost*> view_hosts; |
131 std::vector<std::string> extension_ids; | 184 std::vector<std::string> extension_ids; |
132 | 185 ProcessManager* process_manager = |
133 for (ExtensionSet::const_iterator it = granted_extensions_.begin(); | 186 ProcessManager::Get(web_contents()->GetBrowserContext()); |
134 it != granted_extensions_.end(); ++it) { | 187 for (const scoped_refptr<const Extension>& extension : granted_extensions_) { |
135 it->get()->permissions_data()->ClearTabSpecificPermissions(tab_id_); | 188 extension->permissions_data()->ClearTabSpecificPermissions(tab_id_); |
136 extension_ids.push_back((*it)->id()); | 189 extension_ids.push_back(extension->id()); |
| 190 std::set<content::RenderViewHost*> extension_view_hosts = |
| 191 process_manager->GetRenderViewHostsForExtension(extension->id()); |
| 192 view_hosts.insert(extension_view_hosts.begin(), extension_view_hosts.end()); |
137 } | 193 } |
138 | 194 |
139 content::RenderViewHost* render_view_host = | 195 CreateMessageFunction clear_message = |
140 web_contents()->GetRenderViewHost(); | 196 base::Bind(&CreateClearMessage, extension_ids, tab_id_); |
141 render_view_host->Send(new ExtensionMsg_ClearTabSpecificPermissions( | 197 SendMessageToProcesses(view_hosts, |
142 render_view_host->GetRoutingID(), extension_ids)); | 198 web_contents()->GetRenderProcessHost(), |
| 199 clear_message); |
| 200 |
143 granted_extensions_.Clear(); | 201 granted_extensions_.Clear(); |
144 } | 202 } |
145 | 203 |
146 } // namespace extensions | 204 } // namespace extensions |
OLD | NEW |