Home | History | Annotate | Download | only in shelf
      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/shelf/shelf_window_watcher.h"
      6 
      7 #include "ash/ash_switches.h"
      8 #include "ash/shelf/shelf_item_types.h"
      9 #include "ash/shelf/shelf_model.h"
     10 #include "ash/shelf/shelf_util.h"
     11 #include "ash/shell.h"
     12 #include "ash/shell_window_ids.h"
     13 #include "ash/test/ash_test_base.h"
     14 #include "ash/test/shell_test_api.h"
     15 #include "ash/wm/window_resizer.h"
     16 #include "ash/wm/window_state.h"
     17 #include "ash/wm/window_util.h"
     18 #include "base/command_line.h"
     19 #include "ui/aura/client/aura_constants.h"
     20 #include "ui/aura/window.h"
     21 #include "ui/base/hit_test.h"
     22 
     23 namespace ash {
     24 
     25 class ShelfWindowWatcherTest : public test::AshTestBase {
     26  public:
     27   ShelfWindowWatcherTest() : model_(NULL) {}
     28   virtual ~ShelfWindowWatcherTest() {}
     29 
     30   virtual void SetUp() OVERRIDE {
     31     test::AshTestBase::SetUp();
     32     model_ = test::ShellTestApi(Shell::GetInstance()).shelf_model();
     33   }
     34 
     35   virtual void TearDown() OVERRIDE {
     36     model_ = NULL;
     37     test::AshTestBase::TearDown();
     38   }
     39 
     40   ShelfID CreateShelfItem(aura::Window* window) {
     41     ShelfID id = model_->next_id();
     42     ShelfItemDetails item_details;
     43     item_details.type = TYPE_PLATFORM_APP;
     44     SetShelfItemDetailsForWindow(window, item_details);
     45     return id;
     46   }
     47 
     48  protected:
     49   ShelfModel* model_;
     50 
     51  private:
     52   DISALLOW_COPY_AND_ASSIGN(ShelfWindowWatcherTest);
     53 };
     54 
     55 TEST_F(ShelfWindowWatcherTest, CreateAndRemoveShelfItem) {
     56   // ShelfModel only has an APP_LIST item.
     57   EXPECT_EQ(1, model_->item_count());
     58 
     59   scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(0));
     60   scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithId(0));
     61 
     62   // Create a ShelfItem for w1.
     63   ShelfID id_w1 = CreateShelfItem(w1.get());
     64   EXPECT_EQ(2, model_->item_count());
     65 
     66   int index_w1 = model_->ItemIndexByID(id_w1);
     67   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
     68 
     69   // Create a ShelfItem for w2.
     70   ShelfID id_w2 = CreateShelfItem(w2.get());
     71   EXPECT_EQ(3, model_->item_count());
     72 
     73   int index_w2 = model_->ItemIndexByID(id_w2);
     74   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w2].status);
     75 
     76   // ShelfItem is removed when assoicated window is destroyed.
     77   ClearShelfItemDetailsForWindow(w1.get());
     78   EXPECT_EQ(2, model_->item_count());
     79   ClearShelfItemDetailsForWindow(w2.get());
     80   EXPECT_EQ(1, model_->item_count());
     81   // Clears twice doesn't do anything.
     82   ClearShelfItemDetailsForWindow(w2.get());
     83   EXPECT_EQ(1, model_->item_count());
     84 
     85 }
     86 
     87 TEST_F(ShelfWindowWatcherTest, ActivateWindow) {
     88   // ShelfModel only have APP_LIST item.
     89   EXPECT_EQ(1, model_->item_count());
     90   scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(0));
     91   scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithId(0));
     92 
     93   // Create a ShelfItem for w1.
     94   ShelfID id_w1 = CreateShelfItem(w1.get());
     95   EXPECT_EQ(2, model_->item_count());
     96   int index_w1 = model_->ItemIndexByID(id_w1);
     97   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
     98 
     99   // Create a ShelfItem for w2.
    100   ShelfID id_w2 = CreateShelfItem(w2.get());
    101   EXPECT_EQ(3, model_->item_count());
    102   int index_w2 = model_->ItemIndexByID(id_w2);
    103   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
    104   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w2].status);
    105 
    106   // ShelfItem for w1 is active when w1 is activated.
    107   wm::ActivateWindow(w1.get());
    108   EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w1].status);
    109 
    110   // ShelfItem for w2 is active state when w2 is activated.
    111   wm::ActivateWindow(w2.get());
    112   EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
    113   EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w2].status);
    114 }
    115 
    116 TEST_F(ShelfWindowWatcherTest, UpdateWindowProperty) {
    117   // ShelfModel only has an APP_LIST item.
    118   EXPECT_EQ(1, model_->item_count());
    119 
    120   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
    121 
    122   // Create a ShelfItem for |window|.
    123   ShelfID id = CreateShelfItem(window.get());
    124   EXPECT_EQ(2, model_->item_count());
    125 
    126   int index = model_->ItemIndexByID(id);
    127   EXPECT_EQ(STATUS_RUNNING, model_->items()[index].status);
    128 
    129   // Update ShelfItem for |window|.
    130   ShelfItemDetails details;
    131   details.type = TYPE_PLATFORM_APP;
    132 
    133   SetShelfItemDetailsForWindow(window.get(), details);
    134   // No new item is created after updating a launcher item.
    135   EXPECT_EQ(2, model_->item_count());
    136   // index and id are not changed after updating a launcher item.
    137   EXPECT_EQ(index, model_->ItemIndexByID(id));
    138   EXPECT_EQ(id, model_->items()[index].id);
    139 }
    140 
    141 TEST_F(ShelfWindowWatcherTest, MaximizeAndRestoreWindow) {
    142   // ShelfModel only has an APP_LIST item.
    143   EXPECT_EQ(1, model_->item_count());
    144 
    145   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
    146   wm::WindowState* window_state = wm::GetWindowState(window.get());
    147 
    148   // Create a ShelfItem for |window|.
    149   ShelfID id = CreateShelfItem(window.get());
    150   EXPECT_EQ(2, model_->item_count());
    151 
    152   int index = model_->ItemIndexByID(id);
    153   EXPECT_EQ(STATUS_RUNNING, model_->items()[index].status);
    154 
    155   // Maximize window |window|.
    156   EXPECT_FALSE(window_state->IsMaximized());
    157   window_state->Maximize();
    158   EXPECT_TRUE(window_state->IsMaximized());
    159   // No new item is created after maximizing a window |window|.
    160   EXPECT_EQ(2, model_->item_count());
    161   // index and id are not changed after maximizing a window |window|.
    162   EXPECT_EQ(index, model_->ItemIndexByID(id));
    163   EXPECT_EQ(id, model_->items()[index].id);
    164 
    165   // Restore window |window|.
    166   window_state->Restore();
    167   EXPECT_FALSE(window_state->IsMaximized());
    168   // No new item is created after restoring a window |window|.
    169   EXPECT_EQ(2, model_->item_count());
    170   // Index and id are not changed after maximizing a window |window|.
    171   EXPECT_EQ(index, model_->ItemIndexByID(id));
    172   EXPECT_EQ(id, model_->items()[index].id);
    173 }
    174 
    175 // Check that an item is removed when its associated Window is re-parented.
    176 TEST_F(ShelfWindowWatcherTest, ReparentWindow) {
    177   // ShelfModel only has an APP_LIST item.
    178   EXPECT_EQ(1, model_->item_count());
    179 
    180   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
    181   window->set_owned_by_parent(false);
    182 
    183   // Create a ShelfItem for |window|.
    184   ShelfID id = CreateShelfItem(window.get());
    185   EXPECT_EQ(2, model_->item_count());
    186 
    187   int index = model_->ItemIndexByID(id);
    188   EXPECT_EQ(STATUS_RUNNING, model_->items()[index].status);
    189 
    190   aura::Window* root_window = window->GetRootWindow();
    191   aura::Window* default_container = Shell::GetContainer(
    192       root_window,
    193       kShellWindowId_DefaultContainer);
    194   EXPECT_EQ(default_container, window->parent());
    195 
    196   aura::Window* new_parent = Shell::GetContainer(
    197       root_window,
    198       kShellWindowId_PanelContainer);
    199 
    200   // Check |window|'s item is removed when it is re-parented to |new_parent|
    201   // which is not default container.
    202   new_parent->AddChild(window.get());
    203   EXPECT_EQ(1, model_->item_count());
    204 
    205   // Check |window|'s item is added when it is re-parented to
    206   // |default_container|.
    207   default_container->AddChild(window.get());
    208   EXPECT_EQ(2, model_->item_count());
    209 }
    210 
    211 // Check |window|'s item is not changed during the dragging.
    212 // TODO(simonhong): Add a test for removing a Window during the dragging.
    213 TEST_F(ShelfWindowWatcherTest, DragWindow) {
    214   // ShelfModel only has an APP_LIST item.
    215   EXPECT_EQ(1, model_->item_count());
    216 
    217   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
    218 
    219   // Create a ShelfItem for |window|.
    220   ShelfID id = CreateShelfItem(window.get());
    221   EXPECT_EQ(2, model_->item_count());
    222 
    223   int index = model_->ItemIndexByID(id);
    224   EXPECT_EQ(STATUS_RUNNING, model_->items()[index].status);
    225 
    226   // Simulate dragging of |window| and check its item is not changed.
    227   scoped_ptr<WindowResizer> resizer(
    228       CreateWindowResizer(window.get(),
    229                           gfx::Point(),
    230                           HTCAPTION,
    231                           aura::client::WINDOW_MOVE_SOURCE_MOUSE));
    232   ASSERT_TRUE(resizer.get());
    233   resizer->Drag(gfx::Point(50, 50), 0);
    234   resizer->CompleteDrag();
    235 
    236   //Index and id are not changed after dragging a |window|.
    237   EXPECT_EQ(index, model_->ItemIndexByID(id));
    238   EXPECT_EQ(id, model_->items()[index].id);
    239 }
    240 
    241 // Check |window|'s item is removed when it is re-parented not to default
    242 // container during the dragging.
    243 TEST_F(ShelfWindowWatcherTest, ReparentWindowDuringTheDragging) {
    244   // ShelfModel only has an APP_LIST item.
    245   EXPECT_EQ(1, model_->item_count());
    246 
    247   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
    248   window->set_owned_by_parent(false);
    249 
    250   // Create a ShelfItem for |window|.
    251   ShelfID id = CreateShelfItem(window.get());
    252   EXPECT_EQ(2, model_->item_count());
    253   int index = model_->ItemIndexByID(id);
    254   EXPECT_EQ(STATUS_RUNNING, model_->items()[index].status);
    255 
    256   aura::Window* root_window = window->GetRootWindow();
    257   aura::Window* default_container = Shell::GetContainer(
    258       root_window,
    259       kShellWindowId_DefaultContainer);
    260   EXPECT_EQ(default_container, window->parent());
    261 
    262   aura::Window* new_parent = Shell::GetContainer(
    263       root_window,
    264       kShellWindowId_PanelContainer);
    265 
    266   // Simulate re-parenting to |new_parent| during the dragging.
    267   {
    268     scoped_ptr<WindowResizer> resizer(
    269         CreateWindowResizer(window.get(),
    270                             gfx::Point(),
    271                             HTCAPTION,
    272                             aura::client::WINDOW_MOVE_SOURCE_MOUSE));
    273     ASSERT_TRUE(resizer.get());
    274     resizer->Drag(gfx::Point(50, 50), 0);
    275     resizer->CompleteDrag();
    276     EXPECT_EQ(2, model_->item_count());
    277 
    278     // Item should be removed when |window| is re-parented not to default
    279     // container before fininshing the dragging.
    280     EXPECT_TRUE(wm::GetWindowState(window.get())->is_dragged());
    281     new_parent->AddChild(window.get());
    282     EXPECT_EQ(1, model_->item_count());
    283   }
    284   EXPECT_FALSE(wm::GetWindowState(window.get())->is_dragged());
    285   EXPECT_EQ(1, model_->item_count());
    286 }
    287 
    288 }  // namespace ash
    289