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 23namespace ash { 24 25class 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 55TEST_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 87TEST_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 116TEST_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 141TEST_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. 176TEST_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. 213TEST_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. 243TEST_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