| // Copyright 2024 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_AI_AI_DATA_KEYED_SERVICE_H_ | 
 | #define CHROME_BROWSER_AI_AI_DATA_KEYED_SERVICE_H_ | 
 |  | 
 | #include <optional> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | #include "base/feature_list.h" | 
 | #include "base/functional/callback.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "build/build_config.h" | 
 | #include "chrome/common/buildflags.h" | 
 | #include "components/keyed_service/core/keyed_service.h" | 
 | #include "components/optimization_guide/proto/features/actions_data.pb.h" | 
 | #include "components/optimization_guide/proto/features/model_prototyping.pb.h" | 
 |  | 
 | #if BUILDFLAG(ENABLE_GLIC) | 
 | #include "chrome/browser/actor/actor_coordinator.h" | 
 | #include "chrome/browser/glic/host/context/glic_page_context_fetcher.h" | 
 | #endif | 
 |  | 
 | namespace content { | 
 | class WebContents; | 
 | class BrowserContext; | 
 | }  // namespace content | 
 |  | 
 | // Browser service to collect AI data. | 
 | class AiDataKeyedService : public KeyedService { | 
 |  public: | 
 |   // Data related to AiData collection. | 
 |   using BrowserData = optimization_guide::proto::BrowserCollectedInformation; | 
 |   using AiData = std::optional<BrowserData>; | 
 |   using AiDataCallback = base::OnceCallback<void(AiData)>; | 
 |   using AiDataSpecifier = | 
 |       optimization_guide::proto::ModelPrototypingCollectionSpecifier; | 
 |  | 
 |   explicit AiDataKeyedService(content::BrowserContext* browser_context); | 
 |   AiDataKeyedService(const AiDataKeyedService&) = delete; | 
 |   AiDataKeyedService& operator=(const AiDataKeyedService&) = delete; | 
 |   ~AiDataKeyedService() override; | 
 |  | 
 |   // Returns the list of extensions that are allowlisted for data collection. | 
 |   static bool IsExtensionAllowlistedForData(const std::string& extension_id); | 
 |  | 
 |   // Returns the list of extensions that are allowlisted for actions. | 
 |   static bool IsExtensionAllowlistedForActions(const std::string& extension_id); | 
 |  | 
 |   // Fills an AiData and returns the result via the passed in callback. If the | 
 |   // AiData is empty, data collection failed. |callback| is guaranteed to be | 
 |   // called, and guaranteed to be called asynchronously. This method uses a set | 
 |   // of default specifiers. See |GetAiDataWithSpecifiers| for more details. | 
 |   void GetAiData(int dom_node_id, | 
 |                  content::WebContents* web_contents, | 
 |                  std::string user_input, | 
 |                  AiDataCallback callback, | 
 |                  int tabs_for_inner_text = 10); | 
 |  | 
 |   // Fills an AiData and returns the result via the passed in callback. If the | 
 |   // AiData is empty, data collection failed. |callback| is guaranteed to be | 
 |   // called, and guaranteed to be called asynchronously. | 
 |   // |tabs_for_inner_text|: The number of tabs to collect inner text for. | 
 |   void GetAiDataWithSpecifier(content::WebContents* web_contents, | 
 |                               AiDataSpecifier specifier, | 
 |                               AiDataCallback callback); | 
 |  | 
 |   // Starts an actor task. | 
 |   void StartTask( | 
 |       optimization_guide::proto::BrowserStartTask task, | 
 |       base::OnceCallback< | 
 |           void(optimization_guide::proto::BrowserStartTaskResult)> callback); | 
 |  | 
 |   // Stops an actor task. | 
 |   void StopTask(int64_t task_id, base::OnceCallback<void(bool)> callback); | 
 |  | 
 |   // Executes an actor action. The first action in a task must be navigate. | 
 |   void ExecuteAction( | 
 |       optimization_guide::proto::BrowserAction action, | 
 |       base::OnceCallback<void(optimization_guide::proto::BrowserActionResult)> | 
 |           callback); | 
 |  | 
 |   static const base::Feature& GetAllowlistedAiDataExtensionsFeatureForTesting(); | 
 |   static const base::Feature& | 
 |   GetAllowlistedActionsExtensionsFeatureForTesting(); | 
 |  | 
 |  private: | 
 | #if BUILDFLAG(ENABLE_GLIC) | 
 |   // Called when the actor coordinator has created a new tab for the task. | 
 |   void TaskCreated( | 
 |       base::OnceCallback<void(optimization_guide::proto::BrowserActionResult)> | 
 |           callback, | 
 |       optimization_guide::proto::BrowserAction action, | 
 |       int task_id, | 
 |       int tab_id, | 
 |       base::WeakPtr<tabs::TabInterface>); | 
 |   // Converts the result of a page context fetch to a BrowserActionResult. | 
 |   void ConvertToBrowserActionResult( | 
 |       base::OnceCallback<void(optimization_guide::proto::BrowserActionResult)> | 
 |           callback, | 
 |       std::unique_ptr<glic::GlicPageContextFetcher> fetcher, | 
 |       int task_id, | 
 |       int tab_id, | 
 |       bool action_success, | 
 |       glic::mojom::GetContextResultPtr result); | 
 |   // Called when the actor coordinator has started a tas. | 
 |   void OnTaskCreated( | 
 |       base::OnceCallback< | 
 |           void(optimization_guide::proto::BrowserStartTaskResult)> callback, | 
 |       int task_id, | 
 |       int tab_id, | 
 |       base::WeakPtr<tabs::TabInterface> tab); | 
 |   // Called when the actor coordinator has finished an action which required | 
 |   // task creation. | 
 |   void OnActionFinished( | 
 |       base::OnceCallback<void(optimization_guide::proto::BrowserActionResult)> | 
 |           callback, | 
 |       int task_id, | 
 |       int tab_id, | 
 |       bool success); | 
 |   // The actor coordinator which manages task and action routing. | 
 |   std::unique_ptr<actor::ActorCoordinator> actor_coordinator_; | 
 |  | 
 |   // Whether the task still needs a navigate action to be executed as the | 
 |   // first action in the task. | 
 |   bool task_needs_navigate_ = false; | 
 |  | 
 |   // The tab that the task is running on. | 
 |   base::WeakPtr<tabs::TabInterface> tab_; | 
 |  | 
 |   // The tab id and task id of the current task. | 
 |   int tab_id_ = 1; | 
 |   int task_id_ = 1; | 
 | #endif | 
 |  | 
 |   // A `KeyedService` should never outlive the `BrowserContext`. | 
 |   raw_ptr<content::BrowserContext> browser_context_; | 
 |  | 
 |   base::WeakPtrFactory<AiDataKeyedService> weak_factory_{this}; | 
 | }; | 
 |  | 
 | #endif  // CHROME_BROWSER_AI_AI_DATA_KEYED_SERVICE_H_ |