ash_test_helper.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. // Copyright 2013 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. #include "ash/test/ash_test_helper.h"
  5. #include <algorithm>
  6. #include "ash/accelerators/accelerator_controller_impl.h"
  7. #include "ash/accelerometer/accelerometer_reader.h"
  8. #include "ash/ambient/test/ambient_ash_test_helper.h"
  9. #include "ash/app_list/test/app_list_test_helper.h"
  10. #include "ash/assistant/assistant_controller_impl.h"
  11. #include "ash/assistant/test/test_assistant_service.h"
  12. #include "ash/constants/ash_switches.h"
  13. #include "ash/display/display_configuration_controller_test_api.h"
  14. #include "ash/display/screen_ash.h"
  15. #include "ash/host/ash_window_tree_host.h"
  16. #include "ash/keyboard/keyboard_controller_impl.h"
  17. #include "ash/keyboard/test_keyboard_ui.h"
  18. #include "ash/public/cpp/test/test_keyboard_controller_observer.h"
  19. #include "ash/public/cpp/test/test_new_window_delegate.h"
  20. #include "ash/session/test_session_controller_client.h"
  21. #include "ash/shell.h"
  22. #include "ash/shell_init_params.h"
  23. #include "ash/style/dark_light_mode_controller_impl.h"
  24. #include "ash/system/message_center/session_state_notification_blocker.h"
  25. #include "ash/system/model/system_tray_model.h"
  26. #include "ash/system/screen_layout_observer.h"
  27. #include "ash/test/ash_test_ui_stabilizer.h"
  28. #include "ash/test/ash_test_views_delegate.h"
  29. #include "ash/test/toplevel_window.h"
  30. #include "ash/test_shell_delegate.h"
  31. #include "ash/wallpaper/test_wallpaper_controller_client.h"
  32. #include "ash/wallpaper/wallpaper_controller_impl.h"
  33. #include "ash/wm/overview/overview_controller.h"
  34. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  35. #include "base/run_loop.h"
  36. #include "base/system/sys_info.h"
  37. #include "base/system/system_monitor.h"
  38. #include "chromeos/ash/components/audio/cras_audio_handler.h"
  39. #include "chromeos/ash/components/dbus/audio/cras_audio_client.h"
  40. #include "chromeos/ash/components/dbus/rgbkbd/rgbkbd_client.h"
  41. #include "chromeos/dbus/power/power_policy_controller.h"
  42. #include "chromeos/login/login_state/login_state.h"
  43. #include "device/bluetooth/bluetooth_adapter_factory.h"
  44. #include "device/bluetooth/dbus/bluez_dbus_manager.h"
  45. #include "ui/aura/test/test_windows.h"
  46. #include "ui/aura/window.h"
  47. #include "ui/aura/window_tree_host.h"
  48. #include "ui/base/ime/ash/mock_input_method_manager.h"
  49. #include "ui/color/color_provider_manager.h"
  50. #include "ui/display/display_switches.h"
  51. #include "ui/display/manager/display_manager.h"
  52. #include "ui/display/test/display_manager_test_api.h"
  53. #include "ui/display/util/display_util.h"
  54. #include "ui/events/gesture_detection/gesture_configuration.h"
  55. #include "ui/gfx/geometry/point.h"
  56. #include "ui/platform_window/common/platform_window_defaults.h"
  57. #include "ui/views/test/views_test_helper_aura.h"
  58. #include "ui/wm/core/capture_controller.h"
  59. #include "ui/wm/core/cursor_manager.h"
  60. #include "ui/wm/core/focus_controller.h"
  61. namespace ash {
  62. namespace {
  63. std::unique_ptr<views::TestViewsDelegate> MakeTestViewsDelegate() {
  64. return std::make_unique<AshTestViewsDelegate>();
  65. }
  66. } // namespace
  67. AshTestHelper::InitParams::InitParams() = default;
  68. AshTestHelper::InitParams::InitParams(InitParams&&) = default;
  69. AshTestHelper::InitParams::~InitParams() = default;
  70. class AshTestHelper::BluezDBusManagerInitializer {
  71. public:
  72. BluezDBusManagerInitializer() { bluez::BluezDBusManager::InitializeFake(); }
  73. ~BluezDBusManagerInitializer() {
  74. device::BluetoothAdapterFactory::Shutdown();
  75. bluez::BluezDBusManager::Shutdown();
  76. }
  77. };
  78. class AshTestHelper::PowerPolicyControllerInitializer {
  79. public:
  80. PowerPolicyControllerInitializer() {
  81. chromeos::PowerPolicyController::Initialize(
  82. chromeos::PowerManagerClient::Get());
  83. }
  84. ~PowerPolicyControllerInitializer() {
  85. chromeos::PowerPolicyController::Shutdown();
  86. }
  87. };
  88. AshTestHelper::AshTestHelper(ui::ContextFactory* context_factory)
  89. : AuraTestHelper(context_factory),
  90. system_monitor_(std::make_unique<base::SystemMonitor>()) {
  91. views::ViewsTestHelperAura::SetFallbackTestViewsDelegateFactory(
  92. &MakeTestViewsDelegate);
  93. // TODO(jamescook): Can we do this without changing command line?
  94. // Use the origin (1,1) so that it doesn't overlap with the native mouse
  95. // cursor.
  96. if (!base::SysInfo::IsRunningOnChromeOS() &&
  97. !command_line_->GetProcessCommandLine()->HasSwitch(
  98. ::switches::kHostWindowBounds)) {
  99. // TODO(oshima): Disable native events instead of adding offset.
  100. command_line_->GetProcessCommandLine()->AppendSwitchASCII(
  101. ::switches::kHostWindowBounds, "10+10-800x600");
  102. }
  103. TabletModeController::SetUseScreenshotForTest(false);
  104. display::ResetDisplayIdForTest();
  105. display::SetInternalDisplayIds({});
  106. CrasAudioClient::InitializeFake();
  107. // Create CrasAudioHandler for testing since g_browser_process is not
  108. // created in AshTestBase tests.
  109. CrasAudioHandler::InitializeForTesting();
  110. // Reset the global state for the cursor manager. This includes the
  111. // last cursor visibility state, etc.
  112. wm::CursorManager::ResetCursorVisibilityStateForTest();
  113. // Clears the saved state so that test doesn't use on the wrong
  114. // default state.
  115. shell::ToplevelWindow::ClearSavedStateForTest();
  116. }
  117. AshTestHelper::~AshTestHelper() {
  118. if (app_list_test_helper_)
  119. TearDown();
  120. // Ensure the next test starts with a null display::Screen. This must be done
  121. // here instead of in TearDown() since some tests test access to the Screen
  122. // after the shell shuts down (which they use TearDown() to trigger).
  123. ScreenAsh::DeleteScreenForShutdown();
  124. // This should never have a meaningful effect, since either there is no
  125. // ViewsTestHelperAura instance or the instance is currently in its
  126. // destructor.
  127. views::ViewsTestHelperAura::SetFallbackTestViewsDelegateFactory(nullptr);
  128. }
  129. void AshTestHelper::SetUp() {
  130. SetUp(InitParams());
  131. }
  132. void AshTestHelper::TearDown() {
  133. ambient_ash_test_helper_.reset();
  134. // The AppListTestHelper holds a pointer to the AppListController the Shell
  135. // owns, so shut the test helper down first.
  136. app_list_test_helper_.reset();
  137. // Stop event dispatch like we do in ChromeBrowserMainExtraPartsAsh.
  138. Shell::Get()->ShutdownEventDispatch();
  139. Shell::DeleteInstance();
  140. // Suspend the tear down until all resources are returned via
  141. // CompositorFrameSinkClient::ReclaimResources()
  142. base::RunLoop().RunUntilIdle();
  143. chromeos::LoginState::Shutdown();
  144. CrasAudioHandler::Shutdown();
  145. CrasAudioClient::Shutdown();
  146. // The PowerPolicyController holds a pointer to the PowerManagementClient, so
  147. // shut the controller down first.
  148. power_policy_controller_initializer_.reset();
  149. chromeos::PowerManagerClient::Shutdown();
  150. RgbkbdClient::Shutdown();
  151. TabletModeController::SetUseScreenshotForTest(true);
  152. // Destroy all owned objects to prevent tests from depending on their state
  153. // after this returns.
  154. test_keyboard_controller_observer_.reset();
  155. session_controller_client_.reset();
  156. test_views_delegate_.reset();
  157. new_window_delegate_provider_.reset();
  158. bluez_dbus_manager_initializer_.reset();
  159. system_tray_client_.reset();
  160. assistant_service_.reset();
  161. notifier_settings_controller_.reset();
  162. prefs_provider_.reset();
  163. statistics_provider_.reset();
  164. command_line_.reset();
  165. // Purge ColorProviderManager between tests so that we don't accumulate
  166. // ColorProviderInitializers. crbug.com/1349232.
  167. ui::ColorProviderManager::ResetForTesting();
  168. AuraTestHelper::TearDown();
  169. // Cleanup the global state for InputMethodManager, but only if
  170. // it was setup by this test helper. This allows tests to implement
  171. // their own override, and in that case we shouldn't call Shutdown
  172. // otherwise the global state will be deleted twice.
  173. if (input_method_manager_) {
  174. input_method::InputMethodManager::Shutdown();
  175. input_method_manager_ = nullptr;
  176. }
  177. }
  178. aura::Window* AshTestHelper::GetContext() {
  179. aura::Window* root_window = Shell::GetRootWindowForNewWindows();
  180. if (!root_window)
  181. root_window = Shell::GetPrimaryRootWindow();
  182. DCHECK(root_window);
  183. return root_window;
  184. }
  185. aura::WindowTreeHost* AshTestHelper::GetHost() {
  186. auto* manager = Shell::Get()->window_tree_host_manager();
  187. const int64_t id = manager->GetPrimaryDisplayId();
  188. return manager->GetAshWindowTreeHostForDisplayId(id)->AsWindowTreeHost();
  189. }
  190. aura::TestScreen* AshTestHelper::GetTestScreen() {
  191. // If a test needs this, we may need to refactor TestScreen such that its
  192. // methods can operate atop some sort of real screen/host/display, and hook
  193. // them to the ones provided by the shell. For now, not bothering.
  194. NOTIMPLEMENTED();
  195. return nullptr;
  196. }
  197. aura::client::FocusClient* AshTestHelper::GetFocusClient() {
  198. return Shell::Get()->focus_controller();
  199. }
  200. aura::client::CaptureClient* AshTestHelper::GetCaptureClient() {
  201. return wm::CaptureController::Get();
  202. }
  203. void AshTestHelper::SetUp(InitParams init_params) {
  204. // Build `ui_stabilizer_` only for a pixel diff test.
  205. if (init_params.pixel_test_init_params) {
  206. // Constructing `ui_stabilizer_` sets the locale. Therefore, building
  207. // `ui_stabilizer_` before the code that establishes the Ash UI.
  208. ui_stabilizer_ = std::make_unique<AshTestUiStabilizer>(
  209. *init_params.pixel_test_init_params);
  210. }
  211. // This block of objects are conditionally initialized here rather than in the
  212. // constructor to make it easier for test classes to override them.
  213. if (!input_method::InputMethodManager::Get()) {
  214. // |input_method_manager_| is not owned and is cleaned up in TearDown()
  215. // by calling InputMethodManager::Shutdown().
  216. input_method_manager_ = new input_method::MockInputMethodManager();
  217. input_method::InputMethodManager::Initialize(input_method_manager_);
  218. }
  219. if (!bluez::BluezDBusManager::IsInitialized()) {
  220. bluez_dbus_manager_initializer_ =
  221. std::make_unique<BluezDBusManagerInitializer>();
  222. }
  223. if (!RgbkbdClient::Get())
  224. RgbkbdClient::InitializeFake();
  225. if (!chromeos::PowerManagerClient::Get())
  226. chromeos::PowerManagerClient::InitializeFake();
  227. if (!chromeos::PowerPolicyController::IsInitialized()) {
  228. power_policy_controller_initializer_ =
  229. std::make_unique<PowerPolicyControllerInitializer>();
  230. }
  231. if (!NewWindowDelegate::GetInstance()) {
  232. new_window_delegate_provider_ =
  233. std::make_unique<TestNewWindowDelegateProvider>(
  234. std::make_unique<TestNewWindowDelegate>());
  235. }
  236. if (!views::ViewsDelegate::GetInstance())
  237. test_views_delegate_ = MakeTestViewsDelegate();
  238. chromeos::LoginState::Initialize();
  239. ambient_ash_test_helper_ = std::make_unique<AmbientAshTestHelper>();
  240. ShellInitParams shell_init_params;
  241. shell_init_params.delegate = std::move(init_params.delegate);
  242. if (!shell_init_params.delegate)
  243. shell_init_params.delegate = std::make_unique<TestShellDelegate>();
  244. shell_init_params.context_factory = GetContextFactory();
  245. shell_init_params.local_state = init_params.local_state;
  246. shell_init_params.keyboard_ui_factory =
  247. std::make_unique<TestKeyboardUIFactory>();
  248. Shell::CreateInstance(std::move(shell_init_params));
  249. Shell* shell = Shell::Get();
  250. // The dark/light mode educational nudge is expected to be shown when session
  251. // state changed to ACTIVE. This means it might be shown above the shelf in
  252. // all the tests with an active user session. This setting here make it will
  253. // not be shown by default in tests. As keep it shown will change the
  254. // operations needed in many of the tests, e.g, when productive launcher is
  255. // shown as well, we need one more click outside of the launcher to dismiss
  256. // the nudge first before dismissing the launcher.
  257. shell->dark_light_mode_controller()->SetShowNudgeForTesting(false);
  258. // Set up a test wallpaper controller client before signing in any users. At
  259. // the time a user logs in, Wallpaper controller relies on
  260. // WallpaperControllerClient to check if user data should be synced.
  261. wallpaper_controller_client_ =
  262. std::make_unique<TestWallpaperControllerClient>();
  263. shell->wallpaper_controller()->SetClient(wallpaper_controller_client_.get());
  264. // Disable the notification delay timer used to prevent non system
  265. // notifications from showing up right after login. This needs to be done
  266. // before any user sessions are added since the delay timer starts right
  267. // after that.
  268. SessionStateNotificationBlocker::SetUseLoginNotificationDelayForTest(false);
  269. // Cursor is visible by default in tests.
  270. shell->cursor_manager()->ShowCursor();
  271. shell->assistant_controller()->SetAssistant(assistant_service_.get());
  272. shell->system_tray_model()->SetClient(system_tray_client_.get());
  273. session_controller_client_ = std::make_unique<TestSessionControllerClient>(
  274. shell->session_controller(), prefs_provider_.get());
  275. session_controller_client_->InitializeAndSetClient();
  276. if (init_params.start_session)
  277. session_controller_client_->CreatePredefinedUserSessions(1);
  278. // Requires the AppListController the Shell creates.
  279. app_list_test_helper_ = std::make_unique<AppListTestHelper>();
  280. Shell::GetPrimaryRootWindow()->Show();
  281. Shell::GetPrimaryRootWindow()->GetHost()->Show();
  282. // Don't change the display size due to host size resize.
  283. display::test::DisplayManagerTestApi(shell->display_manager())
  284. .DisableChangeDisplayUponHostResize();
  285. // Create the test keyboard controller observer to respond to
  286. // OnLoadKeyboardContentsRequested().
  287. test_keyboard_controller_observer_ =
  288. std::make_unique<TestKeyboardControllerObserver>(
  289. shell->keyboard_controller());
  290. // Tests that change the display configuration generally don't care about the
  291. // notifications and the popup UI can interfere with things like cursors.
  292. shell->screen_layout_observer()->set_show_notifications_for_testing(false);
  293. // Disable display change animations in unit tests.
  294. DisplayConfigurationControllerTestApi(
  295. shell->display_configuration_controller())
  296. .SetDisplayAnimator(false);
  297. // Remove the app dragging animations delay for testing purposes.
  298. shell->overview_controller()->set_delayed_animation_task_delay_for_test(
  299. base::TimeDelta());
  300. // Tests expect empty wallpaper.
  301. shell->wallpaper_controller()->CreateEmptyWallpaperForTesting();
  302. // Move the mouse cursor to far away so that native events don't interfere
  303. // with test expectations.
  304. Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000));
  305. shell->cursor_manager()->EnableMouseEvents();
  306. // Changing GestureConfiguration shouldn't make tests fail. These values
  307. // prevent unexpected events from being generated during tests. Such as
  308. // delayed events which create race conditions on slower tests.
  309. ui::GestureConfiguration* gesture_config =
  310. ui::GestureConfiguration::GetInstance();
  311. gesture_config->set_max_touch_down_duration_for_click_in_ms(800);
  312. gesture_config->set_long_press_time_in_ms(1000);
  313. gesture_config->set_max_touch_move_in_pixels_for_click(5);
  314. // Fake the |ec_lid_angle_driver_status_| in the unittests.
  315. AccelerometerReader::GetInstance()->SetECLidAngleDriverStatusForTesting(
  316. ECLidAngleDriverStatus::NOT_SUPPORTED);
  317. // Call `StabilizeUIForPixelTest()` after the user session is activated (if
  318. // any) in the test setup.
  319. if (ui_stabilizer_) {
  320. DCHECK(init_params.pixel_test_init_params);
  321. StabilizeUIForPixelTest();
  322. }
  323. }
  324. display::Display AshTestHelper::GetSecondaryDisplay() const {
  325. return display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
  326. .GetSecondaryDisplay();
  327. }
  328. void AshTestHelper::SimulateUserLogin(const AccountId& account_id,
  329. user_manager::UserType user_type) {
  330. session_controller_client_->AddUserSession(
  331. account_id, account_id.GetUserEmail(), user_type);
  332. session_controller_client_->SwitchActiveUser(account_id);
  333. session_controller_client_->SetSessionState(
  334. session_manager::SessionState::ACTIVE);
  335. }
  336. void AshTestHelper::StabilizeUIForPixelTest() {
  337. const gfx::Size primary_display_size =
  338. display::Screen::GetScreen()
  339. ->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow())
  340. .size();
  341. ui_stabilizer_->StabilizeUi(primary_display_size);
  342. }
  343. } // namespace ash