Commit 0b868ca7 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Worker: Factor out the impl of the 'shadow page' concept into its own class

For code cleanup, this CL factors out the implementation of the 'shadow page'
concept from WebEmbeddedWorkerImpl and WebSharedWorkerImpl into
WorkerShadowPage.

<What's the 'shadow page'?>

The 'shadow page' concept was introduced for providing script loading on
out-of-process workers (i.e., SharedWorker and ServiceWorker). Loading
components are strongly associated with frames, but such the workers don't have
frames. The 'shadow page' provides a virtual frame to them.

Bug: 500856
Change-Id: I0e4cbbbf5ca784ac04b6a50e54689f141e9cb890
Reviewed-on: https://chromium-review.googlesource.com/593527
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491284}
parent 49d1e1f8
...@@ -93,6 +93,8 @@ blink_core_sources("exported") { ...@@ -93,6 +93,8 @@ blink_core_sources("exported") {
"WebViewBase.h", "WebViewBase.h",
"WebViewImpl.cpp", "WebViewImpl.cpp",
"WebViewImpl.h", "WebViewImpl.h",
"WorkerShadowPage.cpp",
"WorkerShadowPage.h",
] ]
jumbo_excluded_sources = [ jumbo_excluded_sources = [
......
...@@ -35,17 +35,15 @@ ...@@ -35,17 +35,15 @@
#include <memory> #include <memory>
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "core/dom/ExecutionContext.h" #include "core/exported/WorkerShadowPage.h"
#include "core/workers/SharedWorkerReportingProxy.h" #include "core/workers/SharedWorkerReportingProxy.h"
#include "core/workers/WorkerClients.h" #include "core/workers/WorkerClients.h"
#include "core/workers/WorkerThread.h" #include "core/workers/WorkerThread.h"
#include "platform/WebTaskRunner.h" #include "platform/WebTaskRunner.h"
#include "platform/wtf/RefPtr.h" #include "platform/wtf/RefPtr.h"
#include "public/platform/Platform.h"
#include "public/platform/WebAddressSpace.h" #include "public/platform/WebAddressSpace.h"
#include "public/platform/WebContentSecurityPolicy.h" #include "public/platform/WebContentSecurityPolicy.h"
#include "public/web/WebDevToolsAgentClient.h" #include "public/web/WebDevToolsAgentClient.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebSharedWorkerClient.h" #include "public/web/WebSharedWorkerClient.h"
#include "public/web/shared_worker_content_settings_proxy.mojom-blink.h" #include "public/web/shared_worker_content_settings_proxy.mojom-blink.h"
...@@ -53,12 +51,10 @@ namespace blink { ...@@ -53,12 +51,10 @@ namespace blink {
class WebApplicationCacheHost; class WebApplicationCacheHost;
class WebApplicationCacheHostClient; class WebApplicationCacheHostClient;
class WebLocalFrameBase;
class WebServiceWorkerNetworkProvider; class WebServiceWorkerNetworkProvider;
class WebSharedWorkerClient; class WebSharedWorkerClient;
class WebString; class WebString;
class WebURL; class WebURL;
class WebView;
class WorkerInspectorProxy; class WorkerInspectorProxy;
class WorkerScriptLoader; class WorkerScriptLoader;
...@@ -66,19 +62,15 @@ class WorkerScriptLoader; ...@@ -66,19 +62,15 @@ class WorkerScriptLoader;
// implementation. This is basically accessed on the main thread, but some // implementation. This is basically accessed on the main thread, but some
// methods must be called from a worker thread. Such methods are suffixed with // methods must be called from a worker thread. Such methods are suffixed with
// *OnWorkerThread or have header comments. // *OnWorkerThread or have header comments.
class CORE_EXPORT WebSharedWorkerImpl final class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker,
: public WebFrameClient, public WorkerShadowPage::Client {
public WebSharedWorker,
NON_EXPORTED_BASE(public WebDevToolsAgentClient) {
public: public:
explicit WebSharedWorkerImpl(WebSharedWorkerClient*); explicit WebSharedWorkerImpl(WebSharedWorkerClient*);
// WebFrameClient methods to support resource loading thru the 'shadow page'. // WorkerShadowPage::Client overrides.
std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost( std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
WebApplicationCacheHostClient*) override; WebApplicationCacheHostClient*) override;
void FrameDetached(WebLocalFrame*, DetachType) override; void OnShadowPageInitialized() override;
void DidFinishDocumentLoad() override;
service_manager::InterfaceProvider* GetInterfaceProvider() override;
// WebDevToolsAgentClient overrides. // WebDevToolsAgentClient overrides.
void SendProtocolMessage(int session_id, void SendProtocolMessage(int session_id,
...@@ -112,13 +104,6 @@ class CORE_EXPORT WebSharedWorkerImpl final ...@@ -112,13 +104,6 @@ class CORE_EXPORT WebSharedWorkerImpl final
const WebString& method, const WebString& method,
const WebString& message) override; const WebString& message) override;
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const WebURLRequest& request,
SingleThreadTaskRunner* task_runner) override {
// TODO(yhirano): Stop using Platform::CreateURLLoader() here.
return Platform::Current()->CreateURLLoader(request, task_runner);
}
// Callback methods for SharedWorkerReportingProxy. // Callback methods for SharedWorkerReportingProxy.
void CountFeature(WebFeature); void CountFeature(WebFeature);
void PostMessageToPageInspector(int session_id, const String& message); void PostMessageToPageInspector(int session_id, const String& message);
...@@ -133,22 +118,12 @@ class CORE_EXPORT WebSharedWorkerImpl final ...@@ -133,22 +118,12 @@ class CORE_EXPORT WebSharedWorkerImpl final
// Shuts down the worker thread. // Shuts down the worker thread.
void TerminateWorkerThread(); void TerminateWorkerThread();
// Creates the shadow loader used for worker network requests.
void InitializeLoader(bool data_saver_enabled);
void LoadShadowPage();
void DidReceiveScriptLoaderResponse(); void DidReceiveScriptLoaderResponse();
void OnScriptLoaderFinished(); void OnScriptLoaderFinished();
void ConnectTaskOnWorkerThread(std::unique_ptr<WebMessagePortChannel>); void ConnectTaskOnWorkerThread(std::unique_ptr<WebMessagePortChannel>);
// 'shadow page' - created to proxy loading requests from the worker. std::unique_ptr<WorkerShadowPage> shadow_page_;
// Will be accessed by worker thread when posting tasks.
Persistent<ExecutionContext> loading_document_;
Persistent<ThreadableLoadingContext> loading_context_;
WebView* web_view_;
Persistent<WebLocalFrameBase> main_frame_;
bool asked_to_terminate_;
std::unique_ptr<WebServiceWorkerNetworkProvider> network_provider_; std::unique_ptr<WebServiceWorkerNetworkProvider> network_provider_;
...@@ -156,13 +131,13 @@ class CORE_EXPORT WebSharedWorkerImpl final ...@@ -156,13 +131,13 @@ class CORE_EXPORT WebSharedWorkerImpl final
Persistent<SharedWorkerReportingProxy> reporting_proxy_; Persistent<SharedWorkerReportingProxy> reporting_proxy_;
std::unique_ptr<WorkerThread> worker_thread_; std::unique_ptr<WorkerThread> worker_thread_;
service_manager::InterfaceProvider interface_provider_;
mojom::blink::SharedWorkerContentSettingsProxyPtrInfo content_settings_info_; mojom::blink::SharedWorkerContentSettingsProxyPtrInfo content_settings_info_;
WebSharedWorkerClient* client_; WebSharedWorkerClient* client_;
bool pause_worker_context_on_start_; bool asked_to_terminate_ = false;
bool is_paused_on_start_; bool pause_worker_context_on_start_ = false;
bool is_paused_on_start_ = false;
// Kept around only while main script loading is ongoing. // Kept around only while main script loading is ongoing.
RefPtr<WorkerScriptLoader> main_script_loader_; RefPtr<WorkerScriptLoader> main_script_loader_;
......
// Copyright 2017 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 "core/exported/WorkerShadowPage.h"
#include "core/exported/WebViewImpl.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "public/platform/Platform.h"
#include "public/web/WebSettings.h"
namespace blink {
WorkerShadowPage::WorkerShadowPage(Client* client)
: web_view_(WebViewImpl::Create(nullptr, kWebPageVisibilityStateVisible)),
main_frame_(WebLocalFrameImpl::CreateMainFrame(web_view_,
this,
nullptr,
nullptr,
g_empty_atom,
WebSandboxFlags::kNone)),
client_(client) {
DCHECK(IsMainThread());
// TODO(http://crbug.com/363843): This needs to find a better way to
// not create graphics layers.
web_view_->GetSettings()->SetAcceleratedCompositingEnabled(false);
main_frame_->SetDevToolsAgentClient(client_);
// Create an empty InterfaceProvider because WebFrameClient subclasses are
// required to do it even if it's not used.
// See https://chromium-review.googlesource.com/c/576370
service_manager::mojom::InterfaceProviderPtr provider;
mojo::MakeRequest(&provider);
interface_provider_.Bind(std::move(provider));
}
WorkerShadowPage::~WorkerShadowPage() {
DCHECK(IsMainThread());
// Detach the client before closing the view to avoid getting called back.
main_frame_->SetClient(nullptr);
web_view_->Close();
main_frame_->Close();
}
void WorkerShadowPage::Initialize(const KURL& script_url) {
DCHECK(IsMainThread());
AdvanceState(State::kInitializing);
// Construct substitute data source. We only need it to have same origin as
// the worker so the loading checks work correctly.
CString content("");
RefPtr<SharedBuffer> buffer(
SharedBuffer::Create(content.data(), content.length()));
main_frame_->GetFrame()->Loader().Load(
FrameLoadRequest(0, ResourceRequest(script_url), SubstituteData(buffer)));
}
void WorkerShadowPage::SetContentSecurityPolicyAndReferrerPolicy(
ContentSecurityPolicyResponseHeaders csp_headers,
String referrer_policy) {
DCHECK(IsMainThread());
Document* document = main_frame_->GetFrame()->GetDocument();
ContentSecurityPolicy* content_security_policy =
ContentSecurityPolicy::Create();
content_security_policy->SetOverrideURLForSelf(document->Url());
content_security_policy->DidReceiveHeaders(csp_headers);
document->InitContentSecurityPolicy(content_security_policy);
if (!referrer_policy.IsNull())
document->ParseAndSetReferrerPolicy(referrer_policy);
}
void WorkerShadowPage::DidFinishDocumentLoad() {
DCHECK(IsMainThread());
AdvanceState(State::kInitialized);
client_->OnShadowPageInitialized();
}
std::unique_ptr<WebApplicationCacheHost>
WorkerShadowPage::CreateApplicationCacheHost(
WebApplicationCacheHostClient* appcache_host_client) {
DCHECK(IsMainThread());
return client_->CreateApplicationCacheHost(appcache_host_client);
}
void WorkerShadowPage::FrameDetached(WebLocalFrame* frame, DetachType type) {
DCHECK(IsMainThread());
DCHECK(type == DetachType::kRemove && frame->Parent());
DCHECK(frame->FrameWidget());
frame->Close();
}
service_manager::InterfaceProvider* WorkerShadowPage::GetInterfaceProvider() {
DCHECK(IsMainThread());
return &interface_provider_;
}
std::unique_ptr<blink::WebURLLoader> WorkerShadowPage::CreateURLLoader(
const WebURLRequest& request,
SingleThreadTaskRunner* task_runner) {
DCHECK(IsMainThread());
// TODO(yhirano): Stop using Platform::CreateURLLoader() here.
return Platform::Current()->CreateURLLoader(request, task_runner);
}
bool WorkerShadowPage::WasInitialized() const {
return state_ == State::kInitialized;
}
void WorkerShadowPage::AdvanceState(State new_state) {
switch (new_state) {
case State::kUninitialized:
NOTREACHED();
return;
case State::kInitializing:
DCHECK_EQ(State::kUninitialized, state_);
state_ = new_state;
return;
case State::kInitialized:
DCHECK_EQ(State::kInitializing, state_);
state_ = new_state;
return;
}
}
} // namespace blink
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WorkerShadowPage_h
#define WorkerShadowPage_h
#include "core/frame/WebLocalFrameImpl.h"
#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
#include "public/web/WebDevToolsAgentClient.h"
#include "public/web/WebDocumentLoader.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebView.h"
#include "services/service_manager/public/cpp/interface_provider.h"
namespace blink {
class WebApplicationCacheHost;
class WebApplicationCacheHostClient;
class WebSettings;
// WorkerShadowPage implements the 'shadow page' concept.
//
// Loading components are strongly associated with frames, but out-of-process
// workers (i.e., SharedWorker and ServiceWorker) don't have frames. To enable
// loading on such workers, this class provides a virtual frame (a.k.a, shadow
// page) to them.
//
// WorkerShadowPage lives on the main thread.
//
// TODO(nhiroki): Move this into core/workers once all dependencies on
// core/exported are gone (now depending on core/exported/WebViewImpl.h in
// *.cpp).
// TODO(kinuko): Make this go away (https://crbug.com/538751).
class CORE_EXPORT WorkerShadowPage : public WebFrameClient {
public:
class CORE_EXPORT Client : NON_EXPORTED_BASE(public WebDevToolsAgentClient) {
public:
virtual ~Client() {}
// Called when the shadow page is requested to create an application cache
// host.
virtual std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
WebApplicationCacheHostClient*) = 0;
// Called when Initialize() is completed.
virtual void OnShadowPageInitialized() = 0;
};
explicit WorkerShadowPage(Client*);
~WorkerShadowPage() override;
// Calls Client::OnShadowPageInitialized() when complete.
void Initialize(const KURL& script_url);
void SetContentSecurityPolicyAndReferrerPolicy(
ContentSecurityPolicyResponseHeaders csp_headers,
String referrer_policy);
// WebFrameClient overrides.
std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
WebApplicationCacheHostClient*) override;
void FrameDetached(WebLocalFrame*, DetachType) override;
void DidFinishDocumentLoad() override;
service_manager::InterfaceProvider* GetInterfaceProvider() override;
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const WebURLRequest&,
SingleThreadTaskRunner*) override;
Document* GetDocument() { return main_frame_->GetFrame()->GetDocument(); }
WebSettings* GetSettings() { return web_view_->GetSettings(); }
WebDocumentLoader* DocumentLoader() {
return main_frame_->GetDocumentLoader();
}
WebDevToolsAgent* DevToolsAgent() { return main_frame_->DevToolsAgent(); }
bool WasInitialized() const;
private:
enum class State { kUninitialized, kInitializing, kInitialized };
void AdvanceState(State);
WebView* web_view_;
Persistent<WebLocalFrameImpl> main_frame_;
Client* client_;
service_manager::InterfaceProvider interface_provider_;
State state_ = State::kUninitialized;
};
} // namespace blink
#endif // WorkerShadowPage_h
...@@ -32,35 +32,30 @@ ...@@ -32,35 +32,30 @@
#define WebEmbeddedWorkerImpl_h #define WebEmbeddedWorkerImpl_h
#include <memory> #include <memory>
#include "core/frame/csp/ContentSecurityPolicy.h" #include "core/exported/WorkerShadowPage.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/WorkerClients.h" #include "core/workers/WorkerClients.h"
#include "modules/ModulesExport.h" #include "modules/ModulesExport.h"
#include "platform/WebTaskRunner.h" #include "platform/WebTaskRunner.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "public/platform/Platform.h"
#include "public/platform/WebContentSecurityPolicy.h" #include "public/platform/WebContentSecurityPolicy.h"
#include "public/web/WebDevToolsAgentClient.h" #include "public/web/WebDevToolsAgentClient.h"
#include "public/web/WebEmbeddedWorker.h" #include "public/web/WebEmbeddedWorker.h"
#include "public/web/WebEmbeddedWorkerStartData.h" #include "public/web/WebEmbeddedWorkerStartData.h"
#include "public/web/WebFrameClient.h"
#include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_provider.h"
namespace blink { namespace blink {
class ThreadableLoadingContext;
class ServiceWorkerGlobalScopeProxy; class ServiceWorkerGlobalScopeProxy;
class ServiceWorkerInstalledScriptsManager; class ServiceWorkerInstalledScriptsManager;
class WaitableEvent; class WaitableEvent;
class WebLocalFrameBase;
class WebView;
class WorkerInspectorProxy; class WorkerInspectorProxy;
class WorkerScriptLoader; class WorkerScriptLoader;
class WorkerThread; class WorkerThread;
class MODULES_EXPORT WebEmbeddedWorkerImpl final class MODULES_EXPORT WebEmbeddedWorkerImpl final
: public WebEmbeddedWorker, : public WebEmbeddedWorker,
public WebFrameClient, public WorkerShadowPage::Client {
NON_EXPORTED_BASE(public WebDevToolsAgentClient) {
WTF_MAKE_NONCOPYABLE(WebEmbeddedWorkerImpl); WTF_MAKE_NONCOPYABLE(WebEmbeddedWorkerImpl);
public: public:
...@@ -96,22 +91,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final ...@@ -96,22 +91,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
ContentSecurityPolicyResponseHeaders, ContentSecurityPolicyResponseHeaders,
WTF::String referrer_policy, WTF::String referrer_policy,
WaitableEvent*); WaitableEvent*);
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const WebURLRequest& request,
SingleThreadTaskRunner* task_runner) override {
// TODO(yhirano): Stop using Platform::CreateURLLoader() here.
return Platform::Current()->CreateURLLoader(request, task_runner);
}
private: // WorkerShadowPage::Client overrides.
void PrepareShadowPageForLoader(); std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
void LoadShadowPage(); WebApplicationCacheHostClient*) override;
void OnShadowPageInitialized() override;
// WebFrameClient overrides.
void FrameDetached(WebLocalFrame*, DetachType) override;
void DidFinishDocumentLoad() override;
service_manager::InterfaceProvider* GetInterfaceProvider() override;
private:
// WebDevToolsAgentClient overrides. // WebDevToolsAgentClient overrides.
void SendProtocolMessage(int session_id, void SendProtocolMessage(int session_id,
int call_id, int call_id,
...@@ -128,17 +114,12 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final ...@@ -128,17 +114,12 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
std::unique_ptr<WebServiceWorkerContextClient> worker_context_client_; std::unique_ptr<WebServiceWorkerContextClient> worker_context_client_;
// This is valid until the worker thread is created. After the worker thread // These are valid until StartWorkerThread() is called. After the worker
// is created, this is passed to the worker thread. // thread is created, these are passed to the worker thread.
std::unique_ptr<ServiceWorkerInstalledScriptsManager> std::unique_ptr<ServiceWorkerInstalledScriptsManager>
installed_scripts_manager_; installed_scripts_manager_;
// This is kept until startWorkerContext is called, and then passed on
// to WorkerContext.
std::unique_ptr<WebContentSettingsClient> content_settings_client_; std::unique_ptr<WebContentSettingsClient> content_settings_client_;
service_manager::InterfaceProvider interface_provider_;
// Kept around only while main script loading is ongoing. // Kept around only while main script loading is ongoing.
RefPtr<WorkerScriptLoader> main_script_loader_; RefPtr<WorkerScriptLoader> main_script_loader_;
...@@ -146,17 +127,9 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final ...@@ -146,17 +127,9 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
Persistent<ServiceWorkerGlobalScopeProxy> worker_global_scope_proxy_; Persistent<ServiceWorkerGlobalScopeProxy> worker_global_scope_proxy_;
Persistent<WorkerInspectorProxy> worker_inspector_proxy_; Persistent<WorkerInspectorProxy> worker_inspector_proxy_;
// 'shadow page' - created to proxy loading requests from the worker. std::unique_ptr<WorkerShadowPage> shadow_page_;
// Both WebView and WebFrame objects are close()'ed (where they're
// deref'ed) when this EmbeddedWorkerImpl is destructed, therefore they
// are guaranteed to exist while this object is around.
WebView* web_view_;
Persistent<WebLocalFrameBase> main_frame_;
Persistent<ThreadableLoadingContext> loading_context_;
bool loading_shadow_page_; bool asked_to_terminate_ = false;
bool asked_to_terminate_;
enum WaitingForDebuggerState { kWaitingForDebugger, kNotWaitingForDebugger }; enum WaitingForDebuggerState { kWaitingForDebugger, kNotWaitingForDebugger };
......
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