Home | History | Annotate | Download | only in wm
      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 
      5 #include "ash/shell.h"
      6 #include "ash/shell_window_ids.h"
      7 #include "ash/test/ash_test_base.h"
      8 #include "ash/test/test_shell_delegate.h"
      9 #include "ash/wm/window_util.h"
     10 #include "base/command_line.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "ui/app_list/app_list_switches.h"
     13 #include "ui/app_list/views/app_list_view.h"
     14 #include "ui/aura/test/event_generator.h"
     15 #include "ui/aura/test/test_windows.h"
     16 #include "ui/aura/window.h"
     17 
     18 namespace ash {
     19 
     20 namespace {
     21 
     22 const int kMinimalCenteredAppListMargin = 10;
     23 
     24 }
     25 
     26 // The parameter is true to test the centered app list, false for normal.
     27 // (The test name ends in "/0" for normal, "/1" for centered.)
     28 class AppListControllerTest : public test::AshTestBase,
     29                               public ::testing::WithParamInterface<bool> {
     30  public:
     31   AppListControllerTest();
     32   virtual ~AppListControllerTest();
     33   virtual void SetUp() OVERRIDE;
     34 
     35   bool IsCentered() const;
     36 };
     37 
     38 AppListControllerTest::AppListControllerTest() {
     39 }
     40 
     41 AppListControllerTest::~AppListControllerTest() {
     42 }
     43 
     44 void AppListControllerTest::SetUp() {
     45   AshTestBase::SetUp();
     46   if (IsCentered()) {
     47     CommandLine* command_line = CommandLine::ForCurrentProcess();
     48     command_line->AppendSwitch(app_list::switches::kEnableCenteredAppList);
     49   }
     50 }
     51 
     52 bool AppListControllerTest::IsCentered() const {
     53   return GetParam();
     54 }
     55 
     56 // Tests that app launcher hides when focus moves to a normal window.
     57 TEST_P(AppListControllerTest, HideOnFocusOut) {
     58   Shell::GetInstance()->ToggleAppList(NULL);
     59   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
     60 
     61   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
     62   wm::ActivateWindow(window.get());
     63 
     64   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
     65 }
     66 
     67 // Tests that app launcher remains visible when focus is moved to a different
     68 // window in kShellWindowId_AppListContainer.
     69 TEST_P(AppListControllerTest, RemainVisibleWhenFocusingToApplistContainer) {
     70   Shell::GetInstance()->ToggleAppList(NULL);
     71   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
     72 
     73   aura::Window* applist_container = Shell::GetContainer(
     74       Shell::GetPrimaryRootWindow(), kShellWindowId_AppListContainer);
     75   scoped_ptr<aura::Window> window(
     76       aura::test::CreateTestWindowWithId(0, applist_container));
     77   wm::ActivateWindow(window.get());
     78 
     79   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
     80 }
     81 
     82 // Tests that clicking outside the app-list bubble closes it.
     83 TEST_P(AppListControllerTest, ClickOutsideBubbleClosesBubble) {
     84   Shell* shell = Shell::GetInstance();
     85   shell->ToggleAppList(NULL);
     86 
     87   aura::Window* app_window = shell->GetAppListWindow();
     88   ASSERT_TRUE(app_window);
     89   aura::test::EventGenerator generator(shell->GetPrimaryRootWindow(),
     90                                        app_window);
     91   // Click on the bubble itself. The bubble should remain visible.
     92   generator.ClickLeftButton();
     93   EXPECT_TRUE(shell->GetAppListTargetVisibility());
     94 
     95   // Click outside the bubble. This should close it.
     96   gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();
     97   gfx::Point point_outside =
     98       gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
     99       gfx::Vector2d(10, 0);
    100   EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
    101   generator.MoveMouseToInHost(point_outside);
    102   generator.ClickLeftButton();
    103   EXPECT_FALSE(shell->GetAppListTargetVisibility());
    104 }
    105 
    106 // Tests that clicking outside the app-list bubble closes it.
    107 TEST_P(AppListControllerTest, TapOutsideBubbleClosesBubble) {
    108   Shell* shell = Shell::GetInstance();
    109   shell->ToggleAppList(NULL);
    110 
    111   aura::Window* app_window = shell->GetAppListWindow();
    112   ASSERT_TRUE(app_window);
    113   gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();
    114 
    115   aura::test::EventGenerator generator(shell->GetPrimaryRootWindow());
    116   // Click on the bubble itself. The bubble should remain visible.
    117   generator.GestureTapAt(app_window_bounds.CenterPoint());
    118   EXPECT_TRUE(shell->GetAppListTargetVisibility());
    119 
    120   // Click outside the bubble. This should close it.
    121   gfx::Point point_outside =
    122       gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
    123       gfx::Vector2d(10, 0);
    124   EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
    125   generator.GestureTapAt(point_outside);
    126   EXPECT_FALSE(shell->GetAppListTargetVisibility());
    127 }
    128 
    129 // Tests opening the app launcher on a non-primary display, then deleting the
    130 // display.
    131 TEST_P(AppListControllerTest, NonPrimaryDisplay) {
    132   if (!SupportsMultipleDisplays())
    133     return;
    134 
    135   // Set up a screen with two displays (horizontally adjacent).
    136   UpdateDisplay("800x600,800x600");
    137 
    138   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    139   ASSERT_EQ(2u, root_windows.size());
    140   aura::Window* secondary_window = root_windows[1];
    141   EXPECT_EQ("800,0 800x600", secondary_window->GetBoundsInScreen().ToString());
    142 
    143   Shell::GetInstance()->ToggleAppList(secondary_window);
    144   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    145 
    146   // Remove the secondary display. Shouldn't crash (http://crbug.com/368990).
    147   UpdateDisplay("800x600");
    148 
    149   // Updating the displays should close the app list.
    150   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
    151 }
    152 
    153 // Tests opening the app launcher on a tiny display that is too small to contain
    154 // it.
    155 TEST_P(AppListControllerTest, TinyDisplay) {
    156   // Don't test this for the non-centered app list case; it isn't designed for
    157   // small displays. The most common case of a small display --- when the
    158   // virtual keyboard is open --- switches into the centered app list mode, so
    159   // we just want to run this test in that case.
    160   if (!IsCentered())
    161     return;
    162 
    163   // UpdateDisplay is not supported in this case, so just skip the test.
    164   if (!SupportsHostWindowResize())
    165     return;
    166 
    167   // Set up a screen with a tiny display (height smaller than the app list).
    168   UpdateDisplay("400x300");
    169 
    170   Shell::GetInstance()->ToggleAppList(NULL);
    171   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    172 
    173   // The top of the app list should be on-screen (even if the bottom is not).
    174   // We need to manually calculate the Y coordinate of the top of the app list
    175   // from the anchor (center) and height. There isn't a bounds rect that gives
    176   // the actual app list position (the widget bounds include the bubble border
    177   // which is much bigger than the actual app list size).
    178   app_list::AppListView* app_list = Shell::GetInstance()->GetAppListView();
    179   int app_list_view_top =
    180       app_list->anchor_rect().y() - app_list->bounds().height() / 2;
    181   EXPECT_GE(app_list_view_top, kMinimalCenteredAppListMargin);
    182 }
    183 
    184 INSTANTIATE_TEST_CASE_P(AppListControllerTestInstance,
    185                         AppListControllerTest,
    186                         ::testing::Bool());
    187 
    188 }  // namespace ash
    189