| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/browser/task_queue_util.h" |
| |
| #include "content/public/browser/browser_context.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extensions_browser_client.h" |
| #include "extensions/browser/lazy_background_task_queue.h" |
| #include "extensions/browser/lazy_context_id.h" |
| #include "extensions/browser/service_worker_task_queue.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/extension_id.h" |
| #include "extensions/common/manifest_handlers/background_info.h" |
| #include "extensions/common/manifest_handlers/incognito_info.h" |
| |
| namespace extensions { |
| |
| namespace { |
| |
| // Get the ServiceWorkerTaskQueue instance for the BrowserContext. |
| // |
| ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForBrowserContext( |
| content::BrowserContext* browser_context, |
| bool is_split_mode) { |
| content::BrowserContext* context_to_use = browser_context; |
| // Incognito extensions in split mode use their own task queue, while those |
| // in spanning mode use the task queue of the original BrowserContext. |
| if (browser_context->IsOffTheRecord() && !is_split_mode) { |
| context_to_use = |
| ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context); |
| } |
| return ServiceWorkerTaskQueue::Get(context_to_use); |
| } |
| |
| // Get the ServiceWorkerTaskQueue instance for the extension. |
| // |
| // Only call this for a SW-based extension. |
| ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForExtension( |
| content::BrowserContext* browser_context, |
| const Extension* extension) { |
| DCHECK(BackgroundInfo::IsServiceWorkerBased(extension)); |
| return GetServiceWorkerTaskQueueForBrowserContext( |
| browser_context, IncognitoInfo::IsSplitMode(extension)); |
| } |
| |
| // Get the ServiceWorkerTaskQueue instance for the extension ID. |
| // |
| // Only call this for a SW-based extension. |
| ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForExtensionId( |
| content::BrowserContext* browser_context, |
| const ExtensionId& extension_id) { |
| // Incognito extensions in split mode use their own task queue, while those |
| // in spanning mode use the task queue of the original BrowserContext. |
| // This is an optimization to avoid looking up an Extension instance, |
| // since we only need it for the off-the-record case. |
| if (!browser_context->IsOffTheRecord()) { |
| return ServiceWorkerTaskQueue::Get(browser_context); |
| } |
| |
| const Extension* extension = ExtensionRegistry::Get(browser_context) |
| ->enabled_extensions() |
| .GetByID(extension_id); |
| DCHECK(extension); |
| return GetServiceWorkerTaskQueueForExtension(browser_context, extension); |
| } |
| |
| // Use a pointer-to-member function so we can use the same logic for the |
| // activation and deactivation paths. |
| using TaskQueueFunction = void (ServiceWorkerTaskQueue::*)(const Extension*); |
| |
| void DoTaskQueueFunction(content::BrowserContext* browser_context, |
| const Extension* extension, |
| TaskQueueFunction function) { |
| // This is only necessary for service worker-based extensions. |
| if (!BackgroundInfo::IsServiceWorkerBased(extension)) |
| return; |
| |
| ServiceWorkerTaskQueue* const queue = |
| ServiceWorkerTaskQueue::Get(browser_context); |
| (queue->*function)(extension); |
| |
| // There is a separate task queue for the off-the-record context |
| // for any extension running in split mode. |
| if (!ExtensionsBrowserClient::Get()->HasOffTheRecordContext( |
| browser_context) || |
| !IncognitoInfo::IsSplitMode(extension) || |
| !ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( |
| extension->id(), browser_context)) { |
| return; |
| } |
| |
| content::BrowserContext* off_the_record_context = |
| ExtensionsBrowserClient::Get()->GetOffTheRecordContext(browser_context); |
| DCHECK(off_the_record_context); |
| ServiceWorkerTaskQueue* const off_the_record_queue = |
| ServiceWorkerTaskQueue::Get(off_the_record_context); |
| (off_the_record_queue->*function)(extension); |
| } |
| |
| } // anonymous namespace |
| |
| LazyContextTaskQueue* GetTaskQueueForLazyContextId( |
| const LazyContextId& context_id) { |
| if (context_id.is_for_event_page()) |
| return LazyBackgroundTaskQueue::Get(context_id.browser_context()); |
| |
| DCHECK(context_id.is_for_service_worker()); |
| return GetServiceWorkerTaskQueueForExtensionId(context_id.browser_context(), |
| context_id.extension_id()); |
| } |
| |
| void ActivateTaskQueueForExtension(content::BrowserContext* browser_context, |
| const Extension* extension) { |
| DCHECK(!browser_context->IsOffTheRecord()); |
| DoTaskQueueFunction(browser_context, extension, |
| &ServiceWorkerTaskQueue::ActivateExtension); |
| } |
| |
| void DeactivateTaskQueueForExtension(content::BrowserContext* browser_context, |
| const Extension* extension) { |
| DCHECK(!browser_context->IsOffTheRecord()); |
| DoTaskQueueFunction(browser_context, extension, |
| &ServiceWorkerTaskQueue::DeactivateExtension); |
| } |
| |
| } // namespace extensions |