1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PREDICTORS_PREFETCH_MANAGER_H_
#define CHROME_BROWSER_PREDICTORS_PREFETCH_MANAGER_H_
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
#include "net/base/network_anonymization_key.h"
#include "services/network/public/mojom/fetch_api.mojom-forward.h"
#include "services/network/public/mojom/url_loader.mojom-forward.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-forward.h"
#include "url/gurl.h"
class Profile;
namespace blink {
class ThrottlingURLLoader;
}
namespace network {
namespace mojom {
class URLLoaderClient;
}
class SharedURLLoaderFactory;
struct URLLoaderCompletionStatus;
}
namespace predictors {
struct PrefetchRequest;
struct PrefetchInfo;
struct PrefetchJob;
inline constexpr size_t kMaxInflightPrefetches = 3;
struct PrefetchStats {
explicit PrefetchStats(const GURL& url);
~PrefetchStats();
PrefetchStats(const PrefetchStats&) = delete;
PrefetchStats& operator=(const PrefetchStats&) = delete;
GURL url;
base::TimeTicks start_time;
// TODO(falken): Add stats about what was requested to measure
// the accuracy.
};
// PrefetchManager prefetches input lists of URLs.
// - The input list of URLs is associated with a main frame url that can be
// used for cancelling.
// - Limits the total number of prefetches in flight.
// - All methods of the class must be called on the UI thread.
//
// This class is very similar to PreconnectManager, which does
// preresolve/preconnect instead of prefetching. It is only
// usable when LoadingPredictorPrefetch is enabled.
class PrefetchManager {
public:
// Delegate methods are not called when the
// kPrefetchManagerUseNetworkContextPrefetch feature is enabled, as this class
// does not track progress in that case.
class Delegate {
public:
virtual ~Delegate() = default;
// Called when a prefetch is initiated. |prefetch_url| is the subresource
// being prefetched, and |url| is the main frame of the navigation.
virtual void PrefetchInitiated(const GURL& url,
const GURL& prefetch_url) = 0;
// Called when all prefetch jobs for the |stats->url| are finished.
// Called on the UI thread.
virtual void PrefetchFinished(std::unique_ptr<PrefetchStats> stats) = 0;
};
// For testing. Observer methods will not be called when the
// kPrefetchManagerUseNetworkContextPrefetch feature is enabled.
class Observer {
public:
virtual ~Observer() = default;
virtual void OnPrefetchFinished(
const GURL& url,
const GURL& prefetch_url,
const network::URLLoaderCompletionStatus& status) {}
virtual void OnAllPrefetchesFinished(const GURL& url) {}
};
PrefetchManager(base::WeakPtr<Delegate> delegate, Profile* profile);
~PrefetchManager();
PrefetchManager(const PrefetchManager&) = delete;
PrefetchManager& operator=(const PrefetchManager&) = delete;
static bool IsAvailableForPrefetch(
network::mojom::RequestDestination destination);
// Starts prefetch jobs keyed by |url|.
void Start(const GURL& url, std::vector<PrefetchRequest> requests);
// Stops further prefetch jobs keyed by |url|. Queued jobs will never start;
// started jobs will continue to completion.
void Stop(const GURL& url);
base::WeakPtr<PrefetchManager> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Called by PrefetchInfo.
void AllPrefetchJobsForUrlFinished(PrefetchInfo& info);
void set_observer_for_testing(Observer* observer) {
observer_for_testing_ = observer;
}
private:
friend class PrefetchManagerTest;
void PrefetchUrl(std::unique_ptr<PrefetchJob> job,
scoped_refptr<network::SharedURLLoaderFactory> factory);
void OnPrefetchFinished(
std::unique_ptr<PrefetchJob> job,
std::unique_ptr<blink::ThrottlingURLLoader> loader,
std::unique_ptr<network::mojom::URLLoaderClient> client,
const network::URLLoaderCompletionStatus& status);
void TryToLaunchPrefetchJobs();
base::WeakPtr<Delegate> delegate_;
const raw_ptr<Profile, DanglingUntriaged> profile_;
// All the jobs that haven't yet started. A job is removed once it starts.
// Inflight jobs destruct once finished.
std::list<std::unique_ptr<PrefetchJob>> queued_jobs_;
std::map<GURL, std::unique_ptr<PrefetchInfo>> prefetch_info_;
// The total number of prefetches that have started and not yet finished,
// across all main frame URLs.
size_t inflight_jobs_count_ = 0;
raw_ptr<Observer, DanglingUntriaged> observer_for_testing_ = nullptr;
// True if the feature "PrefetchManagerUseNetworkContextPrefetch" is in use,
// in which case this class just fires off prefetches but does not track their
// completion.
const bool use_network_context_prefetch_;
base::WeakPtrFactory<PrefetchManager> weak_factory_{this};
};
// Returns a relevant ResourceType for the given RequestDestination if it's
// supported by prefetch. Otherwise, returns nullopt.
std::optional<blink::mojom::ResourceType> GetResourceTypeForPrefetch(
network::mojom::RequestDestination destination);
} // namespace predictors
#endif // CHROME_BROWSER_PREDICTORS_PREFETCH_MANAGER_H_
|