1 // Copyright 2013 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.
5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "content/browser/service_worker/service_worker_registration.h"
14 #include "content/common/content_export.h"
15 #include "content/common/service_worker/service_worker_types.h"
16 #include "content/public/common/request_context_frame_type.h"
17 #include "content/public/common/request_context_type.h"
18 #include "content/public/common/resource_type.h"
25 class BlobStorageContext
;
30 class ResourceRequestBody
;
31 class ServiceWorkerContextCore
;
32 class ServiceWorkerDispatcherHost
;
33 class ServiceWorkerRequestHandler
;
34 class ServiceWorkerVersion
;
36 // This class is the browser-process representation of a service worker
37 // provider. There is a provider per document or a worker and the lifetime
38 // of this object is tied to the lifetime of its document or the worker
39 // in the renderer process.
40 // This class holds service worker state that is scoped to an individual
41 // document or a worker.
43 // Note this class can also host a running service worker, in which
44 // case it will observe resource loads made directly by the service worker.
45 class CONTENT_EXPORT ServiceWorkerProviderHost
46 : public NON_EXPORTED_BASE(ServiceWorkerRegistration::Listener
),
47 public base::SupportsWeakPtr
<ServiceWorkerProviderHost
> {
49 using GetClientInfoCallback
=
50 base::Callback
<void(const ServiceWorkerClientInfo
&)>;
51 using GetRegistrationForReadyCallback
=
52 base::Callback
<void(ServiceWorkerRegistration
* reigstration
)>;
54 // When this provider host is for a Service Worker context, |route_id| is
55 // MSG_ROUTING_NONE. When this provider host is for a Document,
56 // |route_id| is the frame ID of the Document. When this provider host is for
57 // a Shared Worker, |route_id| is the Shared Worker route ID.
58 // |provider_type| gives additional information whether the provider is
59 // created for controller (ServiceWorker) or controllee (Document or
61 ServiceWorkerProviderHost(int render_process_id
,
64 ServiceWorkerProviderType provider_type
,
65 base::WeakPtr
<ServiceWorkerContextCore
> context
,
66 ServiceWorkerDispatcherHost
* dispatcher_host
);
67 virtual ~ServiceWorkerProviderHost();
69 const std::string
& client_uuid() const { return client_uuid_
; }
70 int process_id() const { return render_process_id_
; }
71 int provider_id() const { return provider_id_
; }
73 int route_id() const { return route_id_
; }
75 bool IsHostToRunningServiceWorker() {
76 return running_hosted_version_
.get() != NULL
;
79 ServiceWorkerVersion
* controlling_version() const {
80 return controlling_version_
.get();
82 ServiceWorkerVersion
* active_version() const {
83 return associated_registration_
.get() ?
84 associated_registration_
->active_version() : NULL
;
86 ServiceWorkerVersion
* waiting_version() const {
87 return associated_registration_
.get() ?
88 associated_registration_
->waiting_version() : NULL
;
90 ServiceWorkerVersion
* installing_version() const {
91 return associated_registration_
.get() ?
92 associated_registration_
->installing_version() : NULL
;
95 ServiceWorkerRegistration
* associated_registration() const {
96 return associated_registration_
.get();
99 // The running version, if any, that this provider is providing resource
101 ServiceWorkerVersion
* running_hosted_version() const {
102 return running_hosted_version_
.get();
105 void SetDocumentUrl(const GURL
& url
);
106 const GURL
& document_url() const { return document_url_
; }
108 void SetTopmostFrameUrl(const GURL
& url
);
109 const GURL
& topmost_frame_url() const { return topmost_frame_url_
; }
111 ServiceWorkerProviderType
provider_type() const { return provider_type_
; }
112 bool IsProviderForClient() const;
113 blink::WebServiceWorkerClientType
client_type() const;
115 // Associates to |registration| to listen for its version change events and
116 // sets the controller. If |notify_controllerchange| is true, instructs the
117 // renderer to dispatch a 'controllerchange' event.
118 void AssociateRegistration(ServiceWorkerRegistration
* registration
,
119 bool notify_controllerchange
);
121 // Clears the associated registration and stop listening to it.
122 void DisassociateRegistration();
124 // Returns false if the version is not in the expected STARTING in our
125 // process state. That would be indicative of a bad IPC message.
126 bool SetHostedVersionId(int64 versions_id
);
128 // Returns a handler for a request, the handler may return NULL if
129 // the request doesn't require special handling.
130 scoped_ptr
<ServiceWorkerRequestHandler
> CreateRequestHandler(
131 FetchRequestMode request_mode
,
132 FetchCredentialsMode credentials_mode
,
133 FetchRedirectMode redirect_mode
,
134 ResourceType resource_type
,
135 RequestContextType request_context_type
,
136 RequestContextFrameType frame_type
,
137 base::WeakPtr
<storage::BlobStorageContext
> blob_storage_context
,
138 scoped_refptr
<ResourceRequestBody
> body
);
140 // Used to get a ServiceWorkerObjectInfo to send to the renderer. Finds an
141 // existing ServiceWorkerHandle, and increments its reference count, or else
142 // creates a new one (initialized to ref count 1). Returns the
143 // ServiceWorkerInfo from the handle. The renderer is expected to use
144 // ServiceWorkerHandleReference::Adopt to balance out the ref count.
145 ServiceWorkerObjectInfo
GetOrCreateServiceWorkerHandle(
146 ServiceWorkerVersion
* version
);
148 // Returns true if |registration| can be associated with this provider.
149 bool CanAssociateRegistration(ServiceWorkerRegistration
* registration
);
151 // For use by the ServiceWorkerControlleeRequestHandler to disallow
152 // new registration association while a navigation is occurring and
153 // an existing registration is being looked for.
154 void SetAllowAssociation(bool allow
) { allow_association_
= allow
; }
156 // Returns true if the context referred to by this host (i.e. |context_|) is
158 bool IsContextAlive();
160 // Dispatches message event to the document.
162 ServiceWorkerVersion
* version
,
163 const base::string16
& message
,
164 const std::vector
<TransferredMessagePort
>& sent_message_ports
);
166 // Activates the WebContents associated with
167 // { render_process_id_, route_id_ }.
168 // Runs the |callback| with the updated ServiceWorkerClientInfo in parameter.
169 void Focus(const GetClientInfoCallback
& callback
);
171 // Asks the renderer to send back the document information.
172 void GetWindowClientInfo(const GetClientInfoCallback
& callback
) const;
174 // Same as above but has to be called from the UI thread.
175 // It is taking the process and frame ids in parameter because |this| is meant
176 // to live on the IO thread.
177 static ServiceWorkerClientInfo
GetWindowClientInfoOnUI(int render_process_id
,
178 int render_frame_id
);
180 // Adds reference of this host's process to the |pattern|, the reference will
181 // be removed in destructor.
182 void AddScopedProcessReferenceToPattern(const GURL
& pattern
);
184 // |registration| claims the document to be controlled.
185 void ClaimedByRegistration(ServiceWorkerRegistration
* registration
);
187 // Called by dispatcher host to get the registration for the "ready" property.
188 // Returns false if there's a completed or ongoing request for the document.
189 // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-ready
190 bool GetRegistrationForReady(const GetRegistrationForReadyCallback
& callback
);
192 // Methods to support cross site navigations.
193 void PrepareForCrossSiteTransfer();
194 void CompleteCrossSiteTransfer(
198 ServiceWorkerProviderType new_provider_type
,
199 ServiceWorkerDispatcherHost
* dispatcher_host
);
200 ServiceWorkerDispatcherHost
* dispatcher_host() const {
201 return dispatcher_host_
;
204 // Sends event messages to the renderer. Events for the worker are queued up
205 // until the worker thread id is known via SetReadyToSendMessagesToWorker().
206 void SendUpdateFoundMessage(
207 int registration_handle_id
);
208 void SendSetVersionAttributesMessage(
209 int registration_handle_id
,
210 ChangedVersionAttributesMask changed_mask
,
211 ServiceWorkerVersion
* installing_version
,
212 ServiceWorkerVersion
* waiting_version
,
213 ServiceWorkerVersion
* active_version
);
214 void SendServiceWorkerStateChangedMessage(
215 int worker_handle_id
,
216 blink::WebServiceWorkerState state
);
218 // Sets the worker thread id and flushes queued events.
219 void SetReadyToSendMessagesToWorker(int render_thread_id
);
221 void AddMatchingRegistration(ServiceWorkerRegistration
* registration
);
222 void RemoveMatchingRegistration(ServiceWorkerRegistration
* registration
);
224 // Add matched registrations for document generated by shift-reload.
225 void AddAllMatchingRegistrations();
227 // An optimized implementation of [[Match Service Worker Registration]]
228 // for current document.
229 ServiceWorkerRegistration
* MatchRegistration() const;
231 // Called when our controller has been terminated and doomed due to an
232 // exceptional condition like it could no longer be read from the script
234 void NotifyControllerLost();
237 friend class ServiceWorkerProviderHostTest
;
238 friend class ServiceWorkerWriteToCacheJobTest
;
239 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest
, Update_SameScript
);
240 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest
,
241 Update_SameSizeScript
);
242 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest
,
243 Update_TruncatedScript
);
244 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest
,
245 Update_ElongatedScript
);
246 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest
,
248 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest
,
249 UpdateBefore24Hours
);
250 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest
,
252 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest
,
253 UpdateForceBypassCache
);
255 struct OneShotGetReadyCallback
{
256 GetRegistrationForReadyCallback callback
;
259 explicit OneShotGetReadyCallback(
260 const GetRegistrationForReadyCallback
& callback
);
261 ~OneShotGetReadyCallback();
264 // ServiceWorkerRegistration::Listener overrides.
265 void OnVersionAttributesChanged(
266 ServiceWorkerRegistration
* registration
,
267 ChangedVersionAttributesMask changed_mask
,
268 const ServiceWorkerRegistrationInfo
& info
) override
;
269 void OnRegistrationFailed(ServiceWorkerRegistration
* registration
) override
;
270 void OnRegistrationFinishedUninstalling(
271 ServiceWorkerRegistration
* registration
) override
;
272 void OnSkippedWaiting(ServiceWorkerRegistration
* registration
) override
;
274 // Sets the controller version field to |version| or if |version| is NULL,
275 // clears the field. If |notify_controllerchange| is true, instructs the
276 // renderer to dispatch a 'controller' change event.
277 void SetControllerVersionAttribute(ServiceWorkerVersion
* version
,
278 bool notify_controllerchange
);
280 void SendAssociateRegistrationMessage();
282 // Increase/decrease this host's process reference for |pattern|.
283 void IncreaseProcessReference(const GURL
& pattern
);
284 void DecreaseProcessReference(const GURL
& pattern
);
286 void ReturnRegistrationForReadyIfNeeded();
288 bool IsReadyToSendMessages() const;
289 void Send(IPC::Message
* message
) const;
291 std::string client_uuid_
;
292 int render_process_id_
;
294 int render_thread_id_
;
296 ServiceWorkerProviderType provider_type_
;
298 GURL topmost_frame_url_
;
300 std::vector
<GURL
> associated_patterns_
;
301 scoped_refptr
<ServiceWorkerRegistration
> associated_registration_
;
303 // Keyed by registration scope URL length.
304 typedef std::map
<size_t, scoped_refptr
<ServiceWorkerRegistration
>>
305 ServiceWorkerRegistrationMap
;
306 // Contains all living registrations which has pattern this document's
308 ServiceWorkerRegistrationMap matching_registrations_
;
310 scoped_ptr
<OneShotGetReadyCallback
> get_ready_callback_
;
311 scoped_refptr
<ServiceWorkerVersion
> controlling_version_
;
312 scoped_refptr
<ServiceWorkerVersion
> running_hosted_version_
;
313 base::WeakPtr
<ServiceWorkerContextCore
> context_
;
314 ServiceWorkerDispatcherHost
* dispatcher_host_
;
315 bool allow_association_
;
317 std::vector
<base::Closure
> queued_events_
;
319 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHost
);
322 } // namespace content
324 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_