1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_
#define ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_
#include <memory>
#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/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/assistant/model/assistant_ui_model_observer.h"
#include "ash/display/window_tree_host_manager.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/assistant/controller/assistant_controller_observer.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/tablet_mode_observer.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_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/aura/window_observer.h"
#include "ui/display/types/display_constants.h"
class PrefRegistrySimple;
namespace ash {
class AppListBadgeController;
class AppListBubblePresenter;
class AppListControllerObserver;
class AppListItem;
struct AppListItemMetadata;
class AppListModel;
class AppListModelProvider;
class AppListPresenterImpl;
enum class AppListSortOrder;
// Ash's AppListController owns the AppListModel and implements interface
// functions that allow Chrome to modify and observe the Shelf and AppListModel
// state. It also controls the "home launcher", the tablet mode app list.
class ASH_EXPORT AppListControllerImpl
: public AppListController,
public SessionObserver,
public AppListViewDelegate,
public ShellObserver,
public OverviewObserver,
public SplitViewObserver,
public TabletModeObserver,
public KeyboardControllerObserver,
public WallpaperControllerObserver,
public AssistantStateObserver,
public WindowTreeHostManager::Observer,
public aura::WindowObserver,
public AssistantControllerObserver,
public AssistantUiModelObserver,
public FeatureDiscoveryDurationReporter::ReporterObserver {
public:
AppListControllerImpl();
AppListControllerImpl(const AppListControllerImpl&) = delete;
AppListControllerImpl& operator=(const AppListControllerImpl&) = delete;
~AppListControllerImpl() override;
enum HomeLauncherTransitionState {
kFinished, // No drag or animation is in progress
kMostlyShown, // The home launcher occupies more than half of the screen
kMostlyHidden, // The home launcher occupies less than half of the screen
};
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
AppListPresenterImpl* fullscreen_presenter() {
return fullscreen_presenter_.get();
}
// AppListController:
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 absl::optional<int64_t>& display_id) override;
bool IsVisible() override;
bool IsImageSearchToggleable() override;
// SessionObserver:
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
void OnUserSessionAdded(const AccountId& account_id) override;
// Methods used in ash:
bool GetTargetVisibility(const absl::optional<int64_t>& display_id) const;
// 'should_record_metrics' is false when transitioning to tablet mode with a
// visible window which is shown over, and thus hides, the app list.
void Show(int64_t display_id,
AppListShowSource show_source,
base::TimeTicks event_time_stamp,
bool should_record_metrics);
void UpdateAppListWithNewTemporarySortOrder(
const absl::optional<AppListSortOrder>& new_order,
bool animate,
base::OnceClosure update_position_closure) override;
// In tablet mode, takes the user to the home screen, either by ending
// Overview Mode/Split View Mode or by minimizing the other windows. Returns
// false if there was nothing to do because the given display was already
// "home". Illegal to call in clamshell mode.
bool GoHome(int64_t display_id);
// Toggles app list visibility. In tablet mode, this can only show the app
// list (by hiding any windows that might be shown over the homde launcher).
// |display_id| is the id of display where app list should toggle.
// |show_source| is the source of the event. |event_time_stamp| records the
// event timestamp.
ShelfAction ToggleAppList(int64_t display_id,
AppListShowSource show_source,
base::TimeTicks event_time_stamp);
// Returns whether the home launcher should be visible.
bool ShouldHomeLauncherBeVisible() const;
// AppListViewDelegate:
AppListNotifier* GetNotifier() override;
std::unique_ptr<ash::ScopedIphSession> CreateLauncherSearchIphSession()
override;
void StartAssistant() 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) override;
void GetContextMenuModel(const std::string& id,
AppListItemContext item_context,
GetContextMenuModelCallback callback) override;
void ShowWallpaperContextMenu(const gfx::Point& onscreen_location,
ui::MenuSourceType source_type) override;
bool KeyboardTraversalEngaged() override;
bool CanProcessEventsOnApplistViews() override;
bool ShouldDismissImmediately() override;
AssistantViewDelegate* GetAssistantViewDelegate() override;
void OnSearchResultVisibilityChanged(const std::string& id,
bool visibility) override;
bool IsAssistantAllowedAndEnabled() const 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() override;
// Notifies observers of AppList visibility changes.
void OnVisibilityChanged(bool visible, int64_t display_id);
void OnVisibilityWillChange(bool visible, int64_t display_id);
// ShellObserver:
void OnShelfAlignmentChanged(aura::Window* root_window,
ShelfAlignment old_alignment) override;
void OnShellDestroying() override;
// OverviewObserver:
void OnOverviewModeStarting() override;
void OnOverviewModeStartingAnimationComplete(bool canceled) override;
void OnOverviewModeEnding(OverviewSession* session) override;
void OnOverviewModeEnded() override;
void OnOverviewModeEndingAnimationComplete(bool canceled) override;
// SplitViewObserver:
void OnSplitViewStateChanged(SplitViewController::State previous_state,
SplitViewController::State state) override;
// TabletModeObserver:
void OnTabletModeStarted() override;
void OnTabletModeEnded() override;
// KeyboardControllerObserver:
void OnKeyboardVisibilityChanged(bool is_visible) override;
// WallpaperControllerObserver:
void OnWallpaperPreviewStarted() override;
void OnWallpaperPreviewEnded() override;
// AssistantStateObserver:
void OnAssistantStatusChanged(assistant::AssistantStatus status) override;
void OnAssistantSettingsEnabled(bool enabled) override;
void OnAssistantFeatureAllowedChanged(
assistant::AssistantAllowedState state) override;
// WindowTreeHostManager::Observer:
void OnDisplayConfigurationChanged() override;
// aura::WindowObserver:
void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
void OnWindowDestroyed(aura::Window* window) override;
// AssistantControllerObserver:
void OnAssistantReady() override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(
AssistantVisibility new_visibility,
AssistantVisibility old_visibility,
absl::optional<AssistantEntryPoint> entry_point,
absl::optional<AssistantExitPoint> exit_point) override;
// Gets the home screen window, if available, or null if the home screen
// window is being hidden for effects (e.g. when dragging windows or
// previewing the wallpaper).
aura::Window* GetHomeScreenWindow() const;
// Scales the home launcher view maintaining the view center point, and
// updates its opacity. If |callback| is non-null, the update should be
// animated, and the |callback| should be called with the animation settings.
// |animation_info| - Information about the transition trigger that will be
// used to report animation metrics. Should be set only if |callback| is
// not null (otherwise the transition will not be animated).
using UpdateAnimationSettingsCallback =
base::RepeatingCallback<void(ui::ScopedLayerAnimationSettings* settings)>;
void UpdateScaleAndOpacityForHomeLauncher(
float scale,
float opacity,
absl::optional<HomeLauncherAnimationInfo> animation_info,
UpdateAnimationSettingsCallback callback);
// Called when the HomeLauncher positional animation has completed.
void OnHomeLauncherAnimationComplete(bool shown, int64_t display_id);
// Called when the HomeLauncher has changed its position on the screen,
// during either an animation or a drag.
void OnHomeLauncherPositionChanged(int percent_shown, int64_t display_id);
// True if home screen is visible.
bool IsHomeScreenVisible();
// Called when a window starts/ends dragging. If the home screen is shown, we
// should hide it during dragging a window and reshow it when the drag ends.
void OnWindowDragStarted();
// If |animate| is true, scale-in-to-show home screen if home screen should
// be shown after drag ends.
void OnWindowDragEnded(bool animate);
bool onscreen_keyboard_shown() const { return onscreen_keyboard_shown_; }
// Performs the 'back' action for the active page.
void Back();
void SetKeyboardTraversalMode(bool engaged);
// Returns whether the assistant page is showing (either in bubble app list or
// fullscreen app list).
bool IsShowingEmbeddedAssistantUI() const;
// Sets up `close_assistant_ui_runner_` to close the assistant.
void ScheduleCloseAssistant();
// Runs `close_assistant_ui_runner_` when it is non-null.
void MaybeCloseAssistant();
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();
// Updates which container the fullscreen launcher window should be in.
void UpdateFullscreenLauncherContainer(
absl::optional<int64_t> display_id = absl::nullopt);
// Returns the parent window of the `AppListView` for a |display_id|.
aura::Window* GetFullscreenLauncherContainerForDisplayId(
absl::optional<int64_t> display_id = absl::nullopt);
// Methods for recording the state of the app list before it changes in order
// to record metrics.
void RecordAppListState();
AppListBadgeController* badge_controller_for_test() {
return badge_controller_.get();
}
// Returns the preferred width for the bubble launcher for the |root_window|.
int GetPreferredBubbleWidth(aura::Window* root_window) const;
// Set the launchable quick app button shown next to the home button. This app
// icon is shown next to the home button until the app is launched or the
// launcher is opened.
// Returns true when the quick app was changed to a valid `app_id` or reset
// using an empty `app_id`.
bool SetHomeButtonQuickApp(const std::string& app_id);
private:
// Convenience methods for getting models from `model_provider_`.
AppListModel* GetModel();
SearchModel* GetSearchModel();
std::unique_ptr<AppListItem> CreateAppListItem(
std::unique_ptr<AppListItemMetadata> metadata);
// Update the visibility of UIs controlled by `SearchBoxModel`.
void UpdateSearchBoxUiVisibilities();
int64_t GetDisplayIdToShowAppListOn();
void ResetHomeLauncherIfShown();
void ShowHomeScreen(AppListShowSource show_source);
// Updates the visibility of the home screen based on e.g. if the device is
// in overview mode.
void UpdateHomeScreenVisibility();
// Returns true if home screen should be shown based on the current
// configuration.
bool ShouldShowHomeScreen() const;
// Updates home launcher scale and opacity when the overview mode state
// changes. `show_home_launcher` - whether the home launcher should be shown.
// `animate` - whether the transition should be animated.
void UpdateForOverviewModeChange(bool show_home_launcher, bool animate);
// Shuts down the AppListControllerImpl, removing itself as an observer.
void Shutdown();
// Record the app launch for AppListAppLaunchedV2 metric.
void RecordAppLaunched(AppListLaunchedFrom launched_from);
// Updates the window that is tracked as |tracked_app_window_|.
void UpdateTrackedAppWindow();
// Responsible for starting or stopping |smoothness_tracker_|.
void StartTrackingAnimationSmoothness(int64_t display_id);
void RecordAnimationSmoothness();
// Called when all the window minimize animations triggered by a tablet mode
// "Go Home" have ended. |display_id| is the home screen display ID.
void OnGoHomeWindowAnimationsEnded(int64_t display_id);
// FeatureDiscoveryDurationReporter::ReporterObserver:
void OnReporterActivated() override;
// Gets the container which should contain the fullscreen launcher.
int GetFullscreenLauncherContainerId() const;
// Whether the home launcher is
// * being shown (either through an animation or a drag)
// * being hidden (either through an animation or a drag)
// * not animating nor being dragged.
// In the case where the home launcher is being dragged, the gesture can
// reverse direction at any point during the drag, in which case the only
// information given by "showing" versus "hiding" is the starting point of
// the drag and the assumed final state (which won't be accurate if the
// gesture is reversed).
HomeLauncherTransitionState home_launcher_transition_state_ = kFinished;
raw_ptr<AppListClient, ExperimentalAsh> client_ = nullptr;
// Tracks the most recent show source for the app list.
absl::optional<AppListShowSource> last_open_source_;
// Tracks active app list and search models to app list UI stack. It can be
// accessed outside AppListModelControllerImpl using
// `AppListModelController::Get()`.
std::unique_ptr<AppListModelProvider> model_provider_;
// Manages the tablet mode home launcher.
// |fullscreen_presenter_| should be put below |client_| and |model_| to
// prevent a crash in destruction.
std::unique_ptr<AppListPresenterImpl> fullscreen_presenter_;
// Manages the clamshell launcher bubble.
std::unique_ptr<AppListBubblePresenter> bubble_presenter_;
// Tracks the current page shown in the app list view (tracked for the
// fullscreen presenter).
AppListState app_list_page_ = AppListState::kInvalidState;
// Tracks the current state of `AppListView` (tracked for the fullscreen
// presenter)
AppListViewState app_list_view_state_ = AppListViewState::kClosed;
// True if the on-screen keyboard is shown.
bool onscreen_keyboard_shown_ = false;
// True if the most recent event handled by |presenter_| was a key event.
bool keyboard_traversal_engaged_ = false;
// True if Shutdown() has been called.
bool is_shutdown_ = false;
// Whether to immediately dismiss the AppListView.
bool should_dismiss_immediately_ = false;
// The last target visibility change and its display id.
bool last_target_visible_ = false;
int64_t last_target_visible_display_id_ = display::kInvalidDisplayId;
// The last visibility change and its display id.
bool last_visible_ = false;
int64_t last_visible_display_id_ = display::kInvalidDisplayId;
// Used in mojo callings to specify the profile whose app list data is
// read/written by Ash side through IPC. Notice that in multi-profile mode,
// each profile has its own AppListModelUpdater to manipulate app list items.
int profile_id_ = kAppListInvalidProfileID;
// Used when tablet mode is active to track the MRU window among the windows
// that were obscuring the home launcher when the home launcher visibility was
// last calculated.
// This window changing it's visibility to false is used as a signal that the
// home launcher visibility should be recalculated.
raw_ptr<aura::Window, ExperimentalAsh> tracked_app_window_ = nullptr;
// A callback that can be registered by a test to wait for the app list state
// transition animation to finish.
StateTransitionAnimationCallback state_transition_animation_callback_;
// A callback that can be registered by a test to wait for the home launcher
// visibility animation to finish. Should only be used in tablet mode.
HomeLauncherAnimationCallback home_launcher_animation_callback_;
// The AppListViewState at the moment it was recorded, used to record app
// launching metrics. This allows an accurate AppListViewState to be recorded
// before AppListViewState changes.
absl::optional<AppListViewState> recorded_app_list_view_state_;
// Whether the applist was shown at the moment it was recorded, used to record
// app launching metrics. This is recorded because AppList visibility can
// change before the metric is recorded.
absl::optional<bool> recorded_app_list_visibility_;
// The last time the app list was shown.
absl::optional<base::TimeTicks> last_show_timestamp_;
base::ObserverList<AppListControllerObserver> observers_;
// Sub-controller to handle app item badges. Must be constructed after
// `model_provider_`.
std::unique_ptr<AppListBadgeController> badge_controller_;
// Whether the wallpaper is being previewed. The home screen should be hidden
// during wallpaper preview.
bool in_wallpaper_preview_ = false;
// Whether we're currently in a window dragging process.
bool in_window_dragging_ = false;
// Whether a session was ever set ACTIVE for the app list.
bool has_session_started_ = false;
// The last overview mode exit type - cached when the overview exit starts, so
// it can be used to decide how to update home screen when overview mode exit
// animations are finished (at which point this information will not be
// available).
absl::optional<OverviewEnterExitType> overview_exit_type_;
// Responsible for recording smoothness related UMA stats for home screen
// animations.
absl::optional<ui::ThroughputTracker> smoothness_tracker_;
// Used for closing the Assistant ui in the asynchronous way.
base::ScopedClosureRunner close_assistant_ui_runner_;
base::ScopedObservation<SplitViewController, SplitViewObserver>
split_view_observation_{this};
base::WeakPtrFactory<AppListControllerImpl> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_
|