Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/renderer/dispatcher.h" | 5 #include "extensions/renderer/dispatcher.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 | 204 |
| 205 } // namespace | 205 } // namespace |
| 206 | 206 |
| 207 // Note that we can't use Blink public APIs in the constructor becase Blink | 207 // Note that we can't use Blink public APIs in the constructor becase Blink |
| 208 // is not initialized at the point we create Dispatcher. | 208 // is not initialized at the point we create Dispatcher. |
| 209 Dispatcher::Dispatcher(DispatcherDelegate* delegate) | 209 Dispatcher::Dispatcher(DispatcherDelegate* delegate) |
| 210 : delegate_(delegate), | 210 : delegate_(delegate), |
| 211 content_watcher_(new ContentWatcher()), | 211 content_watcher_(new ContentWatcher()), |
| 212 source_map_(&ResourceBundle::GetSharedInstance()), | 212 source_map_(&ResourceBundle::GetSharedInstance()), |
| 213 v8_schema_registry_(new V8SchemaRegistry), | 213 v8_schema_registry_(new V8SchemaRegistry), |
| 214 is_webkit_initialized_(false), | |
| 215 user_script_set_manager_observer_(this), | 214 user_script_set_manager_observer_(this), |
| 216 webrequest_used_(false) { | 215 webrequest_used_(false) { |
| 217 const base::CommandLine& command_line = | 216 const base::CommandLine& command_line = |
| 218 *(base::CommandLine::ForCurrentProcess()); | 217 *(base::CommandLine::ForCurrentProcess()); |
| 219 set_idle_notifications_ = | 218 set_idle_notifications_ = |
| 220 command_line.HasSwitch(switches::kExtensionProcess) || | 219 command_line.HasSwitch(switches::kExtensionProcess) || |
| 221 command_line.HasSwitch(::switches::kSingleProcess); | 220 command_line.HasSwitch(::switches::kSingleProcess); |
| 222 | 221 |
| 223 if (set_idle_notifications_) { | 222 if (set_idle_notifications_) { |
| 224 RenderThread::Get()->SetIdleNotificationDelayInMs( | 223 RenderThread::Get()->SetIdleNotificationDelayInMs( |
| 225 kInitialExtensionIdleHandlerDelayMs); | 224 kInitialExtensionIdleHandlerDelayMs); |
| 226 } | 225 } |
| 227 | 226 |
| 228 script_context_set_.reset(new ScriptContextSet(&active_extension_ids_)); | 227 script_context_set_.reset(new ScriptContextSet(&active_extension_ids_)); |
| 229 user_script_set_manager_.reset(new UserScriptSetManager()); | 228 user_script_set_manager_.reset(new UserScriptSetManager()); |
| 230 script_injection_manager_.reset( | 229 script_injection_manager_.reset( |
| 231 new ScriptInjectionManager(user_script_set_manager_.get())); | 230 new ScriptInjectionManager(user_script_set_manager_.get())); |
| 232 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); | 231 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); |
| 233 request_sender_.reset(new RequestSender(this)); | 232 request_sender_.reset(new RequestSender(this)); |
| 234 PopulateSourceMap(); | 233 PopulateSourceMap(); |
| 235 WakeEventPage::Get()->Init(RenderThread::Get()); | 234 WakeEventPage::Get()->Init(RenderThread::Get()); |
| 235 | |
| 236 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); | |
| 237 | |
| 238 // WebSecurityPolicy whitelists. They should be registered for both | |
| 239 // chrome-extension: and chrome-extension-resource. | |
| 240 using RegisterFunction = void (*)(const WebString&); | |
| 241 RegisterFunction register_functions[] = { | |
| 242 // Treat as secure because communication with them is entirely in the | |
| 243 // browser, so there is no danger of manipulation or eavesdropping on | |
| 244 // communication with them by third parties. | |
| 245 WebSecurityPolicy::registerURLSchemeAsSecure, | |
| 246 // As far as Blink is concerned, they should be allowed to receive CORS | |
| 247 // requests. At the Extensions layer, requests will actually be blocked | |
| 248 // unless overridden by the web_accessible_resources manifest key. | |
| 249 // TODO(kalman): See what happens with a service worker. | |
| 250 WebSecurityPolicy::registerURLSchemeAsCORSEnabled, | |
| 251 // Resources should bypass Content Security Policy checks when included in | |
| 252 // protected resources. TODO(kalman): What are "protected resources"? | |
| 253 WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy, | |
| 254 // Extension resources are HTTP-like and safe to expose to the fetch API. | |
| 255 // The rules for the fetch API are consistent with XHR. | |
| 256 WebSecurityPolicy::registerURLSchemeAsSupportingFetchAPI, | |
| 257 // Extension resources, when loaded as the top-level document, should | |
| 258 // bypass Blink's strict first-party origin checks. | |
| 259 WebSecurityPolicy::registerURLSchemeAsFirstPartyWhenTopLevel, | |
| 260 }; | |
| 261 | |
| 262 WebString extension_scheme(base::ASCIIToUTF16(kExtensionScheme)); | |
| 263 WebString extension_resource_scheme(base::ASCIIToUTF16( | |
| 264 kExtensionResourceScheme)); | |
| 265 for (RegisterFunction func : register_functions) { | |
| 266 func(extension_scheme); | |
| 267 func(extension_resource_scheme); | |
| 268 } | |
| 269 | |
| 270 // For extensions, we want to ensure we call the IdleHandler every so often, | |
| 271 // even if the extension keeps up activity. | |
| 272 if (set_idle_notifications_) { | |
| 273 forced_idle_timer_.reset(new base::RepeatingTimer); | |
| 274 forced_idle_timer_->Start( | |
| 275 FROM_HERE, | |
| 276 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), | |
| 277 RenderThread::Get(), | |
| 278 &RenderThread::IdleHandler); | |
| 279 } | |
| 280 | |
| 281 // Initialize host permissions for any extensions that were activated before | |
| 282 // WebKit was initialized. | |
|
Avi (use Gerrit)
2016/03/23 00:10:38
s/WebKit/Blink/
| |
| 283 for (const std::string& extension_id : active_extension_ids_) { | |
| 284 const Extension* extension = | |
| 285 RendererExtensionRegistry::Get()->GetByID(extension_id); | |
| 286 CHECK(extension); | |
| 287 InitOriginPermissions(extension); | |
| 288 } | |
| 289 | |
| 290 EnableCustomElementWhiteList(); | |
| 236 } | 291 } |
| 237 | 292 |
| 238 Dispatcher::~Dispatcher() { | 293 Dispatcher::~Dispatcher() { |
| 239 } | 294 } |
| 240 | 295 |
| 241 void Dispatcher::OnRenderFrameCreated(content::RenderFrame* render_frame) { | 296 void Dispatcher::OnRenderFrameCreated(content::RenderFrame* render_frame) { |
| 242 script_injection_manager_->OnRenderFrameCreated(render_frame); | 297 script_injection_manager_->OnRenderFrameCreated(render_frame); |
| 243 } | 298 } |
| 244 | 299 |
| 245 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { | 300 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 OnClearTabSpecificPermissions) | 937 OnClearTabSpecificPermissions) |
| 883 IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) | 938 IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI) |
| 884 IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, | 939 IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages, |
| 885 content_watcher_.get(), | 940 content_watcher_.get(), |
| 886 ContentWatcher::OnWatchPages) | 941 ContentWatcher::OnWatchPages) |
| 887 IPC_MESSAGE_UNHANDLED(handled = false) | 942 IPC_MESSAGE_UNHANDLED(handled = false) |
| 888 IPC_END_MESSAGE_MAP() | 943 IPC_END_MESSAGE_MAP() |
| 889 | 944 |
| 890 return handled; | 945 return handled; |
| 891 } | 946 } |
| 892 | |
| 893 void Dispatcher::WebKitInitialized() { | |
| 894 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); | |
| 895 | |
| 896 // WebSecurityPolicy whitelists. They should be registered for both | |
| 897 // chrome-extension: and chrome-extension-resource. | |
| 898 using RegisterFunction = void (*)(const WebString&); | |
| 899 RegisterFunction register_functions[] = { | |
| 900 // Treat as secure because communication with them is entirely in the | |
| 901 // browser, so there is no danger of manipulation or eavesdropping on | |
| 902 // communication with them by third parties. | |
| 903 WebSecurityPolicy::registerURLSchemeAsSecure, | |
| 904 // As far as Blink is concerned, they should be allowed to receive CORS | |
| 905 // requests. At the Extensions layer, requests will actually be blocked | |
| 906 // unless overridden by the web_accessible_resources manifest key. | |
| 907 // TODO(kalman): See what happens with a service worker. | |
| 908 WebSecurityPolicy::registerURLSchemeAsCORSEnabled, | |
| 909 // Resources should bypass Content Security Policy checks when included in | |
| 910 // protected resources. TODO(kalman): What are "protected resources"? | |
| 911 WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy, | |
| 912 // Extension resources are HTTP-like and safe to expose to the fetch API. | |
| 913 // The rules for the fetch API are consistent with XHR. | |
| 914 WebSecurityPolicy::registerURLSchemeAsSupportingFetchAPI, | |
| 915 // Extension resources, when loaded as the top-level document, should | |
| 916 // bypass Blink's strict first-party origin checks. | |
| 917 WebSecurityPolicy::registerURLSchemeAsFirstPartyWhenTopLevel, | |
| 918 }; | |
| 919 | |
| 920 WebString extension_scheme(base::ASCIIToUTF16(kExtensionScheme)); | |
| 921 WebString extension_resource_scheme(base::ASCIIToUTF16( | |
| 922 kExtensionResourceScheme)); | |
| 923 for (RegisterFunction func : register_functions) { | |
| 924 func(extension_scheme); | |
| 925 func(extension_resource_scheme); | |
| 926 } | |
| 927 | |
| 928 // For extensions, we want to ensure we call the IdleHandler every so often, | |
| 929 // even if the extension keeps up activity. | |
| 930 if (set_idle_notifications_) { | |
| 931 forced_idle_timer_.reset(new base::RepeatingTimer); | |
| 932 forced_idle_timer_->Start( | |
| 933 FROM_HERE, | |
| 934 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), | |
| 935 RenderThread::Get(), | |
| 936 &RenderThread::IdleHandler); | |
| 937 } | |
| 938 | |
| 939 // Initialize host permissions for any extensions that were activated before | |
| 940 // WebKit was initialized. | |
| 941 for (const std::string& extension_id : active_extension_ids_) { | |
| 942 const Extension* extension = | |
| 943 RendererExtensionRegistry::Get()->GetByID(extension_id); | |
| 944 CHECK(extension); | |
| 945 InitOriginPermissions(extension); | |
| 946 } | |
| 947 | |
| 948 EnableCustomElementWhiteList(); | |
| 949 | |
| 950 is_webkit_initialized_ = true; | |
| 951 } | |
| 952 | |
| 953 void Dispatcher::IdleNotification() { | 947 void Dispatcher::IdleNotification() { |
| 954 if (set_idle_notifications_ && forced_idle_timer_) { | 948 if (set_idle_notifications_ && forced_idle_timer_) { |
| 955 // Dampen the forced delay as well if the extension stays idle for long | 949 // Dampen the forced delay as well if the extension stays idle for long |
| 956 // periods of time. (forced_idle_timer_ can be NULL after | 950 // periods of time. (forced_idle_timer_ can be NULL after |
| 957 // OnRenderProcessShutdown has been called.) | 951 // OnRenderProcessShutdown has been called.) |
| 958 int64_t forced_delay_ms = | 952 int64_t forced_delay_ms = |
| 959 std::max(RenderThread::Get()->GetIdleNotificationDelayInMs(), | 953 std::max(RenderThread::Get()->GetIdleNotificationDelayInMs(), |
| 960 kMaxExtensionIdleHandlerDelayMs); | 954 kMaxExtensionIdleHandlerDelayMs); |
| 961 forced_idle_timer_->Stop(); | 955 forced_idle_timer_->Stop(); |
| 962 forced_idle_timer_->Start( | 956 forced_idle_timer_->Start( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 996 error.c_str()); | 990 error.c_str()); |
| 997 LOG(FATAL) << extension_id << " was never loaded: " << error; | 991 LOG(FATAL) << extension_id << " was never loaded: " << error; |
| 998 } | 992 } |
| 999 | 993 |
| 1000 active_extension_ids_.insert(extension_id); | 994 active_extension_ids_.insert(extension_id); |
| 1001 | 995 |
| 1002 // This is called when starting a new extension page, so start the idle | 996 // This is called when starting a new extension page, so start the idle |
| 1003 // handler ticking. | 997 // handler ticking. |
| 1004 RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); | 998 RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); |
| 1005 | 999 |
| 1006 if (is_webkit_initialized_) { | 1000 DOMActivityLogger::AttachToWorld( |
| 1007 DOMActivityLogger::AttachToWorld( | 1001 DOMActivityLogger::kMainWorldId, extension_id); |
| 1008 DOMActivityLogger::kMainWorldId, extension_id); | |
| 1009 | 1002 |
| 1010 InitOriginPermissions(extension); | 1003 InitOriginPermissions(extension); |
| 1011 } | |
| 1012 | 1004 |
| 1013 UpdateActiveExtensions(); | 1005 UpdateActiveExtensions(); |
| 1014 } | 1006 } |
| 1015 | 1007 |
| 1016 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { | 1008 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { |
| 1017 DispatchEvent(extension_id, kOnSuspendCanceledEvent); | 1009 DispatchEvent(extension_id, kOnSuspendCanceledEvent); |
| 1018 } | 1010 } |
| 1019 | 1011 |
| 1020 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { | 1012 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { |
| 1021 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; | 1013 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1182 const Extension* extension = | 1174 const Extension* extension = |
| 1183 RendererExtensionRegistry::Get()->GetByID(params.extension_id); | 1175 RendererExtensionRegistry::Get()->GetByID(params.extension_id); |
| 1184 if (!extension) | 1176 if (!extension) |
| 1185 return; | 1177 return; |
| 1186 | 1178 |
| 1187 scoped_ptr<const PermissionSet> active = | 1179 scoped_ptr<const PermissionSet> active = |
| 1188 params.active_permissions.ToPermissionSet(); | 1180 params.active_permissions.ToPermissionSet(); |
| 1189 scoped_ptr<const PermissionSet> withheld = | 1181 scoped_ptr<const PermissionSet> withheld = |
| 1190 params.withheld_permissions.ToPermissionSet(); | 1182 params.withheld_permissions.ToPermissionSet(); |
| 1191 | 1183 |
| 1192 if (is_webkit_initialized_) { | 1184 UpdateOriginPermissions( |
| 1193 UpdateOriginPermissions( | 1185 extension->url(), |
| 1194 extension->url(), | 1186 extension->permissions_data()->GetEffectiveHostPermissions(), |
| 1195 extension->permissions_data()->GetEffectiveHostPermissions(), | 1187 active->effective_hosts()); |
| 1196 active->effective_hosts()); | |
| 1197 } | |
| 1198 | 1188 |
| 1199 extension->permissions_data()->SetPermissions(std::move(active), | 1189 extension->permissions_data()->SetPermissions(std::move(active), |
| 1200 std::move(withheld)); | 1190 std::move(withheld)); |
| 1201 UpdateBindings(extension->id()); | 1191 UpdateBindings(extension->id()); |
| 1202 } | 1192 } |
| 1203 | 1193 |
| 1204 void Dispatcher::OnUpdateTabSpecificPermissions(const GURL& visible_url, | 1194 void Dispatcher::OnUpdateTabSpecificPermissions(const GURL& visible_url, |
| 1205 const std::string& extension_id, | 1195 const std::string& extension_id, |
| 1206 const URLPatternSet& new_hosts, | 1196 const URLPatternSet& new_hosts, |
| 1207 bool update_origin_whitelist, | 1197 bool update_origin_whitelist, |
| 1208 int tab_id) { | 1198 int tab_id) { |
| 1209 const Extension* extension = | 1199 const Extension* extension = |
| 1210 RendererExtensionRegistry::Get()->GetByID(extension_id); | 1200 RendererExtensionRegistry::Get()->GetByID(extension_id); |
| 1211 if (!extension) | 1201 if (!extension) |
| 1212 return; | 1202 return; |
| 1213 | 1203 |
| 1214 URLPatternSet old_effective = | 1204 URLPatternSet old_effective = |
| 1215 extension->permissions_data()->GetEffectiveHostPermissions(); | 1205 extension->permissions_data()->GetEffectiveHostPermissions(); |
| 1216 extension->permissions_data()->UpdateTabSpecificPermissions( | 1206 extension->permissions_data()->UpdateTabSpecificPermissions( |
| 1217 tab_id, | 1207 tab_id, |
| 1218 extensions::PermissionSet(extensions::APIPermissionSet(), | 1208 extensions::PermissionSet(extensions::APIPermissionSet(), |
| 1219 extensions::ManifestPermissionSet(), new_hosts, | 1209 extensions::ManifestPermissionSet(), new_hosts, |
| 1220 extensions::URLPatternSet())); | 1210 extensions::URLPatternSet())); |
| 1221 | 1211 |
| 1222 if (is_webkit_initialized_ && update_origin_whitelist) { | 1212 if (update_origin_whitelist) { |
| 1223 UpdateOriginPermissions( | 1213 UpdateOriginPermissions( |
| 1224 extension->url(), | 1214 extension->url(), |
| 1225 old_effective, | 1215 old_effective, |
| 1226 extension->permissions_data()->GetEffectiveHostPermissions()); | 1216 extension->permissions_data()->GetEffectiveHostPermissions()); |
| 1227 } | 1217 } |
| 1228 } | 1218 } |
| 1229 | 1219 |
| 1230 void Dispatcher::OnClearTabSpecificPermissions( | 1220 void Dispatcher::OnClearTabSpecificPermissions( |
| 1231 const std::vector<std::string>& extension_ids, | 1221 const std::vector<std::string>& extension_ids, |
| 1232 bool update_origin_whitelist, | 1222 bool update_origin_whitelist, |
| 1233 int tab_id) { | 1223 int tab_id) { |
| 1234 for (const std::string& id : extension_ids) { | 1224 for (const std::string& id : extension_ids) { |
| 1235 const Extension* extension = RendererExtensionRegistry::Get()->GetByID(id); | 1225 const Extension* extension = RendererExtensionRegistry::Get()->GetByID(id); |
| 1236 if (extension) { | 1226 if (extension) { |
| 1237 URLPatternSet old_effective = | 1227 URLPatternSet old_effective = |
| 1238 extension->permissions_data()->GetEffectiveHostPermissions(); | 1228 extension->permissions_data()->GetEffectiveHostPermissions(); |
| 1239 extension->permissions_data()->ClearTabSpecificPermissions(tab_id); | 1229 extension->permissions_data()->ClearTabSpecificPermissions(tab_id); |
| 1240 if (is_webkit_initialized_ && update_origin_whitelist) { | 1230 if (update_origin_whitelist) { |
| 1241 UpdateOriginPermissions( | 1231 UpdateOriginPermissions( |
| 1242 extension->url(), | 1232 extension->url(), |
| 1243 old_effective, | 1233 old_effective, |
| 1244 extension->permissions_data()->GetEffectiveHostPermissions()); | 1234 extension->permissions_data()->GetEffectiveHostPermissions()); |
| 1245 } | 1235 } |
| 1246 } | 1236 } |
| 1247 } | 1237 } |
| 1248 } | 1238 } |
| 1249 | 1239 |
| 1250 void Dispatcher::OnUsingWebRequestAPI(bool webrequest_used) { | 1240 void Dispatcher::OnUsingWebRequestAPI(bool webrequest_used) { |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 // The "guestViewDeny" module must always be loaded last. It registers | 1615 // The "guestViewDeny" module must always be loaded last. It registers |
| 1626 // error-providing custom elements for the GuestView types that are not | 1616 // error-providing custom elements for the GuestView types that are not |
| 1627 // available, and thus all of those types must have been checked and loaded | 1617 // available, and thus all of those types must have been checked and loaded |
| 1628 // (or not loaded) beforehand. | 1618 // (or not loaded) beforehand. |
| 1629 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { | 1619 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { |
| 1630 module_system->Require("guestViewDeny"); | 1620 module_system->Require("guestViewDeny"); |
| 1631 } | 1621 } |
| 1632 } | 1622 } |
| 1633 | 1623 |
| 1634 } // namespace extensions | 1624 } // namespace extensions |
| OLD | NEW |