blob: 038247a18070f83af0c318c39a1221fca3e8e192 [file] [log] [blame]
// Copyright 2014 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/embedded_worker_test_helper.h"
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/embedded_worker_status.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_test_utils.h"
#include "content/common/background_fetch/background_fetch_types.h"
#include "content/common/renderer.mojom.h"
#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/http/http_util.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
namespace content {
namespace {
void OnFetchEventCommon(
blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
auto response = blink::mojom::FetchAPIResponse::New();
response->status_code = 200;
response->status_text = "OK";
response->response_type = network::mojom::FetchResponseType::kDefault;
response_callback->OnResponse(std::move(response), base::Time::Now());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
} // namespace
// A URLLoaderFactory that returns 200 OK with a simple body to any request.
class EmbeddedWorkerTestHelper::MockNetworkURLLoaderFactory final
: public network::mojom::URLLoaderFactory {
public:
MockNetworkURLLoaderFactory() = default;
// network::mojom::URLLoaderFactory implementation.
void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& url_request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
std::string headers = "HTTP/1.1 200 OK\n\n";
net::HttpResponseInfo info;
info.headers = new net::HttpResponseHeaders(
net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));
network::ResourceResponseHead response;
response.headers = info.headers;
response.headers->GetMimeType(&response.mime_type);
client->OnReceiveResponse(response);
std::string body = "this body came from the network";
uint32_t bytes_written = body.size();
mojo::DataPipe data_pipe;
data_pipe.producer_handle->WriteData(body.data(), &bytes_written,
MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
network::URLLoaderCompletionStatus status;
status.error_code = net::OK;
client->OnComplete(status);
}
void Clone(network::mojom::URLLoaderFactoryRequest request) override {
bindings_.AddBinding(this, std::move(request));
}
private:
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
DISALLOW_COPY_AND_ASSIGN(MockNetworkURLLoaderFactory);
};
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
MockEmbeddedWorkerInstanceClient(
base::WeakPtr<EmbeddedWorkerTestHelper> helper)
: helper_(helper), binding_(this) {}
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
~MockEmbeddedWorkerInstanceClient() {}
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
mojom::EmbeddedWorkerStartParamsPtr params) {
if (!helper_)
return;
embedded_worker_id_ = params->embedded_worker_id;
EmbeddedWorkerInstance* worker =
helper_->registry()->GetWorker(params->embedded_worker_id);
ASSERT_TRUE(worker);
helper_->OnStartWorkerStub(std::move(params));
}
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StopWorker() {
if (!helper_)
return;
ASSERT_TRUE(embedded_worker_id_);
EmbeddedWorkerInstance* worker =
helper_->registry()->GetWorker(embedded_worker_id_.value());
// |worker| is possible to be null when corresponding EmbeddedWorkerInstance
// is removed right after sending StopWorker.
if (worker)
EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, worker->status());
helper_->OnStopWorkerStub(embedded_worker_id_.value());
}
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
ResumeAfterDownload() {
helper_->OnResumeAfterDownloadStub(embedded_worker_id_.value());
}
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message) {
// TODO(shimazu): Pass these arguments to the test helper when a test is
// necessary to check them individually.
}
// static
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::Bind(
const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
mojom::EmbeddedWorkerInstanceClientRequest request) {
std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>>* clients =
helper->mock_instance_clients();
size_t next_client_index = helper->mock_instance_clients_next_index_;
ASSERT_GE(clients->size(), next_client_index);
if (clients->size() == next_client_index) {
clients->push_back(
std::make_unique<MockEmbeddedWorkerInstanceClient>(helper));
}
std::unique_ptr<MockEmbeddedWorkerInstanceClient>& client =
clients->at(next_client_index);
helper->mock_instance_clients_next_index_ = next_client_index + 1;
if (client)
client->binding_.Bind(std::move(request));
}
class EmbeddedWorkerTestHelper::MockServiceWorker
: public mojom::ServiceWorker {
public:
static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
int embedded_worker_id,
mojom::ServiceWorkerRequest request) {
mojo::MakeStrongBinding(
std::make_unique<MockServiceWorker>(helper, embedded_worker_id),
std::move(request));
}
MockServiceWorker(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
int embedded_worker_id)
: helper_(helper), embedded_worker_id_(embedded_worker_id) {}
~MockServiceWorker() override {}
void InitializeGlobalScope(
blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info)
override {
if (!helper_)
return;
helper_->OnInitializeGlobalScope(embedded_worker_id_,
std::move(service_worker_host),
std::move(registration_info));
}
void DispatchInstallEvent(
DispatchInstallEventCallback callback) override {
if (!helper_)
return;
helper_->OnInstallEventStub(std::move(callback));
}
void DispatchActivateEvent(DispatchActivateEventCallback callback) override {
if (!helper_)
return;
helper_->OnActivateEventStub(std::move(callback));
}
void DispatchBackgroundFetchAbortEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchAbortEventCallback callback) override {
if (!helper_)
return;
helper_->OnBackgroundFetchAbortEventStub(developer_id, unique_id, fetches,
std::move(callback));
}
void DispatchBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
DispatchBackgroundFetchClickEventCallback callback) override {
if (!helper_)
return;
helper_->OnBackgroundFetchClickEventStub(developer_id, state,
std::move(callback));
}
void DispatchBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchFailEventCallback callback) override {
if (!helper_)
return;
helper_->OnBackgroundFetchFailEventStub(developer_id, unique_id, fetches,
std::move(callback));
}
void DispatchBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchedEventCallback callback) override {
if (!helper_)
return;
helper_->OnBackgroundFetchedEventStub(developer_id, unique_id, fetches,
std::move(callback));
}
void DispatchCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
DispatchCookieChangeEventCallback callback) override {
if (!helper_)
return;
helper_->OnCookieChangeEventStub(cookie, cause, std::move(callback));
}
void DispatchFetchEvent(
blink::mojom::DispatchFetchEventParamsPtr params,
blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override {
if (!helper_)
return;
helper_->OnFetchEventStub(
embedded_worker_id_, params->request, std::move(params->preload_handle),
std::move(response_callback), std::move(callback));
}
void DispatchNotificationClickEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
DispatchNotificationClickEventCallback callback) override {
if (!helper_)
return;
helper_->OnNotificationClickEventStub(notification_id, notification_data,
action_index, reply,
std::move(callback));
}
void DispatchNotificationCloseEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
DispatchNotificationCloseEventCallback callback) override {
if (!helper_)
return;
helper_->OnNotificationCloseEventStub(notification_id, notification_data,
std::move(callback));
}
void DispatchPushEvent(const base::Optional<std::string>& payload,
DispatchPushEventCallback callback) override {
if (!helper_)
return;
helper_->OnPushEventStub(payload, std::move(callback));
}
void DispatchSyncEvent(const std::string& tag,
bool last_chance,
base::TimeDelta timeout,
DispatchSyncEventCallback callback) override {
NOTIMPLEMENTED();
}
void DispatchAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchAbortPaymentEventCallback callback) override {
if (!helper_)
return;
helper_->OnAbortPaymentEventStub(std::move(response_callback),
std::move(callback));
}
void DispatchCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchCanMakePaymentEventCallback callback) override {
if (!helper_)
return;
helper_->OnCanMakePaymentEventStub(std::move(event_data),
std::move(response_callback),
std::move(callback));
}
void DispatchPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchPaymentRequestEventCallback callback) override {
if (!helper_)
return;
helper_->OnPaymentRequestEventStub(std::move(event_data),
std::move(response_callback),
std::move(callback));
}
void DispatchExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
DispatchExtendableMessageEventCallback callback) override {
if (!helper_)
return;
helper_->OnExtendableMessageEventStub(std::move(event),
std::move(callback));
}
void Ping(PingCallback callback) override { std::move(callback).Run(); }
void SetIdleTimerDelayToZero() override {
if (!helper_)
return;
helper_->OnSetIdleTimerDelayToZero(embedded_worker_id_);
}
private:
base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
const int embedded_worker_id_;
};
class EmbeddedWorkerTestHelper::MockRendererInterface : public mojom::Renderer {
public:
explicit MockRendererInterface(base::WeakPtr<EmbeddedWorkerTestHelper> helper)
: helper_(helper) {}
void AddBinding(mojom::RendererAssociatedRequest request) {
bindings_.AddBinding(this, std::move(request));
}
private:
void CreateEmbedderRendererService(
service_manager::mojom::ServiceRequest service_request) override {
NOTREACHED();
}
void CreateView(mojom::CreateViewParamsPtr) override { NOTREACHED(); }
void CreateFrame(mojom::CreateFrameParamsPtr) override { NOTREACHED(); }
void SetUpEmbeddedWorkerChannelForServiceWorker(
mojom::EmbeddedWorkerInstanceClientRequest client_request) override {
MockEmbeddedWorkerInstanceClient::Bind(helper_, std::move(client_request));
}
void CreateFrameProxy(
int32_t routing_id,
int32_t render_view_routing_id,
int32_t opener_routing_id,
int32_t parent_routing_id,
const FrameReplicationState& replicated_state,
const base::UnguessableToken& devtools_frame_token) override {
NOTREACHED();
}
void OnNetworkConnectionChanged(
net::NetworkChangeNotifier::ConnectionType type,
double max_bandwidth_mbps) override {
NOTREACHED();
}
void OnNetworkQualityChanged(net::EffectiveConnectionType type,
base::TimeDelta http_rtt,
base::TimeDelta transport_rtt,
double bandwidth_kbps) override {
NOTREACHED();
}
void SetWebKitSharedTimersSuspended(bool suspend) override { NOTREACHED(); }
void SetUserAgent(const std::string& user_agent) override { NOTREACHED(); }
void UpdateScrollbarTheme(
mojom::UpdateScrollbarThemeParamsPtr params) override {
NOTREACHED();
}
void OnSystemColorsChanged(int32_t aqua_color_variant,
const std::string& highlight_text_color,
const std::string& highlight_color) override {
NOTREACHED();
}
void PurgePluginListCache(bool reload_pages) override { NOTREACHED(); }
void SetProcessBackgrounded(bool backgrounded) override { NOTREACHED(); }
void SetSchedulerKeepActive(bool keep_active) override { NOTREACHED(); }
void ProcessPurgeAndSuspend() override { NOTREACHED(); }
void SetIsLockedToSite() override { NOTREACHED(); }
void EnableV8LowMemoryMode() override { NOTREACHED(); }
base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
mojo::AssociatedBindingSet<mojom::Renderer> bindings_;
};
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
const base::FilePath& user_data_directory)
: browser_context_(std::make_unique<TestBrowserContext>()),
render_process_host_(
std::make_unique<MockRenderProcessHost>(browser_context_.get())),
new_render_process_host_(
std::make_unique<MockRenderProcessHost>(browser_context_.get())),
wrapper_(base::MakeRefCounted<ServiceWorkerContextWrapper>(
browser_context_.get())),
mock_instance_clients_next_index_(0),
next_thread_id_(0),
mock_render_process_id_(render_process_host_->GetID()),
new_mock_render_process_id_(new_render_process_host_->GetID()),
url_loader_factory_getter_(
base::MakeRefCounted<URLLoaderFactoryGetter>()),
weak_factory_(this) {
scoped_refptr<base::SequencedTaskRunner> database_task_runner =
base::ThreadTaskRunnerHandle::Get();
wrapper_->InitInternal(user_data_directory, std::move(database_task_runner),
nullptr, nullptr, nullptr,
url_loader_factory_getter_.get());
wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id());
wrapper_->process_manager()->SetNewProcessIdForTest(new_render_process_id());
// Install a mocked mojom::Renderer interface to catch requests to
// establish Mojo connection for EWInstanceClient.
mock_renderer_interface_ =
std::make_unique<MockRendererInterface>(AsWeakPtr());
auto renderer_interface_ptr =
std::make_unique<mojom::RendererAssociatedPtr>();
mock_renderer_interface_->AddBinding(
mojo::MakeRequestAssociatedWithDedicatedPipe(
renderer_interface_ptr.get()));
render_process_host_->OverrideRendererInterfaceForTesting(
std::move(renderer_interface_ptr));
auto new_renderer_interface_ptr =
std::make_unique<mojom::RendererAssociatedPtr>();
mock_renderer_interface_->AddBinding(
mojo::MakeRequestAssociatedWithDedicatedPipe(
new_renderer_interface_ptr.get()));
new_render_process_host_->OverrideRendererInterfaceForTesting(
std::move(new_renderer_interface_ptr));
if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
default_network_loader_factory_ =
std::make_unique<MockNetworkURLLoaderFactory>();
SetNetworkFactory(default_network_loader_factory_.get());
}
}
void EmbeddedWorkerTestHelper::SetNetworkFactory(
network::mojom::URLLoaderFactory* factory) {
if (!factory)
factory = default_network_loader_factory_.get();
// Reset factory in URLLoaderFactoryGetter so that we don't hit DCHECK()
// there.
url_loader_factory_getter_->SetNetworkFactoryForTesting(nullptr);
url_loader_factory_getter_->SetNetworkFactoryForTesting(factory);
render_process_host_->OverrideURLLoaderFactory(factory);
new_render_process_host_->OverrideURLLoaderFactory(factory);
}
EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() {
if (wrapper_.get())
wrapper_->Shutdown();
}
void EmbeddedWorkerTestHelper::RegisterMockInstanceClient(
std::unique_ptr<MockEmbeddedWorkerInstanceClient> client) {
mock_instance_clients_.push_back(std::move(client));
}
ServiceWorkerContextCore* EmbeddedWorkerTestHelper::context() {
return wrapper_->context();
}
void EmbeddedWorkerTestHelper::ShutdownContext() {
wrapper_->Shutdown();
wrapper_ = nullptr;
}
// static
net::HttpResponseInfo EmbeddedWorkerTestHelper::CreateHttpResponseInfo() {
net::HttpResponseInfo info;
const char data[] =
"HTTP/1.1 200 OK\0"
"Content-Type: application/javascript\0"
"\0";
info.headers =
new net::HttpResponseHeaders(std::string(data, arraysize(data)));
return info;
}
void EmbeddedWorkerTestHelper::OnStartWorker(
int embedded_worker_id,
int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
MockServiceWorker::Create(AsWeakPtr(), embedded_worker_id,
std::move(service_worker_request));
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id] =
service_worker_version_id;
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id].Bind(
std::move(instance_host));
embedded_worker_id_installed_scripts_info_map_[embedded_worker_id] =
std::move(installed_scripts_info);
ServiceWorkerRemoteProviderEndpoint* provider_endpoint =
&embedded_worker_id_remote_provider_map_[embedded_worker_id];
provider_endpoint->BindWithProviderInfo(std::move(provider_info));
SimulateWorkerReadyForInspection(embedded_worker_id);
SimulateWorkerScriptCached(
embedded_worker_id,
base::BindOnce(&EmbeddedWorkerTestHelper::DidSimulateWorkerScriptCached,
AsWeakPtr(), embedded_worker_id, pause_after_download));
}
void EmbeddedWorkerTestHelper::DidSimulateWorkerScriptCached(
int embedded_worker_id,
bool pause_after_download) {
SimulateWorkerScriptLoaded(embedded_worker_id);
if (!pause_after_download)
OnResumeAfterDownload(embedded_worker_id);
}
void EmbeddedWorkerTestHelper::OnResumeAfterDownload(int embedded_worker_id) {
SimulateScriptEvaluationStart(embedded_worker_id);
SimulateWorkerStarted(
embedded_worker_id,
blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
GetNextThreadId());
}
void EmbeddedWorkerTestHelper::OnStopWorker(int embedded_worker_id) {
// By default just notify the sender that the worker is stopped.
SimulateWorkerStopped(embedded_worker_id);
}
void EmbeddedWorkerTestHelper::OnActivateEvent(
mojom::ServiceWorker::DispatchActivateEventCallback callback) {
dispatched_events()->push_back(Event::Activate);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnInstallEvent(
mojom::ServiceWorker::DispatchInstallEventCallback callback) {
dispatched_events()->push_back(Event::Install);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
true /* has_fetch_handler */, base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
// TODO(falken): In-line common into here.
OnFetchEventCommon(std::move(response_callback), std::move(finish_callback));
}
void EmbeddedWorkerTestHelper::OnPushEvent(
base::Optional<std::string> payload,
mojom::ServiceWorker::DispatchPushEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnNotificationClickEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnNotificationCloseEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) {
response_callback->OnResponseForAbortPayment(true, base::Time::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) {
bool can_make_payment = false;
for (const auto& method_data : event_data->method_data) {
if (method_data->supported_method == "test-method") {
can_make_payment = true;
break;
}
}
response_callback->OnResponseForCanMakePayment(can_make_payment,
base::Time::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) {
response_callback->OnResponseForPaymentRequest(
payments::mojom::PaymentHandlerResponse::New(), base::Time::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnSetIdleTimerDelayToZero(
int embedded_worker_id) {
// Subclasses may implement this method.
}
void EmbeddedWorkerTestHelper::SimulateWorkerReadyForInspection(
int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
->OnReadyForInspection();
base::RunLoop().RunUntilIdle();
}
void EmbeddedWorkerTestHelper::SimulateWorkerScriptCached(
int embedded_worker_id,
base::OnceClosure callback) {
int64_t version_id =
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id];
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
if (!version) {
std::move(callback).Run();
return;
}
if (!version->script_cache_map()->size()) {
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
// Add a dummy ResourceRecord for the main script to the script cache map of
// the ServiceWorkerVersion.
records.push_back(WriteToDiskCacheAsync(
context()->storage(), version->script_url(),
context()->storage()->NewResourceId(), {} /* headers */, "I'm a body",
"I'm a meta data", std::move(callback)));
version->script_cache_map()->SetResources(records);
}
if (!version->GetMainScriptHttpResponseInfo())
version->SetMainScriptHttpResponseInfo(CreateHttpResponseInfo());
// Call |callback| if |version| already has ResourceRecords.
if (!callback.is_null())
std::move(callback).Run();
}
void EmbeddedWorkerTestHelper::SimulateWorkerScriptLoaded(
int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
->OnScriptLoaded();
base::RunLoop().RunUntilIdle();
}
void EmbeddedWorkerTestHelper::SimulateScriptEvaluationStart(
int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
->OnScriptEvaluationStart();
base::RunLoop().RunUntilIdle();
}
void EmbeddedWorkerTestHelper::SimulateWorkerStarted(
int embedded_worker_id,
blink::mojom::ServiceWorkerStartStatus status,
int thread_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStarted(
status, thread_id, mojom::EmbeddedWorkerStartTiming::New());
base::RunLoop().RunUntilIdle();
}
void EmbeddedWorkerTestHelper::SimulateWorkerStopped(int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
if (worker) {
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStopped();
embedded_worker_id_remote_provider_map_.erase(embedded_worker_id);
base::RunLoop().RunUntilIdle();
}
}
void EmbeddedWorkerTestHelper::OnInitializeGlobalScope(
int embedded_worker_id,
blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) {
embedded_worker_id_host_map_[embedded_worker_id].Bind(
std::move(service_worker_host));
// To enable the caller end points to make calls safely with no need to pass
// these associated interface requests through a message pipe endpoint.
mojo::AssociateWithDisconnectedPipe(registration_info->request.PassHandle());
if (registration_info->installing) {
mojo::AssociateWithDisconnectedPipe(
registration_info->installing->request.PassHandle());
}
if (registration_info->waiting) {
mojo::AssociateWithDisconnectedPipe(
registration_info->waiting->request.PassHandle());
}
if (registration_info->active) {
mojo::AssociateWithDisconnectedPipe(
registration_info->active->request.PassHandle());
}
// Keep all Mojo connections alive.
embedded_worker_id_registration_info_map_[embedded_worker_id] =
std::move(registration_info);
}
void EmbeddedWorkerTestHelper::OnStartWorkerStub(
mojom::EmbeddedWorkerStartParamsPtr params) {
EmbeddedWorkerInstance* worker =
registry()->GetWorker(params->embedded_worker_id);
ASSERT_TRUE(worker);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(),
params->embedded_worker_id, params->service_worker_version_id,
params->scope, params->script_url, params->pause_after_download,
std::move(params->service_worker_request),
std::move(params->controller_request),
std::move(params->instance_host), std::move(params->provider_info),
std::move(params->installed_scripts_info)));
}
void EmbeddedWorkerTestHelper::OnResumeAfterDownloadStub(
int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnResumeAfterDownload,
AsWeakPtr(), embedded_worker_id));
}
void EmbeddedWorkerTestHelper::OnStopWorkerStub(int embedded_worker_id) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnStopWorker,
AsWeakPtr(), embedded_worker_id));
}
void EmbeddedWorkerTestHelper::OnActivateEventStub(
mojom::ServiceWorker::DispatchActivateEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnActivateEvent,
AsWeakPtr(), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent,
AsWeakPtr(), developer_id, unique_id, fetches,
std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEventStub(
const std::string& developer_id,
mojom::BackgroundFetchState state,
mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent,
AsWeakPtr(), developer_id, state, std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent,
AsWeakPtr(), developer_id, unique_id, fetches,
std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchedEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent,
AsWeakPtr(), developer_id, unique_id, fetches,
std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnCookieChangeEventStub(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnCookieChangeEvent,
AsWeakPtr(), cookie, cause, std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub(
mojom::ExtendableMessageEventPtr event,
mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent,
AsWeakPtr(), std::move(event), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnInstallEventStub(
mojom::ServiceWorker::DispatchInstallEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent,
AsWeakPtr(), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnFetchEventStub(
int embedded_worker_id,
const network::ResourceRequest& request,
blink::mojom::FetchEventPreloadHandlePtr preload_handle,
blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(),
embedded_worker_id, request, std::move(preload_handle),
std::move(response_callback), std::move(finish_callback)));
}
void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationClickEvent,
AsWeakPtr(), notification_id, notification_data,
action_index, reply, std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationCloseEvent,
AsWeakPtr(), notification_id, notification_data,
std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnPushEventStub(
base::Optional<std::string> payload,
mojom::ServiceWorker::DispatchPushEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnPushEvent, AsWeakPtr(),
std::move(payload), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnAbortPaymentEventStub(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnAbortPaymentEvent,
AsWeakPtr(), std::move(response_callback),
std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnCanMakePaymentEventStub(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnCanMakePaymentEvent,
AsWeakPtr(), std::move(event_data),
std::move(response_callback), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnPaymentRequestEventStub(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnPaymentRequestEvent,
AsWeakPtr(), std::move(event_data),
std::move(response_callback), std::move(callback)));
}
EmbeddedWorkerRegistry* EmbeddedWorkerTestHelper::registry() {
DCHECK(context());
return context()->embedded_worker_registry();
}
} // namespace content