| Index: content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| index 2d892c777cd8f1f80c8682fdef1efef486a850ab..3e3b15e392e3c6730cd1d91ed9c77f613d7a49b8 100644
|
| --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
|
| @@ -11,6 +11,8 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/time/time.h"
|
| #include "base/trace_event/trace_event.h"
|
| +#include "content/browser/devtools/service_worker_devtools_agent_host.h"
|
| +#include "content/browser/devtools/service_worker_devtools_manager.h"
|
| #include "content/browser/loader/resource_dispatcher_host_impl.h"
|
| #include "content/browser/loader/resource_request_info_impl.h"
|
| #include "content/browser/loader/resource_requester_info.h"
|
| @@ -23,6 +25,7 @@
|
| #include "content/common/service_worker/service_worker_status_code.h"
|
| #include "content/common/service_worker/service_worker_types.h"
|
| #include "content/common/service_worker/service_worker_utils.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| #include "content/public/common/browser_side_navigation_policy.h"
|
| #include "mojo/public/cpp/bindings/associated_binding.h"
|
| #include "mojo/public/cpp/bindings/binding.h"
|
| @@ -68,16 +71,56 @@ class DelegatingURLLoader final : public mojom::URLLoader {
|
| DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoader);
|
| };
|
|
|
| +ServiceWorkerDevToolsAgentHost* GetAgentHost(
|
| + const std::pair<int, int>& worker_id) {
|
| + return ServiceWorkerDevToolsManager::GetInstance()
|
| + ->GetDevToolsAgentHostForWorker(worker_id.first, worker_id.second);
|
| +}
|
| +
|
| +void NotifyNavigationPreloadRequestSentOnUI(
|
| + const ResourceRequest& request,
|
| + const std::pair<int, int>& worker_id,
|
| + const std::string& request_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + if (ServiceWorkerDevToolsAgentHost* agent_host = GetAgentHost(worker_id))
|
| + agent_host->NavigationPreloadRequestSent(request_id, request);
|
| +}
|
| +
|
| +void NotifyNavigationPreloadResponseReceivedOnUI(
|
| + const GURL& url,
|
| + const ResourceResponseHead& head,
|
| + const std::pair<int, int>& worker_id,
|
| + const std::string& request_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + if (ServiceWorkerDevToolsAgentHost* agent_host = GetAgentHost(worker_id))
|
| + agent_host->NavigationPreloadResponseReceived(request_id, url, head);
|
| +}
|
| +
|
| +void NotifyNavigationPreloadCompletedOnUI(
|
| + const ResourceRequestCompletionStatus& completion_status,
|
| + const std::pair<int, int>& worker_id,
|
| + const std::string& request_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + if (ServiceWorkerDevToolsAgentHost* agent_host = GetAgentHost(worker_id))
|
| + agent_host->NavigationPreloadCompleted(request_id, completion_status);
|
| +}
|
| +
|
| // This class wraps a mojo::InterfacePtr<URLLoaderClient>. It also is a
|
| // URLLoaderClient implementation and delegates URLLoaderClient calls to the
|
| // wrapped client.
|
| class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| public:
|
| + using WorkerId = std::pair<int, int>;
|
| explicit DelegatingURLLoaderClient(mojom::URLLoaderClientPtr client,
|
| - base::OnceClosure on_response)
|
| + base::OnceClosure on_response,
|
| + const ResourceRequest& request)
|
| : binding_(this),
|
| client_(std::move(client)),
|
| - on_response_(std::move(on_response)) {}
|
| + on_response_(std::move(on_response)),
|
| + url_(request.url) {
|
| + AddDevToolsCallback(
|
| + base::Bind(&NotifyNavigationPreloadRequestSentOnUI, request));
|
| + }
|
| ~DelegatingURLLoaderClient() override {
|
| if (!completed_) {
|
| // Let the service worker know that the request has been canceled.
|
| @@ -87,6 +130,12 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| }
|
| }
|
|
|
| + void MayBeReportToDevTools(WorkerId worker_id, int fetch_event_id) {
|
| + worker_id_ = worker_id;
|
| + devtools_request_id_ = base::StringPrintf("preload-%d", fetch_event_id);
|
| + MayBeRunDevToolsCallbacks();
|
| + }
|
| +
|
| void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
|
| client_->OnDataDownloaded(data_length, encoded_length);
|
| }
|
| @@ -107,6 +156,8 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| client_->OnReceiveResponse(head, std::move(downloaded_file));
|
| DCHECK(on_response_);
|
| std::move(on_response_).Run();
|
| + AddDevToolsCallback(
|
| + base::Bind(&NotifyNavigationPreloadResponseReceivedOnUI, url_, head));
|
| }
|
| void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
|
| const ResourceResponseHead& head) override {
|
| @@ -120,6 +171,8 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| const ResourceRequestCompletionStatus& completion_status) override {
|
| client_->OnComplete(completion_status);
|
| completed_ = true;
|
| + AddDevToolsCallback(
|
| + base::Bind(&NotifyNavigationPreloadCompletedOnUI, completion_status));
|
| }
|
|
|
| void Bind(mojom::URLLoaderClientAssociatedPtrInfo* ptr_info,
|
| @@ -128,11 +181,32 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
|
| }
|
|
|
| private:
|
| + void MayBeRunDevToolsCallbacks() {
|
| + if (!worker_id_)
|
| + return;
|
| + while (!devtools_callbacks.empty()) {
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(std::move(devtools_callbacks.front()),
|
| + *worker_id_, devtools_request_id_));
|
| + devtools_callbacks.pop();
|
| + }
|
| + }
|
| + void AddDevToolsCallback(
|
| + base::Callback<void(const WorkerId&, const std::string&)> callback) {
|
| + devtools_callbacks.push(callback);
|
| + MayBeRunDevToolsCallbacks();
|
| + }
|
| +
|
| mojo::AssociatedBinding<mojom::URLLoaderClient> binding_;
|
| mojom::URLLoaderClientPtr client_;
|
| base::OnceClosure on_response_;
|
| bool completed_ = false;
|
| + const GURL url_;
|
|
|
| + base::Optional<std::pair<int, int>> worker_id_;
|
| + std::string devtools_request_id_;
|
| + std::queue<base::Callback<void(const WorkerId&, const std::string&)>>
|
| + devtools_callbacks;
|
| DISALLOW_COPY_AND_ASSIGN(DelegatingURLLoaderClient);
|
| };
|
|
|
| @@ -226,18 +300,23 @@ class ServiceWorkerFetchDispatcher::URLLoaderAssets
|
| public:
|
| URLLoaderAssets(mojom::URLLoaderFactoryPtr url_loader_factory,
|
| std::unique_ptr<mojom::URLLoader> url_loader,
|
| - std::unique_ptr<mojom::URLLoaderClient> url_loader_client)
|
| + std::unique_ptr<DelegatingURLLoaderClient> url_loader_client)
|
| : url_loader_factory_(std::move(url_loader_factory)),
|
| url_loader_(std::move(url_loader)),
|
| url_loader_client_(std::move(url_loader_client)) {}
|
|
|
| + void MayBeReportToDevTools(std::pair<int, int> worker_id,
|
| + int fetch_event_id) {
|
| + url_loader_client_->MayBeReportToDevTools(worker_id, fetch_event_id);
|
| + }
|
| +
|
| private:
|
| friend class base::RefCounted<URLLoaderAssets>;
|
| virtual ~URLLoaderAssets() {}
|
|
|
| mojom::URLLoaderFactoryPtr url_loader_factory_;
|
| std::unique_ptr<mojom::URLLoader> url_loader_;
|
| - std::unique_ptr<mojom::URLLoaderClient> url_loader_client_;
|
| + std::unique_ptr<DelegatingURLLoaderClient> url_loader_client_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(URLLoaderAssets);
|
| };
|
| @@ -364,6 +443,14 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
|
| base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run,
|
| base::Owned(response_callback)));
|
|
|
| + if (url_loader_assets_) {
|
| + url_loader_assets_->MayBeReportToDevTools(
|
| + std::make_pair(
|
| + version_->embedded_worker()->process_id(),
|
| + version_->embedded_worker()->worker_devtools_agent_route_id()),
|
| + fetch_event_id);
|
| + }
|
| +
|
| // |event_dispatcher| is owned by |version_|. So it is safe to pass the
|
| // unretained raw pointer of |version_| to OnFetchEventFinished callback.
|
| // Pass |url_loader_assets_| to the callback to keep the URL loader related
|
| @@ -472,6 +559,8 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
|
| request.render_frame_id = original_info->GetRenderFrameID();
|
| request.is_main_frame = original_info->IsMainFrame();
|
| request.parent_is_main_frame = original_info->ParentIsMainFrame();
|
| + request.enable_load_timing = original_info->is_load_timing_enabled();
|
| + request.report_raw_headers = original_info->ShouldReportRawHeaders();
|
|
|
| DCHECK(net::HttpUtil::IsValidHeaderValue(
|
| version_->navigation_preload_state().header));
|
| @@ -489,7 +578,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
|
| preload_handle_->url_loader_client_request =
|
| mojo::MakeRequest(&url_loader_client_ptr);
|
| auto url_loader_client = base::MakeUnique<DelegatingURLLoaderClient>(
|
| - std::move(url_loader_client_ptr), std::move(on_response));
|
| + std::move(url_loader_client_ptr), std::move(on_response), request);
|
| mojom::URLLoaderClientAssociatedPtrInfo url_loader_client_associated_ptr_info;
|
| url_loader_client->Bind(&url_loader_client_associated_ptr_info,
|
| url_loader_factory.associated_group());
|
|
|