Adding UMA for SRT prompt from menu
[chromium-blink-merge.git] / ash / wm / system_modal_container_layout_manager_unittest.cc
blob6229587b890fb91196e300c6748ee4793d82a518
1 // 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.
5 #include "ash/wm/system_modal_container_layout_manager.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/session/session_state_delegate.h"
9 #include "ash/shell.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/test/ash_test_base.h"
12 #include "ash/wm/window_util.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/run_loop.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/compositor/layer.h"
19 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
20 #include "ui/compositor/test/layer_animator_test_controller.h"
21 #include "ui/events/test/event_generator.h"
22 #include "ui/gfx/screen.h"
23 #include "ui/keyboard/keyboard_controller.h"
24 #include "ui/keyboard/keyboard_controller_proxy.h"
25 #include "ui/keyboard/keyboard_switches.h"
26 #include "ui/keyboard/keyboard_util.h"
27 #include "ui/views/test/capture_tracking_view.h"
28 #include "ui/views/widget/widget.h"
29 #include "ui/views/widget/widget_delegate.h"
30 #include "ui/wm/core/window_util.h"
32 namespace ash {
33 namespace test {
35 namespace {
37 aura::Window* GetModalContainer() {
38 return Shell::GetPrimaryRootWindowController()->GetContainer(
39 ash::kShellWindowId_SystemModalContainer);
42 bool AllRootWindowsHaveModalBackgroundsForContainer(int container_id) {
43 std::vector<aura::Window*> containers =
44 Shell::GetContainersFromAllRootWindows(container_id, NULL);
45 bool has_modal_screen = !containers.empty();
46 for (std::vector<aura::Window*>::iterator iter = containers.begin();
47 iter != containers.end(); ++iter) {
48 has_modal_screen &= static_cast<SystemModalContainerLayoutManager*>(
49 (*iter)->layout_manager())->has_modal_background();
51 return has_modal_screen;
54 bool AllRootWindowsHaveLockedModalBackgrounds() {
55 return AllRootWindowsHaveModalBackgroundsForContainer(
56 kShellWindowId_LockSystemModalContainer);
59 bool AllRootWindowsHaveModalBackgrounds() {
60 return AllRootWindowsHaveModalBackgroundsForContainer(
61 kShellWindowId_SystemModalContainer);
64 class TestWindow : public views::WidgetDelegateView {
65 public:
66 explicit TestWindow(bool modal) : modal_(modal) {}
67 ~TestWindow() override {}
69 // The window needs be closed from widget in order for
70 // aura::client::kModalKey property to be reset.
71 static void CloseTestWindow(aura::Window* window) {
72 views::Widget::GetWidgetForNativeWindow(window)->Close();
75 // Overridden from views::View:
76 gfx::Size GetPreferredSize() const override { return gfx::Size(50, 50); }
78 // Overridden from views::WidgetDelegate:
79 views::View* GetContentsView() override { return this; }
80 ui::ModalType GetModalType() const override {
81 return modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE;
84 private:
85 bool modal_;
87 DISALLOW_COPY_AND_ASSIGN(TestWindow);
90 class EventTestWindow : public TestWindow {
91 public:
92 explicit EventTestWindow(bool modal) : TestWindow(modal),
93 mouse_presses_(0) {}
94 ~EventTestWindow() override {}
96 aura::Window* OpenTestWindowWithContext(aura::Window* context) {
97 views::Widget* widget =
98 views::Widget::CreateWindowWithContext(this, context);
99 widget->Show();
100 return widget->GetNativeView();
103 aura::Window* OpenTestWindowWithParent(aura::Window* parent) {
104 DCHECK(parent);
105 views::Widget* widget =
106 views::Widget::CreateWindowWithParent(this, parent);
107 widget->Show();
108 return widget->GetNativeView();
111 // Overridden from views::View:
112 bool OnMousePressed(const ui::MouseEvent& event) override {
113 mouse_presses_++;
114 return false;
117 int mouse_presses() const { return mouse_presses_; }
118 private:
119 int mouse_presses_;
121 DISALLOW_COPY_AND_ASSIGN(EventTestWindow);
124 class TransientWindowObserver : public aura::WindowObserver {
125 public:
126 TransientWindowObserver() : destroyed_(false) {}
127 ~TransientWindowObserver() override {}
129 bool destroyed() const { return destroyed_; }
131 // Overridden from aura::WindowObserver:
132 void OnWindowDestroyed(aura::Window* window) override { destroyed_ = true; }
134 private:
135 bool destroyed_;
137 DISALLOW_COPY_AND_ASSIGN(TransientWindowObserver);
140 } // namespace
142 class SystemModalContainerLayoutManagerTest : public AshTestBase {
143 public:
144 void SetUp() override {
145 // Allow a virtual keyboard (and initialize it per default).
146 base::CommandLine::ForCurrentProcess()->AppendSwitch(
147 keyboard::switches::kEnableVirtualKeyboard);
148 AshTestBase::SetUp();
149 Shell::GetPrimaryRootWindowController()->ActivateKeyboard(
150 keyboard::KeyboardController::GetInstance());
153 void TearDown() override {
154 Shell::GetPrimaryRootWindowController()->DeactivateKeyboard(
155 keyboard::KeyboardController::GetInstance());
156 AshTestBase::TearDown();
159 aura::Window* OpenToplevelTestWindow(bool modal) {
160 views::Widget* widget = views::Widget::CreateWindowWithContext(
161 new TestWindow(modal), CurrentContext());
162 widget->Show();
163 return widget->GetNativeView();
166 aura::Window* OpenTestWindowWithParent(aura::Window* parent, bool modal) {
167 views::Widget* widget =
168 views::Widget::CreateWindowWithParent(new TestWindow(modal), parent);
169 widget->Show();
170 return widget->GetNativeView();
173 // Show or hide the keyboard.
174 void ShowKeyboard(bool show) {
175 keyboard::KeyboardController* keyboard =
176 keyboard::KeyboardController::GetInstance();
177 ASSERT_TRUE(keyboard);
178 if (show == keyboard->keyboard_visible())
179 return;
181 if (show) {
182 keyboard->ShowKeyboard(true);
183 if (keyboard->proxy()->GetKeyboardWindow()->bounds().height() == 0) {
184 keyboard->proxy()->GetKeyboardWindow()->SetBounds(
185 keyboard::FullWidthKeyboardBoundsFromRootBounds(
186 Shell::GetPrimaryRootWindow()->bounds(), 100));
188 } else {
189 keyboard->HideKeyboard(keyboard::KeyboardController::HIDE_REASON_MANUAL);
192 DCHECK_EQ(show, keyboard->keyboard_visible());
197 TEST_F(SystemModalContainerLayoutManagerTest, NonModalTransient) {
198 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
199 aura::Window* transient = OpenTestWindowWithParent(parent.get(), false);
200 TransientWindowObserver destruction_observer;
201 transient->AddObserver(&destruction_observer);
203 EXPECT_EQ(parent.get(), ::wm::GetTransientParent(transient));
204 EXPECT_EQ(parent->parent(), transient->parent());
206 // The transient should be destroyed with its parent.
207 parent.reset();
208 EXPECT_TRUE(destruction_observer.destroyed());
211 TEST_F(SystemModalContainerLayoutManagerTest, ModalTransient) {
212 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
213 // parent should be active.
214 EXPECT_TRUE(wm::IsActiveWindow(parent.get()));
215 aura::Window* t1 = OpenTestWindowWithParent(parent.get(), true);
217 TransientWindowObserver do1;
218 t1->AddObserver(&do1);
220 EXPECT_EQ(parent.get(), ::wm::GetTransientParent(t1));
221 EXPECT_EQ(GetModalContainer(), t1->parent());
223 // t1 should now be active.
224 EXPECT_TRUE(wm::IsActiveWindow(t1));
226 // Attempting to click the parent should result in no activation change.
227 ui::test::EventGenerator e1(Shell::GetPrimaryRootWindow(), parent.get());
228 e1.ClickLeftButton();
229 EXPECT_TRUE(wm::IsActiveWindow(t1));
231 // Now open another modal transient parented to the original modal transient.
232 aura::Window* t2 = OpenTestWindowWithParent(t1, true);
233 TransientWindowObserver do2;
234 t2->AddObserver(&do2);
236 EXPECT_TRUE(wm::IsActiveWindow(t2));
238 EXPECT_EQ(t1, ::wm::GetTransientParent(t2));
239 EXPECT_EQ(GetModalContainer(), t2->parent());
241 // t2 should still be active, even after clicking on t1.
242 ui::test::EventGenerator e2(Shell::GetPrimaryRootWindow(), t1);
243 e2.ClickLeftButton();
244 EXPECT_TRUE(wm::IsActiveWindow(t2));
246 // Both transients should be destroyed with parent.
247 parent.reset();
248 EXPECT_TRUE(do1.destroyed());
249 EXPECT_TRUE(do2.destroyed());
252 TEST_F(SystemModalContainerLayoutManagerTest, ModalNonTransient) {
253 scoped_ptr<aura::Window> t1(OpenToplevelTestWindow(true));
254 // parent should be active.
255 EXPECT_TRUE(wm::IsActiveWindow(t1.get()));
256 TransientWindowObserver do1;
257 t1->AddObserver(&do1);
259 EXPECT_EQ(NULL, ::wm::GetTransientParent(t1.get()));
260 EXPECT_EQ(GetModalContainer(), t1->parent());
262 // t1 should now be active.
263 EXPECT_TRUE(wm::IsActiveWindow(t1.get()));
265 // Attempting to click the parent should result in no activation change.
266 ui::test::EventGenerator e1(Shell::GetPrimaryRootWindow(),
267 Shell::GetPrimaryRootWindow());
268 e1.ClickLeftButton();
269 EXPECT_TRUE(wm::IsActiveWindow(t1.get()));
271 // Now open another modal transient parented to the original modal transient.
272 aura::Window* t2 = OpenTestWindowWithParent(t1.get(), true);
273 TransientWindowObserver do2;
274 t2->AddObserver(&do2);
276 EXPECT_TRUE(wm::IsActiveWindow(t2));
278 EXPECT_EQ(t1, ::wm::GetTransientParent(t2));
279 EXPECT_EQ(GetModalContainer(), t2->parent());
281 // t2 should still be active, even after clicking on t1.
282 ui::test::EventGenerator e2(Shell::GetPrimaryRootWindow(), t1.get());
283 e2.ClickLeftButton();
284 EXPECT_TRUE(wm::IsActiveWindow(t2));
286 // Both transients should be destroyed with parent.
287 t1.reset();
288 EXPECT_TRUE(do1.destroyed());
289 EXPECT_TRUE(do2.destroyed());
292 // Tests that we can activate an unrelated window after a modal window is closed
293 // for a window.
294 TEST_F(SystemModalContainerLayoutManagerTest, CanActivateAfterEndModalSession) {
295 scoped_ptr<aura::Window> unrelated(OpenToplevelTestWindow(false));
296 unrelated->SetBounds(gfx::Rect(100, 100, 50, 50));
297 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
298 // parent should be active.
299 EXPECT_TRUE(wm::IsActiveWindow(parent.get()));
301 scoped_ptr<aura::Window> transient(
302 OpenTestWindowWithParent(parent.get(), true));
303 // t1 should now be active.
304 EXPECT_TRUE(wm::IsActiveWindow(transient.get()));
306 // Attempting to click the parent should result in no activation change.
307 ui::test::EventGenerator e1(Shell::GetPrimaryRootWindow(), parent.get());
308 e1.ClickLeftButton();
309 EXPECT_TRUE(wm::IsActiveWindow(transient.get()));
311 // Now close the transient.
312 transient->Hide();
313 TestWindow::CloseTestWindow(transient.release());
315 base::RunLoop().RunUntilIdle();
317 // parent should now be active again.
318 EXPECT_TRUE(wm::IsActiveWindow(parent.get()));
320 // Attempting to click unrelated should activate it.
321 ui::test::EventGenerator e2(Shell::GetPrimaryRootWindow(), unrelated.get());
322 e2.ClickLeftButton();
323 EXPECT_TRUE(wm::IsActiveWindow(unrelated.get()));
326 TEST_F(SystemModalContainerLayoutManagerTest, EventFocusContainers) {
327 // Create a normal window and attempt to receive a click event.
328 EventTestWindow* main_delegate = new EventTestWindow(false);
329 scoped_ptr<aura::Window> main(
330 main_delegate->OpenTestWindowWithContext(CurrentContext()));
331 EXPECT_TRUE(wm::IsActiveWindow(main.get()));
332 ui::test::EventGenerator e1(Shell::GetPrimaryRootWindow(), main.get());
333 e1.ClickLeftButton();
334 EXPECT_EQ(1, main_delegate->mouse_presses());
336 // Create a modal window for the main window and verify that the main window
337 // no longer receives mouse events.
338 EventTestWindow* transient_delegate = new EventTestWindow(true);
339 aura::Window* transient =
340 transient_delegate->OpenTestWindowWithParent(main.get());
341 EXPECT_TRUE(wm::IsActiveWindow(transient));
342 e1.ClickLeftButton();
343 EXPECT_EQ(1, transient_delegate->mouse_presses());
345 for (int block_reason = FIRST_BLOCK_REASON;
346 block_reason < NUMBER_OF_BLOCK_REASONS;
347 ++block_reason) {
348 // Create a window in the lock screen container and ensure that it receives
349 // the mouse event instead of the modal window (crbug.com/110920).
350 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
351 EventTestWindow* lock_delegate = new EventTestWindow(false);
352 scoped_ptr<aura::Window> lock(lock_delegate->OpenTestWindowWithParent(
353 Shell::GetPrimaryRootWindowController()->GetContainer(
354 ash::kShellWindowId_LockScreenContainer)));
355 EXPECT_TRUE(wm::IsActiveWindow(lock.get()));
356 e1.ClickLeftButton();
357 EXPECT_EQ(1, lock_delegate->mouse_presses());
359 // Make sure that a modal container created by the lock screen can still
360 // receive mouse events.
361 EventTestWindow* lock_modal_delegate = new EventTestWindow(true);
362 aura::Window* lock_modal =
363 lock_modal_delegate->OpenTestWindowWithParent(lock.get());
364 EXPECT_TRUE(wm::IsActiveWindow(lock_modal));
365 e1.ClickLeftButton();
366 // Verify that none of the other containers received any more mouse presses.
367 EXPECT_EQ(1, lock_modal_delegate->mouse_presses());
368 EXPECT_EQ(1, lock_delegate->mouse_presses());
369 EXPECT_EQ(1, main_delegate->mouse_presses());
370 EXPECT_EQ(1, transient_delegate->mouse_presses());
371 UnblockUserSession();
375 // Makes sure we don't crash if a modal window is shown while the parent window
376 // is hidden.
377 TEST_F(SystemModalContainerLayoutManagerTest, ShowModalWhileHidden) {
378 // Hide the lock screen.
379 Shell::GetPrimaryRootWindowController()
380 ->GetContainer(kShellWindowId_SystemModalContainer)
381 ->layer()
382 ->SetOpacity(0);
384 // Create a modal window.
385 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
386 scoped_ptr<aura::Window> modal_window(
387 OpenTestWindowWithParent(parent.get(), true));
388 parent->Show();
389 modal_window->Show();
392 // Verifies we generate a capture lost when showing a modal window.
393 TEST_F(SystemModalContainerLayoutManagerTest, ChangeCapture) {
394 views::Widget* widget = views::Widget::CreateWindowWithContext(
395 new TestWindow(false), CurrentContext());
396 scoped_ptr<aura::Window> widget_window(widget->GetNativeView());
397 views::test::CaptureTrackingView* view = new views::test::CaptureTrackingView;
398 widget->GetContentsView()->AddChildView(view);
399 view->SetBoundsRect(widget->GetContentsView()->bounds());
400 widget->Show();
402 gfx::Point center(view->width() / 2, view->height() / 2);
403 views::View::ConvertPointToScreen(view, &center);
404 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), center);
405 generator.PressLeftButton();
406 EXPECT_TRUE(view->got_press());
407 scoped_ptr<aura::Window> modal_window(
408 OpenTestWindowWithParent(widget->GetNativeView(), true));
409 modal_window->Show();
410 EXPECT_TRUE(view->got_capture_lost());
413 // Verifies that the window gets moved into the visible screen area upon screen
414 // resize.
415 TEST_F(SystemModalContainerLayoutManagerTest, KeepVisible) {
416 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
417 scoped_ptr<aura::Window> main(OpenTestWindowWithParent(GetModalContainer(),
418 true));
419 main->SetBounds(gfx::Rect(924, 668, 100, 100));
420 // We set now the bounds of the root window to something new which will
421 // Then trigger the repos operation.
422 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
424 gfx::Rect bounds = main->bounds();
425 EXPECT_EQ(bounds, gfx::Rect(700, 500, 100, 100));
428 // Verifies that centered windows will remain centered after the visible screen
429 // area changed.
430 TEST_F(SystemModalContainerLayoutManagerTest, KeepCentered) {
431 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
432 scoped_ptr<aura::Window> main(OpenTestWindowWithParent(GetModalContainer(),
433 true));
434 // Center the window.
435 main->SetBounds(gfx::Rect((800 - 512) / 2, (600 - 256) / 2, 512, 256));
437 // We set now the bounds of the root window to something new which will
438 // Then trigger the reposition operation.
439 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
441 // The window should still be centered.
442 gfx::Rect bounds = main->bounds();
443 EXPECT_EQ(bounds.ToString(), gfx::Rect(256, 256, 512, 256).ToString());
446 TEST_F(SystemModalContainerLayoutManagerTest, ShowNormalBackgroundOrLocked) {
447 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
448 scoped_ptr<aura::Window> modal_window(
449 OpenTestWindowWithParent(parent.get(), true));
450 parent->Show();
451 modal_window->Show();
453 // Normal system modal window. Shows normal system modal background and not
454 // locked.
455 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
456 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
458 TestWindow::CloseTestWindow(modal_window.release());
459 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
460 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
462 for (int block_reason = FIRST_BLOCK_REASON;
463 block_reason < NUMBER_OF_BLOCK_REASONS;
464 ++block_reason) {
465 // Normal system modal window while blocked. Shows blocked system modal
466 // background.
467 BlockUserSession(static_cast<UserSessionBlockReason>(block_reason));
468 scoped_ptr<aura::Window> lock_parent(OpenTestWindowWithParent(
469 Shell::GetPrimaryRootWindowController()->GetContainer(
470 ash::kShellWindowId_LockScreenContainer),
471 false));
472 scoped_ptr<aura::Window> lock_modal_window(OpenTestWindowWithParent(
473 lock_parent.get(), true));
474 lock_parent->Show();
475 lock_modal_window->Show();
476 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
477 EXPECT_TRUE(AllRootWindowsHaveLockedModalBackgrounds());
478 TestWindow::CloseTestWindow(lock_modal_window.release());
480 // Normal system modal window while blocked, but it belongs to the normal
481 // window. Shouldn't show blocked system modal background, but normal.
482 scoped_ptr<aura::Window> modal_window(
483 OpenTestWindowWithParent(parent.get(), true));
484 modal_window->Show();
485 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
486 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
487 TestWindow::CloseTestWindow(modal_window.release());
488 UnblockUserSession();
489 // Here we should check the behavior of the locked system modal dialog when
490 // unlocked, but such case isn't handled very well right now.
491 // See crbug.com/157660
492 // TODO(mukai): add the test case when the bug is fixed.
496 TEST_F(SystemModalContainerLayoutManagerTest, MultiDisplays) {
497 if (!SupportsMultipleDisplays())
498 return;
500 UpdateDisplay("500x500,500x500");
502 scoped_ptr<aura::Window> normal(OpenToplevelTestWindow(false));
503 normal->SetBounds(gfx::Rect(100, 100, 50, 50));
505 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
506 EXPECT_EQ(2U, root_windows.size());
507 aura::Window* container1 = Shell::GetContainer(
508 root_windows[0], ash::kShellWindowId_SystemModalContainer);
509 aura::Window* container2 = Shell::GetContainer(
510 root_windows[1], ash::kShellWindowId_SystemModalContainer);
512 scoped_ptr<aura::Window> modal1(
513 OpenTestWindowWithParent(container1, true));
514 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
515 EXPECT_TRUE(wm::IsActiveWindow(modal1.get()));
517 scoped_ptr<aura::Window> modal11(
518 OpenTestWindowWithParent(container1, true));
519 EXPECT_TRUE(wm::IsActiveWindow(modal11.get()));
521 scoped_ptr<aura::Window> modal2(
522 OpenTestWindowWithParent(container2, true));
523 EXPECT_TRUE(wm::IsActiveWindow(modal2.get()));
525 // Sanity check if they're on the correct containers.
526 EXPECT_EQ(container1, modal1->parent());
527 EXPECT_EQ(container1, modal11->parent());
528 EXPECT_EQ(container2, modal2->parent());
530 TestWindow::CloseTestWindow(modal2.release());
531 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
532 EXPECT_TRUE(wm::IsActiveWindow(modal11.get()));
534 TestWindow::CloseTestWindow(modal11.release());
535 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
536 EXPECT_TRUE(wm::IsActiveWindow(modal1.get()));
538 UpdateDisplay("500x500");
539 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
540 EXPECT_TRUE(wm::IsActiveWindow(modal1.get()));
542 UpdateDisplay("500x500,600x600");
543 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
544 EXPECT_TRUE(wm::IsActiveWindow(modal1.get()));
546 // No more modal screen.
547 modal1->Hide();
548 TestWindow::CloseTestWindow(modal1.release());
549 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
550 EXPECT_TRUE(wm::IsActiveWindow(normal.get()));
553 // Test that with the visible keyboard, an existing system modal dialog gets
554 // positioned into the visible area.
555 TEST_F(SystemModalContainerLayoutManagerTest,
556 SystemModalDialogGetPushedFromKeyboard) {
557 const gfx::Rect& container_bounds = GetModalContainer()->bounds();
558 // Place the window at the bottom of the screen.
559 gfx::Size modal_size(100, 100);
560 gfx::Point modal_origin = gfx::Point(
561 (container_bounds.right() - modal_size.width()) / 2, // X centered
562 container_bounds.bottom() - modal_size.height()); // at bottom
563 gfx::Rect modal_bounds = gfx::Rect(modal_origin, modal_size);
565 // Create a modal window.
566 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
567 scoped_ptr<aura::Window> modal_window(
568 OpenTestWindowWithParent(parent.get(), true));
569 modal_window->SetBounds(modal_bounds);
570 parent->Show();
571 modal_window->Show();
573 EXPECT_EQ(modal_bounds.ToString(), modal_window->bounds().ToString());
575 // The keyboard gets shown and the dialog should get pushed.
576 ShowKeyboard(true);
577 EXPECT_NE(modal_bounds.ToString(), modal_window->bounds().ToString());
578 EXPECT_GT(modal_bounds.y(), modal_window->bounds().y());
579 EXPECT_EQ(modal_size.ToString(), modal_window->bounds().size().ToString());
580 EXPECT_EQ(modal_origin.x(), modal_window->bounds().x());
582 // After the keyboard is gone, the window will remain where it was.
583 ShowKeyboard(false);
584 EXPECT_NE(modal_bounds.ToString(), modal_window->bounds().ToString());
585 EXPECT_EQ(modal_size.ToString(), modal_window->bounds().size().ToString());
586 EXPECT_EQ(modal_origin.x(), modal_window->bounds().x());
589 // Test that windows will not get cropped through the visible virtual keyboard -
590 // if centered.
591 TEST_F(SystemModalContainerLayoutManagerTest,
592 SystemModalDialogGetPushedButNotCroppedFromKeyboard) {
593 const gfx::Rect& container_bounds = GetModalContainer()->bounds();
594 const gfx::Size screen_size = Shell::GetPrimaryRootWindow()->bounds().size();
595 // Place the window at the bottom of the screen.
596 gfx::Size modal_size(100, screen_size.height() - 70);
597 gfx::Point modal_origin = gfx::Point(
598 (container_bounds.right() - modal_size.width()) / 2, // X centered
599 container_bounds.bottom() - modal_size.height()); // at bottom
600 gfx::Rect modal_bounds = gfx::Rect(modal_origin, modal_size);
602 // Create a modal window.
603 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
604 scoped_ptr<aura::Window> modal_window(
605 OpenTestWindowWithParent(parent.get(), true));
606 modal_window->SetBounds(modal_bounds);
607 parent->Show();
608 modal_window->Show();
610 EXPECT_EQ(modal_bounds.ToString(), modal_window->bounds().ToString());
612 // The keyboard gets shown and the dialog should get pushed up, but not get
613 // cropped (and aligned to the top).
614 ShowKeyboard(true);
615 EXPECT_EQ(modal_size.ToString(), modal_window->bounds().size().ToString());
616 EXPECT_EQ(modal_origin.x(), modal_window->bounds().x());
617 EXPECT_EQ(0, modal_window->bounds().y());
619 ShowKeyboard(false);
622 // Test that windows will not get cropped through the visible virtual keyboard -
623 // if not centered.
624 TEST_F(SystemModalContainerLayoutManagerTest,
625 SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered) {
626 const gfx::Size screen_size = Shell::GetPrimaryRootWindow()->bounds().size();
627 // Place the window at the bottom of the screen.
628 gfx::Size modal_size(100, screen_size.height() - 70);
629 gfx::Point modal_origin = gfx::Point(10, 20);
630 gfx::Rect modal_bounds = gfx::Rect(modal_origin, modal_size);
632 // Create a modal window.
633 scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
634 scoped_ptr<aura::Window> modal_window(
635 OpenTestWindowWithParent(parent.get(), true));
636 modal_window->SetBounds(modal_bounds);
637 parent->Show();
638 modal_window->Show();
640 EXPECT_EQ(modal_bounds.ToString(), modal_window->bounds().ToString());
642 // The keyboard gets shown and the dialog should get pushed up, but not get
643 // cropped (and aligned to the top).
644 ShowKeyboard(true);
645 EXPECT_EQ(modal_size.ToString(), modal_window->bounds().size().ToString());
646 EXPECT_EQ(modal_origin.x(), modal_window->bounds().x());
647 EXPECT_EQ(0, modal_window->bounds().y());
649 ShowKeyboard(false);
652 } // namespace test
653 } // namespace ash