summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorclamy <clamy@chromium.org>2015-10-27 09:20:49 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-27 16:22:04 +0000
commit2a7a25b565fd4b702bb12ce40f16284d965a11ad (patch)
tree6a35f7fe47cd36f1616e0cae3254d699624bc04d /content
parent349ad1fff5eed0f938acb47396ca64dd93277ebe (diff)
downloadchromium_src-2a7a25b565fd4b702bb12ce40f16284d965a11ad.zip
chromium_src-2a7a25b565fd4b702bb12ce40f16284d965a11ad.tar.gz
chromium_src-2a7a25b565fd4b702bb12ce40f16284d965a11ad.tar.bz2
PlzNavigate: Make ServiceWorker work with PlzNavigate.
This CL makes the ServiceWorker architecture work with PlzNavigate enabled. This is done by allowing the browser to pre-create a ServiceWorkerProviderHost during navigations if needed. If the navigation is successful, the renderer chosen to commit the navigation will create a matching ServiceWorkerNetworkProvider. If no ServiceWorkerProviderHost was pre-created, the renderer creates a ServiceWorkerNetworkProvider in the traditional way. This is a continuation of https://codereview.chromium.org/1294243004/ by fdegans@ following his departure from the team. BUG=440463 Review URL: https://codereview.chromium.org/1399363004 Cr-Commit-Position: refs/heads/master@{#356310}
Diffstat (limited to 'content')
-rw-r--r--content/browser/frame_host/navigation_handle_impl.cc30
-rw-r--r--content/browser/frame_host/navigation_handle_impl.h11
-rw-r--r--content/browser/frame_host/navigation_request.cc15
-rw-r--r--content/browser/frame_host/navigation_request.h4
-rw-r--r--content/browser/frame_host/navigation_request_info.cc1
-rw-r--r--content/browser/frame_host/navigation_request_info.h1
-rw-r--r--content/browser/loader/navigation_url_loader.cc5
-rw-r--r--content/browser/loader/navigation_url_loader.h2
-rw-r--r--content/browser/loader/navigation_url_loader_factory.h1
-rw-r--r--content/browser/loader/navigation_url_loader_impl.cc9
-rw-r--r--content/browser/loader/navigation_url_loader_impl.h2
-rw-r--r--content/browser/loader/navigation_url_loader_impl_core.cc5
-rw-r--r--content/browser/loader/navigation_url_loader_impl_core.h2
-rw-r--r--content/browser/loader/navigation_url_loader_unittest.cc2
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc22
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.h9
-rw-r--r--content/browser/service_worker/service_worker_context_core.cc27
-rw-r--r--content/browser/service_worker/service_worker_context_core.h16
-rw-r--r--content/browser/service_worker/service_worker_context_wrapper.h1
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc37
-rw-r--r--content/browser/service_worker/service_worker_navigation_handle.cc35
-rw-r--r--content/browser/service_worker/service_worker_navigation_handle.h78
-rw-r--r--content/browser/service_worker/service_worker_navigation_handle_core.cc63
-rw-r--r--content/browser/service_worker/service_worker_navigation_handle_core.h57
-rw-r--r--content/browser/service_worker/service_worker_provider_host.cc86
-rw-r--r--content/browser/service_worker/service_worker_provider_host.h19
-rw-r--r--content/browser/service_worker/service_worker_request_handler.cc130
-rw-r--r--content/browser/service_worker/service_worker_request_handler.h14
-rw-r--r--content/child/service_worker/service_worker_network_provider.cc74
-rw-r--r--content/child/service_worker/service_worker_network_provider.h14
-rw-r--r--content/common/frame_messages.h1
-rw-r--r--content/common/navigation_params.cc2
-rw-r--r--content/common/navigation_params.h12
-rw-r--r--content/common/service_worker/service_worker_utils.h7
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/renderer/render_frame_impl.cc28
-rw-r--r--content/test/test_navigation_url_loader_factory.cc1
-rw-r--r--content/test/test_navigation_url_loader_factory.h1
38 files changed, 736 insertions, 92 deletions
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 1c53047..2e30d1e 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -4,12 +4,19 @@
#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "base/command_line.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "net/url_request/redirect_info.h"
+#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
@@ -45,6 +52,29 @@ NavigationHandleImpl::NavigationHandleImpl(const GURL& url,
is_transferring_(false),
frame_tree_node_(frame_tree_node),
next_index_(0) {
+ // PlzNavigate
+ // Initialize the ServiceWorkerNavigationHandle if it can be created for this
+ // frame.
+ bool can_create_service_worker =
+ (frame_tree_node_->current_replication_state().sandbox_flags &
+ blink::WebSandboxFlags::Origin) != blink::WebSandboxFlags::Origin;
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation) &&
+ can_create_service_worker) {
+ BrowserContext* browser_context =
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext();
+ // TODO(clamy): Picking the partition based on the URL is incorrect.
+ // See crbug.com/513539
+ StoragePartition* partition =
+ BrowserContext::GetStoragePartitionForSite(browser_context, url_);
+ DCHECK(partition);
+ ServiceWorkerContextWrapper* service_worker_context =
+ static_cast<ServiceWorkerContextWrapper*>(
+ partition->GetServiceWorkerContext());
+ service_worker_handle_.reset(
+ new ServiceWorkerNavigationHandle(service_worker_context));
+ }
+
GetDelegate()->DidStartNavigation(this);
}
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 59a5f65..6f46707 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -19,6 +19,7 @@
namespace content {
class NavigatorDelegate;
+class ServiceWorkerNavigationHandle;
struct NavigationRequestInfo;
// This class keeps track of a single navigation. It is created upon receipt of
@@ -104,6 +105,11 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
is_transferring_ = is_transferring;
}
+ // PlzNavigate
+ ServiceWorkerNavigationHandle* service_worker_handle() const {
+ return service_worker_handle_.get();
+ }
+
typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
ThrottleChecksFinishedCallback;
@@ -194,6 +200,11 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// This callback will be run when all throttle checks have been performed.
ThrottleChecksFinishedCallback complete_callback_;
+ // PlzNavigate
+ // Manages the lifetime of a pre-created ServiceWorkerProviderHost until a
+ // corresponding ServiceWorkerNetworkProvider is created in the renderer.
+ scoped_ptr<ServiceWorkerNavigationHandle> service_worker_handle_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationHandleImpl);
};
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 171b1b5..a6ba970 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -11,6 +11,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/navigation_url_loader.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/resource_request_body.h"
#include "content/public/browser/navigation_controller.h"
@@ -19,6 +20,7 @@
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/redirect_info.h"
+#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
@@ -252,6 +254,17 @@ void NavigationRequest::OnResponseStarted(
scoped_ptr<StreamHandle> body) {
DCHECK(state_ == STARTED);
state_ = RESPONSE_STARTED;
+
+ // Update the service worker params of the request params.
+ request_params_.should_create_service_worker =
+ (frame_tree_node_->current_replication_state().sandbox_flags &
+ blink::WebSandboxFlags::Origin) != blink::WebSandboxFlags::Origin;
+ if (navigation_handle_->service_worker_handle()) {
+ request_params_.service_worker_provider_id =
+ navigation_handle_->service_worker_handle()
+ ->service_worker_provider_host_id();
+ }
+
frame_tree_node_->navigator()->CommitNavigation(frame_tree_node_,
response.get(), body.Pass());
}
@@ -282,7 +295,7 @@ void NavigationRequest::OnStartChecksComplete(
loader_ = NavigationURLLoader::Create(
frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
- info_.Pass(), this);
+ info_.Pass(), navigation_handle_->service_worker_handle(), this);
}
void NavigationRequest::OnRedirectChecksComplete(
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 57218e7..294d086 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -171,9 +171,11 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// redirects.
// Note: |common_params_| and |begin_params_| are not const as they can be
// modified during redirects.
+ // Note: |request_params_| is not const because service_worker_provider_id
+ // and should_create_service_worker will be set in OnResponseStarted.
CommonNavigationParams common_params_;
BeginNavigationParams begin_params_;
- const RequestNavigationParams request_params_;
+ RequestNavigationParams request_params_;
const bool browser_initiated_;
NavigationState state_;
diff --git a/content/browser/frame_host/navigation_request_info.cc b/content/browser/frame_host/navigation_request_info.cc
index 42fa7d27..de061de 100644
--- a/content/browser/frame_host/navigation_request_info.cc
+++ b/content/browser/frame_host/navigation_request_info.cc
@@ -21,7 +21,6 @@ NavigationRequestInfo::NavigationRequestInfo(
is_main_frame(is_main_frame),
parent_is_main_frame(parent_is_main_frame),
frame_tree_node_id(frame_tree_node_id),
- service_worker_provider_id(kInvalidServiceWorkerProviderId),
request_body(request_body) {}
NavigationRequestInfo::~NavigationRequestInfo() {}
diff --git a/content/browser/frame_host/navigation_request_info.h b/content/browser/frame_host/navigation_request_info.h
index fc10074..f63db77 100644
--- a/content/browser/frame_host/navigation_request_info.h
+++ b/content/browser/frame_host/navigation_request_info.h
@@ -42,7 +42,6 @@ struct CONTENT_EXPORT NavigationRequestInfo {
const bool parent_is_main_frame;
const int frame_tree_node_id;
- int service_worker_provider_id;
scoped_refptr<ResourceRequestBody> request_body;
};
diff --git a/content/browser/loader/navigation_url_loader.cc b/content/browser/loader/navigation_url_loader.cc
index c1513dc..0da9a25 100644
--- a/content/browser/loader/navigation_url_loader.cc
+++ b/content/browser/loader/navigation_url_loader.cc
@@ -15,13 +15,14 @@ static NavigationURLLoaderFactory* g_factory = nullptr;
scoped_ptr<NavigationURLLoader> NavigationURLLoader::Create(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) {
if (g_factory) {
return g_factory->CreateLoader(browser_context, request_info.Pass(),
- delegate);
+ service_worker_handle, delegate);
}
return scoped_ptr<NavigationURLLoader>(new NavigationURLLoaderImpl(
- browser_context, request_info.Pass(), delegate));
+ browser_context, request_info.Pass(), service_worker_handle, delegate));
}
void NavigationURLLoader::SetFactoryForTesting(
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h
index 89553f6..d3d5866 100644
--- a/content/browser/loader/navigation_url_loader.h
+++ b/content/browser/loader/navigation_url_loader.h
@@ -15,6 +15,7 @@ namespace content {
class BrowserContext;
class NavigationURLLoaderDelegate;
class NavigationURLLoaderFactory;
+class ServiceWorkerNavigationHandle;
struct CommonNavigationParams;
struct NavigationRequestInfo;
@@ -35,6 +36,7 @@ class CONTENT_EXPORT NavigationURLLoader {
static scoped_ptr<NavigationURLLoader> Create(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate);
// For testing purposes; sets the factory for use in testing.
diff --git a/content/browser/loader/navigation_url_loader_factory.h b/content/browser/loader/navigation_url_loader_factory.h
index 770644e..a2fd371 100644
--- a/content/browser/loader/navigation_url_loader_factory.h
+++ b/content/browser/loader/navigation_url_loader_factory.h
@@ -18,6 +18,7 @@ class NavigationURLLoaderFactory {
virtual scoped_ptr<NavigationURLLoader> CreateLoader(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) = 0;
protected:
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 7cbd911..2cae9a6 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -9,6 +9,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/browser/loader/navigation_url_loader_impl_core.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/stream_handle.h"
@@ -18,17 +19,19 @@ namespace content {
NavigationURLLoaderImpl::NavigationURLLoaderImpl(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate)
- : delegate_(delegate),
- weak_factory_(this) {
+ : delegate_(delegate), weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
core_ = new NavigationURLLoaderImplCore(weak_factory_.GetWeakPtr());
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core =
+ service_worker_handle ? service_worker_handle->core() : nullptr;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&NavigationURLLoaderImplCore::Start, base::Unretained(core_),
browser_context->GetResourceContext(),
- base::Passed(&request_info)));
+ service_worker_handle_core, base::Passed(&request_info)));
}
NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 6a88fc8..5c7fcd0 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -19,6 +19,7 @@ struct RedirectInfo;
namespace content {
class NavigationURLLoaderImplCore;
+class ServiceWorkerNavigationHandle;
class StreamHandle;
struct ResourceResponse;
@@ -27,6 +28,7 @@ class NavigationURLLoaderImpl : public NavigationURLLoader {
// The caller is responsible for ensuring that |delegate| outlives the loader.
NavigationURLLoaderImpl(BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate);
~NavigationURLLoaderImpl() override;
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc
index 7fe6951..f7c1dde 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.cc
+++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -10,6 +10,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/stream_handle.h"
@@ -37,6 +38,7 @@ NavigationURLLoaderImplCore::~NavigationURLLoaderImplCore() {
void NavigationURLLoaderImplCore::Start(
ResourceContext* resource_context,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core,
scoped_ptr<NavigationRequestInfo> request_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -46,7 +48,7 @@ void NavigationURLLoaderImplCore::Start(
base::TimeTicks::Now()));
ResourceDispatcherHostImpl::Get()->BeginNavigationRequest(
- resource_context, *request_info, this);
+ resource_context, *request_info, this, service_worker_handle_core);
}
void NavigationURLLoaderImplCore::FollowRedirect() {
@@ -56,7 +58,6 @@ void NavigationURLLoaderImplCore::FollowRedirect() {
resource_handler_->FollowRedirect();
}
-
void NavigationURLLoaderImplCore::NotifyRequestRedirected(
const net::RedirectInfo& redirect_info,
ResourceResponse* response) {
diff --git a/content/browser/loader/navigation_url_loader_impl_core.h b/content/browser/loader/navigation_url_loader_impl_core.h
index 8a93469..9016ba6 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.h
+++ b/content/browser/loader/navigation_url_loader_impl_core.h
@@ -23,6 +23,7 @@ class NavigationResourceHandler;
class ResourceContext;
class ResourceHandler;
class ResourceRequestBody;
+class ServiceWorkerNavigationHandleCore;
class StreamHandle;
struct ResourceResponse;
@@ -40,6 +41,7 @@ class NavigationURLLoaderImplCore {
// Starts the request.
void Start(ResourceContext* resource_context,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core,
scoped_ptr<NavigationRequestInfo> request_info);
// Follows the current pending redirect.
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc
index 5c4c7fd..418046e 100644
--- a/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -188,7 +188,7 @@ class NavigationURLLoaderTest : public testing::Test {
-1, scoped_refptr<ResourceRequestBody>()));
return NavigationURLLoader::Create(browser_context_.get(),
- request_info.Pass(), delegate);
+ request_info.Pass(), nullptr, delegate);
}
// Helper function for fetching the body of a URL to a string.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index efae657..f342602 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1969,7 +1969,8 @@ void ResourceDispatcherHostImpl::FinishedWithResourcesForRequest(
void ResourceDispatcherHostImpl::BeginNavigationRequest(
ResourceContext* resource_context,
const NavigationRequestInfo& info,
- NavigationURLLoaderImplCore* loader) {
+ NavigationURLLoaderImplCore* loader,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core) {
// PlzNavigate: BeginNavigationRequest currently should only be used for the
// browser-side navigations project.
CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -2034,10 +2035,11 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
new_request->SetLoadFlags(load_flags);
+ storage::BlobStorageContext* blob_context = GetBlobStorageContext(
+ GetChromeBlobStorageContextForResourceContext(resource_context));
+
// Resolve elements from request_body and prepare upload data.
if (info.request_body.get()) {
- storage::BlobStorageContext* blob_context = GetBlobStorageContext(
- GetChromeBlobStorageContextForResourceContext(resource_context));
AttachRequestBodyBlobDataHandles(
info.request_body.get(),
blob_context);
@@ -2094,15 +2096,19 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
if (new_request->url().SchemeIs(url::kBlobScheme)) {
// Hang on to a reference to ensure the blob is not released prior
// to the job being started.
- ChromeBlobStorageContext* blob_context =
- GetChromeBlobStorageContextForResourceContext(resource_context);
storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
new_request.get(),
- blob_context->context()->GetBlobDataFromPublicURL(new_request->url()));
+ blob_context->GetBlobDataFromPublicURL(new_request->url()));
}
- // TODO(davidben): Attach ServiceWorkerRequestHandler.
- // TODO(michaeln): Help out with this and that.
+ RequestContextFrameType frame_type =
+ info.is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
+ : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
+ ServiceWorkerRequestHandler::InitializeForNavigation(
+ new_request.get(), service_worker_handle_core, blob_context,
+ info.begin_params.skip_service_worker, resource_type,
+ info.begin_params.request_context_type, frame_type, info.request_body);
+
// TODO(davidben): Attach AppCacheInterceptor.
scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler(
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index 7772917..d575c10 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -67,6 +67,7 @@ class ResourceMessageDelegate;
class ResourceMessageFilter;
class ResourceRequestInfoImpl;
class SaveFileManager;
+class ServiceWorkerNavigationHandleCore;
class WebContentsImpl;
struct CommonNavigationParams;
struct DownloadSaveInfo;
@@ -273,9 +274,11 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// PlzNavigate: Begins a request for NavigationURLLoader. |loader| is the
// loader to attach to the leaf resource handler.
- void BeginNavigationRequest(ResourceContext* resource_context,
- const NavigationRequestInfo& info,
- NavigationURLLoaderImplCore* loader);
+ void BeginNavigationRequest(
+ ResourceContext* resource_context,
+ const NavigationRequestInfo& info,
+ NavigationURLLoaderImplCore* loader,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core);
private:
friend class ResourceDispatcherHostTest;
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 45f0a2d..ec97d01 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -517,6 +517,33 @@ ServiceWorkerVersion* ServiceWorkerContextCore::GetLiveVersion(
return (it != live_versions_.end()) ? it->second : NULL;
}
+// PlzNavigate
+void ServiceWorkerContextCore::AddNavigationHandleCore(
+ int service_worker_provider_id,
+ ServiceWorkerNavigationHandleCore* handle) {
+ auto result = navigation_handle_cores_map_.insert(
+ std::pair<int, ServiceWorkerNavigationHandleCore*>(
+ service_worker_provider_id, handle));
+ DCHECK(result.second)
+ << "Inserting a duplicate ServiceWorkerNavigationHandleCore";
+}
+
+// PlzNavigate
+void ServiceWorkerContextCore::RemoveNavigationHandleCore(
+ int service_worker_provider_id) {
+ navigation_handle_cores_map_.erase(service_worker_provider_id);
+}
+
+// PlzNavigate
+ServiceWorkerNavigationHandleCore*
+ServiceWorkerContextCore::GetNavigationHandleCore(
+ int service_worker_provider_id) {
+ auto result = navigation_handle_cores_map_.find(service_worker_provider_id);
+ if (result == navigation_handle_cores_map_.end())
+ return nullptr;
+ return result->second;
+}
+
void ServiceWorkerContextCore::AddLiveVersion(ServiceWorkerVersion* version) {
// TODO(horo): If we will see crashes here, we have to find the root cause of
// the version ID conflict. Otherwise change CHECK to DCHECK.
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index 99b986c..53a354d 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -42,6 +42,7 @@ class ServiceWorkerContextWrapper;
class ServiceWorkerDatabaseTaskManager;
class ServiceWorkerHandle;
class ServiceWorkerJobCoordinator;
+class ServiceWorkerNavigationHandleCore;
class ServiceWorkerProviderHost;
class ServiceWorkerRegistration;
class ServiceWorkerStorage;
@@ -223,6 +224,15 @@ class CONTENT_EXPORT ServiceWorkerContextCore
return live_versions_;
}
+ // PlzNavigate
+ // Methods to manage the map keeping track of all
+ // ServiceWorkerNavigationHandleCores registered for ongoing navigations.
+ void AddNavigationHandleCore(int service_worker_provider_id,
+ ServiceWorkerNavigationHandleCore* handle);
+ void RemoveNavigationHandleCore(int service_worker_provider_id);
+ ServiceWorkerNavigationHandleCore* GetNavigationHandleCore(
+ int service_worker_provider_id);
+
std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
@@ -298,6 +308,12 @@ class CONTENT_EXPORT ServiceWorkerContextCore
std::map<int64, ServiceWorkerRegistration*> live_registrations_;
std::map<int64, ServiceWorkerVersion*> live_versions_;
std::map<int64, scoped_refptr<ServiceWorkerVersion>> protected_versions_;
+
+ // PlzNavigate
+ // Map of ServiceWorkerNavigationHandleCores used for navigation requests.
+ std::map<int, ServiceWorkerNavigationHandleCore*>
+ navigation_handle_cores_map_;
+
int next_handle_id_;
int next_registration_handle_id_;
// Set in RegisterServiceWorker(), cleared in ClearAllServiceWorkersForTest().
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index 81463a0..0e1a83c 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -168,6 +168,7 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
friend class EmbeddedWorkerBrowserTest;
friend class ServiceWorkerDispatcherHost;
friend class ServiceWorkerInternalsUI;
+ friend class ServiceWorkerNavigationHandleCore;
friend class ServiceWorkerProcessManager;
friend class ServiceWorkerRequestHandler;
friend class ServiceWorkerVersionBrowserTest;
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index a042183..62e5a78 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -4,6 +4,7 @@
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
+#include "base/command_line.h"
#include "base/logging.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/utf_string_conversions.h"
@@ -15,6 +16,7 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_handle.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/common/service_worker/embedded_worker_messages.h"
@@ -23,6 +25,7 @@
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/net_util.h"
@@ -733,10 +736,36 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(
bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
return;
}
- scoped_ptr<ServiceWorkerProviderHost> provider_host(
- new ServiceWorkerProviderHost(render_process_id_, route_id, provider_id,
- provider_type, GetContext()->AsWeakPtr(),
- this));
+
+ scoped_ptr<ServiceWorkerProviderHost> provider_host;
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation) &&
+ ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) {
+ // PlzNavigate
+ // Retrieve the provider host previously created for navigation requests.
+ ServiceWorkerNavigationHandleCore* navigation_handle_core =
+ GetContext()->GetNavigationHandleCore(provider_id);
+ if (navigation_handle_core != nullptr)
+ provider_host = navigation_handle_core->RetrievePreCreatedHost();
+ if (provider_host == nullptr) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
+ return;
+ }
+ DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type);
+ provider_host->CompleteNavigationInitialized(render_process_id_, route_id,
+ this);
+ } else {
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
+ return;
+ }
+ provider_host =
+ scoped_ptr<ServiceWorkerProviderHost>(new ServiceWorkerProviderHost(
+ render_process_id_, route_id, provider_id, provider_type,
+ GetContext()->AsWeakPtr(), this));
+ }
GetContext()->AddProviderHost(provider_host.Pass());
}
diff --git a/content/browser/service_worker/service_worker_navigation_handle.cc b/content/browser/service_worker/service_worker_navigation_handle.cc
new file mode 100644
index 0000000..2bc87a22
--- /dev/null
+++ b/content/browser/service_worker/service_worker_navigation_handle.cc
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
+
+#include "base/bind.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+ServiceWorkerNavigationHandle::ServiceWorkerNavigationHandle(
+ ServiceWorkerContextWrapper* context_wrapper)
+ : service_worker_provider_host_id_(kInvalidServiceWorkerProviderId),
+ weak_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ core_ = new ServiceWorkerNavigationHandleCore(weak_factory_.GetWeakPtr(),
+ context_wrapper);
+}
+
+ServiceWorkerNavigationHandle::~ServiceWorkerNavigationHandle() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Delete the ServiceWorkerNavigationHandleCore on the IO thread.
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, core_);
+}
+
+void ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost(
+ int service_worker_provider_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ service_worker_provider_host_id_ = service_worker_provider_host_id;
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_handle.h b/content/browser/service_worker/service_worker_navigation_handle.h
new file mode 100644
index 0000000..c5c6938
--- /dev/null
+++ b/content/browser/service_worker/service_worker_navigation_handle.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+
+namespace content {
+
+class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandleCore;
+
+// This class is used to manage the lifetime of ServiceWorkerProviderHosts
+// created during navigation. This is a UI thread class, with a pendant class
+// on the IO thread, the ServiceWorkerNavigationHandleCore.
+//
+// The lifetime of the ServiceWorkerNavigationHandle, the
+// ServiceWorkerNavigationHandleCore and the ServiceWorkerProviderHost are the
+// following :
+// 1) We create a ServiceWorkerNavigationHandle on the UI thread with a
+// service worker provider id of -1. This also leads to the creation of a
+// ServiceWorkerNavigationHandleCore with an id of -1.
+//
+// 2) When the navigation request is sent to the IO thread, we include a
+// pointer to the ServiceWorkerNavigationHandleCore.
+//
+// 3) If we pre-create a ServiceWorkerProviderHost for this navigation, its
+// ownershipped is passed to the ServiceWorkerNavigationHandleCore. The
+// ServiceWorkerNavigationHandleCore id is updated.
+//
+// 4) The ServiceWorkerNavigationHandleCore informs the
+// ServiceWorkerNavigationHandle on the UI that the service worker provider
+// id was updated.
+//
+// 5) When the navigation is ready to commit, the NavigationRequest will
+// update the RequestNavigationParams based on the id from the
+// ServiceWorkerNavigationHandle.
+//
+// 6) If the commit leads to the creation of a ServiceWorkerNetworkProvider
+// in the renderer, a ServiceWorkerHostMsg_ProviderCreated will be received
+// in the browser. The ServiceWorkerDispatcherHost will retrieve the
+// ServiceWorkerProviderHost from the ServiceWorkerNavigationHandleCore and
+// put it in the ServiceWorkerContextCore map of ServiceWorkerProviderHosts.
+//
+// 7) When the navigation finishes, the ServiceWorkerNavigationHandle is
+// destroyed. The destructor of the ServiceWorkerNavigationHandle posts a
+// task to destroy the ServiceWorkerNavigationHandleCore on the IO thread.
+// This in turn leads to the destruction of an unclaimed
+// ServiceWorkerProviderHost.
+class ServiceWorkerNavigationHandle {
+ public:
+ explicit ServiceWorkerNavigationHandle(
+ ServiceWorkerContextWrapper* context_wrapper);
+ ~ServiceWorkerNavigationHandle();
+
+ int service_worker_provider_host_id() const {
+ return service_worker_provider_host_id_;
+ }
+ ServiceWorkerNavigationHandleCore* core() const { return core_; }
+
+ // Called after a ServiceWorkerProviderHost with id
+ // |service_worker_provider_host_id| was pre-created for the navigation on the
+ // IO thread.
+ void DidCreateServiceWorkerProviderHost(int service_worker_provider_host_id);
+
+ private:
+ int service_worker_provider_host_id_;
+ ServiceWorkerNavigationHandleCore* core_;
+ base::WeakPtrFactory<ServiceWorkerNavigationHandle> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationHandle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
diff --git a/content/browser/service_worker/service_worker_navigation_handle_core.cc b/content/browser/service_worker/service_worker_navigation_handle_core.cc
new file mode 100644
index 0000000..f1dc1ee
--- /dev/null
+++ b/content/browser/service_worker/service_worker_navigation_handle_core.cc
@@ -0,0 +1,63 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
+
+#include "base/bind.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+ServiceWorkerNavigationHandleCore::ServiceWorkerNavigationHandleCore(
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle,
+ ServiceWorkerContextWrapper* context_wrapper)
+ : context_wrapper_(context_wrapper), ui_handle_(ui_handle) {
+ // The ServiceWorkerNavigationHandleCore is created on the UI thread but
+ // should only be accessed from the IO thread afterwards.
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+ServiceWorkerNavigationHandleCore::~ServiceWorkerNavigationHandleCore() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (precreated_host_.get() && context_wrapper_->context()) {
+ context_wrapper_->context()->RemoveNavigationHandleCore(
+ precreated_host_->provider_id());
+ }
+}
+
+void ServiceWorkerNavigationHandleCore::DidPreCreateProviderHost(
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(precreated_host.get());
+ DCHECK(context_wrapper_->context());
+
+ precreated_host_ = precreated_host.Pass();
+ context_wrapper_->context()->AddNavigationHandleCore(
+ precreated_host_->provider_id(), this);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost,
+ ui_handle_, precreated_host_->provider_id()));
+}
+
+scoped_ptr<ServiceWorkerProviderHost>
+ServiceWorkerNavigationHandleCore::RetrievePreCreatedHost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(precreated_host_);
+ // Remove the ServiceWorkerNavigationHandleCore from the list of
+ // ServiceWorkerNavigationHandleCores since it will no longer hold a
+ // ServiceWorkerProviderHost.
+ DCHECK(context_wrapper_->context());
+ context_wrapper_->context()->RemoveNavigationHandleCore(
+ precreated_host_->provider_id());
+ return precreated_host_.Pass();
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_handle_core.h b/content/browser/service_worker/service_worker_navigation_handle_core.h
new file mode 100644
index 0000000..c1ed9eb
--- /dev/null
+++ b/content/browser/service_worker/service_worker_navigation_handle_core.h
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace content {
+
+class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandle;
+class ServiceWorkerProviderHost;
+
+// PlzNavigate
+// This class is used to manage the lifetime of ServiceWorkerProviderHosts
+// created during navigations. This class is created on the UI thread, but
+// should only be accessed from the IO thread afterwards. It is the IO thread
+// pendant of ServiceWorkerNavigationHandle. See the
+// ServiceWorkerNavigationHandle header for more details about the lifetime of
+// both classes.
+class ServiceWorkerNavigationHandleCore {
+ public:
+ ServiceWorkerNavigationHandleCore(
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle,
+ ServiceWorkerContextWrapper* context_wrapper);
+ ~ServiceWorkerNavigationHandleCore();
+
+ // Called when a ServiceWorkerProviderHost was pre-created for the navigation
+ // tracked by this ServiceWorkerNavigationHandleCore. Takes ownership of
+ // |precreated_host|.
+ void DidPreCreateProviderHost(
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host);
+
+ // Called when the renderer created a ServiceWorkerNetworkProvider matching
+ // |precreated_host_|. This releases ownership of |precreated_host_|.
+ scoped_ptr<ServiceWorkerProviderHost> RetrievePreCreatedHost();
+
+ ServiceWorkerContextWrapper* context_wrapper() const {
+ return context_wrapper_.get();
+ }
+
+ private:
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host_;
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationHandleCore);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index a27a2c1..d145d4b 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -4,6 +4,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "base/command_line.h"
#include "base/guid.h"
#include "base/stl_util.h"
#include "base/time/time.h"
@@ -27,6 +28,7 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"
+#include "content/public/common/content_switches.h"
namespace content {
@@ -57,6 +59,11 @@ ServiceWorkerClientInfo FocusOnUIThread(int render_process_id,
render_frame_id);
}
+// PlzNavigate
+// Next ServiceWorkerProviderHost ID for navigations, starts at -2 and keeps
+// going down.
+int g_next_navigation_provider_id = -2;
+
} // anonymous namespace
ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
@@ -68,6 +75,19 @@ ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
}
+// static
+scoped_ptr<ServiceWorkerProviderHost>
+ServiceWorkerProviderHost::PreCreateNavigationHost(
+ base::WeakPtr<ServiceWorkerContextCore> context) {
+ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
+ // Generate a new browser-assigned id for the host.
+ int provider_id = g_next_navigation_provider_id--;
+ return scoped_ptr<ServiceWorkerProviderHost>(new ServiceWorkerProviderHost(
+ ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE, provider_id,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, context, nullptr));
+}
+
ServiceWorkerProviderHost::ServiceWorkerProviderHost(
int render_process_id,
int route_id,
@@ -84,9 +104,14 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
context_(context),
dispatcher_host_(dispatcher_host),
allow_association_(true) {
- DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_);
DCHECK_NE(SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME, provider_type_);
+
+ // PlzNavigate
+ CHECK_IMPLIES(render_process_id == ChildProcessHost::kInvalidUniqueID,
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
+
if (provider_type_ == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
// Actual thread id is set when the service worker context gets started.
render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
@@ -516,29 +541,28 @@ void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, new_process_id);
DCHECK_NE(MSG_ROUTING_NONE, new_frame_id);
- render_process_id_ = new_process_id;
- route_id_ = new_frame_id;
render_thread_id_ = kDocumentMainThreadId;
provider_id_ = new_provider_id;
provider_type_ = new_provider_type;
- dispatcher_host_ = new_dispatcher_host;
- for (const GURL& pattern : associated_patterns_)
- IncreaseProcessReference(pattern);
+ FinalizeInitialization(new_process_id, new_frame_id, new_dispatcher_host);
+}
- for (auto& key_registration : matching_registrations_)
- IncreaseProcessReference(key_registration.second->pattern());
+// PlzNavigate
+void ServiceWorkerProviderHost::CompleteNavigationInitialized(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host) {
+ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
+ DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
+ DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type_);
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
- if (associated_registration_.get()) {
- SendAssociateRegistrationMessage();
- if (dispatcher_host_ && associated_registration_->active_version()) {
- Send(new ServiceWorkerMsg_SetControllerServiceWorker(
- render_thread_id_, provider_id(),
- GetOrCreateServiceWorkerHandle(
- associated_registration_->active_version()),
- false /* shouldNotifyControllerChange */));
- }
- }
+ DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
+ DCHECK_NE(MSG_ROUTING_NONE, frame_routing_id);
+
+ FinalizeInitialization(process_id, frame_routing_id, dispatcher_host);
}
void ServiceWorkerProviderHost::SendUpdateFoundMessage(
@@ -684,4 +708,30 @@ void ServiceWorkerProviderHost::Send(IPC::Message* message) const {
dispatcher_host_->Send(message);
}
+void ServiceWorkerProviderHost::FinalizeInitialization(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host) {
+ render_process_id_ = process_id;
+ route_id_ = frame_routing_id;
+ dispatcher_host_ = dispatcher_host;
+
+ for (const GURL& pattern : associated_patterns_)
+ IncreaseProcessReference(pattern);
+
+ for (auto& key_registration : matching_registrations_)
+ IncreaseProcessReference(key_registration.second->pattern());
+
+ if (associated_registration_.get()) {
+ SendAssociateRegistrationMessage();
+ if (dispatcher_host_ && associated_registration_->active_version()) {
+ Send(new ServiceWorkerMsg_SetControllerServiceWorker(
+ render_thread_id_, provider_id(),
+ GetOrCreateServiceWorkerHandle(
+ associated_registration_->active_version()),
+ false /* shouldNotifyControllerChange */));
+ }
+ }
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index 70ed349..1ed95fa 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -52,6 +52,13 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
using GetRegistrationForReadyCallback =
base::Callback<void(ServiceWorkerRegistration* reigstration)>;
+ // PlzNavigate
+ // Used to pre-create a ServiceWorkerProviderHost for a navigation. The
+ // ServiceWorkerNetworkProvider will later be created in the renderer, should
+ // the navigation succeed.
+ static scoped_ptr<ServiceWorkerProviderHost> PreCreateNavigationHost(
+ base::WeakPtr<ServiceWorkerContextCore> context);
+
// When this provider host is for a Service Worker context, |route_id| is
// MSG_ROUTING_NONE. When this provider host is for a Document,
// |route_id| is the frame ID of the Document. When this provider host is for
@@ -202,6 +209,13 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
return dispatcher_host_;
}
+ // PlzNavigate
+ // Completes initialization of provider hosts used for navigation requests.
+ void CompleteNavigationInitialized(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host);
+
// Sends event messages to the renderer. Events for the worker are queued up
// until the worker thread id is known via SetReadyToSendMessagesToWorker().
void SendUpdateFoundMessage(
@@ -289,6 +303,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
bool IsReadyToSendMessages() const;
void Send(IPC::Message* message) const;
+ // Finalizes cross-site transfers and navigation-initalized hosts.
+ void FinalizeInitialization(int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host);
+
std::string client_uuid_;
int render_process_id_;
int route_id_;
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc
index 6d7d04b..27f3dea 100644
--- a/content/browser/service_worker/service_worker_request_handler.cc
+++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -6,8 +6,10 @@
#include <string>
+#include "base/command_line.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_url_request_job.h"
@@ -15,7 +17,10 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/resource_context.h"
+#include "content/public/common/child_process_host.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
+#include "ipc/ipc_message.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_interceptor.h"
@@ -49,8 +54,92 @@ class ServiceWorkerRequestInterceptor
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor);
};
+void FinalizeHandlerInitialization(
+ net::URLRequest* request,
+ ServiceWorkerProviderHost* provider_host,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body) {
+ if (skip_service_worker) {
+ // TODO(horo): Does this work properly for PlzNavigate?
+ if (ServiceWorkerUtils::IsMainResourceType(resource_type)) {
+ provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
+ provider_host->SetTopmostFrameUrl(request->first_party_for_cookies());
+ // A page load with skip_service_worker should be triggered by
+ // shift-reload, so retain all live matching registrations.
+ provider_host->AddAllMatchingRegistrations();
+ }
+ return;
+ }
+
+ scoped_ptr<ServiceWorkerRequestHandler> handler(
+ provider_host->CreateRequestHandler(
+ request_mode, credentials_mode, redirect_mode, resource_type,
+ request_context_type, frame_type, blob_storage_context->AsWeakPtr(),
+ body));
+ if (!handler)
+ return;
+
+ request->SetUserData(&kUserDataKey, handler.release());
+}
+
} // namespace
+// PlzNavigate
+void ServiceWorkerRequestHandler::InitializeForNavigation(
+ net::URLRequest* request,
+ ServiceWorkerNavigationHandleCore* navigation_handle_core,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body) {
+ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
+
+ // Only create a handler when there is a ServiceWorkerNavigationHandlerCore
+ // to take ownership of a pre-created SeviceWorkerProviderHost.
+ if (!navigation_handle_core)
+ return;
+
+ // Create the handler even for insecure HTTP since it's used in the
+ // case of redirect to HTTPS.
+ if (!request->url().SchemeIsHTTPOrHTTPS() &&
+ !OriginCanAccessServiceWorkers(request->url())) {
+ return;
+ }
+
+ if (!navigation_handle_core->context_wrapper() ||
+ !navigation_handle_core->context_wrapper()->context()) {
+ return;
+ }
+
+ // Initialize the SWProviderHost.
+ scoped_ptr<ServiceWorkerProviderHost> provider_host =
+ ServiceWorkerProviderHost::PreCreateNavigationHost(
+ navigation_handle_core->context_wrapper()->context()->AsWeakPtr());
+
+ FinalizeHandlerInitialization(
+ request, provider_host.get(), blob_storage_context, skip_service_worker,
+ FETCH_REQUEST_MODE_SAME_ORIGIN, FETCH_CREDENTIALS_MODE_INCLUDE,
+ FetchRedirectMode::MANUAL_MODE, resource_type, request_context_type,
+ frame_type, body);
+
+ // Transfer ownership to the ServiceWorkerNavigationHandleCore.
+ // In the case of a successful navigation, the SWProviderHost will be
+ // transferred to its "final" destination in the OnProviderCreated handler. If
+ // the navigation fails, it will be destroyed along with the
+ // ServiceWorkerNavigationHandleCore.
+ navigation_handle_core->DidPreCreateProviderHost(provider_host.Pass());
+}
+
void ServiceWorkerRequestHandler::InitializeHandler(
net::URLRequest* request,
ServiceWorkerContextWrapper* context_wrapper,
@@ -82,26 +171,10 @@ void ServiceWorkerRequestHandler::InitializeHandler(
if (!provider_host || !provider_host->IsContextAlive())
return;
- if (skip_service_worker) {
- if (ServiceWorkerUtils::IsMainResourceType(resource_type)) {
- provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
- provider_host->SetTopmostFrameUrl(request->first_party_for_cookies());
- // A page load with skip_service_worker should be triggered by
- // shift-reload, so retain all live matching registrations.
- provider_host->AddAllMatchingRegistrations();
- }
- return;
- }
-
- scoped_ptr<ServiceWorkerRequestHandler> handler(
- provider_host->CreateRequestHandler(
- request_mode, credentials_mode, redirect_mode, resource_type,
- request_context_type, frame_type, blob_storage_context->AsWeakPtr(),
- body));
- if (!handler)
- return;
-
- request->SetUserData(&kUserDataKey, handler.release());
+ FinalizeHandlerInitialization(request, provider_host, blob_storage_context,
+ skip_service_worker, request_mode,
+ credentials_mode, redirect_mode, resource_type,
+ request_context_type, frame_type, body);
}
ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
@@ -128,30 +201,33 @@ bool ServiceWorkerRequestHandler::IsControlledByServiceWorker(
void ServiceWorkerRequestHandler::PrepareForCrossSiteTransfer(
int old_process_id) {
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
if (!provider_host_ || !context_)
return;
old_process_id_ = old_process_id;
old_provider_id_ = provider_host_->provider_id();
- host_for_cross_site_transfer_ =
- context_->TransferProviderHostOut(old_process_id,
- provider_host_->provider_id());
+ host_for_cross_site_transfer_ = context_->TransferProviderHostOut(
+ old_process_id, provider_host_->provider_id());
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get());
}
void ServiceWorkerRequestHandler::CompleteCrossSiteTransfer(
int new_process_id, int new_provider_id) {
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
if (!host_for_cross_site_transfer_.get() || !context_)
return;
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get());
- context_->TransferProviderHostIn(
- new_process_id,
- new_provider_id,
- host_for_cross_site_transfer_.Pass());
+ context_->TransferProviderHostIn(new_process_id, new_provider_id,
+ host_for_cross_site_transfer_.Pass());
DCHECK_EQ(provider_host_->provider_id(), new_provider_id);
}
void ServiceWorkerRequestHandler::MaybeCompleteCrossSiteTransferInOldProcess(
int old_process_id) {
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
if (!host_for_cross_site_transfer_.get() || !context_ ||
old_process_id_ != old_process_id) {
return;
diff --git a/content/browser/service_worker/service_worker_request_handler.h b/content/browser/service_worker/service_worker_request_handler.h
index 2c14eb1..3d170c0 100644
--- a/content/browser/service_worker/service_worker_request_handler.h
+++ b/content/browser/service_worker/service_worker_request_handler.h
@@ -33,6 +33,7 @@ class ResourceContext;
class ResourceRequestBody;
class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandleCore;
class ServiceWorkerProviderHost;
struct ResourceResponseInfo;
@@ -41,6 +42,19 @@ struct ResourceResponseInfo;
class CONTENT_EXPORT ServiceWorkerRequestHandler
: public base::SupportsUserData::Data {
public:
+ // PlzNavigate
+ // Attaches a newly created handler if the given |request| needs to be handled
+ // by ServiceWorker.
+ static void InitializeForNavigation(
+ net::URLRequest* request,
+ ServiceWorkerNavigationHandleCore* navigation_handle_core,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body);
+
// Attaches a newly created handler if the given |request| needs to
// be handled by ServiceWorker.
// TODO(kinuko): While utilizing UserData to attach data to URLRequest
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc
index 1dcf75e..cb0225c 100644
--- a/content/child/service_worker/service_worker_network_provider.cc
+++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -5,9 +5,13 @@
#include "content/child/service_worker/service_worker_network_provider.h"
#include "base/atomic_sequence_num.h"
+#include "base/command_line.h"
#include "content/child/child_thread_impl.h"
#include "content/child/service_worker/service_worker_provider_context.h"
+#include "content/common/navigation_params.h"
#include "content/common/service_worker/service_worker_messages.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/content_switches.h"
namespace content {
@@ -44,10 +48,66 @@ ServiceWorkerNetworkProvider* ServiceWorkerNetworkProvider::FromDocumentState(
datasource_userdata->GetUserData(&kUserDataKey));
}
+// static
+scoped_ptr<ServiceWorkerNetworkProvider>
+ServiceWorkerNetworkProvider::CreateForNavigation(
+ int route_id,
+ const RequestNavigationParams& request_params,
+ blink::WebSandboxFlags sandbox_flags,
+ bool content_initiated) {
+ bool browser_side_navigation =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation);
+ bool should_create_provider_for_window = false;
+ int service_worker_provider_id = kInvalidServiceWorkerProviderId;
+ scoped_ptr<ServiceWorkerNetworkProvider> network_provider;
+
+ // Determine if a ServiceWorkerNetworkProvider should be created and properly
+ // initialized for the navigation. A default ServiceWorkerNetworkProvider
+ // will always be created since it is expected in a certain number of places,
+ // however it will have an invalid id.
+ // PlzNavigate: |service_worker_provider_id| can be sent by the browser, if
+ // it already created the SeviceWorkerProviderHost.
+ if (browser_side_navigation && !content_initiated) {
+ should_create_provider_for_window =
+ request_params.should_create_service_worker;
+ service_worker_provider_id = request_params.service_worker_provider_id;
+ DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(
+ service_worker_provider_id) ||
+ service_worker_provider_id == kInvalidServiceWorkerProviderId);
+ } else {
+ should_create_provider_for_window =
+ (sandbox_flags & blink::WebSandboxFlags::Origin) !=
+ blink::WebSandboxFlags::Origin;
+ }
+
+ // Now create the ServiceWorkerNetworkProvider (with invalid id if needed).
+ if (should_create_provider_for_window) {
+ if (service_worker_provider_id == kInvalidServiceWorkerProviderId) {
+ network_provider = scoped_ptr<ServiceWorkerNetworkProvider>(
+ new ServiceWorkerNetworkProvider(route_id,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW));
+ } else {
+ CHECK(browser_side_navigation);
+ DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(
+ service_worker_provider_id));
+ network_provider = scoped_ptr<ServiceWorkerNetworkProvider>(
+ new ServiceWorkerNetworkProvider(route_id,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW,
+ service_worker_provider_id));
+ }
+ } else {
+ network_provider = scoped_ptr<ServiceWorkerNetworkProvider>(
+ new ServiceWorkerNetworkProvider());
+ }
+ return network_provider.Pass();
+}
+
ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
int route_id,
- ServiceWorkerProviderType provider_type)
- : provider_id_(GenerateProviderIdForType(provider_type)) {
+ ServiceWorkerProviderType provider_type,
+ int browser_provider_id)
+ : provider_id_(browser_provider_id) {
if (provider_id_ == kInvalidServiceWorkerProviderId)
return;
context_ = new ServiceWorkerProviderContext(provider_id_, provider_type);
@@ -57,6 +117,16 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
provider_id_, route_id, provider_type));
}
+ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
+ int route_id,
+ ServiceWorkerProviderType provider_type)
+ : ServiceWorkerNetworkProvider(route_id,
+ provider_type,
+ GenerateProviderIdForType(provider_type)) {}
+
+ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider()
+ : provider_id_(kInvalidServiceWorkerProviderId) {}
+
ServiceWorkerNetworkProvider::~ServiceWorkerNetworkProvider() {
if (provider_id_ == kInvalidServiceWorkerProviderId)
return;
diff --git a/content/child/service_worker/service_worker_network_provider.h b/content/child/service_worker/service_worker_network_provider.h
index ec1bdce..c34adf4 100644
--- a/content/child/service_worker/service_worker_network_provider.h
+++ b/content/child/service_worker/service_worker_network_provider.h
@@ -11,10 +11,12 @@
#include "base/supports_user_data.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
class ServiceWorkerProviderContext;
+struct RequestNavigationParams;
// A unique provider_id is generated for each instance.
// Instantiated prior to the main resource load being started and remains
@@ -37,7 +39,19 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider
static ServiceWorkerNetworkProvider* FromDocumentState(
base::SupportsUserData* document_state);
+ static scoped_ptr<ServiceWorkerNetworkProvider> CreateForNavigation(
+ int route_id,
+ const RequestNavigationParams& request_params,
+ blink::WebSandboxFlags sandbox_flags,
+ bool content_initiated);
+
+ // PlzNavigate
+ // The |browser_provider_id| is initialized by the browser for navigations.
+ ServiceWorkerNetworkProvider(int route_id,
+ ServiceWorkerProviderType type,
+ int browser_provider_id);
ServiceWorkerNetworkProvider(int route_id, ServiceWorkerProviderType type);
+ ServiceWorkerNetworkProvider();
~ServiceWorkerNetworkProvider() override;
int provider_id() const { return provider_id_; }
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 4af27d3..0e02874 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -312,6 +312,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(current_history_list_offset)
IPC_STRUCT_TRAITS_MEMBER(current_history_list_length)
IPC_STRUCT_TRAITS_MEMBER(should_clear_history_list)
+ IPC_STRUCT_TRAITS_MEMBER(should_create_service_worker)
IPC_STRUCT_TRAITS_MEMBER(service_worker_provider_id)
IPC_STRUCT_TRAITS_END()
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc
index dfaefb1..63e6a11 100644
--- a/content/common/navigation_params.cc
+++ b/content/common/navigation_params.cc
@@ -126,6 +126,7 @@ RequestNavigationParams::RequestNavigationParams()
current_history_list_offset(-1),
current_history_list_length(0),
should_clear_history_list(false),
+ should_create_service_worker(false),
service_worker_provider_id(kInvalidServiceWorkerProviderId) {}
RequestNavigationParams::RequestNavigationParams(
@@ -159,6 +160,7 @@ RequestNavigationParams::RequestNavigationParams(
current_history_list_offset(current_history_list_offset),
current_history_list_length(current_history_list_length),
should_clear_history_list(should_clear_history_list),
+ should_create_service_worker(false),
service_worker_provider_id(kInvalidServiceWorkerProviderId) {}
RequestNavigationParams::~RequestNavigationParams() {
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h
index 8093623..cf3d89a 100644
--- a/content/common/navigation_params.h
+++ b/content/common/navigation_params.h
@@ -285,10 +285,14 @@ struct CONTENT_EXPORT RequestNavigationParams {
bool should_clear_history_list;
// PlzNavigate
- // The ServiceWorkerProviderHost ID used for navigations.
- // Set to kInvalidServiceWorkerProviderId for sandboxed frames and sync loads.
- // This parameter is not used in the current navigation architecture, where it
- // will always be equal to kInvalidServiceWorkerProviderId.
+ // Whether a ServiceWorkerProviderHost should be created for the window.
+ bool should_create_service_worker;
+
+ // PlzNavigate
+ // The ServiceWorkerProviderHost ID used for navigations, if it was already
+ // created by the browser. Set to kInvalidServiceWorkerProviderId otherwise.
+ // This parameter is not used in the current navigation architecture, where
+ // it will always be equal to kInvalidServiceWorkerProviderId.
int service_worker_provider_id;
};
diff --git a/content/common/service_worker/service_worker_utils.h b/content/common/service_worker/service_worker_utils.h
index 1f74735..8538b5e 100644
--- a/content/common/service_worker/service_worker_utils.h
+++ b/content/common/service_worker/service_worker_utils.h
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/resource_type.h"
#include "url/gurl.h"
@@ -38,6 +39,12 @@ class ServiceWorkerUtils {
static bool ContainsDisallowedCharacter(const GURL& scope,
const GURL& script_url,
std::string* error_message);
+
+ // PlzNavigate
+ // Returns true if the |provider_id| was assigned by the browser process.
+ static bool IsBrowserAssignedProviderId(int provider_id) {
+ return provider_id < kInvalidServiceWorkerProviderId;
+ }
};
class CONTENT_EXPORT LongestScopeMatcher {
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index b645c11..e956edd 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1383,6 +1383,10 @@
'browser/service_worker/service_worker_job_coordinator.h',
'browser/service_worker/service_worker_metrics.cc',
'browser/service_worker/service_worker_metrics.h',
+ 'browser/service_worker/service_worker_navigation_handle.cc',
+ 'browser/service_worker/service_worker_navigation_handle.h',
+ 'browser/service_worker/service_worker_navigation_handle_core.cc',
+ 'browser/service_worker/service_worker_navigation_handle_core.h',
'browser/service_worker/service_worker_process_manager.cc',
'browser/service_worker/service_worker_process_manager.h',
'browser/service_worker/service_worker_provider_host.cc',
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3cb0fb9..8489199 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2648,20 +2648,18 @@ void RenderFrameImpl::didCreateDataSource(blink::WebLocalFrame* frame,
// Create the serviceworker's per-document network observing object if it
// does not exist (When navigation happens within a page, the provider already
// exists).
- if (!ServiceWorkerNetworkProvider::FromDocumentState(
- DocumentState::FromDataSource(datasource))) {
- ServiceWorkerProviderType provider_type =
- SERVICE_WORKER_PROVIDER_FOR_WINDOW;
- if ((frame->effectiveSandboxFlags() & blink::WebSandboxFlags::Origin) ==
- blink::WebSandboxFlags::Origin) {
- provider_type = SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME;
- }
- scoped_ptr<ServiceWorkerNetworkProvider> network_provider(
- new ServiceWorkerNetworkProvider(routing_id_, provider_type));
- ServiceWorkerNetworkProvider::AttachToDocumentState(
- DocumentState::FromDataSource(datasource),
- network_provider.Pass());
- }
+ if (ServiceWorkerNetworkProvider::FromDocumentState(
+ DocumentState::FromDataSource(datasource)))
+ return;
+
+ NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
+ DocumentState::FromDataSource(datasource)->navigation_state());
+
+ ServiceWorkerNetworkProvider::AttachToDocumentState(
+ DocumentState::FromDataSource(datasource),
+ ServiceWorkerNetworkProvider::CreateForNavigation(
+ routing_id_, navigation_state->request_params(),
+ frame->effectiveSandboxFlags(), content_initiated));
}
void RenderFrameImpl::didStartProvisionalLoad(blink::WebLocalFrame* frame,
@@ -3420,12 +3418,14 @@ void RenderFrameImpl::willSendRequest(
ServiceWorkerNetworkProvider* provider =
ServiceWorkerNetworkProvider::FromDocumentState(
DocumentState::FromDataSource(frame->provisionalDataSource()));
+ DCHECK(provider);
provider_id = provider->provider_id();
}
} else if (frame->dataSource()) {
ServiceWorkerNetworkProvider* provider =
ServiceWorkerNetworkProvider::FromDocumentState(
DocumentState::FromDataSource(frame->dataSource()));
+ DCHECK(provider);
provider_id = provider->provider_id();
// Explicitly set the SkipServiceWorker flag here if the renderer process
// hasn't received SetControllerServiceWorker message.
diff --git a/content/test/test_navigation_url_loader_factory.cc b/content/test/test_navigation_url_loader_factory.cc
index f106a02..29eddd1 100644
--- a/content/test/test_navigation_url_loader_factory.cc
+++ b/content/test/test_navigation_url_loader_factory.cc
@@ -20,6 +20,7 @@ TestNavigationURLLoaderFactory::~TestNavigationURLLoaderFactory() {
scoped_ptr<NavigationURLLoader> TestNavigationURLLoaderFactory::CreateLoader(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) {
return scoped_ptr<NavigationURLLoader>(new TestNavigationURLLoader(
request_info.Pass(), delegate));
diff --git a/content/test/test_navigation_url_loader_factory.h b/content/test/test_navigation_url_loader_factory.h
index a91c416..a3bfe2f 100644
--- a/content/test/test_navigation_url_loader_factory.h
+++ b/content/test/test_navigation_url_loader_factory.h
@@ -27,6 +27,7 @@ class TestNavigationURLLoaderFactory : public NavigationURLLoaderFactory {
scoped_ptr<NavigationURLLoader> CreateLoader(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) override;
private: