Commit 2e83a107 authored by rajendrant's avatar rajendrant Committed by Commit Bot

Report transfer size updates, resource starts and completes to chrome

Background:
Currently page load metrics tracks data usage when requests complete.
This misses canceled requests when the tab closes. The current codepath
will also deprecated due to the upcoming network servicification work.

This CL reports the continuous data use to page load metrics in renderer.
Response starts and completions are reported as well so that the observer
can keep track of data per resource. Subsequent CLs will send this to
browser process via the existing PageLoadMetrics mojo.

Bug: 836029
Change-Id: I023ea08b2b8f1974ea40586afeee3a27b9900782
Reviewed-on: https://chromium-review.googlesource.com/1042795
Commit-Queue: rajendrant <rajendrant@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568353}
parent 8828e090
...@@ -85,6 +85,20 @@ void MetricsRenderFrameObserver::DidObserveNewCssPropertyUsage( ...@@ -85,6 +85,20 @@ void MetricsRenderFrameObserver::DidObserveNewCssPropertyUsage(
} }
} }
void MetricsRenderFrameObserver::DidStartResponse(
int request_id,
const network::ResourceResponseHead& response_head) {}
void MetricsRenderFrameObserver::DidCompleteResponse(
int request_id,
const network::URLLoaderCompletionStatus& status) {}
void MetricsRenderFrameObserver::DidCancelResponse(int request_id) {}
void MetricsRenderFrameObserver::DidReceiveTransferSizeUpdate(
int request_id,
int received_data_length) {}
void MetricsRenderFrameObserver::FrameDetached() { void MetricsRenderFrameObserver::FrameDetached() {
page_timing_metrics_sender_.reset(); page_timing_metrics_sender_.reset();
} }
......
...@@ -38,6 +38,15 @@ class MetricsRenderFrameObserver : public content::RenderFrameObserver { ...@@ -38,6 +38,15 @@ class MetricsRenderFrameObserver : public content::RenderFrameObserver {
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override; void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
void DidObserveNewCssPropertyUsage(int css_property, void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) override; bool is_animated) override;
void DidStartResponse(
int request_id,
const network::ResourceResponseHead& response_head) override;
void DidReceiveTransferSizeUpdate(int request_id,
int received_data_length) override;
void DidCompleteResponse(
int request_id,
const network::URLLoaderCompletionStatus& status) override;
void DidCancelResponse(int request_id) override;
void DidCommitProvisionalLoad(bool is_new_navigation, void DidCommitProvisionalLoad(bool is_new_navigation,
bool is_same_document_navigation) override; bool is_same_document_navigation) override;
void OnDestruct() override; void OnDestruct() override;
......
...@@ -30,6 +30,11 @@ struct WebURLError; ...@@ -30,6 +30,11 @@ struct WebURLError;
class WebWorkerFetchContext; class WebWorkerFetchContext;
} }
namespace network {
struct ResourceResponseHead;
struct URLLoaderCompletionStatus;
} // namespace network
namespace content { namespace content {
class RendererPpapiHost; class RendererPpapiHost;
...@@ -123,6 +128,24 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener, ...@@ -123,6 +128,24 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidObserveNewCssPropertyUsage(int css_property, virtual void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) {} bool is_animated) {}
// Notification when the renderer a response started, completed or canceled.
// Complete or Cancel is guaranteed to be called for a response that started.
// |request_id| uniquely identifies the request within this render frame.
virtual void DidStartResponse(
int request_id,
const network::ResourceResponseHead& response_head) {}
virtual void DidCompleteResponse(
int request_id,
const network::URLLoaderCompletionStatus& status) {}
virtual void DidCancelResponse(int request_id) {}
// Notification when the renderer observes data used during the page load.
// This is used for page load metrics. |received_data_length| is the received
// network bytes. |resource_id| uniquely identifies the resource within this
// render frame.
virtual void DidReceiveTransferSizeUpdate(int resource_id,
int received_data_length) {}
// Called when the focused node has changed to |node|. // Called when the focused node has changed to |node|.
virtual void FocusedNodeChanged(const blink::WebNode& node) {} virtual void FocusedNodeChanged(const blink::WebNode& node) {}
......
...@@ -96,10 +96,34 @@ void NotifySubresourceStarted( ...@@ -96,10 +96,34 @@ void NotifySubresourceStarted(
render_frame->GetFrameHost()->SubresourceResponseStarted(url, cert_status); render_frame->GetFrameHost()->SubresourceResponseStarted(url, cert_status);
} }
void NotifyResourceLoadStarted(
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
int render_frame_id,
int request_id,
const network::ResourceResponseHead& response_head) {
if (!thread_task_runner)
return;
if (!thread_task_runner->BelongsToCurrentThread()) {
thread_task_runner->PostTask(
FROM_HERE, base::BindOnce(NotifyResourceLoadStarted, thread_task_runner,
render_frame_id, request_id, response_head));
return;
}
RenderFrameImpl* render_frame =
RenderFrameImpl::FromRoutingID(render_frame_id);
if (!render_frame)
return;
render_frame->DidStartResponse(request_id, response_head);
}
void NotifyResourceLoadComplete( void NotifyResourceLoadComplete(
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner, scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
int render_frame_id, int render_frame_id,
mojom::ResourceLoadInfoPtr resource_load_info) { mojom::ResourceLoadInfoPtr resource_load_info,
const network::URLLoaderCompletionStatus& status) {
if (!thread_task_runner) if (!thread_task_runner)
return; return;
...@@ -107,7 +131,7 @@ void NotifyResourceLoadComplete( ...@@ -107,7 +131,7 @@ void NotifyResourceLoadComplete(
thread_task_runner->PostTask( thread_task_runner->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(NotifyResourceLoadComplete, thread_task_runner, base::BindOnce(NotifyResourceLoadComplete, thread_task_runner,
render_frame_id, std::move(resource_load_info))); render_frame_id, std::move(resource_load_info), status));
return; return;
} }
...@@ -116,10 +140,57 @@ void NotifyResourceLoadComplete( ...@@ -116,10 +140,57 @@ void NotifyResourceLoadComplete(
if (!render_frame) if (!render_frame)
return; return;
render_frame->DidCompleteResponse(resource_load_info->request_id, status);
render_frame->GetFrameHost()->ResourceLoadComplete( render_frame->GetFrameHost()->ResourceLoadComplete(
std::move(resource_load_info)); std::move(resource_load_info));
} }
void NotifyResourceLoadCancel(
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
int render_frame_id,
int request_id) {
if (!thread_task_runner)
return;
if (!thread_task_runner->BelongsToCurrentThread()) {
thread_task_runner->PostTask(
FROM_HERE, base::BindOnce(NotifyResourceLoadCancel, thread_task_runner,
render_frame_id, request_id));
return;
}
RenderFrameImpl* render_frame =
RenderFrameImpl::FromRoutingID(render_frame_id);
if (!render_frame)
return;
render_frame->DidCancelResponse(request_id);
}
void NotifyResourceTransferSizeUpdate(
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
int render_frame_id,
int request_id,
int transfer_size_diff) {
if (!thread_task_runner)
return;
if (!thread_task_runner->BelongsToCurrentThread()) {
thread_task_runner->PostTask(
FROM_HERE,
base::BindOnce(NotifyResourceTransferSizeUpdate, thread_task_runner,
render_frame_id, request_id, transfer_size_diff));
return;
}
RenderFrameImpl* render_frame =
RenderFrameImpl::FromRoutingID(render_frame_id);
if (!render_frame)
return;
render_frame->DidReceiveTransferSizeUpdate(request_id, transfer_size_diff);
}
// Returns true if the headers indicate that this resource should always be // Returns true if the headers indicate that this resource should always be
// revalidated or not cached. // revalidated or not cached.
bool AlwaysAccessNetwork( bool AlwaysAccessNetwork(
...@@ -232,6 +303,14 @@ void ResourceDispatcher::OnReceivedResponse( ...@@ -232,6 +303,14 @@ void ResourceDispatcher::OnReceivedResponse(
} }
request_info->peer->OnReceivedResponse(renderer_response_info); request_info->peer->OnReceivedResponse(renderer_response_info);
// Make a deep copy of ResourceResponseHead before passing it cross-thread.
auto resource_response = base::MakeRefCounted<network::ResourceResponse>();
resource_response->head = response_head;
auto deep_copied_response = resource_response->DeepCopy();
NotifyResourceLoadStarted(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id, request_id,
deep_copied_response->head);
} }
void ResourceDispatcher::OnReceivedCachedMetadata( void ResourceDispatcher::OnReceivedCachedMetadata(
...@@ -322,6 +401,7 @@ void ResourceDispatcher::OnRequestComplete( ...@@ -322,6 +401,7 @@ void ResourceDispatcher::OnRequestComplete(
return; return;
request_info->buffer.reset(); request_info->buffer.reset();
request_info->buffer_size = 0; request_info->buffer_size = 0;
request_info->did_request_complete = true;
auto resource_load_info = mojom::ResourceLoadInfo::New(); auto resource_load_info = mojom::ResourceLoadInfo::New();
resource_load_info->url = request_info->response_url; resource_load_info->url = request_info->response_url;
...@@ -347,7 +427,7 @@ void ResourceDispatcher::OnRequestComplete( ...@@ -347,7 +427,7 @@ void ResourceDispatcher::OnRequestComplete(
NotifyResourceLoadComplete(RenderThreadImpl::DeprecatedGetMainTaskRunner(), NotifyResourceLoadComplete(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id, request_info->render_frame_id,
std::move(resource_load_info)); std::move(resource_load_info), status);
RequestPeer* peer = request_info->peer.get(); RequestPeer* peer = request_info->peer.get();
...@@ -397,6 +477,11 @@ bool ResourceDispatcher::RemovePendingRequest( ...@@ -397,6 +477,11 @@ bool ResourceDispatcher::RemovePendingRequest(
if (it == pending_requests_.end()) if (it == pending_requests_.end())
return false; return false;
if (!it->second->did_request_complete) {
NotifyResourceLoadCancel(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
it->second->render_frame_id, request_id);
}
// Cancel loading. // Cancel loading.
it->second->url_loader = nullptr; it->second->url_loader = nullptr;
// Clear URLLoaderClient to stop receiving further Mojo IPC from the browser // Clear URLLoaderClient to stop receiving further Mojo IPC from the browser
...@@ -465,6 +550,10 @@ void ResourceDispatcher::OnTransferSizeUpdated(int request_id, ...@@ -465,6 +550,10 @@ void ResourceDispatcher::OnTransferSizeUpdated(int request_id,
// TODO(yhirano): Consider using int64_t in // TODO(yhirano): Consider using int64_t in
// RequestPeer::OnTransferSizeUpdated. // RequestPeer::OnTransferSizeUpdated.
request_info->peer->OnTransferSizeUpdated(transfer_size_diff); request_info->peer->OnTransferSizeUpdated(transfer_size_diff);
NotifyResourceTransferSizeUpdate(
RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id, request_id, transfer_size_diff);
} }
ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
......
...@@ -214,6 +214,7 @@ class CONTENT_EXPORT ResourceDispatcher { ...@@ -214,6 +214,7 @@ class CONTENT_EXPORT ResourceDispatcher {
navigation_response_override; navigation_response_override;
bool should_follow_redirect = true; bool should_follow_redirect = true;
bool always_access_network = false; bool always_access_network = false;
bool did_request_complete = false;
std::vector<content::mojom::RedirectInfoPtr> redirect_info_chain; std::vector<content::mojom::RedirectInfoPtr> redirect_info_chain;
......
...@@ -4816,6 +4816,32 @@ void RenderFrameImpl::DidLoadResourceFromMemoryCache( ...@@ -4816,6 +4816,32 @@ void RenderFrameImpl::DidLoadResourceFromMemoryCache(
response.MimeType().Utf8(), WebURLRequestToResourceType(request))); response.MimeType().Utf8(), WebURLRequestToResourceType(request)));
} }
void RenderFrameImpl::DidStartResponse(
int request_id,
const network::ResourceResponseHead& response_head) {
for (auto& observer : observers_)
observer.DidStartResponse(request_id, response_head);
}
void RenderFrameImpl::DidCompleteResponse(
int request_id,
const network::URLLoaderCompletionStatus& status) {
for (auto& observer : observers_)
observer.DidCompleteResponse(request_id, status);
}
void RenderFrameImpl::DidCancelResponse(int request_id) {
for (auto& observer : observers_)
observer.DidCancelResponse(request_id);
}
void RenderFrameImpl::DidReceiveTransferSizeUpdate(int resource_id,
int received_data_length) {
for (auto& observer : observers_) {
observer.DidReceiveTransferSizeUpdate(resource_id, received_data_length);
}
}
void RenderFrameImpl::DidDisplayInsecureContent() { void RenderFrameImpl::DidDisplayInsecureContent() {
Send(new FrameHostMsg_DidDisplayInsecureContent(routing_id_)); Send(new FrameHostMsg_DidDisplayInsecureContent(routing_id_));
} }
......
...@@ -876,6 +876,13 @@ class CONTENT_EXPORT RenderFrameImpl ...@@ -876,6 +876,13 @@ class CONTENT_EXPORT RenderFrameImpl
// browser. // browser.
void OnDroppedNavigation(); void OnDroppedNavigation();
void DidStartResponse(int request_id,
const network::ResourceResponseHead& response_head);
void DidCompleteResponse(int request_id,
const network::URLLoaderCompletionStatus& status);
void DidCancelResponse(int request_id);
void DidReceiveTransferSizeUpdate(int request_id, int received_data_length);
protected: protected:
explicit RenderFrameImpl(CreateParams params); explicit RenderFrameImpl(CreateParams params);
......
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