#ifndef ASH_BIRCH_BIRCH_CORAL_PROVIDER_H_
#define ASH_BIRCH_BIRCH_CORAL_PROVIDER_H_
#include "ash/ash_export.h"
#include "ash/birch/birch_data_provider.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/tab_cluster/tab_cluster_ui_controller.h"
#include "ash/wm/coral/coral_controller.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_observer.h"
#include "base/containers/flat_map.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/token.h"
#include "chromeos/ash/services/coral/public/mojom/coral_service.mojom.h"
#include "ui/aura/window_observer.h"
class PrefRegistrySimple;
namespace ash {
class CoralItemRemover;
class Desk;
class ASH_EXPORT BirchCoralProvider : public BirchDataProvider,
public TabClusterUIController::Observer,
public coral::mojom::TitleObserver,
public SessionObserver,
public aura::WindowObserver,
public OverviewObserver {
public:
class Observer : public base::CheckedObserver {
public:
Observer();
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
~Observer() override;
virtual void OnCoralGroupRemoved(const base::Token& group_id);
virtual void OnCoralEntityRemoved(const base::Token& group_id,
std::string_view identifier);
virtual void OnCoralGroupTitleUpdated(const base::Token& group_id,
const std::string& title);
};
BirchCoralProvider();
BirchCoralProvider(const BirchCoralProvider&) = delete;
BirchCoralProvider& operator=(const BirchCoralProvider&) = delete;
~BirchCoralProvider() override;
const Desk* in_session_source_desk() const { return in_session_source_desk_; }
static BirchCoralProvider* Get();
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
const coral::mojom::GroupPtr& GetGroupById(const base::Token& group_id) const;
coral::mojom::GroupPtr ExtractGroupById(const base::Token& group_id);
void RemoveGroup(const base::Token& group_id);
void RemoveItemFromGroup(const base::Token& group_id,
const std::string& identifier);
void OnPostLoginClusterRestored();
mojo::PendingRemote<coral::mojom::TitleObserver> BindRemote();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
bool IsCoralServiceAvailable();
void RequestBirchDataFetch() override;
void OnTabItemAdded(TabClusterUIItem* tab_item) override;
void OnTabItemUpdated(TabClusterUIItem* tab_item) override;
void OnTabItemRemoved(TabClusterUIItem* tab_item) override;
void TitleUpdated(const base::Token& id, const std::string& title) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
void OnActiveUserSessionChanged(const AccountId& account_id) override;
void OnWindowDestroyed(aura::Window* window) override;
void OnWindowParentChanged(aura::Window* window,
aura::Window* parent) override;
void OnOverviewModeEnded() override;
const CoralRequest& GetCoralRequestForTest() const { return request_; }
CoralItemRemover* GetCoralItemRemoverForTest() {
return coral_item_remover_.get();
}
void OverrideCoralResponseForTest(std::unique_ptr<CoralResponse> response);
private:
FRIEND_TEST_ALL_PREFIXES(CoralControllerTest, RestoreSuppressionContext);
FRIEND_TEST_ALL_PREFIXES(CoralControllerTest, InSessionSuppressionContext);
FRIEND_TEST_ALL_PREFIXES(CoralSavedGroupTest, SaveSuppressionContext);
bool GetAndCheckLanguageAvailability();
bool GetGenAIAvailability();
bool HasValidPostLoginData() const;
void HandlePostLoginDataRequest();
void HandleInSessionDataRequest();
bool HasValidPostLoginResponse();
void HandlePostLoginCoralResponse(std::unique_ptr<CoralResponse> response);
void HandleInSessionCoralResponse(std::unique_ptr<CoralResponse> response);
void HandleCoralResponse(std::unique_ptr<CoralResponse> response);
void FilterCoralContentItems(std::vector<coral::mojom::EntityPtr>* items,
CoralSource source);
void MaybeCacheTabEmbedding(TabClusterUIItem* tab_item);
void CacheTabEmbedding(TabClusterUIItem* tab_item);
void ObserveAllWindowsInResponse();
void OnTabRemovedFromSourceDesk(TabClusterUIItem* tab_item);
void OnAppWindowRemovedFromSourceDesk(aura::Window* app_window);
void RemoveEntity(std::string_view entity_identifier);
void Reset();
void OnGenAIAgeAvailabilityReceived(bool allow);
CoralRequest request_;
base::TimeTicks post_login_response_expiration_timestamp_;
bool is_gen_ai_age_availability_checked_ = false;
std::optional<bool> is_gen_ai_location_allow_;
std::optional<std::string> system_language_;
std::unique_ptr<CoralResponse> response_;
std::unique_ptr<CoralResponse> fake_response_;
std::unique_ptr<CoralItemRemover> coral_item_remover_;
mojo::Receiver<coral::mojom::TitleObserver> receiver_{this};
ScopedSessionObserver session_observer_{this};
base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
windows_observation_{this};
base::ScopedObservation<OverviewController, OverviewObserver>
overview_observation_{this};
raw_ptr<const Desk> in_session_source_desk_ = nullptr;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<BirchCoralProvider> weak_ptr_factory_{this};
};
}
#endif