Home | History | Annotate | Download | only in wm
      1 // Copyright 2014 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 "athena/wm/public/window_manager.h"
      6 
      7 #include "athena/screen/public/screen_manager.h"
      8 #include "athena/test/athena_test_base.h"
      9 #include "athena/wm/public/window_list_provider.h"
     10 #include "athena/wm/split_view_controller.h"
     11 #include "athena/wm/test/window_manager_impl_test_api.h"
     12 #include "athena/wm/window_manager_impl.h"
     13 #include "ui/aura/client/window_tree_client.h"
     14 #include "ui/aura/test/test_window_delegate.h"
     15 #include "ui/aura/window.h"
     16 #include "ui/base/hit_test.h"
     17 #include "ui/events/test/event_generator.h"
     18 #include "ui/gfx/display.h"
     19 #include "ui/gfx/screen.h"
     20 #include "ui/wm/core/window_util.h"
     21 
     22 namespace athena {
     23 
     24 class WindowManagerTest : public test::AthenaTestBase {
     25  public:
     26   WindowManagerTest() {}
     27   virtual ~WindowManagerTest() {}
     28 
     29   scoped_ptr<aura::Window> CreateAndActivateWindow(
     30       aura::WindowDelegate* delegate) {
     31     scoped_ptr<aura::Window> window(CreateTestWindow(delegate, gfx::Rect()));
     32     window->Show();
     33     wm::ActivateWindow(window.get());
     34     return window.Pass();
     35   }
     36 
     37  private:
     38   DISALLOW_COPY_AND_ASSIGN(WindowManagerTest);
     39 };
     40 
     41 TEST_F(WindowManagerTest, OverviewModeBasics) {
     42   aura::test::TestWindowDelegate delegate;
     43   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
     44   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
     45 
     46   test::WindowManagerImplTestApi wm_api;
     47   wm::ActivateWindow(second.get());
     48 
     49   ASSERT_FALSE(WindowManager::Get()->IsOverviewModeActive());
     50   EXPECT_EQ(first->bounds().ToString(), second->bounds().ToString());
     51   EXPECT_EQ(gfx::Screen::GetNativeScreen()
     52                 ->GetPrimaryDisplay()
     53                 .work_area()
     54                 .size()
     55                 .ToString(),
     56             first->bounds().size().ToString());
     57   EXPECT_FALSE(WindowManager::Get()->IsOverviewModeActive());
     58 
     59   // Tests that going into overview mode does not change the window bounds.
     60   WindowManager::Get()->ToggleOverview();
     61   ASSERT_TRUE(WindowManager::Get()->IsOverviewModeActive());
     62   EXPECT_EQ(first->bounds().ToString(), second->bounds().ToString());
     63   EXPECT_EQ(gfx::Screen::GetNativeScreen()
     64                 ->GetPrimaryDisplay()
     65                 .work_area()
     66                 .size()
     67                 .ToString(),
     68             first->bounds().size().ToString());
     69   EXPECT_TRUE(first->IsVisible());
     70   EXPECT_TRUE(second->IsVisible());
     71 
     72   // Terminate overview mode. |first| should be hidden, since it's not visible
     73   // to the user anymore.
     74   WindowManager::Get()->ToggleOverview();
     75   ASSERT_FALSE(WindowManager::Get()->IsOverviewModeActive());
     76   EXPECT_FALSE(first->IsVisible());
     77   EXPECT_TRUE(second->IsVisible());
     78 }
     79 
     80 TEST_F(WindowManagerTest, OverviewToSplitViewMode) {
     81   test::WindowManagerImplTestApi wm_api;
     82 
     83   aura::test::TestWindowDelegate delegate;
     84   scoped_ptr<aura::Window> w1(CreateAndActivateWindow(&delegate));
     85   scoped_ptr<aura::Window> w2(CreateAndActivateWindow(&delegate));
     86   scoped_ptr<aura::Window> w3(CreateAndActivateWindow(&delegate));
     87   wm::ActivateWindow(w3.get());
     88 
     89   WindowManager::Get()->ToggleOverview();
     90   EXPECT_TRUE(w1->IsVisible());
     91   EXPECT_TRUE(w2->IsVisible());
     92   EXPECT_TRUE(w3->IsVisible());
     93 
     94   // Go into split-view mode.
     95   WindowOverviewModeDelegate* overview_delegate = wm_api.wm();
     96   overview_delegate->OnSelectSplitViewWindow(w3.get(), NULL, w3.get());
     97   EXPECT_TRUE(w3->IsVisible());
     98   EXPECT_TRUE(w2->IsVisible());
     99   EXPECT_FALSE(w1->IsVisible());
    100 }
    101 
    102 TEST_F(WindowManagerTest, NewWindowFromOverview) {
    103   aura::test::TestWindowDelegate delegate;
    104   scoped_ptr<aura::Window> w1(CreateAndActivateWindow(&delegate));
    105   scoped_ptr<aura::Window> w2(CreateAndActivateWindow(&delegate));
    106 
    107   WindowManager::Get()->ToggleOverview();
    108   EXPECT_TRUE(w1->IsVisible());
    109   EXPECT_TRUE(w2->IsVisible());
    110 
    111   // Test that opening a new window exits overview mode. The new window could
    112   // have been opened by JavaScript or by the home card.
    113   scoped_ptr<aura::Window> w3(CreateAndActivateWindow(&delegate));
    114 
    115   ASSERT_FALSE(WindowManager::Get()->IsOverviewModeActive());
    116   EXPECT_TRUE(w3->IsVisible());
    117   EXPECT_TRUE(wm::IsActiveWindow(w3.get()));
    118   EXPECT_FALSE(w1->IsVisible());
    119   EXPECT_FALSE(w2->IsVisible());
    120 }
    121 
    122 TEST_F(WindowManagerTest, BezelGestureToSplitViewMode) {
    123   aura::test::TestWindowDelegate delegate;
    124   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
    125   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
    126   scoped_ptr<aura::Window> third(CreateAndActivateWindow(&delegate));
    127 
    128   test::WindowManagerImplTestApi wm_api;
    129 
    130   // Test that going into split-view mode with two-finger gesture selects the
    131   // correct windows on left and right splits.
    132   ui::test::EventGenerator generator(root_window());
    133   const gfx::Point start_points[2] = {
    134       gfx::Point(2, 10), gfx::Point(4, 20),
    135   };
    136   const int kEventTimeSepration = 16;
    137   int x_middle = root_window()->bounds().width() / 2;
    138   generator.GestureMultiFingerScroll(
    139       2, start_points, kEventTimeSepration, 1, x_middle, 0);
    140   ASSERT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    141   EXPECT_EQ(second.get(), wm_api.GetSplitViewController()->left_window());
    142   EXPECT_EQ(third.get(), wm_api.GetSplitViewController()->right_window());
    143   EXPECT_EQ(second->bounds().size().ToString(),
    144             third->bounds().size().ToString());
    145 }
    146 
    147 TEST_F(WindowManagerTest, BezelGestureToSwitchBetweenWindows) {
    148   aura::test::TestWindowDelegate delegate;
    149   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
    150   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
    151   scoped_ptr<aura::Window> third(CreateAndActivateWindow(&delegate));
    152   first->Hide();
    153   second->Hide();
    154 
    155   test::WindowManagerImplTestApi wm_api;
    156 
    157   EXPECT_EQ(third.get(),
    158             wm_api.GetWindowListProvider()->GetWindowList().back());
    159 
    160   // Do a two-finger swipe from the left bezel.
    161   ui::test::EventGenerator generator(root_window());
    162   const gfx::Point left_bezel_points[2] = {
    163       gfx::Point(2, 10), gfx::Point(4, 20),
    164   };
    165   const int kEventTimeSeparation = 16;
    166   int width = root_window()->bounds().width();
    167   generator.GestureMultiFingerScroll(
    168       2, left_bezel_points, kEventTimeSeparation, 1, width, 0);
    169   EXPECT_TRUE(wm::IsActiveWindow(second.get()));
    170   EXPECT_EQ(second.get(),
    171             wm_api.GetWindowListProvider()->GetWindowList().back());
    172 
    173   // Do a two-finger swipe from the right bezel.
    174   const gfx::Point right_bezel_points[2] = {
    175       gfx::Point(width - 5, 10),
    176       gfx::Point(width - 10, 20)
    177   };
    178   generator.GestureMultiFingerScroll(
    179       2, right_bezel_points, kEventTimeSeparation, 1, -width, 0);
    180   EXPECT_TRUE(wm::IsActiveWindow(third.get()));
    181   EXPECT_EQ(third.get(),
    182             wm_api.GetWindowListProvider()->GetWindowList().back());
    183 }
    184 
    185 TEST_F(WindowManagerTest, TitleDragSwitchBetweenWindows) {
    186   aura::test::TestWindowDelegate delegate;
    187   delegate.set_window_component(HTCAPTION);
    188   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
    189   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
    190   scoped_ptr<aura::Window> third(CreateAndActivateWindow(&delegate));
    191 
    192   test::WindowManagerImplTestApi wm_api;
    193 
    194   EXPECT_EQ(third.get(),
    195             wm_api.GetWindowListProvider()->GetWindowList().back());
    196 
    197   // Do a title-swipe from the top to switch to the previous window.
    198   ui::test::EventGenerator generator(root_window());
    199   generator.GestureScrollSequence(gfx::Point(20, 10),
    200                                   gfx::Point(20, 400),
    201                                   base::TimeDelta::FromMilliseconds(20),
    202                                   5);
    203   EXPECT_TRUE(wm::IsActiveWindow(second.get()));
    204   EXPECT_EQ(second.get(),
    205             wm_api.GetWindowListProvider()->GetWindowList().back());
    206   EXPECT_TRUE(second->IsVisible());
    207   EXPECT_FALSE(third->IsVisible());
    208 
    209   // Performing the same gesture again will switch back to |third|.
    210   generator.GestureScrollSequence(gfx::Point(20, 10),
    211                                   gfx::Point(20, 400),
    212                                   base::TimeDelta::FromMilliseconds(20),
    213                                   5);
    214   EXPECT_TRUE(wm::IsActiveWindow(third.get()));
    215   EXPECT_EQ(third.get(),
    216             wm_api.GetWindowListProvider()->GetWindowList().back());
    217   EXPECT_FALSE(second->IsVisible());
    218   EXPECT_TRUE(third->IsVisible());
    219 
    220   // Perform a swipe that doesn't go enough to perform the window switch.
    221   generator.GestureScrollSequence(gfx::Point(20, 10),
    222                                   gfx::Point(20, 90),
    223                                   base::TimeDelta::FromMilliseconds(20),
    224                                   5);
    225   EXPECT_TRUE(wm::IsActiveWindow(third.get()));
    226   EXPECT_EQ(third.get(),
    227             wm_api.GetWindowListProvider()->GetWindowList().back());
    228   EXPECT_FALSE(second->IsVisible());
    229   EXPECT_TRUE(third->IsVisible());
    230 }
    231 
    232 TEST_F(WindowManagerTest, TitleDragSwitchBetweenWindowsInSplitViewMode) {
    233   aura::test::TestWindowDelegate delegate;
    234   delegate.set_window_component(HTCAPTION);
    235   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
    236   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
    237   scoped_ptr<aura::Window> third(CreateAndActivateWindow(&delegate));
    238   scoped_ptr<aura::Window> fourth(CreateAndActivateWindow(&delegate));
    239 
    240   test::WindowManagerImplTestApi wm_api;
    241 
    242   // Test that going into split-view mode with two-finger gesture selects the
    243   // correct windows on left and right splits.
    244   ui::test::EventGenerator generator(root_window());
    245   const gfx::Point start_points[2] = {
    246       gfx::Point(2, 10), gfx::Point(4, 20),
    247   };
    248   const int kEventTimeSepration = 16;
    249   int x_middle = root_window()->bounds().width() / 2;
    250   generator.GestureMultiFingerScroll(
    251       2, start_points, kEventTimeSepration, 1, x_middle, 0);
    252   ASSERT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    253   EXPECT_EQ(third.get(), wm_api.GetSplitViewController()->left_window());
    254   EXPECT_EQ(fourth.get(), wm_api.GetSplitViewController()->right_window());
    255 
    256   // Swipe the title of the left window. It should switch to |second|.
    257   generator.GestureScrollSequence(gfx::Point(20, 10),
    258                                   gfx::Point(20, 400),
    259                                   base::TimeDelta::FromMilliseconds(20),
    260                                   5);
    261   EXPECT_EQ(second.get(), wm_api.GetSplitViewController()->left_window());
    262   EXPECT_EQ(fourth.get(), wm_api.GetSplitViewController()->right_window());
    263   aura::Window::Windows windows =
    264       wm_api.GetWindowListProvider()->GetWindowList();
    265   ASSERT_EQ(4u, windows.size());
    266   EXPECT_EQ(second.get(), windows[3]);
    267   EXPECT_EQ(fourth.get(), windows[2]);
    268 
    269   // Swipe the title of the right window now. It should switch to |third|.
    270   generator.GestureScrollSequence(gfx::Point(x_middle + 20, 10),
    271                                   gfx::Point(x_middle + 20, 400),
    272                                   base::TimeDelta::FromMilliseconds(20),
    273                                   5);
    274   EXPECT_EQ(second.get(), wm_api.GetSplitViewController()->left_window());
    275   EXPECT_EQ(third.get(), wm_api.GetSplitViewController()->right_window());
    276   windows = wm_api.GetWindowListProvider()->GetWindowList();
    277   ASSERT_EQ(4u, windows.size());
    278   EXPECT_EQ(third.get(), windows[3]);
    279   EXPECT_EQ(second.get(), windows[2]);
    280 }
    281 
    282 TEST_F(WindowManagerTest, NewWindowBounds) {
    283   aura::test::TestWindowDelegate delegate;
    284   scoped_ptr<aura::Window> first(CreateAndActivateWindow(&delegate));
    285 
    286   test::WindowManagerImplTestApi wm_api;
    287   // The window should have the same size as the container.
    288   const gfx::Size work_area =
    289       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size();
    290   EXPECT_EQ(work_area.ToString(),
    291             first->bounds().size().ToString());
    292   EXPECT_TRUE(first->bounds().origin().IsOrigin());
    293 
    294   // A second window should have the same bounds as the first one.
    295   scoped_ptr<aura::Window> second(CreateAndActivateWindow(&delegate));
    296   EXPECT_EQ(first->bounds().ToString(), second->bounds().ToString());
    297 
    298   // Get into split view.
    299   wm_api.GetSplitViewController()->ActivateSplitMode(NULL, NULL, NULL);
    300   const gfx::Rect left_bounds =
    301       wm_api.GetSplitViewController()->left_window()->bounds();
    302   EXPECT_NE(work_area.ToString(),
    303             left_bounds.size().ToString());
    304 
    305   // A new window should replace the left window when in split view.
    306   scoped_ptr<aura::Window> third(CreateAndActivateWindow(&delegate));
    307   EXPECT_EQ(wm_api.GetSplitViewController()->left_window(), third.get());
    308   EXPECT_EQ(left_bounds.ToString(), third->bounds().ToString());
    309 }
    310 
    311 TEST_F(WindowManagerTest, SplitModeActivationByShortcut) {
    312   test::WindowManagerImplTestApi wm_api;
    313 
    314   aura::test::TestWindowDelegate delegate;
    315   scoped_ptr<aura::Window> w1(CreateAndActivateWindow(&delegate));
    316 
    317   // Splitview mode needs at least two windows.
    318   wm_api.wm()->ToggleSplitView();
    319   EXPECT_FALSE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    320 
    321   scoped_ptr<aura::Window> w2(CreateAndActivateWindow(&delegate));
    322   w2->Show();
    323 
    324   wm_api.wm()->ToggleSplitView();
    325   EXPECT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    326   int width =
    327       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().width();
    328 
    329   EXPECT_EQ(w1->bounds().width(), w2->bounds().width());
    330   EXPECT_GE(width / 2, w1->bounds().width());
    331 
    332   // Toggle back to normal mode.
    333   wm_api.wm()->ToggleSplitView();
    334   EXPECT_FALSE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    335 
    336   EXPECT_EQ(width, w1->bounds().width());
    337   EXPECT_EQ(width, w2->bounds().width());
    338 }
    339 
    340 TEST_F(WindowManagerTest, OverviewModeFromSplitMode) {
    341   test::WindowManagerImplTestApi wm_api;
    342 
    343   aura::test::TestWindowDelegate delegate;
    344   scoped_ptr<aura::Window> w1(CreateAndActivateWindow(&delegate));
    345   scoped_ptr<aura::Window> w2(CreateAndActivateWindow(&delegate));
    346   scoped_ptr<aura::Window> w3(CreateAndActivateWindow(&delegate));
    347 
    348   // Get into split-view mode, and then turn on overview mode.
    349   wm_api.GetSplitViewController()->ActivateSplitMode(NULL, NULL, NULL);
    350   WindowManager::Get()->ToggleOverview();
    351   EXPECT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    352   EXPECT_EQ(w3.get(), wm_api.GetSplitViewController()->left_window());
    353   EXPECT_EQ(w2.get(), wm_api.GetSplitViewController()->right_window());
    354 
    355   WindowOverviewModeDelegate* overview_delegate = wm_api.wm();
    356   overview_delegate->OnSelectWindow(w1.get());
    357   EXPECT_FALSE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
    358   EXPECT_TRUE(w1->IsVisible());
    359   // Make sure the windows that were in split-view mode are hidden.
    360   EXPECT_FALSE(w2->IsVisible());
    361   EXPECT_FALSE(w3->IsVisible());
    362 }
    363 
    364 }  // namespace athena
    365