| // Copyright 2019 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_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_KEYED_SERVICE_H_ |
| #define CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_KEYED_SERVICE_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <vector> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/scoped_observation.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/profiles/profile_observer.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/optimization_guide/core/delivery/optimization_guide_model_provider.h" |
| #include "components/optimization_guide/core/hints/optimization_guide_decider.h" |
| #include "components/optimization_guide/core/model_execution/feature_keys.h" |
| #include "components/optimization_guide/core/model_execution/model_broker_client.h" |
| #include "components/optimization_guide/core/model_execution/model_execution_features_controller.h" |
| #include "components/optimization_guide/core/model_execution/on_device_model_adaptation_loader.h" |
| #include "components/optimization_guide/core/optimization_guide_model_executor.h" |
| #include "components/optimization_guide/core/optimization_guide_on_device_capability_provider.h" |
| #include "components/optimization_guide/proto/hints.pb.h" |
| #include "components/optimization_guide/proto/model_execution.pb.h" |
| #include "components/optimization_guide/proto/model_quality_service.pb.h" |
| #include "components/optimization_guide/proto/models.pb.h" |
| #include "components/optimization_guide/public/mojom/model_broker.mojom.h" |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #include "base/android/scoped_java_ref.h" |
| #include "chrome/browser/bookmarks/android/bookmark_bridge.h" |
| #endif // BUILDFLAG(IS_ANDROID) |
| |
| namespace content { |
| class BrowserContext; |
| } // namespace content |
| |
| namespace contextual_cueing { |
| class ZeroStateSuggestionsPageData; |
| } // namespace contextual_cueing |
| |
| namespace download { |
| class BackgroundDownloadService; |
| } // namespace download |
| |
| namespace glic { |
| class GlicPageContextEligibilityObserver; |
| } // namespace glic |
| |
| namespace on_device_internals { |
| class PageHandler; |
| } |
| |
| namespace optimization_guide { |
| class ChromeHintsManager; |
| class ModelExecutionEnabledBrowserTest; |
| class ModelExecutionLiveTest; |
| class ModelExecutionManager; |
| class ModelInfo; |
| class ModelQualityLogsUploaderService; |
| class ModelValidatorKeyedService; |
| class OnDeviceAssetManager; |
| class OnDeviceModelAvailabilityObserver; |
| class OnDeviceModelComponentStateManager; |
| class OptimizationGuideStore; |
| class OptimizationGuideKeyedServiceBrowserTest; |
| class PredictionManager; |
| class PredictionManagerBrowserTestBase; |
| class PredictionModelDownloadClient; |
| class PredictionModelStoreBrowserTestBase; |
| class PushNotificationManager; |
| class TabUrlProvider; |
| class TopHostProvider; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| namespace android { |
| class OptimizationGuideBridge; |
| } // namespace android |
| #endif // BUILDFLAG(IS_ANDROID) |
| } // namespace optimization_guide |
| |
| class ChromeBrowserMainExtraPartsOptimizationGuide; |
| class GURL; |
| class OptimizationGuideLogger; |
| class OptimizationGuideNavigationData; |
| class Profile; |
| |
| namespace settings { |
| class SettingsUI; |
| } // namespace settings |
| |
| // Keyed service that can be used to get information received from the remote |
| // Optimization Guide Service. For regular profiles, this will do the work to |
| // fetch the necessary information from the remote Optimization Guide Service |
| // in anticipation for when it is needed. For off the record profiles, this will |
| // act in a "read-only" mode where it will only serve information that was |
| // received from the remote Optimization Guide Service when not off the record |
| // and no information will be retrieved. |
| class OptimizationGuideKeyedService |
| : public KeyedService, |
| public optimization_guide::OptimizationGuideDecider, |
| public optimization_guide::OptimizationGuideModelProvider, |
| public optimization_guide::OptimizationGuideModelExecutor, |
| public optimization_guide::OptimizationGuideOnDeviceCapabilityProvider, |
| public ProfileObserver { |
| public: |
| explicit OptimizationGuideKeyedService( |
| content::BrowserContext* browser_context); |
| |
| OptimizationGuideKeyedService(const OptimizationGuideKeyedService&) = delete; |
| OptimizationGuideKeyedService& operator=( |
| const OptimizationGuideKeyedService&) = delete; |
| |
| ~OptimizationGuideKeyedService() override; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); |
| #endif |
| |
| // Allow models to be subscribed via the broker. |
| void BindModelBroker( |
| mojo::PendingReceiver<optimization_guide::mojom::ModelBroker> receiver); |
| virtual std::unique_ptr<optimization_guide::ModelBrokerClient> |
| CreateModelBrokerClient(); |
| |
| // optimization_guide::OptimizationGuideDecider implementation: |
| void RegisterOptimizationTypes( |
| const std::vector<optimization_guide::proto::OptimizationType>& |
| optimization_types) override; |
| void CanApplyOptimization( |
| const GURL& url, |
| optimization_guide::proto::OptimizationType optimization_type, |
| optimization_guide::OptimizationGuideDecisionCallback callback) override; |
| optimization_guide::OptimizationGuideDecision CanApplyOptimization( |
| const GURL& url, |
| optimization_guide::proto::OptimizationType optimization_type, |
| optimization_guide::OptimizationMetadata* optimization_metadata) override; |
| |
| // optimization_guide::OptimizationGuideModelProvider implementation: |
| void AddObserverForOptimizationTargetModel( |
| optimization_guide::proto::OptimizationTarget optimization_target, |
| const std::optional<optimization_guide::proto::Any>& model_metadata, |
| optimization_guide::OptimizationTargetModelObserver* observer) override; |
| void RemoveObserverForOptimizationTargetModel( |
| optimization_guide::proto::OptimizationTarget optimization_target, |
| optimization_guide::OptimizationTargetModelObserver* observer) override; |
| |
| // optimization_guide::OptimizationGuideModelExecutor implementation: |
| std::unique_ptr<Session> StartSession( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| const std::optional<optimization_guide::SessionConfigParams>& |
| config_params) override; |
| void ExecuteModel( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| const google::protobuf::MessageLite& request_metadata, |
| const std::optional<base::TimeDelta>& execution_timeout, |
| optimization_guide::OptimizationGuideModelExecutionResultCallback |
| callback) override; |
| void AddOnDeviceModelAvailabilityChangeObserver( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| optimization_guide::OnDeviceModelAvailabilityObserver* observer) override; |
| void RemoveOnDeviceModelAvailabilityChangeObserver( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| optimization_guide::OnDeviceModelAvailabilityObserver* observer) override; |
| on_device_model::Capabilities GetOnDeviceCapabilities() override; |
| |
| // optimization_guide::OptimizationGuideOnDeviceCapabilityProvider |
| // implementation: |
| optimization_guide::OnDeviceModelEligibilityReason |
| GetOnDeviceModelEligibility( |
| optimization_guide::ModelBasedCapabilityKey feature) override; |
| void GetOnDeviceModelEligibilityAsync( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| const on_device_model::Capabilities& capabilities, |
| base::OnceCallback< |
| void(optimization_guide::OnDeviceModelEligibilityReason)> callback) |
| override; |
| std::optional<optimization_guide::SamplingParamsConfig> |
| GetSamplingParamsConfig( |
| optimization_guide::ModelBasedCapabilityKey feature) override; |
| std::optional<const optimization_guide::proto::Any> GetFeatureMetadata( |
| optimization_guide::ModelBasedCapabilityKey feature) override; |
| |
| // Returns true if the `feature` should be currently enabled for this user. |
| // Note that the return value here may not match the feature enable state on |
| // chrome settings page since the latter takes effect on browser restart. |
| // Virtualized for testing. |
| virtual bool ShouldFeatureBeCurrentlyEnabledForUser( |
| optimization_guide::UserVisibleFeatureKey feature) const; |
| |
| // Returns true if signed-in user is allowed to execute models, disregarding |
| // the `allow_unsigned_user` switch. |
| virtual bool ShouldFeatureAllowModelExecutionForSignedInUser( |
| optimization_guide::UserVisibleFeatureKey feature) const; |
| |
| // Returns whether the `feature` should be currently allowed for showing the |
| // Feedback UI (and sending Feedback reports). |
| virtual bool ShouldFeatureBeCurrentlyAllowedForFeedback( |
| optimization_guide::proto::LogAiDataRequest::FeatureCase feature) const; |
| |
| // Returns true if the opt-in setting should be shown for this profile for |
| // given `feature`. This should only be called by settings UX. |
| bool IsSettingVisible( |
| optimization_guide::UserVisibleFeatureKey feature) const; |
| |
| // Returns true if the user passes all sign-in checks and is allowed to use |
| // model execution. This does not perform any feature related checks such as |
| // allowed by enterprise policy. |
| virtual bool ShouldModelExecutionBeAllowedForUser() const; |
| |
| // Adds `observer` which can observe the change in feature settings. |
| void AddModelExecutionSettingsEnabledObserver( |
| optimization_guide::SettingsEnabledObserver* observer); |
| |
| // Removes `observer`. |
| void RemoveModelExecutionSettingsEnabledObserver( |
| optimization_guide::SettingsEnabledObserver* observer); |
| |
| // Adds hints for a URL with provided metadata to the optimization guide. |
| // For testing purposes only. This will flush any callbacks for |url| that |
| // were registered via |CanApplyOptimization|. If no applicable callbacks |
| // were registered, this will just add the hint for later use. |
| void AddHintForTesting( |
| const GURL& url, |
| optimization_guide::proto::OptimizationType optimization_type, |
| const std::optional<optimization_guide::OptimizationMetadata>& metadata); |
| |
| // Adds hints for a URL with provided metadata to the optimization guide. |
| // Hints added via this method will work for `CanApplyOptimizationOnDemand` |
| // calls. For testing purposes only. |
| void AddOnDemandHintForTesting( |
| const GURL& url, |
| optimization_guide::proto::OptimizationType optimization_type, |
| const optimization_guide::OptimizationGuideDecisionWithMetadata& |
| decision); |
| |
| // Adds a model execution result to be provided when an execution request |
| // comes in with the given `feature`. |
| void AddExecutionResultForTesting( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| optimization_guide::OptimizationGuideModelExecutionResult result); |
| |
| // Override the model file sent to observers of |optimization_target|. Use |
| // |TestModelInfoBuilder| to construct the model metadata. For |
| // testing purposes only. |
| void OverrideTargetModelForTesting( |
| optimization_guide::proto::OptimizationTarget optimization_target, |
| std::unique_ptr<optimization_guide::ModelInfo> model_info); |
| |
| void SetModelQualityLogsUploaderServiceForTesting( |
| std::unique_ptr<optimization_guide::ModelQualityLogsUploaderService> |
| uploader); |
| |
| void AllowUnsignedUserForTesting( |
| optimization_guide::UserVisibleFeatureKey feature); |
| |
| // Creates the platform specific push notification manager. May returns |
| // nullptr for desktop or when the push notification feature is disabled. |
| static std::unique_ptr<optimization_guide::PushNotificationManager> |
| MaybeCreatePushNotificationManager(Profile* profile); |
| |
| OptimizationGuideLogger* GetOptimizationGuideLogger() { |
| return optimization_guide_logger_.get(); |
| } |
| |
| optimization_guide::ModelQualityLogsUploaderService* |
| GetModelQualityLogsUploaderService() { |
| return model_quality_logs_uploader_service_.get(); |
| } |
| |
| virtual optimization_guide::ModelExecutionFeaturesController* |
| GetModelExecutionFeaturesController(); |
| |
| private: |
| friend class ChromeBrowserMainExtraPartsOptimizationGuide; |
| friend class ChromeBrowsingDataRemoverDelegate; |
| friend class contextual_cueing::ZeroStateSuggestionsPageData; |
| friend class glic::GlicPageContextEligibilityObserver; |
| friend class HintsFetcherBrowserTest; |
| friend class on_device_internals::PageHandler; |
| friend class OptimizationGuideInternalsUI; |
| friend class OptimizationGuideMessageHandler; |
| friend class OptimizationGuideWebContentsObserver; |
| friend class optimization_guide::ModelExecutionEnabledBrowserTest; |
| friend class optimization_guide::ModelExecutionLiveTest; |
| friend class optimization_guide::ModelValidatorKeyedService; |
| friend class optimization_guide::OptimizationGuideKeyedServiceBrowserTest; |
| friend class optimization_guide::PredictionManagerBrowserTestBase; |
| friend class optimization_guide::PredictionModelDownloadClient; |
| friend class optimization_guide::PredictionModelStoreBrowserTestBase; |
| friend class PersonalizedHintsFetcherBrowserTest; |
| friend class settings::SettingsUI; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| friend class optimization_guide::android::OptimizationGuideBridge; |
| #endif // BUILDFLAG(IS_ANDROID) |
| |
| // Allows tests to override the value of `version_info::IsOfficialBuild()`. |
| static void SetIsOfficialBuildForTesting(bool is_official_build); |
| |
| // Initializes |this|. |
| void Initialize(); |
| |
| void InitializeModelExecution(Profile* profile); |
| |
| // Virtualized for testing. |
| virtual optimization_guide::ChromeHintsManager* GetHintsManager(); |
| |
| optimization_guide::TopHostProvider* GetTopHostProvider() { |
| return top_host_provider_.get(); |
| } |
| |
| optimization_guide::PredictionManager* GetPredictionManager() { |
| return prediction_manager_.get(); |
| } |
| |
| optimization_guide::OnDeviceModelComponentStateManager* |
| GetComponentManager() { |
| return on_device_component_manager_.get(); |
| } |
| |
| optimization_guide::ModelExecutionManager* GetModelExecutionManager() { |
| return model_execution_manager_.get(); |
| } |
| |
| // Notifies |hints_manager_| that the navigation associated with |
| // |navigation_data| has started or redirected. Virtual for testing. |
| virtual void OnNavigationStartOrRedirect( |
| OptimizationGuideNavigationData* navigation_data); |
| |
| // Notifies |hints_manager_| that the navigation associated with |
| // |navigation_redirect_chain| has finished. Virtual for testing. |
| virtual void OnNavigationFinish( |
| const std::vector<GURL>& navigation_redirect_chain); |
| |
| // Clears data specific to the user. |
| void ClearData(); |
| |
| // KeyedService implementation: |
| void Shutdown() override; |
| |
| // ProfileObserver implementation: |
| void OnProfileInitializationComplete(Profile* profile) override; |
| |
| // optimization_guide::NewOptimizationGuideDecider implementation: |
| void CanApplyOptimizationOnDemand( |
| const std::vector<GURL>& urls, |
| const base::flat_set<optimization_guide::proto::OptimizationType>& |
| optimization_types, |
| optimization_guide::proto::RequestContext request_context, |
| optimization_guide::OnDemandOptimizationGuideDecisionRepeatingCallback |
| callback, |
| std::optional<optimization_guide::proto::RequestContextMetadata> |
| request_context_metadata = std::nullopt) override; |
| |
| download::BackgroundDownloadService* BackgroundDownloadServiceProvider(); |
| |
| bool ComponentUpdatesEnabledProvider() const; |
| |
| // Records synthetic field trial for `feature` with trial name appended with |
| // `feature_name`. |
| void RecordModelExecutionFeatureSyntheticFieldTrial( |
| optimization_guide::UserVisibleFeatureKey feature, |
| std::string_view feature_name); |
| |
| // Ensures the performance class will be up to date and available when |
| // `complete` runs. |
| void EnsurePerformanceClassAvailable(base::OnceClosure complete); |
| |
| void FinishGetOnDeviceModelEligibility( |
| optimization_guide::ModelBasedCapabilityKey feature, |
| const on_device_model::Capabilities& capabilities, |
| base::OnceCallback< |
| void(optimization_guide::OnDeviceModelEligibilityReason)> callback); |
| |
| // Gets the possible capabilities that this device can support. This can be |
| // used to get all the capabilities this device supports before downloading |
| // the model. This will be a superset of GetOnDeviceCapabilities(). |
| on_device_model::Capabilities GetPossibleOnDeviceCapabilities() const; |
| |
| raw_ptr<content::BrowserContext> browser_context_; |
| |
| // The store of hints. |
| std::unique_ptr<optimization_guide::OptimizationGuideStore> hint_store_; |
| |
| // The logger that plumbs the debug logs to the optimization guide |
| // internals page. Must outlive `prediction_manager_` and `hints_manager_`. |
| raw_ptr<OptimizationGuideLogger> optimization_guide_logger_; |
| |
| // Keep a reference to this so it stays alive. |
| scoped_refptr<optimization_guide::OnDeviceModelComponentStateManager> |
| on_device_component_manager_; |
| |
| // The tab URL provider to use for fetching information for the user's active |
| // tabs. Will be null if the user is off the record. |
| std::unique_ptr<optimization_guide::TabUrlProvider> tab_url_provider_; |
| |
| // The top host provider to use for fetching information for the user's top |
| // hosts. Will be null if the user has not consented to this type of browser |
| // behavior. |
| std::unique_ptr<optimization_guide::TopHostProvider> top_host_provider_; |
| |
| // Manages the storing, loading, and fetching of hints. |
| std::unique_ptr<optimization_guide::ChromeHintsManager> hints_manager_; |
| |
| // Manages the storing, loading, and evaluating of optimization target |
| // prediction models. |
| std::unique_ptr<optimization_guide::PredictionManager> prediction_manager_; |
| |
| std::unique_ptr<optimization_guide::OnDeviceAssetManager> |
| on_device_asset_manager_; |
| |
| // Manages the model execution. Not created for off the record profiles. |
| std::unique_ptr<optimization_guide::ModelExecutionManager> |
| model_execution_manager_; |
| |
| std::unique_ptr<optimization_guide::ModelExecutionFeaturesController> |
| model_execution_features_controller_; |
| |
| // Manages the model quality logs uploader service. Not created for off the |
| // record profiles. |
| std::unique_ptr<optimization_guide::ModelQualityLogsUploaderService> |
| model_quality_logs_uploader_service_; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| // Manage and fetch the java object that wraps this OptimizationGuide on |
| // android. |
| std::unique_ptr<optimization_guide::android::OptimizationGuideBridge> |
| android_bridge_; |
| #endif |
| |
| // Used to observe profile initialization event. |
| base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this}; |
| |
| base::WeakPtrFactory<OptimizationGuideKeyedService> weak_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_KEYED_SERVICE_H_ |