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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CLIENT_H_ 6 #define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CLIENT_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <map> 12 #include <memory> 13 #include <string> 14 15 #include "base/callback.h" 16 #include "base/containers/id_map.h" 17 #include "base/macros.h" 18 #include "base/memory/scoped_refptr.h" 19 #include "base/strings/string16.h" 20 #include "base/time/time.h" 21 #include "content/common/content_export.h" 22 #include "ipc/ipc_listener.h" 23 #include "mojo/public/cpp/bindings/pending_associated_remote.h" 24 #include "mojo/public/cpp/bindings/pending_receiver.h" 25 #include "mojo/public/cpp/bindings/remote.h" 26 #include "mojo/public/cpp/bindings/shared_associated_remote.h" 27 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" 28 #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-forward.h" 29 #include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h" 30 #include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom-forward.h" 31 #include "third_party/blink/public/mojom/service_worker/embedded_worker.mojom.h" 32 #include "third_party/blink/public/mojom/service_worker/service_worker.mojom-forward.h" 33 #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-forward.h" 34 #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-forward.h" 35 #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom-forward.h" 36 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-forward.h" 37 #include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom-forward.h" 38 #include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom-forward.h" 39 #include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom.h" 40 #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h" 41 #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h" 42 #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" 43 #include "third_party/blink/public/web/web_embedded_worker.h" 44 #include "v8/include/v8.h" 45 46 namespace base { 47 class SequencedTaskRunner; 48 class SingleThreadTaskRunner; 49 } 50 51 namespace blink { 52 class ChildURLLoaderFactoryBundle; 53 class WebServiceWorkerContextProxy; 54 class WebURLResponse; 55 struct WebServiceWorkerInstalledScriptsManagerParams; 56 } 57 58 namespace content { 59 60 class EmbeddedWorkerInstanceClientImpl; 61 class WebServiceWorkerFetchContext; 62 63 // ServiceWorkerContextClient is a "client" of a service worker execution 64 // context. It enables communication between the embedder and Blink's 65 // ServiceWorkerGlobalScope. It is created when the service worker begins 66 // starting up, and destroyed when the service worker stops. It is owned by 67 // WebEmbeddedWorkerImpl (which is owned by EmbeddedWorkerInstanceClientImpl). 68 // 69 // This class is created and destroyed on the "initiator" thread. The initiator 70 // thread is the thread that constructs this class. Currently it's the main 71 // thread but could be the IO thread in the future. https://crbug.com/692909 72 // 73 // Unless otherwise noted (here or in base class documentation), all methods 74 // are called on the worker thread. 75 class CONTENT_EXPORT ServiceWorkerContextClient 76 : public blink::WebServiceWorkerContextClient { 77 public: 78 // Called on the initiator thread. 79 // - |is_starting_installed_worker| is true if the script is already installed 80 // and will be streamed from the browser process. 81 // - |owner| must outlive this new instance. 82 // - |start_timing| should be initially populated with 83 // |start_worker_received_time|. This instance will fill in the rest during 84 // startup. 85 // - |subresource_loader_updater| is a mojo receiver that will be bound to 86 // ServiceWorkerFetchContextImpl. This interface is used to update 87 // subresource loader factories. 88 // - |script_url_to_skip_throttling| is the URL of the service worker script 89 // that already started being loaded by the browser process due to the 90 // update check, or the empty URL if there is no such script. See also 91 // comments in EmbeddedWorkerStartParams::script_url_to_skip_throttling. 92 ServiceWorkerContextClient( 93 int64_t service_worker_version_id, 94 const GURL& service_worker_scope, 95 const GURL& script_url, 96 bool is_starting_installed_worker, 97 const blink::RendererPreferences& renderer_preferences, 98 mojo::PendingReceiver<blink::mojom::ServiceWorker> 99 service_worker_receiver, 100 mojo::PendingReceiver<blink::mojom::ControllerServiceWorker> 101 controller_receiver, 102 mojo::PendingAssociatedRemote<blink::mojom::EmbeddedWorkerInstanceHost> 103 instance_host, 104 blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, 105 EmbeddedWorkerInstanceClientImpl* owner, 106 blink::mojom::EmbeddedWorkerStartTimingPtr start_timing, 107 mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> 108 preference_watcher_receiver, 109 std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders, 110 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 111 subresource_loader_updater, 112 const GURL& script_url_to_skip_throttling, 113 scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner, 114 int32_t service_worker_route_id, 115 const std::vector<std::string>& cors_exempt_header_list); 116 // Called on the initiator thread. 117 ~ServiceWorkerContextClient() override; 118 119 // Called on the initiator thread. 120 void StartWorkerContextOnInitiatorThread( 121 std::unique_ptr<blink::WebEmbeddedWorker> worker, 122 std::unique_ptr<blink::WebEmbeddedWorkerStartData> start_data, 123 std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams>, 124 mojo::PendingRemote<blink::mojom::WorkerContentSettingsProxy> 125 content_settings, 126 mojo::PendingRemote<blink::mojom::CacheStorage> cache_storage, 127 mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker> 128 browser_interface_broker); 129 130 // Called on the initiator thread. 131 blink::WebEmbeddedWorker& worker(); 132 133 // WebServiceWorkerContextClient overrides. 134 void WorkerReadyForInspectionOnInitiatorThread( 135 blink::CrossVariantMojoRemote<blink::mojom::DevToolsAgentInterfaceBase> 136 devtools_agent_remote, 137 blink::CrossVariantMojoReceiver< 138 blink::mojom::DevToolsAgentHostInterfaceBase> 139 devtools_agent_host_receiver) override; 140 void FailedToFetchClassicScript() override; 141 void FailedToFetchModuleScript() override; 142 void WorkerScriptLoadedOnWorkerThread() override; 143 void WorkerContextStarted( 144 blink::WebServiceWorkerContextProxy* proxy, 145 scoped_refptr<base::SequencedTaskRunner> worker_task_runner) override; 146 void WillEvaluateScript(v8::Local<v8::Context> v8_context) override; 147 void DidEvaluateScript(bool success) override; 148 void WillInitializeWorkerContext() override; 149 void WillDestroyWorkerContext(v8::Local<v8::Context> context) override; 150 void WorkerContextDestroyed() override; 151 void CountFeature(blink::mojom::WebFeature feature) override; 152 void ReportException(const blink::WebString& error_message, 153 int line_number, 154 int column_number, 155 const blink::WebString& source_url) override; 156 void ReportConsoleMessage(blink::mojom::ConsoleMessageSource source, 157 blink::mojom::ConsoleMessageLevel level, 158 const blink::WebString& message, 159 int line_number, 160 const blink::WebString& source_url) override; 161 void SetupNavigationPreload(int fetch_event_id, 162 const blink::WebURL& url, 163 std::unique_ptr<blink::WebFetchEventPreloadHandle> 164 preload_handle) override; 165 void RequestTermination(RequestTerminationCallback callback) override; 166 scoped_refptr<blink::WebServiceWorkerFetchContext> 167 CreateWorkerFetchContextOnInitiatorThread() override; 168 169 ///////////////////////////////////////////////////////////////////////////// 170 // The following are for use by NavigationPreloadRequest. 171 // 172 // Called to resolve the FetchEvent.preloadResponse promise. 173 void OnNavigationPreloadResponse( 174 int fetch_event_id, 175 std::unique_ptr<blink::WebURLResponse> response, 176 mojo::ScopedDataPipeConsumerHandle data_pipe); 177 178 // Called when the navigation preload request completed. Either 179 // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be 180 // called to release the preload related resources. 181 void OnNavigationPreloadComplete(int fetch_event_id, 182 base::TimeTicks completion_time, 183 int64_t encoded_data_length, 184 int64_t encoded_body_length, 185 int64_t decoded_body_length); 186 187 // Called when an error occurred while receiving the response of the 188 // navigation preload request. 189 void OnNavigationPreloadError( 190 int fetch_event_id, 191 std::unique_ptr<blink::WebServiceWorkerError> error); 192 ///////////////////////////////////////////////////////////////////////////// 193 194 private: 195 struct WorkerContextData; 196 friend class ControllerServiceWorkerImpl; 197 friend class ServiceWorkerContextClientTest; 198 FRIEND_TEST_ALL_PREFIXES( 199 ServiceWorkerContextClientTest, 200 DispatchOrQueueFetchEvent_RequestedTerminationAndDie); 201 FRIEND_TEST_ALL_PREFIXES( 202 ServiceWorkerContextClientTest, 203 DispatchOrQueueFetchEvent_RequestedTerminationAndWakeUp); 204 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextClientTest, 205 DispatchOrQueueFetchEvent_NotRequestedTermination); 206 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextClientTest, TaskInServiceWorker); 207 208 void SendWorkerStarted(blink::mojom::ServiceWorkerStartStatus status); 209 210 // Stops the worker context. Called on the initiator thread. 211 void StopWorkerOnInitiatorThread(); 212 213 base::WeakPtr<ServiceWorkerContextClient> GetWeakPtr(); 214 215 const int64_t service_worker_version_id_; 216 const GURL service_worker_scope_; 217 const GURL script_url_; 218 // True if this service worker was already installed at worker 219 // startup time. 220 const bool is_starting_installed_worker_; 221 222 // See comments in EmbeddedWorkerStartParams::script_url_to_skip_throttling. 223 const GURL script_url_to_skip_throttling_; 224 225 blink::RendererPreferences renderer_preferences_; 226 // Passed on creation of ServiceWorkerFetchContext. 227 mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> 228 preference_watcher_receiver_; 229 230 scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner_; 231 scoped_refptr<base::SequencedTaskRunner> worker_task_runner_; 232 233 // Not owned; |this| is destroyed when |proxy_| becomes invalid. 234 blink::WebServiceWorkerContextProxy* proxy_; 235 236 // These Mojo objects are bound on the worker thread. 237 mojo::PendingReceiver<blink::mojom::ServiceWorker> 238 pending_service_worker_receiver_; 239 mojo::PendingReceiver<blink::mojom::ControllerServiceWorker> 240 controller_receiver_; 241 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 242 pending_subresource_loader_updater_; 243 244 // This is bound on the initiator thread. 245 mojo::SharedAssociatedRemote<blink::mojom::EmbeddedWorkerInstanceHost> 246 instance_host_; 247 248 // This holds blink.mojom.ServiceWorkerContainer(Host) connections to the 249 // browser-side ServiceWorkerHost to keep it alive there. 250 // Note: |service_worker_provider_info_->script_loader_factory_remote| is 251 // moved to WebServiceWorkerNetworkProviderImpl when 252 // CreateServiceWorkerNetworkProvider is called. 253 blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr 254 service_worker_provider_info_; 255 256 // Must be accessed on the initiator thread only. 257 EmbeddedWorkerInstanceClientImpl* owner_; 258 259 // Initialized on the worker thread in WorkerContextStarted and 260 // destructed on the worker thread in WillDestroyWorkerContext. 261 // 262 // WARNING: This can be cleared at nearly any time, since WillDestroyContext 263 // is called by Blink when it decides to terminate the worker thread. This 264 // includes during event dispatch if a JavaScript debugger breakpoint pauses 265 // execution (see issue 934622). It should be safe to assume |context_| is 266 // valid at the start of a task that was posted to |worker_task_runner_|, as 267 // that is from WorkerThread::GetTaskRunner() which safely drops the task on 268 // worker termination. 269 std::unique_ptr<WorkerContextData> context_; 270 271 // Accessed on the worker thread. Passed to the browser process after worker 272 // startup completes. 273 blink::mojom::EmbeddedWorkerStartTimingPtr start_timing_; 274 275 // A URLLoaderFactory instance used for subresource loading. 276 scoped_refptr<blink::ChildURLLoaderFactoryBundle> loader_factories_; 277 278 // Out-of-process NetworkService: 279 // Detects disconnection from the network service. 280 mojo::Remote<network::mojom::URLLoaderFactory> 281 network_service_disconnect_handler_holder_; 282 283 std::unique_ptr<blink::WebEmbeddedWorker> worker_; 284 285 int32_t service_worker_route_id_; 286 287 std::vector<std::string> cors_exempt_header_list_; 288 289 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextClient); 290 }; 291 292 } // namespace content 293 294 #endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CLIENT_H_ 295