Commit d17049f1 authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

Plumb prefetch results in IsolatedPrerender Metrics Collector

Also transitions the origin prober over to using the new probe result
enum so that it can be passed to the metrics collector.

ScopedRefPtr:
The metrics collector uses a scoped ref ptr to manage its lifetime.
For mainframe prefetching, the TabHelper has the only refptr to the
collector. But during NSP, the refptr is shared to every subresource
manager that is created.
If the next navigation does not go to a prefetched page, all subresource
managers are destroyed, as well as the TabHelper's CurrentPageLoad class
which destroys the metrics collector. Since there would not be any
cache reuse to record in the metrics, it can be safely destroyed then.
If the next navigation goes to a prefetched page, then all refptrs to
the metrics collector will be destroyed, except for the one in the
subresource manager associated with that page. This allows the
subresource manager to record cache reuse directly, without relying on
the TabHelper to make some lifetime guarantee about the metrics
collector.
Furthermore, this pattern keeps the cache reuse logic out of the
TabHelper when it is already isolated to the subresource manager.

Bug: 1136174
Change-Id: I4e0e52acb8f99a1490f67d98b44329f997e40720
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463544
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818670}
parent 34c3cc61
...@@ -143,7 +143,9 @@ class TLSProber { ...@@ -143,7 +143,9 @@ class TLSProber {
mojo::ScopedDataPipeConsumerHandle receive_stream, mojo::ScopedDataPipeConsumerHandle receive_stream,
mojo::ScopedDataPipeProducerHandle send_stream, mojo::ScopedDataPipeProducerHandle send_stream,
const base::Optional<net::SSLInfo>& ssl_info) { const base::Optional<net::SSLInfo>& ssl_info) {
std::move(callback_).Run(result == net::OK); std::move(callback_).Run(
result == net::OK ? IsolatedPrerenderProbeResult::kTLSProbeSuccess
: IsolatedPrerenderProbeResult::kTLSProbeFailure);
delete this; delete this;
} }
...@@ -156,7 +158,7 @@ class TLSProber { ...@@ -156,7 +158,7 @@ class TLSProber {
} }
void HandleFailure() { void HandleFailure() {
std::move(callback_).Run(false); std::move(callback_).Run(IsolatedPrerenderProbeResult::kTLSProbeFailure);
delete this; delete this;
} }
...@@ -177,7 +179,9 @@ void HTTPProbeHelper( ...@@ -177,7 +179,9 @@ void HTTPProbeHelper(
std::unique_ptr<AvailabilityProber> prober, std::unique_ptr<AvailabilityProber> prober,
IsolatedPrerenderOriginProber::OnProbeResultCallback callback, IsolatedPrerenderOriginProber::OnProbeResultCallback callback,
bool success) { bool success) {
std::move(callback).Run(success); std::move(callback).Run(success
? IsolatedPrerenderProbeResult::kTLSProbeSuccess
: IsolatedPrerenderProbeResult::kTLSProbeFailure);
} }
class CanaryCheckDelegate : public AvailabilityProber::Delegate { class CanaryCheckDelegate : public AvailabilityProber::Delegate {
...@@ -323,7 +327,7 @@ void IsolatedPrerenderOriginProber::OnTLSCanaryCheckComplete(bool success) { ...@@ -323,7 +327,7 @@ void IsolatedPrerenderOriginProber::OnTLSCanaryCheckComplete(bool success) {
StartCanaryCheck(dns_canary_check_->AsWeakPtr()); StartCanaryCheck(dns_canary_check_->AsWeakPtr());
} }
bool IsolatedPrerenderOriginProber::ShouldProbeOrigins() { bool IsolatedPrerenderOriginProber::ShouldProbeOrigins() const {
if (!IsolatedPrerenderProbingEnabled()) { if (!IsolatedPrerenderProbingEnabled()) {
return false; return false;
} }
...@@ -442,7 +446,7 @@ void IsolatedPrerenderOriginProber::HTTPProbe(const GURL& url, ...@@ -442,7 +446,7 @@ void IsolatedPrerenderOriginProber::HTTPProbe(const GURL& url,
// Transfer ownership of the prober to the callback so that the class instance // Transfer ownership of the prober to the callback so that the class instance
// is automatically destroyed when the probe is complete. // is automatically destroyed when the probe is complete.
OnProbeResultCallback owning_callback = auto owning_callback =
base::BindOnce(&HTTPProbeHelper, std::move(prober), std::move(callback)); base::BindOnce(&HTTPProbeHelper, std::move(prober), std::move(callback));
prober_ptr->SetOnCompleteCallback(base::BindOnce(std::move(owning_callback))); prober_ptr->SetOnCompleteCallback(base::BindOnce(std::move(owning_callback)));
...@@ -460,12 +464,12 @@ void IsolatedPrerenderOriginProber::OnDNSResolved( ...@@ -460,12 +464,12 @@ void IsolatedPrerenderOriginProber::OnDNSResolved(
// A TLS connection needs the resolved addresses, so it also fails here. // A TLS connection needs the resolved addresses, so it also fails here.
if (!successful) { if (!successful) {
std::move(callback).Run(false); std::move(callback).Run(IsolatedPrerenderProbeResult::kDNSProbeFailure);
return; return;
} }
if (!also_do_tls_connect) { if (!also_do_tls_connect) {
std::move(callback).Run(true); std::move(callback).Run(IsolatedPrerenderProbeResult::kDNSProbeSuccess);
return; return;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_probe_result.h"
#include "net/base/address_list.h" #include "net/base/address_list.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -30,7 +31,7 @@ class IsolatedPrerenderOriginProber { ...@@ -30,7 +31,7 @@ class IsolatedPrerenderOriginProber {
~IsolatedPrerenderOriginProber(); ~IsolatedPrerenderOriginProber();
// Returns true if a probe needs to be done before using prefetched resources. // Returns true if a probe needs to be done before using prefetched resources.
bool ShouldProbeOrigins(); bool ShouldProbeOrigins() const;
// Sets the probe url override delegate for testing. // Sets the probe url override delegate for testing.
void SetProbeURLOverrideDelegateOverrideForTesting( void SetProbeURLOverrideDelegateOverrideForTesting(
...@@ -43,9 +44,10 @@ class IsolatedPrerenderOriginProber { ...@@ -43,9 +44,10 @@ class IsolatedPrerenderOriginProber {
// Tells whether a DNS canary check is active. Used for testing. // Tells whether a DNS canary check is active. Used for testing.
bool IsDNSCanaryCheckActiveForTesting() const; bool IsDNSCanaryCheckActiveForTesting() const;
// Starts a probe to |url| and calls |callback| with a bool to indicate // Starts a probe to |url| and calls |callback| with an
// success (when true) or failure (when false). // |IsolatedPrerenderProbeResult| to indicate success.
using OnProbeResultCallback = base::OnceCallback<void(bool)>; using OnProbeResultCallback =
base::OnceCallback<void(IsolatedPrerenderProbeResult)>;
void Probe(const GURL& url, OnProbeResultCallback callback); void Probe(const GURL& url, OnProbeResultCallback callback);
private: private:
......
...@@ -85,6 +85,10 @@ enum class IsolatedPrerenderPrefetchStatus { ...@@ -85,6 +85,10 @@ enum class IsolatedPrerenderPrefetchStatus {
kPrefetchUsedNoProbeNSPNotStarted = 22, kPrefetchUsedNoProbeNSPNotStarted = 22,
kPrefetchUsedProbeSuccessNSPNotStarted = 23, kPrefetchUsedProbeSuccessNSPNotStarted = 23,
kPrefetchNotUsedProbeFailedNSPNotStarted = 24, kPrefetchNotUsedProbeFailedNSPNotStarted = 24,
// A subresource which was not fetched because it was throttled by an
// experimental control for the max number of subresources per prerender.
kSubresourceThrottled = 25,
}; };
#endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PREFETCH_STATUS_H_ #endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PREFETCH_STATUS_H_
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "content/public/common/content_constants.h" #include "content/public/common/content_constants.h"
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "third_party/blink/public/common/client_hints/client_hints.h" #include "third_party/blink/public/common/client_hints/client_hints.h"
namespace { namespace {
...@@ -27,24 +28,6 @@ namespace { ...@@ -27,24 +28,6 @@ namespace {
const char kAllowedUAClientHint[] = "sec-ch-ua"; const char kAllowedUAClientHint[] = "sec-ch-ua";
const char kAllowedUAMobileClientHint[] = "sec-ch-ua-mobile"; const char kAllowedUAMobileClientHint[] = "sec-ch-ua-mobile";
void RecordSubresourceMetricsDuringPrerender(
const network::URLLoaderCompletionStatus& status,
base::Optional<int> http_response_code) {
base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Subresources.NetError",
std::abs(status.error_code));
if (http_response_code) {
base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Subresources.RespCode",
*http_response_code);
}
}
void RecordSubresourceMetricsAfterClick(
const network::URLLoaderCompletionStatus& status,
base::Optional<int> http_response_code) {
UMA_HISTOGRAM_BOOLEAN("IsolatedPrerender.AfterClick.Subresources.UsedCache",
status.exists_in_cache);
}
// Little helper class for // Little helper class for
// |CheckRedirectsBeforeRunningResourceSuccessfulCallback| since size_t can't be // |CheckRedirectsBeforeRunningResourceSuccessfulCallback| since size_t can't be
// ref counted. // ref counted.
...@@ -183,8 +166,8 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest:: ...@@ -183,8 +166,8 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::
void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest:: void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::
OnReceiveResponse(network::mojom::URLResponseHeadPtr head) { OnReceiveResponse(network::mojom::URLResponseHeadPtr head) {
if (head && head->headers) { if (head) {
http_response_code_ = head->headers->response_code(); head_ = head->Clone();
} }
target_client_->OnReceiveResponse(std::move(head)); target_client_->OnReceiveResponse(std::move(head));
} }
...@@ -228,7 +211,8 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest:: ...@@ -228,7 +211,8 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::
void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::OnComplete( void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::OnComplete(
const network::URLLoaderCompletionStatus& status) { const network::URLLoaderCompletionStatus& status) {
if (on_complete_metrics_callback_) { if (on_complete_metrics_callback_) {
std::move(on_complete_metrics_callback_).Run(status, http_response_code_); std::move(on_complete_metrics_callback_)
.Run(redirect_chain_[0], head_->Clone(), status);
} }
MaybeReportResourceLoadSuccess(status); MaybeReportResourceLoadSuccess(status);
target_client_->OnComplete(status); target_client_->OnComplete(status);
...@@ -247,15 +231,19 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest:: ...@@ -247,15 +231,19 @@ void IsolatedPrerenderProxyingURLLoaderFactory::InProgressRequest::
return; return;
} }
if (!http_response_code_) { if (!head_) {
return;
}
if (!head_->headers) {
return; return;
} }
if (*http_response_code_ >= 300) { if (head_->headers->response_code() >= net::HTTP_MULTIPLE_CHOICES) {
return; return;
} }
if (*http_response_code_ < 200) { if (head_->headers->response_code() < net::HTTP_OK) {
return; return;
} }
...@@ -319,6 +307,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::AbortRequest:: ...@@ -319,6 +307,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::AbortRequest::
IsolatedPrerenderProxyingURLLoaderFactory:: IsolatedPrerenderProxyingURLLoaderFactory::
IsolatedPrerenderProxyingURLLoaderFactory( IsolatedPrerenderProxyingURLLoaderFactory(
ResourceMetricsObserver* metrics_observer,
int frame_tree_node_id, int frame_tree_node_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver, mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> mojo::PendingRemote<network::mojom::URLLoaderFactory>
...@@ -326,9 +315,12 @@ IsolatedPrerenderProxyingURLLoaderFactory:: ...@@ -326,9 +315,12 @@ IsolatedPrerenderProxyingURLLoaderFactory::
mojo::PendingRemote<network::mojom::URLLoaderFactory> isolated_factory, mojo::PendingRemote<network::mojom::URLLoaderFactory> isolated_factory,
DisconnectCallback on_disconnect, DisconnectCallback on_disconnect,
ResourceLoadSuccessfulCallback on_resource_load_successful) ResourceLoadSuccessfulCallback on_resource_load_successful)
: frame_tree_node_id_(frame_tree_node_id), : metrics_observer_(metrics_observer),
frame_tree_node_id_(frame_tree_node_id),
on_resource_load_successful_(std::move(on_resource_load_successful)), on_resource_load_successful_(std::move(on_resource_load_successful)),
on_disconnect_(std::move(on_disconnect)) { on_disconnect_(std::move(on_disconnect)) {
DCHECK(metrics_observer_);
network_process_factory_.Bind(std::move(network_process_factory)); network_process_factory_.Bind(std::move(network_process_factory));
network_process_factory_.set_disconnect_handler(base::BindOnce( network_process_factory_.set_disconnect_handler(base::BindOnce(
&IsolatedPrerenderProxyingURLLoaderFactory::OnNetworkProcessFactoryError, &IsolatedPrerenderProxyingURLLoaderFactory::OnNetworkProcessFactoryError,
...@@ -381,6 +373,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::CreateLoaderAndStart( ...@@ -381,6 +373,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::CreateLoaderAndStart(
// Check if this prerender has exceeded its max number of subresources. // Check if this prerender has exceeded its max number of subresources.
request_count_++; request_count_++;
if (request_count_ > IsolatedPrerenderMaxSubresourcesPerPrerender()) { if (request_count_ > IsolatedPrerenderMaxSubresourcesPerPrerender()) {
metrics_observer_->OnResourceThrottled(request.url);
std::unique_ptr<AbortRequest> request = std::make_unique<AbortRequest>( std::unique_ptr<AbortRequest> request = std::make_unique<AbortRequest>(
std::move(loader_receiver), std::move(client)); std::move(loader_receiver), std::move(client));
// The request will manage its own lifecycle based on the mojo pipes. // The request will manage its own lifecycle based on the mojo pipes.
...@@ -410,7 +403,9 @@ void IsolatedPrerenderProxyingURLLoaderFactory::CreateLoaderAndStart( ...@@ -410,7 +403,9 @@ void IsolatedPrerenderProxyingURLLoaderFactory::CreateLoaderAndStart(
std::move(loader_receiver), routing_id, request_id, options, request, std::move(loader_receiver), routing_id, request_id, options, request,
std::move(client), traffic_annotation); std::move(client), traffic_annotation);
in_progress_request->SetOnCompleteRecordMetricsCallback( in_progress_request->SetOnCompleteRecordMetricsCallback(
base::BindOnce(&RecordSubresourceMetricsAfterClick)); base::BindOnce(&IsolatedPrerenderProxyingURLLoaderFactory::
RecordSubresourceMetricsAfterClick,
base::Unretained(this)));
requests_.insert(std::move(in_progress_request)); requests_.insert(std::move(in_progress_request));
} else { } else {
// Resource was not cached during the NSP, so load it normally. // Resource was not cached during the NSP, so load it normally.
...@@ -433,7 +428,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult( ...@@ -433,7 +428,7 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult(
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
const GURL& url, const GURL& url,
bool eligible, bool eligible,
base::Optional<IsolatedPrerenderPrefetchStatus> not_used) { base::Optional<IsolatedPrerenderPrefetchStatus> status) {
DCHECK_EQ(request.url, url); DCHECK_EQ(request.url, url);
DCHECK(!previously_cached_subresources_.has_value()); DCHECK(!previously_cached_subresources_.has_value());
DCHECK(request.cors_exempt_headers.HasHeader( DCHECK(request.cors_exempt_headers.HasHeader(
...@@ -470,6 +465,10 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult( ...@@ -470,6 +465,10 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult(
// not, it must still be put on the wire to avoid privacy attacks but should // not, it must still be put on the wire to avoid privacy attacks but should
// not be cached or change any cookies. // not be cached or change any cookies.
if (!eligible) { if (!eligible) {
if (status) {
metrics_observer_->OnResourceNotEligible(url, *status);
}
isolated_request.load_flags |= net::LOAD_DISABLE_CACHE; isolated_request.load_flags |= net::LOAD_DISABLE_CACHE;
isolated_request.credentials_mode = network::mojom::CredentialsMode::kOmit; isolated_request.credentials_mode = network::mojom::CredentialsMode::kOmit;
...@@ -482,10 +481,37 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult( ...@@ -482,10 +481,37 @@ void IsolatedPrerenderProxyingURLLoaderFactory::OnEligibilityResult(
std::move(loader_receiver), routing_id, request_id, options, std::move(loader_receiver), routing_id, request_id, options,
isolated_request, std::move(client), traffic_annotation); isolated_request, std::move(client), traffic_annotation);
in_progress_request->SetOnCompleteRecordMetricsCallback( in_progress_request->SetOnCompleteRecordMetricsCallback(
base::BindOnce(&RecordSubresourceMetricsDuringPrerender)); base::BindOnce(&IsolatedPrerenderProxyingURLLoaderFactory::
RecordSubresourceMetricsDuringPrerender,
base::Unretained(this)));
requests_.insert(std::move(in_progress_request)); requests_.insert(std::move(in_progress_request));
} }
void IsolatedPrerenderProxyingURLLoaderFactory::
RecordSubresourceMetricsDuringPrerender(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status) {
base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Subresources.NetError",
std::abs(status.error_code));
if (head && head->headers) {
base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Subresources.RespCode",
head->headers->response_code());
}
metrics_observer_->OnResourceFetchComplete(url, std::move(head), status);
}
void IsolatedPrerenderProxyingURLLoaderFactory::
RecordSubresourceMetricsAfterClick(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status) {
UMA_HISTOGRAM_BOOLEAN("IsolatedPrerender.AfterClick.Subresources.UsedCache",
status.exists_in_cache);
metrics_observer_->OnResourceUsedFromCache(url);
}
void IsolatedPrerenderProxyingURLLoaderFactory::Clone( void IsolatedPrerenderProxyingURLLoaderFactory::Clone(
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) { mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) {
proxy_receivers_.Add(this, std::move(loader_receiver)); proxy_receivers_.Add(this, std::move(loader_receiver));
......
...@@ -35,6 +35,27 @@ class Profile; ...@@ -35,6 +35,27 @@ class Profile;
class IsolatedPrerenderProxyingURLLoaderFactory class IsolatedPrerenderProxyingURLLoaderFactory
: public network::mojom::URLLoaderFactory { : public network::mojom::URLLoaderFactory {
public: public:
class ResourceMetricsObserver {
public:
// Called when the resource finishes, either in failure or success.
virtual void OnResourceFetchComplete(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status) = 0;
// Called when a subresource load exceeds the experimental maximum and the
// load is aborted before going to the network.
virtual void OnResourceThrottled(const GURL& url) = 0;
// Called when a subresource is not eligible to be prefetched.
virtual void OnResourceNotEligible(
const GURL& url,
IsolatedPrerenderPrefetchStatus status) = 0;
// Called when a previously prefetched subresource is loaded from the cache.
virtual void OnResourceUsedFromCache(const GURL& url) = 0;
};
using DisconnectCallback = using DisconnectCallback =
base::OnceCallback<void(IsolatedPrerenderProxyingURLLoaderFactory*)>; base::OnceCallback<void(IsolatedPrerenderProxyingURLLoaderFactory*)>;
...@@ -42,6 +63,7 @@ class IsolatedPrerenderProxyingURLLoaderFactory ...@@ -42,6 +63,7 @@ class IsolatedPrerenderProxyingURLLoaderFactory
base::RepeatingCallback<void(const GURL& url)>; base::RepeatingCallback<void(const GURL& url)>;
IsolatedPrerenderProxyingURLLoaderFactory( IsolatedPrerenderProxyingURLLoaderFactory(
ResourceMetricsObserver* metrics_observer,
int frame_tree_node_id, int frame_tree_node_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> mojo::PendingRemote<network::mojom::URLLoaderFactory>
...@@ -91,8 +113,9 @@ class IsolatedPrerenderProxyingURLLoaderFactory ...@@ -91,8 +113,9 @@ class IsolatedPrerenderProxyingURLLoaderFactory
// Sets a callback that will be run during |OnComplete| to record metrics. // Sets a callback that will be run during |OnComplete| to record metrics.
using OnCompleteRecordMetricsCallback = base::OnceCallback<void( using OnCompleteRecordMetricsCallback = base::OnceCallback<void(
const network::URLLoaderCompletionStatus& status, const GURL& url,
base::Optional<int> http_response_code)>; network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status)>;
void SetOnCompleteRecordMetricsCallback( void SetOnCompleteRecordMetricsCallback(
OnCompleteRecordMetricsCallback callback); OnCompleteRecordMetricsCallback callback);
...@@ -139,8 +162,8 @@ class IsolatedPrerenderProxyingURLLoaderFactory ...@@ -139,8 +162,8 @@ class IsolatedPrerenderProxyingURLLoaderFactory
// This should be run on destruction of |this|. // This should be run on destruction of |this|.
base::OnceClosure destruction_callback_; base::OnceClosure destruction_callback_;
// Records the HTTP response code in |OnReceiveResponse|. // Holds onto the response head for reporting to the metrics callback.
base::Optional<int> http_response_code_; network::mojom::URLResponseHeadPtr head_;
// All urls loaded by |this| in order of redirects. The first element is the // All urls loaded by |this| in order of redirects. The first element is the
// requested url and the last element is the final loaded url. Always has // requested url and the last element is the final loaded url. Always has
...@@ -210,7 +233,17 @@ class IsolatedPrerenderProxyingURLLoaderFactory ...@@ -210,7 +233,17 @@ class IsolatedPrerenderProxyingURLLoaderFactory
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
const GURL& url, const GURL& url,
bool eligible, bool eligible,
base::Optional<IsolatedPrerenderPrefetchStatus> not_used); base::Optional<IsolatedPrerenderPrefetchStatus> status);
void RecordSubresourceMetricsDuringPrerender(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status);
void RecordSubresourceMetricsAfterClick(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status);
// Returns true when this factory was created during a NoStatePrefetch. // Returns true when this factory was created during a NoStatePrefetch.
// Internally, this means |NotifyPageNavigatedToAfterSRP| has not been called. // Internally, this means |NotifyPageNavigatedToAfterSRP| has not been called.
...@@ -222,6 +255,8 @@ class IsolatedPrerenderProxyingURLLoaderFactory ...@@ -222,6 +255,8 @@ class IsolatedPrerenderProxyingURLLoaderFactory
void RemoveRequest(InProgressRequest* request); void RemoveRequest(InProgressRequest* request);
void MaybeDestroySelf(); void MaybeDestroySelf();
// Must outlive |this|.
ResourceMetricsObserver* metrics_observer_;
// For getting the web contents. // For getting the web contents.
const int frame_tree_node_id_; const int frame_tree_node_id_;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "chrome/browser/prerender/isolated/isolated_prerender_subresource_manager.h" #include "chrome/browser/prerender/isolated/isolated_prerender_subresource_manager.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_proxying_url_loader_factory.h" #include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_metrics_collector.h"
#include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h" #include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
...@@ -134,7 +134,7 @@ bool IsolatedPrerenderSubresourceManager::MaybeProxyURLLoaderFactory( ...@@ -134,7 +134,7 @@ bool IsolatedPrerenderSubresourceManager::MaybeProxyURLLoaderFactory(
frame->GetIsolationInfoForSubresources()); frame->GetIsolationInfoForSubresources());
auto proxy = std::make_unique<IsolatedPrerenderProxyingURLLoaderFactory>( auto proxy = std::make_unique<IsolatedPrerenderProxyingURLLoaderFactory>(
frame->GetFrameTreeNodeId(), std::move(proxied_receiver), this, frame->GetFrameTreeNodeId(), std::move(proxied_receiver),
std::move(network_process_factory_remote), std::move(network_process_factory_remote),
std::move(isolated_factory_remote), std::move(isolated_factory_remote),
base::BindOnce( base::BindOnce(
...@@ -168,3 +168,47 @@ void IsolatedPrerenderSubresourceManager::RemoveProxiedURLLoaderFactory( ...@@ -168,3 +168,47 @@ void IsolatedPrerenderSubresourceManager::RemoveProxiedURLLoaderFactory(
DCHECK(it != proxied_loader_factories_.end()); DCHECK(it != proxied_loader_factories_.end());
proxied_loader_factories_.erase(it); proxied_loader_factories_.erase(it);
} }
void IsolatedPrerenderSubresourceManager::SetPrefetchMetricsCollector(
scoped_refptr<IsolatedPrerenderPrefetchMetricsCollector> collector) {
metrics_collector_ = collector;
}
void IsolatedPrerenderSubresourceManager::OnResourceFetchComplete(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status) {
if (!metrics_collector_)
return;
metrics_collector_->OnSubresourcePrefetched(
/*mainframe_url=*/url_,
/*subresource_url=*/url, std::move(head), status);
}
void IsolatedPrerenderSubresourceManager::OnResourceNotEligible(
const GURL& url,
IsolatedPrerenderPrefetchStatus status) {
if (!metrics_collector_)
return;
metrics_collector_->OnSubresourceNotEligible(
/*mainframe_url=*/url_,
/*subresource_url=*/url, status);
}
void IsolatedPrerenderSubresourceManager::OnResourceThrottled(const GURL& url) {
if (!metrics_collector_)
return;
metrics_collector_->OnSubresourceNotEligible(
/*mainframe_url=*/url_,
/*subresource_url=*/url,
IsolatedPrerenderPrefetchStatus::kSubresourceThrottled);
}
void IsolatedPrerenderSubresourceManager::OnResourceUsedFromCache(
const GURL& url) {
if (!metrics_collector_)
return;
metrics_collector_->OnCachedSubresourceUsed(/*mainframe_url=*/url_,
/*subresource_url=*/url);
}
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_proxying_url_loader_factory.h"
#include "components/prerender/browser/prerender_handle.h" #include "components/prerender/browser/prerender_handle.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
...@@ -32,11 +33,14 @@ class PrerenderHandle; ...@@ -32,11 +33,14 @@ class PrerenderHandle;
} }
class PrefetchedMainframeResponseContainer; class PrefetchedMainframeResponseContainer;
class IsolatedPrerenderPrefetchMetricsCollector;
class IsolatedPrerenderProxyingURLLoaderFactory; class IsolatedPrerenderProxyingURLLoaderFactory;
// This class manages the isolated prerender of a page and its subresources. // This class manages the isolated prerender of a page and its subresources.
class IsolatedPrerenderSubresourceManager class IsolatedPrerenderSubresourceManager
: public prerender::PrerenderHandle::Observer { : public prerender::PrerenderHandle::Observer,
public IsolatedPrerenderProxyingURLLoaderFactory::
ResourceMetricsObserver {
public: public:
// A callback to create new URL Loader Factories for subresources. // A callback to create new URL Loader Factories for subresources.
using CreateIsolatedLoaderFactoryRepeatingCallback = using CreateIsolatedLoaderFactoryRepeatingCallback =
...@@ -61,6 +65,10 @@ class IsolatedPrerenderSubresourceManager ...@@ -61,6 +65,10 @@ class IsolatedPrerenderSubresourceManager
return successfully_loaded_subresources_; return successfully_loaded_subresources_;
} }
// Sets the prefetch metrics collector to report subresource fetches to.
void SetPrefetchMetricsCollector(
scoped_refptr<IsolatedPrerenderPrefetchMetricsCollector> collector);
// Takes ownership of |mainframe_response_|. // Takes ownership of |mainframe_response_|.
std::unique_ptr<PrefetchedMainframeResponseContainer> TakeMainframeResponse(); std::unique_ptr<PrefetchedMainframeResponseContainer> TakeMainframeResponse();
...@@ -96,6 +104,16 @@ class IsolatedPrerenderSubresourceManager ...@@ -96,6 +104,16 @@ class IsolatedPrerenderSubresourceManager
void OnPrerenderNetworkBytesChanged( void OnPrerenderNetworkBytesChanged(
prerender::PrerenderHandle* handle) override {} prerender::PrerenderHandle* handle) override {}
// IsolatedPrerenderProxyingURLLoaderFactory::ResourceMetricsObserver:
void OnResourceFetchComplete(
const GURL& url,
network::mojom::URLResponseHeadPtr head,
const network::URLLoaderCompletionStatus& status) override;
void OnResourceNotEligible(const GURL& url,
IsolatedPrerenderPrefetchStatus status) override;
void OnResourceThrottled(const GURL& url) override;
void OnResourceUsedFromCache(const GURL& url) override;
IsolatedPrerenderSubresourceManager( IsolatedPrerenderSubresourceManager(
const IsolatedPrerenderSubresourceManager&) = delete; const IsolatedPrerenderSubresourceManager&) = delete;
IsolatedPrerenderSubresourceManager& operator=( IsolatedPrerenderSubresourceManager& operator=(
...@@ -139,6 +157,10 @@ class IsolatedPrerenderSubresourceManager ...@@ -139,6 +157,10 @@ class IsolatedPrerenderSubresourceManager
// The mainframe response headers and body. // The mainframe response headers and body.
std::unique_ptr<PrefetchedMainframeResponseContainer> mainframe_response_; std::unique_ptr<PrefetchedMainframeResponseContainer> mainframe_response_;
// Collects metrics from the implementation of
// |IsolatedPrerenderProxyingURLLoaderFactory::ResourceMetricsObserver|.
scoped_refptr<IsolatedPrerenderPrefetchMetricsCollector> metrics_collector_;
// State for managing the NoStatePrerender when it is running. If // State for managing the NoStatePrerender when it is running. If
// |nsp_handle_| is set, then |on_nsp_done_callback_| is also set and vise // |nsp_handle_| is set, then |on_nsp_done_callback_| is also set and vise
// versa. // versa.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "chrome/browser/prerender/isolated/isolated_prerender_features.h" #include "chrome/browser/prerender/isolated/isolated_prerender_features.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h" #include "chrome/browser/prerender/isolated/isolated_prerender_network_context_client.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_params.h" #include "chrome/browser/prerender/isolated/isolated_prerender_params.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_metrics_collector.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_proxy_configurator.h" #include "chrome/browser/prerender/isolated/isolated_prerender_proxy_configurator.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_service.h" #include "chrome/browser/prerender/isolated/isolated_prerender_service.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_service_factory.h" #include "chrome/browser/prerender/isolated/isolated_prerender_service_factory.h"
...@@ -348,6 +349,16 @@ void IsolatedPrerenderTabHelper::NotifyPrefetchProbeLatency( ...@@ -348,6 +349,16 @@ void IsolatedPrerenderTabHelper::NotifyPrefetchProbeLatency(
page_->probe_latency_ = probe_latency; page_->probe_latency_ = probe_latency;
} }
void IsolatedPrerenderTabHelper::ReportProbeResult(
const GURL& url,
IsolatedPrerenderProbeResult result) {
if (!page_->prefetch_metrics_collector_) {
return;
}
page_->prefetch_metrics_collector_->OnMainframeNavigationProbeResult(url,
result);
}
void IsolatedPrerenderTabHelper::OnPrefetchStatusUpdate( void IsolatedPrerenderTabHelper::OnPrefetchStatusUpdate(
const GURL& url, const GURL& url,
IsolatedPrerenderPrefetchStatus usage) { IsolatedPrerenderPrefetchStatus usage) {
...@@ -381,6 +392,7 @@ IsolatedPrerenderTabHelper::MaybeUpdatePrefetchStatusWithNSPContext( ...@@ -381,6 +392,7 @@ IsolatedPrerenderTabHelper::MaybeUpdatePrefetchStatusWithNSPContext(
case IsolatedPrerenderPrefetchStatus::kPrefetchFailedNotHTML: case IsolatedPrerenderPrefetchStatus::kPrefetchFailedNotHTML:
case IsolatedPrerenderPrefetchStatus::kPrefetchSuccessful: case IsolatedPrerenderPrefetchStatus::kPrefetchSuccessful:
case IsolatedPrerenderPrefetchStatus::kNavigatedToLinkNotOnSRP: case IsolatedPrerenderPrefetchStatus::kNavigatedToLinkNotOnSRP:
case IsolatedPrerenderPrefetchStatus::kSubresourceThrottled:
return status; return status;
// These statuses we are going to update to, and this is the only place that // These statuses we are going to update to, and this is the only place that
// they are set so they are not expected to be passed in. // they are set so they are not expected to be passed in.
...@@ -554,6 +566,8 @@ void IsolatedPrerenderTabHelper::DidFinishNavigation( ...@@ -554,6 +566,8 @@ void IsolatedPrerenderTabHelper::DidFinishNavigation(
std::make_unique<CurrentPageLoad>(navigation_handle); std::make_unique<CurrentPageLoad>(navigation_handle);
if (page_->srp_metrics_->predicted_urls_count_ > 0) { if (page_->srp_metrics_->predicted_urls_count_ > 0) {
page_->prefetch_metrics_collector_->OnMainframeNavigatedTo(url);
// If the previous page load was a Google SRP, the AfterSRPMetrics class // If the previous page load was a Google SRP, the AfterSRPMetrics class
// needs to be created now from the SRP's |page_| and then set on the new // needs to be created now from the SRP's |page_| and then set on the new
// one when we set it at the end of this method. // one when we set it at the end of this method.
...@@ -790,6 +804,13 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete( ...@@ -790,6 +804,13 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete(
base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Mainframe.NetError", base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Mainframe.NetError",
std::abs(loader->NetError())); std::abs(loader->NetError()));
if (loader->CompletionStatus()) {
page_->prefetch_metrics_collector_->OnMainframeResourcePrefetched(
url, page_->original_prediction_ordering_.find(url)->second,
loader->ResponseInfo() ? loader->ResponseInfo()->Clone() : nullptr,
loader->CompletionStatus().value());
}
if (loader->NetError() != net::OK) { if (loader->NetError() != net::OK) {
OnPrefetchStatusUpdate( OnPrefetchStatusUpdate(
url, IsolatedPrerenderPrefetchStatus::kPrefetchFailedNetError); url, IsolatedPrerenderPrefetchStatus::kPrefetchFailedNetError);
...@@ -805,6 +826,7 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete( ...@@ -805,6 +826,7 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete(
DCHECK(!head->proxy_server.is_direct()); DCHECK(!head->proxy_server.is_direct());
HandlePrefetchResponse(url, isolation_info, std::move(head), HandlePrefetchResponse(url, isolation_info, std::move(head),
std::move(body)); std::move(body));
} }
...@@ -938,6 +960,8 @@ void IsolatedPrerenderTabHelper::DoNoStatePrefetch() { ...@@ -938,6 +960,8 @@ void IsolatedPrerenderTabHelper::DoNoStatePrefetch() {
service->OnAboutToNoStatePrefetch(url, CopyPrefetchResponseForNSP(url)); service->OnAboutToNoStatePrefetch(url, CopyPrefetchResponseForNSP(url));
DCHECK_EQ(manager, service->GetSubresourceManagerForURL(url)); DCHECK_EQ(manager, service->GetSubresourceManagerForURL(url));
manager->SetPrefetchMetricsCollector(page_->prefetch_metrics_collector_);
manager->SetCreateIsolatedLoaderFactoryCallback(base::BindRepeating( manager->SetCreateIsolatedLoaderFactoryCallback(base::BindRepeating(
&IsolatedPrerenderTabHelper::CreateNewURLLoaderFactory, &IsolatedPrerenderTabHelper::CreateNewURLLoaderFactory,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
...@@ -1065,6 +1089,13 @@ void IsolatedPrerenderTabHelper::OnPredictionUpdated( ...@@ -1065,6 +1089,13 @@ void IsolatedPrerenderTabHelper::OnPredictionUpdated(
return; return;
} }
if (!page_->prefetch_metrics_collector_) {
page_->prefetch_metrics_collector_ =
base::MakeRefCounted<IsolatedPrerenderPrefetchMetricsCollector>(
page_->navigation_start_,
web_contents()->GetMainFrame()->GetPageUkmSourceId());
}
// It's very likely we'll prefetch something at this point, so inform PLM to // It's very likely we'll prefetch something at this point, so inform PLM to
// start tracking metrics. // start tracking metrics.
InformPLMOfLikelyPrefetching(web_contents()); InformPLMOfLikelyPrefetching(web_contents());
...@@ -1189,6 +1220,10 @@ void IsolatedPrerenderTabHelper::OnGotEligibilityResult( ...@@ -1189,6 +1220,10 @@ void IsolatedPrerenderTabHelper::OnGotEligibilityResult(
if (!eligible) { if (!eligible) {
if (status) { if (status) {
OnPrefetchStatusUpdate(url, status.value()); OnPrefetchStatusUpdate(url, status.value());
DCHECK(page_->prefetch_metrics_collector_);
page_->prefetch_metrics_collector_->OnMainframeResourceNotEligible(
url, page_->original_prediction_ordering_.find(url)->second, *status);
} }
return; return;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service.h" #include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_status.h" #include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_status.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_probe_result.h"
#include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h" #include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h"
#include "content/public/browser/service_worker_context.h" #include "content/public/browser/service_worker_context.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
...@@ -27,11 +28,13 @@ ...@@ -27,11 +28,13 @@
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "net/base/isolation_info.h" #include "net/base/isolation_info.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h" #include "services/network/public/mojom/url_response_head.mojom-forward.h"
#include "url/gurl.h" #include "url/gurl.h"
class IsolatedPrerenderPageLoadMetricsObserver; class IsolatedPrerenderPageLoadMetricsObserver;
class IsolatedPrerenderPrefetchMetricsCollector;
class IsolatedPrerenderSubresourceManager; class IsolatedPrerenderSubresourceManager;
class Profile; class Profile;
...@@ -193,6 +196,10 @@ class IsolatedPrerenderTabHelper ...@@ -193,6 +196,10 @@ class IsolatedPrerenderTabHelper
// Called by the URLLoaderInterceptor to update |page_.probe_latency_|. // Called by the URLLoaderInterceptor to update |page_.probe_latency_|.
void NotifyPrefetchProbeLatency(base::TimeDelta probe_latency); void NotifyPrefetchProbeLatency(base::TimeDelta probe_latency);
// Called by the URLLoaderInterceptor to report the outcome of an origin
// probe.
void ReportProbeResult(const GURL& url, IsolatedPrerenderProbeResult result);
// When a previously prefetched page is navigated to, any cookies set on that // When a previously prefetched page is navigated to, any cookies set on that
// page load should be copied over to the normal profile. While this copy is // page load should be copied over to the normal profile. While this copy is
// in progress, this method returns true to indicate to the navigation loader // in progress, this method returns true to indicate to the navigation loader
...@@ -253,6 +260,12 @@ class IsolatedPrerenderTabHelper ...@@ -253,6 +260,12 @@ class IsolatedPrerenderTabHelper
// Only set for pages after a Google SRP. // Only set for pages after a Google SRP.
std::unique_ptr<AfterSRPMetrics> after_srp_metrics_; std::unique_ptr<AfterSRPMetrics> after_srp_metrics_;
// Collects metrics on all prefetching. This is a scoped refptr so that it
// can also be shared with subresource managers until all pointers to it are
// destroyed, at which time it logs UKM.
scoped_refptr<IsolatedPrerenderPrefetchMetricsCollector>
prefetch_metrics_collector_;
// The status of each prefetch. // The status of each prefetch.
std::map<GURL, IsolatedPrerenderPrefetchStatus> prefetch_status_by_url_; std::map<GURL, IsolatedPrerenderPrefetchStatus> prefetch_status_by_url_;
......
...@@ -50,6 +50,22 @@ void ReportProbeLatency(int frame_tree_node_id, base::TimeDelta probe_latency) { ...@@ -50,6 +50,22 @@ void ReportProbeLatency(int frame_tree_node_id, base::TimeDelta probe_latency) {
tab_helper->NotifyPrefetchProbeLatency(probe_latency); tab_helper->NotifyPrefetchProbeLatency(probe_latency);
} }
void ReportProbeResult(int frame_tree_node_id,
const GURL& url,
IsolatedPrerenderProbeResult result) {
content::WebContents* web_contents =
content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
if (!web_contents)
return;
IsolatedPrerenderTabHelper* tab_helper =
IsolatedPrerenderTabHelper::FromWebContents(web_contents);
if (!tab_helper)
return;
tab_helper->ReportProbeResult(url, result);
}
void RecordCookieWaitTime(base::TimeDelta wait_time) { void RecordCookieWaitTime(base::TimeDelta wait_time) {
UMA_HISTOGRAM_CUSTOM_TIMES( UMA_HISTOGRAM_CUSTOM_TIMES(
"IsolatedPrerender.AfterClick.Mainframe.CookieWaitTime", wait_time, "IsolatedPrerender.AfterClick.Mainframe.CookieWaitTime", wait_time,
...@@ -228,12 +244,13 @@ void IsolatedPrerenderURLLoaderInterceptor::DoNotInterceptNavigation() { ...@@ -228,12 +244,13 @@ void IsolatedPrerenderURLLoaderInterceptor::DoNotInterceptNavigation() {
void IsolatedPrerenderURLLoaderInterceptor::OnProbeComplete( void IsolatedPrerenderURLLoaderInterceptor::OnProbeComplete(
base::OnceClosure on_success_callback, base::OnceClosure on_success_callback,
bool success) { IsolatedPrerenderProbeResult result) {
DCHECK(probe_start_time_.has_value()); DCHECK(probe_start_time_.has_value());
ReportProbeLatency(frame_tree_node_id_, ReportProbeLatency(frame_tree_node_id_,
base::TimeTicks::Now() - probe_start_time_.value()); base::TimeTicks::Now() - probe_start_time_.value());
ReportProbeResult(frame_tree_node_id_, url_, result);
if (success) { if (IsolatedPrerenderProbeResultIsSuccess(result)) {
std::move(on_success_callback).Run(); std::move(on_success_callback).Run();
return; return;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/availability/availability_prober.h" #include "chrome/browser/availability/availability_prober.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_status.h" #include "chrome/browser/prerender/isolated/isolated_prerender_prefetch_status.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_probe_result.h"
#include "content/public/browser/url_loader_request_interceptor.h" #include "content/public/browser/url_loader_request_interceptor.h"
#include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/resource_request.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -60,8 +61,9 @@ class IsolatedPrerenderURLLoaderInterceptor ...@@ -60,8 +61,9 @@ class IsolatedPrerenderURLLoaderInterceptor
bool MaybeInterceptNoStatePrefetchNavigation( bool MaybeInterceptNoStatePrefetchNavigation(
const network::ResourceRequest& tentative_resource_request); const network::ResourceRequest& tentative_resource_request);
// Called when the probe finishes with |success|. // Called when the probe finishes with |result|.
void OnProbeComplete(base::OnceClosure on_success_callback, bool success); void OnProbeComplete(base::OnceClosure on_success_callback,
IsolatedPrerenderProbeResult result);
// Notifies the Tab Helper about the usage of a prefetched resource. // Notifies the Tab Helper about the usage of a prefetched resource.
void NotifyPrefetchStatusUpdate(IsolatedPrerenderPrefetchStatus usage) const; void NotifyPrefetchStatusUpdate(IsolatedPrerenderPrefetchStatus usage) const;
......
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