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.
5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
7 #include "ash/ash_switches.h"
8 #include "ash/display/display_controller.h"
9 #include "ash/shelf/shelf.h"
10 #include "ash/shelf/shelf_button.h"
11 #include "ash/shelf/shelf_constants.h"
12 #include "ash/shelf/shelf_model.h"
13 #include "ash/shelf/shelf_util.h"
14 #include "ash/shelf/shelf_view.h"
15 #include "ash/shell.h"
16 #include "ash/test/app_list_controller_test_api.h"
17 #include "ash/test/shelf_test_api.h"
18 #include "ash/test/shelf_view_test_api.h"
19 #include "ash/test/shell_test_api.h"
20 #include "ash/wm/window_state.h"
21 #include "ash/wm/window_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "chrome/browser/apps/app_browsertest_util.h"
25 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/extensions/extension_apitest.h"
27 #include "chrome/browser/extensions/extension_browsertest.h"
28 #include "chrome/browser/extensions/extension_function_test_utils.h"
29 #include "chrome/browser/extensions/extension_service.h"
30 #include "chrome/browser/extensions/launch_util.h"
31 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/ui/app_list/app_list_service.h"
33 #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
34 #include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h"
35 #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h"
36 #include "chrome/browser/ui/browser.h"
37 #include "chrome/browser/ui/browser_commands.h"
38 #include "chrome/browser/ui/browser_finder.h"
39 #include "chrome/browser/ui/browser_list.h"
40 #include "chrome/browser/ui/browser_window.h"
41 #include "chrome/browser/ui/chrome_pages.h"
42 #include "chrome/browser/ui/extensions/app_launch_params.h"
43 #include "chrome/browser/ui/extensions/application_launch.h"
44 #include "chrome/browser/ui/host_desktop.h"
45 #include "chrome/browser/ui/settings_window_manager.h"
46 #include "chrome/browser/ui/tabs/tab_strip_model.h"
47 #include "chrome/common/chrome_switches.h"
48 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
49 #include "chrome/test/base/ui_test_utils.h"
50 #include "content/public/browser/notification_service.h"
51 #include "content/public/browser/notification_source.h"
52 #include "content/public/browser/web_contents.h"
53 #include "content/public/test/browser_test_utils.h"
54 #include "extensions/browser/app_window/app_window.h"
55 #include "extensions/browser/app_window/app_window_registry.h"
56 #include "extensions/browser/app_window/native_app_window.h"
57 #include "extensions/browser/extension_system.h"
58 #include "extensions/common/constants.h"
59 #include "extensions/common/switches.h"
60 #include "extensions/test/extension_test_message_listener.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "ui/app_list/app_list_switches.h"
63 #include "ui/app_list/views/app_list_item_view.h"
64 #include "ui/app_list/views/apps_grid_view.h"
65 #include "ui/app_list/views/start_page_view.h"
66 #include "ui/app_list/views/tile_item_view.h"
67 #include "ui/aura/client/aura_constants.h"
68 #include "ui/aura/window.h"
69 #include "ui/base/window_open_disposition.h"
70 #include "ui/events/event.h"
71 #include "ui/events/test/event_generator.h"
73 using extensions::AppWindow
;
74 using extensions::Extension
;
75 using content::WebContents
;
79 class TestEvent
: public ui::Event
{
81 explicit TestEvent(ui::EventType type
)
82 : ui::Event(type
, base::TimeDelta(), 0) {
84 ~TestEvent() override
{}
87 DISALLOW_COPY_AND_ASSIGN(TestEvent
);
90 class TestAppWindowRegistryObserver
91 : public extensions::AppWindowRegistry::Observer
{
93 explicit TestAppWindowRegistryObserver(Profile
* profile
)
94 : profile_(profile
), icon_updates_(0) {
95 extensions::AppWindowRegistry::Get(profile_
)->AddObserver(this);
98 ~TestAppWindowRegistryObserver() override
{
99 extensions::AppWindowRegistry::Get(profile_
)->RemoveObserver(this);
102 // Overridden from AppWindowRegistry::Observer:
103 void OnAppWindowIconChanged(AppWindow
* app_window
) override
{
107 int icon_updates() { return icon_updates_
; }
113 DISALLOW_COPY_AND_ASSIGN(TestAppWindowRegistryObserver
);
116 // Click the "All Apps" button from the app launcher start page. Assumes that
117 // the app launcher is open to the start page. On the non-experimental launcher,
119 // |display_origin| is the top-left corner of the active display, in screen
121 void ClickAllAppsButtonFromStartPage(ui::test::EventGenerator
* generator
,
122 const gfx::Point
& display_origin
) {
123 if (!app_list::switches::IsExperimentalAppListEnabled())
126 ash::test::AppListControllerTestApi
controller_test(
127 ash::Shell::GetInstance());
129 app_list::StartPageView
* start_page_view
= controller_test
.GetStartPageView();
130 DCHECK(start_page_view
);
132 app_list::TileItemView
* all_apps_button
= start_page_view
->all_apps_button();
133 gfx::Rect all_apps_rect
= all_apps_button
->GetBoundsInScreen();
134 all_apps_rect
.Offset(-display_origin
.x(), -display_origin
.y());
135 generator
->MoveMouseTo(all_apps_rect
.CenterPoint().x(),
136 all_apps_rect
.CenterPoint().y());
137 generator
->ClickLeftButton();
138 base::MessageLoop::current()->RunUntilIdle();
139 // Run Layout() to effectively complete the animation to the apps page.
140 controller_test
.LayoutContentsView();
145 class LauncherPlatformAppBrowserTest
146 : public extensions::PlatformAppBrowserTest
{
148 LauncherPlatformAppBrowserTest() : shelf_(NULL
), controller_(NULL
) {
151 ~LauncherPlatformAppBrowserTest() override
{}
153 void RunTestOnMainThreadLoop() override
{
154 shelf_
= ash::Shelf::ForPrimaryDisplay();
155 controller_
= ChromeLauncherController::instance();
156 return extensions::PlatformAppBrowserTest::RunTestOnMainThreadLoop();
159 ash::ShelfModel
* shelf_model() {
160 return ash::test::ShellTestApi(ash::Shell::GetInstance()).shelf_model();
163 ash::ShelfID
CreateAppShortcutLauncherItem(const std::string
& name
) {
164 return controller_
->CreateAppShortcutLauncherItem(
165 name
, controller_
->model()->item_count());
168 const ash::ShelfItem
& GetLastLauncherItem() {
169 // Unless there are any panels, the item at index [count - 1] will be
171 return shelf_model()->items()[shelf_model()->item_count() - 1];
174 const ash::ShelfItem
& GetLastLauncherPanelItem() {
175 // Panels show up on the right side of the shelf, so the desired item
176 // will be the last one.
177 return shelf_model()->items()[shelf_model()->item_count() - 1];
180 LauncherItemController
* GetItemController(ash::ShelfID id
) {
181 return controller_
->id_to_item_controller_map_
[id
];
184 // Returns the number of menu items, ignoring separators.
185 int GetNumApplicationMenuItems(const ash::ShelfItem
& item
) {
186 const int event_flags
= 0;
187 scoped_ptr
<ash::ShelfMenuModel
> menu(new LauncherApplicationMenuItemModel(
188 controller_
->GetApplicationList(item
, event_flags
)));
190 for (int i
= 0; i
< menu
->GetItemCount(); ++i
) {
191 if (menu
->GetTypeAt(i
) != ui::MenuModel::TYPE_SEPARATOR
)
197 // Activate the shelf item with the given |id|.
198 void ActivateShelfItem(int id
) {
199 shelf_
->ActivateShelfItem(id
);
203 ChromeLauncherController
* controller_
;
207 DISALLOW_COPY_AND_ASSIGN(LauncherPlatformAppBrowserTest
);
211 // Drag the item off the shelf and let the mouse go.
213 // Drag the item off the shelf, move the mouse back and then let go.
214 RIP_OFF_ITEM_AND_RETURN
,
215 // Drag the item off the shelf and then issue a cancel command.
216 RIP_OFF_ITEM_AND_CANCEL
,
217 // Drag the item off the shelf and do not release the mouse.
218 RIP_OFF_ITEM_AND_DONT_RELEASE_MOUSE
,
221 class ShelfAppBrowserTest
: public ExtensionBrowserTest
{
223 ShelfAppBrowserTest() : shelf_(NULL
), model_(NULL
), controller_(NULL
) {
226 ~ShelfAppBrowserTest() override
{}
228 void RunTestOnMainThreadLoop() override
{
229 shelf_
= ash::Shelf::ForPrimaryDisplay();
230 model_
= ash::test::ShellTestApi(ash::Shell::GetInstance()).shelf_model();
231 controller_
= ChromeLauncherController::instance();
232 return ExtensionBrowserTest::RunTestOnMainThreadLoop();
235 size_t NumberOfDetectedLauncherBrowsers(bool show_all_tabs
) {
236 LauncherItemController
* item_controller
=
237 controller_
->GetBrowserShortcutLauncherItemController();
238 int items
= item_controller
->GetApplicationList(
239 show_all_tabs
? ui::EF_SHIFT_DOWN
: 0).size();
240 // If we have at least one item, we have also a title which we remove here.
241 return items
? (items
- 1) : 0;
244 const Extension
* LoadAndLaunchExtension(
246 extensions::LaunchContainer container
,
247 WindowOpenDisposition disposition
) {
248 EXPECT_TRUE(LoadExtension(test_data_dir_
.AppendASCII(name
)));
250 ExtensionService
* service
= extensions::ExtensionSystem::Get(
251 profile())->extension_service();
252 const Extension
* extension
=
253 service
->GetExtensionById(last_loaded_extension_id(), false);
254 EXPECT_TRUE(extension
);
256 OpenApplication(AppLaunchParams(profile(), extension
, container
,
257 disposition
, extensions::SOURCE_TEST
));
261 ash::ShelfID
CreateShortcut(const char* name
) {
262 ExtensionService
* service
= extensions::ExtensionSystem::Get(
263 profile())->extension_service();
264 LoadExtension(test_data_dir_
.AppendASCII(name
));
267 const Extension
* extension
=
268 service
->GetExtensionById(last_loaded_extension_id(), false);
269 const std::string app_id
= extension
->id();
271 // Then create a shortcut.
272 int item_count
= model_
->item_count();
273 ash::ShelfID shortcut_id
= controller_
->CreateAppShortcutLauncherItem(
276 controller_
->PersistPinnedState();
277 EXPECT_EQ(++item_count
, model_
->item_count());
278 const ash::ShelfItem
& item
= *model_
->ItemByID(shortcut_id
);
279 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
283 void RemoveShortcut(ash::ShelfID id
) {
284 controller_
->Unpin(id
);
287 // Activate the shelf item with the given |id|.
288 void ActivateShelfItem(int id
) {
289 shelf_
->ActivateShelfItem(id
);
292 ash::ShelfID
PinFakeApp(const std::string
& name
) {
293 return controller_
->CreateAppShortcutLauncherItem(
294 name
, model_
->item_count());
297 // Get the index of an item which has the given type.
298 int GetIndexOfShelfItemType(ash::ShelfItemType type
) {
299 return model_
->GetItemIndexForType(type
);
302 // Try to rip off |item_index|.
303 void RipOffItemIndex(int index
,
304 ui::test::EventGenerator
* generator
,
305 ash::test::ShelfViewTestAPI
* test
,
306 RipOffCommand command
) {
307 ash::ShelfButton
* button
= test
->GetButton(index
);
308 gfx::Point start_point
= button
->GetBoundsInScreen().CenterPoint();
309 gfx::Point
rip_off_point(start_point
.x(), 0);
310 generator
->MoveMouseTo(start_point
.x(), start_point
.y());
311 base::MessageLoop::current()->RunUntilIdle();
312 generator
->PressLeftButton();
313 base::MessageLoop::current()->RunUntilIdle();
314 generator
->MoveMouseTo(rip_off_point
.x(), rip_off_point
.y());
315 base::MessageLoop::current()->RunUntilIdle();
316 test
->RunMessageLoopUntilAnimationsDone();
317 if (command
== RIP_OFF_ITEM_AND_RETURN
) {
318 generator
->MoveMouseTo(start_point
.x(), start_point
.y());
319 base::MessageLoop::current()->RunUntilIdle();
320 test
->RunMessageLoopUntilAnimationsDone();
321 } else if (command
== RIP_OFF_ITEM_AND_CANCEL
) {
322 // This triggers an internal cancel. Using VKEY_ESCAPE was too unreliable.
323 button
->OnMouseCaptureLost();
325 if (command
!= RIP_OFF_ITEM_AND_DONT_RELEASE_MOUSE
) {
326 generator
->ReleaseLeftButton();
327 base::MessageLoop::current()->RunUntilIdle();
328 test
->RunMessageLoopUntilAnimationsDone();
333 ash::ShelfModel
* model_
;
334 ChromeLauncherController
* controller_
;
338 DISALLOW_COPY_AND_ASSIGN(ShelfAppBrowserTest
);
341 class ShelfAppBrowserTestNoDefaultBrowser
: public ShelfAppBrowserTest
{
343 ShelfAppBrowserTestNoDefaultBrowser() {}
344 ~ShelfAppBrowserTestNoDefaultBrowser() override
{}
346 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
347 ShelfAppBrowserTest::SetUpCommandLine(command_line
);
348 command_line
->AppendSwitch(switches::kNoStartupWindow
);
353 DISALLOW_COPY_AND_ASSIGN(ShelfAppBrowserTestNoDefaultBrowser
);
356 // Since the default for minimizing on click might change, I added both classes
357 // to either get the minimize on click or not.
358 class ShelfAppBrowserNoMinimizeOnClick
: public LauncherPlatformAppBrowserTest
{
360 ShelfAppBrowserNoMinimizeOnClick() {}
361 ~ShelfAppBrowserNoMinimizeOnClick() override
{}
363 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
364 LauncherPlatformAppBrowserTest::SetUpCommandLine(command_line
);
365 command_line
->AppendSwitch(
366 switches::kDisableMinimizeOnSecondLauncherItemClick
);
371 DISALLOW_COPY_AND_ASSIGN(ShelfAppBrowserNoMinimizeOnClick
);
374 typedef LauncherPlatformAppBrowserTest ShelfAppBrowserMinimizeOnClick
;
376 // Test that we can launch a platform app and get a running item.
377 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, LaunchUnpinned
) {
378 int item_count
= shelf_model()->item_count();
379 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
380 AppWindow
* window
= CreateAppWindow(extension
);
382 ASSERT_EQ(item_count
, shelf_model()->item_count());
383 const ash::ShelfItem
& item
= GetLastLauncherItem();
384 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item
.type
);
385 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
386 CloseAppWindow(window
);
388 EXPECT_EQ(item_count
, shelf_model()->item_count());
391 // Test that we can launch a platform app that already has a shortcut.
392 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, LaunchPinned
) {
393 int item_count
= shelf_model()->item_count();
396 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
397 const std::string app_id
= extension
->id();
399 // Then create a shortcut.
400 ash::ShelfID shortcut_id
= CreateAppShortcutLauncherItem(app_id
);
402 ASSERT_EQ(item_count
, shelf_model()->item_count());
403 ash::ShelfItem item
= *shelf_model()->ItemByID(shortcut_id
);
404 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
405 EXPECT_EQ(ash::STATUS_CLOSED
, item
.status
);
407 // Open a window. Confirm the item is now running.
408 AppWindow
* window
= CreateAppWindow(extension
);
409 ash::wm::ActivateWindow(window
->GetNativeWindow());
410 ASSERT_EQ(item_count
, shelf_model()->item_count());
411 item
= *shelf_model()->ItemByID(shortcut_id
);
412 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
413 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
415 // Then close it, make sure there's still an item.
416 CloseAppWindow(window
);
417 ASSERT_EQ(item_count
, shelf_model()->item_count());
418 item
= *shelf_model()->ItemByID(shortcut_id
);
419 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
420 EXPECT_EQ(ash::STATUS_CLOSED
, item
.status
);
423 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, PinRunning
) {
425 int item_count
= shelf_model()->item_count();
426 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
427 AppWindow
* window
= CreateAppWindow(extension
);
429 ASSERT_EQ(item_count
, shelf_model()->item_count());
430 const ash::ShelfItem
& item1
= GetLastLauncherItem();
431 ash::ShelfID id
= item1
.id
;
432 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
433 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
435 // Create a shortcut. The app item should be after it.
436 ash::ShelfID foo_id
= CreateAppShortcutLauncherItem("foo");
438 ASSERT_EQ(item_count
, shelf_model()->item_count());
439 EXPECT_LT(shelf_model()->ItemIndexByID(foo_id
),
440 shelf_model()->ItemIndexByID(id
));
442 // Pin the app. The item should remain.
443 controller_
->Pin(id
);
444 ASSERT_EQ(item_count
, shelf_model()->item_count());
445 const ash::ShelfItem
& item2
= *shelf_model()->ItemByID(id
);
446 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item2
.type
);
447 EXPECT_EQ(ash::STATUS_ACTIVE
, item2
.status
);
449 // New shortcuts should come after the item.
450 ash::ShelfID bar_id
= CreateAppShortcutLauncherItem("bar");
452 ASSERT_EQ(item_count
, shelf_model()->item_count());
453 EXPECT_LT(shelf_model()->ItemIndexByID(id
),
454 shelf_model()->ItemIndexByID(bar_id
));
456 // Then close it, make sure the item remains.
457 CloseAppWindow(window
);
458 ASSERT_EQ(item_count
, shelf_model()->item_count());
461 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, UnpinRunning
) {
462 int item_count
= shelf_model()->item_count();
465 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
466 const std::string app_id
= extension
->id();
468 // Then create a shortcut.
469 ash::ShelfID shortcut_id
= CreateAppShortcutLauncherItem(app_id
);
471 ASSERT_EQ(item_count
, shelf_model()->item_count());
472 ash::ShelfItem item
= *shelf_model()->ItemByID(shortcut_id
);
473 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
474 EXPECT_EQ(ash::STATUS_CLOSED
, item
.status
);
476 // Create a second shortcut. This will be needed to force the first one to
477 // move once it gets unpinned.
478 ash::ShelfID foo_id
= CreateAppShortcutLauncherItem("foo");
480 ASSERT_EQ(item_count
, shelf_model()->item_count());
481 EXPECT_LT(shelf_model()->ItemIndexByID(shortcut_id
),
482 shelf_model()->ItemIndexByID(foo_id
));
484 // Open a window. Confirm the item is now running.
485 AppWindow
* window
= CreateAppWindow(extension
);
486 ash::wm::ActivateWindow(window
->GetNativeWindow());
487 ASSERT_EQ(item_count
, shelf_model()->item_count());
488 item
= *shelf_model()->ItemByID(shortcut_id
);
489 EXPECT_EQ(ash::TYPE_APP_SHORTCUT
, item
.type
);
490 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
492 // Unpin the app. The item should remain.
493 controller_
->Unpin(shortcut_id
);
494 ASSERT_EQ(item_count
, shelf_model()->item_count());
495 item
= *shelf_model()->ItemByID(shortcut_id
);
496 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item
.type
);
497 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
498 // The item should have moved after the other shortcuts.
499 EXPECT_GT(shelf_model()->ItemIndexByID(shortcut_id
),
500 shelf_model()->ItemIndexByID(foo_id
));
502 // Then close it, make sure the item's gone.
503 CloseAppWindow(window
);
505 ASSERT_EQ(item_count
, shelf_model()->item_count());
508 // Test that we can launch a platform app with more than one window.
509 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, MultipleWindows
) {
510 int item_count
= shelf_model()->item_count();
513 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
514 AppWindow
* window1
= CreateAppWindow(extension
);
516 ASSERT_EQ(item_count
, shelf_model()->item_count());
517 const ash::ShelfItem
& item1
= GetLastLauncherItem();
518 ash::ShelfID item_id
= item1
.id
;
519 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
520 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
521 EXPECT_EQ(2, GetNumApplicationMenuItems(item1
)); // Title + 1 window
523 // Add second window.
524 AppWindow
* window2
= CreateAppWindow(extension
);
525 // Confirm item stays.
526 ASSERT_EQ(item_count
, shelf_model()->item_count());
527 const ash::ShelfItem
& item2
= *shelf_model()->ItemByID(item_id
);
528 EXPECT_EQ(ash::STATUS_ACTIVE
, item2
.status
);
529 EXPECT_EQ(3, GetNumApplicationMenuItems(item2
)); // Title + 2 windows
531 // Close second window.
532 CloseAppWindow(window2
);
533 // Confirm item stays.
534 ASSERT_EQ(item_count
, shelf_model()->item_count());
535 const ash::ShelfItem
& item3
= *shelf_model()->ItemByID(item_id
);
536 EXPECT_EQ(ash::STATUS_ACTIVE
, item3
.status
);
537 EXPECT_EQ(2, GetNumApplicationMenuItems(item3
)); // Title + 1 window
539 // Close first window.
540 CloseAppWindow(window1
);
541 // Confirm item is removed.
543 ASSERT_EQ(item_count
, shelf_model()->item_count());
546 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, MultipleApps
) {
547 int item_count
= shelf_model()->item_count();
550 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
551 AppWindow
* window1
= CreateAppWindow(extension1
);
553 ASSERT_EQ(item_count
, shelf_model()->item_count());
554 const ash::ShelfItem
& item1
= GetLastLauncherItem();
555 ash::ShelfID item_id1
= item1
.id
;
556 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
557 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
559 // Then run second app.
560 const Extension
* extension2
= LoadAndLaunchPlatformApp("launch_2",
562 AppWindow
* window2
= CreateAppWindow(extension2
);
564 ASSERT_EQ(item_count
, shelf_model()->item_count());
565 const ash::ShelfItem
& item2
= GetLastLauncherItem();
566 ash::ShelfID item_id2
= item2
.id
;
567 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item2
.type
);
568 EXPECT_EQ(ash::STATUS_ACTIVE
, item2
.status
);
570 EXPECT_NE(item_id1
, item_id2
);
571 EXPECT_EQ(ash::STATUS_RUNNING
, shelf_model()->ItemByID(item_id1
)->status
);
574 CloseAppWindow(window2
);
576 ASSERT_EQ(item_count
, shelf_model()->item_count());
577 // First app should be active again.
578 EXPECT_EQ(ash::STATUS_ACTIVE
, shelf_model()->ItemByID(item_id1
)->status
);
581 CloseAppWindow(window1
);
583 ASSERT_EQ(item_count
, shelf_model()->item_count());
586 // Confirm that app windows can be reactivated by clicking their icons and that
587 // the correct activation order is maintained.
588 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, WindowActivation
) {
589 int item_count
= shelf_model()->item_count();
592 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
593 AppWindow
* window1
= CreateAppWindow(extension1
);
595 ASSERT_EQ(item_count
, shelf_model()->item_count());
596 const ash::ShelfItem
& item1
= GetLastLauncherItem();
597 ash::ShelfID item_id1
= item1
.id
;
598 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
599 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
601 // Then run second app.
602 const Extension
* extension2
= LoadAndLaunchPlatformApp("launch_2",
604 AppWindow
* window2
= CreateAppWindow(extension2
);
606 ASSERT_EQ(item_count
, shelf_model()->item_count());
607 const ash::ShelfItem
& item2
= GetLastLauncherItem();
608 ash::ShelfID item_id2
= item2
.id
;
609 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item2
.type
);
610 EXPECT_EQ(ash::STATUS_ACTIVE
, item2
.status
);
612 EXPECT_NE(item_id1
, item_id2
);
613 EXPECT_EQ(ash::STATUS_RUNNING
, shelf_model()->ItemByID(item_id1
)->status
);
615 // Activate first one.
616 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id1
));
617 EXPECT_EQ(ash::STATUS_ACTIVE
, shelf_model()->ItemByID(item_id1
)->status
);
618 EXPECT_EQ(ash::STATUS_RUNNING
, shelf_model()->ItemByID(item_id2
)->status
);
619 EXPECT_TRUE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
620 EXPECT_FALSE(ash::wm::IsActiveWindow(window2
->GetNativeWindow()));
622 // Activate second one.
623 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id2
));
624 EXPECT_EQ(ash::STATUS_RUNNING
, shelf_model()->ItemByID(item_id1
)->status
);
625 EXPECT_EQ(ash::STATUS_ACTIVE
, shelf_model()->ItemByID(item_id2
)->status
);
626 EXPECT_FALSE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
627 EXPECT_TRUE(ash::wm::IsActiveWindow(window2
->GetNativeWindow()));
629 // Add window for app1. This will activate it.
630 AppWindow
* window1b
= CreateAppWindow(extension1
);
631 ash::wm::ActivateWindow(window1b
->GetNativeWindow());
632 EXPECT_FALSE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
633 EXPECT_FALSE(ash::wm::IsActiveWindow(window2
->GetNativeWindow()));
634 EXPECT_TRUE(ash::wm::IsActiveWindow(window1b
->GetNativeWindow()));
636 // Activate launcher item for app1, this will activate the first app window.
637 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id1
));
638 EXPECT_TRUE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
639 EXPECT_FALSE(ash::wm::IsActiveWindow(window1b
->GetNativeWindow()));
640 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id1
));
641 EXPECT_TRUE(ash::wm::IsActiveWindow(window1b
->GetNativeWindow()));
643 // Activate the second app again
644 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id2
));
645 EXPECT_FALSE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
646 EXPECT_TRUE(ash::wm::IsActiveWindow(window2
->GetNativeWindow()));
647 EXPECT_FALSE(ash::wm::IsActiveWindow(window1b
->GetNativeWindow()));
649 // Activate the first app again
650 ActivateShelfItem(shelf_model()->ItemIndexByID(item_id1
));
651 EXPECT_TRUE(ash::wm::IsActiveWindow(window1b
->GetNativeWindow()));
652 EXPECT_FALSE(ash::wm::IsActiveWindow(window2
->GetNativeWindow()));
653 EXPECT_FALSE(ash::wm::IsActiveWindow(window1
->GetNativeWindow()));
656 CloseAppWindow(window2
);
658 EXPECT_EQ(item_count
, shelf_model()->item_count());
659 // First app should be active again.
660 EXPECT_EQ(ash::STATUS_ACTIVE
, shelf_model()->ItemByID(item_id1
)->status
);
663 CloseAppWindow(window1b
);
664 CloseAppWindow(window1
);
666 EXPECT_EQ(item_count
, shelf_model()->item_count());
669 // Verify that ChromeLauncherController::CanInstall() returns true for ephemeral
670 // apps and false when the app is promoted to a regular installed app.
671 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, InstallEphemeralApp
) {
672 int item_count
= shelf_model()->item_count();
674 // Sanity check to verify that ChromeLauncherController::CanInstall() returns
675 // false for apps that are fully installed.
676 const Extension
* app
= LoadAndLaunchPlatformApp("launch", "Launched");
678 CreateAppWindow(app
);
680 ASSERT_EQ(item_count
, shelf_model()->item_count());
681 const ash::ShelfItem
& app_item
= GetLastLauncherItem();
682 ash::ShelfID app_id
= app_item
.id
;
683 EXPECT_FALSE(controller_
->CanInstall(app_id
));
685 // Add an ephemeral app.
686 const Extension
* ephemeral_app
= InstallEphemeralAppWithSourceAndFlags(
687 test_data_dir_
.AppendASCII("platform_apps").AppendASCII("launch_2"),
689 extensions::Manifest::INTERNAL
,
690 Extension::NO_FLAGS
);
691 ASSERT_TRUE(ephemeral_app
);
692 CreateAppWindow(ephemeral_app
);
694 ASSERT_EQ(item_count
, shelf_model()->item_count());
695 const ash::ShelfItem
& ephemeral_item
= GetLastLauncherItem();
696 ash::ShelfID ephemeral_id
= ephemeral_item
.id
;
698 // Verify that the shelf item for the ephemeral app can be installed.
699 EXPECT_TRUE(controller_
->CanInstall(ephemeral_id
));
701 // Promote the ephemeral app to a regular installed app.
702 ExtensionService
* service
=
703 extensions::ExtensionSystem::Get(profile())->extension_service();
704 service
->PromoteEphemeralApp(ephemeral_app
, false);
706 // Verify that the shelf item for the app can no longer be installed.
707 EXPECT_FALSE(controller_
->CanInstall(ephemeral_id
));
710 // Confirm that Click behavior for app windows is correnct.
711 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserNoMinimizeOnClick
, AppClickBehavior
) {
712 // Launch a platform app and create a window for it.
713 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
714 AppWindow
* window1
= CreateAppWindow(extension1
);
715 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
716 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
717 // Confirm that a controller item was created and is the correct state.
718 const ash::ShelfItem
& item1
= GetLastLauncherItem();
719 LauncherItemController
* item1_controller
= GetItemController(item1
.id
);
720 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
721 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
722 EXPECT_EQ(LauncherItemController::TYPE_APP
, item1_controller
->type());
723 // Clicking the item should have no effect.
724 TestEvent
click_event(ui::ET_MOUSE_PRESSED
);
725 item1_controller
->ItemSelected(click_event
);
726 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
727 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
728 // Minimize the window and confirm that the controller item is updated.
729 window1
->GetBaseWindow()->Minimize();
730 EXPECT_FALSE(window1
->GetNativeWindow()->IsVisible());
731 EXPECT_FALSE(window1
->GetBaseWindow()->IsActive());
732 EXPECT_EQ(ash::STATUS_RUNNING
, item1
.status
);
733 // Clicking the item should activate the window.
734 item1_controller
->ItemSelected(click_event
);
735 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
736 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
737 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
738 // Maximizing a window should preserve state after minimize + click.
739 window1
->GetBaseWindow()->Maximize();
740 window1
->GetBaseWindow()->Minimize();
741 item1_controller
->ItemSelected(click_event
);
742 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
743 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
744 EXPECT_TRUE(window1
->GetBaseWindow()->IsMaximized());
747 // Confirm the minimizing click behavior for apps.
748 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserMinimizeOnClick
,
749 PackagedAppClickBehaviorInMinimizeMode
) {
750 // Launch one platform app and create a window for it.
751 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
752 AppWindow
* window1
= CreateAppWindow(extension1
);
753 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
754 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
756 // Confirm that a controller item was created and is the correct state.
757 const ash::ShelfItem
& item1
= GetLastLauncherItem();
758 LauncherItemController
* item1_controller
= GetItemController(item1
.id
);
759 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
760 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
761 EXPECT_EQ(LauncherItemController::TYPE_APP
, item1_controller
->type());
762 // Since it is already active, clicking it should minimize.
763 TestEvent
click_event(ui::ET_MOUSE_PRESSED
);
764 item1_controller
->ItemSelected(click_event
);
765 EXPECT_FALSE(window1
->GetNativeWindow()->IsVisible());
766 EXPECT_FALSE(window1
->GetBaseWindow()->IsActive());
767 EXPECT_TRUE(window1
->GetBaseWindow()->IsMinimized());
768 EXPECT_EQ(ash::STATUS_RUNNING
, item1
.status
);
769 // Clicking the item again should activate the window again.
770 item1_controller
->ItemSelected(click_event
);
771 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
772 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
773 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
774 // Maximizing a window should preserve state after minimize + click.
775 window1
->GetBaseWindow()->Maximize();
776 window1
->GetBaseWindow()->Minimize();
777 item1_controller
->ItemSelected(click_event
);
778 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
779 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
780 EXPECT_TRUE(window1
->GetBaseWindow()->IsMaximized());
781 window1
->GetBaseWindow()->Restore();
782 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
783 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
784 EXPECT_FALSE(window1
->GetBaseWindow()->IsMaximized());
786 // Creating a second window of the same type should change the behavior so
787 // that a click does not change the activation state.
788 AppWindow
* window1a
= CreateAppWindow(extension1
);
789 EXPECT_TRUE(window1a
->GetNativeWindow()->IsVisible());
790 EXPECT_TRUE(window1a
->GetBaseWindow()->IsActive());
791 // The first click does nothing.
792 item1_controller
->ItemSelected(click_event
);
793 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
794 EXPECT_TRUE(window1a
->GetNativeWindow()->IsVisible());
795 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
796 EXPECT_FALSE(window1a
->GetBaseWindow()->IsActive());
797 // The second neither.
798 item1_controller
->ItemSelected(click_event
);
799 EXPECT_TRUE(window1
->GetNativeWindow()->IsVisible());
800 EXPECT_TRUE(window1a
->GetNativeWindow()->IsVisible());
801 EXPECT_TRUE(window1
->GetBaseWindow()->IsActive());
802 EXPECT_FALSE(window1a
->GetBaseWindow()->IsActive());
805 // Confirm that click behavior for app panels is correct.
806 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, AppPanelClickBehavior
) {
807 // Enable experimental APIs to allow panel creation.
808 base::CommandLine::ForCurrentProcess()->AppendSwitch(
809 extensions::switches::kEnableExperimentalExtensionApis
);
810 // Launch a platform app and create a panel window for it.
811 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
812 AppWindow::CreateParams params
;
813 params
.window_type
= AppWindow::WINDOW_TYPE_PANEL
;
814 params
.focused
= false;
815 AppWindow
* panel
= CreateAppWindowFromParams(extension1
, params
);
816 EXPECT_TRUE(panel
->GetNativeWindow()->IsVisible());
817 // Panels should not be active by default.
818 EXPECT_FALSE(panel
->GetBaseWindow()->IsActive());
819 // Confirm that a controller item was created and is the correct state.
820 const ash::ShelfItem
& item1
= GetLastLauncherPanelItem();
821 LauncherItemController
* item1_controller
= GetItemController(item1
.id
);
822 EXPECT_EQ(ash::TYPE_APP_PANEL
, item1
.type
);
823 EXPECT_EQ(ash::STATUS_RUNNING
, item1
.status
);
824 EXPECT_EQ(LauncherItemController::TYPE_APP_PANEL
, item1_controller
->type());
825 // Click the item and confirm that the panel is activated.
826 TestEvent
click_event(ui::ET_MOUSE_PRESSED
);
827 item1_controller
->ItemSelected(click_event
);
828 EXPECT_TRUE(panel
->GetBaseWindow()->IsActive());
829 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
830 // Click the item again and confirm that the panel is minimized.
831 item1_controller
->ItemSelected(click_event
);
832 EXPECT_TRUE(panel
->GetBaseWindow()->IsMinimized());
833 EXPECT_EQ(ash::STATUS_RUNNING
, item1
.status
);
834 // Click the item again and confirm that the panel is activated.
835 item1_controller
->ItemSelected(click_event
);
836 EXPECT_TRUE(panel
->GetNativeWindow()->IsVisible());
837 EXPECT_TRUE(panel
->GetBaseWindow()->IsActive());
838 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
841 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, BrowserActivation
) {
842 int item_count
= shelf_model()->item_count();
845 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
846 CreateAppWindow(extension1
);
848 ASSERT_EQ(item_count
, shelf_model()->item_count());
849 const ash::ShelfItem
& item1
= GetLastLauncherItem();
850 ash::ShelfID item_id1
= item1
.id
;
851 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
852 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
854 ash::wm::ActivateWindow(browser()->window()->GetNativeWindow());
855 EXPECT_EQ(ash::STATUS_RUNNING
, shelf_model()->ItemByID(item_id1
)->status
);
858 // Test that opening an app sets the correct icon
859 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, SetIcon
) {
860 TestAppWindowRegistryObserver
test_observer(browser()->profile());
862 // Enable experimental APIs to allow panel creation.
863 base::CommandLine::ForCurrentProcess()->AppendSwitch(
864 extensions::switches::kEnableExperimentalExtensionApis
);
866 int base_shelf_item_count
= shelf_model()->item_count();
867 ExtensionTestMessageListener
completed_listener("Completed", false);
868 LoadAndLaunchPlatformApp("app_icon", "Launched");
869 ASSERT_TRUE(completed_listener
.WaitUntilSatisfied());
871 // Now wait until the WebContent has decoded the icons and chrome has
872 // processed it. This needs to be in a loop since the renderer runs in a
873 // different process.
874 while (test_observer
.icon_updates() < 3) {
875 base::RunLoop run_loop
;
876 run_loop
.RunUntilIdle();
879 // This test creates one app window and one panel window.
880 int shelf_item_count
= shelf_model()->item_count();
881 ASSERT_EQ(base_shelf_item_count
+ 2, shelf_item_count
);
882 // The Panel will be the last item, the app second-to-last.
883 const ash::ShelfItem
& app_item
=
884 shelf_model()->items()[shelf_item_count
- 2];
885 const ash::ShelfItem
& panel_item
=
886 shelf_model()->items()[shelf_item_count
- 1];
887 const LauncherItemController
* app_item_controller
=
888 GetItemController(app_item
.id
);
889 const LauncherItemController
* panel_item_controller
=
890 GetItemController(panel_item
.id
);
891 // Icons for Apps are set by the AppWindowLauncherController, so
892 // image_set_by_controller() should be set.
893 EXPECT_TRUE(app_item_controller
->image_set_by_controller());
894 EXPECT_TRUE(panel_item_controller
->image_set_by_controller());
895 // Ensure icon heights are correct (see test.js in app_icon/ test directory)
896 EXPECT_EQ(ash::kShelfSize
, app_item
.image
.height());
897 EXPECT_EQ(64, panel_item
.image
.height());
900 // Test that we can launch an app with a shortcut.
901 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, LaunchPinned
) {
902 TabStripModel
* tab_strip
= browser()->tab_strip_model();
903 int tab_count
= tab_strip
->count();
904 ash::ShelfID shortcut_id
= CreateShortcut("app1");
905 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
906 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
907 EXPECT_EQ(++tab_count
, tab_strip
->count());
908 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
909 WebContents
* tab
= tab_strip
->GetActiveWebContents();
910 content::WebContentsDestroyedWatcher
destroyed_watcher(tab
);
911 browser()->tab_strip_model()->CloseSelectedTabs();
912 destroyed_watcher
.Wait();
913 EXPECT_EQ(--tab_count
, tab_strip
->count());
914 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
917 // Launch the app first and then create the shortcut.
918 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, LaunchUnpinned
) {
919 TabStripModel
* tab_strip
= browser()->tab_strip_model();
920 int tab_count
= tab_strip
->count();
921 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
,
923 EXPECT_EQ(++tab_count
, tab_strip
->count());
924 ash::ShelfID shortcut_id
= CreateShortcut("app1");
925 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
926 WebContents
* tab
= tab_strip
->GetActiveWebContents();
927 content::WebContentsDestroyedWatcher
destroyed_watcher(tab
);
928 browser()->tab_strip_model()->CloseSelectedTabs();
929 destroyed_watcher
.Wait();
930 EXPECT_EQ(--tab_count
, tab_strip
->count());
931 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
934 // Launches an app in the background and then tries to open it. This is test for
936 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, LaunchInBackground
) {
937 TabStripModel
* tab_strip
= browser()->tab_strip_model();
938 int tab_count
= tab_strip
->count();
939 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
,
941 EXPECT_EQ(++tab_count
, tab_strip
->count());
942 ChromeLauncherController::instance()->LaunchApp(last_loaded_extension_id(),
943 ash::LAUNCH_FROM_UNKNOWN
,
947 // Confirm that clicking a icon for an app running in one of 2 maxmized windows
948 // activates the right window.
949 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, LaunchMaximized
) {
950 aura::Window
* window1
= browser()->window()->GetNativeWindow();
951 ash::wm::WindowState
* window1_state
= ash::wm::GetWindowState(window1
);
952 window1_state
->Maximize();
953 content::WindowedNotificationObserver
open_observer(
954 chrome::NOTIFICATION_BROWSER_WINDOW_READY
,
955 content::NotificationService::AllSources());
956 chrome::NewEmptyWindow(browser()->profile(), chrome::HOST_DESKTOP_TYPE_ASH
);
957 open_observer
.Wait();
958 Browser
* browser2
= content::Source
<Browser
>(open_observer
.source()).ptr();
959 aura::Window
* window2
= browser2
->window()->GetNativeWindow();
960 TabStripModel
* tab_strip
= browser2
->tab_strip_model();
961 int tab_count
= tab_strip
->count();
962 ash::wm::GetWindowState(window2
)->Maximize();
964 ash::ShelfID shortcut_id
= CreateShortcut("app1");
965 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
966 EXPECT_EQ(++tab_count
, tab_strip
->count());
967 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
970 window1_state
->Activate();
971 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut_id
)).status
);
973 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
974 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
977 // Activating the same app multiple times should launch only a single copy.
978 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, ActivateApp
) {
979 TabStripModel
* tab_strip
= browser()->tab_strip_model();
980 int tab_count
= tab_strip
->count();
981 const Extension
* extension
=
982 LoadExtension(test_data_dir_
.AppendASCII("app1"));
984 ChromeLauncherController::instance()->ActivateApp(extension
->id(),
985 ash::LAUNCH_FROM_UNKNOWN
,
987 EXPECT_EQ(++tab_count
, tab_strip
->count());
988 ChromeLauncherController::instance()->ActivateApp(extension
->id(),
989 ash::LAUNCH_FROM_UNKNOWN
,
991 EXPECT_EQ(tab_count
, tab_strip
->count());
994 // Launching the same app multiple times should launch a copy for each call.
995 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, LaunchApp
) {
996 TabStripModel
* tab_strip
= browser()->tab_strip_model();
997 int tab_count
= tab_strip
->count();
998 const Extension
* extension
=
999 LoadExtension(test_data_dir_
.AppendASCII("app1"));
1001 ChromeLauncherController::instance()->LaunchApp(extension
->id(),
1002 ash::LAUNCH_FROM_UNKNOWN
,
1004 EXPECT_EQ(++tab_count
, tab_strip
->count());
1005 ChromeLauncherController::instance()->LaunchApp(extension
->id(),
1006 ash::LAUNCH_FROM_UNKNOWN
,
1008 EXPECT_EQ(++tab_count
, tab_strip
->count());
1011 // Launch 2 apps and toggle which is active.
1012 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, MultipleApps
) {
1013 int item_count
= model_
->item_count();
1014 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1015 int tab_count
= tab_strip
->count();
1016 ash::ShelfID shortcut1
= CreateShortcut("app1");
1017 EXPECT_EQ(++item_count
, model_
->item_count());
1018 ash::ShelfID shortcut2
= CreateShortcut("app2");
1019 EXPECT_EQ(++item_count
, model_
->item_count());
1021 // Launch first app.
1022 ActivateShelfItem(model_
->ItemIndexByID(shortcut1
));
1023 EXPECT_EQ(++tab_count
, tab_strip
->count());
1024 WebContents
* tab1
= tab_strip
->GetActiveWebContents();
1025 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut1
)).status
);
1027 // Launch second app.
1028 ActivateShelfItem(model_
->ItemIndexByID(shortcut2
));
1029 EXPECT_EQ(++tab_count
, tab_strip
->count());
1030 WebContents
* tab2
= tab_strip
->GetActiveWebContents();
1031 ASSERT_NE(tab1
, tab2
);
1032 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut1
)).status
);
1033 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut2
)).status
);
1035 // Reactivate first app.
1036 ActivateShelfItem(model_
->ItemIndexByID(shortcut1
));
1037 EXPECT_EQ(tab_count
, tab_strip
->count());
1038 EXPECT_EQ(tab_strip
->GetActiveWebContents(), tab1
);
1039 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut1
)).status
);
1040 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut2
)).status
);
1042 // Open second tab for second app. This should activate it.
1043 ui_test_utils::NavigateToURLWithDisposition(
1045 GURL("http://www.example.com/path3/foo.html"),
1048 EXPECT_EQ(++tab_count
, tab_strip
->count());
1049 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut1
)).status
);
1050 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut2
)).status
);
1052 // Reactivate first app.
1053 ActivateShelfItem(model_
->ItemIndexByID(shortcut1
));
1054 EXPECT_EQ(tab_count
, tab_strip
->count());
1055 EXPECT_EQ(tab_strip
->GetActiveWebContents(), tab1
);
1056 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut1
)).status
);
1057 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut2
)).status
);
1059 // And second again. This time the second tab should become active.
1060 ActivateShelfItem(model_
->ItemIndexByID(shortcut2
));
1061 EXPECT_EQ(tab_count
, tab_strip
->count());
1062 EXPECT_EQ(tab_strip
->GetActiveWebContents(), tab2
);
1063 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut1
)).status
);
1064 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut2
)).status
);
1067 // Confirm that a page can be navigated from and to while maintaining the
1068 // correct running state.
1069 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, Navigation
) {
1070 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1071 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
1072 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1073 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
1076 ui_test_utils::NavigateToURL(
1077 browser(), GURL("http://www.example.com/path0/bar.html"));
1078 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
1081 ui_test_utils::NavigateToURL(
1082 browser(), GURL("http://www.example.com/path1/foo.html"));
1083 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
1086 // Confirm that a tab can be moved between browsers while maintaining the
1087 // correct running state.
1088 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, TabDragAndDrop
) {
1089 TabStripModel
* tab_strip_model1
= browser()->tab_strip_model();
1090 EXPECT_EQ(1, tab_strip_model1
->count());
1091 int browser_index
= GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT
);
1092 EXPECT_TRUE(browser_index
>= 0);
1093 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1095 // Create a shortcut for app1.
1096 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1097 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1098 EXPECT_EQ(ash::STATUS_CLOSED
, (*model_
->ItemByID(shortcut_id
)).status
);
1100 // Activate app1 and check its item status.
1101 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1102 EXPECT_EQ(2, tab_strip_model1
->count());
1103 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->items()[browser_index
].status
);
1104 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
1106 // Create a new browser with blank tab.
1107 Browser
* browser2
= CreateBrowser(profile());
1108 EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1109 TabStripModel
* tab_strip_model2
= browser2
->tab_strip_model();
1110 EXPECT_EQ(1, tab_strip_model2
->count());
1111 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1112 EXPECT_EQ(ash::STATUS_RUNNING
, (*model_
->ItemByID(shortcut_id
)).status
);
1114 // Detach a tab at index 1 (app1) from |tab_strip_model1| and insert it as an
1115 // active tab at index 1 to |tab_strip_model2|.
1116 content::WebContents
* detached_tab
= tab_strip_model1
->DetachWebContentsAt(1);
1117 tab_strip_model2
->InsertWebContentsAt(1,
1119 TabStripModel::ADD_ACTIVE
);
1120 EXPECT_EQ(1, tab_strip_model1
->count());
1121 EXPECT_EQ(2, tab_strip_model2
->count());
1122 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->items()[browser_index
].status
);
1123 EXPECT_EQ(ash::STATUS_ACTIVE
, (*model_
->ItemByID(shortcut_id
)).status
);
1125 tab_strip_model1
->CloseAllTabs();
1126 tab_strip_model2
->CloseAllTabs();
1129 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, MultipleOwnedTabs
) {
1130 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1131 int tab_count
= tab_strip
->count();
1132 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1133 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1134 EXPECT_EQ(++tab_count
, tab_strip
->count());
1135 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1136 WebContents
* first_tab
= tab_strip
->GetActiveWebContents();
1138 // Create new tab owned by app.
1139 ui_test_utils::NavigateToURLWithDisposition(
1141 GURL("http://www.example.com/path2/bar.html"),
1143 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1144 EXPECT_EQ(++tab_count
, tab_strip
->count());
1145 // Confirm app is still active.
1146 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1148 // Create new tab not owned by app.
1149 ui_test_utils::NavigateToURLWithDisposition(
1151 GURL("http://www.example.com/path3/foo.html"),
1154 EXPECT_EQ(++tab_count
, tab_strip
->count());
1155 // No longer active.
1156 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->ItemByID(shortcut_id
)->status
);
1158 // Activating app makes first tab active again.
1159 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1160 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1161 EXPECT_EQ(tab_strip
->GetActiveWebContents(), first_tab
);
1164 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, RefocusFilter
) {
1165 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1166 int tab_count
= tab_strip
->count();
1167 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1168 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1169 EXPECT_EQ(++tab_count
, tab_strip
->count());
1170 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1171 WebContents
* first_tab
= tab_strip
->GetActiveWebContents();
1173 controller_
->SetRefocusURLPatternForTest(
1174 shortcut_id
, GURL("http://www.example.com/path1/*"));
1175 // Create new tab owned by app.
1176 ui_test_utils::NavigateToURLWithDisposition(
1178 GURL("http://www.example.com/path2/bar.html"),
1180 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1181 EXPECT_EQ(++tab_count
, tab_strip
->count());
1182 // Confirm app is still active.
1183 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1185 // Create new tab not owned by app.
1186 ui_test_utils::NavigateToURLWithDisposition(
1188 GURL("http://www.example.com/path3/foo.html"),
1191 EXPECT_EQ(++tab_count
, tab_strip
->count());
1192 // No longer active.
1193 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->ItemByID(shortcut_id
)->status
);
1195 // Activating app makes first tab active again, because second tab isn't
1196 // in its refocus url path.
1197 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1198 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1199 EXPECT_EQ(tab_strip
->GetActiveWebContents(), first_tab
);
1202 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, RefocusFilterLaunch
) {
1203 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1204 int tab_count
= tab_strip
->count();
1205 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1206 controller_
->SetRefocusURLPatternForTest(
1207 shortcut_id
, GURL("http://www.example.com/path1/*"));
1210 ui_test_utils::NavigateToURLWithDisposition(
1212 GURL("http://www.example2.com/path2/bar.html"),
1214 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1215 EXPECT_EQ(++tab_count
, tab_strip
->count());
1216 WebContents
* first_tab
= tab_strip
->GetActiveWebContents();
1217 // Confirm app is not active.
1218 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1220 // Activating app should launch new tab, because second tab isn't
1221 // in its refocus url path.
1222 ActivateShelfItem(model_
->ItemIndexByID(shortcut_id
));
1223 EXPECT_EQ(++tab_count
, tab_strip
->count());
1224 WebContents
* second_tab
= tab_strip
->GetActiveWebContents();
1225 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1226 EXPECT_NE(first_tab
, second_tab
);
1227 EXPECT_EQ(tab_strip
->GetActiveWebContents(), second_tab
);
1230 // Check the launcher activation state for applications and browser.
1231 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, ActivationStateCheck
) {
1232 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1233 // Get the browser item index
1234 int browser_index
= GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT
);
1235 EXPECT_TRUE(browser_index
>= 0);
1237 // Even though we are just comming up, the browser should be active.
1238 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1240 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1241 controller_
->SetRefocusURLPatternForTest(
1242 shortcut_id
, GURL("http://www.example.com/path1/*"));
1244 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1245 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1247 // Create new tab which would be the running app.
1248 ui_test_utils::NavigateToURLWithDisposition(
1250 GURL("http://www.example.com/path1/bar.html"),
1252 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1254 // There should never be two items active at the same time.
1255 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1256 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->items()[browser_index
].status
);
1258 tab_strip
->ActivateTabAt(0, false);
1259 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->ItemByID(shortcut_id
)->status
);
1260 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1262 tab_strip
->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE
);
1263 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1264 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->items()[browser_index
].status
);
1266 ash::wm::DeactivateWindow(browser()->window()->GetNativeWindow());
1267 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1268 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->items()[browser_index
].status
);
1271 // Check that the launcher activation state for a V1 application stays closed
1272 // even after an asynchronous browser event comes in after the tab got
1274 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, AsyncActivationStateCheck
) {
1275 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1277 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1278 controller_
->SetRefocusURLPatternForTest(
1279 shortcut_id
, GURL("http://www.example.com/path1/*"));
1281 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1283 // Create new tab which would be the running app.
1284 ui_test_utils::NavigateToURLWithDisposition(
1286 GURL("http://www.example.com/path1/bar.html"),
1288 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1290 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(shortcut_id
)->status
);
1291 // To address the issue of crbug.com/174050, the tab we are about to close
1292 // has to be active.
1293 tab_strip
->ActivateTabAt(1, false);
1294 EXPECT_EQ(1, tab_strip
->active_index());
1296 // Close the web contents.
1297 tab_strip
->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE
);
1298 // The status should now be set to closed.
1299 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(shortcut_id
)->status
);
1302 // Checks that a windowed application does not add an item to the browser list.
1303 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTestNoDefaultBrowser
,
1304 WindowedAppDoesNotAddToBrowser
) {
1305 // Get the number of items in the browser menu.
1306 size_t items
= NumberOfDetectedLauncherBrowsers(false);
1307 size_t running_browser
= chrome::GetTotalBrowserCount();
1308 EXPECT_EQ(0u, items
);
1309 EXPECT_EQ(0u, running_browser
);
1311 LoadAndLaunchExtension(
1312 "app1", extensions::LAUNCH_CONTAINER_WINDOW
, NEW_WINDOW
);
1314 // No new browser should get detected, even though one more is running.
1315 EXPECT_EQ(0u, NumberOfDetectedLauncherBrowsers(false));
1316 EXPECT_EQ(++running_browser
, chrome::GetTotalBrowserCount());
1318 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
, NEW_WINDOW
);
1320 // A new browser should get detected and one more should be running.
1321 EXPECT_EQ(NumberOfDetectedLauncherBrowsers(false), 1u);
1322 EXPECT_EQ(++running_browser
, chrome::GetTotalBrowserCount());
1325 // Checks the functionality to enumerate all browsers vs. all tabs.
1326 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTestNoDefaultBrowser
,
1327 EnumerateALlBrowsersAndTabs
) {
1328 // Create at least one browser.
1329 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
, NEW_WINDOW
);
1330 size_t browsers
= NumberOfDetectedLauncherBrowsers(false);
1331 size_t tabs
= NumberOfDetectedLauncherBrowsers(true);
1333 // Create a second browser.
1334 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
, NEW_WINDOW
);
1336 EXPECT_EQ(++browsers
, NumberOfDetectedLauncherBrowsers(false));
1337 EXPECT_EQ(++tabs
, NumberOfDetectedLauncherBrowsers(true));
1339 // Create only a tab.
1340 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
,
1341 NEW_FOREGROUND_TAB
);
1343 EXPECT_EQ(browsers
, NumberOfDetectedLauncherBrowsers(false));
1344 EXPECT_EQ(++tabs
, NumberOfDetectedLauncherBrowsers(true));
1347 // Check that the keyboard activation of a launcher item tabs properly through
1348 // the items at hand.
1349 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, AltNumberTabsTabbing
) {
1350 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1352 ash::ShelfID shortcut_id
= CreateShortcut("app");
1353 controller_
->SetRefocusURLPatternForTest(
1354 shortcut_id
, GURL("http://www.example.com/path/*"));
1355 std::string url
= "http://www.example.com/path/bla";
1357 int shortcut_index
= model_
->ItemIndexByID(shortcut_id
);
1359 // Create an application handled browser tab.
1360 ui_test_utils::NavigateToURLWithDisposition(
1364 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1366 content::WebContents
* content1
= tab_strip
->GetActiveWebContents();
1368 // Create some other browser tab.
1369 ui_test_utils::NavigateToURLWithDisposition(
1371 GURL("http://www.test.com"),
1373 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1374 content::WebContents
* content1a
= tab_strip
->GetActiveWebContents();
1376 // Make sure that the active tab is now our handled tab.
1377 EXPECT_NE(content1a
, content1
);
1379 // The active tab should still be the unnamed tab. Then we switch and reach
1380 // the first app and stay there.
1381 EXPECT_EQ(content1a
, tab_strip
->GetActiveWebContents());
1382 ActivateShelfItem(shortcut_index
);
1383 EXPECT_EQ(content1
, tab_strip
->GetActiveWebContents());
1384 ActivateShelfItem(shortcut_index
);
1385 EXPECT_EQ(content1
, tab_strip
->GetActiveWebContents());
1387 ui_test_utils::NavigateToURLWithDisposition(
1391 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1392 content::WebContents
* content2
= tab_strip
->GetActiveWebContents();
1394 EXPECT_EQ(content2
, browser()->tab_strip_model()->GetActiveWebContents());
1395 ActivateShelfItem(shortcut_index
);
1396 EXPECT_EQ(content1
, browser()->tab_strip_model()->GetActiveWebContents());
1397 ActivateShelfItem(shortcut_index
);
1398 EXPECT_EQ(content2
, browser()->tab_strip_model()->GetActiveWebContents());
1401 // Check that the keyboard activation of a launcher item tabs properly through
1402 // the items at hand.
1403 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
,
1404 AltNumberAppsTabbing
) {
1406 const Extension
* extension1
= LoadAndLaunchPlatformApp("launch", "Launched");
1407 ui::BaseWindow
* window1
= CreateAppWindow(extension1
)->GetBaseWindow();
1408 const ash::ShelfItem
& item1
= GetLastLauncherItem();
1409 ash::ShelfID app_id
= item1
.id
;
1410 int app_index
= shelf_model()->ItemIndexByID(app_id
);
1412 EXPECT_EQ(ash::TYPE_PLATFORM_APP
, item1
.type
);
1413 EXPECT_EQ(ash::STATUS_ACTIVE
, item1
.status
);
1415 const Extension
* extension2
= LoadAndLaunchPlatformApp("launch_2",
1417 ui::BaseWindow
* window2
= CreateAppWindow(extension2
)->GetBaseWindow();
1419 // By now the browser should be active. Issue Alt keystrokes several times to
1420 // see that we stay on that application.
1421 EXPECT_TRUE(window2
->IsActive());
1422 ActivateShelfItem(app_index
);
1423 EXPECT_TRUE(window1
->IsActive());
1424 ActivateShelfItem(app_index
);
1425 EXPECT_TRUE(window1
->IsActive());
1427 ui::BaseWindow
* window1a
= CreateAppWindow(extension1
)->GetBaseWindow();
1429 EXPECT_TRUE(window1a
->IsActive());
1430 EXPECT_FALSE(window1
->IsActive());
1431 ActivateShelfItem(app_index
);
1432 EXPECT_TRUE(window1
->IsActive());
1433 ActivateShelfItem(app_index
);
1434 EXPECT_TRUE(window1a
->IsActive());
1437 // Test that we can launch a platform app panel and get a running item.
1438 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, LaunchPanelWindow
) {
1439 int item_count
= shelf_model()->item_count();
1440 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
1441 AppWindow::CreateParams params
;
1442 params
.window_type
= AppWindow::WINDOW_TYPE_PANEL
;
1443 params
.focused
= false;
1444 AppWindow
* window
= CreateAppWindowFromParams(extension
, params
);
1446 ASSERT_EQ(item_count
, shelf_model()->item_count());
1447 const ash::ShelfItem
& item
= GetLastLauncherPanelItem();
1448 EXPECT_EQ(ash::TYPE_APP_PANEL
, item
.type
);
1449 // Opening a panel does not activate it.
1450 EXPECT_EQ(ash::STATUS_RUNNING
, item
.status
);
1451 CloseAppWindow(window
);
1453 EXPECT_EQ(item_count
, shelf_model()->item_count());
1456 // Test that we get correct shelf presence with hidden app windows.
1457 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, HiddenAppWindows
) {
1458 int item_count
= shelf_model()->item_count();
1459 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
1460 AppWindow::CreateParams params
;
1462 // Create a hidden window.
1463 params
.hidden
= true;
1464 AppWindow
* window_1
= CreateAppWindowFromParams(extension
, params
);
1465 EXPECT_EQ(item_count
, shelf_model()->item_count());
1467 // Create a visible window.
1468 params
.hidden
= false;
1469 AppWindow
* window_2
= CreateAppWindowFromParams(extension
, params
);
1471 EXPECT_EQ(item_count
, shelf_model()->item_count());
1473 // Minimize the visible window.
1474 window_2
->Minimize();
1475 EXPECT_EQ(item_count
, shelf_model()->item_count());
1477 // Hide the visible window.
1480 EXPECT_EQ(item_count
, shelf_model()->item_count());
1482 // Show the originally hidden window.
1483 window_1
->Show(AppWindow::SHOW_ACTIVE
);
1485 EXPECT_EQ(item_count
, shelf_model()->item_count());
1487 // Close the originally hidden window.
1488 CloseAppWindow(window_1
);
1490 EXPECT_EQ(item_count
, shelf_model()->item_count());
1493 // Test attention states of windows.
1494 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest
, WindowAttentionStatus
) {
1495 const Extension
* extension
= LoadAndLaunchPlatformApp("launch", "Launched");
1496 AppWindow::CreateParams params
;
1497 params
.window_type
= AppWindow::WINDOW_TYPE_PANEL
;
1498 params
.focused
= false;
1499 AppWindow
* panel
= CreateAppWindowFromParams(extension
, params
);
1500 EXPECT_TRUE(panel
->GetNativeWindow()->IsVisible());
1501 // Panels should not be active by default.
1502 EXPECT_FALSE(panel
->GetBaseWindow()->IsActive());
1503 // Confirm that a controller item was created and is the correct state.
1504 const ash::ShelfItem
& item
= GetLastLauncherPanelItem();
1505 LauncherItemController
* item_controller
= GetItemController(item
.id
);
1506 EXPECT_EQ(ash::TYPE_APP_PANEL
, item
.type
);
1507 EXPECT_EQ(ash::STATUS_RUNNING
, item
.status
);
1508 EXPECT_EQ(LauncherItemController::TYPE_APP_PANEL
, item_controller
->type());
1510 // App windows should go to attention state.
1511 panel
->GetNativeWindow()->SetProperty(aura::client::kDrawAttentionKey
, true);
1512 EXPECT_EQ(ash::STATUS_ATTENTION
, item
.status
);
1514 // Click the item and confirm that the panel is activated.
1515 TestEvent
click_event(ui::ET_MOUSE_PRESSED
);
1516 item_controller
->ItemSelected(click_event
);
1517 EXPECT_TRUE(panel
->GetBaseWindow()->IsActive());
1518 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
1520 // Active windows don't show attention.
1521 panel
->GetNativeWindow()->SetProperty(aura::client::kDrawAttentionKey
, true);
1522 EXPECT_EQ(ash::STATUS_ACTIVE
, item
.status
);
1525 // Checks that the browser Alt "tabbing" is properly done.
1526 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTestNoDefaultBrowser
,
1527 AltNumberBrowserTabbing
) {
1528 // Get the number of items in the browser menu.
1529 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
1530 // The first activation should create a browser at index 1 (App List @ 0).
1531 shelf_
->ActivateShelfItem(1);
1532 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1533 // A second activation should not create a new instance.
1534 shelf_
->ActivateShelfItem(1);
1535 Browser
* browser1
= chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
1536 EXPECT_TRUE(browser1
);
1537 aura::Window
* window1
= browser1
->window()->GetNativeWindow();
1538 Browser
* browser2
= CreateBrowser(profile());
1539 aura::Window
* window2
= browser2
->window()->GetNativeWindow();
1541 EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1542 EXPECT_NE(window1
, window2
);
1543 EXPECT_EQ(window2
, ash::wm::GetActiveWindow());
1545 // Activate multiple times the switcher to see that the windows get activated.
1546 shelf_
->ActivateShelfItem(1);
1547 EXPECT_EQ(window1
, ash::wm::GetActiveWindow());
1548 shelf_
->ActivateShelfItem(1);
1549 EXPECT_EQ(window2
, ash::wm::GetActiveWindow());
1551 // Create a third browser - make sure that we do not toggle simply between
1553 Browser
* browser3
= CreateBrowser(profile());
1554 aura::Window
* window3
= browser3
->window()->GetNativeWindow();
1556 EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
1557 EXPECT_NE(window1
, window3
);
1558 EXPECT_NE(window2
, window3
);
1559 EXPECT_EQ(window3
, ash::wm::GetActiveWindow());
1561 shelf_
->ActivateShelfItem(1);
1562 EXPECT_EQ(window1
, ash::wm::GetActiveWindow());
1563 shelf_
->ActivateShelfItem(1);
1564 EXPECT_EQ(window2
, ash::wm::GetActiveWindow());
1565 shelf_
->ActivateShelfItem(1);
1566 EXPECT_EQ(window3
, ash::wm::GetActiveWindow());
1567 shelf_
->ActivateShelfItem(1);
1568 EXPECT_EQ(window1
, ash::wm::GetActiveWindow());
1570 // Create anther app and make sure that none of our browsers is active.
1571 LoadAndLaunchExtension("app1", extensions::LAUNCH_CONTAINER_TAB
, NEW_WINDOW
);
1572 EXPECT_NE(window1
, ash::wm::GetActiveWindow());
1573 EXPECT_NE(window2
, ash::wm::GetActiveWindow());
1575 // After activation our browser should be active again.
1576 shelf_
->ActivateShelfItem(1);
1577 EXPECT_EQ(window1
, ash::wm::GetActiveWindow());
1580 // Checks that after a session restore, we do not start applications on an
1582 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, ActivateAfterSessionRestore
) {
1583 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
1585 // Create a known application.
1586 ash::ShelfID shortcut_id
= CreateShortcut("app1");
1588 // Create a new browser - without activating it - and load an "app" into it.
1589 Browser::CreateParams params
=
1590 Browser::CreateParams(profile(), chrome::GetActiveDesktop());
1591 params
.initial_show_state
= ui::SHOW_STATE_INACTIVE
;
1592 Browser
* browser2
= new Browser(params
);
1593 controller_
->SetRefocusURLPatternForTest(
1594 shortcut_id
, GURL("http://www.example.com/path/*"));
1595 std::string url
= "http://www.example.com/path/bla";
1596 ui_test_utils::NavigateToURLWithDisposition(
1600 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1602 // Remember the number of tabs for each browser.
1603 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1604 int tab_count1
= tab_strip
->count();
1605 TabStripModel
* tab_strip2
= browser2
->tab_strip_model();
1606 int tab_count2
= tab_strip2
->count();
1608 // Check that we have two browsers and the inactive browser remained inactive.
1609 EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1610 EXPECT_EQ(chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()),
1612 // Check that the LRU browser list does only contain the original browser.
1613 BrowserList
* ash_browser_list
=
1614 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH
);
1615 BrowserList::const_reverse_iterator it
=
1616 ash_browser_list
->begin_last_active();
1617 EXPECT_EQ(*it
, browser());
1619 EXPECT_EQ(it
, ash_browser_list
->end_last_active());
1621 // Now request to either activate an existing app or create a new one.
1622 LauncherItemController
* item_controller
=
1623 controller_
->GetLauncherItemController(shortcut_id
);
1624 item_controller
->ItemSelected(ui::KeyEvent(ui::ET_KEY_RELEASED
,
1628 // Check that we have set focus on the existing application and nothing new
1630 EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
1631 EXPECT_EQ(tab_count1
, tab_strip
->count());
1632 EXPECT_EQ(tab_count2
, tab_strip2
->count());
1633 EXPECT_EQ(chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()),
1637 // Do various drag and drop interaction tests between the application list and
1639 // TODO(skuhne): Test is flaky with a real compositor: crbug.com/331924
1640 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, DISABLED_DragAndDrop
) {
1641 // Get a number of interfaces we need.
1642 ui::test::EventGenerator
generator(ash::Shell::GetPrimaryRootWindow(),
1644 ash::test::ShelfViewTestAPI
test(
1645 ash::test::ShelfTestAPI(shelf_
).shelf_view());
1646 AppListService
* service
= AppListService::Get(chrome::GetActiveDesktop());
1648 // There should be two items in our launcher by this time.
1649 EXPECT_EQ(2, model_
->item_count());
1650 EXPECT_FALSE(service
->IsAppListVisible());
1652 // Open the app list menu and check that the drag and drop host was set.
1653 gfx::Rect app_list_bounds
=
1654 test
.shelf_view()->GetAppListButtonView()->GetBoundsInScreen();
1655 generator
.MoveMouseTo(app_list_bounds
.CenterPoint().x(),
1656 app_list_bounds
.CenterPoint().y());
1657 base::MessageLoop::current()->RunUntilIdle();
1658 generator
.ClickLeftButton();
1660 EXPECT_TRUE(service
->IsAppListVisible());
1661 app_list::AppsGridView
* grid_view
=
1662 ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).
1664 ASSERT_TRUE(grid_view
);
1665 ASSERT_TRUE(grid_view
->has_drag_and_drop_host_for_test());
1667 // There should be 2 items in our application list.
1668 const views::ViewModelT
<app_list::AppListItemView
>* vm_grid
=
1669 grid_view
->view_model_for_test();
1670 EXPECT_EQ(2, vm_grid
->view_size());
1672 // Test #1: Drag an app list which does not exist yet item into the
1673 // launcher. Keeping it dragged, see that a new item gets created. Continuing
1674 // to drag it out should remove it again.
1676 // Get over item #1 of the application list and press the mouse button.
1677 views::View
* item1
= vm_grid
->view_at(1);
1678 gfx::Rect bounds_grid_1
= item1
->GetBoundsInScreen();
1679 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1680 bounds_grid_1
.CenterPoint().y());
1681 base::MessageLoop::current()->RunUntilIdle();
1682 generator
.PressLeftButton();
1684 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1686 // Drag the item into the shelf and check that a new item gets created.
1687 const views::ViewModel
* vm_shelf
= test
.shelf_view()->view_model_for_test();
1688 views::View
* shelf1
= vm_shelf
->view_at(1);
1689 gfx::Rect bounds_shelf_1
= shelf1
->GetBoundsInScreen();
1690 generator
.MoveMouseTo(bounds_shelf_1
.CenterPoint().x(),
1691 bounds_shelf_1
.CenterPoint().y());
1692 base::MessageLoop::current()->RunUntilIdle();
1694 // Check that a new item got created.
1695 EXPECT_EQ(3, model_
->item_count());
1696 EXPECT_TRUE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1698 // Move it where the item originally was and check that it disappears again.
1699 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1700 bounds_grid_1
.CenterPoint().y());
1701 base::MessageLoop::current()->RunUntilIdle();
1702 EXPECT_EQ(2, model_
->item_count());
1703 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1705 // Dropping it should keep the launcher as it originally was.
1706 generator
.ReleaseLeftButton();
1707 base::MessageLoop::current()->RunUntilIdle();
1708 EXPECT_EQ(2, model_
->item_count());
1709 // There are a few animations which need finishing before we can continue.
1710 test
.RunMessageLoopUntilAnimationsDone();
1711 // Move the mouse outside of the launcher.
1712 generator
.MoveMouseTo(0, 0);
1714 // Test #2: Check that the unknown item dropped into the launcher will
1715 // create a new item.
1716 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1717 bounds_grid_1
.CenterPoint().y());
1718 generator
.PressLeftButton();
1719 generator
.MoveMouseTo(bounds_shelf_1
.CenterPoint().x(),
1720 bounds_shelf_1
.CenterPoint().y());
1721 base::MessageLoop::current()->RunUntilIdle();
1722 EXPECT_EQ(3, model_
->item_count());
1723 EXPECT_TRUE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1724 generator
.ReleaseLeftButton();
1725 base::MessageLoop::current()->RunUntilIdle();
1726 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1727 EXPECT_EQ(3, model_
->item_count()); // It should be still there.
1728 test
.RunMessageLoopUntilAnimationsDone();
1730 // Test #3: Check that the now known item dropped into the launcher will
1731 // not create a new item.
1732 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1733 bounds_grid_1
.CenterPoint().y());
1734 generator
.PressLeftButton();
1735 generator
.MoveMouseTo(bounds_shelf_1
.CenterPoint().x(),
1736 bounds_shelf_1
.CenterPoint().y());
1737 base::MessageLoop::current()->RunUntilIdle();
1738 EXPECT_EQ(3, model_
->item_count()); // No new item got added.
1739 EXPECT_TRUE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1740 generator
.ReleaseLeftButton();
1741 base::MessageLoop::current()->RunUntilIdle();
1742 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1743 EXPECT_EQ(3, model_
->item_count()); // And it remains that way.
1745 // Test #4: Check that by pressing ESC the operation gets cancelled.
1746 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1747 bounds_grid_1
.CenterPoint().y());
1748 generator
.PressLeftButton();
1749 generator
.MoveMouseTo(bounds_shelf_1
.CenterPoint().x(),
1750 bounds_shelf_1
.CenterPoint().y());
1751 base::MessageLoop::current()->RunUntilIdle();
1752 // Issue an ESC and see that the operation gets cancelled.
1753 generator
.PressKey(ui::VKEY_ESCAPE
, 0);
1754 generator
.ReleaseKey(ui::VKEY_ESCAPE
, 0);
1755 EXPECT_FALSE(grid_view
->dragging());
1756 EXPECT_FALSE(grid_view
->has_dragged_view());
1757 generator
.ReleaseLeftButton();
1760 #if !defined(OS_WIN)
1761 // Used to test drag & drop an item between app list and shelf with multi
1762 // display environment.
1763 class ShelfAppBrowserTestWithMultiMonitor
1764 : public ShelfAppBrowserTestNoDefaultBrowser
{
1766 ShelfAppBrowserTestWithMultiMonitor() {}
1767 ~ShelfAppBrowserTestWithMultiMonitor() override
{}
1769 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
1770 ShelfAppBrowserTestNoDefaultBrowser::SetUpCommandLine(command_line
);
1771 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1772 "800x800,801+0-800x800");
1777 DISALLOW_COPY_AND_ASSIGN(ShelfAppBrowserTestWithMultiMonitor
);
1780 // Do basic drag and drop interaction tests between the application list and
1781 // the launcher in the secondary monitor.
1782 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTestWithMultiMonitor
,
1784 // Get a number of interfaces we need.
1785 DCHECK_EQ(ash::Shell::GetAllRootWindows().size(), 2U);
1786 aura::Window
* secondary_root_window
= ash::Shell::GetAllRootWindows()[1];
1787 ash::Shelf
* secondary_shelf
= ash::Shelf::ForWindow(secondary_root_window
);
1789 ui::test::EventGenerator
generator(secondary_root_window
, gfx::Point());
1790 ash::test::ShelfViewTestAPI
test(
1791 ash::test::ShelfTestAPI(secondary_shelf
).shelf_view());
1792 AppListService
* service
= AppListService::Get(chrome::GetActiveDesktop());
1794 // There should be two items in our shelf by this time.
1795 EXPECT_EQ(2, model_
->item_count());
1796 EXPECT_FALSE(service
->IsAppListVisible());
1798 // Open the app list menu and check that the drag and drop host was set.
1799 gfx::Rect app_list_bounds
=
1800 test
.shelf_view()->GetAppListButtonView()->GetBoundsInScreen();
1801 gfx::Display display
=
1802 ash::Shell::GetScreen()->GetDisplayNearestWindow(secondary_root_window
);
1803 const gfx::Point
& origin
= display
.bounds().origin();
1804 app_list_bounds
.Offset(-origin
.x(), -origin
.y());
1806 generator
.MoveMouseTo(app_list_bounds
.CenterPoint().x(),
1807 app_list_bounds
.CenterPoint().y());
1808 generator
.ClickLeftButton();
1809 base::MessageLoop::current()->RunUntilIdle();
1810 EXPECT_TRUE(service
->IsAppListVisible());
1812 // Click the "all apps" button on the start page.
1813 ClickAllAppsButtonFromStartPage(&generator
, origin
);
1814 EXPECT_TRUE(service
->IsAppListVisible());
1816 app_list::AppsGridView
* grid_view
=
1817 ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).
1819 ASSERT_TRUE(grid_view
);
1820 ASSERT_TRUE(grid_view
->has_drag_and_drop_host_for_test());
1822 // There should be 2 items in our application list.
1823 const views::ViewModelT
<app_list::AppListItemView
>* vm_grid
=
1824 grid_view
->view_model_for_test();
1825 EXPECT_EQ(2, vm_grid
->view_size());
1827 // Drag an app list item which does not exist yet in the shelf.
1828 // Keeping it dragged, see that a new item gets created.
1829 // Continuing to drag it out should remove it again.
1831 // Get over item #1 of the application list and press the mouse button.
1832 views::View
* item1
= vm_grid
->view_at(1);
1833 gfx::Rect bounds_grid_1
= item1
->GetBoundsInScreen();
1834 bounds_grid_1
.Offset(-origin
.x(), -origin
.y());
1835 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
1836 bounds_grid_1
.CenterPoint().y());
1837 base::MessageLoop::current()->RunUntilIdle();
1838 generator
.PressLeftButton();
1840 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1842 // Drag the item into the shelf and check that a new item gets created.
1843 const views::ViewModel
* vm_shelf
= test
.shelf_view()->view_model_for_test();
1844 views::View
* shelf1
= vm_shelf
->view_at(1);
1845 gfx::Rect bounds_shelf_1
= shelf1
->GetBoundsInScreen();
1846 bounds_shelf_1
.Offset(-origin
.x(), -origin
.y());
1847 generator
.MoveMouseTo(bounds_shelf_1
.CenterPoint().x(),
1848 bounds_shelf_1
.CenterPoint().y());
1849 base::MessageLoop::current()->RunUntilIdle();
1851 // Check that a new item got created.
1852 EXPECT_EQ(3, model_
->item_count());
1853 EXPECT_TRUE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1855 // Move it to an empty slot on grid_view.
1856 gfx::Rect empty_slot_rect
= bounds_grid_1
;
1857 empty_slot_rect
.Offset(0, grid_view
->GetTotalTileSize().height());
1858 generator
.MoveMouseTo(empty_slot_rect
.CenterPoint().x(),
1859 empty_slot_rect
.CenterPoint().y());
1860 base::MessageLoop::current()->RunUntilIdle();
1861 EXPECT_EQ(2, model_
->item_count());
1862 EXPECT_FALSE(grid_view
->forward_events_to_drag_and_drop_host_for_test());
1864 // Dropping it should keep the shelf as it originally was.
1865 generator
.ReleaseLeftButton();
1866 base::MessageLoop::current()->RunUntilIdle();
1867 EXPECT_EQ(2, model_
->item_count());
1871 // Do tests for removal of items from the shelf by dragging.
1872 // Disabled due to flake: http://crbug.com/448482
1873 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, DISABLED_DragOffShelf
) {
1874 ui::test::EventGenerator
generator(ash::Shell::GetPrimaryRootWindow(),
1876 ash::test::ShelfViewTestAPI
test(
1877 ash::test::ShelfTestAPI(shelf_
).shelf_view());
1878 test
.SetAnimationDuration(1); // Speed up animations for test.
1879 // Create a known application and check that we have 3 items in the shelf.
1880 CreateShortcut("app1");
1881 test
.RunMessageLoopUntilAnimationsDone();
1882 EXPECT_EQ(3, model_
->item_count());
1884 // Test #1: Ripping out the browser item should not change anything.
1885 int browser_index
= GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT
);
1886 EXPECT_LE(0, browser_index
);
1887 RipOffItemIndex(browser_index
, &generator
, &test
, RIP_OFF_ITEM
);
1888 // => It should not have been removed and the location should be unchanged.
1889 EXPECT_EQ(3, model_
->item_count());
1890 EXPECT_EQ(browser_index
,
1891 GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT
));
1892 // Make sure that the hide state has been unset after the snap back animation
1894 ash::ShelfButton
* button
= test
.GetButton(browser_index
);
1895 EXPECT_FALSE(button
->state() & ash::ShelfButton::STATE_HIDDEN
);
1897 // Test #2: Ripping out the application and canceling the operation should
1898 // not change anything.
1899 int app_index
= GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
);
1900 EXPECT_LE(0, app_index
);
1901 RipOffItemIndex(app_index
, &generator
, &test
, RIP_OFF_ITEM_AND_CANCEL
);
1902 // => It should not have been removed and the location should be unchanged.
1903 ASSERT_EQ(3, model_
->item_count());
1904 EXPECT_EQ(app_index
, GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
));
1906 // Test #3: Ripping out the application and moving it back in should not
1908 RipOffItemIndex(app_index
, &generator
, &test
, RIP_OFF_ITEM_AND_RETURN
);
1909 // => It should not have been removed and the location should be unchanged.
1910 ASSERT_EQ(3, model_
->item_count());
1911 // Through the operation the index might have changed.
1912 app_index
= GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
);
1914 // Test #4: Ripping out the application should remove the item.
1915 RipOffItemIndex(app_index
, &generator
, &test
, RIP_OFF_ITEM
);
1916 // => It should not have been removed and the location should be unchanged.
1917 EXPECT_EQ(2, model_
->item_count());
1918 EXPECT_EQ(-1, GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
));
1920 // Test #5: Uninstalling an application while it is being ripped off should
1922 ash::ShelfID app_id
= CreateShortcut("app2");
1923 test
.RunMessageLoopUntilAnimationsDone();
1924 int app2_index
= GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
);
1925 EXPECT_EQ(3, model_
->item_count()); // And it remains that way.
1926 RipOffItemIndex(app2_index
,
1929 RIP_OFF_ITEM_AND_DONT_RELEASE_MOUSE
);
1930 RemoveShortcut(app_id
);
1931 test
.RunMessageLoopUntilAnimationsDone();
1932 EXPECT_EQ(2, model_
->item_count()); // The item should now be gone.
1933 generator
.ReleaseLeftButton();
1934 base::MessageLoop::current()->RunUntilIdle();
1935 EXPECT_EQ(2, model_
->item_count()); // And it remains that way.
1936 EXPECT_EQ(-1, GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
));
1938 // Test #6: Ripping out the application when the overflow button exists.
1939 // After ripping out, overflow button should be removed.
1940 int items_added
= 0;
1941 EXPECT_FALSE(test
.IsOverflowButtonVisible());
1943 // Create fake app shortcuts until overflow button is created.
1944 while (!test
.IsOverflowButtonVisible()) {
1945 std::string fake_app_id
= base::StringPrintf("fake_app_%d", items_added
);
1946 PinFakeApp(fake_app_id
);
1947 test
.RunMessageLoopUntilAnimationsDone();
1950 ASSERT_LT(items_added
, 10000);
1952 // Make one more item after creating a overflow button.
1953 std::string fake_app_id
= base::StringPrintf("fake_app_%d", items_added
);
1954 PinFakeApp(fake_app_id
);
1955 test
.RunMessageLoopUntilAnimationsDone();
1957 int total_count
= model_
->item_count();
1958 app_index
= GetIndexOfShelfItemType(ash::TYPE_APP_SHORTCUT
);
1959 RipOffItemIndex(app_index
, &generator
, &test
, RIP_OFF_ITEM
);
1960 // When an item is ripped off from the shelf that has overflow button
1961 // (see crbug.com/3050787), it was hidden accidentally and was then
1962 // suppressing any further events. If handled correctly the operation will
1963 // however correctly done and the item will get removed (as well as the
1964 // overflow button).
1965 EXPECT_EQ(total_count
- 1, model_
->item_count());
1966 EXPECT_TRUE(test
.IsOverflowButtonVisible());
1968 // Rip off again and the overflow button should has disappeared.
1969 RipOffItemIndex(app_index
, &generator
, &test
, RIP_OFF_ITEM
);
1970 EXPECT_EQ(total_count
- 2, model_
->item_count());
1971 EXPECT_FALSE(test
.IsOverflowButtonVisible());
1974 // Check that clicking on an app shelf item launches a new browser.
1975 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, ClickItem
) {
1976 // Get a number of interfaces we need.
1977 ui::test::EventGenerator
generator(ash::Shell::GetPrimaryRootWindow(),
1979 ash::test::ShelfViewTestAPI
test(
1980 ash::test::ShelfTestAPI(shelf_
).shelf_view());
1981 AppListService
* service
= AppListService::Get(chrome::GetActiveDesktop());
1982 // There should be two items in our shelf by this time.
1983 EXPECT_EQ(2, model_
->item_count());
1984 EXPECT_FALSE(service
->IsAppListVisible());
1986 // Open the app list menu and check that the drag and drop host was set.
1987 gfx::Rect app_list_bounds
=
1988 test
.shelf_view()->GetAppListButtonView()->GetBoundsInScreen();
1989 generator
.MoveMouseTo(app_list_bounds
.CenterPoint().x(),
1990 app_list_bounds
.CenterPoint().y());
1991 generator
.ClickLeftButton();
1992 base::MessageLoop::current()->RunUntilIdle();
1993 EXPECT_TRUE(service
->IsAppListVisible());
1995 // Click the "all apps" button on the start page.
1996 ClickAllAppsButtonFromStartPage(&generator
, gfx::Point());
1997 EXPECT_TRUE(service
->IsAppListVisible());
1999 // Click an app icon in the app grid view.
2000 app_list::AppsGridView
* grid_view
=
2001 ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).
2003 ASSERT_TRUE(grid_view
);
2004 const views::ViewModelT
<app_list::AppListItemView
>* vm_grid
=
2005 grid_view
->view_model_for_test();
2006 EXPECT_EQ(2, vm_grid
->view_size());
2007 gfx::Rect bounds_grid_1
= vm_grid
->view_at(1)->GetBoundsInScreen();
2008 // Test now that a click does create a new application tab.
2009 TabStripModel
* tab_strip
= browser()->tab_strip_model();
2010 int tab_count
= tab_strip
->count();
2011 generator
.MoveMouseTo(bounds_grid_1
.CenterPoint().x(),
2012 bounds_grid_1
.CenterPoint().y());
2013 generator
.ClickLeftButton();
2014 base::MessageLoop::current()->RunUntilIdle();
2015 EXPECT_EQ(tab_count
+ 1, tab_strip
->count());
2018 // Check LauncherItemController of Browser Shortcut functionality.
2019 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTestNoDefaultBrowser
,
2020 BrowserShortcutLauncherItemController
) {
2021 LauncherItemController
* item_controller
=
2022 controller_
->GetBrowserShortcutLauncherItemController();
2024 // Get the number of browsers.
2025 size_t running_browser
= chrome::GetTotalBrowserCount();
2026 EXPECT_EQ(0u, running_browser
);
2027 EXPECT_FALSE(item_controller
->IsOpen());
2029 // Activate. This creates new browser
2030 item_controller
->Activate(ash::LAUNCH_FROM_UNKNOWN
);
2031 // New Window is created.
2032 running_browser
= chrome::GetTotalBrowserCount();
2033 EXPECT_EQ(1u, running_browser
);
2034 EXPECT_TRUE(item_controller
->IsOpen());
2037 ash::wm::WindowState
* window_state
= ash::wm::GetActiveWindowState();
2038 window_state
->Minimize();
2039 EXPECT_TRUE(window_state
->IsMinimized());
2041 // Activate again. This doesn't create new browser.
2042 // It activates window.
2043 item_controller
->Activate(ash::LAUNCH_FROM_UNKNOWN
);
2044 running_browser
= chrome::GetTotalBrowserCount();
2045 EXPECT_EQ(1u, running_browser
);
2046 EXPECT_TRUE(item_controller
->IsOpen());
2047 EXPECT_FALSE(window_state
->IsMinimized());
2050 // Check that GetShelfIDForWindow() returns |ShelfID| of the active tab.
2051 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, MatchingShelfIDandActiveTab
) {
2052 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2053 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2054 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
2055 EXPECT_EQ(2, model_
->item_count());
2057 aura::Window
* window
= browser()->window()->GetNativeWindow();
2059 int browser_index
= GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT
);
2060 ash::ShelfID browser_id
= model_
->items()[browser_index
].id
;
2061 EXPECT_EQ(browser_id
, ash::GetShelfIDForWindow(window
));
2063 ash::ShelfID app_id
= CreateShortcut("app1");
2064 EXPECT_EQ(3, model_
->item_count());
2066 // Creates a new tab for "app1" and checks that GetShelfIDForWindow()
2067 // returns |ShelfID| of "app1".
2068 ActivateShelfItem(model_
->ItemIndexByID(app_id
));
2069 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2070 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
2071 EXPECT_EQ(app_id
, ash::GetShelfIDForWindow(window
));
2073 // Makes tab at index 0(NTP) as an active tab and checks that
2074 // GetShelfIDForWindow() returns |ShelfID| of browser shortcut.
2075 browser()->tab_strip_model()->ActivateTabAt(0, false);
2076 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
2077 EXPECT_EQ(browser_id
, ash::GetShelfIDForWindow(window
));
2080 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, OverflowBubble
) {
2081 // Make sure to have a browser window
2082 chrome::NewTab(browser());
2085 EXPECT_FALSE(shelf_
->IsShowingOverflowBubble());
2087 ash::test::ShelfViewTestAPI
test(
2088 ash::test::ShelfTestAPI(shelf_
).shelf_view());
2090 int items_added
= 0;
2091 while (!test
.IsOverflowButtonVisible()) {
2092 std::string fake_app_id
= base::StringPrintf("fake_app_%d", items_added
);
2093 PinFakeApp(fake_app_id
);
2096 ASSERT_LT(items_added
, 10000);
2099 // Now show overflow bubble.
2100 test
.ShowOverflowBubble();
2101 EXPECT_TRUE(shelf_
->IsShowingOverflowBubble());
2103 // Unpin first pinned app and there should be no crash.
2104 controller_
->UnpinAppWithID(std::string("fake_app_0"));
2106 test
.RunMessageLoopUntilAnimationsDone();
2107 EXPECT_FALSE(shelf_
->IsShowingOverflowBubble());
2110 // Check that a windowed V1 application can navigate away from its domain, but
2111 // still gets detected properly.
2112 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, V1AppNavigation
) {
2113 // We assume that the web store is always there (which it apparently is).
2114 controller_
->PinAppWithID(extensions::kWebStoreAppId
);
2115 ash::ShelfID id
= controller_
->GetShelfIDForAppID(
2116 extensions::kWebStoreAppId
);
2118 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(id
)->status
);
2120 // Create a windowed application.
2121 AppLaunchParams
params(
2122 profile(), controller_
->GetExtensionForAppID(extensions::kWebStoreAppId
),
2123 CURRENT_TAB
, chrome::HOST_DESKTOP_TYPE_ASH
, extensions::SOURCE_TEST
);
2124 params
.container
= extensions::LAUNCH_CONTAINER_WINDOW
;
2125 OpenApplication(params
);
2126 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(id
)->status
);
2128 // Find the browser which holds our app.
2129 Browser
* app_browser
= NULL
;
2130 const BrowserList
* ash_browser_list
=
2131 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH
);
2132 for (BrowserList::const_reverse_iterator it
=
2133 ash_browser_list
->begin_last_active();
2134 it
!= ash_browser_list
->end_last_active() && !app_browser
; ++it
) {
2135 if ((*it
)->is_app()) {
2140 ASSERT_TRUE(app_browser
);
2142 // After navigating away in the app, we should still be active.
2143 ui_test_utils::NavigateToURL(app_browser
,
2144 GURL("http://www.foo.com/bar.html"));
2145 // Make sure the navigation was entirely performed.
2146 base::MessageLoop::current()->RunUntilIdle();
2147 EXPECT_EQ(ash::STATUS_ACTIVE
, model_
->ItemByID(id
)->status
);
2148 app_browser
->tab_strip_model()->CloseWebContentsAt(0,
2149 TabStripModel::CLOSE_NONE
);
2150 // Make sure that the app is really gone.
2151 base::MessageLoop::current()->RunUntilIdle();
2152 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(id
)->status
);
2155 // Checks that a opening a settings window creates a new launcher item.
2156 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, SettingsWindow
) {
2157 chrome::SettingsWindowManager
* settings_manager
=
2158 chrome::SettingsWindowManager::GetInstance();
2159 ash::ShelfModel
* shelf_model
= ash::Shell::GetInstance()->shelf_model();
2161 // Get the number of items in the shelf and browser menu.
2162 int item_count
= shelf_model
->item_count();
2163 size_t browser_count
= NumberOfDetectedLauncherBrowsers(false);
2165 // Open a settings window. Number of browser items should remain unchanged,
2166 // number of shelf items should increase.
2167 settings_manager
->ShowChromePageForProfile(
2168 browser()->profile(),
2169 chrome::GetSettingsUrl(std::string()));
2170 Browser
* settings_browser
=
2171 settings_manager
->FindBrowserForProfile(browser()->profile());
2172 ASSERT_TRUE(settings_browser
);
2173 EXPECT_EQ(browser_count
, NumberOfDetectedLauncherBrowsers(false));
2174 EXPECT_EQ(item_count
+ 1, shelf_model
->item_count());
2176 // TODO(stevenjb): Test multiprofile on Chrome OS when test support is addded.
2177 // crbug.com/230464.
2180 // Check that tabbed hosted and bookmark apps have correct shelf presence.
2181 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, TabbedHostedAndBookmarkApps
) {
2182 // Load and pin a hosted app.
2183 const Extension
* hosted_app
=
2184 LoadExtension(test_data_dir_
.AppendASCII("app1/"));
2185 ASSERT_TRUE(hosted_app
);
2186 controller_
->PinAppWithID(hosted_app
->id());
2187 const ash::ShelfID hosted_app_shelf_id
=
2188 controller_
->GetShelfIDForAppID(hosted_app
->id());
2190 // Load and pin a bookmark app.
2191 const Extension
* bookmark_app
= InstallExtensionWithSourceAndFlags(
2192 test_data_dir_
.AppendASCII("app2/"), 1, extensions::Manifest::INTERNAL
,
2193 extensions::Extension::FROM_BOOKMARK
);
2194 ASSERT_TRUE(bookmark_app
);
2195 controller_
->PinAppWithID(bookmark_app
->id());
2196 const ash::ShelfID bookmark_app_shelf_id
=
2197 controller_
->GetShelfIDForAppID(bookmark_app
->id());
2199 // The apps should be closed.
2200 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(hosted_app_shelf_id
)->status
);
2201 EXPECT_EQ(ash::STATUS_CLOSED
,
2202 model_
->ItemByID(bookmark_app_shelf_id
)->status
);
2204 // Navigate to the app's launch URLs in two tabs.
2205 ui_test_utils::NavigateToURL(
2206 browser(), extensions::AppLaunchInfo::GetLaunchWebURL(hosted_app
));
2207 ui_test_utils::NavigateToURLWithDisposition(
2208 browser(), extensions::AppLaunchInfo::GetLaunchWebURL(bookmark_app
),
2209 NEW_FOREGROUND_TAB
, 0);
2211 // The apps should now be running, with the last opened app active.
2212 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->ItemByID(hosted_app_shelf_id
)->status
);
2213 EXPECT_EQ(ash::STATUS_ACTIVE
,
2214 model_
->ItemByID(bookmark_app_shelf_id
)->status
);
2216 // Now use the launcher controller to activate the apps.
2217 controller_
->ActivateApp(hosted_app
->id(), ash::LAUNCH_FROM_APP_LIST
, 0);
2218 controller_
->ActivateApp(bookmark_app
->id(), ash::LAUNCH_FROM_APP_LIST
, 0);
2220 // There should be no new browsers or tabs as both apps were already open.
2221 EXPECT_EQ(1u, chrome::GetTotalBrowserCountForProfile(browser()->profile()));
2222 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2225 // Check that windowed hosted and bookmark apps have correct shelf presence.
2226 IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest
, WindowedHostedAndBookmarkApps
) {
2227 // Load and pin a hosted app.
2228 const Extension
* hosted_app
=
2229 LoadExtension(test_data_dir_
.AppendASCII("app1/"));
2230 ASSERT_TRUE(hosted_app
);
2231 controller_
->PinAppWithID(hosted_app
->id());
2232 const ash::ShelfID hosted_app_shelf_id
=
2233 controller_
->GetShelfIDForAppID(hosted_app
->id());
2235 // Load and pin a bookmark app.
2236 const Extension
* bookmark_app
= InstallExtensionWithSourceAndFlags(
2237 test_data_dir_
.AppendASCII("app2/"), 1, extensions::Manifest::INTERNAL
,
2238 extensions::Extension::FROM_BOOKMARK
);
2239 ASSERT_TRUE(bookmark_app
);
2240 controller_
->PinAppWithID(bookmark_app
->id());
2241 const ash::ShelfID bookmark_app_shelf_id
=
2242 controller_
->GetShelfIDForAppID(bookmark_app
->id());
2244 // Set both apps to open in windows.
2245 extensions::SetLaunchType(browser()->profile(), hosted_app
->id(),
2246 extensions::LAUNCH_TYPE_WINDOW
);
2247 extensions::SetLaunchType(browser()->profile(), bookmark_app
->id(),
2248 extensions::LAUNCH_TYPE_WINDOW
);
2250 // The apps should be closed.
2251 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(hosted_app_shelf_id
)->status
);
2252 EXPECT_EQ(ash::STATUS_CLOSED
,
2253 model_
->ItemByID(bookmark_app_shelf_id
)->status
);
2255 // Navigate to the app's launch URLs in two tabs.
2256 ui_test_utils::NavigateToURL(
2257 browser(), extensions::AppLaunchInfo::GetLaunchWebURL(hosted_app
));
2258 ui_test_utils::NavigateToURLWithDisposition(
2259 browser(), extensions::AppLaunchInfo::GetLaunchWebURL(bookmark_app
),
2260 NEW_FOREGROUND_TAB
, 0);
2262 // The apps should still be closed.
2263 EXPECT_EQ(ash::STATUS_CLOSED
, model_
->ItemByID(hosted_app_shelf_id
)->status
);
2264 EXPECT_EQ(ash::STATUS_CLOSED
,
2265 model_
->ItemByID(bookmark_app_shelf_id
)->status
);
2267 // Now use the launcher controller to activate the apps.
2268 controller_
->ActivateApp(hosted_app
->id(), ash::LAUNCH_FROM_APP_LIST
, 0);
2269 controller_
->ActivateApp(bookmark_app
->id(), ash::LAUNCH_FROM_APP_LIST
, 0);
2271 // There should be two new browsers.
2272 EXPECT_EQ(3u, chrome::GetTotalBrowserCountForProfile(browser()->profile()));
2274 // The apps should now be running, with the last opened app active.
2275 EXPECT_EQ(ash::STATUS_RUNNING
, model_
->ItemByID(hosted_app_shelf_id
)->status
);
2276 EXPECT_EQ(ash::STATUS_ACTIVE
,
2277 model_
->ItemByID(bookmark_app_shelf_id
)->status
);