#include "components/optimization_guide/core/hints_manager.h"
#include <cstddef>
#include <optional>
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/histogram_macros_local.h"
#include "base/notreached.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/optimization_guide/core/access_token_helper.h"
#include "components/optimization_guide/core/bloom_filter.h"
#include "components/optimization_guide/core/hint_cache.h"
#include "components/optimization_guide/core/hints_component_util.h"
#include "components/optimization_guide/core/hints_fetcher_factory.h"
#include "components/optimization_guide/core/hints_processing_util.h"
#include "components/optimization_guide/core/insertion_ordered_set.h"
#include "components/optimization_guide/core/optimization_filter.h"
#include "components/optimization_guide/core/optimization_guide_constants.h"
#include "components/optimization_guide/core/optimization_guide_decision.h"
#include "components/optimization_guide/core/optimization_guide_enums.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/optimization_guide/core/optimization_guide_logger.h"
#include "components/optimization_guide/core/optimization_guide_navigation_data.h"
#include "components/optimization_guide/core/optimization_guide_permissions_util.h"
#include "components/optimization_guide/core/optimization_guide_prefs.h"
#include "components/optimization_guide/core/optimization_guide_store.h"
#include "components/optimization_guide/core/optimization_guide_switches.h"
#include "components/optimization_guide/core/optimization_guide_util.h"
#include "components/optimization_guide/core/optimization_hints_component_update_listener.h"
#include "components/optimization_guide/core/optimization_metadata.h"
#include "components/optimization_guide/core/tab_url_provider.h"
#include "components/optimization_guide/core/top_host_provider.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "google_apis/gaia/gaia_constants.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace optimization_guide {
namespace {
constexpr char kManualConfigComponentVersion[] = …;
base::TimeDelta RandomFetchDelay() { … }
void MaybeRunUpdateClosure(base::OnceClosure update_closure) { … }
std::optional<base::Version>
GetPendingOptimizationHintsComponentVersionFromPref(PrefService* pref_service) { … }
bool IsOptimizationTypeAllowed(const google::protobuf::RepeatedPtrField<
proto::Optimization>& optimizations,
proto::OptimizationType optimization_type,
OptimizationMetadata* optimization_metadata) { … }
class ScopedHintsManagerRaceNavigationHintsFetchAttemptRecorder { … };
bool ShouldIgnoreNewlyRegisteredOptimizationType(
proto::OptimizationType optimization_type) { … }
class ScopedCanApplyOptimizationLogger { … };
std::unique_ptr<proto::Configuration> ReadComponentFile(
const HintsComponentInfo& info) { … }
void MaybeLogGetHintRequestInfo(
proto::RequestContext request_context,
const base::flat_set<proto::OptimizationType>& requested_optimization_types,
const std::vector<GURL>& urls_to_fetch,
const std::vector<std::string>& hosts_to_fetch,
OptimizationGuideLogger* optimization_guide_logger) { … }
bool ShouldContextResponsePopulateHintCache(
proto::RequestContext request_context) { … }
}
HintsManager::HintsManager(
bool is_off_the_record,
const std::string& application_locale,
PrefService* pref_service,
base::WeakPtr<OptimizationGuideStore> hint_store,
TopHostProvider* top_host_provider,
TabUrlProvider* tab_url_provider,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<PushNotificationManager> push_notification_manager,
signin::IdentityManager* identity_manager,
OptimizationGuideLogger* optimization_guide_logger)
: … { … }
HintsManager::~HintsManager() { … }
void HintsManager::Shutdown() { … }
OptimizationGuideDecision
HintsManager::GetOptimizationGuideDecisionFromOptimizationTypeDecision(
OptimizationTypeDecision optimization_type_decision) { … }
void HintsManager::OnHintsComponentAvailable(const HintsComponentInfo& info) { … }
void HintsManager::ProcessOptimizationFilters(
const google::protobuf::RepeatedPtrField<proto::OptimizationFilter>&
allowlist_optimization_filters,
const google::protobuf::RepeatedPtrField<proto::OptimizationFilter>&
blocklist_optimization_filters) { … }
void HintsManager::ProcessOptimizationFilterSet(
const google::protobuf::RepeatedPtrField<proto::OptimizationFilter>&
filters,
bool is_allowlist) { … }
void HintsManager::OnHintCacheInitialized() { … }
void HintsManager::UpdateComponentHints(
base::OnceClosure update_closure,
std::unique_ptr<StoreUpdateData> update_data,
std::unique_ptr<proto::Configuration> config) { … }
void HintsManager::OnComponentHintsUpdated(base::OnceClosure update_closure,
bool hints_updated) { … }
void HintsManager::InitiateHintsFetchScheduling() { … }
void HintsManager::ListenForNextUpdateForTesting(
base::OnceClosure next_update_closure) { … }
void HintsManager::SetHintsFetcherFactoryForTesting(
std::unique_ptr<HintsFetcherFactory> hints_fetcher_factory) { … }
void HintsManager::SetClockForTesting(const base::Clock* clock) { … }
void HintsManager::ScheduleActiveTabsHintsFetch() { … }
const std::vector<GURL> HintsManager::GetActiveTabURLsToRefresh() { … }
void HintsManager::FetchHintsForActiveTabs() { … }
void HintsManager::OnHintsForActiveTabsFetched(
const base::flat_set<std::string>& hosts_fetched,
const base::flat_set<GURL>& urls_fetched,
std::optional<std::unique_ptr<proto::GetHintsResponse>>
get_hints_response) { … }
void HintsManager::OnPageNavigationHintsFetched(
base::WeakPtr<OptimizationGuideNavigationData> navigation_data_weak_ptr,
const std::optional<GURL>& navigation_url,
const base::flat_set<GURL>& page_navigation_urls_requested,
const base::flat_set<std::string>& page_navigation_hosts_requested,
std::optional<std::unique_ptr<proto::GetHintsResponse>>
get_hints_response) { … }
void HintsManager::OnFetchedActiveTabsHintsStored() { … }
void HintsManager::OnFetchedPageNavigationHintsStored(
base::WeakPtr<OptimizationGuideNavigationData> navigation_data_weak_ptr,
const std::optional<GURL>& navigation_url,
const base::flat_set<std::string>& page_navigation_hosts_requested) { … }
bool HintsManager::IsHintBeingFetchedForNavigation(const GURL& navigation_url) { … }
void HintsManager::CleanUpFetcherForNavigation(const GURL& navigation_url) { … }
base::Time HintsManager::GetLastHintsFetchAttemptTime() const { … }
void HintsManager::SetLastHintsFetchAttemptTime(base::Time last_attempt_time) { … }
void HintsManager::LoadHintForURL(const GURL& url, base::OnceClosure callback) { … }
void HintsManager::LoadHintForHost(const std::string& host,
base::OnceClosure callback) { … }
void HintsManager::FetchHintsForURLs(const std::vector<GURL>& urls,
proto::RequestContext request_context) { … }
void HintsManager::OnHintLoaded(base::OnceClosure callback,
const proto::Hint* loaded_hint) const { … }
void HintsManager::RegisterOptimizationTypes(
const std::vector<proto::OptimizationType>& optimization_types) { … }
bool HintsManager::HasLoadedOptimizationAllowlist(
proto::OptimizationType optimization_type) { … }
bool HintsManager::HasLoadedOptimizationBlocklist(
proto::OptimizationType optimization_type) { … }
base::flat_map<proto::OptimizationType, OptimizationGuideDecisionWithMetadata>
HintsManager::GetDecisionsWithCachedInformationForURLAndOptimizationTypes(
const GURL& url,
const base::flat_set<proto::OptimizationType>& optimization_types) { … }
void HintsManager::CanApplyOptimizationOnDemand(
const std::vector<GURL>& urls,
const base::flat_set<proto::OptimizationType>& optimization_types,
proto::RequestContext request_context,
OnDemandOptimizationGuideDecisionRepeatingCallback callback,
std::optional<proto::RequestContextMetadata> request_context_metadata) { … }
void HintsManager::FetchOptimizationGuideServiceBatchHints(
const InsertionOrderedSet<std::string>& hosts,
const InsertionOrderedSet<GURL>& urls,
const base::flat_set<optimization_guide::proto::OptimizationType>&
optimization_types,
optimization_guide::proto::RequestContext request_context,
OnDemandOptimizationGuideDecisionRepeatingCallback callback,
std::optional<proto::RequestContextMetadata> request_context_metadata,
const std::string& access_token) { … }
void HintsManager::CanApplyOptimization(
const GURL& url,
proto::OptimizationType optimization_type,
OptimizationGuideDecisionCallback callback) { … }
void HintsManager::ProcessAndInvokeOnDemandHintsCallbacks(
std::unique_ptr<proto::GetHintsResponse> response,
const base::flat_set<GURL> requested_urls,
const base::flat_set<proto::OptimizationType> optimization_types,
OnDemandOptimizationGuideDecisionRepeatingCallback callback) { … }
void HintsManager::OnBatchUpdateHintsFetched(
int32_t request_id,
proto::RequestContext request_context,
const base::flat_set<std::string>& hosts_requested,
const base::flat_set<GURL>& urls_requested,
const base::flat_set<GURL>& urls_with_pending_callback,
const base::flat_set<proto::OptimizationType>& optimization_types,
OnDemandOptimizationGuideDecisionRepeatingCallback callback,
std::optional<std::unique_ptr<proto::GetHintsResponse>>
get_hints_response) { … }
void HintsManager::OnBatchUpdateHintsStored(
const base::flat_set<GURL>& urls,
const base::flat_set<proto::OptimizationType>& optimization_types,
OnDemandOptimizationGuideDecisionRepeatingCallback callback) { … }
std::pair<int32_t, HintsFetcher*>
HintsManager::CreateAndTrackBatchUpdateHintsFetcher() { … }
void HintsManager::CleanUpBatchUpdateHintsFetcher(int32_t request_id) { … }
void HintsManager::InvokeOnDemandHintsCallbackForURL(
const GURL& url,
const base::flat_set<proto::OptimizationType>& optimization_types,
OnDemandOptimizationGuideDecisionRepeatingCallback callback) { … }
void HintsManager::CanApplyOptimizationAsync(
const GURL& navigation_url,
proto::OptimizationType optimization_type,
OptimizationGuideDecisionCallback callback) { … }
OptimizationTypeDecision HintsManager::CanApplyOptimization(
const GURL& navigation_url,
proto::OptimizationType optimization_type,
OptimizationMetadata* optimization_metadata) { … }
OptimizationTypeDecision HintsManager::CanApplyOptimization(
bool is_on_demand_request,
const GURL& url,
proto::OptimizationType optimization_type,
const proto::Hint* url_keyed_hint,
const proto::Hint* host_keyed_hint,
bool skip_cache,
OptimizationMetadata* optimization_metadata) { … }
void HintsManager::PrepareToInvokeRegisteredCallbacks(
const GURL& navigation_url) { … }
void HintsManager::OnReadyToInvokeRegisteredCallbacks(
const GURL& navigation_url) { … }
bool HintsManager::HasOptimizationTypeToFetchFor() { … }
bool HintsManager::IsAllowedToFetchNavigationHints(const GURL& url) { … }
void HintsManager::OnNavigationStartOrRedirect(
OptimizationGuideNavigationData* navigation_data,
base::OnceClosure callback) { … }
void HintsManager::MaybeFetchHintsForNavigation(
OptimizationGuideNavigationData* navigation_data) { … }
void HintsManager::OnNavigationFinish(
const std::vector<GURL>& navigation_redirect_chain) { … }
void HintsManager::OnDeferredStartup() { … }
base::WeakPtr<OptimizationGuideStore> HintsManager::hint_store() { … }
HintCache* HintsManager::hint_cache() { … }
PushNotificationManager* HintsManager::push_notification_manager() { … }
HintsFetcherFactory* HintsManager::GetHintsFetcherFactory() { … }
bool HintsManager::HasAllInformationForDecisionAvailable(
const GURL& navigation_url,
proto::OptimizationType optimization_type) { … }
void HintsManager::ClearFetchedHints() { … }
void HintsManager::ClearHostKeyedHints() { … }
void HintsManager::AddHintForTesting(
const GURL& url,
proto::OptimizationType optimization_type,
const std::optional<OptimizationMetadata>& metadata) { … }
void HintsManager::RemoveFetchedEntriesByHintKeys(
base::OnceClosure on_success,
proto::KeyRepresentation key_representation,
const base::flat_set<std::string>& hint_keys) { … }
}