blob: 94f7aaf2be9f573357eda2684db6c11cf921ef27 [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"
Mitsuru Oshima8abd8b1d02019-05-09 17:55:2311#include "ash/accelerometer/accelerometer_reader.h"
Mitsuru Oshima57cc7852019-04-10 00:15:2712#include "ash/app_list/app_list_controller_impl.h"
Mitsuru Oshima57cc7852019-04-10 00:15:2713#include "ash/app_list/views/app_list_view.h"
Darren Shen7daf3e12019-07-02 07:25:4914#include "ash/keyboard/keyboard_controller_impl.h"
Mitsuru Oshima9a6378d92019-11-01 00:48:1515#include "ash/public/cpp/autotest_private_api_utils.h"
Mitsuru Oshimaa6adca4f2019-07-10 23:30:4616#include "ash/public/cpp/tablet_mode_observer.h"
[email protected]0c68e892012-12-08 16:54:5317#include "ash/root_window_controller.h"
18#include "ash/shell.h"
Toni Barzic9d0c82f42017-12-06 00:53:5219#include "ash/system/power/backlights_forced_off_setter.h"
Qiang Xu0a86020f2017-10-12 08:34:5420#include "ash/system/power/power_button_controller.h"
Jun Mukai2b91e702019-09-05 18:24:3821#include "ash/wm/overview/overview_animation_state_waiter.h"
Sammie Quon80e82a12019-01-23 19:55:2222#include "ash/wm/overview/overview_controller.h"
Evan Stade426a2982018-10-19 22:42:0723#include "ash/wm/splitview/split_view_controller.h"
Evan Staded689b332018-08-02 01:17:2224#include "ash/wm/tablet_mode/tablet_mode_controller.h"
Ahmed Fakhryfee7a0a2019-04-05 22:49:4825#include "ash/wm/workspace_controller.h"
Scott Violetd8ceadb2019-03-21 01:31:4326#include "base/run_loop.h"
James Cookbbe5cb12017-08-08 18:32:2127#include "components/prefs/testing_pref_service.h"
Scott Violetd8ceadb2019-03-21 01:31:4328#include "ui/aura/window_tree_host.h"
29#include "ui/compositor/compositor.h"
30#include "ui/compositor/compositor_observer.h"
Sammie Quon358e9572019-11-21 04:38:0231#include "ui/compositor/layer_animation_observer.h"
Sammie Quon4986fdf2020-05-15 19:33:5832#include "ui/display/manager/display_manager.h"
Ahmed Fakhry607ade02019-10-31 15:59:3933#include "ui/events/devices/device_data_manager_test_api.h"
Jun Mukai2af6db52019-01-09 00:22:4234#include "ui/events/gesture_detection/gesture_configuration.h"
[email protected]0c68e892012-12-08 16:54:5335
36namespace ash {
Scott Violetd8ceadb2019-03-21 01:31:4337namespace {
38
39// Wait for a WindowTreeHost to no longer be holding pointer events.
40class PointerMoveLoopWaiter : public ui::CompositorObserver {
41 public:
42 explicit PointerMoveLoopWaiter(aura::WindowTreeHost* window_tree_host)
43 : window_tree_host_(window_tree_host) {
44 window_tree_host_->compositor()->AddObserver(this);
45 }
46
47 ~PointerMoveLoopWaiter() override {
48 window_tree_host_->compositor()->RemoveObserver(this);
49 }
50
51 void Wait() {
52 // Use a while loop as it's possible for releasing the lock to trigger
53 // processing events, which again grabs the lock.
54 while (window_tree_host_->holding_pointer_moves()) {
55 run_loop_ = std::make_unique<base::RunLoop>(
56 base::RunLoop::Type::kNestableTasksAllowed);
57 run_loop_->Run();
58 run_loop_.reset();
59 }
60 }
61
62 // ui::CompositorObserver:
63 void OnCompositingEnded(ui::Compositor* compositor) override {
64 if (run_loop_)
65 run_loop_->Quit();
66 }
67
68 private:
69 aura::WindowTreeHost* window_tree_host_;
70 std::unique_ptr<base::RunLoop> run_loop_;
71
72 DISALLOW_COPY_AND_ASSIGN(PointerMoveLoopWaiter);
73};
74
Sammie Quon358e9572019-11-21 04:38:0275class WindowAnimationWaiter : public ui::LayerAnimationObserver {
76 public:
77 explicit WindowAnimationWaiter(aura::Window* window)
78 : animator_(window->layer()->GetAnimator()) {
79 animator_->AddObserver(this);
80 }
81 ~WindowAnimationWaiter() override = default;
82
83 WindowAnimationWaiter(const WindowAnimationWaiter& other) = delete;
84 WindowAnimationWaiter& operator=(const WindowAnimationWaiter& rhs) = delete;
85
86 // ui::LayerAnimationObserver:
87 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
88 if (!animator_->is_animating()) {
89 animator_->RemoveObserver(this);
90 run_loop_.Quit();
91 }
92 }
93 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {}
94 void OnLayerAnimationScheduled(
95 ui::LayerAnimationSequence* sequence) override {}
96
97 void Wait() {
Sammie Quon358e9572019-11-21 04:38:0298 run_loop_.Run();
99 }
100
101 private:
102 ui::LayerAnimator* animator_;
103 base::RunLoop run_loop_;
104};
105
Scott Violetd8ceadb2019-03-21 01:31:43106} // namespace
[email protected]0c68e892012-12-08 16:54:53107
Jun Mukai44986382019-05-14 18:19:20108ShellTestApi::ShellTestApi() : shell_(Shell::Get()) {}
109ShellTestApi::~ShellTestApi() = default;
James Cook00848f02018-01-05 18:02:57110
Sammie Quon408e9da2019-06-20 19:36:21111// static
112void ShellTestApi::SetTabletControllerUseScreenshotForTest(
113 bool use_screenshot) {
114 TabletModeController::SetUseScreenshotForTest(use_screenshot);
115}
116
James Cook459354b32017-09-27 23:18:01117MessageCenterController* ShellTestApi::message_center_controller() {
118 return shell_->message_center_controller_.get();
119}
120
[email protected]093b8d642014-04-03 20:59:28121WorkspaceController* ShellTestApi::workspace_controller() {
Ahmed Fakhryfee7a0a2019-04-05 22:49:48122 // TODO(afakhry): Split this into two, one for root, and one for context.
123 return GetActiveWorkspaceController(shell_->GetPrimaryRootWindow());
[email protected]0c68e892012-12-08 16:54:53124}
125
[email protected]093b8d642014-04-03 20:59:28126ScreenPositionController* ShellTestApi::screen_position_controller() {
[email protected]0c68e892012-12-08 16:54:53127 return shell_->screen_position_controller_.get();
128}
129
erg36cfb952017-06-21 19:41:45130NativeCursorManagerAsh* ShellTestApi::native_cursor_manager_ash() {
[email protected]c0ff0342013-02-27 00:41:29131 return shell_->native_cursor_manager_;
132}
133
[email protected]093b8d642014-04-03 20:59:28134DragDropController* ShellTestApi::drag_drop_controller() {
[email protected]c086bab2013-06-06 21:46:44135 return shell_->drag_drop_controller_.get();
136}
137
Qiang Xu36234e532018-04-11 04:54:02138PowerPrefs* ShellTestApi::power_prefs() {
139 return shell_->power_prefs_.get();
140}
141
Sammie Quon4986fdf2020-05-15 19:33:58142display::DisplayManager* ShellTestApi::display_manager() {
143 return shell_->display_manager();
144}
145
Qiang Xu50c6f8c2017-08-31 20:55:24146void ShellTestApi::ResetPowerButtonControllerForTest() {
Toni Barzic9d0c82f42017-12-06 00:53:52147 shell_->backlights_forced_off_setter_->ResetForTest();
148 shell_->power_button_controller_ = std::make_unique<PowerButtonController>(
149 shell_->backlights_forced_off_setter_.get());
Qiang Xu50c6f8c2017-08-31 20:55:24150}
151
James Cook7b7c6a52018-01-04 23:40:03152void ShellTestApi::SimulateModalWindowOpenForTest(bool modal_window_open) {
153 shell_->simulate_modal_window_open_for_test_ = modal_window_open;
154}
155
Jun Mukai44986382019-05-14 18:19:20156bool ShellTestApi::IsSystemModalWindowOpen() {
157 return Shell::IsSystemModalWindowOpen();
James Cook00848f02018-01-05 18:02:57158}
159
James Cookbbca6452021-01-13 17:26:03160void ShellTestApi::SetTabletModeEnabledForTest(bool enable) {
Ahmed Fakhry607ade02019-10-31 15:59:39161 // Detach mouse devices, so we can enter tablet mode.
162 // Calling RunUntilIdle() here is necessary before setting the mouse devices
163 // to prevent the callback from evdev thread from overwriting whatever we set
164 // here below. See `InputDeviceFactoryEvdevProxy::OnStartupScanComplete()`.
165 base::RunLoop().RunUntilIdle();
Xiaoqian Dai7e182452020-05-05 23:29:19166 ui::DeviceDataManagerTestApi().OnDeviceListsComplete();
Ahmed Fakhry607ade02019-10-31 15:59:39167 ui::DeviceDataManagerTestApi().SetMouseDevices({});
168
Mitsuru Oshimaa6adca4f2019-07-10 23:30:46169 TabletMode::Waiter waiter(enable);
Mitsuru Oshima9e05edd2019-06-17 19:35:39170 shell_->tablet_mode_controller()->SetEnabledForTest(enable);
Mitsuru Oshimaa6adca4f2019-07-10 23:30:46171 waiter.Wait();
Evan Staded689b332018-08-02 01:17:22172}
173
Jun Mukai44986382019-05-14 18:19:20174void ShellTestApi::EnableVirtualKeyboard() {
Darren Shen7daf3e12019-07-02 07:25:49175 shell_->keyboard_controller()->SetEnableFlag(
Darren Shen8604a212019-06-07 00:41:38176 keyboard::KeyboardEnableFlag::kCommandLineEnabled);
Noel Gordonfe3ac342018-09-10 05:12:57177}
178
Jun Mukai44986382019-05-14 18:19:20179void ShellTestApi::ToggleFullscreen() {
Manu Cornetc3511d902020-01-10 22:44:43180 accelerators::ToggleFullscreen();
Evan Stade7768d472018-10-25 22:40:17181}
182
Jun Mukaiaa8479c82019-01-08 02:30:39183void ShellTestApi::AddRemoveDisplay() {
184 shell_->display_manager()->AddRemoveDisplay();
185}
186
Jun Mukai44986382019-05-14 18:19:20187void ShellTestApi::WaitForNoPointerHoldLock() {
Scott Violetd8ceadb2019-03-21 01:31:43188 aura::WindowTreeHost* primary_host =
189 Shell::GetPrimaryRootWindowController()->GetHost();
190 if (primary_host->holding_pointer_moves())
191 PointerMoveLoopWaiter(primary_host).Wait();
Scott Violetd8ceadb2019-03-21 01:31:43192}
193
Jun Mukai44986382019-05-14 18:19:20194void ShellTestApi::WaitForNextFrame(base::OnceClosure closure) {
Xiyuan Xia65d4bbf2019-04-08 15:13:38195 Shell::GetPrimaryRootWindowController()
196 ->GetHost()
197 ->compositor()
198 ->RequestPresentationTimeForNextFrame(base::BindOnce(
Jun Mukai44986382019-05-14 18:19:20199 [](base::OnceClosure closure,
Xiyuan Xia65d4bbf2019-04-08 15:13:38200 const gfx::PresentationFeedback& feedback) {
Jun Mukai44986382019-05-14 18:19:20201 std::move(closure).Run();
Xiyuan Xia65d4bbf2019-04-08 15:13:38202 },
Jun Mukai44986382019-05-14 18:19:20203 std::move(closure)));
Xiyuan Xia65d4bbf2019-04-08 15:13:38204}
205
Jun Mukai44986382019-05-14 18:19:20206void ShellTestApi::WaitForOverviewAnimationState(OverviewAnimationState state) {
207 auto* overview_controller = shell_->overview_controller();
208 if (state == OverviewAnimationState::kEnterAnimationComplete &&
Sammie Quon2c85f73d2019-05-08 23:10:27209 overview_controller->InOverviewSession() &&
Mitsuru Oshima57cc7852019-04-10 00:15:27210 !overview_controller->IsInStartAnimation()) {
211 // If there is no animation applied, call the callback immediately.
Mitsuru Oshima57cc7852019-04-10 00:15:27212 return;
213 }
Jun Mukai44986382019-05-14 18:19:20214 if (state == OverviewAnimationState::kExitAnimationComplete &&
Sammie Quon2c85f73d2019-05-08 23:10:27215 !overview_controller->InOverviewSession() &&
Mitsuru Oshima57cc7852019-04-10 00:15:27216 !overview_controller->IsCompletingShutdownAnimations()) {
217 // If there is no animation applied, call the callback immediately.
Mitsuru Oshima57cc7852019-04-10 00:15:27218 return;
219 }
Jun Mukai44986382019-05-14 18:19:20220 base::RunLoop run_loop;
Jun Mukai2b91e702019-09-05 18:24:38221 new OverviewAnimationStateWaiter(
Reilly Grantb6702232019-11-26 22:46:04222 state, base::BindOnce([](base::RunLoop* run_loop,
223 bool finished) { run_loop->QuitWhenIdle(); },
224 base::Unretained(&run_loop)));
Jun Mukai44986382019-05-14 18:19:20225 run_loop.Run();
Mitsuru Oshima57cc7852019-04-10 00:15:27226}
227
Mitsuru Oshima77bfc272019-04-10 23:40:18228void ShellTestApi::WaitForLauncherAnimationState(
Manu Cornetc3511d902020-01-10 22:44:43229 AppListViewState target_state) {
Jun Mukai44986382019-05-14 18:19:20230 base::RunLoop run_loop;
Mitsuru Oshima9a6378d92019-11-01 00:48:15231 WaitForLauncherState(target_state, run_loop.QuitWhenIdleClosure());
Jun Mukai44986382019-05-14 18:19:20232 run_loop.Run();
Mitsuru Oshima77bfc272019-04-10 23:40:18233}
234
Sammie Quon358e9572019-11-21 04:38:02235void ShellTestApi::WaitForWindowFinishAnimating(aura::Window* window) {
236 WindowAnimationWaiter waiter(window);
237 waiter.Wait();
238}
239
Toni Barzic8caccc82020-01-30 23:27:19240base::OnceClosure ShellTestApi::CreateWaiterForFinishingWindowAnimation(
241 aura::Window* window) {
242 auto waiter = std::make_unique<WindowAnimationWaiter>(window);
243 return base::BindOnce(&WindowAnimationWaiter::Wait, std::move(waiter));
244}
245
Jun Mukaic9ba6b512019-06-05 19:21:42246PaginationModel* ShellTestApi::GetAppListPaginationModel() {
Manu Cornet191c3142019-10-09 06:31:32247 AppListView* view =
Jun Mukaic9ba6b512019-06-05 19:21:42248 Shell::Get()->app_list_controller()->presenter()->GetView();
249 if (!view)
250 return nullptr;
251 return view->GetAppsPaginationModel();
252}
253
Sammie Quond322167b2021-01-11 22:10:40254bool ShellTestApi::IsContextMenuShown() const {
255 return Shell::GetPrimaryRootWindowController()->IsContextMenuShown();
256}
257
[email protected]0c68e892012-12-08 16:54:53258} // namespace ash