[Extensions] Clean up LazyContextId issues.
The CL cleans up issues within LazyContextId and how it's used. 1. LazyContextId currently stores the service worker scope for instances created for a service worker-based extension. Since we only ever register the extension's script at the root scope, there's no need to store this, since it can be inferred from the extension's ID. 2. ServiceWorkerTaskQueue::SequencedContextId is a std::pair containing a LazyContextId and a base::UnguessableToken that's generated when the queue tries to activate the service worker. This CL changes this to a struct with named fields for clarity. It also only stores the extension's ID and the BrowserContext from the LazyContextId, since that's all that's needed. 3. There are places where LazyContextId instances are created and the type of the instance (for and EventPage-based extension or a service worker-based extension) is inferred from the constructor used. Since the scope is no longer saved, there is no longer a need for unique constructors and the type cannot be inferred. This CL adds static member functions that are clearly named and create the expected type of LazyContextId. There is also an option to create one for an extension where the function determines the type of LazyContextId based on the extension. This is the safest and clearest way, so many call sites are migrated to use this static member function. Bug: None Change-Id: If40c9a7fa9fa0148bb2d1b0faa7f988a18dfe654 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5050418 Reviewed-by: Fabian Sommer <fabiansommer@chromium.org> Reviewed-by: Ben Reich <benreich@chromium.org> Reviewed-by: Trent Apted <tapted@chromium.org> Auto-Submit: David Bertoni <dbertoni@chromium.org> Commit-Queue: David Bertoni <dbertoni@chromium.org> Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1236662}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b061739061
commit
9cfed26659
apps
chrome/browser
extensions
@ -295,7 +295,9 @@ class PlatformAppPathLauncher
|
|||||||
// available, or it might be in the process of being unloaded, in which case
|
// available, or it might be in the process of being unloaded, in which case
|
||||||
// the lazy background task queue is used to load the extension and then
|
// the lazy background task queue is used to load the extension and then
|
||||||
// call back to us.
|
// call back to us.
|
||||||
const extensions::LazyContextId context_id(context_, extension_id);
|
const auto context_id =
|
||||||
|
extensions::LazyContextId::ForExtension(context_, app);
|
||||||
|
CHECK(context_id.IsForBackgroundPage());
|
||||||
extensions::LazyContextTaskQueue* const queue = context_id.GetTaskQueue();
|
extensions::LazyContextTaskQueue* const queue = context_id.GetTaskQueue();
|
||||||
if (queue->ShouldEnqueueTask(context_, app)) {
|
if (queue->ShouldEnqueueTask(context_, app)) {
|
||||||
queue->AddPendingTask(
|
queue->AddPendingTask(
|
||||||
|
@ -245,7 +245,9 @@ void FileBrowserHandlerExecutor::ExecuteFileActionsOnUIThread(
|
|||||||
extensions::ExtensionHost* extension_host =
|
extensions::ExtensionHost* extension_host =
|
||||||
manager->GetBackgroundHostForExtension(extension_->id());
|
manager->GetBackgroundHostForExtension(extension_->id());
|
||||||
|
|
||||||
const extensions::LazyContextId context_id(profile_, extension_->id());
|
const auto context_id =
|
||||||
|
extensions::LazyContextId::ForExtension(profile_, extension_.get());
|
||||||
|
CHECK(context_id.IsForBackgroundPage());
|
||||||
extensions::LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
extensions::LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
||||||
|
|
||||||
if (task_queue->ShouldEnqueueTask(profile_, extension_.get())) {
|
if (task_queue->ShouldEnqueueTask(profile_, extension_.get())) {
|
||||||
|
@ -195,8 +195,8 @@ class ExtensionLoadObserver final
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the extension's background host is active.
|
// Ensure that the extension's background host is active.
|
||||||
const extensions::LazyContextId context_id(browser_context,
|
const auto context_id =
|
||||||
extension->id());
|
extensions::LazyContextId::ForExtension(browser_context, extension);
|
||||||
extensions::LazyContextTaskQueue* queue = context_id.GetTaskQueue();
|
extensions::LazyContextTaskQueue* queue = context_id.GetTaskQueue();
|
||||||
if (!queue->ShouldEnqueueTask(browser_context, extension)) {
|
if (!queue->ShouldEnqueueTask(browser_context, extension)) {
|
||||||
// The background host already exists.
|
// The background host already exists.
|
||||||
|
@ -175,7 +175,9 @@ void FileBrowserHandlerExecutorFlow::PrepareToLaunch() {
|
|||||||
// available, or it might be in the process of being unloaded, in which case
|
// available, or it might be in the process of being unloaded, in which case
|
||||||
// the lazy background task queue is used to load the extension and then
|
// the lazy background task queue is used to load the extension and then
|
||||||
// call back to us.
|
// call back to us.
|
||||||
const extensions::LazyContextId context_id(profile_, extension_->id());
|
const auto context_id =
|
||||||
|
extensions::LazyContextId::ForExtension(profile_, extension_.get());
|
||||||
|
CHECK(context_id.IsForBackgroundPage());
|
||||||
extensions::LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
extensions::LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
||||||
|
|
||||||
if (task_queue->ShouldEnqueueTask(profile_, extension_.get())) {
|
if (task_queue->ShouldEnqueueTask(profile_, extension_.get())) {
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
#include "extensions/browser/api/offscreen/offscreen_document_manager.h"
|
#include "extensions/browser/api/offscreen/offscreen_document_manager.h"
|
||||||
#include "extensions/browser/background_script_executor.h"
|
#include "extensions/browser/background_script_executor.h"
|
||||||
#include "extensions/browser/extension_util.h"
|
#include "extensions/browser/extension_util.h"
|
||||||
|
#include "extensions/browser/lazy_context_id.h"
|
||||||
|
#include "extensions/browser/lazy_context_task_queue.h"
|
||||||
#include "extensions/browser/offscreen_document_host.h"
|
#include "extensions/browser/offscreen_document_host.h"
|
||||||
#include "extensions/browser/service_worker_task_queue.h"
|
|
||||||
#include "extensions/browser/test_extension_registry_observer.h"
|
#include "extensions/browser/test_extension_registry_observer.h"
|
||||||
#include "extensions/common/extension.h"
|
#include "extensions/common/extension.h"
|
||||||
#include "extensions/common/features/feature_channel.h"
|
#include "extensions/common/features/feature_channel.h"
|
||||||
@ -99,8 +100,10 @@ scoped_refptr<const Extension> SetExtensionIncognitoEnabled(
|
|||||||
// Wakes up the service worker for the `extension` in the given `profile`.
|
// Wakes up the service worker for the `extension` in the given `profile`.
|
||||||
void WakeUpServiceWorker(const Extension& extension, Profile& profile) {
|
void WakeUpServiceWorker(const Extension& extension, Profile& profile) {
|
||||||
base::RunLoop run_loop;
|
base::RunLoop run_loop;
|
||||||
ServiceWorkerTaskQueue::Get(&profile)->AddPendingTask(
|
const auto context_id = LazyContextId::ForExtension(&profile, &extension);
|
||||||
LazyContextId(&profile, extension.id(), extension.url()),
|
ASSERT_TRUE(context_id.IsForServiceWorker());
|
||||||
|
context_id.GetTaskQueue()->AddPendingTask(
|
||||||
|
context_id,
|
||||||
base::BindOnce([](std::unique_ptr<LazyContextTaskQueue::ContextInfo>) {
|
base::BindOnce([](std::unique_ptr<LazyContextTaskQueue::ContextInfo>) {
|
||||||
}).Then(run_loop.QuitWhenIdleClosure()));
|
}).Then(run_loop.QuitWhenIdleClosure()));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
|
@ -73,9 +73,7 @@ void InspectInactiveServiceWorkerBackground(const Extension* extension,
|
|||||||
DevToolsOpenedByAction opened_by) {
|
DevToolsOpenedByAction opened_by) {
|
||||||
DCHECK(extension);
|
DCHECK(extension);
|
||||||
DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
|
DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
|
||||||
LazyContextId context_id(
|
const auto context_id = LazyContextId::ForExtension(profile, extension);
|
||||||
profile, extension->id(),
|
|
||||||
Extension::GetBaseURLFromExtensionId(extension->id()));
|
|
||||||
context_id.GetTaskQueue()->AddPendingTask(
|
context_id.GetTaskQueue()->AddPendingTask(
|
||||||
context_id,
|
context_id,
|
||||||
base::BindOnce(&InspectServiceWorkerBackgroundHelper, opened_by));
|
base::BindOnce(&InspectServiceWorkerBackgroundHelper, opened_by));
|
||||||
@ -91,7 +89,7 @@ void InspectBackgroundPage(const Extension* extension,
|
|||||||
InspectExtensionHost(
|
InspectExtensionHost(
|
||||||
opened_by, std::make_unique<LazyContextTaskQueue::ContextInfo>(host));
|
opened_by, std::make_unique<LazyContextTaskQueue::ContextInfo>(host));
|
||||||
} else {
|
} else {
|
||||||
const LazyContextId context_id(profile, extension->id());
|
const auto context_id = LazyContextId::ForExtension(profile, extension);
|
||||||
context_id.GetTaskQueue()->AddPendingTask(
|
context_id.GetTaskQueue()->AddPendingTask(
|
||||||
context_id, base::BindOnce(&InspectExtensionHost, opened_by));
|
context_id, base::BindOnce(&InspectExtensionHost, opened_by));
|
||||||
}
|
}
|
||||||
|
@ -2302,8 +2302,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
|
|||||||
const Extension* extension = LoadExtension(test_dir.UnpackedPath());
|
const Extension* extension = LoadExtension(test_dir.UnpackedPath());
|
||||||
ASSERT_TRUE(extension);
|
ASSERT_TRUE(extension);
|
||||||
ASSERT_EQ(test_extension_id, extension->id());
|
ASSERT_EQ(test_extension_id, extension->id());
|
||||||
LazyContextId context_id(browser()->profile(), extension->id(),
|
LazyContextId context_id =
|
||||||
extension->url());
|
LazyContextId::ForExtension(browser()->profile(), extension);
|
||||||
// Let the worker start so it rejects 'install' event. This causes the worker
|
// Let the worker start so it rejects 'install' event. This causes the worker
|
||||||
// to stop.
|
// to stop.
|
||||||
observer.WaitForWorkerStart();
|
observer.WaitForWorkerStart();
|
||||||
|
@ -80,11 +80,7 @@ const char kProhibitedByPoliciesError[] =
|
|||||||
|
|
||||||
LazyContextId LazyContextIdFor(content::BrowserContext* browser_context,
|
LazyContextId LazyContextIdFor(content::BrowserContext* browser_context,
|
||||||
const Extension* extension) {
|
const Extension* extension) {
|
||||||
if (BackgroundInfo::HasLazyBackgroundPage(extension))
|
return LazyContextId::ForExtension(browser_context, extension);
|
||||||
return LazyContextId(browser_context, extension->id());
|
|
||||||
|
|
||||||
DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
|
|
||||||
return LazyContextId(browser_context, extension->id(), extension->url());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Extension* GetExtensionForNativeAppChannel(
|
const Extension* GetExtensionForNativeAppChannel(
|
||||||
|
@ -110,15 +110,16 @@ void DispatchOnStartupEventImpl(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExtensionsBrowserClient::Get()->IsShuttingDown() ||
|
||||||
|
!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't send onStartup events to incognito browser contexts.
|
// Don't send onStartup events to incognito browser contexts.
|
||||||
if (browser_context->IsOffTheRecord()) {
|
if (browser_context->IsOffTheRecord()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExtensionsBrowserClient::Get()->IsShuttingDown() ||
|
|
||||||
!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ExtensionSystem* system = ExtensionSystem::Get(browser_context);
|
ExtensionSystem* system = ExtensionSystem::Get(browser_context);
|
||||||
if (!system) {
|
if (!system) {
|
||||||
return;
|
return;
|
||||||
@ -132,7 +133,8 @@ void DispatchOnStartupEventImpl(
|
|||||||
.GetByID(extension_id);
|
.GetByID(extension_id);
|
||||||
if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) &&
|
if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) &&
|
||||||
first_call) {
|
first_call) {
|
||||||
const LazyContextId context_id(browser_context, extension_id);
|
const auto context_id =
|
||||||
|
LazyContextId::ForExtension(browser_context, extension);
|
||||||
LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
||||||
if (task_queue->ShouldEnqueueTask(browser_context, extension)) {
|
if (task_queue->ShouldEnqueueTask(browser_context, extension)) {
|
||||||
task_queue->AddPendingTask(
|
task_queue->AddPendingTask(
|
||||||
@ -639,9 +641,13 @@ void RuntimeAPI::OnExtensionInstalledAndLoaded(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() {
|
ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() {
|
||||||
|
if (!BackgroundInfo::HasBackgroundPage(extension())) {
|
||||||
|
return RespondNow(Error(kNoBackgroundPageError));
|
||||||
|
}
|
||||||
ExtensionHost* host = ProcessManager::Get(browser_context())
|
ExtensionHost* host = ProcessManager::Get(browser_context())
|
||||||
->GetBackgroundHostForExtension(extension_id());
|
->GetBackgroundHostForExtension(extension_id());
|
||||||
const LazyContextId context_id(browser_context(), extension_id());
|
const auto context_id =
|
||||||
|
LazyContextId::ForExtension(browser_context(), extension());
|
||||||
LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
LazyContextTaskQueue* task_queue = context_id.GetTaskQueue();
|
||||||
if (task_queue->ShouldEnqueueTask(browser_context(), extension())) {
|
if (task_queue->ShouldEnqueueTask(browser_context(), extension())) {
|
||||||
task_queue->AddPendingTask(
|
task_queue->AddPendingTask(
|
||||||
|
@ -138,11 +138,12 @@ LazyContextId LazyContextIdForListener(const EventListener* listener,
|
|||||||
// TODO(lazyboy): Clean these inconsistencies across different types of event
|
// TODO(lazyboy): Clean these inconsistencies across different types of event
|
||||||
// listener and their corresponding background types.
|
// listener and their corresponding background types.
|
||||||
if (is_service_worker_based_extension && listener->is_for_service_worker()) {
|
if (is_service_worker_based_extension && listener->is_for_service_worker()) {
|
||||||
return LazyContextId(browser_context, listener->extension_id(),
|
return LazyContextId::ForServiceWorker(browser_context,
|
||||||
listener->listener_url());
|
listener->extension_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
return LazyContextId(browser_context, listener->extension_id());
|
return LazyContextId::ForBackgroundPage(browser_context,
|
||||||
|
listener->extension_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
// A global identifier used to distinguish extension events.
|
// A global identifier used to distinguish extension events.
|
||||||
|
@ -608,7 +608,8 @@ void ExtensionRegistrar::MaybeSpinUpLazyContext(const Extension* extension,
|
|||||||
// installed, this will result in a no-op task that's not necessary, since
|
// installed, this will result in a no-op task that's not necessary, since
|
||||||
// this is really only needed for a previously-installed extension. However,
|
// this is really only needed for a previously-installed extension. However,
|
||||||
// that cost is minimal, since the worker is already active.
|
// that cost is minimal, since the worker is already active.
|
||||||
const LazyContextId context_id(browser_context_, extension);
|
const auto context_id =
|
||||||
|
LazyContextId::ForExtension(browser_context_, extension);
|
||||||
context_id.GetTaskQueue()->AddPendingTask(context_id, base::DoNothing());
|
context_id.GetTaskQueue()->AddPendingTask(context_id, base::DoNothing());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ void AppViewGuest::CreateWebContents(std::unique_ptr<GuestViewBase> owned_this,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LazyContextId context_id(browser_context(), guest_extension->id());
|
const auto context_id =
|
||||||
|
LazyContextId::ForExtension(browser_context(), guest_extension);
|
||||||
LazyContextTaskQueue* queue = context_id.GetTaskQueue();
|
LazyContextTaskQueue* queue = context_id.GetTaskQueue();
|
||||||
if (queue->ShouldEnqueueTask(browser_context(), guest_extension)) {
|
if (queue->ShouldEnqueueTask(browser_context(), guest_extension)) {
|
||||||
queue->AddPendingTask(
|
queue->AddPendingTask(
|
||||||
|
@ -117,10 +117,15 @@ void LazyBackgroundTaskQueue::ProcessPendingTasks(
|
|||||||
DCHECK(extension);
|
DCHECK(extension);
|
||||||
|
|
||||||
if (!ExtensionsBrowserClient::Get()->IsSameContext(browser_context,
|
if (!ExtensionsBrowserClient::Get()->IsSameContext(browser_context,
|
||||||
browser_context_))
|
browser_context_)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto key = LazyContextId::ForExtension(browser_context, extension);
|
||||||
|
if (key.IsForServiceWorker()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PendingTasksKey key(browser_context, extension->id());
|
|
||||||
auto map_it = pending_tasks_.find(key);
|
auto map_it = pending_tasks_.find(key);
|
||||||
if (map_it == pending_tasks_.end()) {
|
if (map_it == pending_tasks_.end()) {
|
||||||
if (BackgroundInfo::HasLazyBackgroundPage(extension))
|
if (BackgroundInfo::HasLazyBackgroundPage(extension))
|
||||||
@ -215,7 +220,8 @@ void LazyBackgroundTaskQueue::OnExtensionUnloaded(
|
|||||||
void LazyBackgroundTaskQueue::CreateLazyBackgroundHostOnExtensionLoaded(
|
void LazyBackgroundTaskQueue::CreateLazyBackgroundHostOnExtensionLoaded(
|
||||||
content::BrowserContext* browser_context,
|
content::BrowserContext* browser_context,
|
||||||
const Extension* extension) {
|
const Extension* extension) {
|
||||||
PendingTasksKey key(browser_context, extension->id());
|
const auto key = LazyContextId::ForExtension(browser_context, extension);
|
||||||
|
CHECK(key.IsForBackgroundPage());
|
||||||
if (!base::Contains(pending_tasks_, key))
|
if (!base::Contains(pending_tasks_, key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -74,12 +74,11 @@ class LazyBackgroundTaskQueue : public KeyedService,
|
|||||||
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
|
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
|
||||||
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest,
|
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest,
|
||||||
CreateLazyBackgroundPageOnExtensionLoaded);
|
CreateLazyBackgroundPageOnExtensionLoaded);
|
||||||
|
using PendingTasksList = std::vector<PendingTask>;
|
||||||
// A map between a LazyContextId and the queue of tasks pending the load of
|
// A map between a LazyContextId and the queue of tasks pending the load of
|
||||||
// its background page.
|
// its background page.
|
||||||
using PendingTasksKey = LazyContextId;
|
|
||||||
using PendingTasksList = std::vector<PendingTask>;
|
|
||||||
using PendingTasksMap =
|
using PendingTasksMap =
|
||||||
std::map<PendingTasksKey, std::unique_ptr<PendingTasksList>>;
|
std::map<LazyContextId, std::unique_ptr<PendingTasksList>>;
|
||||||
|
|
||||||
// ExtensionHostRegistry::Observer:
|
// ExtensionHostRegistry::Observer:
|
||||||
void OnExtensionHostCompletedFirstLoad(
|
void OnExtensionHostCompletedFirstLoad(
|
||||||
|
@ -155,8 +155,8 @@ TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
|
|||||||
|
|
||||||
// Adding a pending task increases the number of extensions with tasks, but
|
// Adding a pending task increases the number of extensions with tasks, but
|
||||||
// doesn't run the task.
|
// doesn't run the task.
|
||||||
const LazyContextId no_background_context_id(browser_context(),
|
const auto no_background_context_id =
|
||||||
no_background->id());
|
LazyContextId::ForExtension(browser_context(), no_background.get());
|
||||||
queue.AddPendingTask(
|
queue.AddPendingTask(
|
||||||
no_background_context_id,
|
no_background_context_id,
|
||||||
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
||||||
@ -177,8 +177,8 @@ TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
|
|||||||
// a background host, and if that fails, runs the task immediately.
|
// a background host, and if that fails, runs the task immediately.
|
||||||
scoped_refptr<const Extension> lazy_background =
|
scoped_refptr<const Extension> lazy_background =
|
||||||
CreateLazyBackgroundExtension();
|
CreateLazyBackgroundExtension();
|
||||||
const LazyContextId lazy_background_context_id(browser_context(),
|
const auto lazy_background_context_id =
|
||||||
lazy_background->id());
|
LazyContextId::ForExtension(browser_context(), lazy_background.get());
|
||||||
queue.AddPendingTask(
|
queue.AddPendingTask(
|
||||||
lazy_background_context_id,
|
lazy_background_context_id,
|
||||||
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
||||||
@ -201,7 +201,7 @@ TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
|
|||||||
|
|
||||||
// Schedule a task to run.
|
// Schedule a task to run.
|
||||||
queue.AddPendingTask(
|
queue.AddPendingTask(
|
||||||
LazyContextId(browser_context(), extension->id()),
|
LazyContextId::ForExtension(browser_context(), extension.get()),
|
||||||
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
||||||
base::Unretained(this)));
|
base::Unretained(this)));
|
||||||
EXPECT_EQ(0, task_run_count());
|
EXPECT_EQ(0, task_run_count());
|
||||||
@ -237,7 +237,7 @@ TEST_F(LazyBackgroundTaskQueueTest, CreateLazyBackgroundPageOnExtensionLoaded) {
|
|||||||
EXPECT_EQ(0, process_manager()->create_count());
|
EXPECT_EQ(0, process_manager()->create_count());
|
||||||
|
|
||||||
queue.AddPendingTask(
|
queue.AddPendingTask(
|
||||||
LazyContextId(browser_context(), lazy_background->id()),
|
LazyContextId::ForExtension(browser_context(), lazy_background.get()),
|
||||||
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
base::BindOnce(&LazyBackgroundTaskQueueTest::RunPendingTask,
|
||||||
base::Unretained(this)));
|
base::Unretained(this)));
|
||||||
EXPECT_EQ(1u, queue.pending_tasks_.size());
|
EXPECT_EQ(1u, queue.pending_tasks_.size());
|
||||||
|
@ -12,30 +12,24 @@
|
|||||||
|
|
||||||
namespace extensions {
|
namespace extensions {
|
||||||
|
|
||||||
LazyContextId::LazyContextId(content::BrowserContext* context,
|
LazyContextId::LazyContextId(Type type,
|
||||||
|
content::BrowserContext* context,
|
||||||
const ExtensionId& extension_id)
|
const ExtensionId& extension_id)
|
||||||
: type_(Type::kEventPage), context_(context), extension_id_(extension_id) {}
|
: type_(type), context_(context), extension_id_(extension_id) {}
|
||||||
|
|
||||||
LazyContextId::LazyContextId(content::BrowserContext* context,
|
|
||||||
const ExtensionId& extension_id,
|
|
||||||
const GURL& service_worker_scope)
|
|
||||||
: type_(Type::kServiceWorker),
|
|
||||||
context_(context),
|
|
||||||
extension_id_(extension_id),
|
|
||||||
service_worker_scope_(service_worker_scope) {}
|
|
||||||
|
|
||||||
LazyContextId::LazyContextId(content::BrowserContext* context,
|
LazyContextId::LazyContextId(content::BrowserContext* context,
|
||||||
const Extension* extension)
|
const Extension* extension)
|
||||||
: context_(context), extension_id_(extension->id()) {
|
: context_(context), extension_id_(extension->id()) {
|
||||||
if (BackgroundInfo::HasLazyBackgroundPage(extension)) {
|
if (BackgroundInfo::IsServiceWorkerBased(extension)) {
|
||||||
type_ = Type::kEventPage;
|
|
||||||
} else {
|
|
||||||
// TODO(crbug.com/773103): This currently assumes all workers are
|
|
||||||
// registered in the '/' scope.
|
|
||||||
DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
|
|
||||||
type_ = Type::kServiceWorker;
|
type_ = Type::kServiceWorker;
|
||||||
service_worker_scope_ =
|
} else if (BackgroundInfo::HasBackgroundPage(extension)) {
|
||||||
Extension::GetBaseURLFromExtensionId(extension->id());
|
// Packaged apps and extensions with persistent background and event pages
|
||||||
|
// all use the same task queue.
|
||||||
|
type_ = Type::kBackgroundPage;
|
||||||
|
} else {
|
||||||
|
// There are tests where a LazyContextId is constructed for an extension
|
||||||
|
// without a background page or service worker, so this is a fallback.
|
||||||
|
type_ = Type::kNone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "extensions/common/extension_id.h"
|
#include "extensions/common/extension_id.h"
|
||||||
#include "url/gurl.h"
|
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class BrowserContext;
|
class BrowserContext;
|
||||||
@ -21,22 +20,20 @@ class LazyContextTaskQueue;
|
|||||||
|
|
||||||
class LazyContextId {
|
class LazyContextId {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
static LazyContextId ForBackgroundPage(content::BrowserContext* context,
|
||||||
kEventPage,
|
const ExtensionId& extension_id) {
|
||||||
kServiceWorker,
|
return LazyContextId(Type::kBackgroundPage, context, extension_id);
|
||||||
};
|
}
|
||||||
|
|
||||||
// An event page (lazy background) context.
|
static LazyContextId ForServiceWorker(content::BrowserContext* context,
|
||||||
LazyContextId(content::BrowserContext* context,
|
const ExtensionId& extension_id) {
|
||||||
const ExtensionId& extension_id);
|
return LazyContextId(Type::kServiceWorker, context, extension_id);
|
||||||
|
}
|
||||||
|
|
||||||
// An extension service worker context.
|
static LazyContextId ForExtension(content::BrowserContext* context,
|
||||||
LazyContextId(content::BrowserContext* context,
|
const Extension* extension) {
|
||||||
const ExtensionId& extension_id,
|
return LazyContextId(context, extension);
|
||||||
const GURL& service_worker_scope);
|
}
|
||||||
|
|
||||||
// The context is derived from the extension.
|
|
||||||
LazyContextId(content::BrowserContext* context, const Extension* extension);
|
|
||||||
|
|
||||||
// Copy and move constructors.
|
// Copy and move constructors.
|
||||||
LazyContextId(const LazyContextId& other) = default;
|
LazyContextId(const LazyContextId& other) = default;
|
||||||
@ -45,44 +42,52 @@ class LazyContextId {
|
|||||||
LazyContextId& operator=(const LazyContextId&) noexcept = default;
|
LazyContextId& operator=(const LazyContextId&) noexcept = default;
|
||||||
LazyContextId& operator=(LazyContextId&&) noexcept = default;
|
LazyContextId& operator=(LazyContextId&&) noexcept = default;
|
||||||
|
|
||||||
bool is_for_event_page() const { return type_ == Type::kEventPage; }
|
bool IsForBackgroundPage() const { return type_ == Type::kBackgroundPage; }
|
||||||
bool is_for_service_worker() const { return type_ == Type::kServiceWorker; }
|
bool IsForServiceWorker() const { return type_ == Type::kServiceWorker; }
|
||||||
|
|
||||||
content::BrowserContext* browser_context() const { return context_; }
|
content::BrowserContext* browser_context() const { return context_; }
|
||||||
void set_browser_context(content::BrowserContext* context) {
|
|
||||||
context_ = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ExtensionId& extension_id() const { return extension_id_; }
|
const ExtensionId& extension_id() const { return extension_id_; }
|
||||||
|
|
||||||
const GURL& service_worker_scope() const {
|
|
||||||
DCHECK(is_for_service_worker());
|
|
||||||
return service_worker_scope_;
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyContextTaskQueue* GetTaskQueue() const;
|
LazyContextTaskQueue* GetTaskQueue() const;
|
||||||
|
|
||||||
bool operator<(const LazyContextId& rhs) const {
|
|
||||||
return std::tie(type_, context_, extension_id_, service_worker_scope_) <
|
|
||||||
std::tie(rhs.type_, rhs.context_, rhs.extension_id_,
|
|
||||||
rhs.service_worker_scope_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const LazyContextId& rhs) const {
|
|
||||||
return std::tie(type_, context_, extension_id_, service_worker_scope_) ==
|
|
||||||
std::tie(rhs.type_, rhs.context_, rhs.extension_id_,
|
|
||||||
rhs.service_worker_scope_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const LazyContextId& rhs) const { return !(*this == rhs); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class Type {
|
||||||
|
kNone,
|
||||||
|
kBackgroundPage,
|
||||||
|
kServiceWorker,
|
||||||
|
};
|
||||||
|
|
||||||
|
friend bool operator<(const LazyContextId& lhs, const LazyContextId& rhs);
|
||||||
|
friend bool operator==(const LazyContextId& lhs, const LazyContextId& rhs);
|
||||||
|
|
||||||
|
// An event page or service worker based on the type.
|
||||||
|
LazyContextId(Type type,
|
||||||
|
content::BrowserContext* context,
|
||||||
|
const ExtensionId& extension_id);
|
||||||
|
|
||||||
|
// The type is derived from the extension.
|
||||||
|
LazyContextId(content::BrowserContext* context, const Extension* extension);
|
||||||
|
|
||||||
Type type_;
|
Type type_;
|
||||||
raw_ptr<content::BrowserContext, DanglingUntriaged> context_;
|
raw_ptr<content::BrowserContext, DanglingUntriaged> context_;
|
||||||
ExtensionId extension_id_;
|
ExtensionId extension_id_;
|
||||||
GURL service_worker_scope_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const LazyContextId& lhs, const LazyContextId& rhs) {
|
||||||
|
return std::tie(lhs.type_, lhs.context_, lhs.extension_id_) <
|
||||||
|
std::tie(rhs.type_, rhs.context_, rhs.extension_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const LazyContextId& lhs, const LazyContextId& rhs) {
|
||||||
|
return std::tie(lhs.type_, lhs.context_, lhs.extension_id_) ==
|
||||||
|
std::tie(rhs.type_, rhs.context_, rhs.extension_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const LazyContextId& lhs, const LazyContextId& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace extensions
|
} // namespace extensions
|
||||||
|
|
||||||
#endif // EXTENSIONS_BROWSER_LAZY_CONTEXT_ID_H_
|
#endif // EXTENSIONS_BROWSER_LAZY_CONTEXT_ID_H_
|
||||||
|
@ -448,7 +448,9 @@ bool ProcessManager::WakeEventPage(const std::string& extension_id,
|
|||||||
// The extension is already awake.
|
// The extension is already awake.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const LazyContextId context_id(browser_context_, extension_id);
|
|
||||||
|
const auto context_id =
|
||||||
|
LazyContextId::ForBackgroundPage(browser_context_, extension_id);
|
||||||
context_id.GetTaskQueue()->AddPendingTask(
|
context_id.GetTaskQueue()->AddPendingTask(
|
||||||
context_id,
|
context_id,
|
||||||
base::BindOnce(&PropagateExtensionWakeResult, std::move(callback)));
|
base::BindOnce(&PropagateExtensionWakeResult, std::move(callback)));
|
||||||
|
@ -152,8 +152,8 @@ void ServiceWorkerTaskQueue::DidStartWorkerForScope(
|
|||||||
int process_id,
|
int process_id,
|
||||||
int thread_id) {
|
int thread_id) {
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
const ExtensionId& extension_id = context_id.first.extension_id();
|
const ExtensionId& extension_id = context_id.extension_id;
|
||||||
const base::UnguessableToken& activation_token = context_id.second;
|
const base::UnguessableToken& activation_token = context_id.token;
|
||||||
if (!IsCurrentActivation(extension_id, activation_token)) {
|
if (!IsCurrentActivation(extension_id, activation_token)) {
|
||||||
// Extension run with |activation_token| was already deactivated.
|
// Extension run with |activation_token| was already deactivated.
|
||||||
// TODO(lazyboy): Add a DCHECK that the worker in question is actually
|
// TODO(lazyboy): Add a DCHECK that the worker in question is actually
|
||||||
@ -210,8 +210,7 @@ void ServiceWorkerTaskQueue::DidStartWorkerFail(
|
|||||||
base::Time start_time,
|
base::Time start_time,
|
||||||
blink::ServiceWorkerStatusCode status_code) {
|
blink::ServiceWorkerStatusCode status_code) {
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
if (!IsCurrentActivation(context_id.first.extension_id(),
|
if (!IsCurrentActivation(context_id.extension_id, context_id.token)) {
|
||||||
context_id.second)) {
|
|
||||||
// This can happen is when the registration got unregistered right before we
|
// This can happen is when the registration got unregistered right before we
|
||||||
// tried to start it. See crbug.com/999027 for details.
|
// tried to start it. See crbug.com/999027 for details.
|
||||||
DCHECK(!GetWorkerState(context_id));
|
DCHECK(!GetWorkerState(context_id));
|
||||||
@ -228,7 +227,7 @@ void ServiceWorkerTaskQueue::DidStartWorkerFail(
|
|||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
DCHECK(worker_state);
|
DCHECK(worker_state);
|
||||||
if (g_test_observer) {
|
if (g_test_observer) {
|
||||||
g_test_observer->DidStartWorkerFail(context_id.first.extension_id(),
|
g_test_observer->DidStartWorkerFail(context_id.extension_id,
|
||||||
worker_state->pending_tasks_.size(),
|
worker_state->pending_tasks_.size(),
|
||||||
status_code);
|
status_code);
|
||||||
}
|
}
|
||||||
@ -237,12 +236,12 @@ void ServiceWorkerTaskQueue::DidStartWorkerFail(
|
|||||||
// perma-broken state after this as the registration wouldn't be stored if
|
// perma-broken state after this as the registration wouldn't be stored if
|
||||||
// this happens.
|
// this happens.
|
||||||
LOG(ERROR)
|
LOG(ERROR)
|
||||||
<< "DidStartWorkerFail " << context_id.first.extension_id() << ": "
|
<< "DidStartWorkerFail " << context_id.extension_id << ": "
|
||||||
<< static_cast<std::underlying_type_t<blink::ServiceWorkerStatusCode>>(
|
<< static_cast<std::underlying_type_t<blink::ServiceWorkerStatusCode>>(
|
||||||
status_code);
|
status_code);
|
||||||
|
|
||||||
// If there was a pending registration for this scope, erase it.
|
// If there was a pending registration for this extension, erase it.
|
||||||
pending_registrations_.erase(context_id.first.service_worker_scope());
|
pending_registrations_.erase(context_id.extension_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceWorkerTaskQueue::DidInitializeServiceWorkerContext(
|
void ServiceWorkerTaskQueue::DidInitializeServiceWorkerContext(
|
||||||
@ -290,9 +289,8 @@ void ServiceWorkerTaskQueue::DidStartServiceWorkerContext(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SequencedContextId context_id(
|
const SequencedContextId context_id = {extension_id, browser_context_,
|
||||||
LazyContextId(browser_context_, extension_id, service_worker_scope),
|
activation_token};
|
||||||
activation_token);
|
|
||||||
|
|
||||||
const WorkerId worker_id = {extension_id, render_process_id,
|
const WorkerId worker_id = {extension_id, render_process_id,
|
||||||
service_worker_version_id, thread_id};
|
service_worker_version_id, thread_id};
|
||||||
@ -332,9 +330,8 @@ void ServiceWorkerTaskQueue::DidStopServiceWorkerContext(
|
|||||||
const WorkerId worker_id = {extension_id, render_process_id,
|
const WorkerId worker_id = {extension_id, render_process_id,
|
||||||
service_worker_version_id, thread_id};
|
service_worker_version_id, thread_id};
|
||||||
ProcessManager::Get(browser_context_)->UnregisterServiceWorker(worker_id);
|
ProcessManager::Get(browser_context_)->UnregisterServiceWorker(worker_id);
|
||||||
SequencedContextId context_id(
|
const SequencedContextId context_id = {extension_id, browser_context_,
|
||||||
LazyContextId(browser_context_, extension_id, service_worker_scope),
|
activation_token};
|
||||||
activation_token);
|
|
||||||
|
|
||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
DCHECK(worker_state);
|
DCHECK(worker_state);
|
||||||
@ -366,7 +363,7 @@ bool ServiceWorkerTaskQueue::ShouldEnqueueTask(BrowserContext* context,
|
|||||||
void ServiceWorkerTaskQueue::AddPendingTask(
|
void ServiceWorkerTaskQueue::AddPendingTask(
|
||||||
const LazyContextId& lazy_context_id,
|
const LazyContextId& lazy_context_id,
|
||||||
PendingTask task) {
|
PendingTask task) {
|
||||||
DCHECK(lazy_context_id.is_for_service_worker());
|
DCHECK(lazy_context_id.IsForServiceWorker());
|
||||||
|
|
||||||
// TODO(lazyboy): Do we need to handle incognito context?
|
// TODO(lazyboy): Do we need to handle incognito context?
|
||||||
|
|
||||||
@ -375,7 +372,9 @@ void ServiceWorkerTaskQueue::AddPendingTask(
|
|||||||
DCHECK(activation_token)
|
DCHECK(activation_token)
|
||||||
<< "Trying to add pending task to an inactive extension: "
|
<< "Trying to add pending task to an inactive extension: "
|
||||||
<< lazy_context_id.extension_id();
|
<< lazy_context_id.extension_id();
|
||||||
const SequencedContextId context_id(lazy_context_id, *activation_token);
|
const SequencedContextId context_id = {lazy_context_id.extension_id(),
|
||||||
|
lazy_context_id.browser_context(),
|
||||||
|
*activation_token};
|
||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
DCHECK(worker_state);
|
DCHECK(worker_state);
|
||||||
auto& tasks = worker_state->pending_tasks_;
|
auto& tasks = worker_state->pending_tasks_;
|
||||||
@ -400,9 +399,8 @@ void ServiceWorkerTaskQueue::ActivateExtension(const Extension* extension) {
|
|||||||
const ExtensionId extension_id = extension->id();
|
const ExtensionId extension_id = extension->id();
|
||||||
base::UnguessableToken activation_token = base::UnguessableToken::Create();
|
base::UnguessableToken activation_token = base::UnguessableToken::Create();
|
||||||
activation_tokens_[extension_id] = activation_token;
|
activation_tokens_[extension_id] = activation_token;
|
||||||
SequencedContextId context_id(
|
const SequencedContextId context_id = {extension_id, browser_context_,
|
||||||
LazyContextId(browser_context_, extension_id, extension->url()),
|
activation_token};
|
||||||
activation_token);
|
|
||||||
DCHECK(!base::Contains(worker_state_map_, context_id));
|
DCHECK(!base::Contains(worker_state_map_, context_id));
|
||||||
WorkerState& worker_state = worker_state_map_[context_id];
|
WorkerState& worker_state = worker_state_map_[context_id];
|
||||||
|
|
||||||
@ -477,9 +475,8 @@ void ServiceWorkerTaskQueue::DeactivateExtension(const Extension* extension) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activation_tokens_.erase(extension_id);
|
activation_tokens_.erase(extension_id);
|
||||||
SequencedContextId context_id(
|
const SequencedContextId context_id = {extension_id, browser_context_,
|
||||||
LazyContextId(browser_context_, extension_id, extension->url()),
|
*activation_token};
|
||||||
*activation_token);
|
|
||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
DCHECK(worker_state);
|
DCHECK(worker_state);
|
||||||
// TODO(lazyboy): Run orphaned tasks with nullptr ContextInfo.
|
// TODO(lazyboy): Run orphaned tasks with nullptr ContextInfo.
|
||||||
@ -488,7 +485,7 @@ void ServiceWorkerTaskQueue::DeactivateExtension(const Extension* extension) {
|
|||||||
|
|
||||||
// Erase any registrations that might still have been pending being fully
|
// Erase any registrations that might still have been pending being fully
|
||||||
// stored.
|
// stored.
|
||||||
pending_registrations_.erase(extension->url());
|
pending_registrations_.erase(extension_id);
|
||||||
|
|
||||||
content::ServiceWorkerContext* service_worker_context =
|
content::ServiceWorkerContext* service_worker_context =
|
||||||
GetServiceWorkerContext(extension->id());
|
GetServiceWorkerContext(extension->id());
|
||||||
@ -510,19 +507,18 @@ void ServiceWorkerTaskQueue::DeactivateExtension(const Extension* extension) {
|
|||||||
|
|
||||||
void ServiceWorkerTaskQueue::RunTasksAfterStartWorker(
|
void ServiceWorkerTaskQueue::RunTasksAfterStartWorker(
|
||||||
const SequencedContextId& context_id) {
|
const SequencedContextId& context_id) {
|
||||||
DCHECK(context_id.first.is_for_service_worker());
|
if (context_id.browser_context != browser_context_) {
|
||||||
|
|
||||||
const LazyContextId& lazy_context_id = context_id.first;
|
|
||||||
if (lazy_context_id.browser_context() != browser_context_)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
DCHECK_NE(BrowserState::kStarted, worker_state->browser_state_);
|
DCHECK_NE(BrowserState::kStarted, worker_state->browser_state_);
|
||||||
|
|
||||||
content::ServiceWorkerContext* service_worker_context =
|
content::ServiceWorkerContext* service_worker_context =
|
||||||
GetServiceWorkerContext(lazy_context_id.extension_id());
|
GetServiceWorkerContext(context_id.extension_id);
|
||||||
|
|
||||||
const GURL& scope = context_id.first.service_worker_scope();
|
const GURL scope =
|
||||||
|
Extension::GetServiceWorkerScopeFromExtensionId(context_id.extension_id);
|
||||||
service_worker_context->StartWorkerForScope(
|
service_worker_context->StartWorkerForScope(
|
||||||
scope, blink::StorageKey::CreateFirstParty(url::Origin::Create(scope)),
|
scope, blink::StorageKey::CreateFirstParty(url::Origin::Create(scope)),
|
||||||
base::BindOnce(&ServiceWorkerTaskQueue::DidStartWorkerForScope,
|
base::BindOnce(&ServiceWorkerTaskQueue::DidStartWorkerForScope,
|
||||||
@ -538,14 +534,14 @@ void ServiceWorkerTaskQueue::DidRegisterServiceWorker(
|
|||||||
base::Time start_time,
|
base::Time start_time,
|
||||||
blink::ServiceWorkerStatusCode status_code) {
|
blink::ServiceWorkerStatusCode status_code) {
|
||||||
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
||||||
const ExtensionId& extension_id = context_id.first.extension_id();
|
const ExtensionId& extension_id = context_id.extension_id;
|
||||||
DCHECK(registry);
|
DCHECK(registry);
|
||||||
const Extension* extension =
|
const Extension* extension =
|
||||||
registry->enabled_extensions().GetByID(extension_id);
|
registry->enabled_extensions().GetByID(extension_id);
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!IsCurrentActivation(extension_id, context_id.second)) {
|
if (!IsCurrentActivation(extension_id, context_id.token)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,7 +576,7 @@ void ServiceWorkerTaskQueue::DidRegisterServiceWorker(
|
|||||||
base::Time::Now() - start_time);
|
base::Time::Now() - start_time);
|
||||||
|
|
||||||
worker_state->registration_state_ = RegistrationState::kRegistered;
|
worker_state->registration_state_ = RegistrationState::kRegistered;
|
||||||
pending_registrations_.emplace(extension->url(),
|
pending_registrations_.emplace(extension->id(),
|
||||||
*GetCurrentActivationToken(extension->id()));
|
*GetCurrentActivationToken(extension->id()));
|
||||||
|
|
||||||
if (worker_state->has_pending_tasks()) {
|
if (worker_state->has_pending_tasks()) {
|
||||||
@ -674,10 +670,11 @@ void ServiceWorkerTaskQueue::RunPendingTasksIfWorkerReady(
|
|||||||
const auto& worker_id = *worker_state->worker_id_;
|
const auto& worker_id = *worker_state->worker_id_;
|
||||||
for (auto& task : tasks) {
|
for (auto& task : tasks) {
|
||||||
auto context_info = std::make_unique<LazyContextTaskQueue::ContextInfo>(
|
auto context_info = std::make_unique<LazyContextTaskQueue::ContextInfo>(
|
||||||
context_id.first.extension_id(),
|
context_id.extension_id,
|
||||||
content::RenderProcessHost::FromID(worker_id.render_process_id),
|
content::RenderProcessHost::FromID(worker_id.render_process_id),
|
||||||
worker_id.version_id, worker_id.thread_id,
|
worker_id.version_id, worker_id.thread_id,
|
||||||
context_id.first.service_worker_scope());
|
Extension::GetServiceWorkerScopeFromExtensionId(
|
||||||
|
context_id.extension_id));
|
||||||
std::move(task).Run(std::move(context_info));
|
std::move(task).Run(std::move(context_info));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,7 +697,8 @@ ServiceWorkerTaskQueue::GetCurrentActivationToken(
|
|||||||
|
|
||||||
void ServiceWorkerTaskQueue::OnRegistrationStored(int64_t registration_id,
|
void ServiceWorkerTaskQueue::OnRegistrationStored(int64_t registration_id,
|
||||||
const GURL& scope) {
|
const GURL& scope) {
|
||||||
auto iter = pending_registrations_.find(scope);
|
const std::string extension_id = scope.host();
|
||||||
|
auto iter = pending_registrations_.find(extension_id);
|
||||||
if (iter == pending_registrations_.end()) {
|
if (iter == pending_registrations_.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -713,7 +711,6 @@ void ServiceWorkerTaskQueue::OnRegistrationStored(int64_t registration_id,
|
|||||||
base::UnguessableToken activation_token = iter->second;
|
base::UnguessableToken activation_token = iter->second;
|
||||||
pending_registrations_.erase(iter);
|
pending_registrations_.erase(iter);
|
||||||
|
|
||||||
std::string extension_id = scope.host();
|
|
||||||
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
||||||
const Extension* extension =
|
const Extension* extension =
|
||||||
registry->enabled_extensions().GetByID(extension_id);
|
registry->enabled_extensions().GetByID(extension_id);
|
||||||
@ -764,7 +761,9 @@ size_t ServiceWorkerTaskQueue::GetNumPendingTasksForTest(
|
|||||||
if (!activation_token) {
|
if (!activation_token) {
|
||||||
return 0u;
|
return 0u;
|
||||||
}
|
}
|
||||||
const SequencedContextId context_id(lazy_context_id, *activation_token);
|
const SequencedContextId context_id = {lazy_context_id.extension_id(),
|
||||||
|
lazy_context_id.browser_context(),
|
||||||
|
*activation_token};
|
||||||
WorkerState* worker_state = GetWorkerState(context_id);
|
WorkerState* worker_state = GetWorkerState(context_id);
|
||||||
return worker_state ? worker_state->pending_tasks_.size() : 0u;
|
return worker_state ? worker_state->pending_tasks_.size() : 0u;
|
||||||
}
|
}
|
||||||
@ -822,7 +821,7 @@ void ServiceWorkerTaskQueue::DidVerifyRegistration(
|
|||||||
// We expected a SW registration (as ExtensionPrefs said so), but there isn't
|
// We expected a SW registration (as ExtensionPrefs said so), but there isn't
|
||||||
// one. Re-register SW script if the extension is still installed (it's
|
// one. Re-register SW script if the extension is still installed (it's
|
||||||
// possible it was uninstalled while we were checking).
|
// possible it was uninstalled while we were checking).
|
||||||
const ExtensionId& extension_id = context_id.first.extension_id();
|
const ExtensionId& extension_id = context_id.extension_id;
|
||||||
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
||||||
DCHECK(registry);
|
DCHECK(registry);
|
||||||
const Extension* extension =
|
const Extension* extension =
|
||||||
|
@ -186,7 +186,16 @@ class ServiceWorkerTaskQueue : public KeyedService,
|
|||||||
size_t GetNumPendingTasksForTest(const LazyContextId& lazy_context_id);
|
size_t GetNumPendingTasksForTest(const LazyContextId& lazy_context_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using SequencedContextId = std::pair<LazyContextId, base::UnguessableToken>;
|
struct SequencedContextId {
|
||||||
|
ExtensionId extension_id;
|
||||||
|
raw_ptr<content::BrowserContext> browser_context;
|
||||||
|
base::UnguessableToken token;
|
||||||
|
|
||||||
|
bool operator<(const SequencedContextId& rhs) const {
|
||||||
|
return std::tie(extension_id, browser_context, token) <
|
||||||
|
std::tie(rhs.extension_id, rhs.browser_context, rhs.token);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class WorkerState;
|
class WorkerState;
|
||||||
|
|
||||||
@ -280,10 +289,9 @@ class ServiceWorkerTaskQueue : public KeyedService,
|
|||||||
// succeeded in the first step (triggering `DidRegisterServiceWorker`), but
|
// succeeded in the first step (triggering `DidRegisterServiceWorker`), but
|
||||||
// have not yet been stored. They are cleared out (and the registration state
|
// have not yet been stored. They are cleared out (and the registration state
|
||||||
// is stored) in response to `OnRegistrationStored`.
|
// is stored) in response to `OnRegistrationStored`.
|
||||||
// The key is the service worker scope (which is the associated extension's
|
// The key is the extension's ID and the value is the activation token
|
||||||
// base URL), and the value is the activation token expected for that
|
// expected for that registration.
|
||||||
// registration.
|
std::map<ExtensionId, base::UnguessableToken> pending_registrations_;
|
||||||
std::map<GURL, base::UnguessableToken> pending_registrations_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<ServiceWorkerTaskQueue> weak_factory_{this};
|
base::WeakPtrFactory<ServiceWorkerTaskQueue> weak_factory_{this};
|
||||||
};
|
};
|
||||||
|
@ -122,12 +122,16 @@ void DoTaskQueueFunction(content::BrowserContext* browser_context,
|
|||||||
|
|
||||||
LazyContextTaskQueue* GetTaskQueueForLazyContextId(
|
LazyContextTaskQueue* GetTaskQueueForLazyContextId(
|
||||||
const LazyContextId& context_id) {
|
const LazyContextId& context_id) {
|
||||||
if (context_id.is_for_event_page())
|
if (context_id.IsForBackgroundPage()) {
|
||||||
return LazyBackgroundTaskQueue::Get(context_id.browser_context());
|
return LazyBackgroundTaskQueue::Get(context_id.browser_context());
|
||||||
|
}
|
||||||
|
|
||||||
DCHECK(context_id.is_for_service_worker());
|
if (context_id.IsForServiceWorker()) {
|
||||||
return GetServiceWorkerTaskQueueForExtensionId(context_id.browser_context(),
|
return GetServiceWorkerTaskQueueForExtensionId(context_id.browser_context(),
|
||||||
context_id.extension_id());
|
context_id.extension_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivateTaskQueueForExtension(content::BrowserContext* browser_context,
|
void ActivateTaskQueueForExtension(content::BrowserContext* browser_context,
|
||||||
|
@ -220,6 +220,12 @@ class Extension final : public base::RefCountedThreadSafe<Extension> {
|
|||||||
// Returns the base extension url for a given |extension_id|.
|
// Returns the base extension url for a given |extension_id|.
|
||||||
static GURL GetBaseURLFromExtensionId(const ExtensionId& extension_id);
|
static GURL GetBaseURLFromExtensionId(const ExtensionId& extension_id);
|
||||||
|
|
||||||
|
// Returns for scope for the extension's service worker.
|
||||||
|
static GURL GetServiceWorkerScopeFromExtensionId(
|
||||||
|
const ExtensionId& extension_id) {
|
||||||
|
return GetBaseURLFromExtensionId(extension_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the extension origin for a given |extension_id|.
|
// Returns the extension origin for a given |extension_id|.
|
||||||
static url::Origin CreateOriginFromExtensionId(
|
static url::Origin CreateOriginFromExtensionId(
|
||||||
const ExtensionId& extension_id);
|
const ExtensionId& extension_id);
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#include "extensions/browser/extension_host.h"
|
#include "extensions/browser/extension_host.h"
|
||||||
#include "extensions/browser/extension_host_test_helper.h"
|
#include "extensions/browser/extension_host_test_helper.h"
|
||||||
#include "extensions/browser/lazy_context_id.h"
|
#include "extensions/browser/lazy_context_id.h"
|
||||||
|
#include "extensions/browser/lazy_context_task_queue.h"
|
||||||
#include "extensions/browser/process_manager.h"
|
#include "extensions/browser/process_manager.h"
|
||||||
#include "extensions/browser/service_worker_task_queue.h"
|
|
||||||
#include "extensions/common/manifest_handlers/background_info.h"
|
#include "extensions/common/manifest_handlers/background_info.h"
|
||||||
#include "extensions/common/manifest_handlers/incognito_info.h"
|
#include "extensions/common/manifest_handlers/incognito_info.h"
|
||||||
#include "extensions/common/mojom/view_type.mojom.h"
|
#include "extensions/common/mojom/view_type.mojom.h"
|
||||||
@ -83,10 +83,10 @@ void ExtensionBackgroundPageWaiter::WaitForBackgroundWorkerInitialized() {
|
|||||||
[&run_loop](std::unique_ptr<LazyContextTaskQueue::ContextInfo>) {
|
[&run_loop](std::unique_ptr<LazyContextTaskQueue::ContextInfo>) {
|
||||||
run_loop.QuitWhenIdle();
|
run_loop.QuitWhenIdle();
|
||||||
};
|
};
|
||||||
ServiceWorkerTaskQueue::Get(browser_context_)
|
const auto context_id =
|
||||||
->AddPendingTask(
|
LazyContextId::ForExtension(browser_context_, extension_.get());
|
||||||
LazyContextId(browser_context_, extension_->id(), extension_->url()),
|
context_id.GetTaskQueue()->AddPendingTask(
|
||||||
base::BindLambdaForTesting(quit_loop_adapter));
|
context_id, base::BindLambdaForTesting(quit_loop_adapter));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user