blob: 09c15f0ac7c82606cacfe47aec3cede0924eccd6 [file] [log] [blame]
James Cookb0bf8e82017-04-09 17:01:441// 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
skye5fd1222017-04-12 18:43:237#include "ash/public/cpp/config.h"
James Cookb0bf8e82017-04-09 17:01:448#include "ash/public/cpp/shelf_item.h"
msw109806d2017-06-02 20:11:579#include "ash/public/cpp/shelf_model.h"
James Cookb0bf8e82017-04-09 17:01:4410#include "ash/public/cpp/shell_window_ids.h"
11#include "ash/public/cpp/window_properties.h"
12#include "ash/root_window_controller.h"
13#include "ash/session/session_controller.h"
James Cookb0bf8e82017-04-09 17:01:4414#include "ash/shell.h"
15#include "ash/test/ash_test_base.h"
16#include "ash/wm/window_resizer.h"
17#include "ash/wm/window_state.h"
msw19b30c2c2017-06-01 03:21:4018#include "third_party/skia/include/core/SkBitmap.h"
19#include "ui/aura/client/aura_constants.h"
James Cookb0bf8e82017-04-09 17:01:4420#include "ui/aura/window.h"
21#include "ui/base/hit_test.h"
msw19b30c2c2017-06-01 03:21:4022#include "ui/base/resource/resource_bundle.h"
23#include "ui/gfx/image/image_skia.h"
24#include "ui/resources/grit/ui_resources.h"
James Cookb0bf8e82017-04-09 17:01:4425#include "ui/views/widget/widget.h"
msw70ac45f2017-06-05 02:02:4526#include "ui/wm/core/transient_window_controller.h"
James Cookb0bf8e82017-04-09 17:01:4427
28namespace ash {
msw19b30c2c2017-06-01 03:21:4029namespace {
30
31// Create a test 1x1 icon image with a given |color|.
32gfx::ImageSkia CreateImageSkiaIcon(SkColor color) {
33 SkBitmap bitmap;
34 bitmap.allocN32Pixels(1, 1);
35 bitmap.eraseColor(color);
36 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
37}
James Cookb0bf8e82017-04-09 17:01:4438
Alexei Filippove5a9e8c92017-07-18 00:23:0439class ShelfWindowWatcherTest : public test::AshTestBase {
James Cookb0bf8e82017-04-09 17:01:4440 public:
41 ShelfWindowWatcherTest() : model_(nullptr) {}
42 ~ShelfWindowWatcherTest() override {}
43
44 void SetUp() override {
Alexei Filippove5a9e8c92017-07-18 00:23:0445 test::AshTestBase::SetUp();
James Cookb0bf8e82017-04-09 17:01:4446 model_ = Shell::Get()->shelf_model();
47 }
48
49 void TearDown() override {
50 model_ = nullptr;
Alexei Filippove5a9e8c92017-07-18 00:23:0451 test::AshTestBase::TearDown();
James Cookb0bf8e82017-04-09 17:01:4452 }
53
msw6958e7f2017-05-15 22:55:0654 static ShelfID CreateShelfItem(aura::Window* window) {
msw84b8a5f2017-05-05 00:13:3655 static int id = 0;
msw70ac45f2017-06-05 02:02:4556 ShelfID shelf_id(std::to_string(id++));
msw6958e7f2017-05-15 22:55:0657 window->SetProperty(kShelfIDKey, new std::string(shelf_id.Serialize()));
58 window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
msw84b8a5f2017-05-05 00:13:3659 return shelf_id;
James Cookb0bf8e82017-04-09 17:01:4460 }
61
62 protected:
63 ShelfModel* model_;
64
65 private:
66 DISALLOW_COPY_AND_ASSIGN(ShelfWindowWatcherTest);
67};
68
69// Ensure shelf items are added and removed as windows are opened and closed.
70TEST_F(ShelfWindowWatcherTest, OpenAndClose) {
71 // ShelfModel only has an APP_LIST item.
72 EXPECT_EQ(1, model_->item_count());
73
msw70ac45f2017-06-05 02:02:4574 // Windows with valid ShelfItemType and ShelfID properties get shelf items.
James Cookb0bf8e82017-04-09 17:01:4475 std::unique_ptr<views::Widget> widget1 =
76 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
msw6958e7f2017-05-15 22:55:0677 CreateShelfItem(widget1->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:4478 EXPECT_EQ(2, model_->item_count());
79 std::unique_ptr<views::Widget> widget2 =
80 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
msw6958e7f2017-05-15 22:55:0681 CreateShelfItem(widget2->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:4482 EXPECT_EQ(3, model_->item_count());
83
84 // Each ShelfItem is removed when the associated window is destroyed.
85 widget1.reset();
86 EXPECT_EQ(2, model_->item_count());
87 widget2.reset();
88 EXPECT_EQ(1, model_->item_count());
89}
90
mswfeae4322017-06-08 04:24:2291// Ensure shelf items are added and removed for some unknown windows in mash.
msw70ac45f2017-06-05 02:02:4592TEST_F(ShelfWindowWatcherTest, OpenAndCloseMash) {
93 if (Shell::GetAshConfig() != Config::MASH)
94 return;
95
96 // ShelfModel only has an APP_LIST item.
97 EXPECT_EQ(1, model_->item_count());
98
99 // Windows with no valid ShelfItemType and ShelfID properties get shelf items.
100 std::unique_ptr<views::Widget> widget1 =
101 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
102 EXPECT_EQ(2, model_->item_count());
103 std::unique_ptr<views::Widget> widget2 =
104 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
105 EXPECT_EQ(3, model_->item_count());
106
107 // Each ShelfItem is removed when the associated window is destroyed.
108 widget1.reset();
109 EXPECT_EQ(2, model_->item_count());
110 widget2.reset();
111 EXPECT_EQ(1, model_->item_count());
112
mswfeae4322017-06-08 04:24:22113 // Windows with type WINDOW_TYPE_NORMAL get shelf items, others do not.
114 aura::client::WindowType no_item_types[] = {
115 aura::client::WINDOW_TYPE_UNKNOWN, aura::client::WINDOW_TYPE_NORMAL,
116 aura::client::WINDOW_TYPE_POPUP, aura::client::WINDOW_TYPE_CONTROL,
117 aura::client::WINDOW_TYPE_PANEL, aura::client::WINDOW_TYPE_MENU,
118 aura::client::WINDOW_TYPE_TOOLTIP};
119 for (aura::client::WindowType type : no_item_types) {
120 std::unique_ptr<aura::Window> window =
121 base::MakeUnique<aura::Window>(nullptr, type);
122 window->Init(ui::LAYER_NOT_DRAWN);
123 Shell::GetPrimaryRootWindow()
124 ->GetChildById(kShellWindowId_DefaultContainer)
125 ->AddChild(window.get());
126 window->Show();
127 EXPECT_EQ(type == aura::client::WINDOW_TYPE_NORMAL ? 2 : 1,
128 model_->item_count());
129 }
130
msw70ac45f2017-06-05 02:02:45131 // Windows with WindowState::ignored_by_shelf set do not get shelf items.
132 widget1 =
133 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
134 wm::GetWindowState(widget1->GetNativeWindow())->set_ignored_by_shelf(true);
135 // TODO(msw): Make the flag a window property and remove this workaround.
136 widget1->GetNativeWindow()->SetProperty(aura::client::kDrawAttentionKey,
137 true);
138 EXPECT_EQ(1, model_->item_count());
139}
140
James Cookb0bf8e82017-04-09 17:01:44141TEST_F(ShelfWindowWatcherTest, CreateAndRemoveShelfItemProperties) {
142 // TODO: investigate failure in mash. http://crbug.com/695562.
skye5fd1222017-04-12 18:43:23143 if (Shell::GetAshConfig() == Config::MASH)
James Cookb0bf8e82017-04-09 17:01:44144 return;
145
146 // ShelfModel only has an APP_LIST item.
147 EXPECT_EQ(1, model_->item_count());
148
149 // Creating windows without a valid ShelfItemType does not add items.
150 std::unique_ptr<views::Widget> widget1 =
151 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44152 std::unique_ptr<views::Widget> widget2 =
153 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44154 EXPECT_EQ(1, model_->item_count());
155
156 // Create a ShelfItem for the first window.
msw6958e7f2017-05-15 22:55:06157 ShelfID id_w1 = CreateShelfItem(widget1->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44158 EXPECT_EQ(2, model_->item_count());
159
160 int index_w1 = model_->ItemIndexByID(id_w1);
161 EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
162
163 // Create a ShelfItem for the second window.
msw6958e7f2017-05-15 22:55:06164 ShelfID id_w2 = CreateShelfItem(widget2->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44165 EXPECT_EQ(3, model_->item_count());
166
167 int index_w2 = model_->ItemIndexByID(id_w2);
168 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w2].status);
169
170 // ShelfItem is removed when the item type window property is cleared.
msw6958e7f2017-05-15 22:55:06171 widget1->GetNativeWindow()->SetProperty(kShelfItemTypeKey,
172 static_cast<int32_t>(TYPE_UNDEFINED));
James Cookb0bf8e82017-04-09 17:01:44173 EXPECT_EQ(2, model_->item_count());
msw6958e7f2017-05-15 22:55:06174 widget2->GetNativeWindow()->SetProperty(kShelfItemTypeKey,
175 static_cast<int32_t>(TYPE_UNDEFINED));
James Cookb0bf8e82017-04-09 17:01:44176 EXPECT_EQ(1, model_->item_count());
177 // Clearing twice doesn't do anything.
msw6958e7f2017-05-15 22:55:06178 widget2->GetNativeWindow()->SetProperty(kShelfItemTypeKey,
179 static_cast<int32_t>(TYPE_UNDEFINED));
James Cookb0bf8e82017-04-09 17:01:44180 EXPECT_EQ(1, model_->item_count());
181}
182
183TEST_F(ShelfWindowWatcherTest, ActivateWindow) {
184 // TODO: investigate failure in mash. http://crbug.com/695562.
skye5fd1222017-04-12 18:43:23185 if (Shell::GetAshConfig() == Config::MASH)
James Cookb0bf8e82017-04-09 17:01:44186 return;
187
msw6958e7f2017-05-15 22:55:06188 // ShelfModel only has an APP_LIST item.
James Cookb0bf8e82017-04-09 17:01:44189 EXPECT_EQ(1, model_->item_count());
190 std::unique_ptr<views::Widget> widget1 =
191 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44192 std::unique_ptr<views::Widget> widget2 =
193 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44194
195 // Create a ShelfItem for the first window.
msw6958e7f2017-05-15 22:55:06196 ShelfID id_w1 = CreateShelfItem(widget1->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44197 EXPECT_EQ(2, model_->item_count());
198 int index_w1 = model_->ItemIndexByID(id_w1);
199 EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
200
201 // Create a ShelfItem for the second window.
msw6958e7f2017-05-15 22:55:06202 ShelfID id_w2 = CreateShelfItem(widget2->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44203 EXPECT_EQ(3, model_->item_count());
204 int index_w2 = model_->ItemIndexByID(id_w2);
205 EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
206 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w2].status);
207
208 // The ShelfItem for the first window is active when the window is activated.
209 widget1->Activate();
210 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w1].status);
211 EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w2].status);
212
213 // The ShelfItem for the second window is active when the window is activated.
214 widget2->Activate();
215 EXPECT_EQ(STATUS_RUNNING, model_->items()[index_w1].status);
216 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index_w2].status);
217}
218
219TEST_F(ShelfWindowWatcherTest, UpdateWindowProperty) {
James Cookb0bf8e82017-04-09 17:01:44220 // ShelfModel only has an APP_LIST item.
221 EXPECT_EQ(1, model_->item_count());
222
223 std::unique_ptr<views::Widget> widget =
224 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44225
226 // Create a ShelfItem for |window|.
msw6958e7f2017-05-15 22:55:06227 ShelfID id = CreateShelfItem(widget->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44228 EXPECT_EQ(2, model_->item_count());
229
230 int index = model_->ItemIndexByID(id);
231 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index].status);
232
msw6958e7f2017-05-15 22:55:06233 // Update the window's ShelfItemType.
234 widget->GetNativeWindow()->SetProperty(kShelfItemTypeKey,
mswfeae4322017-06-08 04:24:22235 static_cast<int32_t>(TYPE_APP_PANEL));
James Cookb0bf8e82017-04-09 17:01:44236 // No new item is created after updating a launcher item.
237 EXPECT_EQ(2, model_->item_count());
238 // index and id are not changed after updating a launcher item.
239 EXPECT_EQ(index, model_->ItemIndexByID(id));
240 EXPECT_EQ(id, model_->items()[index].id);
241}
242
243TEST_F(ShelfWindowWatcherTest, MaximizeAndRestoreWindow) {
James Cookb0bf8e82017-04-09 17:01:44244 // ShelfModel only has an APP_LIST item.
245 EXPECT_EQ(1, model_->item_count());
246
247 std::unique_ptr<views::Widget> widget =
248 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
msw6958e7f2017-05-15 22:55:06249 wm::WindowState* window_state = wm::GetWindowState(widget->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44250
msw6958e7f2017-05-15 22:55:06251 // Create a ShelfItem for the window.
252 ShelfID id = CreateShelfItem(widget->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44253 EXPECT_EQ(2, model_->item_count());
254
255 int index = model_->ItemIndexByID(id);
256 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index].status);
257
msw6958e7f2017-05-15 22:55:06258 // Maximize the window.
James Cookb0bf8e82017-04-09 17:01:44259 EXPECT_FALSE(window_state->IsMaximized());
260 window_state->Maximize();
261 EXPECT_TRUE(window_state->IsMaximized());
msw6958e7f2017-05-15 22:55:06262 // No new item is created after maximizing the window.
James Cookb0bf8e82017-04-09 17:01:44263 EXPECT_EQ(2, model_->item_count());
msw6958e7f2017-05-15 22:55:06264 // index and id are not changed after maximizing the window.
James Cookb0bf8e82017-04-09 17:01:44265 EXPECT_EQ(index, model_->ItemIndexByID(id));
266 EXPECT_EQ(id, model_->items()[index].id);
267
msw6958e7f2017-05-15 22:55:06268 // Restore the window.
James Cookb0bf8e82017-04-09 17:01:44269 window_state->Restore();
270 EXPECT_FALSE(window_state->IsMaximized());
msw6958e7f2017-05-15 22:55:06271 // No new item is created after restoring the window.
James Cookb0bf8e82017-04-09 17:01:44272 EXPECT_EQ(2, model_->item_count());
msw6958e7f2017-05-15 22:55:06273 // Index and id are not changed after maximizing the window.
James Cookb0bf8e82017-04-09 17:01:44274 EXPECT_EQ(index, model_->ItemIndexByID(id));
275 EXPECT_EQ(id, model_->items()[index].id);
276}
277
278// Check |window|'s item is not changed during the dragging.
279// TODO(simonhong): Add a test for removing a Window during the dragging.
280TEST_F(ShelfWindowWatcherTest, DragWindow) {
James Cookb0bf8e82017-04-09 17:01:44281 // ShelfModel only has an APP_LIST item.
282 EXPECT_EQ(1, model_->item_count());
283
284 std::unique_ptr<views::Widget> widget =
285 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
James Cookb0bf8e82017-04-09 17:01:44286
msw6958e7f2017-05-15 22:55:06287 // Create a ShelfItem for the window.
288 ShelfID id = CreateShelfItem(widget->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44289 EXPECT_EQ(2, model_->item_count());
290
291 int index = model_->ItemIndexByID(id);
292 EXPECT_EQ(STATUS_ACTIVE, model_->items()[index].status);
293
msw6958e7f2017-05-15 22:55:06294 // Simulate dragging of the window and check its item is not changed.
skya5e9a122017-05-22 20:45:35295 std::unique_ptr<WindowResizer> resizer(
296 CreateWindowResizer(widget->GetNativeWindow(), gfx::Point(), HTCAPTION,
Thiago Farina3b086a02017-05-30 22:32:50297 ::wm::WINDOW_MOVE_SOURCE_MOUSE));
James Cookb0bf8e82017-04-09 17:01:44298 ASSERT_TRUE(resizer.get());
299 resizer->Drag(gfx::Point(50, 50), 0);
300 resizer->CompleteDrag();
301
msw6958e7f2017-05-15 22:55:06302 // Index and id are not changed after dragging the window.
James Cookb0bf8e82017-04-09 17:01:44303 EXPECT_EQ(index, model_->ItemIndexByID(id));
304 EXPECT_EQ(id, model_->items()[index].id);
305}
306
mswfeae4322017-06-08 04:24:22307// Ensure panels and dialogs get shelf items.
308TEST_F(ShelfWindowWatcherTest, PanelAndDialogWindows) {
James Cookb0bf8e82017-04-09 17:01:44309 // ShelfModel only has an APP_LIST item.
310 EXPECT_EQ(1, model_->item_count());
311
mswfeae4322017-06-08 04:24:22312 // An item is created for a dialog window.
313 std::unique_ptr<views::Widget> dialog_widget =
msw6958e7f2017-05-15 22:55:06314 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
mswfeae4322017-06-08 04:24:22315 aura::Window* dialog = dialog_widget->GetNativeWindow();
316 dialog->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize()));
317 dialog->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
James Cookb0bf8e82017-04-09 17:01:44318 EXPECT_EQ(2, model_->item_count());
James Cookb0bf8e82017-04-09 17:01:44319
mswfeae4322017-06-08 04:24:22320 // An item is created for a panel window.
James Cookb0bf8e82017-04-09 17:01:44321 views::Widget panel_widget;
322 views::Widget::InitParams panel_params(views::Widget::InitParams::TYPE_PANEL);
323 panel_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
Scott Violet66193f72017-06-26 22:24:18324 panel_params.parent = Shell::GetPrimaryRootWindow()->GetChildById(
325 kShellWindowId_PanelContainer);
James Cookb0bf8e82017-04-09 17:01:44326 panel_widget.Init(panel_params);
327 panel_widget.Show();
mswfeae4322017-06-08 04:24:22328 aura::Window* panel = panel_widget.GetNativeWindow();
329 panel->SetProperty(kShelfIDKey, new std::string(ShelfID("b").Serialize()));
330 panel->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_APP_PANEL));
331 EXPECT_EQ(3, model_->item_count());
332
333 // An item is not created for an app window.
334 std::unique_ptr<views::Widget> app_widget =
335 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
336 aura::Window* app = app_widget->GetNativeWindow();
337 app->SetProperty(kShelfIDKey, new std::string(ShelfID("c").Serialize()));
338 app->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_APP));
339 EXPECT_EQ(3, model_->item_count());
340 app_widget.reset();
James Cookb0bf8e82017-04-09 17:01:44341
342 // Each ShelfItem is removed when the associated window is destroyed.
343 panel_widget.CloseNow();
James Cookb0bf8e82017-04-09 17:01:44344 EXPECT_EQ(2, model_->item_count());
mswfeae4322017-06-08 04:24:22345 dialog_widget.reset();
James Cookb0bf8e82017-04-09 17:01:44346 EXPECT_EQ(1, model_->item_count());
347}
348
msw19b30c2c2017-06-01 03:21:40349// Ensure items use the app icon and window icon aura::Window properties.
350TEST_F(ShelfWindowWatcherTest, ItemIcon) {
351 // ShelfModel only has an APP_LIST item.
352 EXPECT_EQ(1, model_->item_count());
353
354 // Create a ShelfItem for a window; it should have a default icon.
355 std::unique_ptr<views::Widget> widget =
356 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
357 aura::Window* window = widget->GetNativeWindow();
358 ShelfID id = CreateShelfItem(window);
359 EXPECT_EQ(2, model_->item_count());
360 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
361 gfx::Image default_image = rb.GetImageNamed(IDR_DEFAULT_FAVICON_32);
362 EXPECT_TRUE(model_->items()[1].image.BackedBySameObjectAs(
363 default_image.AsImageSkia()));
364
365 // Setting a window icon should update the item icon.
366 const gfx::ImageSkia red = CreateImageSkiaIcon(SK_ColorRED);
367 window->SetProperty(aura::client::kWindowIconKey, new gfx::ImageSkia(red));
368 EXPECT_EQ(SK_ColorRED, model_->items()[1].image.bitmap()->getColor(0, 0));
369
370 // Setting an app icon should override the window icon.
371 const gfx::ImageSkia blue = CreateImageSkiaIcon(SK_ColorBLUE);
372 window->SetProperty(aura::client::kAppIconKey, new gfx::ImageSkia(blue));
373 EXPECT_EQ(SK_ColorBLUE, model_->items()[1].image.bitmap()->getColor(0, 0));
374
375 // Clearing the app icon should restore the window icon to the shelf item.
376 window->ClearProperty(aura::client::kAppIconKey);
377 EXPECT_EQ(SK_ColorRED, model_->items()[1].image.bitmap()->getColor(0, 0));
378}
379
James Cookb0bf8e82017-04-09 17:01:44380TEST_F(ShelfWindowWatcherTest, DontCreateShelfEntriesForChildWindows) {
mswfeae4322017-06-08 04:24:22381 EXPECT_EQ(1, model_->item_count());
382 std::unique_ptr<aura::Window> window =
383 base::MakeUnique<aura::Window>(nullptr, aura::client::WINDOW_TYPE_NORMAL);
James Cookb0bf8e82017-04-09 17:01:44384 window->Init(ui::LAYER_NOT_DRAWN);
mswfeae4322017-06-08 04:24:22385 window->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize()));
386 window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
James Cookb0bf8e82017-04-09 17:01:44387 Shell::GetPrimaryRootWindow()
388 ->GetChildById(kShellWindowId_DefaultContainer)
389 ->AddChild(window.get());
390 window->Show();
mswfeae4322017-06-08 04:24:22391 EXPECT_EQ(2, model_->item_count());
James Cookb0bf8e82017-04-09 17:01:44392
mswfeae4322017-06-08 04:24:22393 std::unique_ptr<aura::Window> child =
394 base::MakeUnique<aura::Window>(nullptr, aura::client::WINDOW_TYPE_NORMAL);
395 child->Init(ui::LAYER_NOT_DRAWN);
396 child->SetProperty(kShelfIDKey, new std::string(ShelfID("b").Serialize()));
397 child->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
398 window->AddChild(child.get());
399 child->Show();
400 // There should not be a new shelf item for |child|.
401 EXPECT_EQ(2, model_->item_count());
James Cookb0bf8e82017-04-09 17:01:44402
mswfeae4322017-06-08 04:24:22403 child.reset();
404 EXPECT_EQ(2, model_->item_count());
James Cookb0bf8e82017-04-09 17:01:44405 window.reset();
mswfeae4322017-06-08 04:24:22406 EXPECT_EQ(1, model_->item_count());
James Cookb0bf8e82017-04-09 17:01:44407}
408
mswfeae4322017-06-08 04:24:22409TEST_F(ShelfWindowWatcherTest, CreateShelfEntriesForTransientWindows) {
410 EXPECT_EQ(1, model_->item_count());
411 std::unique_ptr<aura::Window> window =
412 base::MakeUnique<aura::Window>(nullptr, aura::client::WINDOW_TYPE_NORMAL);
msw70ac45f2017-06-05 02:02:45413 window->Init(ui::LAYER_NOT_DRAWN);
mswfeae4322017-06-08 04:24:22414 window->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize()));
415 window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
msw70ac45f2017-06-05 02:02:45416 Shell::GetPrimaryRootWindow()
417 ->GetChildById(kShellWindowId_DefaultContainer)
418 ->AddChild(window.get());
419 window->Show();
mswfeae4322017-06-08 04:24:22420 EXPECT_EQ(2, model_->item_count());
msw70ac45f2017-06-05 02:02:45421
mswfeae4322017-06-08 04:24:22422 std::unique_ptr<aura::Window> transient =
423 base::MakeUnique<aura::Window>(nullptr, aura::client::WINDOW_TYPE_NORMAL);
424 transient->Init(ui::LAYER_NOT_DRAWN);
425 transient->SetProperty(kShelfIDKey,
426 new std::string(ShelfID("b").Serialize()));
427 transient->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG));
428 Shell::GetPrimaryRootWindow()
429 ->GetChildById(kShellWindowId_DefaultContainer)
430 ->AddChild(transient.get());
431 ::wm::TransientWindowController::Get()->AddTransientChild(window.get(),
432 transient.get());
433 transient->Show();
434 // There should be a new shelf item for |transient|.
435 EXPECT_EQ(3, model_->item_count());
msw70ac45f2017-06-05 02:02:45436
mswfeae4322017-06-08 04:24:22437 transient.reset();
438 EXPECT_EQ(2, model_->item_count());
msw70ac45f2017-06-05 02:02:45439 window.reset();
mswfeae4322017-06-08 04:24:22440 EXPECT_EQ(1, model_->item_count());
msw70ac45f2017-06-05 02:02:45441}
442
James Cookb0bf8e82017-04-09 17:01:44443// Ensures ShelfWindowWatcher supports windows opened prior to session start.
Alexei Filippove5a9e8c92017-07-18 00:23:04444using ShelfWindowWatcherSessionStartTest = test::NoSessionAshTestBase;
James Cookb0bf8e82017-04-09 17:01:44445TEST_F(ShelfWindowWatcherSessionStartTest, PreExistingWindow) {
446 ShelfModel* model = Shell::Get()->shelf_model();
447 ASSERT_FALSE(
448 Shell::Get()->session_controller()->IsActiveUserSessionStarted());
449
450 // ShelfModel only has an APP_LIST item.
451 EXPECT_EQ(1, model->item_count());
452
453 // Construct a window that should get a shelf item once the session starts.
454 std::unique_ptr<views::Widget> widget =
455 CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect());
msw6958e7f2017-05-15 22:55:06456 ShelfWindowWatcherTest::CreateShelfItem(widget->GetNativeWindow());
James Cookb0bf8e82017-04-09 17:01:44457 EXPECT_EQ(1, model->item_count());
458
459 // Start the test user session; ShelfWindowWatcher will find the open window.
460 SetSessionStarted(true);
461 EXPECT_EQ(2, model->item_count());
462}
463
msw19b30c2c2017-06-01 03:21:40464} // namespace
James Cookb0bf8e82017-04-09 17:01:44465} // namespace ash