lock_action_handler_layout_manager_unittest.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. // Copyright 2017 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/wm/lock_action_handler_layout_manager.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "ash/keyboard/keyboard_controller_impl.h"
  8. #include "ash/keyboard/ui/keyboard_ui.h"
  9. #include "ash/keyboard/ui/keyboard_ui_controller.h"
  10. #include "ash/keyboard/ui/keyboard_util.h"
  11. #include "ash/keyboard/ui/test/keyboard_test_util.h"
  12. #include "ash/lock_screen_action/lock_screen_action_background_controller.h"
  13. #include "ash/lock_screen_action/lock_screen_action_background_controller_stub.h"
  14. #include "ash/lock_screen_action/test_lock_screen_action_background_controller.h"
  15. #include "ash/public/cpp/keyboard/keyboard_switches.h"
  16. #include "ash/public/cpp/shelf_config.h"
  17. #include "ash/public/cpp/shell_window_ids.h"
  18. #include "ash/public/mojom/tray_action.mojom.h"
  19. #include "ash/root_window_controller.h"
  20. #include "ash/screen_util.h"
  21. #include "ash/session/test_session_controller_client.h"
  22. #include "ash/shelf/shelf_layout_manager.h"
  23. #include "ash/shell.h"
  24. #include "ash/test/ash_test_base.h"
  25. #include "ash/tray_action/test_tray_action_client.h"
  26. #include "ash/tray_action/tray_action.h"
  27. #include "ash/wm/window_state.h"
  28. #include "base/bind.h"
  29. #include "base/callback.h"
  30. #include "base/command_line.h"
  31. #include "base/memory/ptr_util.h"
  32. #include "ui/aura/client/aura_constants.h"
  33. #include "ui/aura/window.h"
  34. #include "ui/views/widget/widget.h"
  35. #include "ui/views/widget/widget_delegate.h"
  36. namespace ash {
  37. namespace {
  38. aura::Window* GetContainer(ShellWindowId container_id) {
  39. return Shell::GetPrimaryRootWindowController()->GetContainer(container_id);
  40. }
  41. class TestWindowDelegate : public views::WidgetDelegate {
  42. public:
  43. TestWindowDelegate() {
  44. SetCanMaximize(true);
  45. SetCanResize(true);
  46. SetOwnedByWidget(true);
  47. SetFocusTraversesOut(true);
  48. }
  49. TestWindowDelegate(const TestWindowDelegate&) = delete;
  50. TestWindowDelegate& operator=(const TestWindowDelegate&) = delete;
  51. ~TestWindowDelegate() override = default;
  52. // views::WidgetDelegate:
  53. views::Widget* GetWidget() override { return widget_; }
  54. const views::Widget* GetWidget() const override { return widget_; }
  55. bool CanActivate() const override { return true; }
  56. void set_widget(views::Widget* widget) { widget_ = widget; }
  57. private:
  58. views::Widget* widget_ = nullptr;
  59. };
  60. } // namespace
  61. class LockActionHandlerLayoutManagerTest : public AshTestBase {
  62. public:
  63. LockActionHandlerLayoutManagerTest() = default;
  64. LockActionHandlerLayoutManagerTest(
  65. const LockActionHandlerLayoutManagerTest&) = delete;
  66. LockActionHandlerLayoutManagerTest& operator=(
  67. const LockActionHandlerLayoutManagerTest&) = delete;
  68. ~LockActionHandlerLayoutManagerTest() override = default;
  69. void SetUp() override {
  70. // Allow a virtual keyboard (and initialize it per default).
  71. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  72. keyboard::switches::kEnableVirtualKeyboard);
  73. action_background_controller_factory_ = base::BindRepeating(
  74. &LockActionHandlerLayoutManagerTest::CreateActionBackgroundController,
  75. base::Unretained(this));
  76. LockScreenActionBackgroundController::SetFactoryCallbackForTesting(
  77. &action_background_controller_factory_);
  78. AshTestBase::SetUp();
  79. views::Widget::InitParams widget_params(
  80. views::Widget::InitParams::TYPE_WINDOW);
  81. widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  82. lock_window_ = CreateTestingWindow(std::move(widget_params),
  83. kShellWindowId_LockScreenContainer,
  84. std::make_unique<TestWindowDelegate>());
  85. }
  86. void TearDown() override {
  87. lock_window_.reset();
  88. AshTestBase::TearDown();
  89. LockScreenActionBackgroundController::SetFactoryCallbackForTesting(nullptr);
  90. }
  91. std::unique_ptr<aura::Window> CreateTestingWindow(
  92. views::Widget::InitParams params,
  93. ShellWindowId parent_id,
  94. std::unique_ptr<TestWindowDelegate> window_delegate) {
  95. params.parent = GetContainer(parent_id);
  96. views::Widget* widget = new views::Widget;
  97. if (window_delegate) {
  98. window_delegate->set_widget(widget);
  99. params.delegate = window_delegate.release();
  100. }
  101. widget->Init(std::move(params));
  102. widget->Show();
  103. return base::WrapUnique<aura::Window>(widget->GetNativeView());
  104. }
  105. // Show or hide the keyboard.
  106. void ShowKeyboard(bool show) {
  107. auto* keyboard = keyboard::KeyboardUIController::Get();
  108. ASSERT_TRUE(keyboard->IsEnabled());
  109. if (show == keyboard->IsKeyboardVisible())
  110. return;
  111. if (show) {
  112. keyboard->ShowKeyboard(true);
  113. ASSERT_TRUE(keyboard::WaitUntilShown());
  114. } else {
  115. keyboard->HideKeyboardByUser();
  116. }
  117. DCHECK_EQ(show, keyboard->IsKeyboardVisible());
  118. }
  119. void SetUpTrayActionClientAndLockSession(mojom::TrayActionState state) {
  120. Shell::Get()->tray_action()->SetClient(
  121. tray_action_client_.CreateRemoteAndBind(), state);
  122. GetSessionControllerClient()->SetSessionState(
  123. session_manager::SessionState::LOCKED);
  124. }
  125. // Virtual so test specializations can override the background controller
  126. // implementation used in tests.
  127. virtual std::unique_ptr<LockScreenActionBackgroundController>
  128. CreateActionBackgroundController() {
  129. return std::make_unique<LockScreenActionBackgroundControllerStub>();
  130. }
  131. private:
  132. std::unique_ptr<aura::Window> lock_window_;
  133. LockScreenActionBackgroundController::FactoryCallback
  134. action_background_controller_factory_;
  135. TestTrayActionClient tray_action_client_;
  136. };
  137. class LockActionHandlerLayoutManagerTestWithTestBackgroundController
  138. : public LockActionHandlerLayoutManagerTest {
  139. public:
  140. LockActionHandlerLayoutManagerTestWithTestBackgroundController() = default;
  141. LockActionHandlerLayoutManagerTestWithTestBackgroundController(
  142. const LockActionHandlerLayoutManagerTestWithTestBackgroundController&) =
  143. delete;
  144. LockActionHandlerLayoutManagerTestWithTestBackgroundController& operator=(
  145. const LockActionHandlerLayoutManagerTestWithTestBackgroundController&) =
  146. delete;
  147. ~LockActionHandlerLayoutManagerTestWithTestBackgroundController() override =
  148. default;
  149. void TearDown() override {
  150. LockActionHandlerLayoutManagerTest::TearDown();
  151. background_controller_ = nullptr;
  152. }
  153. std::unique_ptr<LockScreenActionBackgroundController>
  154. CreateActionBackgroundController() override {
  155. auto result = std::make_unique<TestLockScreenActionBackgroundController>();
  156. EXPECT_FALSE(background_controller_);
  157. background_controller_ = result.get();
  158. return result;
  159. }
  160. TestLockScreenActionBackgroundController* background_controller() {
  161. return background_controller_;
  162. }
  163. private:
  164. // The lock screen action background controller created by
  165. // |CreateActionBackgroundController|.
  166. TestLockScreenActionBackgroundController* background_controller_ = nullptr;
  167. };
  168. TEST_F(LockActionHandlerLayoutManagerTest, PreserveNormalWindowBounds) {
  169. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  170. views::Widget::InitParams widget_params(
  171. views::Widget::InitParams::TYPE_WINDOW);
  172. const gfx::Rect bounds = gfx::Rect(10, 10, 300, 300);
  173. widget_params.bounds = bounds;
  174. // Note: default window delegate (used when no widget delegate is set) does
  175. // not allow the window to be maximized.
  176. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  177. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  178. nullptr /* window_delegate */);
  179. EXPECT_EQ(bounds.ToString(), window->GetBoundsInScreen().ToString());
  180. gfx::Rect work_area =
  181. screen_util::GetDisplayWorkAreaBoundsInParent(window.get());
  182. window->SetBounds(work_area);
  183. EXPECT_EQ(work_area.ToString(), window->GetBoundsInScreen().ToString());
  184. const gfx::Rect bounds2 = gfx::Rect(100, 100, 200, 200);
  185. window->SetBounds(bounds2);
  186. EXPECT_EQ(bounds2.ToString(), window->GetBoundsInScreen().ToString());
  187. }
  188. TEST_F(LockActionHandlerLayoutManagerTest, MaximizedWindowBounds) {
  189. // Cange the shelf alignment before locking the session.
  190. GetPrimaryShelf()->SetAlignment(ShelfAlignment::kRight);
  191. // This should change the shelf alignment to bottom (temporarily for locked
  192. // state).
  193. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  194. views::Widget::InitParams widget_params(
  195. views::Widget::InitParams::TYPE_WINDOW);
  196. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  197. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  198. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  199. std::make_unique<TestWindowDelegate>());
  200. // Verify that the window bounds are equal to work area for the bottom shelf
  201. // alignment, which matches how the shelf is aligned on the lock screen,
  202. gfx::Rect target_bounds =
  203. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  204. target_bounds.Inset(
  205. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  206. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  207. }
  208. TEST_F(LockActionHandlerLayoutManagerTest, FullscreenWindowBounds) {
  209. // Cange the shelf alignment before locking the session.
  210. GetPrimaryShelf()->SetAlignment(ShelfAlignment::kRight);
  211. // This should change the shelf alignment to bottom (temporarily for locked
  212. // state).
  213. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  214. views::Widget::InitParams widget_params(
  215. views::Widget::InitParams::TYPE_WINDOW);
  216. widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  217. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  218. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  219. std::make_unique<TestWindowDelegate>());
  220. // Verify that the window bounds are equal to work area for the bottom shelf
  221. // alignment, which matches how the shelf is aligned on the lock screen,
  222. gfx::Rect target_bounds =
  223. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  224. target_bounds.Inset(
  225. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  226. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  227. }
  228. TEST_F(LockActionHandlerLayoutManagerTest, MaximizeResizableWindow) {
  229. GetSessionControllerClient()->SetSessionState(
  230. session_manager::SessionState::LOCKED);
  231. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  232. views::Widget::InitParams widget_params(
  233. views::Widget::InitParams::TYPE_WINDOW);
  234. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  235. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  236. std::make_unique<TestWindowDelegate>());
  237. gfx::Rect target_bounds =
  238. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  239. target_bounds.Inset(
  240. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  241. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  242. }
  243. TEST_F(LockActionHandlerLayoutManagerTest, KeyboardBounds) {
  244. gfx::Rect initial_bounds =
  245. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  246. initial_bounds.Inset(
  247. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  248. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  249. views::Widget::InitParams widget_params(
  250. views::Widget::InitParams::TYPE_WINDOW);
  251. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  252. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  253. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  254. std::make_unique<TestWindowDelegate>());
  255. ASSERT_EQ(initial_bounds.ToString(), window->GetBoundsInScreen().ToString());
  256. ShowKeyboard(true);
  257. gfx::Rect keyboard_bounds =
  258. keyboard::KeyboardUIController::Get()->GetVisualBoundsInScreen();
  259. // Sanity check that the keyboard intersects with original window bounds - if
  260. // this is not true, the window bounds would remain unchanged.
  261. ASSERT_TRUE(keyboard_bounds.Intersects(initial_bounds));
  262. gfx::Rect target_bounds =
  263. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  264. target_bounds.Inset(gfx::Insets().set_bottom(keyboard_bounds.height()));
  265. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  266. // Verify that window bounds get updated when Chromevox bounds are shown (so
  267. // the Chromevox panel does not overlay with the action handler window).
  268. ShelfLayoutManager* shelf_layout_manager =
  269. GetPrimaryShelf()->shelf_layout_manager();
  270. ASSERT_TRUE(shelf_layout_manager);
  271. const int kAccessibilityPanelHeight = 45;
  272. std::unique_ptr<views::Widget> widget =
  273. CreateTestWidget(nullptr, kShellWindowId_AccessibilityPanelContainer);
  274. SetAccessibilityPanelHeight(kAccessibilityPanelHeight);
  275. target_bounds.Inset(gfx::Insets().set_top(kAccessibilityPanelHeight));
  276. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  277. ShowKeyboard(false);
  278. }
  279. TEST_F(LockActionHandlerLayoutManagerTest, AddingWindowInActiveState) {
  280. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  281. views::Widget::InitParams widget_params(
  282. views::Widget::InitParams::TYPE_WINDOW);
  283. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  284. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  285. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  286. nullptr /* window_delegate */);
  287. EXPECT_TRUE(window->IsVisible());
  288. EXPECT_TRUE(window->HasFocus());
  289. }
  290. TEST_F(LockActionHandlerLayoutManagerTest, AddingWindowInLaunchingState) {
  291. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  292. views::Widget::InitParams widget_params(
  293. views::Widget::InitParams::TYPE_WINDOW);
  294. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  295. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  296. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  297. nullptr /* window_delegate */);
  298. EXPECT_TRUE(window->IsVisible());
  299. EXPECT_TRUE(window->HasFocus());
  300. }
  301. TEST_F(LockActionHandlerLayoutManagerTest, AddingWindowInNonActiveState) {
  302. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kAvailable);
  303. views::Widget::InitParams widget_params(
  304. views::Widget::InitParams::TYPE_WINDOW);
  305. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  306. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  307. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  308. nullptr /* window_delegate */);
  309. // The window should not be visible if the note action is not in active state.
  310. EXPECT_FALSE(window->IsVisible());
  311. EXPECT_FALSE(window->HasFocus());
  312. // When the action state changes back to active, the window should be
  313. // shown.
  314. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  315. mojom::TrayActionState::kActive);
  316. EXPECT_EQ(GetContainer(kShellWindowId_LockActionHandlerContainer),
  317. window->parent());
  318. EXPECT_TRUE(window->IsVisible());
  319. EXPECT_TRUE(window->HasFocus());
  320. // The window should be hidden again upon leaving the active state.
  321. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  322. mojom::TrayActionState::kAvailable);
  323. EXPECT_EQ(GetContainer(kShellWindowId_LockActionHandlerContainer),
  324. window->parent());
  325. EXPECT_FALSE(window->IsVisible());
  326. EXPECT_FALSE(window->HasFocus());
  327. }
  328. TEST_F(LockActionHandlerLayoutManagerTest, FocusWindowWhileInNonActiveState) {
  329. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kAvailable);
  330. views::Widget::InitParams widget_params(
  331. views::Widget::InitParams::TYPE_WINDOW);
  332. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  333. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  334. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  335. nullptr /* window_delegate */);
  336. EXPECT_EQ(GetContainer(kShellWindowId_LockActionHandlerContainer),
  337. window->parent());
  338. EXPECT_FALSE(window->IsVisible());
  339. EXPECT_FALSE(window->HasFocus());
  340. window->Focus();
  341. EXPECT_FALSE(window->IsVisible());
  342. EXPECT_FALSE(window->HasFocus());
  343. }
  344. TEST_F(LockActionHandlerLayoutManagerTest,
  345. RequestShowWindowOutsideActiveState) {
  346. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kAvailable);
  347. views::Widget::InitParams widget_params(
  348. views::Widget::InitParams::TYPE_WINDOW);
  349. widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  350. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  351. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  352. nullptr /* window_delegate */);
  353. EXPECT_EQ(GetContainer(kShellWindowId_LockActionHandlerContainer),
  354. window->parent());
  355. EXPECT_FALSE(window->IsVisible());
  356. window->Show();
  357. EXPECT_FALSE(window->IsVisible());
  358. EXPECT_FALSE(window->HasFocus());
  359. }
  360. TEST_F(LockActionHandlerLayoutManagerTest, MultipleMonitors) {
  361. UpdateDisplay("300x400,400x500");
  362. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  363. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  364. views::Widget::InitParams widget_params(
  365. views::Widget::InitParams::TYPE_WINDOW);
  366. widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  367. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  368. std::move(widget_params), kShellWindowId_LockActionHandlerContainer,
  369. std::make_unique<TestWindowDelegate>());
  370. gfx::Rect target_bounds =
  371. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  372. target_bounds.Inset(
  373. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  374. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  375. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  376. WindowState* window_state = WindowState::Get(window.get());
  377. window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));
  378. window_state->Maximize();
  379. // Maximize the window width as the restore bounds is inside 2nd display but
  380. // lock container windows are always on primary display.
  381. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  382. target_bounds = gfx::Rect(300, 400);
  383. target_bounds.Inset(
  384. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  385. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  386. window_state->Restore();
  387. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  388. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  389. window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
  390. window_state->Maximize();
  391. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  392. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  393. window_state->Restore();
  394. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  395. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  396. window->SetBoundsInScreen(gfx::Rect(0, 0, 30, 40), GetSecondaryDisplay());
  397. target_bounds = gfx::Rect(400, 500);
  398. target_bounds.Offset(300, 0);
  399. EXPECT_EQ(root_windows[1], window->GetRootWindow());
  400. EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  401. }
  402. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  403. WindowAddedWhileBackgroundShowing) {
  404. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  405. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  406. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  407. kShellWindowId_LockActionHandlerContainer,
  408. std::make_unique<TestWindowDelegate>());
  409. EXPECT_EQ(LockScreenActionBackgroundState::kShowing,
  410. background_controller()->state());
  411. EXPECT_FALSE(window->IsVisible());
  412. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  413. // Move action to active - this will make the app window showable. Though,
  414. // showing the window should be delayed until the background finishes
  415. // showing.
  416. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  417. mojom::TrayActionState::kActive);
  418. EXPECT_FALSE(window->IsVisible());
  419. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  420. // Finish showing the background - this should make the app window visible.
  421. ASSERT_TRUE(background_controller()->FinishShow());
  422. EXPECT_TRUE(window->IsVisible());
  423. EXPECT_TRUE(window->HasFocus());
  424. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  425. // Move action state back to available - this should hide the app window, and
  426. // request the background window to be hidden.
  427. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  428. mojom::TrayActionState::kAvailable);
  429. EXPECT_FALSE(window->IsVisible());
  430. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  431. ASSERT_TRUE(background_controller()->FinishHide());
  432. EXPECT_FALSE(window->IsVisible());
  433. EXPECT_FALSE(background_controller()->GetWindow()->IsVisible());
  434. }
  435. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  436. WindowAddedWhenBackgroundShown) {
  437. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  438. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  439. mojom::TrayActionState::kActive);
  440. // Finish showing the background - this should make the app window visible
  441. // once it's created.
  442. ASSERT_TRUE(background_controller()->FinishShow());
  443. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  444. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  445. kShellWindowId_LockActionHandlerContainer,
  446. std::make_unique<TestWindowDelegate>());
  447. EXPECT_TRUE(window->IsVisible());
  448. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  449. EXPECT_EQ(LockScreenActionBackgroundState::kShown,
  450. background_controller()->state());
  451. // Move action state back to not available - this should immediately hide both
  452. // the app and background window,
  453. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  454. mojom::TrayActionState::kNotAvailable);
  455. EXPECT_FALSE(window->IsVisible());
  456. EXPECT_FALSE(background_controller()->GetWindow()->IsVisible());
  457. EXPECT_EQ(LockScreenActionBackgroundState::kHidden,
  458. background_controller()->state());
  459. }
  460. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  461. SecondWindowAddedWhileShowingBackground) {
  462. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  463. EXPECT_EQ(LockScreenActionBackgroundState::kShowing,
  464. background_controller()->state());
  465. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  466. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  467. kShellWindowId_LockActionHandlerContainer,
  468. std::make_unique<TestWindowDelegate>());
  469. EXPECT_FALSE(window->IsVisible());
  470. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  471. std::unique_ptr<aura::Window> second_window = CreateTestingWindow(
  472. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  473. kShellWindowId_LockActionHandlerContainer,
  474. std::make_unique<TestWindowDelegate>());
  475. EXPECT_FALSE(window->IsVisible());
  476. EXPECT_FALSE(second_window->IsVisible());
  477. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  478. // Finish showing the background. The app windows should be shown at this
  479. // point.
  480. ASSERT_TRUE(background_controller()->FinishShow());
  481. EXPECT_TRUE(window->IsVisible());
  482. EXPECT_FALSE(window->HasFocus());
  483. EXPECT_TRUE(second_window->IsVisible());
  484. EXPECT_TRUE(second_window->HasFocus());
  485. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  486. // Deactivate the action - the windows should get hidden.
  487. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  488. mojom::TrayActionState::kAvailable);
  489. EXPECT_FALSE(window->IsVisible());
  490. EXPECT_FALSE(second_window->IsVisible());
  491. EXPECT_EQ(LockScreenActionBackgroundState::kHiding,
  492. background_controller()->state());
  493. }
  494. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  495. RelaunchWhileHidingBackground) {
  496. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  497. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  498. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  499. kShellWindowId_LockActionHandlerContainer,
  500. std::make_unique<TestWindowDelegate>());
  501. ASSERT_TRUE(background_controller()->FinishShow());
  502. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  503. mojom::TrayActionState::kAvailable);
  504. ASSERT_EQ(LockScreenActionBackgroundState::kHiding,
  505. background_controller()->state());
  506. // Create new app window to show.
  507. window = CreateTestingWindow(
  508. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  509. kShellWindowId_LockActionHandlerContainer,
  510. std::make_unique<TestWindowDelegate>());
  511. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  512. mojom::TrayActionState::kActive);
  513. ASSERT_EQ(LockScreenActionBackgroundState::kShowing,
  514. background_controller()->state());
  515. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  516. EXPECT_FALSE(window->IsVisible());
  517. background_controller()->FinishShow();
  518. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  519. EXPECT_TRUE(window->IsVisible());
  520. EXPECT_TRUE(window->HasFocus());
  521. }
  522. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  523. ActionDeactivatedWhileShowingTheBackground) {
  524. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  525. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  526. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  527. kShellWindowId_LockActionHandlerContainer,
  528. std::make_unique<TestWindowDelegate>());
  529. // Lock screen note action was launched, so the background window is expected
  530. // to start being shown.
  531. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  532. EXPECT_FALSE(window->IsVisible());
  533. EXPECT_EQ(LockScreenActionBackgroundState::kShowing,
  534. background_controller()->state());
  535. // Move lock screen note action back to available state (i.e. not activated
  536. // state), and test that the background window starts hiding.
  537. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  538. mojom::TrayActionState::kAvailable);
  539. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  540. EXPECT_FALSE(window->IsVisible());
  541. EXPECT_EQ(LockScreenActionBackgroundState::kHiding,
  542. background_controller()->state());
  543. }
  544. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  545. ActionDisabledWhileShowingTheBackground) {
  546. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kLaunching);
  547. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  548. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  549. kShellWindowId_LockActionHandlerContainer,
  550. std::make_unique<TestWindowDelegate>());
  551. // Lock screen note action was launched, so the background window is expected
  552. // to start being shown.
  553. EXPECT_TRUE(background_controller()->GetWindow()->IsVisible());
  554. EXPECT_FALSE(window->IsVisible());
  555. EXPECT_EQ(LockScreenActionBackgroundState::kShowing,
  556. background_controller()->state());
  557. // Make lock screen note action unavailable, and test that the background
  558. // window is hidden immediately.
  559. Shell::Get()->tray_action()->UpdateLockScreenNoteState(
  560. mojom::TrayActionState::kNotAvailable);
  561. EXPECT_FALSE(background_controller()->GetWindow()->IsVisible());
  562. EXPECT_FALSE(window->IsVisible());
  563. }
  564. TEST_F(LockActionHandlerLayoutManagerTestWithTestBackgroundController,
  565. BackgroundWindowBounds) {
  566. SetUpTrayActionClientAndLockSession(mojom::TrayActionState::kActive);
  567. ASSERT_TRUE(background_controller()->FinishShow());
  568. std::unique_ptr<aura::Window> window = CreateTestingWindow(
  569. views::Widget::InitParams(views::Widget::InitParams::TYPE_WINDOW),
  570. kShellWindowId_LockActionHandlerContainer,
  571. std::make_unique<TestWindowDelegate>());
  572. ASSERT_TRUE(window->IsVisible());
  573. ASSERT_TRUE(background_controller()->GetWindow()->IsVisible());
  574. // Verify that the window bounds are equal to work area for the bottom shelf
  575. // alignment, which matches how the shelf is aligned on the lock screen,
  576. gfx::Rect target_app_window_bounds =
  577. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  578. target_app_window_bounds.Inset(
  579. gfx::Insets().set_bottom(ShelfConfig::Get()->shelf_size()));
  580. EXPECT_EQ(target_app_window_bounds, window->GetBoundsInScreen());
  581. EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
  582. background_controller()->GetWindow()->GetBoundsInScreen());
  583. }
  584. } // namespace ash