Index: content/browser/service_worker/service_worker_provider_host.cc |
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc |
index 3e6025d0c57ec6d57d22475b1dc8862158e81640..86c53ddf8b97697dde059643806bdc3ba8bf52de 100644 |
--- a/content/browser/service_worker/service_worker_provider_host.cc |
+++ b/content/browser/service_worker/service_worker_provider_host.cc |
@@ -61,8 +61,8 @@ class ServiceWorkerURLTrackingRequestHandler |
// Called via custom URLRequestJobFactory. |
net::URLRequestJob* MaybeCreateJob( |
net::URLRequest* request, |
- net::NetworkDelegate* network_delegate, |
- ResourceContext* resource_context) override { |
+ net::NetworkDelegate* /* network_delegate */, |
+ ResourceContext* /* resource_context */) override { |
// |provider_host_| may have been deleted when the request is resumed. |
if (!provider_host_) |
return nullptr; |
@@ -76,6 +76,25 @@ class ServiceWorkerURLTrackingRequestHandler |
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLTrackingRequestHandler); |
}; |
+void RemoveProviderHost(base::WeakPtr<ServiceWorkerContextCore> context, |
+ int process_id, |
+ int provider_id) { |
+ TRACE_EVENT0("ServiceWorker", |
+ "ServiceWorkerProviderHost::RemoveProviderHost"); |
+ if (!context) |
+ return; |
+ if (!context->GetProviderHost(process_id, provider_id)) { |
+ // PlzNavigate: in some cancellation of navigation cases, it is possible |
+ // for the pre-created host to have been destroyed before being claimed by |
+ // the renderer. The provider is then destroyed in the renderer, and no |
+ // matching host will be found. |
+ CHECK(IsBrowserSideNavigationEnabled() && |
+ ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)); |
+ return; |
+ } |
+ context->RemoveProviderHost(process_id, provider_id); |
+} |
+ |
} // anonymous namespace |
ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( |
@@ -97,9 +116,11 @@ ServiceWorkerProviderHost::PreCreateNavigationHost( |
// Generate a new browser-assigned id for the host. |
int provider_id = g_next_navigation_provider_id--; |
auto host = base::WrapUnique(new ServiceWorkerProviderHost( |
- ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE, provider_id, |
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, are_ancestors_secure, context, |
- nullptr)); |
+ ChildProcessHost::kInvalidUniqueID, |
+ ServiceWorkerProviderHostInfo(provider_id, MSG_ROUTING_NONE, |
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, |
+ are_ancestors_secure), |
+ context, nullptr)); |
host->web_contents_getter_ = web_contents_getter; |
return host; |
} |
@@ -111,8 +132,7 @@ std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create( |
base::WeakPtr<ServiceWorkerContextCore> context, |
ServiceWorkerDispatcherHost* dispatcher_host) { |
return base::WrapUnique(new ServiceWorkerProviderHost( |
- process_id, info.route_id, info.provider_id, info.type, |
- info.is_parent_frame_secure, context, dispatcher_host)); |
+ process_id, std::move(info), context, dispatcher_host)); |
} |
void ServiceWorkerProviderHost::BindWorkerFetchContext( |
@@ -142,33 +162,40 @@ void ServiceWorkerProviderHost::UnregisterWorkerFetchContext( |
ServiceWorkerProviderHost::ServiceWorkerProviderHost( |
int render_process_id, |
- int route_id, |
- int provider_id, |
- ServiceWorkerProviderType provider_type, |
- bool is_parent_frame_secure, |
+ ServiceWorkerProviderHostInfo info, |
base::WeakPtr<ServiceWorkerContextCore> context, |
ServiceWorkerDispatcherHost* dispatcher_host) |
: client_uuid_(base::GenerateGUID()), |
render_process_id_(render_process_id), |
- route_id_(route_id), |
render_thread_id_(kDocumentMainThreadId), |
- provider_id_(provider_id), |
- provider_type_(provider_type), |
- is_parent_frame_secure_(is_parent_frame_secure), |
+ info_(std::move(info)), |
context_(context), |
dispatcher_host_(dispatcher_host), |
- allow_association_(true) { |
- DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_); |
+ allow_association_(true), |
+ binding_(this) { |
+ DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); |
// PlzNavigate |
CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || |
IsBrowserSideNavigationEnabled()); |
- if (provider_type_ == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { |
+ if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) { |
// Actual thread id is set when the service worker context gets started. |
render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
} |
context_->RegisterProviderHostByClientID(client_uuid_, this); |
+ |
+ // PlzNavigate |
+ // |client_| and |binding_| will be bound on CompleteNavigationInitialized. |
+ if (IsBrowserSideNavigationEnabled()) { |
+ DCHECK(!info.client_ptr_info.is_valid() && !info.host_request.is_pending()); |
+ return; |
+ } |
+ |
+ client_.Bind(std::move(info_.client_ptr_info)); |
+ binding_.Bind(std::move(info_.host_request)); |
+ binding_.set_connection_error_handler(base::Bind( |
+ &RemoveProviderHost, context_, render_process_id, info_.provider_id)); |
} |
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
@@ -188,8 +215,8 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
} |
int ServiceWorkerProviderHost::frame_id() const { |
- if (provider_type_ == SERVICE_WORKER_PROVIDER_FOR_WINDOW) |
- return route_id_; |
+ if (info_.type == SERVICE_WORKER_PROVIDER_FOR_WINDOW) |
+ return info_.route_id; |
return MSG_ROUTING_NONE; |
} |
@@ -215,7 +242,7 @@ bool ServiceWorkerProviderHost::IsContextSecureForServiceWorker() const { |
void ServiceWorkerProviderHost::OnVersionAttributesChanged( |
ServiceWorkerRegistration* registration, |
ChangedVersionAttributesMask changed_mask, |
- const ServiceWorkerRegistrationInfo& info) { |
+ const ServiceWorkerRegistrationInfo& /* info */) { |
if (!get_ready_callback_ || get_ready_callback_->called) |
return; |
if (changed_mask.active_changed() && registration->active_version()) { |
@@ -304,7 +331,7 @@ void ServiceWorkerProviderHost::SetHostedVersion( |
} |
bool ServiceWorkerProviderHost::IsProviderForClient() const { |
- switch (provider_type_) { |
+ switch (info_.type) { |
case SERVICE_WORKER_PROVIDER_FOR_WINDOW: |
case SERVICE_WORKER_PROVIDER_FOR_WORKER: |
case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: |
@@ -312,15 +339,15 @@ bool ServiceWorkerProviderHost::IsProviderForClient() const { |
case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
return false; |
case SERVICE_WORKER_PROVIDER_UNKNOWN: |
- NOTREACHED() << provider_type_; |
+ NOTREACHED() << info_.type; |
} |
- NOTREACHED() << provider_type_; |
+ NOTREACHED() << info_.type; |
return false; |
} |
blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type() |
const { |
- switch (provider_type_) { |
+ switch (info_.type) { |
case SERVICE_WORKER_PROVIDER_FOR_WINDOW: |
return blink::kWebServiceWorkerClientTypeWindow; |
case SERVICE_WORKER_PROVIDER_FOR_WORKER: |
@@ -329,9 +356,9 @@ blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type() |
return blink::kWebServiceWorkerClientTypeSharedWorker; |
case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
case SERVICE_WORKER_PROVIDER_UNKNOWN: |
- NOTREACHED() << provider_type_; |
+ NOTREACHED() << info_.type; |
} |
- NOTREACHED() << provider_type_; |
+ NOTREACHED() << info_.type; |
return blink::kWebServiceWorkerClientTypeWindow; |
} |
@@ -537,14 +564,16 @@ bool ServiceWorkerProviderHost::GetRegistrationForReady( |
std::unique_ptr<ServiceWorkerProviderHost> |
ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
- DCHECK_NE(MSG_ROUTING_NONE, route_id_); |
+ DCHECK_NE(MSG_ROUTING_NONE, info_.route_id); |
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
- DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_); |
+ DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); |
- std::unique_ptr<ServiceWorkerProviderHost> new_provider_host = |
+ std::unique_ptr<ServiceWorkerProviderHost> replacement = |
base::WrapUnique(new ServiceWorkerProviderHost( |
- process_id(), frame_id(), provider_id(), provider_type(), |
- is_parent_frame_secure(), context_, dispatcher_host())); |
+ process_id(), |
+ ServiceWorkerProviderHostInfo(std::move(info_), binding_.Unbind(), |
+ client_.PassInterface()), |
+ context_, dispatcher_host())); |
for (const GURL& pattern : associated_patterns_) |
DecreaseProcessReference(pattern); |
@@ -560,45 +589,58 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
} |
render_process_id_ = ChildProcessHost::kInvalidUniqueID; |
- route_id_ = MSG_ROUTING_NONE; |
render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
- provider_id_ = kInvalidServiceWorkerProviderId; |
- provider_type_ = SERVICE_WORKER_PROVIDER_UNKNOWN; |
dispatcher_host_ = nullptr; |
- return new_provider_host; |
+ return replacement; |
} |
void ServiceWorkerProviderHost::CompleteCrossSiteTransfer( |
- int new_process_id, |
- int new_frame_id, |
- int new_provider_id, |
- ServiceWorkerProviderType new_provider_type, |
- ServiceWorkerDispatcherHost* new_dispatcher_host) { |
+ ServiceWorkerProviderHost* provisional_host) { |
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
- DCHECK_NE(ChildProcessHost::kInvalidUniqueID, new_process_id); |
- DCHECK_NE(MSG_ROUTING_NONE, new_frame_id); |
+ DCHECK_NE(ChildProcessHost::kInvalidUniqueID, provisional_host->process_id()); |
+ DCHECK_NE(MSG_ROUTING_NONE, provisional_host->frame_id()); |
render_thread_id_ = kDocumentMainThreadId; |
- provider_id_ = new_provider_id; |
- provider_type_ = new_provider_type; |
+ info_.provider_id = provisional_host->provider_id(); |
+ info_.type = provisional_host->provider_type(); |
+ |
+ // Take the connection over from the provisional host. |
+ DCHECK(!client_.is_bound()); |
+ DCHECK(!binding_.is_bound()); |
+ client_.Bind(provisional_host->client_.PassInterface()); |
+ binding_.Bind(provisional_host->binding_.Unbind()); |
+ binding_.set_connection_error_handler( |
+ base::Bind(&RemoveProviderHost, context_, provisional_host->process_id(), |
+ provisional_host->provider_id())); |
- FinalizeInitialization(new_process_id, new_frame_id, new_dispatcher_host); |
+ FinalizeInitialization(provisional_host->process_id(), |
+ provisional_host->frame_id(), |
+ provisional_host->dispatcher_host()); |
} |
// PlzNavigate |
void ServiceWorkerProviderHost::CompleteNavigationInitialized( |
int process_id, |
- int frame_routing_id, |
+ ServiceWorkerProviderHostInfo info, |
ServiceWorkerDispatcherHost* dispatcher_host) { |
CHECK(IsBrowserSideNavigationEnabled()); |
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
- DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type_); |
+ DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, info_.type); |
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id); |
- DCHECK_NE(MSG_ROUTING_NONE, frame_routing_id); |
+ DCHECK_EQ(info_.provider_id, info.provider_id); |
+ DCHECK_NE(MSG_ROUTING_NONE, info.route_id); |
+ |
+ // Connect with the provider on the renderer. |
+ DCHECK(!client_.is_bound()); |
+ DCHECK(!binding_.is_bound()); |
+ client_.Bind(std::move(info.client_ptr_info)); |
+ binding_.Bind(std::move(info.host_request)); |
+ binding_.set_connection_error_handler( |
+ base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); |
- FinalizeInitialization(process_id, frame_routing_id, dispatcher_host); |
+ FinalizeInitialization(process_id, info.route_id, dispatcher_host); |
} |
void ServiceWorkerProviderHost::SendUpdateFoundMessage( |
@@ -770,7 +812,7 @@ void ServiceWorkerProviderHost::FinalizeInitialization( |
int frame_routing_id, |
ServiceWorkerDispatcherHost* dispatcher_host) { |
render_process_id_ = process_id; |
- route_id_ = frame_routing_id; |
+ info_.route_id = frame_routing_id; |
dispatcher_host_ = dispatcher_host; |
for (const GURL& pattern : associated_patterns_) |