#ifndef CHROME_BROWSER_GLIC_PUBLIC_GLIC_KEYED_SERVICE_H_
#define CHROME_BROWSER_GLIC_PUBLIC_GLIC_KEYED_SERVICE_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/containers/flat_set.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "chrome/browser/actor/actor_task_delegate.h"
#include "chrome/browser/glic/glic_metrics.h"
#include "chrome/browser/glic/glic_zero_state_suggestions_manager.h"
#include "chrome/browser/glic/host/context/glic_sharing_manager_provider.h"
#include "chrome/browser/glic/host/glic.mojom.h"
#include "chrome/browser/glic/host/glic_web_client_access.h"
#include "chrome/browser/glic/host/host.h"
#include "chrome/browser/glic/public/context/glic_sharing_manager.h"
#include "chrome/browser/glic/public/glic_enabling.h"
#include "chrome/browser/glic/public/glic_instance.h"
#include "chrome/common/actor.mojom-forward.h"
#include "chrome/common/actor/task_id.h"
#include "chrome/common/actor_webui.mojom-forward.h"
#include "components/autofill/core/browser/integrators/glic/actor_form_filling_types.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/web_contents.h"
class BrowserWindowInterface;
class Profile;
class ProfileManager;
namespace actor {
class ActorKeyedService;
}
namespace contextual_cueing {
class ContextualCueingService;
}
namespace signin {
class IdentityManager;
}
namespace glic {
class AuthController;
class GlicEnabling;
class GlicFreController;
class GlicMetrics;
class GlicOcclusionNotifier;
class GlicProfileManager;
class GlicRegionCaptureController;
class GlicScreenshotCapturer;
class GlicShareImageHandler;
class GlicTabDataObserver;
class GlicWindowController;
class HostManager;
class GlicActorTaskManager;
enum class GlicPrewarmingChecksResult;
enum class GlicPrewarmingFreSource {
kWhatsNew = 0,
kNudge = 1,
kIph = 2,
kTest = 3,
kBrowserCommand = 4,
kMaxValue = kBrowserCommand,
};
class GlicKeyedService : public KeyedService,
public GlicSharingManagerProvider,
public Host::InstanceDelegate,
public base::MemoryPressureListener,
public actor::ActorTaskDelegate {
public:
explicit GlicKeyedService(
Profile* profile,
signin::IdentityManager* identity_manager,
ProfileManager* profile_manager,
GlicProfileManager* glic_profile_manager,
contextual_cueing::ContextualCueingService* contextual_cueing_service,
actor::ActorKeyedService* actor_keyed_service);
GlicKeyedService(const GlicKeyedService&) = delete;
GlicKeyedService& operator=(const GlicKeyedService&) = delete;
~GlicKeyedService() override;
static GlicKeyedService* Get(content::BrowserContext* context);
void Shutdown() override;
void ToggleUI(BrowserWindowInterface* bwi,
bool prevent_close,
mojom::InvocationSource source,
std::optional<std::string> prompt_suggestion = std::nullopt);
void OpenFreDialogInNewTab(BrowserWindowInterface* bwi,
mojom::InvocationSource source);
void CloseAndShutdown();
void CloseAndShutdown(content::RenderFrameHost* render_frame_host);
virtual void CloseFloatingPanel();
GlicEnabling& enabling() { return *enabling_.get(); }
GlicMetrics* metrics() { return metrics_.get(); }
GlicFreController& fre_controller();
GlicWindowController& window_controller() const;
GlicWindowControllerInterface& GetSingleInstanceWindowController() const;
GlicSharingManager& sharing_manager() override;
void GuestAdded(content::WebContents* guest_contents);
virtual bool IsWindowShowing() const;
bool IsPanelShowingForBrowser(const BrowserWindowInterface& bwi) const;
virtual bool IsWindowDetached() const;
bool IsWindowOrFreShowing() const;
void SetContextAccessIndicator(bool show);
using ContextAccessIndicatorChangedCallback =
base::RepeatingCallback<void(bool)>;
base::CallbackListSubscription AddContextAccessIndicatorStatusChangedCallback(
ContextAccessIndicatorChangedCallback callback);
bool IsContextAccessIndicatorShown(const content::WebContents* contents);
bool is_context_access_indicator_enabled() const {
return is_context_access_indicator_enabled_;
}
tabs::TabInterface* CreateTab(
const ::GURL& url,
bool open_in_background,
const std::optional<int32_t>& window_id,
glic::mojom::WebClientHandler::CreateTabCallback callback) override;
void CreateTask(
base::WeakPtr<actor::ActorTaskDelegate> delegate,
actor::webui::mojom::TaskOptionsPtr options,
mojom::WebClientHandler::CreateTaskCallback callback) override;
void PerformActions(
const std::vector<uint8_t>& actions_proto,
mojom::WebClientHandler::PerformActionsCallback callback) override;
void StopActorTask(actor::TaskId task_id,
mojom::ActorTaskStopReason stop_reason) override;
void PauseActorTask(actor::TaskId task_id,
mojom::ActorTaskPauseReason pause_reason,
tabs::TabInterface::Handle tab_handle) override;
void ResumeActorTask(
actor::TaskId task_id,
const mojom::GetTabContextOptions& context_options,
glic::mojom::WebClientHandler::ResumeActorTaskCallback callback) override;
void InterruptActorTask(actor::TaskId task_id) override;
void UninterruptActorTask(actor::TaskId task_id) override;
void CreateActorTab(
actor::TaskId task_id,
bool open_in_background,
const std::optional<int32_t>& initiator_tab_id,
const std::optional<int32_t>& initiator_window_id,
glic::mojom::WebClientHandler::CreateActorTabCallback callback) override;
void FetchZeroStateSuggestions(
bool is_first_run,
std::optional<std::vector<std::string>> supported_tools,
glic::mojom::WebClientHandler::
GetZeroStateSuggestionsForFocusedTabCallback callback) override;
void GetZeroStateSuggestionsAndSubscribe(
bool has_active_subscription,
const mojom::ZeroStateSuggestionsOptions& options,
mojom::WebClientHandler::GetZeroStateSuggestionsAndSubscribeCallback
callback) override;
void RegisterConversation(
glic::mojom::ConversationInfoPtr info,
mojom::WebClientHandler::RegisterConversationCallback callback) override;
void OnWebClientCleared() override;
void PrepareForOpen() override;
void OnInteractionModeChange(mojom::WebClientMode new_mode) override;
glic::GlicInstanceMetrics* instance_metrics() override;
bool IsActive() override;
void OnUserInputSubmitted(glic::mojom::WebClientMode mode);
base::CallbackListSubscription AddUserInputSubmittedCallback(
base::RepeatingClosure callback);
void CaptureRegion(
content::WebContents* web_contents,
mojo::PendingRemote<mojom::CaptureRegionObserver> observer);
void ShareContextImage(tabs::TabInterface* tab,
content::RenderFrameHost* frame,
const ::GURL& src_url);
AuthController& GetAuthController() { return *auth_controller_; }
GlicRegionCaptureController& region_capture_controller();
bool IsActiveWebContents(content::WebContents* contents);
void AddPreloadCallback(base::OnceCallback<void()> callback);
virtual void TryPreload();
void TryPreloadAfterDelay();
virtual void TryPreloadFre(GlicPrewarmingFreSource source);
void Reload(content::RenderFrameHost* render_frame_host);
void Close(content::RenderFrameHost* outermost_render_frame_host);
Profile* profile() const { return profile_; }
void reset_profile_for_test() { profile_ = nullptr; }
base::WeakPtr<GlicKeyedService> GetWeakPtr();
void OnMemoryPressure(base::MemoryPressureLevel level) override;
void OnTabAddedToTask(actor::TaskId task_id,
const tabs::TabInterface::Handle& tab_handle) override;
HostManager& host_manager();
GlicZeroStateSuggestionsManager* zero_state_suggestions_manager() {
return zero_state_suggestions_manager_.get();
}
bool IsProcessHostForGlic(content::RenderProcessHost* process_host);
bool IsGlicWebUi(content::WebContents* web_contents);
GlicInstance* GetInstanceForActiveTab(BrowserWindowInterface* bwi);
GlicInstance* GetInstanceForTab(tabs::TabInterface* tab);
void SendAdditionalContext(tabs::TabHandle tab_handle,
mojom::AdditionalContextPtr context);
using TabDataChangedCallback =
base::RepeatingCallback<void(const TabDataChange&)>;
base::CallbackListSubscription AddTabDataChangedCallback(
TabDataChangedCallback callback);
void RequestToShowCredentialSelectionDialog(
actor::TaskId task_id,
const base::flat_map<std::string, gfx::Image>& icons,
const std::vector<actor_login::Credential>& credentials,
actor::ActorTaskDelegate::CredentialSelectedCallback callback) override;
void RequestToShowUserConfirmationDialog(
actor::TaskId task_id,
const url::Origin& navigation_origin,
bool for_blocklisted_origin,
actor::ActorTaskDelegate::UserConfirmationDialogCallback callback)
override;
void RequestToConfirmNavigation(
actor::TaskId task_id,
const url::Origin& navigation_origin,
actor::ActorTaskDelegate::NavigationConfirmationCallback callback)
override;
void RequestToShowAutofillSuggestionsDialog(
actor::TaskId task_id,
std::vector<autofill::ActorFormFillingRequest> requests,
AutofillSuggestionSelectedCallback callback) override;
private:
void OnZeroStateSuggestionsFetched(
glic::mojom::ZeroStateSuggestionsPtr suggestions,
glic::mojom::WebClientHandler::
GetZeroStateSuggestionsForFocusedTabCallback callback,
std::vector<std::string> returned_suggestions);
void FinishPreload(GlicPrewarmingChecksResult reason);
void FinishPreloadFre(GlicPrewarmingFreSource source,
GlicPrewarmingChecksResult result);
base::RepeatingCallbackList<void(bool)>
context_access_indicator_callback_list_;
bool is_context_access_indicator_enabled_ = false;
base::RepeatingClosureList user_input_submitted_callback_list_;
raw_ptr<Profile> profile_;
std::unique_ptr<GlicEnabling> enabling_;
std::unique_ptr<GlicMetrics> metrics_;
std::unique_ptr<GlicFreController> fre_controller_;
std::unique_ptr<GlicWindowController> window_controller_;
std::unique_ptr<GlicSharingManager> sharing_manager_;
std::unique_ptr<GlicShareImageHandler> share_image_handler_;
std::unique_ptr<GlicScreenshotCapturer> screenshot_capturer_;
std::unique_ptr<GlicRegionCaptureController> region_capture_controller_;
std::unique_ptr<AuthController> auth_controller_;
std::unique_ptr<base::MemoryPressureListenerRegistration>
memory_pressure_listener_registration_;
std::unique_ptr<GlicOcclusionNotifier> occlusion_notifier_;
std::unique_ptr<GlicZeroStateSuggestionsManager>
zero_state_suggestions_manager_;
base::OnceCallback<void()> preload_callback_;
std::unique_ptr<GlicActorTaskManager> actor_task_manager_;
std::unique_ptr<GlicTabDataObserver> tab_data_observer_;
raw_ptr<contextual_cueing::ContextualCueingService>
contextual_cueing_service_;
base::WeakPtrFactory<GlicKeyedService> weak_ptr_factory_{this};
};
}
#endif