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 // PlzNavigate | 39 // Provider host for navigation with PlzNavigate or service worker's context is |
40 // Next ServiceWorkerProviderHost ID for navigations, starts at -2 and keeps | 40 // created on the browser side. This function provides the next |
41 // going down. | 41 // ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down. |
42 int g_next_navigation_provider_id = -2; | 42 int NextBrowserProvidedProviderId() { |
43 static int g_next_browser_provided_provider_id = -2; | |
44 return g_next_browser_provided_provider_id--; | |
45 } | |
43 | 46 |
44 // A request handler derivative used to handle navigation requests when | 47 // A request handler derivative used to handle navigation requests when |
45 // skip_service_worker flag is set. It tracks the document URL and sets the url | 48 // skip_service_worker flag is set. It tracks the document URL and sets the url |
46 // to the provider host. | 49 // to the provider host. |
47 class ServiceWorkerURLTrackingRequestHandler | 50 class ServiceWorkerURLTrackingRequestHandler |
48 : public ServiceWorkerRequestHandler { | 51 : public ServiceWorkerRequestHandler { |
49 public: | 52 public: |
50 ServiceWorkerURLTrackingRequestHandler( | 53 ServiceWorkerURLTrackingRequestHandler( |
51 base::WeakPtr<ServiceWorkerContextCore> context, | 54 base::WeakPtr<ServiceWorkerContextCore> context, |
52 base::WeakPtr<ServiceWorkerProviderHost> provider_host, | 55 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
53 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 56 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
54 ResourceType resource_type) | 57 ResourceType resource_type) |
55 : ServiceWorkerRequestHandler(context, | 58 : ServiceWorkerRequestHandler(context, |
56 provider_host, | 59 provider_host, |
57 blob_storage_context, | 60 blob_storage_context, |
58 resource_type) {} | 61 resource_type) {} |
59 ~ServiceWorkerURLTrackingRequestHandler() override {} | 62 ~ServiceWorkerURLTrackingRequestHandler() override {} |
60 | 63 |
61 // Called via custom URLRequestJobFactory. | 64 // Called via custom URLRequestJobFactory. |
62 net::URLRequestJob* MaybeCreateJob( | 65 net::URLRequestJob* MaybeCreateJob(net::URLRequest* request, |
63 net::URLRequest* request, | 66 net::NetworkDelegate*, |
64 net::NetworkDelegate* /* network_delegate */, | 67 ResourceContext*) override { |
65 ResourceContext* /* resource_context */) override { | |
66 // |provider_host_| may have been deleted when the request is resumed. | 68 // |provider_host_| may have been deleted when the request is resumed. |
67 if (!provider_host_) | 69 if (!provider_host_) |
68 return nullptr; | 70 return nullptr; |
69 const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); | 71 const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); |
70 provider_host_->SetDocumentUrl(stripped_url); | 72 provider_host_->SetDocumentUrl(stripped_url); |
71 provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); | 73 provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); |
72 return nullptr; | 74 return nullptr; |
73 } | 75 } |
74 | 76 |
75 private: | 77 private: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { | 109 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { |
108 } | 110 } |
109 | 111 |
110 // static | 112 // static |
111 std::unique_ptr<ServiceWorkerProviderHost> | 113 std::unique_ptr<ServiceWorkerProviderHost> |
112 ServiceWorkerProviderHost::PreCreateNavigationHost( | 114 ServiceWorkerProviderHost::PreCreateNavigationHost( |
113 base::WeakPtr<ServiceWorkerContextCore> context, | 115 base::WeakPtr<ServiceWorkerContextCore> context, |
114 bool are_ancestors_secure, | 116 bool are_ancestors_secure, |
115 const WebContentsGetter& web_contents_getter) { | 117 const WebContentsGetter& web_contents_getter) { |
116 CHECK(IsBrowserSideNavigationEnabled()); | 118 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(provider_id, MSG_ROUTING_NONE, | 121 ServiceWorkerProviderHostInfo( |
122 SERVICE_WORKER_PROVIDER_FOR_WINDOW, | 122 NextBrowserProvidedProviderId(), MSG_ROUTING_NONE, |
123 are_ancestors_secure), | 123 SERVICE_WORKER_PROVIDER_FOR_WINDOW, 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::PreCreateForWorkerContext( | |
132 ServiceWorkerVersion* version, | |
133 base::WeakPtr<ServiceWorkerContextCore> context) { | |
134 auto host = base::WrapUnique(new ServiceWorkerProviderHost( | |
135 ChildProcessHost::kInvalidUniqueID, | |
136 ServiceWorkerProviderHostInfo(NextBrowserProvidedProviderId(), | |
137 MSG_ROUTING_NONE, | |
138 SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, | |
139 true /* is_parent_frame_secure */), | |
140 context, nullptr)); | |
141 host->SetHostedVersion(version); | |
142 return host; | |
143 } | |
144 | |
145 // static | |
130 std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create( | 146 std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create( |
131 int process_id, | 147 int process_id, |
132 ServiceWorkerProviderHostInfo info, | 148 ServiceWorkerProviderHostInfo info, |
133 base::WeakPtr<ServiceWorkerContextCore> context, | 149 base::WeakPtr<ServiceWorkerContextCore> context, |
134 ServiceWorkerDispatcherHost* dispatcher_host) { | 150 ServiceWorkerDispatcherHost* dispatcher_host) { |
135 return base::WrapUnique(new ServiceWorkerProviderHost( | 151 return base::WrapUnique(new ServiceWorkerProviderHost( |
136 process_id, std::move(info), context, dispatcher_host)); | 152 process_id, std::move(info), context, dispatcher_host)); |
137 } | 153 } |
138 | 154 |
139 void ServiceWorkerProviderHost::BindWorkerFetchContext( | 155 void ServiceWorkerProviderHost::BindWorkerFetchContext( |
(...skipping 30 matching lines...) Expand all Loading... | |
170 create_time_(base::TimeTicks::Now()), | 186 create_time_(base::TimeTicks::Now()), |
171 render_process_id_(render_process_id), | 187 render_process_id_(render_process_id), |
172 render_thread_id_(kDocumentMainThreadId), | 188 render_thread_id_(kDocumentMainThreadId), |
173 info_(std::move(info)), | 189 info_(std::move(info)), |
174 context_(context), | 190 context_(context), |
175 dispatcher_host_(dispatcher_host), | 191 dispatcher_host_(dispatcher_host), |
176 allow_association_(true), | 192 allow_association_(true), |
177 binding_(this) { | 193 binding_(this) { |
178 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); | 194 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); |
179 | 195 |
180 // PlzNavigate | |
181 CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || | |
182 IsBrowserSideNavigationEnabled()); | |
183 | 196 |
184 if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { | 197 if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { |
185 // Actual thread id is set when the service worker context gets started. | 198 // Actual |render_process_id| will be set after choosing a process for the |
199 // controller, and |render_thread id| will be set when the service worker | |
200 // context gets started. | |
201 CHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id); | |
falken
2017/06/14 08:10:34
Is there a reason this is a CHECK isntead of a DCH
shimazu
2017/06/16 04:18:43
Done.
| |
186 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 202 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
203 } else { | |
204 // PlzNavigate | |
205 CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || | |
206 IsBrowserSideNavigationEnabled()); | |
187 } | 207 } |
208 | |
188 context_->RegisterProviderHostByClientID(client_uuid_, this); | 209 context_->RegisterProviderHostByClientID(client_uuid_, this); |
189 | 210 |
190 // PlzNavigate | 211 // |client_| and |binding_| will be bound on CompleteNavigationInitialized |
191 // |provider_| and |binding_| will be bound on CompleteNavigationInitialized. | 212 // (PlzNavigate) or on CompleteStartWorkerPreparation (providers for |
192 if (IsBrowserSideNavigationEnabled()) { | 213 // controller). |
193 DCHECK(!info.client_ptr_info.is_valid() && !info.host_request.is_pending()); | 214 if (!info_.client_ptr_info.is_valid() && !info_.host_request.is_pending()) { |
215 DCHECK(IsBrowserSideNavigationEnabled() || | |
216 info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER); | |
194 return; | 217 return; |
195 } | 218 } |
196 | 219 |
197 provider_.Bind(std::move(info_.client_ptr_info)); | 220 provider_.Bind(std::move(info_.client_ptr_info)); |
198 binding_.Bind(std::move(info_.host_request)); | 221 binding_.Bind(std::move(info_.host_request)); |
199 binding_.set_connection_error_handler(base::Bind( | 222 binding_.set_connection_error_handler(base::Bind( |
200 &RemoveProviderHost, context_, render_process_id, info_.provider_id)); | 223 &RemoveProviderHost, context_, render_process_id, info_.provider_id)); |
201 } | 224 } |
202 | 225 |
203 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { | 226 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 DCHECK(IsProviderForClient()); | 343 DCHECK(IsProviderForClient()); |
321 Send(new ServiceWorkerMsg_SetControllerServiceWorker( | 344 Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
322 render_thread_id_, provider_id(), GetOrCreateServiceWorkerHandle(version), | 345 render_thread_id_, provider_id(), GetOrCreateServiceWorkerHandle(version), |
323 notify_controllerchange, | 346 notify_controllerchange, |
324 version ? version->used_features() : std::set<uint32_t>())); | 347 version ? version->used_features() : std::set<uint32_t>())); |
325 } | 348 } |
326 | 349 |
327 void ServiceWorkerProviderHost::SetHostedVersion( | 350 void ServiceWorkerProviderHost::SetHostedVersion( |
328 ServiceWorkerVersion* version) { | 351 ServiceWorkerVersion* version) { |
329 DCHECK(!IsProviderForClient()); | 352 DCHECK(!IsProviderForClient()); |
330 DCHECK_EQ(EmbeddedWorkerStatus::STARTING, version->running_status()); | 353 DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status()); |
falken
2017/06/14 08:10:35
does DCHECK(!running_hosted_version_) also hold?
shimazu
2017/06/16 04:18:43
Sounds good!
| |
331 DCHECK_EQ(render_process_id_, version->embedded_worker()->process_id()); | |
332 running_hosted_version_ = version; | 354 running_hosted_version_ = version; |
333 } | 355 } |
334 | 356 |
335 bool ServiceWorkerProviderHost::IsProviderForClient() const { | 357 bool ServiceWorkerProviderHost::IsProviderForClient() const { |
336 switch (info_.type) { | 358 switch (info_.type) { |
337 case SERVICE_WORKER_PROVIDER_FOR_WINDOW: | 359 case SERVICE_WORKER_PROVIDER_FOR_WINDOW: |
338 case SERVICE_WORKER_PROVIDER_FOR_WORKER: | 360 case SERVICE_WORKER_PROVIDER_FOR_WORKER: |
339 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: | 361 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: |
340 return true; | 362 return true; |
341 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: | 363 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 // Increase the references because the process which this provider host will | 674 // Increase the references because the process which this provider host will |
653 // host has been decided. | 675 // host has been decided. |
654 for (const GURL& pattern : associated_patterns_) | 676 for (const GURL& pattern : associated_patterns_) |
655 IncreaseProcessReference(pattern); | 677 IncreaseProcessReference(pattern); |
656 for (auto& key_registration : matching_registrations_) | 678 for (auto& key_registration : matching_registrations_) |
657 IncreaseProcessReference(key_registration.second->pattern()); | 679 IncreaseProcessReference(key_registration.second->pattern()); |
658 | 680 |
659 NotifyControllerToAssociatedProvider(); | 681 NotifyControllerToAssociatedProvider(); |
660 } | 682 } |
661 | 683 |
684 void ServiceWorkerProviderHost::CompleteStartWorkerPreparation( | |
685 int process_id, | |
686 mojom::ServiceWorkerProviderClientInfoPtr* provider_client_info) { | |
687 DCHECK(context_); | |
688 | |
689 DCHECK_EQ(kInvalidEmbeddedWorkerThreadId, render_thread_id_); | |
690 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); | |
691 DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, provider_type()); | |
692 DCHECK(running_hosted_version_); | |
693 | |
694 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id); | |
695 | |
696 ServiceWorkerDispatcherHost* dispatcher_host = | |
697 context_->GetDispatcherHost(process_id); | |
698 DCHECK(dispatcher_host); | |
falken
2017/06/14 08:10:35
Is it possible the process crashed by the time we
shimazu
2017/06/16 04:18:43
Yes, I think so.
Between EmbeddedWorkerInstance::
falken
2017/06/16 15:44:46
If the process crashed, I think dispatcher_host wo
kinuko
2017/06/19 03:20:07
I have a question, if it's possible that process c
shimazu
2017/06/19 03:53:30
Ah, sorry, I didn't understand what falken pointed
| |
699 render_process_id_ = process_id; | |
700 dispatcher_host_ = dispatcher_host; | |
701 | |
702 // Retrieve the registration associated with |version|. The registration | |
703 // must be alive because the version keeps it during starting worker. | |
704 ServiceWorkerRegistration* registration = context_->GetLiveRegistration( | |
705 running_hosted_version()->registration_id()); | |
706 DCHECK(registration); | |
707 ServiceWorkerRegistrationObjectInfo info; | |
708 ServiceWorkerVersionAttributes attrs; | |
709 dispatcher_host->GetRegistrationObjectInfoAndVersionAttributes( | |
710 AsWeakPtr(), registration, &info, &attrs); | |
711 | |
712 // Initialize provider_client_info. | |
713 (*provider_client_info)->provider_id = provider_id(); | |
714 (*provider_client_info)->type = provider_type(); | |
715 (*provider_client_info)->attributes = std::move(attrs); | |
716 (*provider_client_info)->registration = std::move(info); | |
717 (*provider_client_info)->is_parent_frame_secure = is_parent_frame_secure(); | |
718 (*provider_client_info)->client_request = mojo::MakeRequest(&provider_); | |
719 binding_.Bind(mojo::MakeRequest(&(*provider_client_info)->host_ptr_info)); | |
720 binding_.set_connection_error_handler( | |
721 base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); | |
falken
2017/06/14 08:10:34
If the process already crashed, does the error han
shimazu
2017/06/16 04:18:43
Yes, I think so. It'll be triggered when calling S
| |
722 | |
723 // Set the document URL to the script url in order to allow | |
724 // register/unregister/getRegistration on ServiceWorkerGlobalScope. | |
725 SetDocumentUrl(running_hosted_version()->script_url()); | |
726 } | |
727 | |
662 void ServiceWorkerProviderHost::SendUpdateFoundMessage( | 728 void ServiceWorkerProviderHost::SendUpdateFoundMessage( |
663 int registration_handle_id) { | 729 int registration_handle_id) { |
664 if (!dispatcher_host_) | 730 if (!dispatcher_host_) |
665 return; // Could be nullptr in some tests. | 731 return; // Could be nullptr in some tests. |
666 | 732 |
667 if (!IsReadyToSendMessages()) { | 733 if (!IsReadyToSendMessages()) { |
668 queued_events_.push_back( | 734 queued_events_.push_back( |
669 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage, | 735 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage, |
670 AsWeakPtr(), registration_handle_id)); | 736 AsWeakPtr(), registration_handle_id)); |
671 return; | 737 return; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
831 render_thread_id_, provider_id(), | 897 render_thread_id_, provider_id(), |
832 GetOrCreateServiceWorkerHandle( | 898 GetOrCreateServiceWorkerHandle( |
833 associated_registration_->active_version()), | 899 associated_registration_->active_version()), |
834 false /* shouldNotifyControllerChange */, | 900 false /* shouldNotifyControllerChange */, |
835 associated_registration_->active_version()->used_features())); | 901 associated_registration_->active_version()->used_features())); |
836 } | 902 } |
837 } | 903 } |
838 } | 904 } |
839 | 905 |
840 } // namespace content | 906 } // namespace content |
OLD | NEW |