| 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 <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
| 17 #include "base/feature_list.h" | 17 #include "base/feature_list.h" |
| 18 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" | 20 #include "base/memory/ptr_util.h" |
| 21 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/metrics/user_metrics_action.h" | 22 #include "base/metrics/user_metrics_action.h" |
| 23 #include "base/strings/string_piece.h" | 23 #include "base/strings/string_piece.h" |
| 24 #include "base/strings/string_split.h" | |
| 25 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
| 27 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| 28 #include "base/values.h" | 27 #include "base/values.h" |
| 29 #include "build/build_config.h" | 28 #include "build/build_config.h" |
| 30 #include "content/grit/content_resources.h" | 29 #include "content/grit/content_resources.h" |
| 31 #include "content/public/child/v8_value_converter.h" | 30 #include "content/public/child/v8_value_converter.h" |
| 32 #include "content/public/common/content_features.h" | 31 #include "content/public/common/content_features.h" |
| 33 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
| 34 #include "content/public/common/url_constants.h" | 33 #include "content/public/common/url_constants.h" |
| 35 #include "content/public/renderer/render_frame.h" | 34 #include "content/public/renderer/render_frame.h" |
| 36 #include "content/public/renderer/render_thread.h" | 35 #include "content/public/renderer/render_thread.h" |
| 37 #include "extensions/common/api/messaging/message.h" | 36 #include "extensions/common/api/messaging/message.h" |
| 38 #include "extensions/common/constants.h" | 37 #include "extensions/common/constants.h" |
| 39 #include "extensions/common/extension_api.h" | 38 #include "extensions/common/extension_api.h" |
| 40 #include "extensions/common/extension_messages.h" | 39 #include "extensions/common/extension_messages.h" |
| 41 #include "extensions/common/extension_urls.h" | 40 #include "extensions/common/extension_urls.h" |
| 42 #include "extensions/common/feature_switch.h" | 41 #include "extensions/common/feature_switch.h" |
| 43 #include "extensions/common/features/behavior_feature.h" | 42 #include "extensions/common/features/behavior_feature.h" |
| 44 #include "extensions/common/features/feature.h" | 43 #include "extensions/common/features/feature.h" |
| 45 #include "extensions/common/features/feature_channel.h" | 44 #include "extensions/common/features/feature_channel.h" |
| 46 #include "extensions/common/features/feature_provider.h" | 45 #include "extensions/common/features/feature_provider.h" |
| 47 #include "extensions/common/features/feature_util.h" | 46 #include "extensions/common/features/feature_util.h" |
| 48 #include "extensions/common/manifest.h" | 47 #include "extensions/common/manifest.h" |
| 49 #include "extensions/common/manifest_constants.h" | 48 #include "extensions/common/manifest_constants.h" |
| 50 #include "extensions/common/manifest_handlers/background_info.h" | 49 #include "extensions/common/manifest_handlers/background_info.h" |
| 51 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" | 50 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" |
| 52 #include "extensions/common/manifest_handlers/externally_connectable.h" | |
| 53 #include "extensions/common/manifest_handlers/options_page_info.h" | 51 #include "extensions/common/manifest_handlers/options_page_info.h" |
| 54 #include "extensions/common/message_bundle.h" | 52 #include "extensions/common/message_bundle.h" |
| 55 #include "extensions/common/permissions/permission_set.h" | 53 #include "extensions/common/permissions/permission_set.h" |
| 56 #include "extensions/common/permissions/permissions_data.h" | 54 #include "extensions/common/permissions/permissions_data.h" |
| 57 #include "extensions/common/switches.h" | 55 #include "extensions/common/switches.h" |
| 58 #include "extensions/common/view_type.h" | 56 #include "extensions/common/view_type.h" |
| 59 #include "extensions/renderer/api_activity_logger.h" | 57 #include "extensions/renderer/api_activity_logger.h" |
| 60 #include "extensions/renderer/api_definitions_natives.h" | 58 #include "extensions/renderer/api_definitions_natives.h" |
| 61 #include "extensions/renderer/app_window_custom_bindings.h" | 59 #include "extensions/renderer/app_window_custom_bindings.h" |
| 62 #include "extensions/renderer/binding_generating_native_handler.h" | |
| 63 #include "extensions/renderer/blob_native_handler.h" | 60 #include "extensions/renderer/blob_native_handler.h" |
| 64 #include "extensions/renderer/content_watcher.h" | 61 #include "extensions/renderer/content_watcher.h" |
| 65 #include "extensions/renderer/context_menus_custom_bindings.h" | 62 #include "extensions/renderer/context_menus_custom_bindings.h" |
| 66 #include "extensions/renderer/dispatcher_delegate.h" | 63 #include "extensions/renderer/dispatcher_delegate.h" |
| 67 #include "extensions/renderer/display_source_custom_bindings.h" | 64 #include "extensions/renderer/display_source_custom_bindings.h" |
| 68 #include "extensions/renderer/document_custom_bindings.h" | 65 #include "extensions/renderer/document_custom_bindings.h" |
| 69 #include "extensions/renderer/dom_activity_logger.h" | 66 #include "extensions/renderer/dom_activity_logger.h" |
| 70 #include "extensions/renderer/event_bindings.h" | 67 #include "extensions/renderer/event_bindings.h" |
| 71 #include "extensions/renderer/extension_frame_helper.h" | 68 #include "extensions/renderer/extension_frame_helper.h" |
| 72 #include "extensions/renderer/extension_helper.h" | 69 #include "extensions/renderer/extension_helper.h" |
| 73 #include "extensions/renderer/extensions_renderer_client.h" | 70 #include "extensions/renderer/extensions_renderer_client.h" |
| 74 #include "extensions/renderer/file_system_natives.h" | 71 #include "extensions/renderer/file_system_natives.h" |
| 75 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" | 72 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" |
| 76 #include "extensions/renderer/id_generator_custom_bindings.h" | 73 #include "extensions/renderer/id_generator_custom_bindings.h" |
| 74 #include "extensions/renderer/js_extension_bindings_system.h" |
| 77 #include "extensions/renderer/logging_native_handler.h" | 75 #include "extensions/renderer/logging_native_handler.h" |
| 78 #include "extensions/renderer/messaging_bindings.h" | 76 #include "extensions/renderer/messaging_bindings.h" |
| 79 #include "extensions/renderer/module_system.h" | 77 #include "extensions/renderer/module_system.h" |
| 80 #include "extensions/renderer/process_info_native_handler.h" | 78 #include "extensions/renderer/process_info_native_handler.h" |
| 81 #include "extensions/renderer/render_frame_observer_natives.h" | 79 #include "extensions/renderer/render_frame_observer_natives.h" |
| 82 #include "extensions/renderer/renderer_extension_registry.h" | 80 #include "extensions/renderer/renderer_extension_registry.h" |
| 83 #include "extensions/renderer/request_sender.h" | 81 #include "extensions/renderer/request_sender.h" |
| 84 #include "extensions/renderer/runtime_custom_bindings.h" | 82 #include "extensions/renderer/runtime_custom_bindings.h" |
| 85 #include "extensions/renderer/safe_builtins.h" | 83 #include "extensions/renderer/safe_builtins.h" |
| 86 #include "extensions/renderer/script_context.h" | 84 #include "extensions/renderer/script_context.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 using blink::WebVector; | 126 using blink::WebVector; |
| 129 using blink::WebView; | 127 using blink::WebView; |
| 130 using content::RenderThread; | 128 using content::RenderThread; |
| 131 | 129 |
| 132 namespace extensions { | 130 namespace extensions { |
| 133 | 131 |
| 134 namespace { | 132 namespace { |
| 135 | 133 |
| 136 static const int64_t kInitialExtensionIdleHandlerDelayMs = 5 * 1000; | 134 static const int64_t kInitialExtensionIdleHandlerDelayMs = 5 * 1000; |
| 137 static const int64_t kMaxExtensionIdleHandlerDelayMs = 5 * 60 * 1000; | 135 static const int64_t kMaxExtensionIdleHandlerDelayMs = 5 * 60 * 1000; |
| 138 static const char kEventDispatchFunction[] = "dispatchEvent"; | |
| 139 static const char kOnSuspendEvent[] = "runtime.onSuspend"; | 136 static const char kOnSuspendEvent[] = "runtime.onSuspend"; |
| 140 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; | 137 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; |
| 141 | 138 |
| 142 void CrashOnException(const v8::TryCatch& trycatch) { | 139 void CrashOnException(const v8::TryCatch& trycatch) { |
| 143 NOTREACHED(); | 140 NOTREACHED(); |
| 144 }; | 141 }; |
| 145 | 142 |
| 146 // Returns the global value for "chrome" from |context|. If one doesn't exist | |
| 147 // creates a new object for it. | |
| 148 // | |
| 149 // Note that this isn't necessarily an object, since webpages can write, for | |
| 150 // example, "window.chrome = true". | |
| 151 v8::Local<v8::Value> GetOrCreateChrome(ScriptContext* context) { | |
| 152 v8::Local<v8::String> chrome_string( | |
| 153 v8::String::NewFromUtf8(context->isolate(), "chrome")); | |
| 154 v8::Local<v8::Object> global(context->v8_context()->Global()); | |
| 155 v8::Local<v8::Value> chrome(global->Get(chrome_string)); | |
| 156 if (chrome->IsUndefined()) { | |
| 157 chrome = v8::Object::New(context->isolate()); | |
| 158 global->Set(chrome_string, chrome); | |
| 159 } | |
| 160 return chrome; | |
| 161 } | |
| 162 | |
| 163 // Returns |value| cast to an object if possible, else an empty handle. | |
| 164 v8::Local<v8::Object> AsObjectOrEmpty(v8::Local<v8::Value> value) { | |
| 165 return value->IsObject() ? value.As<v8::Object>() : v8::Local<v8::Object>(); | |
| 166 } | |
| 167 | |
| 168 // Calls a method |method_name| in a module |module_name| belonging to the | 143 // Calls a method |method_name| in a module |module_name| belonging to the |
| 169 // module system from |context|. Intended as a callback target from | 144 // module system from |context|. Intended as a callback target from |
| 170 // ScriptContextSet::ForEach. | 145 // ScriptContextSet::ForEach. |
| 171 void CallModuleMethod(const std::string& module_name, | 146 void CallModuleMethod(const std::string& module_name, |
| 172 const std::string& method_name, | 147 const std::string& method_name, |
| 173 const base::ListValue* args, | 148 const base::ListValue* args, |
| 174 ScriptContext* context) { | 149 ScriptContext* context) { |
| 175 v8::HandleScope handle_scope(context->isolate()); | 150 v8::HandleScope handle_scope(context->isolate()); |
| 176 v8::Context::Scope context_scope(context->v8_context()); | 151 v8::Context::Scope context_scope(context->v8_context()); |
| 177 | 152 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 191 class ChromeNativeHandler : public ObjectBackedNativeHandler { | 166 class ChromeNativeHandler : public ObjectBackedNativeHandler { |
| 192 public: | 167 public: |
| 193 explicit ChromeNativeHandler(ScriptContext* context) | 168 explicit ChromeNativeHandler(ScriptContext* context) |
| 194 : ObjectBackedNativeHandler(context) { | 169 : ObjectBackedNativeHandler(context) { |
| 195 RouteFunction( | 170 RouteFunction( |
| 196 "GetChrome", | 171 "GetChrome", |
| 197 base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this))); | 172 base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this))); |
| 198 } | 173 } |
| 199 | 174 |
| 200 void GetChrome(const v8::FunctionCallbackInfo<v8::Value>& args) { | 175 void GetChrome(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 201 args.GetReturnValue().Set(GetOrCreateChrome(context())); | 176 // Check for the chrome property. If one doesn't exist, create one. |
| 177 v8::Local<v8::String> chrome_string( |
| 178 v8::String::NewFromUtf8(context()->isolate(), "chrome")); |
| 179 v8::Local<v8::Object> global(context()->v8_context()->Global()); |
| 180 v8::Local<v8::Value> chrome(global->Get(chrome_string)); |
| 181 if (chrome->IsUndefined()) { |
| 182 chrome = v8::Object::New(context()->isolate()); |
| 183 global->Set(chrome_string, chrome); |
| 184 } |
| 185 args.GetReturnValue().Set(chrome); |
| 202 } | 186 } |
| 203 }; | 187 }; |
| 204 | 188 |
| 205 base::LazyInstance<WorkerScriptContextSet> g_worker_script_context_set = | 189 base::LazyInstance<WorkerScriptContextSet> g_worker_script_context_set = |
| 206 LAZY_INSTANCE_INITIALIZER; | 190 LAZY_INSTANCE_INITIALIZER; |
| 207 | 191 |
| 208 // Dispatches the event with the given name, arguments, and filtering info in | |
| 209 // the given |context|. | |
| 210 void DispatchEventInContext(const std::string& event_name, | |
| 211 const base::ListValue* event_args, | |
| 212 const base::DictionaryValue* filtering_info, | |
| 213 ScriptContext* context) { | |
| 214 v8::HandleScope handle_scope(context->isolate()); | |
| 215 v8::Context::Scope context_scope(context->v8_context()); | |
| 216 | |
| 217 std::vector<v8::Local<v8::Value>> arguments; | |
| 218 arguments.push_back(gin::StringToSymbol(context->isolate(), event_name)); | |
| 219 | |
| 220 { | |
| 221 std::unique_ptr<content::V8ValueConverter> converter( | |
| 222 content::V8ValueConverter::create()); | |
| 223 arguments.push_back( | |
| 224 converter->ToV8Value(event_args, context->v8_context())); | |
| 225 if (!filtering_info->empty()) { | |
| 226 arguments.push_back( | |
| 227 converter->ToV8Value(filtering_info, context->v8_context())); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 context->module_system()->CallModuleMethodSafe( | |
| 232 kEventBindings, kEventDispatchFunction, arguments.size(), | |
| 233 arguments.data()); | |
| 234 } | |
| 235 | |
| 236 } // namespace | 192 } // namespace |
| 237 | 193 |
| 238 // Note that we can't use Blink public APIs in the constructor becase Blink | 194 // Note that we can't use Blink public APIs in the constructor becase Blink |
| 239 // is not initialized at the point we create Dispatcher. | 195 // is not initialized at the point we create Dispatcher. |
| 240 Dispatcher::Dispatcher(DispatcherDelegate* delegate) | 196 Dispatcher::Dispatcher(DispatcherDelegate* delegate) |
| 241 : delegate_(delegate), | 197 : delegate_(delegate), |
| 242 content_watcher_(new ContentWatcher()), | 198 content_watcher_(new ContentWatcher()), |
| 243 source_map_(&ResourceBundle::GetSharedInstance()), | 199 source_map_(&ResourceBundle::GetSharedInstance()), |
| 244 v8_schema_registry_(new V8SchemaRegistry), | 200 v8_schema_registry_(new V8SchemaRegistry), |
| 201 bindings_system_( |
| 202 new JsExtensionBindingsSystem(&source_map_, |
| 203 base::MakeUnique<RequestSender>())), |
| 245 user_script_set_manager_observer_(this), | 204 user_script_set_manager_observer_(this), |
| 246 activity_logging_enabled_(false) { | 205 activity_logging_enabled_(false) { |
| 247 const base::CommandLine& command_line = | 206 const base::CommandLine& command_line = |
| 248 *(base::CommandLine::ForCurrentProcess()); | 207 *(base::CommandLine::ForCurrentProcess()); |
| 249 set_idle_notifications_ = | 208 set_idle_notifications_ = |
| 250 command_line.HasSwitch(switches::kExtensionProcess) || | 209 command_line.HasSwitch(switches::kExtensionProcess) || |
| 251 command_line.HasSwitch(::switches::kSingleProcess); | 210 command_line.HasSwitch(::switches::kSingleProcess); |
| 252 | 211 |
| 253 if (set_idle_notifications_) { | 212 if (set_idle_notifications_) { |
| 254 RenderThread::Get()->SetIdleNotificationDelayInMs( | 213 RenderThread::Get()->SetIdleNotificationDelayInMs( |
| 255 kInitialExtensionIdleHandlerDelayMs); | 214 kInitialExtensionIdleHandlerDelayMs); |
| 256 } | 215 } |
| 257 | 216 |
| 258 script_context_set_.reset(new ScriptContextSet(&active_extension_ids_)); | 217 script_context_set_.reset(new ScriptContextSet(&active_extension_ids_)); |
| 259 user_script_set_manager_.reset(new UserScriptSetManager()); | 218 user_script_set_manager_.reset(new UserScriptSetManager()); |
| 260 script_injection_manager_.reset( | 219 script_injection_manager_.reset( |
| 261 new ScriptInjectionManager(user_script_set_manager_.get())); | 220 new ScriptInjectionManager(user_script_set_manager_.get())); |
| 262 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); | 221 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); |
| 263 request_sender_.reset(new RequestSender()); | |
| 264 PopulateSourceMap(); | 222 PopulateSourceMap(); |
| 265 WakeEventPage::Get()->Init(RenderThread::Get()); | 223 WakeEventPage::Get()->Init(RenderThread::Get()); |
| 266 // Ideally this should be done after checking | 224 // Ideally this should be done after checking |
| 267 // ExtensionAPIEnabledInExtensionServiceWorkers(), but the Dispatcher is | 225 // ExtensionAPIEnabledInExtensionServiceWorkers(), but the Dispatcher is |
| 268 // created so early that sending an IPC from browser/ process to synchronize | 226 // created so early that sending an IPC from browser/ process to synchronize |
| 269 // this enabled-ness is too late. | 227 // this enabled-ness is too late. |
| 270 WorkerThreadDispatcher::Get()->Init(RenderThread::Get()); | 228 WorkerThreadDispatcher::Get()->Init(RenderThread::Get()); |
| 271 | 229 |
| 272 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); | 230 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); |
| 273 | 231 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 { | 317 { |
| 360 std::unique_ptr<ModuleSystem> module_system( | 318 std::unique_ptr<ModuleSystem> module_system( |
| 361 new ModuleSystem(context, &source_map_)); | 319 new ModuleSystem(context, &source_map_)); |
| 362 context->set_module_system(std::move(module_system)); | 320 context->set_module_system(std::move(module_system)); |
| 363 } | 321 } |
| 364 ModuleSystem* module_system = context->module_system(); | 322 ModuleSystem* module_system = context->module_system(); |
| 365 | 323 |
| 366 // Enable natives in startup. | 324 // Enable natives in startup. |
| 367 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); | 325 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); |
| 368 | 326 |
| 369 RegisterNativeHandlers(module_system, context, request_sender_.get(), | 327 RegisterNativeHandlers(module_system, context, |
| 328 bindings_system_->GetRequestSender(), |
| 370 v8_schema_registry_.get()); | 329 v8_schema_registry_.get()); |
| 371 | 330 |
| 372 // chrome.Event is part of the public API (although undocumented). Make it | 331 bindings_system_->DidCreateScriptContext(context); |
| 373 // lazily evalulate to Event from event_bindings.js. For extensions only | |
| 374 // though, not all webpages! | |
| 375 if (context->extension()) { | |
| 376 v8::Local<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); | |
| 377 if (!chrome.IsEmpty()) | |
| 378 module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); | |
| 379 } | |
| 380 | |
| 381 UpdateBindingsForContext(context); | 332 UpdateBindingsForContext(context); |
| 382 | 333 |
| 383 bool is_within_platform_app = IsWithinPlatformApp(); | 334 bool is_within_platform_app = IsWithinPlatformApp(); |
| 384 // Inject custom JS into the platform app context. | 335 // Inject custom JS into the platform app context. |
| 385 if (is_within_platform_app) { | 336 if (is_within_platform_app) { |
| 386 module_system->Require("platformApp"); | 337 module_system->Require("platformApp"); |
| 387 } | 338 } |
| 388 | 339 |
| 389 RequireGuestViewModules(context); | 340 RequireGuestViewModules(context); |
| 390 delegate_->RequireAdditionalModules(context, is_within_platform_app); | 341 delegate_->RequireAdditionalModules(context, is_within_platform_app); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 // won't work before that event has fired? | 417 // won't work before that event has fired? |
| 467 return; | 418 return; |
| 468 } | 419 } |
| 469 | 420 |
| 470 ScriptContext* context = new ScriptContext( | 421 ScriptContext* context = new ScriptContext( |
| 471 v8_context, nullptr, extension, Feature::SERVICE_WORKER_CONTEXT, | 422 v8_context, nullptr, extension, Feature::SERVICE_WORKER_CONTEXT, |
| 472 extension, Feature::SERVICE_WORKER_CONTEXT); | 423 extension, Feature::SERVICE_WORKER_CONTEXT); |
| 473 context->set_url(url); | 424 context->set_url(url); |
| 474 | 425 |
| 475 if (ExtensionsClient::Get()->ExtensionAPIEnabledInExtensionServiceWorkers()) { | 426 if (ExtensionsClient::Get()->ExtensionAPIEnabledInExtensionServiceWorkers()) { |
| 476 WorkerThreadDispatcher::Get()->AddWorkerData(service_worker_version_id); | 427 WorkerThreadDispatcher::Get()->AddWorkerData(service_worker_version_id, |
| 477 { | 428 &source_map_); |
| 478 // TODO(lazyboy): Make sure accessing |source_map_| in worker thread is | 429 |
| 479 // safe. | 430 // TODO(lazyboy): Make sure accessing |source_map_| in worker thread is |
| 480 std::unique_ptr<ModuleSystem> module_system( | 431 // safe. |
| 481 new ModuleSystem(context, &source_map_)); | 432 context->set_module_system( |
| 482 context->set_module_system(std::move(module_system)); | 433 base::MakeUnique<ModuleSystem>(context, &source_map_)); |
| 483 } | |
| 484 | 434 |
| 485 ModuleSystem* module_system = context->module_system(); | 435 ModuleSystem* module_system = context->module_system(); |
| 486 // Enable natives in startup. | 436 // Enable natives in startup. |
| 487 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); | 437 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); |
| 488 RegisterNativeHandlers( | 438 ExtensionBindingsSystem* worker_bindings_system = |
| 489 module_system, context, | 439 WorkerThreadDispatcher::GetBindingsSystem(); |
| 490 WorkerThreadDispatcher::Get()->GetRequestSender(), | 440 RegisterNativeHandlers(module_system, context, |
| 491 WorkerThreadDispatcher::Get()->GetV8SchemaRegistry()); | 441 worker_bindings_system->GetRequestSender(), |
| 492 // chrome.Event is part of the public API (although undocumented). Make it | 442 WorkerThreadDispatcher::GetV8SchemaRegistry()); |
| 493 // lazily evalulate to Event from event_bindings.js. | |
| 494 v8::Local<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); | |
| 495 if (!chrome.IsEmpty()) | |
| 496 module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); | |
| 497 | 443 |
| 498 UpdateBindingsForContext(context); | 444 worker_bindings_system->DidCreateScriptContext(context); |
| 445 worker_bindings_system->UpdateBindingsForContext(context); |
| 446 |
| 499 // TODO(lazyboy): Get rid of RequireGuestViewModules() as this doesn't seem | 447 // TODO(lazyboy): Get rid of RequireGuestViewModules() as this doesn't seem |
| 500 // necessary for Extension SW. | 448 // necessary for Extension SW. |
| 501 RequireGuestViewModules(context); | 449 RequireGuestViewModules(context); |
| 502 delegate_->RequireAdditionalModules(context, | 450 delegate_->RequireAdditionalModules(context, |
| 503 false /* is_within_platform_app */); | 451 false /* is_within_platform_app */); |
| 504 } | 452 } |
| 505 | 453 |
| 506 g_worker_script_context_set.Get().Insert(base::WrapUnique(context)); | 454 g_worker_script_context_set.Get().Insert(base::WrapUnique(context)); |
| 507 | 455 |
| 508 v8::Isolate* isolate = context->isolate(); | 456 v8::Isolate* isolate = context->isolate(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 "Extensions.DidInitializeServiceWorkerContextOnWorkerThread", elapsed); | 496 "Extensions.DidInitializeServiceWorkerContextOnWorkerThread", elapsed); |
| 549 } | 497 } |
| 550 | 498 |
| 551 void Dispatcher::WillReleaseScriptContext( | 499 void Dispatcher::WillReleaseScriptContext( |
| 552 blink::WebLocalFrame* frame, | 500 blink::WebLocalFrame* frame, |
| 553 const v8::Local<v8::Context>& v8_context, | 501 const v8::Local<v8::Context>& v8_context, |
| 554 int world_id) { | 502 int world_id) { |
| 555 ScriptContext* context = script_context_set_->GetByV8Context(v8_context); | 503 ScriptContext* context = script_context_set_->GetByV8Context(v8_context); |
| 556 if (!context) | 504 if (!context) |
| 557 return; | 505 return; |
| 558 | 506 bindings_system_->WillReleaseScriptContext(context); |
| 559 // TODO(kalman): Make |request_sender| use |context->AddInvalidationObserver|. | |
| 560 // In fact |request_sender_| should really be owned by ScriptContext. | |
| 561 request_sender_->InvalidateSource(context); | |
| 562 | 507 |
| 563 script_context_set_->Remove(context); | 508 script_context_set_->Remove(context); |
| 564 VLOG(1) << "Num tracked contexts: " << script_context_set_->size(); | 509 VLOG(1) << "Num tracked contexts: " << script_context_set_->size(); |
| 565 } | 510 } |
| 566 | 511 |
| 567 // static | 512 // static |
| 568 void Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread( | 513 void Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread( |
| 569 v8::Local<v8::Context> v8_context, | 514 v8::Local<v8::Context> v8_context, |
| 570 int64_t service_worker_version_id, | 515 int64_t service_worker_version_id, |
| 571 const GURL& url) { | 516 const GURL& url) { |
| 572 if (url.SchemeIs(kExtensionScheme) || | 517 if (url.SchemeIs(kExtensionScheme) || |
| 573 url.SchemeIs(kExtensionResourceScheme)) { | 518 url.SchemeIs(kExtensionResourceScheme)) { |
| 574 // See comment in DidInitializeServiceWorkerContextOnWorkerThread. | 519 // See comment in DidInitializeServiceWorkerContextOnWorkerThread. |
| 575 g_worker_script_context_set.Get().Remove(v8_context, url); | 520 g_worker_script_context_set.Get().Remove(v8_context, url); |
| 521 // TODO(devlin): We're not calling |
| 522 // ExtensionBindingsSystem::WillReleaseScriptContext() here. This should be |
| 523 // fine, since the entire bindings system is being destroyed when we |
| 524 // remove the worker data, but we might want to notify the system anyway. |
| 576 } | 525 } |
| 577 if (ExtensionsClient::Get()->ExtensionAPIEnabledInExtensionServiceWorkers()) | 526 if (ExtensionsClient::Get()->ExtensionAPIEnabledInExtensionServiceWorkers()) |
| 578 WorkerThreadDispatcher::Get()->RemoveWorkerData(service_worker_version_id); | 527 WorkerThreadDispatcher::Get()->RemoveWorkerData(service_worker_version_id); |
| 579 } | 528 } |
| 580 | 529 |
| 581 void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { | 530 void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { |
| 582 // Note: use GetEffectiveDocumentURL not just frame->document()->url() | 531 // Note: use GetEffectiveDocumentURL not just frame->document()->url() |
| 583 // so that this also injects the stylesheet on about:blank frames that | 532 // so that this also injects the stylesheet on about:blank frames that |
| 584 // are hosted in the extension process. | 533 // are hosted in the extension process. |
| 585 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( | 534 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 return; // The frame is invisible to extensions. | 591 return; // The frame is invisible to extensions. |
| 643 | 592 |
| 644 frame_helper->RunScriptsAtDocumentEnd(); | 593 frame_helper->RunScriptsAtDocumentEnd(); |
| 645 // |frame_helper| and |render_frame| might be dead by now. | 594 // |frame_helper| and |render_frame| might be dead by now. |
| 646 } | 595 } |
| 647 | 596 |
| 648 void Dispatcher::OnExtensionResponse(int request_id, | 597 void Dispatcher::OnExtensionResponse(int request_id, |
| 649 bool success, | 598 bool success, |
| 650 const base::ListValue& response, | 599 const base::ListValue& response, |
| 651 const std::string& error) { | 600 const std::string& error) { |
| 652 request_sender_->HandleResponse(request_id, success, response, error); | 601 bindings_system_->HandleResponse(request_id, success, response, error); |
| 653 } | 602 } |
| 654 | 603 |
| 655 void Dispatcher::DispatchEvent( | 604 void Dispatcher::DispatchEvent( |
| 656 const std::string& extension_id, | 605 const std::string& extension_id, |
| 657 const std::string& event_name, | 606 const std::string& event_name, |
| 658 const base::ListValue& event_args, | 607 const base::ListValue& event_args, |
| 659 const base::DictionaryValue& filtering_info) const { | 608 const base::DictionaryValue& filtering_info) const { |
| 660 script_context_set_->ForEach(extension_id, nullptr, | 609 script_context_set_->ForEach( |
| 661 base::Bind(&DispatchEventInContext, event_name, | 610 extension_id, nullptr, |
| 662 &event_args, &filtering_info)); | 611 base::Bind(&ExtensionBindingsSystem::DispatchEventInContext, |
| 612 base::Unretained(bindings_system_.get()), event_name, |
| 613 &event_args, &filtering_info)); |
| 663 | 614 |
| 664 // Reset the idle handler each time there's any activity like event or message | 615 // Reset the idle handler each time there's any activity like event or message |
| 665 // dispatch. | 616 // dispatch. |
| 666 // TODO(devlin): It's likely this is totally wrong. See | 617 // TODO(devlin): It's likely this is totally wrong. See |
| 667 // https://groups.google.com/a/chromium.org/forum/#!msg/scheduler-dev/iTRVbcmm
pAs/pfqyUyEeAAAJ | 618 // https://groups.google.com/a/chromium.org/forum/#!msg/scheduler-dev/iTRVbcmm
pAs/pfqyUyEeAAAJ |
| 668 if (set_idle_notifications_) { | 619 if (set_idle_notifications_) { |
| 669 RenderThread::Get()->ScheduleIdleHandler( | 620 RenderThread::Get()->ScheduleIdleHandler( |
| 670 kInitialExtensionIdleHandlerDelayMs); | 621 kInitialExtensionIdleHandlerDelayMs); |
| 671 } | 622 } |
| 672 } | 623 } |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { | 979 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { |
| 1029 DispatchEvent(extension_id, kOnSuspendCanceledEvent, base::ListValue(), | 980 DispatchEvent(extension_id, kOnSuspendCanceledEvent, base::ListValue(), |
| 1030 base::DictionaryValue()); | 981 base::DictionaryValue()); |
| 1031 } | 982 } |
| 1032 | 983 |
| 1033 void Dispatcher::OnDeliverMessage(int target_port_id, | 984 void Dispatcher::OnDeliverMessage(int target_port_id, |
| 1034 int source_tab_id, | 985 int source_tab_id, |
| 1035 const Message& message) { | 986 const Message& message) { |
| 1036 std::unique_ptr<RequestSender::ScopedTabID> scoped_tab_id; | 987 std::unique_ptr<RequestSender::ScopedTabID> scoped_tab_id; |
| 1037 if (source_tab_id != -1) { | 988 if (source_tab_id != -1) { |
| 1038 scoped_tab_id.reset( | 989 scoped_tab_id.reset(new RequestSender::ScopedTabID( |
| 1039 new RequestSender::ScopedTabID(request_sender(), source_tab_id)); | 990 bindings_system_->GetRequestSender(), source_tab_id)); |
| 1040 } | 991 } |
| 1041 | 992 |
| 1042 MessagingBindings::DeliverMessage(*script_context_set_, target_port_id, | 993 MessagingBindings::DeliverMessage(*script_context_set_, target_port_id, |
| 1043 message, | 994 message, |
| 1044 NULL); // All render frames. | 995 NULL); // All render frames. |
| 1045 } | 996 } |
| 1046 | 997 |
| 1047 void Dispatcher::OnDispatchOnConnect( | 998 void Dispatcher::OnDispatchOnConnect( |
| 1048 int target_port_id, | 999 int target_port_id, |
| 1049 const std::string& channel_name, | 1000 const std::string& channel_name, |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 // If the extension is later reloaded with a different set of permissions, | 1152 // If the extension is later reloaded with a different set of permissions, |
| 1202 // we'd like it to get a new isolated world ID, so that it can pick up the | 1153 // we'd like it to get a new isolated world ID, so that it can pick up the |
| 1203 // changed origin whitelist. | 1154 // changed origin whitelist. |
| 1204 ScriptInjection::RemoveIsolatedWorld(id); | 1155 ScriptInjection::RemoveIsolatedWorld(id); |
| 1205 | 1156 |
| 1206 // Invalidate all of the contexts that were removed. | 1157 // Invalidate all of the contexts that were removed. |
| 1207 // TODO(kalman): add an invalidation observer interface to ScriptContext. | 1158 // TODO(kalman): add an invalidation observer interface to ScriptContext. |
| 1208 std::set<ScriptContext*> removed_contexts = | 1159 std::set<ScriptContext*> removed_contexts = |
| 1209 script_context_set_->OnExtensionUnloaded(id); | 1160 script_context_set_->OnExtensionUnloaded(id); |
| 1210 for (ScriptContext* context : removed_contexts) { | 1161 for (ScriptContext* context : removed_contexts) { |
| 1211 request_sender_->InvalidateSource(context); | 1162 bindings_system_->WillReleaseScriptContext(context); |
| 1212 } | 1163 } |
| 1213 | 1164 |
| 1214 // Update the available bindings for the remaining contexts. These may have | 1165 // Update the available bindings for the remaining contexts. These may have |
| 1215 // changed if an externally_connectable extension is unloaded and a webpage | 1166 // changed if an externally_connectable extension is unloaded and a webpage |
| 1216 // is no longer accessible. | 1167 // is no longer accessible. |
| 1217 UpdateBindings(""); | 1168 UpdateBindings(""); |
| 1218 | 1169 |
| 1219 // Invalidates the messages map for the extension in case the extension is | 1170 // Invalidates the messages map for the extension in case the extension is |
| 1220 // reloaded with a new messages map. | 1171 // reloaded with a new messages map. |
| 1221 EraseL10nMessagesMap(id); | 1172 EraseL10nMessagesMap(id); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 blink::WebCustomElement::addEmbedderCustomElementName("webview"); | 1326 blink::WebCustomElement::addEmbedderCustomElementName("webview"); |
| 1376 blink::WebCustomElement::addEmbedderCustomElementName("webviewbrowserplugin"); | 1327 blink::WebCustomElement::addEmbedderCustomElementName("webviewbrowserplugin"); |
| 1377 } | 1328 } |
| 1378 | 1329 |
| 1379 void Dispatcher::UpdateBindings(const std::string& extension_id) { | 1330 void Dispatcher::UpdateBindings(const std::string& extension_id) { |
| 1380 script_context_set().ForEach(extension_id, | 1331 script_context_set().ForEach(extension_id, |
| 1381 base::Bind(&Dispatcher::UpdateBindingsForContext, | 1332 base::Bind(&Dispatcher::UpdateBindingsForContext, |
| 1382 base::Unretained(this))); | 1333 base::Unretained(this))); |
| 1383 } | 1334 } |
| 1384 | 1335 |
| 1385 // Note: this function runs on multiple threads: main renderer thread and | |
| 1386 // service worker threads. | |
| 1387 void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { | 1336 void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { |
| 1388 v8::HandleScope handle_scope(context->isolate()); | 1337 bindings_system_->UpdateBindingsForContext(context); |
| 1389 v8::Context::Scope context_scope(context->v8_context()); | 1338 Feature::Context context_type = context->context_type(); |
| 1390 | 1339 if (context_type == Feature::WEB_PAGE_CONTEXT || |
| 1391 // TODO(kalman): Make the bindings registration have zero overhead then run | 1340 context_type == Feature::BLESSED_WEB_PAGE_CONTEXT) { |
| 1392 // the same code regardless of context type. | 1341 UpdateContentCapabilities(context); |
| 1393 switch (context->context_type()) { | |
| 1394 case Feature::UNSPECIFIED_CONTEXT: | |
| 1395 case Feature::WEB_PAGE_CONTEXT: | |
| 1396 case Feature::BLESSED_WEB_PAGE_CONTEXT: | |
| 1397 // Hard-code registration of any APIs that are exposed to webpage-like | |
| 1398 // contexts, because it's too expensive to run the full bindings code. | |
| 1399 // All of the same permission checks will still apply. | |
| 1400 if (context->GetAvailability("app").is_available()) | |
| 1401 RegisterBinding("app", context); | |
| 1402 if (context->GetAvailability("webstore").is_available()) | |
| 1403 RegisterBinding("webstore", context); | |
| 1404 if (context->GetAvailability("dashboardPrivate").is_available()) | |
| 1405 RegisterBinding("dashboardPrivate", context); | |
| 1406 if (IsRuntimeAvailableToContext(context)) | |
| 1407 RegisterBinding("runtime", context); | |
| 1408 UpdateContentCapabilities(context); | |
| 1409 break; | |
| 1410 | |
| 1411 case Feature::SERVICE_WORKER_CONTEXT: | |
| 1412 DCHECK(ExtensionsClient::Get() | |
| 1413 ->ExtensionAPIEnabledInExtensionServiceWorkers()); | |
| 1414 // Intentional fallthrough. | |
| 1415 case Feature::BLESSED_EXTENSION_CONTEXT: | |
| 1416 case Feature::UNBLESSED_EXTENSION_CONTEXT: | |
| 1417 case Feature::CONTENT_SCRIPT_CONTEXT: | |
| 1418 case Feature::WEBUI_CONTEXT: { | |
| 1419 // Extension context; iterate through all the APIs and bind the available | |
| 1420 // ones. | |
| 1421 const FeatureProvider* api_feature_provider = | |
| 1422 FeatureProvider::GetAPIFeatures(); | |
| 1423 for (const auto& map_entry : api_feature_provider->GetAllFeatures()) { | |
| 1424 // Internal APIs are included via require(api_name) from internal code | |
| 1425 // rather than chrome[api_name]. | |
| 1426 if (map_entry.second->IsInternal()) | |
| 1427 continue; | |
| 1428 | |
| 1429 // If this API has a parent feature (and isn't marked 'noparent'), | |
| 1430 // then this must be a function or event, so we should not register. | |
| 1431 if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr) | |
| 1432 continue; | |
| 1433 | |
| 1434 // Skip chrome.test if this isn't a test. | |
| 1435 if (map_entry.first == "test" && | |
| 1436 !base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1437 ::switches::kTestType)) { | |
| 1438 continue; | |
| 1439 } | |
| 1440 | |
| 1441 if (context->IsAnyFeatureAvailableToContext(*map_entry.second)) { | |
| 1442 // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread | |
| 1443 // safety issue? | |
| 1444 RegisterBinding(map_entry.first, context); | |
| 1445 } | |
| 1446 } | |
| 1447 break; | |
| 1448 } | |
| 1449 } | 1342 } |
| 1450 } | 1343 } |
| 1451 | 1344 |
| 1452 void Dispatcher::RegisterBinding(const std::string& api_name, | |
| 1453 ScriptContext* context) { | |
| 1454 std::string bind_name; | |
| 1455 v8::Local<v8::Object> bind_object = | |
| 1456 GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context); | |
| 1457 | |
| 1458 // Empty if the bind object failed to be created, probably because the | |
| 1459 // extension overrode chrome with a non-object, e.g. window.chrome = true. | |
| 1460 if (bind_object.IsEmpty()) | |
| 1461 return; | |
| 1462 | |
| 1463 v8::Local<v8::String> v8_bind_name = | |
| 1464 v8::String::NewFromUtf8(context->isolate(), bind_name.c_str()); | |
| 1465 if (bind_object->HasRealNamedProperty(v8_bind_name)) { | |
| 1466 // The bind object may already have the property if the API has been | |
| 1467 // registered before (or if the extension has put something there already, | |
| 1468 // but, whatevs). | |
| 1469 // | |
| 1470 // In the former case, we need to re-register the bindings for the APIs | |
| 1471 // which the extension now has permissions for (if any), but not touch any | |
| 1472 // others so that we don't destroy state such as event listeners. | |
| 1473 // | |
| 1474 // TODO(kalman): Only register available APIs to make this all moot. | |
| 1475 if (bind_object->HasRealNamedCallbackProperty(v8_bind_name)) | |
| 1476 return; // lazy binding still there, nothing to do | |
| 1477 if (bind_object->Get(v8_bind_name)->IsObject()) | |
| 1478 return; // binding has already been fully installed | |
| 1479 } | |
| 1480 | |
| 1481 ModuleSystem* module_system = context->module_system(); | |
| 1482 if (!source_map_.Contains(api_name)) { | |
| 1483 module_system->RegisterNativeHandler( | |
| 1484 api_name, | |
| 1485 std::unique_ptr<NativeHandler>( | |
| 1486 new BindingGeneratingNativeHandler(context, api_name, "binding"))); | |
| 1487 module_system->SetNativeLazyField( | |
| 1488 bind_object, bind_name, api_name, "binding"); | |
| 1489 } else { | |
| 1490 module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); | |
| 1491 } | |
| 1492 } | |
| 1493 | |
| 1494 // NOTE: please use the naming convention "foo_natives" for these. | 1345 // NOTE: please use the naming convention "foo_natives" for these. |
| 1495 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, | 1346 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
| 1496 ScriptContext* context, | 1347 ScriptContext* context, |
| 1497 RequestSender* request_sender, | 1348 RequestSender* request_sender, |
| 1498 V8SchemaRegistry* v8_schema_registry) { | 1349 V8SchemaRegistry* v8_schema_registry) { |
| 1499 RegisterNativeHandlers(module_system, context, this, request_sender, | 1350 RegisterNativeHandlers(module_system, context, this, request_sender, |
| 1500 v8_schema_registry); | 1351 v8_schema_registry); |
| 1501 const Extension* extension = context->extension(); | 1352 const Extension* extension = context->extension(); |
| 1502 int manifest_version = extension ? extension->manifest_version() : 1; | 1353 int manifest_version = extension ? extension->manifest_version() : 1; |
| 1503 bool is_component_extension = | 1354 bool is_component_extension = |
| 1504 extension && Manifest::IsComponentLocation(extension->location()); | 1355 extension && Manifest::IsComponentLocation(extension->location()); |
| 1505 bool send_request_disabled = | 1356 bool send_request_disabled = |
| 1506 (extension && Manifest::IsUnpackedLocation(extension->location()) && | 1357 (extension && Manifest::IsUnpackedLocation(extension->location()) && |
| 1507 BackgroundInfo::HasLazyBackgroundPage(extension)); | 1358 BackgroundInfo::HasLazyBackgroundPage(extension)); |
| 1508 module_system->RegisterNativeHandler( | 1359 module_system->RegisterNativeHandler( |
| 1509 "process", | 1360 "process", |
| 1510 std::unique_ptr<NativeHandler>(new ProcessInfoNativeHandler( | 1361 std::unique_ptr<NativeHandler>(new ProcessInfoNativeHandler( |
| 1511 context, context->GetExtensionID(), | 1362 context, context->GetExtensionID(), |
| 1512 context->GetContextTypeDescription(), | 1363 context->GetContextTypeDescription(), |
| 1513 ExtensionsRendererClient::Get()->IsIncognitoProcess(), | 1364 ExtensionsRendererClient::Get()->IsIncognitoProcess(), |
| 1514 is_component_extension, manifest_version, send_request_disabled))); | 1365 is_component_extension, manifest_version, send_request_disabled))); |
| 1515 | 1366 |
| 1516 delegate_->RegisterNativeHandlers(this, module_system, context); | 1367 delegate_->RegisterNativeHandlers(this, module_system, context); |
| 1517 } | 1368 } |
| 1518 | 1369 |
| 1519 bool Dispatcher::IsRuntimeAvailableToContext(ScriptContext* context) { | |
| 1520 for (const auto& extension : | |
| 1521 *RendererExtensionRegistry::Get()->GetMainThreadExtensionSet()) { | |
| 1522 ExternallyConnectableInfo* info = static_cast<ExternallyConnectableInfo*>( | |
| 1523 extension->GetManifestData(manifest_keys::kExternallyConnectable)); | |
| 1524 if (info && info->matches.MatchesURL(context->url())) | |
| 1525 return true; | |
| 1526 } | |
| 1527 return false; | |
| 1528 } | |
| 1529 | |
| 1530 void Dispatcher::UpdateContentCapabilities(ScriptContext* context) { | 1370 void Dispatcher::UpdateContentCapabilities(ScriptContext* context) { |
| 1531 APIPermissionSet permissions; | 1371 APIPermissionSet permissions; |
| 1532 for (const auto& extension : | 1372 for (const auto& extension : |
| 1533 *RendererExtensionRegistry::Get()->GetMainThreadExtensionSet()) { | 1373 *RendererExtensionRegistry::Get()->GetMainThreadExtensionSet()) { |
| 1534 blink::WebLocalFrame* web_frame = context->web_frame(); | 1374 blink::WebLocalFrame* web_frame = context->web_frame(); |
| 1535 GURL url = context->url(); | 1375 GURL url = context->url(); |
| 1536 // We allow about:blank pages to take on the privileges of their parents if | 1376 // We allow about:blank pages to take on the privileges of their parents if |
| 1537 // they aren't sandboxed. | 1377 // they aren't sandboxed. |
| 1538 if (web_frame && !web_frame->getSecurityOrigin().isUnique()) | 1378 if (web_frame && !web_frame->getSecurityOrigin().isUnique()) |
| 1539 url = ScriptContext::GetEffectiveDocumentURL(web_frame, url, true); | 1379 url = ScriptContext::GetEffectiveDocumentURL(web_frame, url, true); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1564 iter != active_extension_ids_.end(); | 1404 iter != active_extension_ids_.end(); |
| 1565 ++iter) { | 1405 ++iter) { |
| 1566 const Extension* extension = | 1406 const Extension* extension = |
| 1567 RendererExtensionRegistry::Get()->GetByID(*iter); | 1407 RendererExtensionRegistry::Get()->GetByID(*iter); |
| 1568 if (extension && extension->is_platform_app()) | 1408 if (extension && extension->is_platform_app()) |
| 1569 return true; | 1409 return true; |
| 1570 } | 1410 } |
| 1571 return false; | 1411 return false; |
| 1572 } | 1412 } |
| 1573 | 1413 |
| 1574 // static. | |
| 1575 v8::Local<v8::Object> Dispatcher::GetOrCreateObject( | |
| 1576 const v8::Local<v8::Object>& object, | |
| 1577 const std::string& field, | |
| 1578 v8::Isolate* isolate) { | |
| 1579 v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); | |
| 1580 // If the object has a callback property, it is assumed it is an unavailable | |
| 1581 // API, so it is safe to delete. This is checked before GetOrCreateObject is | |
| 1582 // called. | |
| 1583 if (object->HasRealNamedCallbackProperty(key)) { | |
| 1584 object->Delete(key); | |
| 1585 } else if (object->HasRealNamedProperty(key)) { | |
| 1586 v8::Local<v8::Value> value = object->Get(key); | |
| 1587 CHECK(value->IsObject()); | |
| 1588 return v8::Local<v8::Object>::Cast(value); | |
| 1589 } | |
| 1590 | |
| 1591 v8::Local<v8::Object> new_object = v8::Object::New(isolate); | |
| 1592 object->Set(key, new_object); | |
| 1593 return new_object; | |
| 1594 } | |
| 1595 | |
| 1596 // static. | |
| 1597 v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( | |
| 1598 const std::string& api_name, | |
| 1599 std::string* bind_name, | |
| 1600 ScriptContext* context) { | |
| 1601 std::vector<std::string> split = base::SplitString( | |
| 1602 api_name, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 1603 | |
| 1604 v8::Local<v8::Object> bind_object; | |
| 1605 | |
| 1606 // Check if this API has an ancestor. If the API's ancestor is available and | |
| 1607 // the API is not available, don't install the bindings for this API. If | |
| 1608 // the API is available and its ancestor is not, delete the ancestor and | |
| 1609 // install the bindings for the API. This is to prevent loading the ancestor | |
| 1610 // API schema if it will not be needed. | |
| 1611 // | |
| 1612 // For example: | |
| 1613 // If app is available and app.window is not, just install app. | |
| 1614 // If app.window is available and app is not, delete app and install | |
| 1615 // app.window on a new object so app does not have to be loaded. | |
| 1616 const FeatureProvider* api_feature_provider = | |
| 1617 FeatureProvider::GetAPIFeatures(); | |
| 1618 std::string ancestor_name; | |
| 1619 bool only_ancestor_available = false; | |
| 1620 | |
| 1621 for (size_t i = 0; i < split.size() - 1; ++i) { | |
| 1622 ancestor_name += (i ? "." : "") + split[i]; | |
| 1623 if (api_feature_provider->GetFeature(ancestor_name) && | |
| 1624 context->GetAvailability(ancestor_name).is_available() && | |
| 1625 !context->GetAvailability(api_name).is_available()) { | |
| 1626 only_ancestor_available = true; | |
| 1627 break; | |
| 1628 } | |
| 1629 | |
| 1630 if (bind_object.IsEmpty()) { | |
| 1631 bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); | |
| 1632 if (bind_object.IsEmpty()) | |
| 1633 return v8::Local<v8::Object>(); | |
| 1634 } | |
| 1635 bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); | |
| 1636 } | |
| 1637 | |
| 1638 if (only_ancestor_available) | |
| 1639 return v8::Local<v8::Object>(); | |
| 1640 | |
| 1641 if (bind_name) | |
| 1642 *bind_name = split.back(); | |
| 1643 | |
| 1644 return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context)) | |
| 1645 : bind_object; | |
| 1646 } | |
| 1647 | |
| 1648 void Dispatcher::RequireGuestViewModules(ScriptContext* context) { | 1414 void Dispatcher::RequireGuestViewModules(ScriptContext* context) { |
| 1649 Feature::Context context_type = context->context_type(); | 1415 Feature::Context context_type = context->context_type(); |
| 1650 ModuleSystem* module_system = context->module_system(); | 1416 ModuleSystem* module_system = context->module_system(); |
| 1651 bool requires_guest_view_module = false; | 1417 bool requires_guest_view_module = false; |
| 1652 | 1418 |
| 1653 // Require AppView. | 1419 // Require AppView. |
| 1654 if (context->GetAvailability("appViewEmbedderInternal").is_available()) { | 1420 if (context->GetAvailability("appViewEmbedderInternal").is_available()) { |
| 1655 requires_guest_view_module = true; | 1421 requires_guest_view_module = true; |
| 1656 module_system->Require("appView"); | 1422 module_system->Require("appView"); |
| 1657 } | 1423 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1688 // The "guestViewDeny" module must always be loaded last. It registers | 1454 // The "guestViewDeny" module must always be loaded last. It registers |
| 1689 // error-providing custom elements for the GuestView types that are not | 1455 // error-providing custom elements for the GuestView types that are not |
| 1690 // available, and thus all of those types must have been checked and loaded | 1456 // available, and thus all of those types must have been checked and loaded |
| 1691 // (or not loaded) beforehand. | 1457 // (or not loaded) beforehand. |
| 1692 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { | 1458 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { |
| 1693 module_system->Require("guestViewDeny"); | 1459 module_system->Require("guestViewDeny"); |
| 1694 } | 1460 } |
| 1695 } | 1461 } |
| 1696 | 1462 |
| 1697 } // namespace extensions | 1463 } // namespace extensions |
| OLD | NEW |