blob: 85948899dd641db028b4556db3f1bdd43cadf556 [file] [log] [blame]
lazyboy63b994a2017-06-30 21:20:231// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef EXTENSIONS_BROWSER_SERVICE_WORKER_TASK_QUEUE_H_
6#define EXTENSIONS_BROWSER_SERVICE_WORKER_TASK_QUEUE_H_
7
Istiaque Ahmedccb444022018-06-19 02:11:128#include <map>
9#include <set>
10
11#include "base/memory/weak_ptr.h"
Istiaque Ahmed70f76ac2018-11-02 02:59:5512#include "base/version.h"
lazyboy63b994a2017-06-30 21:20:2313#include "components/keyed_service/core/keyed_service.h"
14#include "extensions/browser/lazy_context_task_queue.h"
15#include "extensions/common/extension_id.h"
16#include "url/gurl.h"
17
18namespace content {
19class BrowserContext;
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2520class ServiceWorkerContext;
lazyboy63b994a2017-06-30 21:20:2321}
22
23namespace extensions {
24class Extension;
25class LazyContextId;
26
lazyboy63b994a2017-06-30 21:20:2327// TODO(lazyboy): Clean up queue when extension is unloaded/uninstalled.
28class ServiceWorkerTaskQueue : public KeyedService,
29 public LazyContextTaskQueue {
30 public:
31 explicit ServiceWorkerTaskQueue(content::BrowserContext* browser_context);
32 ~ServiceWorkerTaskQueue() override;
33
34 // Convenience method to return the ServiceWorkerTaskQueue for a given
35 // |context|.
36 static ServiceWorkerTaskQueue* Get(content::BrowserContext* context);
37
38 bool ShouldEnqueueTask(content::BrowserContext* context,
39 const Extension* extension) override;
David Bertoni8269a092018-12-19 15:55:4240 void AddPendingTask(const LazyContextId& context_id,
41 PendingTask task) override;
lazyboy63b994a2017-06-30 21:20:2342
Istiaque Ahmedccb444022018-06-19 02:11:1243 // Performs Service Worker related tasks upon |extension| activation,
44 // e.g. registering |extension|'s worker, executing any pending tasks.
45 void ActivateExtension(const Extension* extension);
46 // Performs Service Worker related tasks upon |extension| deactivation,
47 // e.g. unregistering |extension|'s worker.
48 void DeactivateExtension(const Extension* extension);
49
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2550 // Called once an extension Service Worker started running.
51 void DidStartServiceWorkerContext(const ExtensionId& extension_id,
52 int64_t service_worker_version_id);
53 // Called once an extension Service Worker was destroyed.
54 void DidStopServiceWorkerContext(const ExtensionId& extension_id,
55 int64_t service_worker_version_id);
56
Istiaque Ahmed70f76ac2018-11-02 02:59:5557 class TestObserver {
58 public:
59 TestObserver() = default;
60 virtual ~TestObserver() = default;
61
62 // Called when an extension with id |extension_id| is going to be activated.
63 // |will_register_service_worker| is true if a Service Worker will be
64 // registered.
65 virtual void OnActivateExtension(const ExtensionId& extension_id,
66 bool will_register_service_worker) = 0;
67
68 private:
69 DISALLOW_COPY_AND_ASSIGN(TestObserver);
70 };
71
72 static void SetObserverForTest(TestObserver* observer);
73
lazyboy63b994a2017-06-30 21:20:2374 private:
Istiaque Ahmedccb444022018-06-19 02:11:1275 struct TaskInfo;
76
Zhuoyu Qian2266251f2018-10-13 02:59:0077 static void DidStartWorkerForScopeOnIO(
David Bertoni16812fc2018-11-27 22:31:3878 PendingTask task,
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2579 const ExtensionId& extension_id,
80 base::WeakPtr<ServiceWorkerTaskQueue> task_queue,
81 int64_t version_id,
82 int process_id,
83 int thread_id);
84 static void StartServiceWorkerOnIOToRunTask(
85 base::WeakPtr<ServiceWorkerTaskQueue> task_queue_weak,
Zhuoyu Qian2266251f2018-10-13 02:59:0086 const GURL& scope,
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2587 const ExtensionId& extension_id,
88 content::ServiceWorkerContext* service_worker_context,
David Bertoni16812fc2018-11-27 22:31:3889 PendingTask task);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2590
David Bertoni27dfaff22018-12-12 20:05:3791 void RunTaskAfterStartWorker(const LazyContextId& context_id,
David Bertoni16812fc2018-11-27 22:31:3892 PendingTask task);
Istiaque Ahmedccb444022018-06-19 02:11:1293
94 void DidRegisterServiceWorker(const ExtensionId& extension_id, bool success);
95 void DidUnregisterServiceWorker(const ExtensionId& extension_id,
96 bool success);
97
David Bertoni16812fc2018-11-27 22:31:3898 void DidStartWorkerForScope(PendingTask task,
Zhuoyu Qian2266251f2018-10-13 02:59:0099 const ExtensionId& extension_id,
100 int64_t version_id,
101 int process_id,
102 int thread_id);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:25103
Istiaque Ahmed70f76ac2018-11-02 02:59:55104 // The following three methods retrieve, store, and remove information
105 // about Service Worker registration of SW based background pages:
106 //
107 // Retrieves the last version of the extension, returns invalid version if
108 // there isn't any such extension.
109 base::Version RetrieveRegisteredServiceWorkerVersion(
110 const ExtensionId& extension_id);
111 // Records that the extension with |extension_id| and |version| successfully
112 // registered a Service Worker.
113 void SetRegisteredServiceWorkerInfo(const ExtensionId& extension_id,
114 const base::Version& version);
115 // Clears any record of registered Service Worker for the given extension with
116 // |extension_id|.
117 void RemoveRegisteredServiceWorkerInfo(const ExtensionId& extension_id);
118
Istiaque Ahmedccb444022018-06-19 02:11:12119 // Set of extension ids that hasn't completed Service Worker registration.
120 std::set<ExtensionId> pending_registrations_;
121
122 // Map of extension id -> pending tasks. These are run once the Service Worker
123 // registration of the extension completes.
124 std::map<ExtensionId, std::vector<TaskInfo>> pending_tasks_;
125
Istiaque Ahmedb8e24bdb2018-09-13 15:17:25126 struct WaitingDidStartWorkerTask;
127
128 using WaitingDidStartWorkerTaskKey =
129 std::pair<ExtensionId, int64_t /* service_worker_version_id */>;
130 // All service workers that are currently loaded.
131 std::set<WaitingDidStartWorkerTaskKey> running_service_worker_contexts_;
132 // All service worker tasks that are waiting for the worker to start.
133 std::map<WaitingDidStartWorkerTaskKey, std::vector<WaitingDidStartWorkerTask>>
134 waiting_did_start_worker_tasks_;
135
Istiaque Ahmedccb444022018-06-19 02:11:12136 content::BrowserContext* const browser_context_ = nullptr;
137
138 base::WeakPtrFactory<ServiceWorkerTaskQueue> weak_factory_;
139
lazyboy63b994a2017-06-30 21:20:23140 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTaskQueue);
141};
142
143} // namespace extensions
144
145#endif // EXTENSIONS_BROWSER_SERVICE_WORKER_TASK_QUEUE_H_