blob: dafa067e4f5ea9baf98b3dc8d0f084e373dac8ca [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>
Istiaque Ahmed4b70a70d2019-02-28 01:36:5710#include <vector>
Istiaque Ahmedccb444022018-06-19 02:11:1211
12#include "base/memory/weak_ptr.h"
Istiaque Ahmed70f76ac2018-11-02 02:59:5513#include "base/version.h"
lazyboy63b994a2017-06-30 21:20:2314#include "components/keyed_service/core/keyed_service.h"
15#include "extensions/browser/lazy_context_task_queue.h"
16#include "extensions/common/extension_id.h"
17#include "url/gurl.h"
18
19namespace content {
20class BrowserContext;
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2521class ServiceWorkerContext;
lazyboy63b994a2017-06-30 21:20:2322}
23
24namespace extensions {
25class Extension;
26class LazyContextId;
27
lazyboy63b994a2017-06-30 21:20:2328// TODO(lazyboy): Clean up queue when extension is unloaded/uninstalled.
Istiaque Ahmed4b70a70d2019-02-28 01:36:5729// TODO(lazyboy): Describe the flow of a task in this queue: i.e. when
30// a worker receives DidRegisterServiceWorker, DidStartWorkerForScope and
31// DidStartServiceWorkerContext events and how queued tasks react to these
32// events.
lazyboy63b994a2017-06-30 21:20:2333class ServiceWorkerTaskQueue : public KeyedService,
34 public LazyContextTaskQueue {
35 public:
36 explicit ServiceWorkerTaskQueue(content::BrowserContext* browser_context);
37 ~ServiceWorkerTaskQueue() override;
38
39 // Convenience method to return the ServiceWorkerTaskQueue for a given
40 // |context|.
41 static ServiceWorkerTaskQueue* Get(content::BrowserContext* context);
42
43 bool ShouldEnqueueTask(content::BrowserContext* context,
44 const Extension* extension) override;
David Bertoni8269a092018-12-19 15:55:4245 void AddPendingTask(const LazyContextId& context_id,
46 PendingTask task) override;
lazyboy63b994a2017-06-30 21:20:2347
Istiaque Ahmedccb444022018-06-19 02:11:1248 // Performs Service Worker related tasks upon |extension| activation,
49 // e.g. registering |extension|'s worker, executing any pending tasks.
50 void ActivateExtension(const Extension* extension);
51 // Performs Service Worker related tasks upon |extension| deactivation,
52 // e.g. unregistering |extension|'s worker.
53 void DeactivateExtension(const Extension* extension);
54
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2555 // Called once an extension Service Worker started running.
Istiaque Ahmed4b70a70d2019-02-28 01:36:5756 // This can be thought as "loadstop", i.e. the global JS script of the worker
57 // has completed executing.
58 void DidStartServiceWorkerContext(int render_process_id,
59 const ExtensionId& extension_id,
60 const GURL& service_worker_scope,
61 int64_t service_worker_version_id,
62 int thread_id);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2563 // Called once an extension Service Worker was destroyed.
Istiaque Ahmed4b70a70d2019-02-28 01:36:5764 void DidStopServiceWorkerContext(int render_process_id,
65 const ExtensionId& extension_id,
66 const GURL& service_worker_scope,
67 int64_t service_worker_version_id,
68 int thread_id);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2569
Istiaque Ahmed70f76ac2018-11-02 02:59:5570 class TestObserver {
71 public:
72 TestObserver() = default;
73 virtual ~TestObserver() = default;
74
75 // Called when an extension with id |extension_id| is going to be activated.
76 // |will_register_service_worker| is true if a Service Worker will be
77 // registered.
78 virtual void OnActivateExtension(const ExtensionId& extension_id,
79 bool will_register_service_worker) = 0;
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(TestObserver);
83 };
84
85 static void SetObserverForTest(TestObserver* observer);
86
lazyboy63b994a2017-06-30 21:20:2387 private:
Zhuoyu Qian2266251f2018-10-13 02:59:0088 static void DidStartWorkerForScopeOnIO(
Istiaque Ahmed4b70a70d2019-02-28 01:36:5789 const LazyContextId& context_id,
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2590 base::WeakPtr<ServiceWorkerTaskQueue> task_queue,
91 int64_t version_id,
92 int process_id,
93 int thread_id);
Istiaque Ahmed4b70a70d2019-02-28 01:36:5794 static void StartServiceWorkerOnIOToRunTasks(
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2595 base::WeakPtr<ServiceWorkerTaskQueue> task_queue_weak,
Istiaque Ahmed4b70a70d2019-02-28 01:36:5796 const LazyContextId& context_id,
97 content::ServiceWorkerContext* service_worker_context);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:2598
Istiaque Ahmed4b70a70d2019-02-28 01:36:5799 void RunTasksAfterStartWorker(const LazyContextId& context_id);
Istiaque Ahmedccb444022018-06-19 02:11:12100
101 void DidRegisterServiceWorker(const ExtensionId& extension_id, bool success);
102 void DidUnregisterServiceWorker(const ExtensionId& extension_id,
103 bool success);
104
Istiaque Ahmed4b70a70d2019-02-28 01:36:57105 void DidStartWorkerForScope(const LazyContextId& context_id,
Zhuoyu Qian2266251f2018-10-13 02:59:00106 int64_t version_id,
107 int process_id,
108 int thread_id);
Istiaque Ahmedb8e24bdb2018-09-13 15:17:25109
Istiaque Ahmed70f76ac2018-11-02 02:59:55110 // The following three methods retrieve, store, and remove information
111 // about Service Worker registration of SW based background pages:
112 //
113 // Retrieves the last version of the extension, returns invalid version if
114 // there isn't any such extension.
115 base::Version RetrieveRegisteredServiceWorkerVersion(
116 const ExtensionId& extension_id);
117 // Records that the extension with |extension_id| and |version| successfully
118 // registered a Service Worker.
119 void SetRegisteredServiceWorkerInfo(const ExtensionId& extension_id,
120 const base::Version& version);
121 // Clears any record of registered Service Worker for the given extension with
122 // |extension_id|.
123 void RemoveRegisteredServiceWorkerInfo(const ExtensionId& extension_id);
124
Istiaque Ahmed4b70a70d2019-02-28 01:36:57125 // If the worker with |context_id| has seen worker start
126 // (DidStartWorkerForScope) and load (DidStartServiceWorkerContext) then runs
127 // all pending tasks for that worker.
128 void RunPendingTasksIfWorkerReady(const LazyContextId& context_id,
129 int64_t version_id,
130 int process_id,
131 int thread_id);
132
Istiaque Ahmedccb444022018-06-19 02:11:12133 // Set of extension ids that hasn't completed Service Worker registration.
134 std::set<ExtensionId> pending_registrations_;
135
Istiaque Ahmed4b70a70d2019-02-28 01:36:57136 // Set of workers that has seen DidStartWorkerForScope.
137 std::set<LazyContextId> started_workers_;
Istiaque Ahmedccb444022018-06-19 02:11:12138
Istiaque Ahmed4b70a70d2019-02-28 01:36:57139 // Set of workers that has seen DidStartServiceWorkerContext.
140 std::set<LazyContextId> loaded_workers_;
Istiaque Ahmedb8e24bdb2018-09-13 15:17:25141
Istiaque Ahmed4b70a70d2019-02-28 01:36:57142 // Pending tasks for a |LazyContextId|.
143 // These tasks will be run once the corresponding worker becomes ready.
144 std::map<LazyContextId, std::vector<PendingTask>> pending_tasks_;
Istiaque Ahmedb8e24bdb2018-09-13 15:17:25145
Istiaque Ahmedccb444022018-06-19 02:11:12146 content::BrowserContext* const browser_context_ = nullptr;
147
148 base::WeakPtrFactory<ServiceWorkerTaskQueue> weak_factory_;
149
lazyboy63b994a2017-06-30 21:20:23150 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTaskQueue);
151};
152
153} // namespace extensions
154
155#endif // EXTENSIONS_BROWSER_SERVICE_WORKER_TASK_QUEUE_H_