| Index: content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
|
| diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
|
| index 46d5a7a4dd8ae4ac728c413eadb5f1578ced0414..434c1f9ad4f903d37cb439b020fbd26063811710 100644
|
| --- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
|
| +++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
|
| @@ -22,11 +22,13 @@
|
| #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_test_utils.h"
|
| #include "content/common/service_worker/embedded_worker_messages.h"
|
| #include "content/common/service_worker/service_worker_messages.h"
|
| #include "content/common/service_worker/service_worker_types.h"
|
| #include "content/common/service_worker/service_worker_utils.h"
|
| +#include "content/public/common/browser_side_navigation_policy.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/test/mock_resource_context.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| @@ -50,6 +52,47 @@ void SetUpDummyMessagePort(std::vector<MessagePort>* ports) {
|
| ports->push_back(MessagePort(std::move(pipe.handle0)));
|
| }
|
|
|
| +struct RemoteProviderInfo {
|
| + mojom::ServiceWorkerProviderHostAssociatedPtr host_ptr;
|
| + mojom::ServiceWorkerProviderAssociatedRequest client_request;
|
| +};
|
| +
|
| +RemoteProviderInfo SetupProviderHostInfoPtrs(
|
| + ServiceWorkerProviderHostInfo* host_info) {
|
| + RemoteProviderInfo remote_info;
|
| + mojom::ServiceWorkerProviderAssociatedPtr browser_side_client_ptr;
|
| + remote_info.client_request =
|
| + mojo::MakeIsolatedRequest(&browser_side_client_ptr);
|
| + host_info->host_request = mojo::MakeIsolatedRequest(&remote_info.host_ptr);
|
| + host_info->client_ptr_info = browser_side_client_ptr.PassInterface();
|
| + EXPECT_TRUE(host_info->host_request.is_pending());
|
| + EXPECT_TRUE(host_info->client_ptr_info.is_valid());
|
| + EXPECT_TRUE(remote_info.host_ptr.is_bound());
|
| + EXPECT_TRUE(remote_info.client_request.is_pending());
|
| + return remote_info;
|
| +}
|
| +
|
| +std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
|
| + ServiceWorkerContextWrapper* context_wrapper) {
|
| + std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(
|
| + [](ServiceWorkerContextWrapper* wrapper) {
|
| + return base::MakeUnique<ServiceWorkerNavigationHandleCore>(nullptr,
|
| + wrapper);
|
| + },
|
| + context_wrapper),
|
| + base::Bind(
|
| + [](std::unique_ptr<ServiceWorkerNavigationHandleCore>* dest,
|
| + std::unique_ptr<ServiceWorkerNavigationHandleCore> src) {
|
| + *dest = std::move(src);
|
| + },
|
| + &navigation_handle_core));
|
| + base::RunLoop().RunUntilIdle();
|
| + return navigation_handle_core;
|
| +}
|
| +
|
| } // namespace
|
|
|
| static const int kRenderFrameId = 1;
|
| @@ -168,6 +211,11 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
|
| const int64_t kProviderId = 99;
|
| ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type,
|
| true /* is_parent_frame_secure */);
|
| + mojom::ServiceWorkerProviderAssociatedPtr client_ptr;
|
| + remote_endpoint_.client_request = mojo::MakeIsolatedRequest(&client_ptr);
|
| + info.client_ptr_info = client_ptr.PassInterface();
|
| + info.host_request = mojo::MakeIsolatedRequest(&remote_endpoint_.host_ptr);
|
| +
|
| dispatcher_host_->OnProviderCreated(std::move(info));
|
| helper_->SimulateAddProcessToPattern(pattern,
|
| helper_->mock_render_process_id());
|
| @@ -253,7 +301,7 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
|
| int provider_id) {
|
| return CreateProviderHostWithDispatcherHost(
|
| helper_->mock_render_process_id(), provider_id, context()->AsWeakPtr(),
|
| - kRenderFrameId, dispatcher_host_.get());
|
| + kRenderFrameId, dispatcher_host_.get(), &remote_endpoint_);
|
| }
|
|
|
| TestBrowserThreadBundle browser_thread_bundle_;
|
| @@ -263,6 +311,7 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
|
| scoped_refptr<ServiceWorkerRegistration> registration_;
|
| scoped_refptr<ServiceWorkerVersion> version_;
|
| ServiceWorkerProviderHost* provider_host_;
|
| + ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
|
| };
|
|
|
| class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
|
| @@ -509,32 +558,64 @@ TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) {
|
| }
|
|
|
| TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
|
| - const int kProviderId = 1001;
|
| + const int kProviderId = (IsBrowserSideNavigationEnabled() ? -2 : 1001);
|
| int process_id = helper_->mock_render_process_id();
|
|
|
| - dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo(
|
| - kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| - true /* is_parent_frame_secure */));
|
| + // Setup ServiceWorkerProviderHostInfo
|
| + ServiceWorkerProviderHostInfo host_info_1(kProviderId, 1 /* route_id */,
|
| + SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| + true /* is_parent_frame_secure */);
|
| + ServiceWorkerProviderHostInfo host_info_2(kProviderId, 1 /* route_id */,
|
| + SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| + true /* is_parent_frame_secure */);
|
| + ServiceWorkerProviderHostInfo host_info_3(kProviderId, 1 /* route_id */,
|
| + SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| + true /* is_parent_frame_secure */);
|
| + RemoteProviderInfo remote_info_1 = SetupProviderHostInfoPtrs(&host_info_1);
|
| + RemoteProviderInfo remote_info_2 = SetupProviderHostInfoPtrs(&host_info_2);
|
| + RemoteProviderInfo remote_info_3 = SetupProviderHostInfoPtrs(&host_info_3);
|
| +
|
| + // PlzNavigate
|
| + std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
|
| + if (IsBrowserSideNavigationEnabled()) {
|
| + navigation_handle_core =
|
| + CreateNavigationHandleCore(helper_->context_wrapper());
|
| + ASSERT_TRUE(navigation_handle_core);
|
| + // ProviderHost should be created before OnProviderCreated.
|
| + navigation_handle_core->DidPreCreateProviderHost(
|
| + ServiceWorkerProviderHost::PreCreateNavigationHost(
|
| + helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
|
| + base::Callback<WebContents*(void)>()));
|
| + }
|
| +
|
| + dispatcher_host_->OnProviderCreated(std::move(host_info_1));
|
| EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
|
|
|
| // Two with the same ID should be seen as a bad message.
|
| - dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo(
|
| - kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| - true /* is_parent_frame_secure */));
|
| + dispatcher_host_->OnProviderCreated(std::move(host_info_2));
|
| EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
|
|
|
| - dispatcher_host_->OnProviderDestroyed(kProviderId);
|
| + // Releasing the interface pointer destroys the counterpart.
|
| + remote_info_1.host_ptr.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
|
|
|
| - // Destroying an ID that does not exist warrants a bad message.
|
| - dispatcher_host_->OnProviderDestroyed(kProviderId);
|
| - EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_);
|
| + // PlzNavigate
|
| + // Prepare another navigation handle to create another provider host.
|
| + if (IsBrowserSideNavigationEnabled()) {
|
| + navigation_handle_core =
|
| + CreateNavigationHandleCore(helper_->context_wrapper());
|
| + ASSERT_TRUE(navigation_handle_core);
|
| + // ProviderHost should be created before OnProviderCreated.
|
| + navigation_handle_core->DidPreCreateProviderHost(
|
| + ServiceWorkerProviderHost::PreCreateNavigationHost(
|
| + helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
|
| + base::Callback<WebContents*(void)>()));
|
| + }
|
|
|
| // Deletion of the dispatcher_host should cause providers for that
|
| // process to get deleted as well.
|
| - dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo(
|
| - kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| - true /* is_parent_frame_secure */));
|
| + dispatcher_host_->OnProviderCreated(std::move(host_info_3));
|
| EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
|
| EXPECT_TRUE(dispatcher_host_->HasOneRef());
|
| dispatcher_host_ = nullptr;
|
| @@ -669,9 +750,15 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
|
| // To show the new dispatcher can operate, simulate provider creation. Since
|
| // the old dispatcher cleaned up the old provider host, the new one won't
|
| // complain.
|
| - new_dispatcher_host->OnProviderCreated(ServiceWorkerProviderHostInfo(
|
| - provider_id, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| - true /* is_parent_frame_secure */));
|
| + ServiceWorkerProviderHostInfo host_info(provider_id, MSG_ROUTING_NONE,
|
| + SERVICE_WORKER_PROVIDER_FOR_WINDOW,
|
| + true /* is_parent_frame_secure */);
|
| + ServiceWorkerRemoteProviderEndpoint remote_endpoint;
|
| + mojom::ServiceWorkerProviderAssociatedPtr client_ptr;
|
| + remote_endpoint.client_request = mojo::MakeIsolatedRequest(&client_ptr);
|
| + host_info.client_ptr_info = client_ptr.PassInterface();
|
| + host_info.host_request = mojo::MakeIsolatedRequest(&remote_endpoint.host_ptr);
|
| + new_dispatcher_host->OnProviderCreated(std::move(host_info));
|
| EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_);
|
| }
|
|
|
|
|