Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: extensions/browser/extension_function_dispatcher.cc

Issue 2166523003: Add ref count to service workers for extension API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sync@tott Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/browser/extension_function_dispatcher.h" 5 #include "extensions/browser/extension_function_dispatcher.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_string_value_serializer.h" 10 #include "base/json/json_string_value_serializer.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/metrics/sparse_histogram.h" 16 #include "base/metrics/sparse_histogram.h"
17 #include "base/process/process.h" 17 #include "base/process/process.h"
18 #include "base/profiler/scoped_profile.h" 18 #include "base/profiler/scoped_profile.h"
19 #include "base/scoped_observer.h" 19 #include "base/scoped_observer.h"
20 #include "base/values.h" 20 #include "base/values.h"
21 #include "build/build_config.h" 21 #include "build/build_config.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/render_frame_host.h" 23 #include "content/public/browser/render_frame_host.h"
24 #include "content/public/browser/render_process_host.h" 24 #include "content/public/browser/render_process_host.h"
25 #include "content/public/browser/render_process_host_observer.h" 25 #include "content/public/browser/render_process_host_observer.h"
26 #include "content/public/browser/render_view_host.h" 26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/service_worker_context.h"
27 #include "content/public/browser/user_metrics.h" 28 #include "content/public/browser/user_metrics.h"
28 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_contents_observer.h" 30 #include "content/public/browser/web_contents_observer.h"
30 #include "content/public/common/result_codes.h" 31 #include "content/public/common/result_codes.h"
31 #include "extensions/browser/api_activity_monitor.h" 32 #include "extensions/browser/api_activity_monitor.h"
32 #include "extensions/browser/extension_function_registry.h" 33 #include "extensions/browser/extension_function_registry.h"
33 #include "extensions/browser/extension_registry.h" 34 #include "extensions/browser/extension_registry.h"
34 #include "extensions/browser/extension_system.h" 35 #include "extensions/browser/extension_system.h"
36 #include "extensions/browser/extension_util.h"
35 #include "extensions/browser/extensions_browser_client.h" 37 #include "extensions/browser/extensions_browser_client.h"
36 #include "extensions/browser/io_thread_extension_message_filter.h" 38 #include "extensions/browser/io_thread_extension_message_filter.h"
37 #include "extensions/browser/process_manager.h" 39 #include "extensions/browser/process_manager.h"
38 #include "extensions/browser/process_map.h" 40 #include "extensions/browser/process_map.h"
39 #include "extensions/browser/quota_service.h" 41 #include "extensions/browser/quota_service.h"
42 #include "extensions/common/constants.h"
40 #include "extensions/common/extension_api.h" 43 #include "extensions/common/extension_api.h"
41 #include "extensions/common/extension_messages.h" 44 #include "extensions/common/extension_messages.h"
42 #include "extensions/common/extension_set.h" 45 #include "extensions/common/extension_set.h"
43 #include "extensions/common/extensions_client.h" 46 #include "extensions/common/extensions_client.h"
44 #include "ipc/ipc_message.h" 47 #include "ipc/ipc_message.h"
45 #include "ipc/ipc_message_macros.h" 48 #include "ipc/ipc_message_macros.h"
46 49
47 using content::BrowserThread; 50 using content::BrowserThread;
48 using content::RenderViewHost; 51 using content::RenderViewHost;
49 52
50 namespace extensions { 53 namespace extensions {
51 namespace { 54 namespace {
52 55
53 // Notifies the ApiActivityMonitor that an extension API function has been 56 // Notifies the ApiActivityMonitor that an extension API function has been
54 // called. May be called from any thread. 57 // called. May be called from any thread.
55 void NotifyApiFunctionCalled(const std::string& extension_id, 58 void NotifyApiFunctionCalled(const std::string& extension_id,
56 const std::string& api_name, 59 const std::string& api_name,
57 const base::ListValue& args, 60 const base::ListValue& args,
58 content::BrowserContext* browser_context) { 61 content::BrowserContext* browser_context) {
59 activity_monitor::OnApiFunctionCalled(browser_context, extension_id, api_name, 62 activity_monitor::OnApiFunctionCalled(browser_context, extension_id, api_name,
60 args); 63 args);
61 } 64 }
62 65
66 bool IsRequestFromServiceWorker(
67 const ExtensionHostMsg_Request_Params& request_params) {
68 return request_params.service_worker_version_id !=
69 extensions::kInvalidServiceWorkerVersionId;
70 }
71
63 // Separate copy of ExtensionAPI used for IO thread extension functions. We need 72 // Separate copy of ExtensionAPI used for IO thread extension functions. We need
64 // this because ExtensionAPI has mutable data. It should be possible to remove 73 // this because ExtensionAPI has mutable data. It should be possible to remove
65 // this once all the extension APIs are updated to the feature system. 74 // this once all the extension APIs are updated to the feature system.
66 struct Static { 75 struct Static {
67 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {} 76 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {}
68 std::unique_ptr<ExtensionAPI> api; 77 std::unique_ptr<ExtensionAPI> api;
69 }; 78 };
70 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; 79 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER;
71 80
72 // Kills the specified process because it sends us a malformed message. 81 // Kills the specified process because it sends us a malformed message.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 UIThreadWorkerResponseCallbackWrapper> 279 UIThreadWorkerResponseCallbackWrapper>
271 observer_; 280 observer_;
272 const int render_process_id_; 281 const int render_process_id_;
273 const int worker_thread_id_; 282 const int worker_thread_id_;
274 base::WeakPtrFactory<UIThreadWorkerResponseCallbackWrapper> weak_ptr_factory_; 283 base::WeakPtrFactory<UIThreadWorkerResponseCallbackWrapper> weak_ptr_factory_;
275 284
276 DISALLOW_COPY_AND_ASSIGN(UIThreadWorkerResponseCallbackWrapper); 285 DISALLOW_COPY_AND_ASSIGN(UIThreadWorkerResponseCallbackWrapper);
277 }; 286 };
278 287
279 struct ExtensionFunctionDispatcher::WorkerResponseCallbackMapKey { 288 struct ExtensionFunctionDispatcher::WorkerResponseCallbackMapKey {
280 WorkerResponseCallbackMapKey(int render_process_id, int embedded_worker_id) 289 WorkerResponseCallbackMapKey(int render_process_id,
290 int64_t service_worker_version_id)
281 : render_process_id(render_process_id), 291 : render_process_id(render_process_id),
282 embedded_worker_id(embedded_worker_id) {} 292 service_worker_version_id(service_worker_version_id) {}
283 293
284 bool operator<(const WorkerResponseCallbackMapKey& other) const { 294 bool operator<(const WorkerResponseCallbackMapKey& other) const {
285 return std::tie(render_process_id, embedded_worker_id) < 295 return std::tie(render_process_id, service_worker_version_id) <
286 std::tie(other.render_process_id, other.embedded_worker_id); 296 std::tie(other.render_process_id, other.service_worker_version_id);
287 } 297 }
288 298
289 int render_process_id; 299 int render_process_id;
290 int embedded_worker_id; 300 int64_t service_worker_version_id;
291 }; 301 };
292 302
293 WindowController* 303 WindowController*
294 ExtensionFunctionDispatcher::Delegate::GetExtensionWindowController() const { 304 ExtensionFunctionDispatcher::Delegate::GetExtensionWindowController() const {
295 return nullptr; 305 return nullptr;
296 } 306 }
297 307
298 content::WebContents* 308 content::WebContents*
299 ExtensionFunctionDispatcher::Delegate::GetAssociatedWebContents() const { 309 ExtensionFunctionDispatcher::Delegate::GetAssociatedWebContents() const {
300 return nullptr; 310 return nullptr;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 ui_thread_response_callback_wrappers_[render_frame_host] = 421 ui_thread_response_callback_wrappers_[render_frame_host] =
412 callback_wrapper; 422 callback_wrapper;
413 } else { 423 } else {
414 callback_wrapper = iter->second; 424 callback_wrapper = iter->second;
415 } 425 }
416 DispatchWithCallbackInternal( 426 DispatchWithCallbackInternal(
417 params, render_frame_host, render_process_id, 427 params, render_frame_host, render_process_id,
418 callback_wrapper->CreateCallback(params.request_id)); 428 callback_wrapper->CreateCallback(params.request_id));
419 } else { 429 } else {
420 // Extension API from Service Worker. 430 // Extension API from Service Worker.
421 DCHECK_GE(params.embedded_worker_id, 0); 431 DCHECK_NE(kInvalidServiceWorkerVersionId, params.service_worker_version_id);
422 WorkerResponseCallbackMapKey key(render_process_id, 432 WorkerResponseCallbackMapKey key(render_process_id,
423 params.embedded_worker_id); 433 params.service_worker_version_id);
424 UIThreadWorkerResponseCallbackWrapperMap::const_iterator iter = 434 UIThreadWorkerResponseCallbackWrapperMap::const_iterator iter =
425 ui_thread_response_callback_wrappers_for_worker_.find(key); 435 ui_thread_response_callback_wrappers_for_worker_.find(key);
426 UIThreadWorkerResponseCallbackWrapper* callback_wrapper = nullptr; 436 UIThreadWorkerResponseCallbackWrapper* callback_wrapper = nullptr;
427 if (iter == ui_thread_response_callback_wrappers_for_worker_.end()) { 437 if (iter == ui_thread_response_callback_wrappers_for_worker_.end()) {
428 callback_wrapper = new UIThreadWorkerResponseCallbackWrapper( 438 callback_wrapper = new UIThreadWorkerResponseCallbackWrapper(
429 AsWeakPtr(), render_process_id, params.worker_thread_id); 439 AsWeakPtr(), render_process_id, params.worker_thread_id);
430 ui_thread_response_callback_wrappers_for_worker_[key] = 440 ui_thread_response_callback_wrappers_for_worker_[key] =
431 base::WrapUnique(callback_wrapper); 441 base::WrapUnique(callback_wrapper);
432 } else { 442 } else {
433 callback_wrapper = iter->second.get(); 443 callback_wrapper = iter->second.get();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 ExtensionAPI::GetSharedInstance(), browser_context_, callback)); 475 ExtensionAPI::GetSharedInstance(), browser_context_, callback));
466 if (!function.get()) 476 if (!function.get())
467 return; 477 return;
468 478
469 UIThreadExtensionFunction* function_ui = 479 UIThreadExtensionFunction* function_ui =
470 function->AsUIThreadExtensionFunction(); 480 function->AsUIThreadExtensionFunction();
471 if (!function_ui) { 481 if (!function_ui) {
472 NOTREACHED(); 482 NOTREACHED();
473 return; 483 return;
474 } 484 }
475 if (params.embedded_worker_id != -1) { 485 if (IsRequestFromServiceWorker(params)) {
476 function_ui->set_is_from_service_worker(true); 486 function_ui->set_service_worker_version_id(
487 params.service_worker_version_id);
477 } else { 488 } else {
478 function_ui->SetRenderFrameHost(render_frame_host); 489 function_ui->SetRenderFrameHost(render_frame_host);
479 } 490 }
480 function_ui->set_dispatcher(AsWeakPtr()); 491 function_ui->set_dispatcher(AsWeakPtr());
481 function_ui->set_browser_context(browser_context_); 492 function_ui->set_browser_context(browser_context_);
482 if (extension && 493 if (extension &&
483 ExtensionsBrowserClient::Get()->CanExtensionCrossIncognito( 494 ExtensionsBrowserClient::Get()->CanExtensionCrossIncognito(
484 extension, browser_context_)) { 495 extension, browser_context_)) {
485 function->set_include_incognito(true); 496 function->set_include_incognito(true);
486 } 497 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 function->OnQuotaExceeded(violation_error); 540 function->OnQuotaExceeded(violation_error);
530 } 541 }
531 542
532 // Note: do not access |this| after this point. We may have been deleted 543 // Note: do not access |this| after this point. We may have been deleted
533 // if function->Run() ended up closing the tab that owns us. 544 // if function->Run() ended up closing the tab that owns us.
534 545
535 // Check if extension was uninstalled by management.uninstall. 546 // Check if extension was uninstalled by management.uninstall.
536 if (!registry->enabled_extensions().GetByID(params.extension_id)) 547 if (!registry->enabled_extensions().GetByID(params.extension_id))
537 return; 548 return;
538 549
539 // We only adjust the keepalive count for UIThreadExtensionFunction for 550 if (!IsRequestFromServiceWorker(params)) {
540 // now, largely for simplicity's sake. This is OK because currently, only 551 // Increment ref count for non-service worker extension API. Ref count for
541 // the webRequest API uses IOThreadExtensionFunction, and that API is not 552 // service worker extension API is handled separately on IO thread via IPC.
542 // compatible with lazy background pages. 553
543 // TODO(lazyboy): API functions from extension Service Worker will incorrectly 554 // We only adjust the keepalive count for UIThreadExtensionFunction for
544 // change keepalive count below. 555 // now, largely for simplicity's sake. This is OK because currently, only
545 process_manager->IncrementLazyKeepaliveCount(extension); 556 // the webRequest API uses IOThreadExtensionFunction, and that API is not
557 // compatible with lazy background pages.
558 process_manager->IncrementLazyKeepaliveCount(function->extension());
559 }
546 } 560 }
547 561
548 void ExtensionFunctionDispatcher::RemoveWorkerCallbacksForProcess( 562 void ExtensionFunctionDispatcher::RemoveWorkerCallbacksForProcess(
549 int render_process_id) { 563 int render_process_id) {
550 UIThreadWorkerResponseCallbackWrapperMap& map = 564 UIThreadWorkerResponseCallbackWrapperMap& map =
551 ui_thread_response_callback_wrappers_for_worker_; 565 ui_thread_response_callback_wrappers_for_worker_;
552 for (UIThreadWorkerResponseCallbackWrapperMap::iterator it = map.begin(); 566 for (UIThreadWorkerResponseCallbackWrapperMap::iterator it = map.begin();
553 it != map.end();) { 567 it != map.end();) {
554 if (it->first.render_process_id == render_process_id) { 568 if (it->first.render_process_id == render_process_id) {
555 it = map.erase(it); 569 it = map.erase(it);
556 continue; 570 continue;
557 } 571 }
558 ++it; 572 ++it;
559 } 573 }
560 } 574 }
561 575
562 void ExtensionFunctionDispatcher::OnExtensionFunctionCompleted( 576 void ExtensionFunctionDispatcher::OnExtensionFunctionCompleted(
563 const Extension* extension) { 577 const Extension* extension,
564 // TODO(lazyboy): API functions from extension Service Worker will incorrectly 578 bool is_from_service_worker) {
565 // change keepalive count below. 579 if (extension && !is_from_service_worker) {
566 if (extension) { 580 // Decrement ref count for non-service worker extension API. Service
581 // worker extension API ref counts are handled separately on IO thread
582 // directly via IPC.
567 ProcessManager::Get(browser_context_) 583 ProcessManager::Get(browser_context_)
568 ->DecrementLazyKeepaliveCount(extension); 584 ->DecrementLazyKeepaliveCount(extension);
569 } 585 }
570 } 586 }
571 587
572 WindowController* 588 WindowController*
573 ExtensionFunctionDispatcher::GetExtensionWindowController() const { 589 ExtensionFunctionDispatcher::GetExtensionWindowController() const {
574 return delegate_ ? delegate_->GetExtensionWindowController() : nullptr; 590 return delegate_ ? delegate_->GetExtensionWindowController() : nullptr;
575 } 591 }
576 592
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 // static 650 // static
635 void ExtensionFunctionDispatcher::SendAccessDenied( 651 void ExtensionFunctionDispatcher::SendAccessDenied(
636 const ExtensionFunction::ResponseCallback& callback, 652 const ExtensionFunction::ResponseCallback& callback,
637 functions::HistogramValue histogram_value) { 653 functions::HistogramValue histogram_value) {
638 base::ListValue empty_list; 654 base::ListValue empty_list;
639 callback.Run(ExtensionFunction::FAILED, empty_list, 655 callback.Run(ExtensionFunction::FAILED, empty_list,
640 "Access to extension API denied.", histogram_value); 656 "Access to extension API denied.", histogram_value);
641 } 657 }
642 658
643 } // namespace extensions 659 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/extension_function_dispatcher.h ('k') | extensions/browser/extension_service_worker_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698