blob: 324179b8ce219c57d0daf0900a5bc2681d459e72 [file] [log] [blame]
Mitsuru Oshima35b4c2a2019-10-17 17:04:341// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/public/cpp/autotest_private_api_utils.h"
6
Mitsuru Oshima9a6378d92019-11-01 00:48:157#include "ash/app_list/app_list_controller_impl.h"
Shengsong Tan3b97bb22019-10-31 02:42:058#include "ash/frame/non_client_frame_view_ash.h"
Mitsuru Oshima9a6378d92019-11-01 00:48:159#include "ash/home_screen/home_screen_controller.h"
Mitsuru Oshima35b4c2a2019-10-17 17:04:3410#include "ash/shell.h"
11#include "ash/wm/mru_window_tracker.h"
12#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
13
14namespace ash {
Mitsuru Oshima9a6378d92019-11-01 00:48:1515namespace {
16
Toni Barzicd770f6a2019-11-04 20:06:4717class HomeLauncherStateWaiter {
Mitsuru Oshima9a6378d92019-11-01 00:48:1518 public:
19 HomeLauncherStateWaiter(bool target_shown, base::OnceClosure closure)
20 : target_shown_(target_shown), closure_(std::move(closure)) {
21 Shell::Get()
Toni Barzicd770f6a2019-11-04 20:06:4722 ->app_list_controller()
23 ->SetHomeLauncherAnimationCallbackForTesting(base::BindRepeating(
24 &HomeLauncherStateWaiter::OnHomeLauncherAnimationCompleted,
25 base::Unretained(this)));
Mitsuru Oshima9a6378d92019-11-01 00:48:1526 }
Toni Barzicd770f6a2019-11-04 20:06:4727 ~HomeLauncherStateWaiter() {
Mitsuru Oshima9a6378d92019-11-01 00:48:1528 Shell::Get()
Toni Barzicd770f6a2019-11-04 20:06:4729 ->app_list_controller()
30 ->SetHomeLauncherAnimationCallbackForTesting(base::NullCallback());
Mitsuru Oshima9a6378d92019-11-01 00:48:1531 }
32
33 private:
Toni Barzicd770f6a2019-11-04 20:06:4734 // Passed to AppListControllerImpl as a callback to run when home launcher
35 // transition animation is complete.
36 void OnHomeLauncherAnimationCompleted(bool shown) {
Mitsuru Oshima9a6378d92019-11-01 00:48:1537 if (shown == target_shown_) {
38 std::move(closure_).Run();
39 delete this;
40 }
41 }
42
43 bool target_shown_;
44 base::OnceClosure closure_;
45
46 DISALLOW_COPY_AND_ASSIGN(HomeLauncherStateWaiter);
47};
48
49// A waiter that waits until the animation ended with the target state, and
50// execute the callback. This self destruction upon completion.
51class LauncherStateWaiter {
52 public:
53 LauncherStateWaiter(ash::AppListViewState state, base::OnceClosure closure)
54 : target_state_(state), closure_(std::move(closure)) {
Toni Barzicd770f6a2019-11-04 20:06:4755 Shell::Get()
56 ->app_list_controller()
57 ->SetStateTransitionAnimationCallbackForTesting(base::BindRepeating(
58 &LauncherStateWaiter::OnStateChanged, base::Unretained(this)));
Mitsuru Oshima9a6378d92019-11-01 00:48:1559 }
60 ~LauncherStateWaiter() {
Toni Barzicd770f6a2019-11-04 20:06:4761 Shell::Get()
62 ->app_list_controller()
63 ->SetStateTransitionAnimationCallbackForTesting(base::NullCallback());
Mitsuru Oshima9a6378d92019-11-01 00:48:1564 }
65
66 void OnStateChanged(ash::AppListViewState state) {
67 if (target_state_ == state) {
68 std::move(closure_).Run();
69 delete this;
70 }
71 }
72
73 private:
74 ash::AppListViewState target_state_;
75 base::OnceClosure closure_;
76
77 DISALLOW_COPY_AND_ASSIGN(LauncherStateWaiter);
78};
79
80} // namespace
Mitsuru Oshima35b4c2a2019-10-17 17:04:3481
82std::vector<aura::Window*> GetAppWindowList() {
83 ScopedSkipUserSessionBlockedCheck skip_session_blocked;
84 return Shell::Get()->mru_window_tracker()->BuildWindowForCycleWithPipList(
85 ash::kAllDesks);
86}
87
Mitsuru Oshima9a6378d92019-11-01 00:48:1588bool WaitForLauncherState(AppListViewState target_state,
89 base::Closure closure) {
90 // In the tablet mode, some of the app-list state switching is handled
91 // differently. For open and close, HomeLauncherGestureHandler handles the
92 // gestures and animation. HomeLauncherStateWaiter can wait for such
93 // animation. For switching between the search and apps-grid,
94 // LauncherStateWaiter can wait for the animation.
95 bool should_wait_for_home_launcher = false;
96 if (Shell::Get()->tablet_mode_controller()->InTabletMode() &&
97 target_state != AppListViewState::kFullscreenSearch) {
98 // App-list can't enter into kPeeking or kHalf state. Thus |target_state|
99 // should be either kClosed or kFullscreenAllApps.
100 DCHECK(target_state == AppListViewState::kClosed ||
101 target_state == AppListViewState::kFullscreenAllApps);
102 const AppListViewState current_state =
103 Shell::Get()->app_list_controller()->GetAppListViewState();
104 should_wait_for_home_launcher =
105 (target_state == AppListViewState::kClosed) ||
106 (current_state != AppListViewState::kFullscreenSearch);
107 }
108 if (should_wait_for_home_launcher) {
109 // We don't check if the home launcher is animating to the target visibility
110 // because a) home launcher behavior is deterministic, b) correctly
111 // deteching if the home launcher is animating to visibile/invisible require
112 // some refactoring.
113 bool target_visible = target_state != ash::AppListViewState::kClosed;
114 new HomeLauncherStateWaiter(target_visible, closure);
115 } else {
116 // Don't wait if the launcher is already in the target state and not
117 // animating.
118 auto* app_list_view =
119 Shell::Get()->app_list_controller()->presenter()->GetView();
120 bool animating =
121 app_list_view &&
122 app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
123 bool at_target_state =
124 (!app_list_view && target_state == ash::AppListViewState::kClosed) ||
125 (app_list_view && app_list_view->app_list_state() == target_state);
126 if (at_target_state && !animating) {
127 std::move(closure).Run();
128 return true;
129 }
130 new LauncherStateWaiter(target_state, closure);
131 }
132 return false;
133}
134
135} // namespace ash