hints_fetcher.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_HINTS_FETCHER_H_
  5. #define COMPONENTS_OPTIMIZATION_GUIDE_CORE_HINTS_FETCHER_H_
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "base/callback.h"
  10. #include "base/containers/flat_set.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/memory/scoped_refptr.h"
  13. #include "base/sequence_checker.h"
  14. #include "base/time/clock.h"
  15. #include "base/time/time.h"
  16. #include "components/optimization_guide/proto/hints.pb.h"
  17. #include "third_party/abseil-cpp/absl/types/optional.h"
  18. #include "url/gurl.h"
  19. class OptimizationGuideLogger;
  20. class PrefService;
  21. namespace network {
  22. class SharedURLLoaderFactory;
  23. class SimpleURLLoader;
  24. } // namespace network
  25. namespace optimization_guide {
  26. // Status of a request to fetch hints.
  27. // This enum must remain synchronized with the enum
  28. // |OptimizationGuideHintsFetcherRequestStatus| in
  29. // tools/metrics/histograms/enums.xml.
  30. enum class HintsFetcherRequestStatus {
  31. // No fetch status known. Used in testing.
  32. kUnknown,
  33. // Fetch request was sent and a response received.
  34. kSuccess,
  35. // Fetch request was sent but no response received.
  36. kResponseError,
  37. // DEPRECATED: Fetch request not sent because of offline network status.
  38. kDeprecatedNetworkOffline,
  39. // Fetch request not sent because fetcher was busy with another request.
  40. kFetcherBusy,
  41. // Fetch request not sent because the host and URL lists were empty.
  42. kNoHostsOrURLsToFetch,
  43. // Fetch request not sent because no supported optimization types were
  44. // provided.
  45. kNoSupportedOptimizationTypes,
  46. // Insert new values before this line.
  47. kMaxValue = kNoSupportedOptimizationTypes
  48. };
  49. // Callback to inform the caller that the remote hints have been fetched and
  50. // to pass back the fetched hints response from the remote Optimization Guide
  51. // Service.
  52. using HintsFetchedCallback = base::OnceCallback<void(
  53. absl::optional<std::unique_ptr<proto::GetHintsResponse>>)>;
  54. // A class to handle requests for optimization hints from a remote Optimization
  55. // Guide Service.
  56. //
  57. // This class fetches new hints from the remote Optimization Guide Service.
  58. class HintsFetcher {
  59. public:
  60. HintsFetcher(
  61. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  62. const GURL& optimization_guide_service_url,
  63. PrefService* pref_service,
  64. OptimizationGuideLogger* optimization_guide_logger);
  65. HintsFetcher(const HintsFetcher&) = delete;
  66. HintsFetcher& operator=(const HintsFetcher&) = delete;
  67. virtual ~HintsFetcher();
  68. // Requests hints from the Optimization Guide Service if a request for them is
  69. // not already in progress. Returns whether a new request was issued.
  70. // |hints_fetched_callback| is run once when the outcome of this request is
  71. // determined (whether a request was actually sent or not). Virtualized for
  72. // testing. Hints fetcher may fetch hints for only a subset of the provided
  73. // |hosts|. |hosts| should be an ordered list in descending order of
  74. // probability that the hints are needed for that host. Only supported |urls|
  75. // will be included in the fetch. |urls| is an ordered list in descending
  76. // order of probability that a hint will be needed for the URL. The supplied
  77. // optimization types will be included in the request, if empty no fetch will
  78. // be made.
  79. virtual bool FetchOptimizationGuideServiceHints(
  80. const std::vector<std::string>& hosts,
  81. const std::vector<GURL>& urls,
  82. const base::flat_set<optimization_guide::proto::OptimizationType>&
  83. optimization_types,
  84. optimization_guide::proto::RequestContext request_context,
  85. const std::string& locale,
  86. HintsFetchedCallback hints_fetched_callback);
  87. // Set |time_clock_| for testing.
  88. void SetTimeClockForTesting(const base::Clock* time_clock);
  89. // Clear all the hosts and expiration times from the
  90. // HintsFetcherHostsSuccessfullyFetched dictionary pref.
  91. static void ClearHostsSuccessfullyFetched(PrefService* pref_service);
  92. // Clear the given host from the HintsFetcherHostsSuccessfullyFetched
  93. // dictionary pref.
  94. static void ClearSingleFetchedHost(PrefService* pref_service,
  95. const std::string& host);
  96. // Adds a fetched host at the given time. Used only for testing.
  97. static void AddFetchedHostForTesting(PrefService* pref_service,
  98. const std::string& host,
  99. base::Time time);
  100. // Return whether the host was covered by a hints fetch and any returned hints
  101. // would not have expired.
  102. static bool WasHostCoveredByFetch(PrefService* pref_service,
  103. const std::string& host);
  104. static bool WasHostCoveredByFetch(PrefService* pref_service,
  105. const std::string& host,
  106. const base::Clock* clock);
  107. private:
  108. // URL loader completion callback.
  109. void OnURLLoadComplete(std::unique_ptr<std::string> response_body);
  110. // Handles the response from the remote Optimization Guide Service.
  111. // |response| is the response body, |status| is the
  112. // |net::Error| of the response, and response_code is the HTTP
  113. // response code (if available).
  114. void HandleResponse(const std::string& response,
  115. int status,
  116. int response_code);
  117. // Stores the hosts in |hosts_fetched_| in the
  118. // HintsFetcherHostsSuccessfullyFetched dictionary pref. The value stored for
  119. // each host is the time that the hints fetched for each host will expire.
  120. // |hosts_fetched_| is cleared once the hosts are stored
  121. // in the pref.
  122. void UpdateHostsSuccessfullyFetched(base::TimeDelta valid_duration);
  123. // Returns the subset of URLs from |urls| for which the URL is considered
  124. // valid and can be included in a hints fetch.
  125. std::vector<GURL> GetSizeLimitedURLsForFetching(
  126. const std::vector<GURL>& urls) const;
  127. // Returns the subset of hosts from |hosts| for which the hints should be
  128. // refreshed. The count of returned hosts is limited to
  129. // features::MaxHostsForOptimizationGuideServiceHintsFetch().
  130. std::vector<std::string> GetSizeLimitedHostsDueForHintsRefresh(
  131. const std::vector<std::string>& hosts) const;
  132. // Used to hold the callback while the SimpleURLLoader performs the request
  133. // asynchronously.
  134. HintsFetchedCallback hints_fetched_callback_;
  135. // The URL for the remote Optimization Guide Service.
  136. const GURL optimization_guide_service_url_;
  137. // Holds the |URLLoader| for an active hints request.
  138. std::unique_ptr<network::SimpleURLLoader> active_url_loader_;
  139. // Context of the fetch request. Opaque field that's returned back in the
  140. // callback and is also included in the requests to the hints server.
  141. optimization_guide::proto::RequestContext request_context_;
  142. // A reference to the PrefService for this profile. Not owned.
  143. raw_ptr<PrefService> pref_service_ = nullptr;
  144. // Holds the hosts being requested by the hints fetcher.
  145. std::vector<std::string> hosts_fetched_;
  146. // Clock used for recording time that the hints fetch occurred.
  147. raw_ptr<const base::Clock> time_clock_;
  148. // Used for creating an |active_url_loader_| when needed for request hints.
  149. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  150. // The start time of the current hints fetch, used to determine the latency in
  151. // retrieving hints from the remote Optimization Guide Service.
  152. base::TimeTicks hints_fetch_start_time_;
  153. // Owned by OptimizationGuideKeyedService and outlives |this|.
  154. raw_ptr<OptimizationGuideLogger> optimization_guide_logger_;
  155. SEQUENCE_CHECKER(sequence_checker_);
  156. };
  157. } // namespace optimization_guide
  158. #endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_HINTS_FETCHER_H_