Commit 9ec5282f authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

Revert "[ServiceWorker] Implement ServiceWorkerContainer.SetController"

This reverts commit 24e5c55f.

Revert "[ServiceWorker] Fix the warning for comparison of unsigned expression"

This reverts commit 4d47a13e.

Reverting due to crashes, see bug.

Bug: 774681, 755861
Change-Id: Ib90a143dec1ca9f378a487e330a98a1bb3d7d50c
TBR: xiaofeng.zhang, shimazu, tsepez, kinuko
Reviewed-on: https://chromium-review.googlesource.com/722840Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509559}
parent d88ebf8b
...@@ -573,13 +573,6 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { ...@@ -573,13 +573,6 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type); DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type);
// Clear the controller from the renderer-side provider, since no one knows
// what's going to happen until after cross-site transfer finishes.
if (controller_) {
SendSetControllerServiceWorker(nullptr,
false /* notify_controllerchange */);
}
std::unique_ptr<ServiceWorkerProviderHost> provisional_host = std::unique_ptr<ServiceWorkerProviderHost> provisional_host =
base::WrapUnique(new ServiceWorkerProviderHost( base::WrapUnique(new ServiceWorkerProviderHost(
process_id(), process_id(),
...@@ -592,6 +585,13 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { ...@@ -592,6 +585,13 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
RemoveAllMatchingRegistrations(); RemoveAllMatchingRegistrations();
// Clear the controller from the renderer-side provider, since no one knows
// what's going to happen until after cross-site transfer finishes.
if (controller_) {
SendSetControllerServiceWorker(nullptr,
false /* notify_controllerchange */);
}
render_process_id_ = ChildProcessHost::kInvalidUniqueID; render_process_id_ = ChildProcessHost::kInvalidUniqueID;
render_thread_id_ = kInvalidEmbeddedWorkerThreadId; render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
dispatcher_host_ = nullptr; dispatcher_host_ = nullptr;
...@@ -898,20 +898,14 @@ void ServiceWorkerProviderHost::SendSetControllerServiceWorker( ...@@ -898,20 +898,14 @@ void ServiceWorkerProviderHost::SendSetControllerServiceWorker(
DCHECK_EQ(controller_.get(), version); DCHECK_EQ(controller_.get(), version);
} }
std::vector<blink::mojom::WebFeature> used_features; ServiceWorkerMsg_SetControllerServiceWorker_Params params;
if (version) { params.thread_id = render_thread_id_;
for (const uint32_t feature : version->used_features()) { params.provider_id = provider_id();
// TODO: version->used_features() should never have a feature outside the params.object_info = GetOrCreateServiceWorkerHandle(version);
// known feature range. But there is special case, see the details in params.should_notify_controllerchange = notify_controllerchange;
// crbug.com/758419. if (version)
if (feature < params.used_features = version->used_features();
static_cast<uint32_t>(blink::mojom::WebFeature::kNumberOfFeatures)) { Send(new ServiceWorkerMsg_SetControllerServiceWorker(params));
used_features.push_back(static_cast<blink::mojom::WebFeature>(feature));
}
}
}
container_->SetController(GetOrCreateServiceWorkerHandle(version),
used_features, notify_controllerchange);
} }
void ServiceWorkerProviderHost::Register( void ServiceWorkerProviderHost::Register(
......
...@@ -36,6 +36,17 @@ namespace content { ...@@ -36,6 +36,17 @@ namespace content {
namespace { namespace {
// Sets the document URL for |host| and associates it with |registration|.
// A dumb version of
// ServiceWorkerControlleeRequestHandler::PrepareForMainResource().
void SimulateServiceWorkerControlleeRequestHandler(
ServiceWorkerProviderHost* host,
ServiceWorkerRegistration* registration) {
host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->AssociateRegistration(registration,
false /* notify_controllerchange */);
}
const char kServiceWorkerScheme[] = "i-can-use-service-worker"; const char kServiceWorkerScheme[] = "i-can-use-service-worker";
class ServiceWorkerTestContentClient : public TestContentClient { class ServiceWorkerTestContentClient : public TestContentClient {
...@@ -461,27 +472,6 @@ TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) { ...@@ -461,27 +472,6 @@ TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) {
EXPECT_FALSE(context_->GetProviderHost(process_id, provider_id)); EXPECT_FALSE(context_->GetProviderHost(process_id, provider_id));
} }
class MockServiceWorkerContainer : public mojom::ServiceWorkerContainer {
public:
explicit MockServiceWorkerContainer(
mojom::ServiceWorkerContainerAssociatedRequest request)
: binding_(this, std::move(request)) {}
~MockServiceWorkerContainer() override = default;
void SetController(const ServiceWorkerObjectInfo& controller,
const std::vector<blink::mojom::WebFeature>& used_features,
bool should_notify_controllerchange) override {
was_set_controller_called_ = true;
}
bool was_set_controller_called() const { return was_set_controller_called_; }
private:
bool was_set_controller_called_ = false;
mojo::AssociatedBinding<mojom::ServiceWorkerContainer> binding_;
};
TEST_F(ServiceWorkerProviderHostTest, Controller) { TEST_F(ServiceWorkerProviderHostTest, Controller) {
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableBrowserSideNavigation); switches::kEnableBrowserSideNavigation);
...@@ -495,31 +485,27 @@ TEST_F(ServiceWorkerProviderHostTest, Controller) { ...@@ -495,31 +485,27 @@ TEST_F(ServiceWorkerProviderHostTest, Controller) {
true /* is_parent_frame_secure */); true /* is_parent_frame_secure */);
remote_endpoints_.emplace_back(); remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info); remote_endpoints_.back().BindWithProviderHostInfo(&info);
auto container = base::MakeUnique<MockServiceWorkerContainer>(
std::move(*remote_endpoints_.back().client_request()));
// Create an active version and then start the navigation. // Create an active version and then start the navigation.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion( scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration1_.get(), GURL("https://www.example.com/sw.js"), registration1_.get(), GURL("https://www.example.com/sw.js"),
1 /* version_id */, helper_->context()->AsWeakPtr()); 1 /* version_id */, helper_->context()->AsWeakPtr());
registration1_->SetActiveVersion(version); registration1_->SetActiveVersion(version);
SimulateServiceWorkerControlleeRequestHandler(host.get(),
registration1_.get());
// Finish the navigation. // Finish the navigation.
host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->CompleteNavigationInitialized( host->CompleteNavigationInitialized(
helper_->mock_render_process_id(), std::move(info), helper_->mock_render_process_id(), std::move(info),
helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id()) helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
->AsWeakPtr()); ->AsWeakPtr());
host->AssociateRegistration(registration1_.get(),
false /* notify_controllerchange */);
base::RunLoop().RunUntilIdle();
// The page should be controlled since there was an active version at the // The page should be controlled since there was an active version at the
// time navigation started. The SetController IPC should have been sent. // time navigation started. The SetController IPC should have been sent.
EXPECT_TRUE(host->active_version()); EXPECT_TRUE(host->active_version());
EXPECT_EQ(host->active_version(), host->controller()); EXPECT_EQ(host->active_version(), host->controller());
EXPECT_TRUE(container->was_set_controller_called()); EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
ServiceWorkerMsg_SetControllerServiceWorker::ID));
} }
TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) { TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
...@@ -535,34 +521,31 @@ TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) { ...@@ -535,34 +521,31 @@ TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
true /* is_parent_frame_secure */); true /* is_parent_frame_secure */);
remote_endpoints_.emplace_back(); remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info); remote_endpoints_.back().BindWithProviderHostInfo(&info);
auto container = base::MakeUnique<MockServiceWorkerContainer>(
std::move(*remote_endpoints_.back().client_request()));
// Create an installing version and then start the navigation. // Associate it with an installing registration then start the navigation.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion( scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration1_.get(), GURL("https://www.example.com/sw.js"), registration1_.get(), GURL("https://www.example.com/sw.js"),
1 /* version_id */, helper_->context()->AsWeakPtr()); 1 /* version_id */, helper_->context()->AsWeakPtr());
registration1_->SetInstallingVersion(version); registration1_->SetInstallingVersion(version);
SimulateServiceWorkerControlleeRequestHandler(host.get(),
registration1_.get());
// Promote the worker to active while navigation is still happening.
registration1_->SetActiveVersion(version);
// Finish the navigation. // Finish the navigation.
host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->CompleteNavigationInitialized( host->CompleteNavigationInitialized(
helper_->mock_render_process_id(), std::move(info), helper_->mock_render_process_id(), std::move(info),
helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id()) helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
->AsWeakPtr()); ->AsWeakPtr());
host->AssociateRegistration(registration1_.get(),
false /* notify_controllerchange */);
// Promote the worker to active while navigation is still happening.
registration1_->SetActiveVersion(version);
base::RunLoop().RunUntilIdle();
// The page should not be controlled since there was no active version at the // The page should not be controlled since there was no active version at the
// time navigation started. Furthermore, no SetController IPC should have been // time navigation started. Furthermore, no SetController IPC should have been
// sent. // sent.
EXPECT_TRUE(host->active_version()); EXPECT_TRUE(host->active_version());
EXPECT_FALSE(host->controller()); EXPECT_FALSE(host->controller());
EXPECT_FALSE(container->was_set_controller_called()); EXPECT_EQ(nullptr, helper_->ipc_sink()->GetFirstMessageMatching(
ServiceWorkerMsg_SetControllerServiceWorker::ID));
} }
TEST_F(ServiceWorkerProviderHostTest, TEST_F(ServiceWorkerProviderHostTest,
......
...@@ -90,6 +90,8 @@ void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { ...@@ -90,6 +90,8 @@ void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
OnSetVersionAttributes) OnSetVersionAttributes)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound,
OnUpdateFound) OnUpdateFound)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
OnSetControllerServiceWorker)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
OnPostMessage) OnPostMessage)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CountFeature, OnCountFeature) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CountFeature, OnCountFeature)
...@@ -171,18 +173,9 @@ void ServiceWorkerDispatcher::AddProviderClient( ...@@ -171,18 +173,9 @@ void ServiceWorkerDispatcher::AddProviderClient(
} }
void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) { void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) {
auto iter = provider_clients_.find(provider_id);
// This could be possibly called multiple times to ensure termination. // This could be possibly called multiple times to ensure termination.
if (iter != provider_clients_.end()) if (base::ContainsKey(provider_clients_, provider_id))
provider_clients_.erase(iter); provider_clients_.erase(provider_id);
}
blink::WebServiceWorkerProviderClient*
ServiceWorkerDispatcher::GetProviderClient(int provider_id) {
auto iter = provider_clients_.find(provider_id);
if (iter != provider_clients_.end())
return iter->second;
return nullptr;
} }
ServiceWorkerDispatcher* ServiceWorkerDispatcher*
...@@ -211,11 +204,6 @@ ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() { ...@@ -211,11 +204,6 @@ ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
g_dispatcher_tls.Pointer()->Get()); g_dispatcher_tls.Pointer()->Get());
} }
std::unique_ptr<ServiceWorkerHandleReference> ServiceWorkerDispatcher::Adopt(
const ServiceWorkerObjectInfo& info) {
return ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
}
void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() { void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() {
delete this; delete this;
} }
...@@ -474,6 +462,43 @@ void ServiceWorkerDispatcher::OnUpdateFound( ...@@ -474,6 +462,43 @@ void ServiceWorkerDispatcher::OnUpdateFound(
found->second->OnUpdateFound(); found->second->OnUpdateFound();
} }
void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
const ServiceWorkerMsg_SetControllerServiceWorker_Params& params) {
TRACE_EVENT2(
"ServiceWorker", "ServiceWorkerDispatcher::OnSetControllerServiceWorker",
"Thread ID", params.thread_id, "Provider ID", params.provider_id);
// Adopt the reference sent from the browser process and pass it to the
// provider context if it exists.
std::unique_ptr<ServiceWorkerHandleReference> handle_ref =
Adopt(params.object_info);
ProviderContextMap::iterator provider =
provider_contexts_.find(params.provider_id);
if (provider != provider_contexts_.end()) {
provider->second->SetController(std::move(handle_ref),
params.used_features);
}
ProviderClientMap::iterator found =
provider_clients_.find(params.provider_id);
if (found != provider_clients_.end()) {
// Sync the controllee's use counter with the service worker's one.
for (uint32_t feature : params.used_features)
found->second->CountFeature(feature);
// Get the existing worker object or create a new one with a new reference
// to populate the .controller field.
scoped_refptr<WebServiceWorkerImpl> worker =
GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create(
params.object_info, thread_safe_sender_.get()));
found->second->SetController(WebServiceWorkerImpl::CreateHandle(worker),
params.should_notify_controllerchange);
// You must not access |found| after setController() because it may fire the
// controllerchange event that may remove the provider client, for example,
// by detaching an iframe.
}
}
void ServiceWorkerDispatcher::OnPostMessage( void ServiceWorkerDispatcher::OnPostMessage(
const ServiceWorkerMsg_MessageToDocument_Params& params) { const ServiceWorkerMsg_MessageToDocument_Params& params) {
// Make sure we're on the main document thread. (That must be the only // Make sure we're on the main document thread. (That must be the only
...@@ -538,4 +563,9 @@ void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration( ...@@ -538,4 +563,9 @@ void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
registrations_.erase(registration_handle_id); registrations_.erase(registration_handle_id);
} }
std::unique_ptr<ServiceWorkerHandleReference> ServiceWorkerDispatcher::Adopt(
const ServiceWorkerObjectInfo& info) {
return ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
}
} // namespace content } // namespace content
...@@ -105,8 +105,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer { ...@@ -105,8 +105,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
blink::WebServiceWorkerProviderClient* client); blink::WebServiceWorkerProviderClient* client);
void RemoveProviderClient(int provider_id); void RemoveProviderClient(int provider_id);
blink::WebServiceWorkerProviderClient* GetProviderClient(int provider_id);
// Returns the existing service worker or a newly created one with the given // Returns the existing service worker or a newly created one with the given
// handle reference. Returns nullptr if the given reference is invalid. // handle reference. Returns nullptr if the given reference is invalid.
scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker( scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker(
...@@ -138,11 +136,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer { ...@@ -138,11 +136,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
// instance if thread-local instance doesn't exist. // instance if thread-local instance doesn't exist.
static ServiceWorkerDispatcher* GetThreadSpecificInstance(); static ServiceWorkerDispatcher* GetThreadSpecificInstance();
// Assumes that the given object information retains an interprocess handle
// reference passed from the browser process, and adopts it.
std::unique_ptr<ServiceWorkerHandleReference> Adopt(
const ServiceWorkerObjectInfo& info);
base::SingleThreadTaskRunner* main_thread_task_runner() { base::SingleThreadTaskRunner* main_thread_task_runner() {
return main_thread_task_runner_.get(); return main_thread_task_runner_.get();
} }
...@@ -224,6 +217,11 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer { ...@@ -224,6 +217,11 @@ class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
void RemoveServiceWorkerRegistration( void RemoveServiceWorkerRegistration(
int registration_handle_id); int registration_handle_id);
// Assumes that the given object information retains an interprocess handle
// reference passed from the browser process, and adopts it.
std::unique_ptr<ServiceWorkerHandleReference> Adopt(
const ServiceWorkerObjectInfo& info);
UnregistrationCallbackMap pending_unregistration_callbacks_; UnregistrationCallbackMap pending_unregistration_callbacks_;
EnableNavigationPreloadCallbackMap enable_navigation_preload_callbacks_; EnableNavigationPreloadCallbackMap enable_navigation_preload_callbacks_;
GetNavigationPreloadStateCallbackMap get_navigation_preload_state_callbacks_; GetNavigationPreloadStateCallbackMap get_navigation_preload_state_callbacks_;
......
...@@ -104,6 +104,20 @@ class ServiceWorkerDispatcherTest : public testing::Test { ...@@ -104,6 +104,20 @@ class ServiceWorkerDispatcherTest : public testing::Test {
return ContainsKey(dispatcher_->registrations_, registration_handle_id); return ContainsKey(dispatcher_->registrations_, registration_handle_id);
} }
void OnSetControllerServiceWorker(int thread_id,
int provider_id,
const ServiceWorkerObjectInfo& info,
bool should_notify_controllerchange,
const std::set<uint32_t>& used_features) {
ServiceWorkerMsg_SetControllerServiceWorker_Params params;
params.thread_id = thread_id;
params.provider_id = provider_id;
params.object_info = info;
params.should_notify_controllerchange = should_notify_controllerchange;
params.used_features = used_features;
dispatcher_->OnSetControllerServiceWorker(params);
}
void OnPostMessage(const ServiceWorkerMsg_MessageToDocument_Params& params) { void OnPostMessage(const ServiceWorkerMsg_MessageToDocument_Params& params) {
dispatcher_->OnPostMessage(params); dispatcher_->OnPostMessage(params);
} }
...@@ -145,7 +159,11 @@ class MockWebServiceWorkerProviderClientImpl ...@@ -145,7 +159,11 @@ class MockWebServiceWorkerProviderClientImpl
} }
void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle, void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle,
bool should_notify_controller_change) override {} bool shouldNotifyControllerChange) override {
// WebPassOwnPtr cannot be owned in Chromium, so drop the handle here.
// The destruction releases ServiceWorkerHandleReference.
is_set_controlled_called_ = true;
}
void DispatchMessageEvent( void DispatchMessageEvent(
std::unique_ptr<blink::WebServiceWorker::Handle> handle, std::unique_ptr<blink::WebServiceWorker::Handle> handle,
...@@ -160,17 +178,136 @@ class MockWebServiceWorkerProviderClientImpl ...@@ -160,17 +178,136 @@ class MockWebServiceWorkerProviderClientImpl
used_features_.insert(feature); used_features_.insert(feature);
} }
bool is_set_controlled_called() const { return is_set_controlled_called_; }
bool is_dispatch_message_event_called() const { bool is_dispatch_message_event_called() const {
return is_dispatch_message_event_called_; return is_dispatch_message_event_called_;
} }
private: private:
const int provider_id_; const int provider_id_;
bool is_set_controlled_called_ = false;
bool is_dispatch_message_event_called_ = false; bool is_dispatch_message_event_called_ = false;
ServiceWorkerDispatcher* dispatcher_; ServiceWorkerDispatcher* dispatcher_;
std::set<uint32_t> used_features_; std::set<uint32_t> used_features_;
}; };
TEST_F(ServiceWorkerDispatcherTest, OnSetControllerServiceWorker) {
const int kProviderId = 10;
bool should_notify_controllerchange = true;
// Assume that these objects are passed from the browser process and own
// references to browser-side registration/worker representations.
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
ServiceWorkerVersionAttributes attrs;
CreateObjectInfoAndVersionAttributes(&info, &attrs);
// (1) In the case there are no SWProviderContext and WebSWProviderClient for
// the provider, the passed reference to the active worker should be adopted
// but immediately released because there is no provider context to own it.
OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
should_notify_controllerchange,
std::set<uint32_t>());
ASSERT_EQ(1UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
ipc_sink()->ClearMessages();
// (2) In the case there is no WebSWProviderClient but SWProviderContext for
// the provider, the passed referecence should be adopted and owned by the
// provider context.
auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
nullptr /* loader_factory_getter */);
ipc_sink()->ClearMessages();
OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
should_notify_controllerchange,
std::set<uint32_t>());
EXPECT_EQ(0UL, ipc_sink()->message_count());
// Destruction of the provider context should release references to the
// associated registration and the controller.
provider_context = nullptr;
ASSERT_EQ(1UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
ipc_sink()->ClearMessages();
// (3) In the case there is no SWProviderContext but WebSWProviderClient for
// the provider, the new reference should be created and owned by the provider
// client (but the reference is immediately released due to limitation of the
// mock provider client. See the comment on setController() of the mock).
// In addition, the passed reference should be adopted but immediately
// released because there is no provider context to own it.
std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client(
new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
ASSERT_FALSE(provider_client->is_set_controlled_called());
OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
should_notify_controllerchange,
std::set<uint32_t>());
EXPECT_TRUE(provider_client->is_set_controlled_called());
ASSERT_EQ(3UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(1)->type());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(2)->type());
provider_client.reset();
ipc_sink()->ClearMessages();
// (4) In the case there are both SWProviderContext and SWProviderClient for
// the provider, the passed referecence should be adopted and owned by the
// provider context. In addition, the new reference should be created for the
// provider client and immediately released due to limitation of the mock
// implementation.
provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
nullptr /* loader_factory_getter */);
provider_client.reset(
new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
ASSERT_FALSE(provider_client->is_set_controlled_called());
ipc_sink()->ClearMessages();
OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
should_notify_controllerchange,
std::set<uint32_t>());
EXPECT_TRUE(provider_client->is_set_controlled_called());
ASSERT_EQ(2UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(1)->type());
}
// Test that clearing the controller by sending a kInvalidServiceWorkerHandle
// results in the provider context having a null controller.
TEST_F(ServiceWorkerDispatcherTest, OnSetControllerServiceWorker_Null) {
const int kProviderId = 10;
bool should_notify_controllerchange = true;
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
ServiceWorkerVersionAttributes attrs;
CreateObjectInfoAndVersionAttributes(&info, &attrs);
std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client(
new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
nullptr /* loader_factory_getter */);
// Set the controller to kInvalidServiceWorkerHandle.
OnSetControllerServiceWorker(
kDocumentMainThreadId, kProviderId, ServiceWorkerObjectInfo(),
should_notify_controllerchange, std::set<uint32_t>());
// Check that it became null.
EXPECT_EQ(nullptr, provider_context->controller());
EXPECT_TRUE(provider_client->is_set_controlled_called());
}
TEST_F(ServiceWorkerDispatcherTest, OnPostMessage) { TEST_F(ServiceWorkerDispatcherTest, OnPostMessage) {
const int kProviderId = 10; const int kProviderId = 10;
......
...@@ -60,6 +60,8 @@ void ServiceWorkerMessageFilter::OnStaleMessageReceived( ...@@ -60,6 +60,8 @@ void ServiceWorkerMessageFilter::OnStaleMessageReceived(
IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg) IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes,
OnStaleSetVersionAttributes) OnStaleSetVersionAttributes)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
OnStaleSetControllerServiceWorker)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
OnStaleMessageToDocument) OnStaleMessageToDocument)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -80,6 +82,12 @@ void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( ...@@ -80,6 +82,12 @@ void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes(
// SetVersionAttributes message doesn't increment it. // SetVersionAttributes message doesn't increment it.
} }
void ServiceWorkerMessageFilter::OnStaleSetControllerServiceWorker(
const ServiceWorkerMsg_SetControllerServiceWorker_Params& params) {
SendServiceWorkerObjectDestroyed(thread_safe_sender(),
params.object_info.handle_id);
}
void ServiceWorkerMessageFilter::OnStaleMessageToDocument( void ServiceWorkerMessageFilter::OnStaleMessageToDocument(
const ServiceWorkerMsg_MessageToDocument_Params& params) { const ServiceWorkerMsg_MessageToDocument_Params& params) {
SendServiceWorkerObjectDestroyed(thread_safe_sender(), SendServiceWorkerObjectDestroyed(thread_safe_sender(),
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "content/common/content_export.h" #include "content/common/content_export.h"
struct ServiceWorkerMsg_MessageToDocument_Params; struct ServiceWorkerMsg_MessageToDocument_Params;
struct ServiceWorkerMsg_SetControllerServiceWorker_Params;
namespace content { namespace content {
...@@ -42,6 +43,8 @@ class CONTENT_EXPORT ServiceWorkerMessageFilter ...@@ -42,6 +43,8 @@ class CONTENT_EXPORT ServiceWorkerMessageFilter
int registration_handle_id, int registration_handle_id,
int changed_mask, int changed_mask,
const ServiceWorkerVersionAttributes& attrs); const ServiceWorkerVersionAttributes& attrs);
void OnStaleSetControllerServiceWorker(
const ServiceWorkerMsg_SetControllerServiceWorker_Params& params);
void OnStaleMessageToDocument( void OnStaleMessageToDocument(
const ServiceWorkerMsg_MessageToDocument_Params& params); const ServiceWorkerMsg_MessageToDocument_Params& params);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_handle_reference.h"
#include "content/child/service_worker/service_worker_subresource_loader.h" #include "content/child/service_worker/service_worker_subresource_loader.h"
#include "content/child/service_worker/web_service_worker_impl.h"
#include "content/child/thread_safe_sender.h" #include "content/child/thread_safe_sender.h"
#include "content/child/worker_thread_registry.h" #include "content/child/worker_thread_registry.h"
#include "content/common/service_worker/service_worker_utils.h" #include "content/common/service_worker/service_worker_utils.h"
...@@ -55,10 +54,6 @@ struct ServiceWorkerProviderContext::ControlleeState { ...@@ -55,10 +54,6 @@ struct ServiceWorkerProviderContext::ControlleeState {
// Tracks feature usage for UseCounter. // Tracks feature usage for UseCounter.
std::set<uint32_t> used_features; std::set<uint32_t> used_features;
// Corresponds to a ServiceWorkerContainer. We notify it when
// ServiceWorkerContainer#controller should be changed.
base::WeakPtr<WebServiceWorkerProviderImpl> web_service_worker_provider;
// Keeps ServiceWorkerWorkerClient pointers of dedicated or shared workers // Keeps ServiceWorkerWorkerClient pointers of dedicated or shared workers
// which are associated with the ServiceWorkerProviderContext. // which are associated with the ServiceWorkerProviderContext.
// - If this ServiceWorkerProviderContext is for a Document, then // - If this ServiceWorkerProviderContext is for a Document, then
...@@ -163,6 +158,50 @@ void ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope( ...@@ -163,6 +158,50 @@ void ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope(
attrs->active = state->active->info(); attrs->active = state->active->info();
} }
void ServiceWorkerProviderContext::SetController(
std::unique_ptr<ServiceWorkerHandleReference> controller,
const std::set<uint32_t>& used_features) {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
ControlleeState* state = controllee_state_.get();
DCHECK(state);
DCHECK(!state->controller ||
state->controller->handle_id() != kInvalidServiceWorkerHandleId);
state->controller = std::move(controller);
state->used_features = used_features;
// Propagate the controller to workers related to this provider.
if (state->controller) {
for (const auto& worker : state->worker_clients) {
// This is a Mojo interface call to the (dedicated or shared) worker
// thread.
worker->SetControllerServiceWorker(state->controller->version_id());
}
}
// S13nServiceWorker
// Set up the URL loader factory for sending URL requests to the controller.
if (!ServiceWorkerUtils::IsServicificationEnabled() || !state->controller) {
state->controller_connector = nullptr;
state->subresource_loader_factory = nullptr;
return;
}
storage::mojom::BlobRegistryPtr blob_registry_ptr;
ChildThreadImpl::current()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, mojo::MakeRequest(&blob_registry_ptr));
auto blob_registry = base::MakeRefCounted<
base::RefCountedData<storage::mojom::BlobRegistryPtr>>(
std::move(blob_registry_ptr));
state->controller_connector =
base::MakeRefCounted<ControllerServiceWorkerConnector>(
container_host_.get());
mojo::MakeStrongBinding(
base::MakeUnique<ServiceWorkerSubresourceLoaderFactory>(
state->controller_connector, state->default_loader_factory_getter,
state->controller->url().GetOrigin(), std::move(blob_registry)),
mojo::MakeRequest(&state->subresource_loader_factory));
}
ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() { ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(controllee_state_); DCHECK(controllee_state_);
...@@ -194,12 +233,6 @@ const std::set<uint32_t>& ServiceWorkerProviderContext::used_features() const { ...@@ -194,12 +233,6 @@ const std::set<uint32_t>& ServiceWorkerProviderContext::used_features() const {
return controllee_state_->used_features; return controllee_state_->used_features;
} }
void ServiceWorkerProviderContext::SetWebServiceWorkerProvider(
base::WeakPtr<WebServiceWorkerProviderImpl> provider) {
DCHECK(controllee_state_);
controllee_state_->web_service_worker_provider = provider;
}
mojom::ServiceWorkerWorkerClientRequest mojom::ServiceWorkerWorkerClientRequest
ServiceWorkerProviderContext::CreateWorkerClientRequest() { ServiceWorkerProviderContext::CreateWorkerClientRequest() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
...@@ -224,63 +257,6 @@ void ServiceWorkerProviderContext::UnregisterWorkerFetchContext( ...@@ -224,63 +257,6 @@ void ServiceWorkerProviderContext::UnregisterWorkerFetchContext(
}); });
} }
void ServiceWorkerProviderContext::SetController(
const ServiceWorkerObjectInfo& controller,
const std::vector<blink::mojom::WebFeature>& used_features,
bool should_notify_controllerchange) {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
ControlleeState* state = controllee_state_.get();
DCHECK(state);
DCHECK(!state->controller ||
state->controller->handle_id() != kInvalidServiceWorkerHandleId);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
state->controller = dispatcher->Adopt(controller);
// Propagate the controller to workers related to this provider.
if (state->controller) {
for (const auto& worker : state->worker_clients) {
// This is a Mojo interface call to the (dedicated or shared) worker
// thread.
worker->SetControllerServiceWorker(state->controller->version_id());
}
}
for (blink::mojom::WebFeature feature : used_features)
state->used_features.insert(static_cast<uint32_t>(feature));
// S13nServiceWorker
// Set up the URL loader factory for sending URL requests to the controller.
if (!ServiceWorkerUtils::IsServicificationEnabled() || !state->controller) {
state->controller_connector = nullptr;
state->subresource_loader_factory = nullptr;
} else {
storage::mojom::BlobRegistryPtr blob_registry_ptr;
ChildThreadImpl::current()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, mojo::MakeRequest(&blob_registry_ptr));
auto blob_registry = base::MakeRefCounted<
base::RefCountedData<storage::mojom::BlobRegistryPtr>>();
blob_registry->data = std::move(blob_registry_ptr);
state->controller_connector =
base::MakeRefCounted<ControllerServiceWorkerConnector>(
container_host_.get());
mojo::MakeStrongBinding(
base::MakeUnique<ServiceWorkerSubresourceLoaderFactory>(
state->controller_connector, state->default_loader_factory_getter,
state->controller->url().GetOrigin(), std::move(blob_registry)),
mojo::MakeRequest(&state->subresource_loader_factory));
}
// The WebServiceWorkerProviderImpl might not exist yet because the document
// has not yet been created (as WebServiceWorkerImpl is created for a
// ServiceWorkerContainer). In that case, once it's created it will still get
// the controller from |this| via WebServiceWorkerProviderImpl::SetClient().
if (state->web_service_worker_provider) {
state->web_service_worker_provider->SetController(
controller, state->used_features, should_notify_controllerchange);
}
}
void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() { void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() {
container_host_.reset(); container_host_.reset();
if (controllee_state_ && controllee_state_->controller_connector) if (controllee_state_ && controllee_state_->controller_connector)
......
...@@ -11,14 +11,12 @@ ...@@ -11,14 +11,12 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner_helpers.h" #include "base/sequenced_task_runner_helpers.h"
#include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/service_worker/web_service_worker_provider_impl.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_container.mojom.h" #include "content/common/service_worker/service_worker_container.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h" #include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_types.h"
#include "content/public/child/child_url_loader_factory_getter.h" #include "content/public/child/child_url_loader_factory_getter.h"
#include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace base { namespace base {
...@@ -104,6 +102,8 @@ class CONTENT_EXPORT ServiceWorkerProviderContext ...@@ -104,6 +102,8 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// For service worker clients. The controller for // For service worker clients. The controller for
// ServiceWorkerContainer#controller. // ServiceWorkerContainer#controller.
void SetController(std::unique_ptr<ServiceWorkerHandleReference> controller,
const std::set<uint32_t>& used_features);
ServiceWorkerHandleReference* controller(); ServiceWorkerHandleReference* controller();
// S13nServiceWorker: // S13nServiceWorker:
...@@ -115,14 +115,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext ...@@ -115,14 +115,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
void CountFeature(uint32_t feature); void CountFeature(uint32_t feature);
const std::set<uint32_t>& used_features() const; const std::set<uint32_t>& used_features() const;
// For service worker clients. Sets a weak pointer back to the
// WebServiceWorkerProviderImpl (which corresponds to ServiceWorkerContainer
// in JavaScript) which has a strong reference to |this|. This allows us to
// notify the WebServiceWorkerProviderImpl when
// ServiceWorkerContainer#controller should be changed.
void SetWebServiceWorkerProvider(
base::WeakPtr<WebServiceWorkerProviderImpl> provider);
// For service worker clients. Creates a ServiceWorkerWorkerClientRequest // For service worker clients. Creates a ServiceWorkerWorkerClientRequest
// which can be used to bind with a WorkerFetchContextImpl in a (dedicated or // which can be used to bind with a WorkerFetchContextImpl in a (dedicated or
// shared) worker thread and receive SetControllerServiceWorker() method call // shared) worker thread and receive SetControllerServiceWorker() method call
...@@ -155,7 +147,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext ...@@ -155,7 +147,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
friend class base::RefCountedThreadSafe<ServiceWorkerProviderContext, friend class base::RefCountedThreadSafe<ServiceWorkerProviderContext,
ServiceWorkerProviderContextDeleter>; ServiceWorkerProviderContextDeleter>;
friend struct ServiceWorkerProviderContextDeleter; friend struct ServiceWorkerProviderContextDeleter;
struct ControlleeState; struct ControlleeState;
struct ControllerState; struct ControllerState;
...@@ -166,11 +157,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext ...@@ -166,11 +157,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// shared) worker, when the connection to the worker is disconnected. // shared) worker, when the connection to the worker is disconnected.
void UnregisterWorkerFetchContext(mojom::ServiceWorkerWorkerClient*); void UnregisterWorkerFetchContext(mojom::ServiceWorkerWorkerClient*);
// Implementation of mojom::ServiceWorkerContainer.
void SetController(const ServiceWorkerObjectInfo& controller,
const std::vector<blink::mojom::WebFeature>& used_features,
bool should_notify_controllerchange) override;
const ServiceWorkerProviderType provider_type_; const ServiceWorkerProviderType provider_type_;
const int provider_id_; const int provider_id_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "ipc/ipc_test_sink.h" #include "ipc/ipc_test_sink.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h" #include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
...@@ -53,41 +52,6 @@ class MockServiceWorkerRegistrationObjectHost ...@@ -53,41 +52,6 @@ class MockServiceWorkerRegistrationObjectHost
bindings_; bindings_;
}; };
class MockWebServiceWorkerProviderClientImpl
: public blink::WebServiceWorkerProviderClient {
public:
MockWebServiceWorkerProviderClientImpl() {}
~MockWebServiceWorkerProviderClientImpl() override {}
void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle,
bool should_notify_controller_change) override {
was_set_controller_called_ = true;
}
void DispatchMessageEvent(
std::unique_ptr<blink::WebServiceWorker::Handle> handle,
const blink::WebString& message,
blink::WebVector<blink::MessagePortChannel> ports) override {
was_dispatch_message_event_called_ = true;
}
void CountFeature(uint32_t feature) override {
used_features_.insert(feature);
}
bool was_set_controller_called() const { return was_set_controller_called_; }
bool was_dispatch_message_event_called() const {
return was_dispatch_message_event_called_;
}
private:
bool was_set_controller_called_ = false;
bool was_dispatch_message_event_called_ = false;
std::set<uint32_t> used_features_;
};
class ServiceWorkerTestSender : public ThreadSafeSender { class ServiceWorkerTestSender : public ThreadSafeSender {
public: public:
explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink) explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink)
...@@ -194,106 +158,4 @@ TEST_F(ServiceWorkerProviderContextTest, CreateForController) { ...@@ -194,106 +158,4 @@ TEST_F(ServiceWorkerProviderContextTest, CreateForController) {
EXPECT_EQ(0, remote_registration_object_host().GetBindingCount()); EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
} }
TEST_F(ServiceWorkerProviderContextTest, SetController) {
const int kProviderId = 10;
// Assume that these objects are passed from the browser process and own
// references to browser-side registration/worker representations.
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
ServiceWorkerVersionAttributes attrs;
CreateObjectInfoAndVersionAttributes(&info, &attrs);
{
// (1) In the case there is no WebSWProviderClient but SWProviderContext for
// the provider, the passed reference should be adopted and owned by the
// provider context.
mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
mojom::ServiceWorkerContainerAssociatedRequest container_request =
mojo::MakeIsolatedRequest(&container_ptr);
auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
std::move(container_request), nullptr /* host_ptr_info */, dispatcher(),
nullptr /* loader_factory_getter */);
ipc_sink()->ClearMessages();
container_ptr->SetController(attrs.active,
std::vector<blink::mojom::WebFeature>(), true);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0UL, ipc_sink()->message_count());
// Destruction of the provider context should release references to the
// the controller.
provider_context = nullptr;
ASSERT_EQ(1UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
ipc_sink()->ClearMessages();
}
{
// (2) In the case there are both SWProviderContext and SWProviderClient for
// the provider, the passed reference should be adopted and owned by the
// provider context. In addition, the new reference should be created for
// the provider client and immediately released due to limitation of the
// mock implementation.
mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
mojo::MakeRequest(&host_ptr_info);
mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
mojom::ServiceWorkerContainerAssociatedRequest container_request =
mojo::MakeIsolatedRequest(&container_ptr);
auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
std::move(container_request), std::move(host_ptr_info), dispatcher(),
nullptr /* loader_factory_getter */);
auto provider_impl = base::MakeUnique<WebServiceWorkerProviderImpl>(
thread_safe_sender(), provider_context.get());
auto client = base::MakeUnique<MockWebServiceWorkerProviderClientImpl>();
provider_impl->SetClient(client.get());
ASSERT_FALSE(client->was_set_controller_called());
ipc_sink()->ClearMessages();
container_ptr->SetController(attrs.active,
std::vector<blink::mojom::WebFeature>(), true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(client->was_set_controller_called());
ASSERT_EQ(2UL, ipc_sink()->message_count());
EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(0)->type());
EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
ipc_sink()->GetMessageAt(1)->type());
}
}
// Test that clearing the controller by sending a kInvalidServiceWorkerHandle
// results in the provider context having a null controller.
TEST_F(ServiceWorkerProviderContextTest, SetController_Null) {
const int kProviderId = 10;
mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
mojo::MakeRequest(&host_ptr_info);
mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
mojom::ServiceWorkerContainerAssociatedRequest container_request =
mojo::MakeIsolatedRequest(&container_ptr);
auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
std::move(container_request), std::move(host_ptr_info), dispatcher(),
nullptr /* loader_factory_getter */);
auto provider_impl = base::MakeUnique<WebServiceWorkerProviderImpl>(
thread_safe_sender(), provider_context.get());
auto client = base::MakeUnique<MockWebServiceWorkerProviderClientImpl>();
provider_impl->SetClient(client.get());
container_ptr->SetController(ServiceWorkerObjectInfo(),
std::vector<blink::mojom::WebFeature>(), true);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(nullptr, provider_context->controller());
EXPECT_TRUE(client->was_set_controller_called());
}
} // namespace content } // namespace content
...@@ -39,20 +39,8 @@ WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl( ...@@ -39,20 +39,8 @@ WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
context_(context), context_(context),
weak_factory_(this) { weak_factory_(this) {
DCHECK(context_); DCHECK(context_);
switch (context_->provider_type()) { DCHECK(context_->provider_type() != SERVICE_WORKER_PROVIDER_FOR_WINDOW ||
case SERVICE_WORKER_PROVIDER_FOR_WINDOW: context_->container_host());
DCHECK(context_->container_host());
context_->SetWebServiceWorkerProvider(weak_factory_.GetWeakPtr());
break;
case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
// Do nothing.
break;
case SERVICE_WORKER_PROVIDER_FOR_WORKER:
case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
case SERVICE_WORKER_PROVIDER_UNKNOWN:
NOTREACHED() << "Unimplemented type: " << context_->provider_type();
break;
}
} }
WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() { WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
...@@ -76,8 +64,17 @@ void WebServiceWorkerProviderImpl::SetClient( ...@@ -76,8 +64,17 @@ void WebServiceWorkerProviderImpl::SetClient(
if (!context_->controller()) if (!context_->controller())
return; return;
SetController(context_->controller()->info(), context_->used_features(), scoped_refptr<WebServiceWorkerImpl> controller =
false /* notify_controllerchange */); GetDispatcher()->GetOrCreateServiceWorker(
ServiceWorkerHandleReference::Create(context_->controller()->info(),
thread_safe_sender_.get()));
// Sync the controllee's use counter with |context_|'s, which keeps
// track of the controller's use counter.
for (uint32_t feature : context_->used_features())
client->CountFeature(feature);
client->SetController(WebServiceWorkerImpl::CreateHandle(controller),
false /* shouldNotifyControllerChange */);
} }
void WebServiceWorkerProviderImpl::RegisterServiceWorker( void WebServiceWorkerProviderImpl::RegisterServiceWorker(
...@@ -195,26 +192,6 @@ bool WebServiceWorkerProviderImpl::ValidateScopeAndScriptURL( ...@@ -195,26 +192,6 @@ bool WebServiceWorkerProviderImpl::ValidateScopeAndScriptURL(
return !has_error; return !has_error;
} }
void WebServiceWorkerProviderImpl::SetController(
const ServiceWorkerObjectInfo& info,
const std::set<uint32_t>& features,
bool should_notify_controller_change) {
blink::WebServiceWorkerProviderClient* provider_client =
GetDispatcher()->GetProviderClient(context_->provider_id());
// The caller should only call this after SetClient() has been called.
DCHECK(provider_client);
scoped_refptr<WebServiceWorkerImpl> controller =
GetDispatcher()->GetOrCreateServiceWorker(
ServiceWorkerHandleReference::Create(info,
thread_safe_sender_.get()));
for (uint32_t feature : features)
provider_client->CountFeature(feature);
provider_client->SetController(WebServiceWorkerImpl::CreateHandle(controller),
should_notify_controller_change);
}
int WebServiceWorkerProviderImpl::provider_id() const { int WebServiceWorkerProviderImpl::provider_id() const {
return context_->provider_id(); return context_->provider_id();
} }
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_types.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
...@@ -31,8 +30,7 @@ struct ServiceWorkerVersionAttributes; ...@@ -31,8 +30,7 @@ struct ServiceWorkerVersionAttributes;
// This class corresponds to one ServiceWorkerContainer interface in // This class corresponds to one ServiceWorkerContainer interface in
// JS context (i.e. navigator.serviceWorker). // JS context (i.e. navigator.serviceWorker).
class CONTENT_EXPORT WebServiceWorkerProviderImpl class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider {
: public blink::WebServiceWorkerProvider {
public: public:
WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender, WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender,
ServiceWorkerProviderContext* context); ServiceWorkerProviderContext* context);
...@@ -57,12 +55,6 @@ class CONTENT_EXPORT WebServiceWorkerProviderImpl ...@@ -57,12 +55,6 @@ class CONTENT_EXPORT WebServiceWorkerProviderImpl
const blink::WebURL& script_url, const blink::WebURL& script_url,
blink::WebString* error_message) override; blink::WebString* error_message) override;
// Sets the ServiceWorkerContainer#controller for this provider. It's not
// used when this WebServiceWorkerProvider is for a service worker context.
void SetController(const ServiceWorkerObjectInfo& info,
const std::set<uint32_t>& features,
bool should_notify_controller_change);
int provider_id() const; int provider_id() const;
private: private:
......
...@@ -8,7 +8,6 @@ import "content/common/service_worker/controller_service_worker.mojom"; ...@@ -8,7 +8,6 @@ import "content/common/service_worker/controller_service_worker.mojom";
import "content/common/service_worker/service_worker_types.mojom"; import "content/common/service_worker/service_worker_types.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom"; import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom"; import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom";
import "third_party/WebKit/public/platform/web_feature.mojom";
import "url/mojo/url.mojom"; import "url/mojo/url.mojom";
// mojom::ServiceWorkerContainerHost is a browser-side interface. The renderer // mojom::ServiceWorkerContainerHost is a browser-side interface. The renderer
...@@ -80,17 +79,8 @@ interface ServiceWorkerContainerHost { ...@@ -80,17 +79,8 @@ interface ServiceWorkerContainerHost {
// that can touch these objects should be a ServiceWorkerContainer, so it’s OK // that can touch these objects should be a ServiceWorkerContainer, so it’s OK
// to use this name. // to use this name.
interface ServiceWorkerContainer { interface ServiceWorkerContainer {
// Corresponds to setting ServiceWorkerContainer#controller.
// If |controller| is invalid (its |handle_id| is invalid), then
// ServiceWorkerContainer#controller is cleared.
// If |controller| is valid, |used_features| is the set of features the
// controller has used, for UseCounter purposes.
// If |should_notify_controllerchange| is true, dispatch a 'controllerchange'
// event.
SetController(ServiceWorkerObjectInfo controller,
array<blink.mojom.WebFeature> used_features,
bool should_notify_controllerchange);
// TODO(xiaofeng.zhang): implement them. // TODO(xiaofeng.zhang): implement them.
// SetController();
// ServiceWorkerStateChanged(); // ServiceWorkerStateChanged();
// ServiceWorkerRegistrationUpdateFound(); // ServiceWorkerRegistrationUpdateFound();
// PostMessage(); // PostMessage();
......
...@@ -140,6 +140,17 @@ IPC_STRUCT_TRAITS_BEGIN(content::PushEventPayload) ...@@ -140,6 +140,17 @@ IPC_STRUCT_TRAITS_BEGIN(content::PushEventPayload)
IPC_STRUCT_TRAITS_MEMBER(is_null) IPC_STRUCT_TRAITS_MEMBER(is_null)
IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_END()
IPC_STRUCT_BEGIN(ServiceWorkerMsg_SetControllerServiceWorker_Params)
IPC_STRUCT_MEMBER(int, thread_id)
IPC_STRUCT_MEMBER(int, provider_id)
IPC_STRUCT_MEMBER(content::ServiceWorkerObjectInfo, object_info)
IPC_STRUCT_MEMBER(bool, should_notify_controllerchange)
// |used_features| is the set of features that the worker has used.
// The values must be from blink::UseCounter::Feature enum.
IPC_STRUCT_MEMBER(std::set<uint32_t>, used_features)
IPC_STRUCT_END()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Messages sent from the child process to the browser. // Messages sent from the child process to the browser.
...@@ -292,6 +303,11 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_UpdateFound, ...@@ -292,6 +303,11 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_UpdateFound,
int /* thread_id */, int /* thread_id */,
int /* registration_handle_id */) int /* registration_handle_id */)
// Tells the child process to set the controller ServiceWorker for the given
// provider.
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_SetControllerServiceWorker,
ServiceWorkerMsg_SetControllerServiceWorker_Params)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidEnableNavigationPreload, IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidEnableNavigationPreload,
int /* thread_id */, int /* thread_id */,
int /* request_id */) int /* request_id */)
......
...@@ -24,7 +24,3 @@ enum ServiceWorkerProviderType { ...@@ -24,7 +24,3 @@ enum ServiceWorkerProviderType {
// Defined in service_worker_types.h. // Defined in service_worker_types.h.
[Native] [Native]
struct ServiceWorkerVersionAttributes; struct ServiceWorkerVersionAttributes;
// Defined in service_worker_types.h.
[Native]
struct ServiceWorkerObjectInfo;
...@@ -17,5 +17,4 @@ sources = [ ...@@ -17,5 +17,4 @@ sources = [
type_mappings = [ type_mappings = [
"content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType", "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType",
"content.mojom.ServiceWorkerVersionAttributes=::content::ServiceWorkerVersionAttributes", "content.mojom.ServiceWorkerVersionAttributes=::content::ServiceWorkerVersionAttributes",
"content.mojom.ServiceWorkerObjectInfo=::content::ServiceWorkerObjectInfo",
] ]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment