blob: 19b05542c838e977a94ca86fe5aab9458abb2dfa [file] [log] [blame]
[email protected]0c68e892012-12-08 16:54:531// Copyright (c) 2012 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
Jun Mukai44986382019-05-14 18:19:205#include "ash/public/cpp/test/shell_test_api.h"
sky5ad143a2017-03-22 04:31:236
Scott Violetd8ceadb2019-03-21 01:31:437#include <memory>
xiyuan317fdbe2017-05-31 15:02:028#include <utility>
9
Evan Stade7768d472018-10-25 22:40:1710#include "ash/accelerators/accelerator_commands.h"
Alexander Alekseev2b4c9592021-05-04 22:26:4411#include "ash/accelerators/accelerator_controller_impl.h"
Mitsuru Oshima8abd8b1d02019-05-09 17:55:2312#include "ash/accelerometer/accelerometer_reader.h"
Mitsuru Oshima57cc7852019-04-10 00:15:2713#include "ash/app_list/app_list_controller_impl.h"
James Cook4f4c3612021-05-27 21:45:2214#include "ash/app_list/app_list_presenter_impl.h"
Mitsuru Oshima57cc7852019-04-10 00:15:2715#include "ash/app_list/views/app_list_view.h"
Alexander Alekseev2b4c9592021-05-04 22:26:4416#include "ash/hud_display/hud_display.h"
Darren Shen7daf3e12019-07-02 07:25:4917#include "ash/keyboard/keyboard_controller_impl.h"
Mitsuru Oshima9a6378d92019-11-01 00:48:1518#include "ash/public/cpp/autotest_private_api_utils.h"
Mitsuru Oshimaa6adca4f2019-07-10 23:30:4619#include "ash/public/cpp/tablet_mode_observer.h"
[email protected]0c68e892012-12-08 16:54:5320#include "ash/root_window_controller.h"
21#include "ash/shell.h"
Ahmed Mehfooz812c5422021-03-29 22:42:1622#include "ash/system/message_center/session_state_notification_blocker.h"
Toni Barzic9d0c82f42017-12-06 00:53:5223#include "ash/system/power/backlights_forced_off_setter.h"
Qiang Xu0a86020f2017-10-12 08:34:5424#include "ash/system/power/power_button_controller.h"
Jun Mukai2b91e702019-09-05 18:24:3825#include "ash/wm/overview/overview_animation_state_waiter.h"
Sammie Quon80e82a12019-01-23 19:55:2226#include "ash/wm/overview/overview_controller.h"
Evan Stade426a2982018-10-19 22:42:0727#include "ash/wm/splitview/split_view_controller.h"
Evan Staded689b332018-08-02 01:17:2228#include "ash/wm/tablet_mode/tablet_mode_controller.h"
Ahmed Fakhryfee7a0a2019-04-05 22:49:4829#include "ash/wm/workspace_controller.h"
Peter Boströmbceb9af2021-05-27 18:18:5830#include "base/bind.h"
Scott Violetd8ceadb2019-03-21 01:31:4331#include "base/run_loop.h"
James Cookbbe5cb12017-08-08 18:32:2132#include "components/prefs/testing_pref_service.h"
Scott Violetd8ceadb2019-03-21 01:31:4333#include "ui/aura/window_tree_host.h"
34#include "ui/compositor/compositor.h"
35#include "ui/compositor/compositor_observer.h"
Lei Zhang0c043322021-04-27 16:43:0536#include "ui/compositor/layer.h"
Sammie Quon358e9572019-11-21 04:38:0237#include "ui/compositor/layer_animation_observer.h"
Sammie Quon4986fdf2020-05-15 19:33:5838#include "ui/display/manager/display_manager.h"
Ahmed Fakhry607ade02019-10-31 15:59:3939#include "ui/events/devices/device_data_manager_test_api.h"
Jun Mukai2af6db52019-01-09 00:22:4240#include "ui/events/gesture_detection/gesture_configuration.h"
[email protected]0c68e892012-12-08 16:54:5341
42namespace ash {
Scott Violetd8ceadb2019-03-21 01:31:4343namespace {
44
45// Wait for a WindowTreeHost to no longer be holding pointer events.
46class PointerMoveLoopWaiter : public ui::CompositorObserver {
47 public:
48 explicit PointerMoveLoopWaiter(aura::WindowTreeHost* window_tree_host)
49 : window_tree_host_(window_tree_host) {
50 window_tree_host_->compositor()->AddObserver(this);
51 }
52
Peter Boströmec31a042021-09-16 23:37:3453 PointerMoveLoopWaiter(const PointerMoveLoopWaiter&) = delete;
54 PointerMoveLoopWaiter& operator=(const PointerMoveLoopWaiter&) = delete;
55
Scott Violetd8ceadb2019-03-21 01:31:4356 ~PointerMoveLoopWaiter() override {
57 window_tree_host_->compositor()->RemoveObserver(this);
58 }
59
60 void Wait() {
61 // Use a while loop as it's possible for releasing the lock to trigger
62 // processing events, which again grabs the lock.
63 while (window_tree_host_->holding_pointer_moves()) {
64 run_loop_ = std::make_unique<base::RunLoop>(
65 base::RunLoop::Type::kNestableTasksAllowed);
66 run_loop_->Run();
67 run_loop_.reset();
68 }
69 }
70
71 // ui::CompositorObserver:
72 void OnCompositingEnded(ui::Compositor* compositor) override {
73 if (run_loop_)
74 run_loop_->Quit();
75 }
76
77 private:
78 aura::WindowTreeHost* window_tree_host_;
79 std::unique_ptr<base::RunLoop> run_loop_;
Scott Violetd8ceadb2019-03-21 01:31:4380};
81
Sammie Quon358e9572019-11-21 04:38:0282class WindowAnimationWaiter : public ui::LayerAnimationObserver {
83 public:
84 explicit WindowAnimationWaiter(aura::Window* window)
85 : animator_(window->layer()->GetAnimator()) {
86 animator_->AddObserver(this);
87 }
88 ~WindowAnimationWaiter() override = default;
89
90 WindowAnimationWaiter(const WindowAnimationWaiter& other) = delete;
91 WindowAnimationWaiter& operator=(const WindowAnimationWaiter& rhs) = delete;
92
93 // ui::LayerAnimationObserver:
94 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
95 if (!animator_->is_animating()) {
96 animator_->RemoveObserver(this);
97 run_loop_.Quit();
98 }
99 }
100 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {}
101 void OnLayerAnimationScheduled(
102 ui::LayerAnimationSequence* sequence) override {}
103
104 void Wait() {
Sammie Quon358e9572019-11-21 04:38:02105 run_loop_.Run();
106 }
107
108 private:
109 ui::LayerAnimator* animator_;
110 base::RunLoop run_loop_;
111};
112
Scott Violetd8ceadb2019-03-21 01:31:43113} // namespace
[email protected]0c68e892012-12-08 16:54:53114
Jun Mukai44986382019-05-14 18:19:20115ShellTestApi::ShellTestApi() : shell_(Shell::Get()) {}
116ShellTestApi::~ShellTestApi() = default;
James Cook00848f02018-01-05 18:02:57117
Sammie Quon408e9da2019-06-20 19:36:21118// static
119void ShellTestApi::SetTabletControllerUseScreenshotForTest(
120 bool use_screenshot) {
121 TabletModeController::SetUseScreenshotForTest(use_screenshot);
122}
123
Ahmed Mehfooz812c5422021-03-29 22:42:16124// static
125void ShellTestApi::SetUseLoginNotificationDelayForTest(bool use_delay) {
126 SessionStateNotificationBlocker::SetUseLoginNotificationDelayForTest(
127 use_delay);
128}
129
Zentaro Kavanagh1f436492021-05-20 23:29:36130// static
131void ShellTestApi::SetShouldShowShortcutNotificationForTest(
132 bool show_notification) {
133 AcceleratorControllerImpl::SetShouldShowShortcutNotificationForTest(
134 show_notification);
135}
136
James Cook459354b32017-09-27 23:18:01137MessageCenterController* ShellTestApi::message_center_controller() {
138 return shell_->message_center_controller_.get();
139}
140
[email protected]093b8d642014-04-03 20:59:28141WorkspaceController* ShellTestApi::workspace_controller() {
Ahmed Fakhryfee7a0a2019-04-05 22:49:48142 // TODO(afakhry): Split this into two, one for root, and one for context.
143 return GetActiveWorkspaceController(shell_->GetPrimaryRootWindow());
[email protected]0c68e892012-12-08 16:54:53144}
145
[email protected]093b8d642014-04-03 20:59:28146ScreenPositionController* ShellTestApi::screen_position_controller() {
[email protected]0c68e892012-12-08 16:54:53147 return shell_->screen_position_controller_.get();
148}
149
erg36cfb952017-06-21 19:41:45150NativeCursorManagerAsh* ShellTestApi::native_cursor_manager_ash() {
[email protected]c0ff0342013-02-27 00:41:29151 return shell_->native_cursor_manager_;
152}
153
[email protected]093b8d642014-04-03 20:59:28154DragDropController* ShellTestApi::drag_drop_controller() {
[email protected]c086bab2013-06-06 21:46:44155 return shell_->drag_drop_controller_.get();
156}
157
Qiang Xu36234e532018-04-11 04:54:02158PowerPrefs* ShellTestApi::power_prefs() {
159 return shell_->power_prefs_.get();
160}
161
Sammie Quon4986fdf2020-05-15 19:33:58162display::DisplayManager* ShellTestApi::display_manager() {
163 return shell_->display_manager();
164}
165
Qiang Xu50c6f8c2017-08-31 20:55:24166void ShellTestApi::ResetPowerButtonControllerForTest() {
Toni Barzic9d0c82f42017-12-06 00:53:52167 shell_->backlights_forced_off_setter_->ResetForTest();
168 shell_->power_button_controller_ = std::make_unique<PowerButtonController>(
169 shell_->backlights_forced_off_setter_.get());
Qiang Xu50c6f8c2017-08-31 20:55:24170}
171
James Cook7b7c6a52018-01-04 23:40:03172void ShellTestApi::SimulateModalWindowOpenForTest(bool modal_window_open) {
173 shell_->simulate_modal_window_open_for_test_ = modal_window_open;
174}
175
Jun Mukai44986382019-05-14 18:19:20176bool ShellTestApi::IsSystemModalWindowOpen() {
177 return Shell::IsSystemModalWindowOpen();
James Cook00848f02018-01-05 18:02:57178}
179
James Cookbbca6452021-01-13 17:26:03180void ShellTestApi::SetTabletModeEnabledForTest(bool enable) {
Ahmed Fakhry607ade02019-10-31 15:59:39181 // Detach mouse devices, so we can enter tablet mode.
182 // Calling RunUntilIdle() here is necessary before setting the mouse devices
183 // to prevent the callback from evdev thread from overwriting whatever we set
184 // here below. See `InputDeviceFactoryEvdevProxy::OnStartupScanComplete()`.
185 base::RunLoop().RunUntilIdle();
Xiaoqian Dai7e182452020-05-05 23:29:19186 ui::DeviceDataManagerTestApi().OnDeviceListsComplete();
Ahmed Fakhry607ade02019-10-31 15:59:39187 ui::DeviceDataManagerTestApi().SetMouseDevices({});
188
Mitsuru Oshimaa6adca4f2019-07-10 23:30:46189 TabletMode::Waiter waiter(enable);
Mitsuru Oshima9e05edd2019-06-17 19:35:39190 shell_->tablet_mode_controller()->SetEnabledForTest(enable);
Mitsuru Oshimaa6adca4f2019-07-10 23:30:46191 waiter.Wait();
Evan Staded689b332018-08-02 01:17:22192}
193
Jun Mukai44986382019-05-14 18:19:20194void ShellTestApi::EnableVirtualKeyboard() {
Darren Shen7daf3e12019-07-02 07:25:49195 shell_->keyboard_controller()->SetEnableFlag(
Darren Shen8604a212019-06-07 00:41:38196 keyboard::KeyboardEnableFlag::kCommandLineEnabled);
Noel Gordonfe3ac342018-09-10 05:12:57197}
198
Jun Mukai44986382019-05-14 18:19:20199void ShellTestApi::ToggleFullscreen() {
Manu Cornetc3511d902020-01-10 22:44:43200 accelerators::ToggleFullscreen();
Evan Stade7768d472018-10-25 22:40:17201}
202
Jun Mukaiaa8479c82019-01-08 02:30:39203void ShellTestApi::AddRemoveDisplay() {
204 shell_->display_manager()->AddRemoveDisplay();
205}
206
Jun Mukai44986382019-05-14 18:19:20207void ShellTestApi::WaitForNoPointerHoldLock() {
Scott Violetd8ceadb2019-03-21 01:31:43208 aura::WindowTreeHost* primary_host =
209 Shell::GetPrimaryRootWindowController()->GetHost();
210 if (primary_host->holding_pointer_moves())
211 PointerMoveLoopWaiter(primary_host).Wait();
Scott Violetd8ceadb2019-03-21 01:31:43212}
213
Jun Mukai44986382019-05-14 18:19:20214void ShellTestApi::WaitForNextFrame(base::OnceClosure closure) {
Xiyuan Xia65d4bbf2019-04-08 15:13:38215 Shell::GetPrimaryRootWindowController()
216 ->GetHost()
217 ->compositor()
218 ->RequestPresentationTimeForNextFrame(base::BindOnce(
Jun Mukai44986382019-05-14 18:19:20219 [](base::OnceClosure closure,
Xiyuan Xia65d4bbf2019-04-08 15:13:38220 const gfx::PresentationFeedback& feedback) {
Jun Mukai44986382019-05-14 18:19:20221 std::move(closure).Run();
Xiyuan Xia65d4bbf2019-04-08 15:13:38222 },
Jun Mukai44986382019-05-14 18:19:20223 std::move(closure)));
Xiyuan Xia65d4bbf2019-04-08 15:13:38224}
225
Jun Mukai44986382019-05-14 18:19:20226void ShellTestApi::WaitForOverviewAnimationState(OverviewAnimationState state) {
227 auto* overview_controller = shell_->overview_controller();
228 if (state == OverviewAnimationState::kEnterAnimationComplete &&
Sammie Quon2c85f73d2019-05-08 23:10:27229 overview_controller->InOverviewSession() &&
Mitsuru Oshima57cc7852019-04-10 00:15:27230 !overview_controller->IsInStartAnimation()) {
231 // If there is no animation applied, call the callback immediately.
Mitsuru Oshima57cc7852019-04-10 00:15:27232 return;
233 }
Jun Mukai44986382019-05-14 18:19:20234 if (state == OverviewAnimationState::kExitAnimationComplete &&
Sammie Quon2c85f73d2019-05-08 23:10:27235 !overview_controller->InOverviewSession() &&
Mitsuru Oshima57cc7852019-04-10 00:15:27236 !overview_controller->IsCompletingShutdownAnimations()) {
237 // If there is no animation applied, call the callback immediately.
Mitsuru Oshima57cc7852019-04-10 00:15:27238 return;
239 }
Jun Mukai44986382019-05-14 18:19:20240 base::RunLoop run_loop;
Jun Mukai2b91e702019-09-05 18:24:38241 new OverviewAnimationStateWaiter(
Reilly Grantb6702232019-11-26 22:46:04242 state, base::BindOnce([](base::RunLoop* run_loop,
243 bool finished) { run_loop->QuitWhenIdle(); },
244 base::Unretained(&run_loop)));
Jun Mukai44986382019-05-14 18:19:20245 run_loop.Run();
Mitsuru Oshima57cc7852019-04-10 00:15:27246}
247
Mitsuru Oshima77bfc272019-04-10 23:40:18248void ShellTestApi::WaitForLauncherAnimationState(
Manu Cornetc3511d902020-01-10 22:44:43249 AppListViewState target_state) {
Jun Mukai44986382019-05-14 18:19:20250 base::RunLoop run_loop;
Mitsuru Oshima9a6378d92019-11-01 00:48:15251 WaitForLauncherState(target_state, run_loop.QuitWhenIdleClosure());
Jun Mukai44986382019-05-14 18:19:20252 run_loop.Run();
Mitsuru Oshima77bfc272019-04-10 23:40:18253}
254
Sammie Quon358e9572019-11-21 04:38:02255void ShellTestApi::WaitForWindowFinishAnimating(aura::Window* window) {
256 WindowAnimationWaiter waiter(window);
257 waiter.Wait();
258}
259
Toni Barzic8caccc82020-01-30 23:27:19260base::OnceClosure ShellTestApi::CreateWaiterForFinishingWindowAnimation(
261 aura::Window* window) {
262 auto waiter = std::make_unique<WindowAnimationWaiter>(window);
263 return base::BindOnce(&WindowAnimationWaiter::Wait, std::move(waiter));
264}
265
Jun Mukaic9ba6b512019-06-05 19:21:42266PaginationModel* ShellTestApi::GetAppListPaginationModel() {
Manu Cornet191c3142019-10-09 06:31:32267 AppListView* view =
Jun Mukaic9ba6b512019-06-05 19:21:42268 Shell::Get()->app_list_controller()->presenter()->GetView();
269 if (!view)
270 return nullptr;
271 return view->GetAppsPaginationModel();
272}
273
Sammie Quond322167b2021-01-11 22:10:40274bool ShellTestApi::IsContextMenuShown() const {
275 return Shell::GetPrimaryRootWindowController()->IsContextMenuShown();
276}
277
Alexander Alekseev2b4c9592021-05-04 22:26:44278bool ShellTestApi::IsActionForAcceleratorEnabled(
279 const ui::Accelerator& accelerator) const {
Zentaro Kavanagh628ab4a2021-07-27 22:19:37280 auto* controller = Shell::Get()->accelerator_controller();
281 return AcceleratorControllerImpl::TestApi(controller)
282 .IsActionForAcceleratorEnabled(accelerator);
Alexander Alekseev2b4c9592021-05-04 22:26:44283}
284
285bool ShellTestApi::PressAccelerator(const ui::Accelerator& accelerator) {
286 return Shell::Get()->accelerator_controller()->AcceleratorPressed(
287 accelerator);
288}
289
290bool ShellTestApi::IsHUDShown() {
291 return hud_display::HUDDisplayView::IsShown();
292}
293
[email protected]0c68e892012-12-08 16:54:53294} // namespace ash