#ifndef ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_
#define ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "ash/app_list/app_list_metrics.h"
#include "ash/app_list/app_list_view_delegate.h"
#include "ash/app_list/app_waiter.h"
#include "ash/app_list/home_launcher_animation_info.h"
#include "ash/app_list/model/search/search_model.h"
#include "ash/app_list/quick_app_access_model.h"
#include "ash/ash_export.h"
#include "ash/capture_mode/sunfish_scanner_feature_watcher.h"
#include "ash/public/cpp/app_list/app_list_client.h"
#include "ash/public/cpp/app_list/app_list_controller.h"
#include "ash/public/cpp/app_list/app_list_model_delegate.h"
#include "ash/public/cpp/feature_discovery_duration_reporter.h"
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell_observer.h"
#include "ash/wm/overview/overview_observer.h"
#include "ash/wm/overview/overview_types.h"
#include "ash/wm/splitview/split_view_observer.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "components/prefs/pref_member.h"
#include "ui/aura/window_observer.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/compositor/compositor_metrics_tracker.h"
#include "ui/display/display_observer.h"
#include "ui/display/manager/display_manager_observer.h"
#include "ui/display/types/display_constants.h"
class PrefRegistrySimple;
namespace display {
enum class TabletState;
}
namespace ash {
class AppListBadgeController;
class AppListBubblePresenter;
class AppListControllerObserver;
class AppListItem;
struct AppListItemMetadata;
class AppListModel;
class AppListModelProvider;
class AppListPresenterImpl;
enum class AppListSortOrder;
class AppsCollectionsController;
class ASH_EXPORT AppListControllerImpl
: public AppListController,
public SessionObserver,
public AppListViewDelegate,
public ShellObserver,
public OverviewObserver,
public SplitViewObserver,
public display::DisplayObserver,
public KeyboardControllerObserver,
public WallpaperControllerObserver,
public display::DisplayManagerObserver,
public aura::WindowObserver,
public FeatureDiscoveryDurationReporter::ReporterObserver,
public SunfishScannerFeatureWatcher::Observer {
public:
AppListControllerImpl();
AppListControllerImpl(const AppListControllerImpl&) = delete;
AppListControllerImpl& operator=(const AppListControllerImpl&) = delete;
~AppListControllerImpl() override;
enum HomeLauncherTransitionState {
kFinished,
kMostlyShown,
kMostlyHidden,
};
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
static void SetSunfishNudgeDisabledForTest(bool is_disabled);
AppListPresenterImpl* fullscreen_presenter() {
return fullscreen_presenter_.get();
}
void SetClient(AppListClient* client) override;
AppListClient* GetClient() override;
void AddObserver(AppListControllerObserver* observer) override;
void RemoveObserver(AppListControllerObserver* obsever) override;
void SetActiveModel(int profile_id,
AppListModel* model,
SearchModel* search_model,
QuickAppAccessModel* quick_app_access_model) override;
void ClearActiveModel() override;
void DismissAppList() override;
void ShowAppList(AppListShowSource source) override;
AppListShowSource LastAppListShowSource() override;
aura::Window* GetWindow() override;
bool IsVisible(const std::optional<int64_t>& display_id) override;
bool IsVisible() override;
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
void OnUserSessionAdded(const AccountId& account_id) override;
void OnSunfishScannerFeatureStatesChanged(
SunfishScannerFeatureWatcher& source) override;
bool GetTargetVisibility(const std::optional<int64_t>& display_id) const;
void Show(int64_t display_id,
AppListShowSource show_source,
base::TimeTicks event_time_stamp,
bool should_record_metrics);
void UpdateAppListWithNewTemporarySortOrder(
const std::optional<AppListSortOrder>& new_order,
bool animate,
base::OnceClosure update_position_closure) override;
bool GoHome(int64_t display_id);
ShelfAction ToggleAppList(int64_t display_id,
AppListShowSource show_source,
base::TimeTicks event_time_stamp);
bool ShouldHomeLauncherBeVisible() const;
AppListNotifier* GetNotifier() override;
std::unique_ptr<ash::ScopedIphSession> CreateLauncherSearchIphSession()
override;
std::vector<AppListSearchControlCategory> GetToggleableCategories()
const override;
void StartSearch(const std::u16string& raw_query) override;
void StartZeroStateSearch(base::OnceClosure callback,
base::TimeDelta timeout) override;
void OpenSearchResult(const std::string& result_id,
int event_flags,
AppListLaunchedFrom launched_from,
AppListLaunchType launch_type,
int suggestion_index,
bool launch_as_default) override;
void InvokeSearchResultAction(const std::string& result_id,
SearchResultActionType action) override;
using GetContextMenuModelCallback =
AppListViewDelegate::GetContextMenuModelCallback;
void ViewShown(int64_t display_id) override;
bool AppListTargetVisibility() const override;
void ViewClosing() override;
void ActivateItem(const std::string& id,
int event_flags,
AppListLaunchedFrom launched_from,
bool is_app_above_the_fold) override;
void GetContextMenuModel(const std::string& id,
AppListItemContext item_context,
GetContextMenuModelCallback callback) override;
void ShowWallpaperContextMenu(const gfx::Point& onscreen_location,
ui::mojom::MenuSourceType source_type) override;
bool KeyboardTraversalEngaged() override;
bool CanProcessEventsOnApplistViews() override;
bool ShouldDismissImmediately() override;
void OnSearchResultVisibilityChanged(const std::string& id,
bool visibility) override;
void OnStateTransitionAnimationCompleted(
AppListViewState state,
bool was_animation_interrupted) override;
void LoadIcon(const std::string& app_id) override;
bool HasValidProfile() const override;
bool ShouldHideContinueSection() const override;
void SetHideContinueSection(bool hide) override;
bool IsCategoryEnabled(AppListSearchControlCategory category) override;
void SetCategoryEnabled(AppListSearchControlCategory category,
bool enabled) override;
void GetAppLaunchedMetricParams(
AppLaunchedMetricParams* metric_params) override;
gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds) override;
AppListState GetCurrentAppListPage() const override;
void OnAppListPageChanged(AppListState page) override;
AppListViewState GetAppListViewState() const override;
void OnViewStateChanged(AppListViewState state) override;
int GetShelfSize() override;
int GetSystemShelfInsetsInTabletMode() override;
bool IsInTabletMode() const override;
void RecordAppsDefaultVisibility(
const std::vector<std::string>& apps_above_the_fold,
const std::vector<std::string>& apps_below_the_fold,
bool is_apps_collections_page) override;
void OnVisibilityChanged(bool visible, int64_t display_id);
void OnVisibilityWillChange(bool visible, int64_t display_id);
void OnShelfAlignmentChanged(aura::Window* root_window,
ShelfAlignment old_alignment) override;
void OnShellDestroying() override;
void OnOverviewModeStarting() override;
void OnOverviewModeStartingAnimationComplete(bool canceled) override;
void OnOverviewModeEnding(OverviewSession* session) override;
void OnOverviewModeEnded() override;
void OnOverviewModeEndingAnimationComplete(bool canceled) override;
void OnSplitViewStateChanged(SplitViewController::State previous_state,
SplitViewController::State state) override;
void OnDisplayTabletStateChanged(display::TabletState state) override;
void OnKeyboardVisibilityChanged(bool is_visible) override;
void OnWallpaperPreviewStarted() override;
void OnWallpaperPreviewEnded() override;
void OnDidApplyDisplayChanges() override;
void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
void OnWindowDestroyed(aura::Window* window) override;
aura::Window* GetHomeScreenWindow() const;
using UpdateAnimationSettingsCallback =
base::RepeatingCallback<void(ui::ScopedLayerAnimationSettings* settings)>;
void UpdateScaleAndOpacityForHomeLauncher(
float scale,
float opacity,
std::optional<HomeLauncherAnimationInfo> animation_info,
UpdateAnimationSettingsCallback callback);
void OnHomeLauncherAnimationComplete(bool shown, int64_t display_id);
void OnHomeLauncherPositionChanged(int percent_shown, int64_t display_id);
bool IsHomeScreenVisible();
void OnWindowDragStarted();
void OnWindowDragEnded(bool animate);
bool onscreen_keyboard_shown() const { return onscreen_keyboard_shown_; }
void Back();
void SetKeyboardTraversalMode(bool engaged);
using StateTransitionAnimationCallback =
base::RepeatingCallback<void(AppListViewState)>;
void SetStateTransitionAnimationCallbackForTesting(
StateTransitionAnimationCallback callback);
using HomeLauncherAnimationCallback =
base::RepeatingCallback<void(bool shown)>;
void SetHomeLauncherAnimationCallbackForTesting(
HomeLauncherAnimationCallback callback);
AppListBubblePresenter* bubble_presenter_for_test() {
return bubble_presenter_.get();
}
void RecordShelfAppLaunched();
void UpdateFullscreenLauncherContainer(
std::optional<int64_t> display_id = std::nullopt);
aura::Window* GetFullscreenLauncherContainerForDisplayId(
std::optional<int64_t> display_id = std::nullopt);
void RecordAppListState();
AppListBadgeController* badge_controller_for_test() {
return badge_controller_.get();
}
int GetPreferredBubbleWidth(aura::Window* root_window) const;
bool SetHomeButtonQuickApp(const std::string& app_id);
void MaybeShowSunfishLauncherNudge(views::View* launcher_button);
private:
AppListModel* GetModel();
SearchModel* GetSearchModel();
std::unique_ptr<AppListItem> CreateAppListItem(
std::unique_ptr<AppListItemMetadata> metadata);
void UpdateSearchBoxUiVisibilities();
int64_t GetDisplayIdToShowAppListOn();
void ResetHomeLauncherIfShown();
void ShowHomeScreen(AppListShowSource show_source);
void UpdateHomeScreenVisibility();
bool ShouldShowHomeScreen() const;
void UpdateForOverviewModeChange(bool show_home_launcher, bool animate);
void Shutdown();
void RecordAppLaunched(AppListLaunchedFrom launched_from);
void UpdateTrackedAppWindow();
void StartTrackingAnimationSmoothness(int64_t display_id);
void RecordAnimationSmoothness();
void OnGoHomeWindowAnimationsEnded(int64_t display_id);
void OnReporterActivated() override;
void OnChangedToInTabletMode();
void OnChangedToInClamshellMode();
int GetFullscreenLauncherContainerId() const;
void ShowGeminiButton(std::string app_name);
void HideGeminiButton();
HomeLauncherTransitionState home_launcher_transition_state_ = kFinished;
raw_ptr<AppListClient> client_ = nullptr;
std::optional<AppListShowSource> last_open_source_;
std::unique_ptr<AppListModelProvider> model_provider_;
StateTransitionAnimationCallback state_transition_animation_callback_;
std::unique_ptr<AppListPresenterImpl> fullscreen_presenter_;
std::unique_ptr<AppListBubblePresenter> bubble_presenter_;
AppListState app_list_page_ = AppListState::kInvalidState;
AppListViewState app_list_view_state_ = AppListViewState::kClosed;
bool onscreen_keyboard_shown_ = false;
bool keyboard_traversal_engaged_ = false;
bool is_shutdown_ = false;
bool should_dismiss_immediately_ = false;
bool last_target_visible_ = false;
int64_t last_target_visible_display_id_ = display::kInvalidDisplayId;
bool last_visible_ = false;
int64_t last_visible_display_id_ = display::kInvalidDisplayId;
int profile_id_ = kAppListInvalidProfileID;
raw_ptr<aura::Window> tracked_app_window_ = nullptr;
HomeLauncherAnimationCallback home_launcher_animation_callback_;
std::optional<AppListViewState> recorded_app_list_view_state_;
std::optional<bool> recorded_app_list_visibility_;
std::optional<base::TimeTicks> last_show_timestamp_;
base::ObserverList<AppListControllerObserver> observers_;
std::unique_ptr<AppListBadgeController> badge_controller_;
bool in_wallpaper_preview_ = false;
bool in_window_dragging_ = false;
bool has_session_started_ = false;
std::optional<OverviewEnterExitType> overview_exit_type_;
std::optional<ui::ThroughputTracker> smoothness_tracker_;
std::optional<AppWaiter> gemini_app_waiter_;
std::unique_ptr<AppsCollectionsController> apps_collections_controller_;
base::ScopedObservation<SplitViewController, SplitViewObserver>
split_view_observation_{this};
base::ScopedObservation<SunfishScannerFeatureWatcher,
SunfishScannerFeatureWatcher::Observer>
sunfish_scanner_feature_observation_{this};
base::WeakPtrFactory<AppListControllerImpl> weak_ptr_factory_{this};
};
}
#endif