[go: nahoru, domu]

blob: c86b86869bc2ce0ef6e0fcb0907ec8132e2d2838 [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2019 The Chromium Authors
Mitsuru Oshima35b4c2a2019-10-17 17:04:342// 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
Arthur Sonzognia98e4432023-11-28 18:15:017#include <optional>
8
Mitsuru Oshima9a6378d92019-11-01 00:48:159#include "ash/app_list/app_list_controller_impl.h"
James Cook4f4c3612021-05-27 21:45:2210#include "ash/app_list/app_list_presenter_impl.h"
Shengsong Tan3b97bb22019-10-31 02:42:0511#include "ash/frame/non_client_frame_view_ash.h"
Mitsuru Oshima35b4c2a2019-10-17 17:04:3412#include "ash/shell.h"
13#include "ash/wm/mru_window_tracker.h"
14#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
Avi Drissman4de6dab2023-01-06 23:17:3515#include "base/functional/bind.h"
16#include "base/functional/callback_helpers.h"
Ali Hijazie63cbaf62023-12-20 19:29:3517#include "base/memory/raw_ptr.h"
Jun Mukaid13d78072021-01-22 20:08:4618#include "base/scoped_observation.h"
Lei Zhang0c043322021-04-27 16:43:0519#include "ui/compositor/layer.h"
Jun Mukaid13d78072021-01-22 20:08:4620#include "ui/compositor/layer_animation_observer.h"
David Sanders0a524ec2022-03-20 07:31:2821#include "ui/compositor/layer_animator.h"
Eriko Kurimotoc6b965382023-12-13 03:55:1322#include "ui/display/screen.h"
Mitsuru Oshima35b4c2a2019-10-17 17:04:3423
24namespace ash {
Mitsuru Oshima9a6378d92019-11-01 00:48:1525namespace {
26
Toni Barzicd770f6a2019-11-04 20:06:4727class HomeLauncherStateWaiter {
Mitsuru Oshima9a6378d92019-11-01 00:48:1528 public:
29 HomeLauncherStateWaiter(bool target_shown, base::OnceClosure closure)
30 : target_shown_(target_shown), closure_(std::move(closure)) {
31 Shell::Get()
Toni Barzicd770f6a2019-11-04 20:06:4732 ->app_list_controller()
33 ->SetHomeLauncherAnimationCallbackForTesting(base::BindRepeating(
34 &HomeLauncherStateWaiter::OnHomeLauncherAnimationCompleted,
35 base::Unretained(this)));
Mitsuru Oshima9a6378d92019-11-01 00:48:1536 }
Peter Boströmec31a042021-09-16 23:37:3437
38 HomeLauncherStateWaiter(const HomeLauncherStateWaiter&) = delete;
39 HomeLauncherStateWaiter& operator=(const HomeLauncherStateWaiter&) = delete;
40
Toni Barzicd770f6a2019-11-04 20:06:4741 ~HomeLauncherStateWaiter() {
Mitsuru Oshima9a6378d92019-11-01 00:48:1542 Shell::Get()
Toni Barzicd770f6a2019-11-04 20:06:4743 ->app_list_controller()
44 ->SetHomeLauncherAnimationCallbackForTesting(base::NullCallback());
Mitsuru Oshima9a6378d92019-11-01 00:48:1545 }
46
47 private:
Toni Barzicd770f6a2019-11-04 20:06:4748 // Passed to AppListControllerImpl as a callback to run when home launcher
49 // transition animation is complete.
50 void OnHomeLauncherAnimationCompleted(bool shown) {
Mitsuru Oshima9a6378d92019-11-01 00:48:1551 if (shown == target_shown_) {
52 std::move(closure_).Run();
53 delete this;
54 }
55 }
56
57 bool target_shown_;
58 base::OnceClosure closure_;
Mitsuru Oshima9a6378d92019-11-01 00:48:1559};
60
61// A waiter that waits until the animation ended with the target state, and
62// execute the callback. This self destruction upon completion.
63class LauncherStateWaiter {
64 public:
65 LauncherStateWaiter(ash::AppListViewState state, base::OnceClosure closure)
66 : target_state_(state), closure_(std::move(closure)) {
Toni Barzicd770f6a2019-11-04 20:06:4767 Shell::Get()
68 ->app_list_controller()
69 ->SetStateTransitionAnimationCallbackForTesting(base::BindRepeating(
70 &LauncherStateWaiter::OnStateChanged, base::Unretained(this)));
Mitsuru Oshima9a6378d92019-11-01 00:48:1571 }
Peter Boströmec31a042021-09-16 23:37:3472
73 LauncherStateWaiter(const LauncherStateWaiter&) = delete;
74 LauncherStateWaiter& operator=(const LauncherStateWaiter&) = delete;
75
Mitsuru Oshima9a6378d92019-11-01 00:48:1576 ~LauncherStateWaiter() {
Toni Barzicd770f6a2019-11-04 20:06:4777 Shell::Get()
78 ->app_list_controller()
79 ->SetStateTransitionAnimationCallbackForTesting(base::NullCallback());
Mitsuru Oshima9a6378d92019-11-01 00:48:1580 }
81
82 void OnStateChanged(ash::AppListViewState state) {
83 if (target_state_ == state) {
84 std::move(closure_).Run();
85 delete this;
86 }
87 }
88
89 private:
90 ash::AppListViewState target_state_;
91 base::OnceClosure closure_;
Mitsuru Oshima9a6378d92019-11-01 00:48:1592};
93
Jun Mukaid13d78072021-01-22 20:08:4694class LauncherAnimationWaiter : public ui::LayerAnimationObserver {
95 public:
96 LauncherAnimationWaiter(AppListView* view, base::OnceClosure closure)
97 : closure_(std::move(closure)) {
98 observation_.Observe(view->GetWidget()->GetLayer()->GetAnimator());
99 }
100 ~LauncherAnimationWaiter() override = default;
101 LauncherAnimationWaiter(const LauncherAnimationWaiter&) = delete;
102 LauncherAnimationWaiter& operator=(const LauncherAnimationWaiter&) = delete;
103
104 private:
105 // ui::LayerAnimationObserver:
106 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
107 std::move(closure_).Run();
108 delete this;
109 }
110 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
111 OnLayerAnimationEnded(sequence);
112 }
113 void OnLayerAnimationScheduled(
114 ui::LayerAnimationSequence* sequence) override {}
115
116 base::OnceClosure closure_;
117 base::ScopedObservation<ui::LayerAnimator, ui::LayerAnimationObserver>
118 observation_{this};
119};
120
Toni Barzic0c295332020-11-12 06:20:24121bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
122 if (Shell::Get()->app_list_controller()->IsVisible(
Arthur Sonzognia98e4432023-11-28 18:15:01123 /*display_id=*/std::nullopt) == target_visible) {
Toni Barzic0c295332020-11-12 06:20:24124 std::move(closure).Run();
125 return true;
126 }
127
128 new HomeLauncherStateWaiter(target_visible, std::move(closure));
129 return false;
130}
131
Jun Mukaid13d78072021-01-22 20:08:46132bool WaitForLauncherAnimation(base::OnceClosure closure) {
133 auto* app_list_view =
James Cook26dd0022022-01-10 23:28:28134 Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
Jun Mukaid13d78072021-01-22 20:08:46135 if (!app_list_view) {
136 std::move(closure).Run();
137 return true;
138 }
139 bool animating =
140 app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
141 if (!animating) {
142 std::move(closure).Run();
143 return true;
144 }
145 new LauncherAnimationWaiter(app_list_view, std::move(closure));
146 return false;
147}
148
Mitsuru Oshima9a6378d92019-11-01 00:48:15149} // namespace
Mitsuru Oshima35b4c2a2019-10-17 17:04:34150
Ali Hijazie63cbaf62023-12-20 19:29:35151std::vector<raw_ptr<aura::Window, VectorExperimental>> GetAppWindowList() {
Mitsuru Oshima35b4c2a2019-10-17 17:04:34152 ScopedSkipUserSessionBlockedCheck skip_session_blocked;
Kazuki Takise9e5b7a02020-03-04 12:12:45153 return Shell::Get()->mru_window_tracker()->BuildAppWindowList(kAllDesks);
Mitsuru Oshima35b4c2a2019-10-17 17:04:34154}
155
Mitsuru Oshima9a6378d92019-11-01 00:48:15156bool WaitForLauncherState(AppListViewState target_state,
Reilly Grantb6702232019-11-26 22:46:04157 base::OnceClosure closure) {
Eriko Kurimotoc6b965382023-12-13 03:55:13158 const bool in_tablet_mode = display::Screen::GetScreen()->InTabletMode();
Toni Barzic0c295332020-11-12 06:20:24159 if (in_tablet_mode) {
160 // App-list can't enter kPeeking or kHalf state in tablet mode. Thus
161 // |target_state| should be either kClosed, kFullscreenAllApps or
162 // kFullscreenSearch.
Mitsuru Oshima9a6378d92019-11-01 00:48:15163 DCHECK(target_state == AppListViewState::kClosed ||
Toni Barzic0c295332020-11-12 06:20:24164 target_state == AppListViewState::kFullscreenAllApps ||
165 target_state == AppListViewState::kFullscreenSearch);
Mitsuru Oshima9a6378d92019-11-01 00:48:15166 }
Toni Barzic0c295332020-11-12 06:20:24167
168 // In the tablet mode, home launcher visibility state needs special handling,
169 // as app list view visibility does not match home launcher visibility. The
170 // app list view is always visible, but the home launcher may be obscured by
171 // app windows. The waiter interprets waits for kClosed state as waits
172 // "home launcher not visible" state - note that the app list view
173 // is actually expected to be in a visible state.
174 AppListViewState effective_target_state =
175 in_tablet_mode && target_state == AppListViewState::kClosed
176 ? AppListViewState::kFullscreenAllApps
177 : target_state;
178
Arthur Sonzognia98e4432023-11-28 18:15:01179 std::optional<bool> target_home_launcher_visibility;
Toni Barzic0c295332020-11-12 06:20:24180 if (in_tablet_mode)
181 target_home_launcher_visibility = target_state != AppListViewState::kClosed;
182
183 // Don't wait if the launcher is already in the target state and not
184 // animating.
185 auto* app_list_view =
James Cook26dd0022022-01-10 23:28:28186 Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
Toni Barzic0c295332020-11-12 06:20:24187 bool animating =
188 app_list_view &&
189 app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
190 bool at_target_state =
191 (!app_list_view && effective_target_state == AppListViewState::kClosed) ||
192 (app_list_view &&
193 app_list_view->app_list_state() == effective_target_state);
Jun Mukaid13d78072021-01-22 20:08:46194
Toni Barzic0c295332020-11-12 06:20:24195 if (at_target_state && !animating) {
196 // In tablet mode, ensure that the home launcher is in the expected state.
197 if (target_home_launcher_visibility.has_value()) {
198 return WaitForHomeLauncherState(*target_home_launcher_visibility,
199 std::move(closure));
Mitsuru Oshima9a6378d92019-11-01 00:48:15200 }
Toni Barzic0c295332020-11-12 06:20:24201 std::move(closure).Run();
202 return true;
Mitsuru Oshima9a6378d92019-11-01 00:48:15203 }
Toni Barzic0c295332020-11-12 06:20:24204
205 // In tablet mode, ensure that the home launcher is in the expected state.
206 base::OnceClosure callback =
207 target_home_launcher_visibility.has_value()
208 ? base::BindOnce(base::IgnoreResult(&WaitForHomeLauncherState),
209 *target_home_launcher_visibility, std::move(closure))
210 : std::move(closure);
Jun Mukaid13d78072021-01-22 20:08:46211 if (at_target_state)
212 return WaitForLauncherAnimation(std::move(callback));
213 new LauncherStateWaiter(
214 target_state,
215 base::BindOnce(base::IgnoreResult(&WaitForLauncherAnimation),
216 std::move(callback)));
Mitsuru Oshima9a6378d92019-11-01 00:48:15217 return false;
218}
219
220} // namespace ash