1 // 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 CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_
6 #define CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_
7 
8 #include <memory>
9 
10 #include "base/optional.h"
11 #include "base/scoped_observer.h"
12 #include "build/build_config.h"
13 #include "content/browser/browser_interface_broker_impl.h"
14 #include "content/public/browser/dedicated_worker_service.h"
15 #include "content/public/browser/global_routing_id.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_process_host_observer.h"
18 #include "media/mojo/mojom/video_decode_perf_history.mojom.h"
19 #include "mojo/public/cpp/bindings/pending_receiver.h"
20 #include "mojo/public/cpp/bindings/pending_remote.h"
21 #include "mojo/public/cpp/bindings/receiver.h"
22 #include "mojo/public/cpp/bindings/remote.h"
23 #include "services/network/public/cpp/cross_origin_embedder_policy.h"
24 #include "third_party/blink/public/mojom/filesystem/file_system.mojom-forward.h"
25 #include "third_party/blink/public/mojom/idle/idle_manager.mojom-forward.h"
26 #include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h"
27 #include "third_party/blink/public/mojom/sms/sms_receiver.mojom-forward.h"
28 #include "third_party/blink/public/mojom/usb/web_usb_service.mojom-forward.h"
29 #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-forward.h"
30 #include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-forward.h"
31 #include "third_party/blink/public/mojom/webtransport/quic_transport_connector.mojom-forward.h"
32 #include "third_party/blink/public/mojom/worker/dedicated_worker_host.mojom.h"
33 #include "third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom.h"
34 #include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h"
35 
36 #if !defined(OS_ANDROID)
37 #include "third_party/blink/public/mojom/serial/serial.mojom-forward.h"
38 #endif
39 
40 namespace url {
41 class Origin;
42 }
43 
44 namespace content {
45 
46 class CrossOriginEmbedderPolicyReporter;
47 class DedicatedWorkerServiceImpl;
48 class ServiceWorkerMainResourceHandle;
49 class ServiceWorkerObjectHost;
50 class StoragePartitionImpl;
51 
52 // Creates a host factory for a dedicated worker. This must be called on the UI
53 // thread.
54 CONTENT_EXPORT void CreateDedicatedWorkerHostFactory(
55     int worker_process_id,
56     base::Optional<GlobalFrameRoutingId> creator_render_frame_host_id,
57     GlobalFrameRoutingId ancestor_render_frame_host_id,
58     const url::Origin& creator_origin,
59     const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
60     mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
61         coep_reporter,
62     mojo::PendingReceiver<blink::mojom::DedicatedWorkerHostFactory> receiver);
63 
64 // A host for a single dedicated worker. It deletes itself upon Mojo
65 // disconnection from the worker in the renderer or when the RenderProcessHost
66 // of the worker is destroyed. This lives on the UI thread.
67 class DedicatedWorkerHost final : public blink::mojom::DedicatedWorkerHost,
68                                   public RenderProcessHostObserver {
69  public:
70   DedicatedWorkerHost(
71       DedicatedWorkerServiceImpl* service,
72       DedicatedWorkerId id,
73       RenderProcessHost* worker_process_host,
74       base::Optional<GlobalFrameRoutingId> creator_render_frame_host_id,
75       GlobalFrameRoutingId ancestor_render_frame_host_id,
76       const url::Origin& creator_origin,
77       const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
78       mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
79           coep_reporter,
80       mojo::PendingReceiver<blink::mojom::DedicatedWorkerHost> host);
81   ~DedicatedWorkerHost() final;
82 
83   void BindBrowserInterfaceBrokerReceiver(
84       mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker> receiver);
85 
GetProcessHost()86   RenderProcessHost* GetProcessHost() { return worker_process_host_; }
GetWorkerOrigin()87   const url::Origin& GetWorkerOrigin() { return worker_origin_; }
88 
89   void CreateIdleManager(
90       mojo::PendingReceiver<blink::mojom::IdleManager> receiver);
91   void CreateNestedDedicatedWorker(
92       mojo::PendingReceiver<blink::mojom::DedicatedWorkerHostFactory> receiver);
93   void BindSmsReceiverReceiver(
94       mojo::PendingReceiver<blink::mojom::SmsReceiver> receiver);
95   void CreateWebUsbService(
96       mojo::PendingReceiver<blink::mojom::WebUsbService> receiver);
97   void CreateWebSocketConnector(
98       mojo::PendingReceiver<blink::mojom::WebSocketConnector> receiver);
99   void CreateQuicTransportConnector(
100       mojo::PendingReceiver<blink::mojom::QuicTransportConnector> receiver);
101   void CreateWakeLockService(
102       mojo::PendingReceiver<blink::mojom::WakeLockService> receiver);
103   void BindCacheStorage(
104       mojo::PendingReceiver<blink::mojom::CacheStorage> receiver);
105 
106 #if !defined(OS_ANDROID)
107   void BindSerialService(
108       mojo::PendingReceiver<blink::mojom::SerialService> receiver);
109 #endif
110 
111   // blink::mojom::DedicatedWorkerHost:
112   void LifecycleStateChanged(blink::mojom::FrameLifecycleState state) override;
113 
114   // TODO(dtapuska): This state needs to be hooked up to the
115   // ServiceWorkerProviderHost so the correct state is queried when looking
116   // for frozen dedicated workers. crbug.com/968417
is_frozen()117   bool is_frozen() const { return is_frozen_; }
118 
119   // PlzDedicatedWorker:
120   void StartScriptLoad(
121       const GURL& script_url,
122       network::mojom::CredentialsMode credentials_mode,
123       blink::mojom::FetchClientSettingsObjectPtr
124           outside_fetch_client_settings_object,
125       mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token,
126       mojo::Remote<blink::mojom::DedicatedWorkerHostFactoryClient> client);
127 
128   void ReportNoBinderForInterface(const std::string& error);
129 
130  private:
131   // RenderProcessHostObserver:
132   void RenderProcessExited(RenderProcessHost* render_process_host,
133                            const ChildProcessTerminationInfo& info) override;
134 
135   // Called from WorkerScriptFetchInitiator. Continues starting the dedicated
136   // worker in the renderer process.
137   //
138   // |success| is true only when the script fetch succeeded.
139   //
140   // Note: None of the following parameters are valid if |success| is false.
141   //
142   // |main_script_load_params| is sent to the renderer process and to be used to
143   // load the dedicated worker main script pre-requested by the browser process.
144   //
145   // |subresource_loader_factories| is sent to the renderer process and is to be
146   // used to request subresources where applicable. For example, this allows the
147   // dedicated worker to load chrome-extension:// URLs which the renderer's
148   // default loader factory can't load.
149   //
150   // |controller| contains information about the service worker controller. Once
151   // a ServiceWorker object about the controller is prepared, it is registered
152   // to |controller_service_worker_object_host|.
153   //
154   // |final_response_url| is the URL calculated from the initial request URL,
155   // redirect chain, and URLs fetched via service worker.
156   // https://fetch.spec.whatwg.org/#concept-response-url
157   void DidStartScriptLoad(
158       bool success,
159       std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
160           subresource_loader_factories,
161       blink::mojom::WorkerMainScriptLoadParamsPtr main_script_load_params,
162       blink::mojom::ControllerServiceWorkerInfoPtr controller,
163       base::WeakPtr<ServiceWorkerObjectHost>
164           controller_service_worker_object_host,
165       const GURL& final_response_url);
166 
167   // Sets up the observer of network service crash.
168   void ObserveNetworkServiceCrash(StoragePartitionImpl* storage_partition_impl);
169 
170   // Creates a network factory for subresource requests from this worker. The
171   // network factory is meant to be passed to the renderer.
172   mojo::PendingRemote<network::mojom::URLLoaderFactory>
173   CreateNetworkFactoryForSubresources(
174       RenderFrameHostImpl* ancestor_render_frame_host,
175       bool* bypass_redirect_checks);
176 
177   // Updates subresource loader factories. This is supposed to be called when
178   // out-of-process Network Service crashes.
179   void UpdateSubresourceLoaderFactories();
180 
181   void OnMojoDisconnect();
182 
183   DedicatedWorkerServiceImpl* const service_;
184 
185   // An internal ID that is unique within a storage partition.
186   const DedicatedWorkerId id_;
187 
188   // The RenderProcessHost that hosts this worker.
189   RenderProcessHost* const worker_process_host_;
190 
191   ScopedObserver<RenderProcessHost, RenderProcessHostObserver>
192       scoped_process_host_observer_;
193 
194   // The ID of the frame that directly starts this worker. This is base::nullopt
195   // when this worker is nested.
196   const base::Optional<GlobalFrameRoutingId> creator_render_frame_host_id_;
197 
198   // The ID of the frame that owns this worker, either directly, or (in the case
199   // of nested workers) indirectly via a tree of dedicated workers.
200   const GlobalFrameRoutingId ancestor_render_frame_host_id_;
201 
202   // The origin of the frame or dedicated worker that starts this worker.
203   const url::Origin creator_origin_;
204 
205   // The origin of this worker.
206   // https://html.spec.whatwg.org/C/#concept-settings-object-origin
207   const url::Origin worker_origin_;
208 
209   // The network isolation key to be used for both the worker script and the
210   // worker's subresources.
211   net::NetworkIsolationKey network_isolation_key_;
212 
213   // The DedicatedWorker's Cross-Origin-Embedder-Policy(COEP). It is equals to
214   // the nearest ancestor frame host's COEP:
215   // https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global
216   const network::CrossOriginEmbedderPolicy cross_origin_embedder_policy_;
217 
218   // This is kept alive during the lifetime of the dedicated worker, since it's
219   // associated with Mojo interfaces (ServiceWorkerContainer and
220   // URLLoaderFactory) that are needed to stay alive while the worker is
221   // starting or running.
222   mojo::Remote<blink::mojom::DedicatedWorkerHostFactoryClient> client_;
223 
224   std::unique_ptr<ServiceWorkerMainResourceHandle> service_worker_handle_;
225 
226   BrowserInterfaceBrokerImpl<DedicatedWorkerHost, const url::Origin&> broker_{
227       this};
228   mojo::Receiver<blink::mojom::BrowserInterfaceBroker> broker_receiver_{
229       &broker_};
230   mojo::Receiver<blink::mojom::DedicatedWorkerHost> host_receiver_;
231 
232   // Indicates if subresource loaders of this worker support file URLs.
233   bool file_url_support_ = false;
234 
235   // The liveness state of the dedicated worker in the renderer.
236   bool is_frozen_ = false;
237 
238   // For observing Network Service connection errors only.
239   mojo::Remote<network::mojom::URLLoaderFactory>
240       network_service_connection_error_handler_holder_;
241   mojo::Remote<blink::mojom::SubresourceLoaderUpdater>
242       subresource_loader_updater_;
243 
244   // The endpoint of this mojo interface is the RenderFrameHostImpl's COEP
245   // reporter. The COEP endpoint is correct, but the context_url is the
246   // Document's URL.
247   // TODO(arthursonzogni): After landing PlzDedicatedWorker, make the
248   // DedicatedWorkerHost to have its own COEP reporter using the right
249   // context_url.
250   mojo::Remote<network::mojom::CrossOriginEmbedderPolicyReporter>
251       coep_reporter_;  // Never null.
252 
253   base::WeakPtrFactory<DedicatedWorkerHost> weak_factory_{this};
254 
255   DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerHost);
256 };
257 
258 }  // namespace content
259 
260 #endif  // CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_
261