blob: 04dc2c72c18c8fc6cb3a51bab05b9efaa899fd07 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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_presenter_impl.h"
#include "ash/app_list/app_list_view_delegate.h"
#include "ash/app_list/model/app_list_model.h"
#include "ash/app_list/model/app_list_model_observer.h"
#include "ash/app_list/model/search/search_model.h"
#include "ash/ash_export.h"
#include "ash/assistant/assistant_controller_observer.h"
#include "ash/assistant/model/assistant_ui_model_observer.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/home_screen/home_screen_delegate.h"
#include "ash/public/cpp/app_list/app_list_controller.h"
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/tablet_mode_observer.h"
#include "ash/public/cpp/wallpaper_controller_observer.h"
#include "ash/session/session_observer.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell_observer.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_observer.h"
#include "base/observer_list.h"
#include "components/sync/model/string_ordinal.h"
#include "ui/aura/window_observer.h"
#include "ui/display/types/display_constants.h"
class PrefRegistrySimple;
namespace ui {
class MouseWheelEvent;
} // namespace ui
namespace ash {
class AppListControllerObserver;
// Ash's AppListController owns the AppListModel and implements interface
// functions that allow Chrome to modify and observe the Shelf and AppListModel
// state.
class ASH_EXPORT AppListControllerImpl : public AppListController,
public SessionObserver,
public AppListModelObserver,
public AppListViewDelegate,
public ShellObserver,
public OverviewObserver,
public TabletModeObserver,
public KeyboardControllerObserver,
public WallpaperControllerObserver,
public AssistantStateObserver,
public WindowTreeHostManager::Observer,
public aura::WindowObserver,
public MruWindowTracker::Observer,
public AssistantControllerObserver,
public AssistantUiModelObserver,
public HomeScreenDelegate {
public:
AppListControllerImpl();
~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* presenter() { return &presenter_; }
// AppListController:
void SetClient(AppListClient* client) override;
AppListClient* GetClient() override;
void AddItem(std::unique_ptr<AppListItemMetadata> app_item) override;
void AddItemToFolder(std::unique_ptr<AppListItemMetadata> app_item,
const std::string& folder_id) override;
void RemoveItem(const std::string& id) override;
void RemoveUninstalledItem(const std::string& id) override;
void MoveItemToFolder(const std::string& id,
const std::string& folder_id) override;
void SetStatus(AppListModelStatus status) override;
void SetState(AppListState state) override;
void HighlightItemInstalledFromUI(const std::string& id) override;
void SetSearchEngineIsGoogle(bool is_google) override;
void SetSearchTabletAndClamshellAccessibleName(
const base::string16& tablet_accessible_name,
const base::string16& clamshell_accessible_name) override;
void SetSearchHintText(const base::string16& hint_text) override;
void UpdateSearchBox(const base::string16& text,
bool initiated_by_user) override;
void PublishSearchResults(
std::vector<std::unique_ptr<SearchResultMetadata>> results) override;
void SetItemMetadata(const std::string& id,
std::unique_ptr<AppListItemMetadata> data) override;
void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) override;
void SetItemIsInstalling(const std::string& id, bool is_installing) override;
void SetItemPercentDownloaded(const std::string& id,
int32_t percent_downloaded) override;
void SetModelData(int profile_id,
std::vector<std::unique_ptr<AppListItemMetadata>> apps,
bool is_search_engine_google) override;
void SetSearchResultMetadata(
std::unique_ptr<SearchResultMetadata> metadata) override;
void SetSearchResultIsInstalling(const std::string& id,
bool is_installing) override;
void SetSearchResultPercentDownloaded(const std::string& id,
int32_t percent_downloaded) override;
void NotifySearchResultItemInstalled(const std::string& id) override;
void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) override;
void FindOrCreateOemFolder(
const std::string& oem_folder_name,
const syncer::StringOrdinal& preferred_oem_position,
FindOrCreateOemFolderCallback callback) override;
void ResolveOemFolderPosition(
const syncer::StringOrdinal& preferred_oem_position,
ResolveOemFolderPositionCallback callback) override;
void DismissAppList() override;
void GetAppInfoDialogBounds(GetAppInfoDialogBoundsCallback callback) override;
void ShowAppList() override;
aura::Window* GetWindow() override;
bool IsVisible() override;
// AppListModelObserver:
void OnAppListItemAdded(AppListItem* item) override;
void OnAppListItemWillBeDeleted(AppListItem* item) override;
void OnAppListItemUpdated(AppListItem* item) override;
void OnAppListStateChanged(AppListState new_state,
AppListState old_state) override;
// SessionObserver:
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
// Methods used in ash:
bool GetTargetVisibility() const;
void Show(int64_t display_id,
base::Optional<AppListShowSource> show_source,
base::TimeTicks event_time_stamp);
void UpdateYPositionAndOpacity(int y_position_in_screen,
float background_opacity);
void EndDragFromShelf(AppListViewState app_list_state);
void ProcessMouseWheelEvent(const ui::MouseWheelEvent& event);
// 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);
AppListViewState GetAppListViewState();
// Returns whether the home launcher should be visible.
bool ShouldHomeLauncherBeVisible() const;
// AppListViewDelegate:
AppListModel* GetModel() override;
SearchModel* GetSearchModel() override;
void StartAssistant() override;
void StartSearch(const base::string16& raw_query) 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 LogResultLaunchHistogram(SearchResultLaunchLocation launch_location,
int suggestion_index) override;
void LogSearchAbandonHistogram() override;
void InvokeSearchResultAction(const std::string& result_id,
int action_index,
int event_flags) override;
using GetContextMenuModelCallback =
AppListViewDelegate::GetContextMenuModelCallback;
void GetSearchResultContextMenuModel(
const std::string& result_id,
GetContextMenuModelCallback callback) override;
void ViewShown(int64_t display_id) override;
void ViewClosing() override;
void ViewClosed() override;
const std::vector<SkColor>& GetWallpaperProminentColors() override;
void ActivateItem(const std::string& id,
int event_flags,
AppListLaunchedFrom launched_from) override;
void GetContextMenuModel(const std::string& id,
GetContextMenuModelCallback callback) override;
ui::ImplicitAnimationObserver* GetAnimationObserver(
AppListViewState target_state) override;
void ShowWallpaperContextMenu(const gfx::Point& onscreen_location,
ui::MenuSourceType source_type) override;
bool ProcessHomeLauncherGesture(ui::GestureEvent* event) override;
bool KeyboardTraversalEngaged() override;
bool CanProcessEventsOnApplistViews() override;
bool ShouldDismissImmediately() override;
void GetNavigableContentsFactory(
mojo::PendingReceiver<content::mojom::NavigableContentsFactory> receiver)
override;
int GetTargetYForAppListHide(aura::Window* root_window) override;
AssistantViewDelegate* GetAssistantViewDelegate() override;
void OnSearchResultVisibilityChanged(const std::string& id,
bool visibility) override;
void NotifySearchResultsForLogging(
const base::string16& raw_query,
const SearchResultIdWithPositionIndices& results,
int position_index) override;
bool IsAssistantAllowedAndEnabled() const override;
bool ShouldShowAssistantPrivacyInfo() const override;
void MaybeIncreaseAssistantPrivacyInfoShownCount() override;
void MarkAssistantPrivacyInfoDismissed() override;
void OnStateTransitionAnimationCompleted(AppListViewState state) override;
void GetAppLaunchedMetricParams(
AppLaunchedMetricParams* metric_params) override;
gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds) override;
int GetShelfSize() override;
void AddObserver(AppListControllerObserver* observer);
void RemoveObserver(AppListControllerObserver* obsever);
// 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;
// TabletModeObserver:
void OnTabletModeStarted() override;
void OnTabletModeEnded() override;
// KeyboardControllerObserver:
void OnKeyboardVisibilityChanged(bool is_visible) override;
// WallpaperControllerObserver:
void OnWallpaperColorsChanged() override;
// AssistantStateObserver:
void OnAssistantStatusChanged(mojom::AssistantState state) override;
void OnAssistantSettingsEnabled(bool enabled) override;
void OnAssistantFeatureAllowedChanged(
mojom::AssistantAllowedState state) override;
// WindowTreeHostManager::Observer:
void OnDisplayConfigurationChanged() override;
// aura::WindowObserver:
void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
void OnWindowDestroyed(aura::Window* window) override;
// MruWindowTracker::Observer:
void OnWindowUntracked(aura::Window* untracked_window) override;
// AssistantControllerObserver:
void OnAssistantReady() override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(
AssistantVisibility new_visibility,
AssistantVisibility old_visibility,
base::Optional<AssistantEntryPoint> entry_point,
base::Optional<AssistantExitPoint> exit_point) override;
// HomeScreenDelegate:
void ShowHomeScreenView() override;
aura::Window* GetHomeScreenWindow() override;
void UpdateYPositionAndOpacityForHomeLauncher(
int y_position_in_screen,
float opacity,
base::Optional<AnimationInfo> animation_info,
UpdateAnimationSettingsCallback callback) override;
void UpdateScaleAndOpacityForHomeLauncher(
float scale,
float opacity,
base::Optional<AnimationInfo> animation_info,
UpdateAnimationSettingsCallback callback) override;
base::Optional<base::TimeDelta> GetOptionalAnimationDuration() override;
base::ScopedClosureRunner DisableHomeScreenBackgroundBlur() override;
void OnHomeLauncherAnimationComplete(bool shown, int64_t display_id) override;
void OnHomeLauncherPositionChanged(int percent_shown,
int64_t display_id) override;
bool IsHomeScreenVisible() override;
gfx::Rect GetInitialAppListItemScreenBoundsForWindow(
aura::Window* window) override;
bool onscreen_keyboard_shown() const { return onscreen_keyboard_shown_; }
HomeLauncherTransitionState home_launcher_transition_state() const {
return home_launcher_transition_state_;
}
// Performs the 'back' action for the active page.
void Back();
void SetKeyboardTraversalMode(bool engaged);
// Returns current visibility of the Assistant page.
bool IsShowingEmbeddedAssistantUI() const;
// Get updated app list view state after dragging from shelf.
AppListViewState CalculateStateAfterShelfDrag(
const ui::LocatedEvent& event_in_screen,
float launcher_above_shelf_bottom_amount) const;
void SetAppListModelForTest(std::unique_ptr<AppListModel> model);
using StateTransitionAnimationCallback =
base::RepeatingCallback<void(AppListViewState)>;
void SetStateTransitionAnimationCallbackForTesting(
StateTransitionAnimationCallback callback);
using HomeLauncherAnimationCallback =
base::RepeatingCallback<void(bool shown)>;
void SetHomeLauncherAnimationCallbackForTesting(
HomeLauncherAnimationCallback callback);
void RecordShelfAppLaunched(
base::Optional<AppListViewState> recorded_app_list_view_state,
base::Optional<bool> home_launcher_shown);
// Updates which container the launcher window should be in.
void UpdateLauncherContainer(
base::Optional<int64_t> display_id = base::nullopt);
// Gets the container which should contain the AppList.
int GetContainerId() const;
// Returns whether the launcher should show behinds apps or infront of them.
bool ShouldLauncherShowBehindApps() const;
// Returns the parent window of the applist for a |display_id|.
aura::Window* GetContainerForDisplayId(
base::Optional<int64_t> display_id = base::nullopt);
private:
// HomeScreenDelegate:
void OnHomeLauncherDragStart() override;
void OnHomeLauncherDragInProgress() override;
void OnHomeLauncherDragEnd() override;
syncer::StringOrdinal GetOemFolderPos();
std::unique_ptr<AppListItem> CreateAppListItem(
std::unique_ptr<AppListItemMetadata> metadata);
AppListFolderItem* FindFolderItem(const std::string& folder_id);
// Update the visibility of Assistant functionality.
void UpdateAssistantVisibility();
// Updates the visibility of expand arrow view.
void UpdateExpandArrowVisibility();
int64_t GetDisplayIdToShowAppListOn();
void ResetHomeLauncherIfShown();
// Returns the length of the most recent query.
int GetLastQueryLength();
// 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();
// 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;
AppListClient* client_ = nullptr;
std::unique_ptr<AppListModel> model_;
SearchModel search_model_;
// |presenter_| should be put below |client_| and |model_| to prevent a crash
// in destruction.
AppListPresenterImpl presenter_;
// 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.
aura::Window* 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_;
// ScopedClosureRunner which while in scope keeps background blur in home
// screen (in particular, apps container suggestion chips background)
// disabled. Set while home screen transitions are in progress.
base::Optional<base::ScopedClosureRunner> home_screen_blur_disabler_;
base::ObserverList<AppListControllerObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(AppListControllerImpl);
};
} // namespace ash
#endif // ASH_APP_LIST_APP_LIST_CONTROLLER_IMPL_H_