OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/service_worker_provider_host.h" | 5 #include "content/browser/service_worker/service_worker_provider_host.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/feature_list.h" | 9 #include "base/feature_list.h" |
10 #include "base/guid.h" | 10 #include "base/guid.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "content/public/common/content_client.h" | 29 #include "content/public/common/content_client.h" |
30 #include "content/public/common/content_features.h" | 30 #include "content/public/common/content_features.h" |
31 #include "content/public/common/origin_util.h" | 31 #include "content/public/common/origin_util.h" |
32 #include "mojo/public/cpp/bindings/strong_associated_binding.h" | 32 #include "mojo/public/cpp/bindings/strong_associated_binding.h" |
33 #include "net/base/url_util.h" | 33 #include "net/base/url_util.h" |
34 | 34 |
35 namespace content { | 35 namespace content { |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 // Provider host for navigation with PlzNavigate or when service worker's | 39 // PlzNavigate |
40 // context is created on the browser side. This function provides the next | 40 // Next ServiceWorkerProviderHost ID for navigations, starts at -2 and keeps |
41 // ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down. | 41 // going down. |
42 int NextBrowserProvidedProviderId() { | 42 int g_next_navigation_provider_id = -2; |
43 static int g_next_browser_provided_provider_id = -2; | |
44 return g_next_browser_provided_provider_id--; | |
45 } | |
46 | 43 |
47 // A request handler derivative used to handle navigation requests when | 44 // A request handler derivative used to handle navigation requests when |
48 // skip_service_worker flag is set. It tracks the document URL and sets the url | 45 // skip_service_worker flag is set. It tracks the document URL and sets the url |
49 // to the provider host. | 46 // to the provider host. |
50 class ServiceWorkerURLTrackingRequestHandler | 47 class ServiceWorkerURLTrackingRequestHandler |
51 : public ServiceWorkerRequestHandler { | 48 : public ServiceWorkerRequestHandler { |
52 public: | 49 public: |
53 ServiceWorkerURLTrackingRequestHandler( | 50 ServiceWorkerURLTrackingRequestHandler( |
54 base::WeakPtr<ServiceWorkerContextCore> context, | 51 base::WeakPtr<ServiceWorkerContextCore> context, |
55 base::WeakPtr<ServiceWorkerProviderHost> provider_host, | 52 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
56 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 53 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
57 ResourceType resource_type) | 54 ResourceType resource_type) |
58 : ServiceWorkerRequestHandler(context, | 55 : ServiceWorkerRequestHandler(context, |
59 provider_host, | 56 provider_host, |
60 blob_storage_context, | 57 blob_storage_context, |
61 resource_type) {} | 58 resource_type) {} |
62 ~ServiceWorkerURLTrackingRequestHandler() override {} | 59 ~ServiceWorkerURLTrackingRequestHandler() override {} |
63 | 60 |
64 // Called via custom URLRequestJobFactory. | 61 // Called via custom URLRequestJobFactory. |
65 net::URLRequestJob* MaybeCreateJob(net::URLRequest* request, | 62 net::URLRequestJob* MaybeCreateJob( |
66 net::NetworkDelegate*, | 63 net::URLRequest* request, |
67 ResourceContext*) override { | 64 net::NetworkDelegate* /* network_delegate */, |
| 65 ResourceContext* /* resource_context */) override { |
68 // |provider_host_| may have been deleted when the request is resumed. | 66 // |provider_host_| may have been deleted when the request is resumed. |
69 if (!provider_host_) | 67 if (!provider_host_) |
70 return nullptr; | 68 return nullptr; |
71 const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); | 69 const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); |
72 provider_host_->SetDocumentUrl(stripped_url); | 70 provider_host_->SetDocumentUrl(stripped_url); |
73 provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); | 71 provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); |
74 return nullptr; | 72 return nullptr; |
75 } | 73 } |
76 | 74 |
77 private: | 75 private: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { | 107 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { |
110 } | 108 } |
111 | 109 |
112 // static | 110 // static |
113 std::unique_ptr<ServiceWorkerProviderHost> | 111 std::unique_ptr<ServiceWorkerProviderHost> |
114 ServiceWorkerProviderHost::PreCreateNavigationHost( | 112 ServiceWorkerProviderHost::PreCreateNavigationHost( |
115 base::WeakPtr<ServiceWorkerContextCore> context, | 113 base::WeakPtr<ServiceWorkerContextCore> context, |
116 bool are_ancestors_secure, | 114 bool are_ancestors_secure, |
117 const WebContentsGetter& web_contents_getter) { | 115 const WebContentsGetter& web_contents_getter) { |
118 CHECK(IsBrowserSideNavigationEnabled()); | 116 CHECK(IsBrowserSideNavigationEnabled()); |
| 117 // Generate a new browser-assigned id for the host. |
| 118 int provider_id = g_next_navigation_provider_id--; |
119 auto host = base::WrapUnique(new ServiceWorkerProviderHost( | 119 auto host = base::WrapUnique(new ServiceWorkerProviderHost( |
120 ChildProcessHost::kInvalidUniqueID, | 120 ChildProcessHost::kInvalidUniqueID, |
121 ServiceWorkerProviderHostInfo( | 121 ServiceWorkerProviderHostInfo(provider_id, MSG_ROUTING_NONE, |
122 NextBrowserProvidedProviderId(), MSG_ROUTING_NONE, | 122 SERVICE_WORKER_PROVIDER_FOR_WINDOW, |
123 SERVICE_WORKER_PROVIDER_FOR_WINDOW, are_ancestors_secure), | 123 are_ancestors_secure), |
124 context, nullptr)); | 124 context, nullptr)); |
125 host->web_contents_getter_ = web_contents_getter; | 125 host->web_contents_getter_ = web_contents_getter; |
126 return host; | 126 return host; |
127 } | 127 } |
128 | 128 |
129 // static | 129 // static |
130 std::unique_ptr<ServiceWorkerProviderHost> | |
131 ServiceWorkerProviderHost::PreCreateForController( | |
132 base::WeakPtr<ServiceWorkerContextCore> context) { | |
133 auto host = base::WrapUnique(new ServiceWorkerProviderHost( | |
134 ChildProcessHost::kInvalidUniqueID, | |
135 ServiceWorkerProviderHostInfo(NextBrowserProvidedProviderId(), | |
136 MSG_ROUTING_NONE, | |
137 SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, | |
138 true /* is_parent_frame_secure */), | |
139 std::move(context), nullptr)); | |
140 return host; | |
141 } | |
142 | |
143 // static | |
144 std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create( | 130 std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create( |
145 int process_id, | 131 int process_id, |
146 ServiceWorkerProviderHostInfo info, | 132 ServiceWorkerProviderHostInfo info, |
147 base::WeakPtr<ServiceWorkerContextCore> context, | 133 base::WeakPtr<ServiceWorkerContextCore> context, |
148 ServiceWorkerDispatcherHost* dispatcher_host) { | 134 ServiceWorkerDispatcherHost* dispatcher_host) { |
149 return base::WrapUnique(new ServiceWorkerProviderHost( | 135 return base::WrapUnique(new ServiceWorkerProviderHost( |
150 process_id, std::move(info), context, dispatcher_host)); | 136 process_id, std::move(info), context, dispatcher_host)); |
151 } | 137 } |
152 | 138 |
153 void ServiceWorkerProviderHost::BindWorkerFetchContext( | 139 void ServiceWorkerProviderHost::BindWorkerFetchContext( |
(...skipping 30 matching lines...) Expand all Loading... |
184 create_time_(base::TimeTicks::Now()), | 170 create_time_(base::TimeTicks::Now()), |
185 render_process_id_(render_process_id), | 171 render_process_id_(render_process_id), |
186 render_thread_id_(kDocumentMainThreadId), | 172 render_thread_id_(kDocumentMainThreadId), |
187 info_(std::move(info)), | 173 info_(std::move(info)), |
188 context_(context), | 174 context_(context), |
189 dispatcher_host_(dispatcher_host), | 175 dispatcher_host_(dispatcher_host), |
190 allow_association_(true), | 176 allow_association_(true), |
191 binding_(this) { | 177 binding_(this) { |
192 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); | 178 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); |
193 | 179 |
| 180 // PlzNavigate |
| 181 CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || |
| 182 IsBrowserSideNavigationEnabled()); |
194 | 183 |
195 if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { | 184 if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { |
196 // Actual |render_process_id| will be set after choosing a process for the | 185 // Actual thread id is set when the service worker context gets started. |
197 // controller, and |render_thread id| will be set when the service worker | |
198 // context gets started. | |
199 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id); | |
200 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 186 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
201 } else { | |
202 // PlzNavigate | |
203 DCHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || | |
204 IsBrowserSideNavigationEnabled()); | |
205 } | 187 } |
206 | |
207 context_->RegisterProviderHostByClientID(client_uuid_, this); | 188 context_->RegisterProviderHostByClientID(client_uuid_, this); |
208 | 189 |
209 // |client_| and |binding_| will be bound on CompleteNavigationInitialized | 190 // PlzNavigate |
210 // (PlzNavigate) or on CompleteStartWorkerPreparation (providers for | 191 // |provider_| and |binding_| will be bound on CompleteNavigationInitialized. |
211 // controller). | 192 if (IsBrowserSideNavigationEnabled()) { |
212 if (!info_.client_ptr_info.is_valid() && !info_.host_request.is_pending()) { | 193 DCHECK(!info.client_ptr_info.is_valid() && !info.host_request.is_pending()); |
213 DCHECK(IsBrowserSideNavigationEnabled() || | |
214 info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER); | |
215 return; | 194 return; |
216 } | 195 } |
217 | 196 |
218 provider_.Bind(std::move(info_.client_ptr_info)); | 197 provider_.Bind(std::move(info_.client_ptr_info)); |
219 binding_.Bind(std::move(info_.host_request)); | 198 binding_.Bind(std::move(info_.host_request)); |
220 binding_.set_connection_error_handler(base::Bind( | 199 binding_.set_connection_error_handler(base::Bind( |
221 &RemoveProviderHost, context_, render_process_id, info_.provider_id)); | 200 &RemoveProviderHost, context_, render_process_id, info_.provider_id)); |
222 } | 201 } |
223 | 202 |
224 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { | 203 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 return; // Could be NULL in some tests. | 317 return; // Could be NULL in some tests. |
339 | 318 |
340 // SetController message should be sent only for controllees. | 319 // SetController message should be sent only for controllees. |
341 DCHECK(IsProviderForClient()); | 320 DCHECK(IsProviderForClient()); |
342 Send(new ServiceWorkerMsg_SetControllerServiceWorker( | 321 Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
343 render_thread_id_, provider_id(), GetOrCreateServiceWorkerHandle(version), | 322 render_thread_id_, provider_id(), GetOrCreateServiceWorkerHandle(version), |
344 notify_controllerchange, | 323 notify_controllerchange, |
345 version ? version->used_features() : std::set<uint32_t>())); | 324 version ? version->used_features() : std::set<uint32_t>())); |
346 } | 325 } |
347 | 326 |
| 327 void ServiceWorkerProviderHost::SetHostedVersion( |
| 328 ServiceWorkerVersion* version) { |
| 329 DCHECK(!IsProviderForClient()); |
| 330 DCHECK_EQ(EmbeddedWorkerStatus::STARTING, version->running_status()); |
| 331 DCHECK_EQ(render_process_id_, version->embedded_worker()->process_id()); |
| 332 running_hosted_version_ = version; |
| 333 } |
| 334 |
348 bool ServiceWorkerProviderHost::IsProviderForClient() const { | 335 bool ServiceWorkerProviderHost::IsProviderForClient() const { |
349 switch (info_.type) { | 336 switch (info_.type) { |
350 case SERVICE_WORKER_PROVIDER_FOR_WINDOW: | 337 case SERVICE_WORKER_PROVIDER_FOR_WINDOW: |
351 case SERVICE_WORKER_PROVIDER_FOR_WORKER: | 338 case SERVICE_WORKER_PROVIDER_FOR_WORKER: |
352 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: | 339 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: |
353 return true; | 340 return true; |
354 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: | 341 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
355 return false; | 342 return false; |
356 case SERVICE_WORKER_PROVIDER_UNKNOWN: | 343 case SERVICE_WORKER_PROVIDER_UNKNOWN: |
357 NOTREACHED() << info_.type; | 344 NOTREACHED() << info_.type; |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 // Increase the references because the process which this provider host will | 652 // Increase the references because the process which this provider host will |
666 // host has been decided. | 653 // host has been decided. |
667 for (const GURL& pattern : associated_patterns_) | 654 for (const GURL& pattern : associated_patterns_) |
668 IncreaseProcessReference(pattern); | 655 IncreaseProcessReference(pattern); |
669 for (auto& key_registration : matching_registrations_) | 656 for (auto& key_registration : matching_registrations_) |
670 IncreaseProcessReference(key_registration.second->pattern()); | 657 IncreaseProcessReference(key_registration.second->pattern()); |
671 | 658 |
672 NotifyControllerToAssociatedProvider(); | 659 NotifyControllerToAssociatedProvider(); |
673 } | 660 } |
674 | 661 |
675 mojom::ServiceWorkerProviderInfoForStartWorkerPtr | |
676 ServiceWorkerProviderHost::CompleteStartWorkerPreparation( | |
677 int process_id, | |
678 scoped_refptr<ServiceWorkerVersion> hosted_version) { | |
679 DCHECK(context_); | |
680 DCHECK_EQ(kInvalidEmbeddedWorkerThreadId, render_thread_id_); | |
681 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); | |
682 DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, provider_type()); | |
683 DCHECK(!running_hosted_version_); | |
684 | |
685 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id); | |
686 | |
687 running_hosted_version_ = std::move(hosted_version); | |
688 | |
689 ServiceWorkerDispatcherHost* dispatcher_host = | |
690 context_->GetDispatcherHost(process_id); | |
691 DCHECK(dispatcher_host); | |
692 render_process_id_ = process_id; | |
693 dispatcher_host_ = dispatcher_host; | |
694 | |
695 // Retrieve the registration associated with |version|. The registration | |
696 // must be alive because the version keeps it during starting worker. | |
697 ServiceWorkerRegistration* registration = context_->GetLiveRegistration( | |
698 running_hosted_version()->registration_id()); | |
699 DCHECK(registration); | |
700 ServiceWorkerRegistrationObjectInfo info; | |
701 ServiceWorkerVersionAttributes attrs; | |
702 dispatcher_host->GetRegistrationObjectInfoAndVersionAttributes( | |
703 AsWeakPtr(), registration, &info, &attrs); | |
704 | |
705 // Initialize provider_info. | |
706 mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info = | |
707 mojom::ServiceWorkerProviderInfoForStartWorker::New(); | |
708 provider_info->provider_id = provider_id(); | |
709 provider_info->attributes = std::move(attrs); | |
710 provider_info->registration = std::move(info); | |
711 provider_info->client_request = mojo::MakeRequest(&provider_); | |
712 binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info)); | |
713 binding_.set_connection_error_handler( | |
714 base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); | |
715 | |
716 // Set the document URL to the script url in order to allow | |
717 // register/unregister/getRegistration on ServiceWorkerGlobalScope. | |
718 SetDocumentUrl(running_hosted_version()->script_url()); | |
719 | |
720 return provider_info; | |
721 } | |
722 | |
723 void ServiceWorkerProviderHost::SendUpdateFoundMessage( | 662 void ServiceWorkerProviderHost::SendUpdateFoundMessage( |
724 int registration_handle_id) { | 663 int registration_handle_id) { |
725 if (!dispatcher_host_) | 664 if (!dispatcher_host_) |
726 return; // Could be nullptr in some tests. | 665 return; // Could be nullptr in some tests. |
727 | 666 |
728 if (!IsReadyToSendMessages()) { | 667 if (!IsReadyToSendMessages()) { |
729 queued_events_.push_back( | 668 queued_events_.push_back( |
730 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage, | 669 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage, |
731 AsWeakPtr(), registration_handle_id)); | 670 AsWeakPtr(), registration_handle_id)); |
732 return; | 671 return; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 render_thread_id_, provider_id(), | 831 render_thread_id_, provider_id(), |
893 GetOrCreateServiceWorkerHandle( | 832 GetOrCreateServiceWorkerHandle( |
894 associated_registration_->active_version()), | 833 associated_registration_->active_version()), |
895 false /* shouldNotifyControllerChange */, | 834 false /* shouldNotifyControllerChange */, |
896 associated_registration_->active_version()->used_features())); | 835 associated_registration_->active_version()->used_features())); |
897 } | 836 } |
898 } | 837 } |
899 } | 838 } |
900 | 839 |
901 } // namespace content | 840 } // namespace content |
OLD | NEW |