Home | History | Annotate | Download | only in launcher
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
      6 
      7 #include "apps/native_app_window.h"
      8 #include "apps/shell_window.h"
      9 #include "apps/shell_window_registry.h"
     10 #include "ash/ash_switches.h"
     11 #include "ash/display/display_controller.h"
     12 #include "ash/launcher/launcher.h"
     13 #include "ash/launcher/launcher_model.h"
     14 #include "ash/launcher/launcher_util.h"
     15 #include "ash/launcher/launcher_view.h"
     16 #include "ash/shell.h"
     17 #include "ash/test/launcher_view_test_api.h"
     18 #include "ash/test/shell_test_api.h"
     19 #include "ash/wm/window_util.h"
     20 #include "base/strings/utf_string_conversions.h"
     21 #include "chrome/browser/automation/automation_util.h"
     22 #include "chrome/browser/chrome_notification_types.h"
     23 #include "chrome/browser/extensions/extension_apitest.h"
     24 #include "chrome/browser/extensions/extension_browsertest.h"
     25 #include "chrome/browser/extensions/extension_function_test_utils.h"
     26 #include "chrome/browser/extensions/extension_service.h"
     27 #include "chrome/browser/extensions/extension_system.h"
     28 #include "chrome/browser/extensions/extension_test_message_listener.h"
     29 #include "chrome/browser/extensions/platform_app_browsertest_util.h"
     30 #include "chrome/browser/profiles/profile.h"
     31 #include "chrome/browser/ui/app_list/app_list_service.h"
     32 #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
     33 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h"
     34 #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h"
     35 #include "chrome/browser/ui/browser.h"
     36 #include "chrome/browser/ui/browser_commands.h"
     37 #include "chrome/browser/ui/browser_finder.h"
     38 #include "chrome/browser/ui/browser_list.h"
     39 #include "chrome/browser/ui/browser_window.h"
     40 #include "chrome/browser/ui/extensions/application_launch.h"
     41 #include "chrome/browser/ui/host_desktop.h"
     42 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     43 #include "chrome/common/chrome_switches.h"
     44 #include "chrome/common/extensions/extension_constants.h"
     45 #include "chrome/test/base/ui_test_utils.h"
     46 #include "content/public/browser/notification_service.h"
     47 #include "content/public/browser/notification_source.h"
     48 #include "content/public/browser/web_contents.h"
     49 #include "extensions/common/switches.h"
     50 #include "testing/gtest/include/gtest/gtest.h"
     51 #include "ui/app_list/views/apps_grid_view.h"
     52 #include "ui/aura/test/event_generator.h"
     53 #include "ui/aura/window.h"
     54 #include "ui/base/events/event.h"
     55 
     56 using apps::ShellWindow;
     57 using extensions::Extension;
     58 using content::WebContents;
     59 
     60 namespace {
     61 
     62 class TestEvent : public ui::Event {
     63  public:
     64   explicit TestEvent(ui::EventType type)
     65       : ui::Event(type, base::TimeDelta(), 0) {
     66   }
     67   virtual ~TestEvent() {
     68   }
     69 
     70  private:
     71   DISALLOW_COPY_AND_ASSIGN(TestEvent);
     72 };
     73 
     74 class TestShellWindowRegistryObserver
     75     : public apps::ShellWindowRegistry::Observer {
     76  public:
     77   explicit TestShellWindowRegistryObserver(Profile* profile)
     78       : profile_(profile),
     79         icon_updates_(0) {
     80     apps::ShellWindowRegistry::Get(profile_)->AddObserver(this);
     81   }
     82 
     83   virtual ~TestShellWindowRegistryObserver() {
     84     apps::ShellWindowRegistry::Get(profile_)->RemoveObserver(this);
     85   }
     86 
     87   // Overridden from ShellWindowRegistry::Observer:
     88   virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE {}
     89 
     90   virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE {
     91     ++icon_updates_;
     92   }
     93 
     94   virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE {}
     95 
     96   int icon_updates() { return icon_updates_; }
     97 
     98  private:
     99   Profile* profile_;
    100   int icon_updates_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(TestShellWindowRegistryObserver);
    103 };
    104 
    105 }  // namespace
    106 
    107 // TODO(skuhne): Change name back to LauncherPlatformAppBrowserTest when the
    108 // old launcher gets ripped out.
    109 class LauncherPlatformPerAppAppBrowserTest
    110     : public extensions::PlatformAppBrowserTest {
    111  protected:
    112   LauncherPlatformPerAppAppBrowserTest()
    113       : launcher_(NULL),
    114         controller_(NULL) {
    115   }
    116 
    117   virtual ~LauncherPlatformPerAppAppBrowserTest() {}
    118 
    119   virtual void RunTestOnMainThreadLoop() OVERRIDE {
    120     launcher_ = ash::Launcher::ForPrimaryDisplay();
    121     controller_ =
    122         static_cast<ChromeLauncherControllerPerApp*>(launcher_->delegate());
    123     return extensions::PlatformAppBrowserTest::RunTestOnMainThreadLoop();
    124   }
    125 
    126   ash::LauncherModel* launcher_model() {
    127     return ash::test::ShellTestApi(ash::Shell::GetInstance()).launcher_model();
    128   }
    129 
    130   ash::LauncherID CreateAppShortcutLauncherItem(const std::string& name) {
    131     return controller_->CreateAppShortcutLauncherItem(
    132         name, controller_->model()->item_count());
    133   }
    134 
    135   const ash::LauncherItem& GetLastLauncherItem() {
    136     // Unless there are any panels, the item at index [count - 1] will be
    137     // the app list, and the item at [count - 2] will be the desired item.
    138     return launcher_model()->items()[launcher_model()->item_count() - 2];
    139   }
    140 
    141   const ash::LauncherItem& GetLastLauncherPanelItem() {
    142     // Panels show up on the right side of the launcher, so the desired item
    143     // will be the last one.
    144     return launcher_model()->items()[launcher_model()->item_count() - 1];
    145   }
    146 
    147   LauncherItemController* GetItemController(ash::LauncherID id) {
    148     return controller_->id_to_item_controller_map_[id];
    149   }
    150 
    151   // Returns the number of menu items, ignoring separators.
    152   int GetNumApplicationMenuItems(const ash::LauncherItem& item) {
    153     const int event_flags = 0;
    154     scoped_ptr<ash::LauncherMenuModel> menu(
    155         controller_->CreateApplicationMenu(item, event_flags));
    156     int num_items = 0;
    157     for (int i = 0; i < menu->GetItemCount(); ++i) {
    158       if (menu->GetTypeAt(i) != ui::MenuModel::TYPE_SEPARATOR)
    159         ++num_items;
    160     }
    161     return num_items;
    162   }
    163 
    164   // Activate the launcher item with the given |id|.
    165   void ActivateLauncherItem(int id) {
    166     launcher_->ActivateLauncherItem(id);
    167   }
    168 
    169   ash::Launcher* launcher_;
    170   ChromeLauncherControllerPerApp* controller_;
    171 
    172  private:
    173 
    174   DISALLOW_COPY_AND_ASSIGN(LauncherPlatformPerAppAppBrowserTest);
    175 };
    176 
    177 // TODO(skuhne): Change name back to LauncherAppBrowserTest when the
    178 // old launcher gets ripped out.
    179 class LauncherPerAppAppBrowserTest : public ExtensionBrowserTest {
    180  protected:
    181   LauncherPerAppAppBrowserTest()
    182       : launcher_(NULL),
    183         model_(NULL) {
    184   }
    185 
    186   virtual ~LauncherPerAppAppBrowserTest() {}
    187 
    188   virtual void RunTestOnMainThreadLoop() OVERRIDE {
    189     launcher_ = ash::Launcher::ForPrimaryDisplay();
    190     model_ =
    191         ash::test::ShellTestApi(ash::Shell::GetInstance()).launcher_model();
    192     return ExtensionBrowserTest::RunTestOnMainThreadLoop();
    193   }
    194 
    195   size_t NumberOfDetectedLauncherBrowsers(bool show_all_tabs) {
    196     ChromeLauncherControllerPerApp* controller =
    197         static_cast<ChromeLauncherControllerPerApp*>(launcher_->delegate());
    198     LauncherItemController* item_controller =
    199       controller->GetBrowserShortcutLauncherItemController();
    200     int items = item_controller->GetApplicationList(
    201         show_all_tabs ? ui::EF_SHIFT_DOWN : 0).size();
    202     // If we have at least one item, we have also a title which we remove here.
    203     return items ? (items - 1) : 0;
    204   }
    205 
    206   const Extension* LoadAndLaunchExtension(
    207       const char* name,
    208       extension_misc::LaunchContainer container,
    209       WindowOpenDisposition disposition) {
    210     EXPECT_TRUE(LoadExtension(test_data_dir_.AppendASCII(name)));
    211 
    212     ExtensionService* service = extensions::ExtensionSystem::Get(
    213         profile())->extension_service();
    214     const Extension* extension =
    215         service->GetExtensionById(last_loaded_extension_id_, false);
    216     EXPECT_TRUE(extension);
    217 
    218     chrome::OpenApplication(chrome::AppLaunchParams(profile(),
    219                                                     extension,
    220                                                     container,
    221                                                     disposition));
    222     return extension;
    223   }
    224 
    225   ash::LauncherID CreateShortcut(const char* name) {
    226     ExtensionService* service = extensions::ExtensionSystem::Get(
    227         profile())->extension_service();
    228     LoadExtension(test_data_dir_.AppendASCII(name));
    229 
    230     // First get app_id.
    231     const Extension* extension =
    232         service->GetExtensionById(last_loaded_extension_id_, false);
    233     const std::string app_id = extension->id();
    234 
    235     // Then create a shortcut.
    236     ChromeLauncherController* controller =
    237         static_cast<ChromeLauncherController*>(launcher_->delegate());
    238     int item_count = model_->item_count();
    239     ash::LauncherID shortcut_id = controller->CreateAppShortcutLauncherItem(
    240         app_id,
    241         item_count);
    242     controller->PersistPinnedState();
    243     EXPECT_EQ(++item_count, model_->item_count());
    244     const ash::LauncherItem& item = *model_->ItemByID(shortcut_id);
    245     EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    246     return item.id;
    247   }
    248 
    249   // Activate the launcher item with the given |id|.
    250   void ActivateLauncherItem(int id) {
    251     launcher_->ActivateLauncherItem(id);
    252   }
    253 
    254   ash::Launcher* launcher_;
    255   ash::LauncherModel* model_;
    256 
    257  private:
    258 
    259   DISALLOW_COPY_AND_ASSIGN(LauncherPerAppAppBrowserTest);
    260 };
    261 
    262 // TODO(skuhne): Change name to LauncherAppBrowserTestNoBrowser when the
    263 // old launcher gets ripped out.
    264 class LauncherPerAppAppBrowserTestNoDefaultBrowser
    265     : public LauncherPerAppAppBrowserTest {
    266  protected:
    267   LauncherPerAppAppBrowserTestNoDefaultBrowser() {}
    268   virtual ~LauncherPerAppAppBrowserTestNoDefaultBrowser() {}
    269 
    270   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    271     LauncherPerAppAppBrowserTest::SetUpCommandLine(command_line);
    272     command_line->AppendSwitch(switches::kNoStartupWindow);
    273   }
    274 
    275  private:
    276 
    277   DISALLOW_COPY_AND_ASSIGN(LauncherPerAppAppBrowserTestNoDefaultBrowser);
    278 };
    279 
    280 // Since the default for minimizing on click might change, I added both classes
    281 // to either get the minimize on click or not.
    282 class LauncherPerAppAppBrowserNoMinimizeOnClick
    283     : public LauncherPlatformPerAppAppBrowserTest {
    284  protected:
    285   LauncherPerAppAppBrowserNoMinimizeOnClick() {}
    286   virtual ~LauncherPerAppAppBrowserNoMinimizeOnClick() {}
    287 
    288   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    289     LauncherPlatformPerAppAppBrowserTest::SetUpCommandLine(command_line);
    290     command_line->AppendSwitch(
    291         switches::kDisableMinimizeOnSecondLauncherItemClick);
    292   }
    293 
    294  private:
    295 
    296   DISALLOW_COPY_AND_ASSIGN(LauncherPerAppAppBrowserNoMinimizeOnClick);
    297 };
    298 
    299 typedef LauncherPlatformPerAppAppBrowserTest
    300     LauncherPerAppAppBrowserMinimizeOnClick;
    301 
    302 // Test that we can launch a platform app and get a running item.
    303 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, LaunchUnpinned) {
    304   int item_count = launcher_model()->item_count();
    305   const Extension* extension = LoadAndLaunchPlatformApp("launch");
    306   ShellWindow* window = CreateShellWindow(extension);
    307   ++item_count;
    308   ASSERT_EQ(item_count, launcher_model()->item_count());
    309   const ash::LauncherItem& item = GetLastLauncherItem();
    310   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item.type);
    311   EXPECT_EQ(ash::STATUS_ACTIVE, item.status);
    312   CloseShellWindow(window);
    313   --item_count;
    314   EXPECT_EQ(item_count, launcher_model()->item_count());
    315 }
    316 
    317 // Test that we can launch a platform app that already has a shortcut.
    318 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, LaunchPinned) {
    319   int item_count = launcher_model()->item_count();
    320 
    321   // First get app_id.
    322   const Extension* extension = LoadAndLaunchPlatformApp("launch");
    323   const std::string app_id = extension->id();
    324 
    325   // Then create a shortcut.
    326   ash::LauncherID shortcut_id = CreateAppShortcutLauncherItem(app_id);
    327   ++item_count;
    328   ASSERT_EQ(item_count, launcher_model()->item_count());
    329   ash::LauncherItem item = *launcher_model()->ItemByID(shortcut_id);
    330   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    331   EXPECT_EQ(ash::STATUS_CLOSED, item.status);
    332 
    333   // Open a window. Confirm the item is now running.
    334   ShellWindow* window = CreateShellWindow(extension);
    335   ash::wm::ActivateWindow(window->GetNativeWindow());
    336   ASSERT_EQ(item_count, launcher_model()->item_count());
    337   item = *launcher_model()->ItemByID(shortcut_id);
    338   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    339   EXPECT_EQ(ash::STATUS_ACTIVE, item.status);
    340 
    341   // Then close it, make sure there's still an item.
    342   CloseShellWindow(window);
    343   ASSERT_EQ(item_count, launcher_model()->item_count());
    344   item = *launcher_model()->ItemByID(shortcut_id);
    345   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    346   EXPECT_EQ(ash::STATUS_CLOSED, item.status);
    347 }
    348 
    349 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, PinRunning) {
    350   // Run.
    351   int item_count = launcher_model()->item_count();
    352   const Extension* extension = LoadAndLaunchPlatformApp("launch");
    353   ShellWindow* window = CreateShellWindow(extension);
    354   ++item_count;
    355   ASSERT_EQ(item_count, launcher_model()->item_count());
    356   const ash::LauncherItem& item1 = GetLastLauncherItem();
    357   ash::LauncherID id = item1.id;
    358   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    359   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    360 
    361   // Create a shortcut. The app item should be after it.
    362   ash::LauncherID foo_id = CreateAppShortcutLauncherItem("foo");
    363   ++item_count;
    364   ASSERT_EQ(item_count, launcher_model()->item_count());
    365   EXPECT_LT(launcher_model()->ItemIndexByID(foo_id),
    366             launcher_model()->ItemIndexByID(id));
    367 
    368   // Pin the app. The item should remain.
    369   controller_->Pin(id);
    370   ASSERT_EQ(item_count, launcher_model()->item_count());
    371   const ash::LauncherItem& item2 = *launcher_model()->ItemByID(id);
    372   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item2.type);
    373   EXPECT_EQ(ash::STATUS_ACTIVE, item2.status);
    374 
    375   // New shortcuts should come after the item.
    376   ash::LauncherID bar_id = CreateAppShortcutLauncherItem("bar");
    377   ++item_count;
    378   ASSERT_EQ(item_count, launcher_model()->item_count());
    379   EXPECT_LT(launcher_model()->ItemIndexByID(id),
    380             launcher_model()->ItemIndexByID(bar_id));
    381 
    382   // Then close it, make sure the item remains.
    383   CloseShellWindow(window);
    384   ASSERT_EQ(item_count, launcher_model()->item_count());
    385 }
    386 
    387 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, UnpinRunning) {
    388   int item_count = launcher_model()->item_count();
    389 
    390   // First get app_id.
    391   const Extension* extension = LoadAndLaunchPlatformApp("launch");
    392   const std::string app_id = extension->id();
    393 
    394   // Then create a shortcut.
    395   ash::LauncherID shortcut_id = CreateAppShortcutLauncherItem(app_id);
    396   ++item_count;
    397   ASSERT_EQ(item_count, launcher_model()->item_count());
    398   ash::LauncherItem item = *launcher_model()->ItemByID(shortcut_id);
    399   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    400   EXPECT_EQ(ash::STATUS_CLOSED, item.status);
    401 
    402   // Create a second shortcut. This will be needed to force the first one to
    403   // move once it gets unpinned.
    404   ash::LauncherID foo_id = CreateAppShortcutLauncherItem("foo");
    405   ++item_count;
    406   ASSERT_EQ(item_count, launcher_model()->item_count());
    407   EXPECT_LT(launcher_model()->ItemIndexByID(shortcut_id),
    408             launcher_model()->ItemIndexByID(foo_id));
    409 
    410   // Open a window. Confirm the item is now running.
    411   ShellWindow* window = CreateShellWindow(extension);
    412   ash::wm::ActivateWindow(window->GetNativeWindow());
    413   ASSERT_EQ(item_count, launcher_model()->item_count());
    414   item = *launcher_model()->ItemByID(shortcut_id);
    415   EXPECT_EQ(ash::TYPE_APP_SHORTCUT, item.type);
    416   EXPECT_EQ(ash::STATUS_ACTIVE, item.status);
    417 
    418   // Unpin the app. The item should remain.
    419   controller_->Unpin(shortcut_id);
    420   ASSERT_EQ(item_count, launcher_model()->item_count());
    421   item = *launcher_model()->ItemByID(shortcut_id);
    422   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item.type);
    423   EXPECT_EQ(ash::STATUS_ACTIVE, item.status);
    424   // The item should have moved after the other shortcuts.
    425   EXPECT_GT(launcher_model()->ItemIndexByID(shortcut_id),
    426             launcher_model()->ItemIndexByID(foo_id));
    427 
    428   // Then close it, make sure the item's gone.
    429   CloseShellWindow(window);
    430   --item_count;
    431   ASSERT_EQ(item_count, launcher_model()->item_count());
    432 }
    433 
    434 // Test that we can launch a platform app with more than one window.
    435 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, MultipleWindows) {
    436   int item_count = launcher_model()->item_count();
    437 
    438   // First run app.
    439   const Extension* extension = LoadAndLaunchPlatformApp("launch");
    440   ShellWindow* window1 = CreateShellWindow(extension);
    441   ++item_count;
    442   ASSERT_EQ(item_count, launcher_model()->item_count());
    443   const ash::LauncherItem& item = GetLastLauncherItem();
    444   ash::LauncherID item_id = item.id;
    445   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item.type);
    446   EXPECT_EQ(ash::STATUS_ACTIVE, item.status);
    447   EXPECT_EQ(2, GetNumApplicationMenuItems(item));  // Title + 1 window
    448 
    449   // Add second window.
    450   ShellWindow* window2 = CreateShellWindow(extension);
    451   // Confirm item stays.
    452   ASSERT_EQ(item_count, launcher_model()->item_count());
    453   const ash::LauncherItem& item2 = *launcher_model()->ItemByID(item_id);
    454   EXPECT_EQ(ash::STATUS_ACTIVE, item2.status);
    455   EXPECT_EQ(3, GetNumApplicationMenuItems(item2));  // Title + 2 windows
    456 
    457   // Close second window.
    458   CloseShellWindow(window2);
    459   // Confirm item stays.
    460   ASSERT_EQ(item_count, launcher_model()->item_count());
    461   const ash::LauncherItem& item3 = *launcher_model()->ItemByID(item_id);
    462   EXPECT_EQ(ash::STATUS_ACTIVE, item3.status);
    463   EXPECT_EQ(2, GetNumApplicationMenuItems(item3));  // Title + 1 window
    464 
    465   // Close first window.
    466   CloseShellWindow(window1);
    467   // Confirm item is removed.
    468   --item_count;
    469   ASSERT_EQ(item_count, launcher_model()->item_count());
    470 }
    471 
    472 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, MultipleApps) {
    473   int item_count = launcher_model()->item_count();
    474 
    475   // First run app.
    476   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    477   ShellWindow* window1 = CreateShellWindow(extension1);
    478   ++item_count;
    479   ASSERT_EQ(item_count, launcher_model()->item_count());
    480   const ash::LauncherItem& item1 = GetLastLauncherItem();
    481   ash::LauncherID item_id1 = item1.id;
    482   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    483   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    484 
    485   // Then run second app.
    486   const Extension* extension2 = LoadAndLaunchPlatformApp("launch_2");
    487   ShellWindow* window2 = CreateShellWindow(extension2);
    488   ++item_count;
    489   ASSERT_EQ(item_count, launcher_model()->item_count());
    490   const ash::LauncherItem& item2 = GetLastLauncherItem();
    491   ash::LauncherID item_id2 = item2.id;
    492   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item2.type);
    493   EXPECT_EQ(ash::STATUS_ACTIVE, item2.status);
    494 
    495   EXPECT_NE(item_id1, item_id2);
    496   EXPECT_EQ(ash::STATUS_RUNNING,
    497             launcher_model()->ItemByID(item_id1)->status);
    498 
    499   // Close second app.
    500   CloseShellWindow(window2);
    501   --item_count;
    502   ASSERT_EQ(item_count, launcher_model()->item_count());
    503   // First app should be active again.
    504   EXPECT_EQ(ash::STATUS_ACTIVE,
    505             launcher_model()->ItemByID(item_id1)->status);
    506 
    507   // Close first app.
    508   CloseShellWindow(window1);
    509   --item_count;
    510   ASSERT_EQ(item_count, launcher_model()->item_count());
    511 
    512 }
    513 
    514 // Confirm that app windows can be reactivated by clicking their icons and that
    515 // the correct activation order is maintained.
    516 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, WindowActivation) {
    517   int item_count = launcher_model()->item_count();
    518 
    519   // First run app.
    520   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    521   ShellWindow* window1 = CreateShellWindow(extension1);
    522   ++item_count;
    523   ASSERT_EQ(item_count, launcher_model()->item_count());
    524   const ash::LauncherItem& item1 = GetLastLauncherItem();
    525   ash::LauncherID item_id1 = item1.id;
    526   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    527   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    528 
    529   // Then run second app.
    530   const Extension* extension2 = LoadAndLaunchPlatformApp("launch_2");
    531   ShellWindow* window2 = CreateShellWindow(extension2);
    532   ++item_count;
    533   ASSERT_EQ(item_count, launcher_model()->item_count());
    534   const ash::LauncherItem& item2 = GetLastLauncherItem();
    535   ash::LauncherID item_id2 = item2.id;
    536   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item2.type);
    537   EXPECT_EQ(ash::STATUS_ACTIVE, item2.status);
    538 
    539   EXPECT_NE(item_id1, item_id2);
    540   EXPECT_EQ(ash::STATUS_RUNNING,
    541             launcher_model()->ItemByID(item_id1)->status);
    542 
    543   // Activate first one.
    544   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id1));
    545   EXPECT_EQ(ash::STATUS_ACTIVE, launcher_model()->ItemByID(item_id1)->status);
    546   EXPECT_EQ(ash::STATUS_RUNNING,
    547             launcher_model()->ItemByID(item_id2)->status);
    548   EXPECT_TRUE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    549   EXPECT_FALSE(ash::wm::IsActiveWindow(window2->GetNativeWindow()));
    550 
    551   // Activate second one.
    552   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id2));
    553   EXPECT_EQ(ash::STATUS_RUNNING,
    554             launcher_model()->ItemByID(item_id1)->status);
    555   EXPECT_EQ(ash::STATUS_ACTIVE, launcher_model()->ItemByID(item_id2)->status);
    556   EXPECT_FALSE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    557   EXPECT_TRUE(ash::wm::IsActiveWindow(window2->GetNativeWindow()));
    558 
    559   // Add window for app1. This will activate it.
    560   ShellWindow* window1b = CreateShellWindow(extension1);
    561   ash::wm::ActivateWindow(window1b->GetNativeWindow());
    562   EXPECT_FALSE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    563   EXPECT_FALSE(ash::wm::IsActiveWindow(window2->GetNativeWindow()));
    564   EXPECT_TRUE(ash::wm::IsActiveWindow(window1b->GetNativeWindow()));
    565 
    566   // Activate launcher item for app1, this will activate the first app window.
    567   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id1));
    568   EXPECT_TRUE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    569   EXPECT_FALSE(ash::wm::IsActiveWindow(window1b->GetNativeWindow()));
    570   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id1));
    571   EXPECT_TRUE(ash::wm::IsActiveWindow(window1b->GetNativeWindow()));
    572 
    573   // Activate the second app again
    574   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id2));
    575   EXPECT_FALSE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    576   EXPECT_TRUE(ash::wm::IsActiveWindow(window2->GetNativeWindow()));
    577   EXPECT_FALSE(ash::wm::IsActiveWindow(window1b->GetNativeWindow()));
    578 
    579   // Activate the first app again
    580   ActivateLauncherItem(launcher_model()->ItemIndexByID(item_id1));
    581   EXPECT_TRUE(ash::wm::IsActiveWindow(window1b->GetNativeWindow()));
    582   EXPECT_FALSE(ash::wm::IsActiveWindow(window2->GetNativeWindow()));
    583   EXPECT_FALSE(ash::wm::IsActiveWindow(window1->GetNativeWindow()));
    584 
    585   // Close second app.
    586   CloseShellWindow(window2);
    587   --item_count;
    588   EXPECT_EQ(item_count, launcher_model()->item_count());
    589   // First app should be active again.
    590   EXPECT_EQ(ash::STATUS_ACTIVE, launcher_model()->ItemByID(item_id1)->status);
    591 
    592   // Close first app.
    593   CloseShellWindow(window1b);
    594   CloseShellWindow(window1);
    595   --item_count;
    596   EXPECT_EQ(item_count, launcher_model()->item_count());
    597 }
    598 
    599 // Confirm that Click behavior for app windows is correnct.
    600 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserNoMinimizeOnClick,
    601                        AppClickBehavior) {
    602   // Launch a platform app and create a window for it.
    603   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    604   ShellWindow* window1 = CreateShellWindow(extension1);
    605   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    606   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    607   // Confirm that a controller item was created and is the correct state.
    608   const ash::LauncherItem& item1 = GetLastLauncherItem();
    609   LauncherItemController* item1_controller = GetItemController(item1.id);
    610   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    611   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    612   EXPECT_EQ(LauncherItemController::TYPE_APP, item1_controller->type());
    613   // Clicking the item should have no effect.
    614   TestEvent click_event(ui::ET_MOUSE_PRESSED);
    615   item1_controller->Clicked(click_event);
    616   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    617   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    618   // Minimize the window and confirm that the controller item is updated.
    619   window1->GetBaseWindow()->Minimize();
    620   EXPECT_FALSE(window1->GetNativeWindow()->IsVisible());
    621   EXPECT_FALSE(window1->GetBaseWindow()->IsActive());
    622   EXPECT_EQ(ash::STATUS_RUNNING, item1.status);
    623   // Clicking the item should activate the window.
    624   item1_controller->Clicked(click_event);
    625   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    626   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    627   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    628   // Maximizing a window should preserve state after minimize + click.
    629   window1->GetBaseWindow()->Maximize();
    630   window1->GetBaseWindow()->Minimize();
    631   item1_controller->Clicked(click_event);
    632   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    633   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    634   EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized());
    635 }
    636 
    637 // Confirm the minimizing click behavior for apps.
    638 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserMinimizeOnClick,
    639                        PackagedAppClickBehaviorInMinimizeMode) {
    640   // Launch one platform app and create a window for it.
    641   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    642   ShellWindow* window1 = CreateShellWindow(extension1);
    643   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    644   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    645 
    646   // Confirm that a controller item was created and is the correct state.
    647   const ash::LauncherItem& item1 = GetLastLauncherItem();
    648   LauncherItemController* item1_controller = GetItemController(item1.id);
    649   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    650   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    651   EXPECT_EQ(LauncherItemController::TYPE_APP, item1_controller->type());
    652   // Since it is already active, clicking it should minimize.
    653   TestEvent click_event(ui::ET_MOUSE_PRESSED);
    654   item1_controller->Clicked(click_event);
    655   EXPECT_FALSE(window1->GetNativeWindow()->IsVisible());
    656   EXPECT_FALSE(window1->GetBaseWindow()->IsActive());
    657   EXPECT_TRUE(window1->GetBaseWindow()->IsMinimized());
    658   EXPECT_EQ(ash::STATUS_RUNNING, item1.status);
    659   // Clicking the item again should activate the window again.
    660   item1_controller->Clicked(click_event);
    661   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    662   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    663   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    664   // Maximizing a window should preserve state after minimize + click.
    665   window1->GetBaseWindow()->Maximize();
    666   window1->GetBaseWindow()->Minimize();
    667   item1_controller->Clicked(click_event);
    668   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    669   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    670   EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized());
    671   window1->GetBaseWindow()->Restore();
    672   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    673   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    674   EXPECT_FALSE(window1->GetBaseWindow()->IsMaximized());
    675 
    676   // Creating a second window of the same type should change the behavior so
    677   // that a click does not change the activation state.
    678   ShellWindow* window1a = CreateShellWindow(extension1);
    679   EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
    680   EXPECT_TRUE(window1a->GetBaseWindow()->IsActive());
    681   // The first click does nothing.
    682   item1_controller->Clicked(click_event);
    683   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    684   EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
    685   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    686   EXPECT_FALSE(window1a->GetBaseWindow()->IsActive());
    687   // The second neither.
    688   item1_controller->Clicked(click_event);
    689   EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
    690   EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
    691   EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
    692   EXPECT_FALSE(window1a->GetBaseWindow()->IsActive());
    693 }
    694 
    695 // Confirm that click behavior for app panels is correct.
    696 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest,
    697                        AppPanelClickBehavior) {
    698   // Enable experimental APIs to allow panel creation.
    699   CommandLine::ForCurrentProcess()->AppendSwitch(
    700       extensions::switches::kEnableExperimentalExtensionApis);
    701   // Launch a platform app and create a panel window for it.
    702   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    703   ShellWindow::CreateParams params;
    704   params.window_type = ShellWindow::WINDOW_TYPE_PANEL;
    705   params.focused = false;
    706   ShellWindow* panel = CreateShellWindowFromParams(extension1, params);
    707   EXPECT_TRUE(panel->GetNativeWindow()->IsVisible());
    708   // Panels should not be active by default.
    709   EXPECT_FALSE(panel->GetBaseWindow()->IsActive());
    710   // Confirm that a controller item was created and is the correct state.
    711   const ash::LauncherItem& item1 = GetLastLauncherPanelItem();
    712   LauncherItemController* item1_controller = GetItemController(item1.id);
    713   EXPECT_EQ(ash::TYPE_APP_PANEL, item1.type);
    714   EXPECT_EQ(ash::STATUS_RUNNING, item1.status);
    715   EXPECT_EQ(LauncherItemController::TYPE_APP_PANEL, item1_controller->type());
    716   // Click the item and confirm that the panel is activated.
    717   TestEvent click_event(ui::ET_MOUSE_PRESSED);
    718   item1_controller->Clicked(click_event);
    719   EXPECT_TRUE(panel->GetBaseWindow()->IsActive());
    720   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    721   // Click the item again and confirm that the panel is minimized.
    722   item1_controller->Clicked(click_event);
    723   EXPECT_TRUE(panel->GetBaseWindow()->IsMinimized());
    724   EXPECT_EQ(ash::STATUS_RUNNING, item1.status);
    725   // Click the item again and confirm that the panel is activated.
    726   item1_controller->Clicked(click_event);
    727   EXPECT_TRUE(panel->GetNativeWindow()->IsVisible());
    728   EXPECT_TRUE(panel->GetBaseWindow()->IsActive());
    729   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    730 }
    731 
    732 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest,
    733     BrowserActivation) {
    734   int item_count = launcher_model()->item_count();
    735 
    736   // First run app.
    737   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
    738   CreateShellWindow(extension1);
    739   ++item_count;
    740   ASSERT_EQ(item_count, launcher_model()->item_count());
    741   const ash::LauncherItem& item1 = GetLastLauncherItem();
    742   ash::LauncherID item_id1 = item1.id;
    743   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
    744   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
    745 
    746   ash::wm::ActivateWindow(browser()->window()->GetNativeWindow());
    747   EXPECT_EQ(ash::STATUS_RUNNING,
    748             launcher_model()->ItemByID(item_id1)->status);
    749 }
    750 
    751 // Test that opening an app sets the correct icon
    752 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, SetIcon) {
    753   TestShellWindowRegistryObserver test_observer(browser()->profile());
    754 
    755   // Enable experimental APIs to allow panel creation.
    756   CommandLine::ForCurrentProcess()->AppendSwitch(
    757       extensions::switches::kEnableExperimentalExtensionApis);
    758 
    759   int base_launcher_item_count = launcher_model()->item_count();
    760   ExtensionTestMessageListener launched_listener("Launched", false);
    761   ExtensionTestMessageListener completed_listener("Completed", false);
    762   LoadAndLaunchPlatformApp("app_icon");
    763   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
    764   ASSERT_TRUE(completed_listener.WaitUntilSatisfied());
    765 
    766   // Now wait until the WebContent has decoded the icons and chrome has
    767   // processed it. This needs to be in a loop since the renderer runs in a
    768   // different process.
    769   while (test_observer.icon_updates() < 3) {
    770     base::RunLoop run_loop;
    771     run_loop.RunUntilIdle();
    772   }
    773 
    774   // This test creates one shell window and one panel window.
    775   int launcher_item_count = launcher_model()->item_count();
    776   ASSERT_EQ(base_launcher_item_count + 2, launcher_item_count);
    777   // The Panel will be the last item, the app list second-to-last, the app
    778   // third from last.
    779   const ash::LauncherItem& app_item =
    780       launcher_model()->items()[launcher_item_count - 3];
    781   const ash::LauncherItem& panel_item =
    782       launcher_model()->items()[launcher_item_count - 1];
    783   const LauncherItemController* app_item_controller =
    784       GetItemController(app_item.id);
    785   const LauncherItemController* panel_item_controller =
    786       GetItemController(panel_item.id);
    787   // Icons for Apps are set by the ShellWindowLauncherController, so
    788   // image_set_by_controller() should be set.
    789   EXPECT_TRUE(app_item_controller->image_set_by_controller());
    790   EXPECT_TRUE(panel_item_controller->image_set_by_controller());
    791   // Ensure icon heights are correct (see test.js in app_icon/ test directory)
    792   EXPECT_EQ(48, app_item.image.height());
    793   EXPECT_EQ(64, panel_item.image.height());
    794 }
    795 
    796 // Test that we can launch an app with a shortcut.
    797 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, LaunchPinned) {
    798   TabStripModel* tab_strip = browser()->tab_strip_model();
    799   int tab_count = tab_strip->count();
    800   ash::LauncherID shortcut_id = CreateShortcut("app1");
    801   EXPECT_EQ(ash::STATUS_CLOSED, (*model_->ItemByID(shortcut_id)).status);
    802   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
    803   EXPECT_EQ(++tab_count, tab_strip->count());
    804   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    805   WebContents* tab = tab_strip->GetActiveWebContents();
    806   content::WindowedNotificationObserver close_observer(
    807       content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
    808       content::Source<WebContents>(tab));
    809   browser()->tab_strip_model()->CloseSelectedTabs();
    810   close_observer.Wait();
    811   EXPECT_EQ(--tab_count, tab_strip->count());
    812   EXPECT_EQ(ash::STATUS_CLOSED, (*model_->ItemByID(shortcut_id)).status);
    813 }
    814 
    815 // Launch the app first and then create the shortcut.
    816 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, LaunchUnpinned) {
    817   TabStripModel* tab_strip = browser()->tab_strip_model();
    818   int tab_count = tab_strip->count();
    819   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB,
    820                          NEW_FOREGROUND_TAB);
    821   EXPECT_EQ(++tab_count, tab_strip->count());
    822   ash::LauncherID shortcut_id = CreateShortcut("app1");
    823   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    824   WebContents* tab = tab_strip->GetActiveWebContents();
    825   content::WindowedNotificationObserver close_observer(
    826       content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
    827       content::Source<WebContents>(tab));
    828   browser()->tab_strip_model()->CloseSelectedTabs();
    829   close_observer.Wait();
    830   EXPECT_EQ(--tab_count, tab_strip->count());
    831   EXPECT_EQ(ash::STATUS_CLOSED, (*model_->ItemByID(shortcut_id)).status);
    832 }
    833 
    834 // Launches an app in the background and then tries to open it. This is test for
    835 // a crash we had.
    836 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, LaunchInBackground) {
    837   TabStripModel* tab_strip = browser()->tab_strip_model();
    838   int tab_count = tab_strip->count();
    839   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB,
    840                          NEW_BACKGROUND_TAB);
    841   EXPECT_EQ(++tab_count, tab_strip->count());
    842   ChromeLauncherController::instance()->LaunchApp(last_loaded_extension_id_, 0);
    843 }
    844 
    845 // Confirm that clicking a icon for an app running in one of 2 maxmized windows
    846 // activates the right window.
    847 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, LaunchMaximized) {
    848   aura::Window* window1 = browser()->window()->GetNativeWindow();
    849   ash::wm::MaximizeWindow(window1);
    850   content::WindowedNotificationObserver open_observer(
    851       chrome::NOTIFICATION_BROWSER_WINDOW_READY,
    852       content::NotificationService::AllSources());
    853   chrome::NewEmptyWindow(browser()->profile(), chrome::HOST_DESKTOP_TYPE_ASH);
    854   open_observer.Wait();
    855   Browser* browser2 = content::Source<Browser>(open_observer.source()).ptr();
    856   aura::Window* window2 = browser2->window()->GetNativeWindow();
    857   TabStripModel* tab_strip = browser2->tab_strip_model();
    858   int tab_count = tab_strip->count();
    859   ash::wm::MaximizeWindow(window2);
    860 
    861   ash::LauncherID shortcut_id = CreateShortcut("app1");
    862   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
    863   EXPECT_EQ(++tab_count, tab_strip->count());
    864   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    865 
    866   window1->Show();
    867   ash::wm::ActivateWindow(window1);
    868   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut_id)).status);
    869 
    870   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
    871   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    872 }
    873 
    874 // Activating the same app multiple times should launch only a single copy.
    875 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, ActivateApp) {
    876   TabStripModel* tab_strip = browser()->tab_strip_model();
    877   int tab_count = tab_strip->count();
    878   const Extension* extension =
    879       LoadExtension(test_data_dir_.AppendASCII("app1"));
    880 
    881   ChromeLauncherController::instance()->ActivateApp(extension->id(), 0);
    882   EXPECT_EQ(++tab_count, tab_strip->count());
    883   ChromeLauncherController::instance()->ActivateApp(extension->id(), 0);
    884   EXPECT_EQ(tab_count, tab_strip->count());
    885 }
    886 
    887 // Launching the same app multiple times should launch a copy for each call.
    888 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, LaunchApp) {
    889   TabStripModel* tab_strip = browser()->tab_strip_model();
    890   int tab_count = tab_strip->count();
    891   const Extension* extension =
    892       LoadExtension(test_data_dir_.AppendASCII("app1"));
    893 
    894   ChromeLauncherController::instance()->LaunchApp(extension->id(), 0);
    895   EXPECT_EQ(++tab_count, tab_strip->count());
    896   ChromeLauncherController::instance()->LaunchApp(extension->id(), 0);
    897   EXPECT_EQ(++tab_count, tab_strip->count());
    898 }
    899 
    900 // Launch 2 apps and toggle which is active.
    901 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, MultipleApps) {
    902   int item_count = model_->item_count();
    903   TabStripModel* tab_strip = browser()->tab_strip_model();
    904   int tab_count = tab_strip->count();
    905   ash::LauncherID shortcut1 = CreateShortcut("app1");
    906   EXPECT_EQ(++item_count, model_->item_count());
    907   ash::LauncherID shortcut2 = CreateShortcut("app2");
    908   EXPECT_EQ(++item_count, model_->item_count());
    909 
    910   // Launch first app.
    911   ActivateLauncherItem(model_->ItemIndexByID(shortcut1));
    912   EXPECT_EQ(++tab_count, tab_strip->count());
    913   WebContents* tab1 = tab_strip->GetActiveWebContents();
    914   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut1)).status);
    915 
    916   // Launch second app.
    917   ActivateLauncherItem(model_->ItemIndexByID(shortcut2));
    918   EXPECT_EQ(++tab_count, tab_strip->count());
    919   WebContents* tab2 = tab_strip->GetActiveWebContents();
    920   ASSERT_NE(tab1, tab2);
    921   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut1)).status);
    922   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut2)).status);
    923 
    924   // Reactivate first app.
    925   ActivateLauncherItem(model_->ItemIndexByID(shortcut1));
    926   EXPECT_EQ(tab_count, tab_strip->count());
    927   EXPECT_EQ(tab_strip->GetActiveWebContents(), tab1);
    928   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut1)).status);
    929   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut2)).status);
    930 
    931   // Open second tab for second app. This should activate it.
    932   ui_test_utils::NavigateToURLWithDisposition(
    933       browser(),
    934       GURL("http://www.example.com/path3/foo.html"),
    935       NEW_FOREGROUND_TAB,
    936       0);
    937   EXPECT_EQ(++tab_count, tab_strip->count());
    938   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut1)).status);
    939   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut2)).status);
    940 
    941   // Reactivate first app.
    942   ActivateLauncherItem(model_->ItemIndexByID(shortcut1));
    943   EXPECT_EQ(tab_count, tab_strip->count());
    944   EXPECT_EQ(tab_strip->GetActiveWebContents(), tab1);
    945   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut1)).status);
    946   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut2)).status);
    947 
    948   // And second again. This time the second tab should become active.
    949   ActivateLauncherItem(model_->ItemIndexByID(shortcut2));
    950   EXPECT_EQ(tab_count, tab_strip->count());
    951   EXPECT_EQ(tab_strip->GetActiveWebContents(), tab2);
    952   EXPECT_EQ(ash::STATUS_RUNNING, (*model_->ItemByID(shortcut1)).status);
    953   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut2)).status);
    954 }
    955 
    956 // Confirm that a page can be navigated from and to while maintaining the
    957 // correct running state.
    958 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, Navigation) {
    959   ash::LauncherID shortcut_id = CreateShortcut("app1");
    960   EXPECT_EQ(ash::STATUS_CLOSED, (*model_->ItemByID(shortcut_id)).status);
    961   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
    962   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    963 
    964   // Navigate away.
    965   ui_test_utils::NavigateToURL(
    966       browser(), GURL("http://www.example.com/path0/bar.html"));
    967   EXPECT_EQ(ash::STATUS_CLOSED, (*model_->ItemByID(shortcut_id)).status);
    968 
    969   // Navigate back.
    970   ui_test_utils::NavigateToURL(
    971       browser(), GURL("http://www.example.com/path1/foo.html"));
    972   EXPECT_EQ(ash::STATUS_ACTIVE, (*model_->ItemByID(shortcut_id)).status);
    973 }
    974 
    975 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, MultipleOwnedTabs) {
    976   TabStripModel* tab_strip = browser()->tab_strip_model();
    977   int tab_count = tab_strip->count();
    978   ash::LauncherID shortcut_id = CreateShortcut("app1");
    979   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
    980   EXPECT_EQ(++tab_count, tab_strip->count());
    981   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
    982   WebContents* first_tab = tab_strip->GetActiveWebContents();
    983 
    984   // Create new tab owned by app.
    985   ui_test_utils::NavigateToURLWithDisposition(
    986       browser(),
    987       GURL("http://www.example.com/path2/bar.html"),
    988       NEW_FOREGROUND_TAB,
    989       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    990   EXPECT_EQ(++tab_count, tab_strip->count());
    991   // Confirm app is still active.
    992   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
    993 
    994   // Create new tab not owned by app.
    995   ui_test_utils::NavigateToURLWithDisposition(
    996       browser(),
    997       GURL("http://www.example.com/path3/foo.html"),
    998       NEW_FOREGROUND_TAB,
    999       0);
   1000   EXPECT_EQ(++tab_count, tab_strip->count());
   1001   // No longer active.
   1002   EXPECT_EQ(ash::STATUS_RUNNING, model_->ItemByID(shortcut_id)->status);
   1003 
   1004   // Activating app makes first tab active again.
   1005   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
   1006   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1007   EXPECT_EQ(tab_strip->GetActiveWebContents(), first_tab);
   1008 }
   1009 
   1010 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, RefocusFilter) {
   1011   ChromeLauncherController* controller =
   1012       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1013   TabStripModel* tab_strip = browser()->tab_strip_model();
   1014   int tab_count = tab_strip->count();
   1015   ash::LauncherID shortcut_id = CreateShortcut("app1");
   1016   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
   1017   EXPECT_EQ(++tab_count, tab_strip->count());
   1018   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1019   WebContents* first_tab = tab_strip->GetActiveWebContents();
   1020 
   1021   controller->SetRefocusURLPatternForTest(
   1022       shortcut_id, GURL("http://www.example.com/path1/*"));
   1023   // Create new tab owned by app.
   1024   ui_test_utils::NavigateToURLWithDisposition(
   1025       browser(),
   1026       GURL("http://www.example.com/path2/bar.html"),
   1027       NEW_FOREGROUND_TAB,
   1028       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1029   EXPECT_EQ(++tab_count, tab_strip->count());
   1030   // Confirm app is still active.
   1031   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1032 
   1033   // Create new tab not owned by app.
   1034   ui_test_utils::NavigateToURLWithDisposition(
   1035       browser(),
   1036       GURL("http://www.example.com/path3/foo.html"),
   1037       NEW_FOREGROUND_TAB,
   1038       0);
   1039   EXPECT_EQ(++tab_count, tab_strip->count());
   1040   // No longer active.
   1041   EXPECT_EQ(ash::STATUS_RUNNING, model_->ItemByID(shortcut_id)->status);
   1042 
   1043   // Activating app makes first tab active again, because second tab isn't
   1044   // in its refocus url path.
   1045   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
   1046   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1047   EXPECT_EQ(tab_strip->GetActiveWebContents(), first_tab);
   1048 }
   1049 
   1050 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, RefocusFilterLaunch) {
   1051   ChromeLauncherController* controller =
   1052       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1053   TabStripModel* tab_strip = browser()->tab_strip_model();
   1054   int tab_count = tab_strip->count();
   1055   ash::LauncherID shortcut_id = CreateShortcut("app1");
   1056   controller->SetRefocusURLPatternForTest(
   1057       shortcut_id, GURL("http://www.example.com/path1/*"));
   1058 
   1059   // Create new tab.
   1060   ui_test_utils::NavigateToURLWithDisposition(
   1061       browser(),
   1062       GURL("http://www.example2.com/path2/bar.html"),
   1063       NEW_FOREGROUND_TAB,
   1064       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1065   EXPECT_EQ(++tab_count, tab_strip->count());
   1066   WebContents* first_tab = tab_strip->GetActiveWebContents();
   1067   // Confirm app is not active.
   1068   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1069 
   1070   // Activating app should launch new tab, because second tab isn't
   1071   // in its refocus url path.
   1072   ActivateLauncherItem(model_->ItemIndexByID(shortcut_id));
   1073   EXPECT_EQ(++tab_count, tab_strip->count());
   1074   WebContents* second_tab = tab_strip->GetActiveWebContents();
   1075   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1076   EXPECT_NE(first_tab, second_tab);
   1077   EXPECT_EQ(tab_strip->GetActiveWebContents(), second_tab);
   1078 }
   1079 
   1080 // Check the launcher activation state for applications and browser.
   1081 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, ActivationStateCheck) {
   1082   ChromeLauncherController* controller =
   1083       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1084   TabStripModel* tab_strip = browser()->tab_strip_model();
   1085   // Get the browser item index
   1086   int browser_index = ash::launcher::GetBrowserItemIndex(*controller->model());
   1087   EXPECT_TRUE(browser_index >= 0);
   1088 
   1089   // Even though we are just comming up, the browser should be active.
   1090   EXPECT_EQ(ash::STATUS_ACTIVE, model_->items()[browser_index].status);
   1091 
   1092   ash::LauncherID shortcut_id = CreateShortcut("app1");
   1093   controller->SetRefocusURLPatternForTest(
   1094       shortcut_id, GURL("http://www.example.com/path1/*"));
   1095 
   1096   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1097   EXPECT_EQ(ash::STATUS_ACTIVE, model_->items()[browser_index].status);
   1098 
   1099   // Create new tab which would be the running app.
   1100   ui_test_utils::NavigateToURLWithDisposition(
   1101       browser(),
   1102       GURL("http://www.example.com/path1/bar.html"),
   1103       NEW_FOREGROUND_TAB,
   1104       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1105 
   1106   // There should never be two items active at the same time.
   1107   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1108   EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[browser_index].status);
   1109 
   1110   tab_strip->ActivateTabAt(0, false);
   1111   EXPECT_EQ(ash::STATUS_RUNNING, model_->ItemByID(shortcut_id)->status);
   1112   EXPECT_EQ(ash::STATUS_ACTIVE, model_->items()[browser_index].status);
   1113 
   1114   tab_strip->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
   1115   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1116   EXPECT_EQ(ash::STATUS_ACTIVE, model_->items()[browser_index].status);
   1117 
   1118   ash::wm::DeactivateWindow(browser()->window()->GetNativeWindow());
   1119   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1120   EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[browser_index].status);
   1121 }
   1122 
   1123 // Check that the launcher activation state for a V1 application stays closed
   1124 // even after an asynchronous browser event comes in after the tab got
   1125 // destroyed.
   1126 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest,
   1127                        AsyncActivationStateCheck) {
   1128   ChromeLauncherController* controller =
   1129       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1130   TabStripModel* tab_strip = browser()->tab_strip_model();
   1131 
   1132   ash::LauncherID shortcut_id = CreateShortcut("app1");
   1133   controller->SetRefocusURLPatternForTest(
   1134       shortcut_id, GURL("http://www.example.com/path1/*"));
   1135 
   1136   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1137 
   1138   // Create new tab which would be the running app.
   1139   ui_test_utils::NavigateToURLWithDisposition(
   1140       browser(),
   1141       GURL("http://www.example.com/path1/bar.html"),
   1142       NEW_FOREGROUND_TAB,
   1143       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1144 
   1145   EXPECT_EQ(ash::STATUS_ACTIVE, model_->ItemByID(shortcut_id)->status);
   1146   // To address the issue of crbug.com/174050, the tab we are about to close
   1147   // has to be active.
   1148   tab_strip->ActivateTabAt(1, false);
   1149   EXPECT_EQ(1, tab_strip->active_index());
   1150 
   1151   // Close the web contents.
   1152   tab_strip->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
   1153   // The status should now be set to closed.
   1154   EXPECT_EQ(ash::STATUS_CLOSED, model_->ItemByID(shortcut_id)->status);
   1155 }
   1156 
   1157 // Checks that a windowed application does not add an item to the browser list.
   1158 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTestNoDefaultBrowser,
   1159     WindowedAppDoesNotAddToBrowser) {
   1160   // Get the number of items in the browser menu.
   1161   size_t items = NumberOfDetectedLauncherBrowsers(false);
   1162   size_t running_browser = chrome::GetTotalBrowserCount();
   1163   EXPECT_EQ(0u, items);
   1164   EXPECT_EQ(0u, running_browser);
   1165 
   1166   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_WINDOW, NEW_WINDOW);
   1167 
   1168   // No new browser should get detected, even though one more is running.
   1169   EXPECT_EQ(0u, NumberOfDetectedLauncherBrowsers(false));
   1170   EXPECT_EQ(++running_browser, chrome::GetTotalBrowserCount());
   1171 
   1172   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB, NEW_WINDOW);
   1173 
   1174   // A new browser should get detected and one more should be running.
   1175   EXPECT_EQ(NumberOfDetectedLauncherBrowsers(false), 1u);
   1176   EXPECT_EQ(++running_browser, chrome::GetTotalBrowserCount());
   1177 }
   1178 
   1179 // Checks the functionality to enumerate all browsers vs. all tabs.
   1180 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTestNoDefaultBrowser,
   1181     EnumerateALlBrowsersAndTabs) {
   1182   // Create at least one browser.
   1183   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB, NEW_WINDOW);
   1184   size_t browsers = NumberOfDetectedLauncherBrowsers(false);
   1185   size_t tabs = NumberOfDetectedLauncherBrowsers(true);
   1186 
   1187   // Create a second browser.
   1188   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB, NEW_WINDOW);
   1189 
   1190   EXPECT_EQ(++browsers, NumberOfDetectedLauncherBrowsers(false));
   1191   EXPECT_EQ(++tabs, NumberOfDetectedLauncherBrowsers(true));
   1192 
   1193   // Create only a tab.
   1194   LoadAndLaunchExtension("app1",
   1195                          extension_misc::LAUNCH_TAB,
   1196                          NEW_FOREGROUND_TAB);
   1197 
   1198   EXPECT_EQ(browsers, NumberOfDetectedLauncherBrowsers(false));
   1199   EXPECT_EQ(++tabs, NumberOfDetectedLauncherBrowsers(true));
   1200 }
   1201 
   1202 // Check that the keyboard activation of a launcher item tabs properly through
   1203 // the items at hand.
   1204 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, AltNumberTabsTabbing) {
   1205   TabStripModel* tab_strip = browser()->tab_strip_model();
   1206   ChromeLauncherController* controller =
   1207       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1208 
   1209   ash::LauncherID shortcut_id = CreateShortcut("app");
   1210   controller->SetRefocusURLPatternForTest(
   1211       shortcut_id, GURL("http://www.example.com/path/*"));
   1212   std::string url = "http://www.example.com/path/bla";
   1213 
   1214   int shortcut_index = model_->ItemIndexByID(shortcut_id);
   1215 
   1216   // Create an application handled browser tab.
   1217   ui_test_utils::NavigateToURLWithDisposition(
   1218       browser(),
   1219       GURL(url),
   1220       NEW_FOREGROUND_TAB,
   1221       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1222 
   1223   content::WebContents* content1 = tab_strip->GetActiveWebContents();
   1224 
   1225   // Create some other browser tab.
   1226   ui_test_utils::NavigateToURLWithDisposition(
   1227       browser(),
   1228       GURL("http://www.test.com"),
   1229       NEW_FOREGROUND_TAB,
   1230       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1231   content::WebContents* content1a = tab_strip->GetActiveWebContents();
   1232 
   1233   // Make sure that the active tab is now our handled tab.
   1234   EXPECT_NE(content1a, content1);
   1235 
   1236   // The active tab should still be the unnamed tab. Then we switch and reach
   1237   // the first app and stay there.
   1238   EXPECT_EQ(content1a, tab_strip->GetActiveWebContents());
   1239   ActivateLauncherItem(shortcut_index);
   1240   EXPECT_EQ(content1, tab_strip->GetActiveWebContents());
   1241   ActivateLauncherItem(shortcut_index);
   1242   EXPECT_EQ(content1, tab_strip->GetActiveWebContents());
   1243 
   1244   ui_test_utils::NavigateToURLWithDisposition(
   1245       browser(),
   1246       GURL(url),
   1247       NEW_FOREGROUND_TAB,
   1248       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1249   content::WebContents* content2 = tab_strip->GetActiveWebContents();
   1250 
   1251   EXPECT_EQ(content2, browser()->tab_strip_model()->GetActiveWebContents());
   1252   ActivateLauncherItem(shortcut_index);
   1253   EXPECT_EQ(content1, browser()->tab_strip_model()->GetActiveWebContents());
   1254   ActivateLauncherItem(shortcut_index);
   1255   EXPECT_EQ(content2, browser()->tab_strip_model()->GetActiveWebContents());
   1256 }
   1257 
   1258 // Check that the keyboard activation of a launcher item tabs properly through
   1259 // the items at hand.
   1260 IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest,
   1261                        AltNumberAppsTabbing) {
   1262   // First run app.
   1263   const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
   1264   ui::BaseWindow* window1 = CreateShellWindow(extension1)->GetBaseWindow();
   1265   const ash::LauncherItem& item1 = GetLastLauncherItem();
   1266   ash::LauncherID app_id = item1.id;
   1267   int app_index = launcher_model()->ItemIndexByID(app_id);
   1268 
   1269   EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
   1270   EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
   1271 
   1272   const Extension* extension2 = LoadAndLaunchPlatformApp("launch_2");
   1273   ui::BaseWindow* window2 = CreateShellWindow(extension2)->GetBaseWindow();
   1274 
   1275   // By now the browser should be active. Issue Alt keystrokes several times to
   1276   // see that we stay on that application.
   1277   EXPECT_TRUE(window2->IsActive());
   1278   ActivateLauncherItem(app_index);
   1279   EXPECT_TRUE(window1->IsActive());
   1280   ActivateLauncherItem(app_index);
   1281   EXPECT_TRUE(window1->IsActive());
   1282 
   1283   ui::BaseWindow* window1a = CreateShellWindow(extension1)->GetBaseWindow();
   1284 
   1285   EXPECT_TRUE(window1a->IsActive());
   1286   EXPECT_FALSE(window1->IsActive());
   1287   ActivateLauncherItem(app_index);
   1288   EXPECT_TRUE(window1->IsActive());
   1289   ActivateLauncherItem(app_index);
   1290   EXPECT_TRUE(window1a->IsActive());
   1291 }
   1292 
   1293 // Checks that the browser Alt "tabbing" is properly done.
   1294 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTestNoDefaultBrowser,
   1295     AltNumberBrowserTabbing) {
   1296   // Get the number of items in the browser menu.
   1297   EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
   1298   // The first activation should create a browser.
   1299   launcher_->ActivateLauncherItem(0);
   1300   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
   1301   // A second activation should not create a new instance.
   1302   launcher_->ActivateLauncherItem(0);
   1303   Browser* browser1 = chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
   1304   EXPECT_TRUE(browser1);
   1305   aura::Window* window1 = browser1->window()->GetNativeWindow();
   1306   Browser* browser2 = CreateBrowser(profile());
   1307   aura::Window* window2 = browser2->window()->GetNativeWindow();
   1308 
   1309   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   1310   EXPECT_NE(window1, window2);
   1311   EXPECT_EQ(window2, ash::wm::GetActiveWindow());
   1312 
   1313   // Activate multiple times the switcher to see that the windows get activated.
   1314   launcher_->ActivateLauncherItem(0);
   1315   EXPECT_EQ(window1, ash::wm::GetActiveWindow());
   1316   launcher_->ActivateLauncherItem(0);
   1317   EXPECT_EQ(window2, ash::wm::GetActiveWindow());
   1318 
   1319   // Create a third browser - make sure that we do not toggle simply between
   1320   // two windows.
   1321   Browser* browser3 = CreateBrowser(profile());
   1322   aura::Window* window3 = browser3->window()->GetNativeWindow();
   1323 
   1324   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
   1325   EXPECT_NE(window1, window3);
   1326   EXPECT_NE(window2, window3);
   1327   EXPECT_EQ(window3, ash::wm::GetActiveWindow());
   1328 
   1329   launcher_->ActivateLauncherItem(0);
   1330   EXPECT_EQ(window1, ash::wm::GetActiveWindow());
   1331   launcher_->ActivateLauncherItem(0);
   1332   EXPECT_EQ(window2, ash::wm::GetActiveWindow());
   1333   launcher_->ActivateLauncherItem(0);
   1334   EXPECT_EQ(window3, ash::wm::GetActiveWindow());
   1335   launcher_->ActivateLauncherItem(0);
   1336   EXPECT_EQ(window1, ash::wm::GetActiveWindow());
   1337 
   1338   // Create anther app and make sure that none of our browsers is active.
   1339   LoadAndLaunchExtension("app1", extension_misc::LAUNCH_TAB, NEW_WINDOW);
   1340   EXPECT_NE(window1, ash::wm::GetActiveWindow());
   1341   EXPECT_NE(window2, ash::wm::GetActiveWindow());
   1342 
   1343   // After activation our browser should be active again.
   1344   launcher_->ActivateLauncherItem(0);
   1345   EXPECT_EQ(window1, ash::wm::GetActiveWindow());
   1346 }
   1347 
   1348 // Checks that after a session restore, we do not start applications on an
   1349 // activation.
   1350 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest,
   1351     ActivateAfterSessionRestore) {
   1352   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
   1353 
   1354   // Create a known application.
   1355   ChromeLauncherController* controller =
   1356       static_cast<ChromeLauncherController*>(launcher_->delegate());
   1357   ash::LauncherID shortcut_id = CreateShortcut("app1");
   1358 
   1359   // Create a new browser - without activating it - and load an "app" into it.
   1360   Browser::CreateParams params =
   1361       Browser::CreateParams(profile(), chrome::GetActiveDesktop());
   1362   params.initial_show_state = ui::SHOW_STATE_INACTIVE;
   1363   Browser* browser2 = new Browser(params);
   1364   controller->SetRefocusURLPatternForTest(
   1365       shortcut_id, GURL("http://www.example.com/path/*"));
   1366   std::string url = "http://www.example.com/path/bla";
   1367   ui_test_utils::NavigateToURLWithDisposition(
   1368       browser2,
   1369       GURL(url),
   1370       NEW_FOREGROUND_TAB,
   1371       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1372 
   1373   // Remember the number of tabs for each browser.
   1374   TabStripModel* tab_strip = browser()->tab_strip_model();
   1375   int tab_count1 = tab_strip->count();
   1376   TabStripModel* tab_strip2 = browser2->tab_strip_model();
   1377   int tab_count2 = tab_strip2->count();
   1378 
   1379   // Check that we have two browsers and the inactive browser remained inactive.
   1380   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   1381   EXPECT_EQ(chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()),
   1382             browser());
   1383   // Check that the LRU browser list does only contain the original browser.
   1384   BrowserList* ash_browser_list =
   1385       BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
   1386   BrowserList::const_reverse_iterator it =
   1387       ash_browser_list->begin_last_active();
   1388   EXPECT_EQ(*it, browser());
   1389   ++it;
   1390   EXPECT_EQ(it, ash_browser_list->end_last_active());
   1391 
   1392   // Now request to either activate an existing app or create a new one.
   1393   controller->ItemSelected(*model_->ItemByID(shortcut_id),
   1394                            ui::KeyEvent(ui::ET_KEY_RELEASED,
   1395                                         ui::VKEY_RETURN,
   1396                                         0,
   1397                                         false));
   1398 
   1399   // Check that we have set focus on the existing application and nothing new
   1400   // was created.
   1401   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   1402   EXPECT_EQ(tab_count1, tab_strip->count());
   1403   EXPECT_EQ(tab_count2, tab_strip2->count());
   1404   EXPECT_EQ(chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()),
   1405             browser2);
   1406 }
   1407 
   1408 // Do various drag and drop interaction tests between the application list and
   1409 // the launcher.
   1410 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, DragAndDrop) {
   1411   // Get a number of interfaces we need.
   1412   aura::test::EventGenerator generator(
   1413       ash::Shell::GetPrimaryRootWindow(), gfx::Point());
   1414   ash::test::LauncherViewTestAPI test(launcher_->GetLauncherViewForTest());
   1415   AppListService* service = AppListService::Get();
   1416 
   1417   // There should be two items in our launcher by this time.
   1418   EXPECT_EQ(2, model_->item_count());
   1419   EXPECT_FALSE(service->IsAppListVisible());
   1420 
   1421   // Open the app list menu and check that the drag and drop host was set.
   1422   gfx::Rect app_list_bounds =
   1423       test.launcher_view()->GetAppListButtonView()->GetBoundsInScreen();
   1424   generator.MoveMouseTo(app_list_bounds.CenterPoint().x(),
   1425                         app_list_bounds.CenterPoint().y());
   1426   base::MessageLoop::current()->RunUntilIdle();
   1427   generator.ClickLeftButton();
   1428 
   1429   EXPECT_TRUE(service->IsAppListVisible());
   1430   app_list::AppsGridView* grid_view =
   1431       app_list::AppsGridView::GetLastGridViewForTest();
   1432   ASSERT_TRUE(grid_view);
   1433   ASSERT_TRUE(grid_view->has_drag_and_drop_host_for_test());
   1434 
   1435   // There should be 2 items in our application list.
   1436   const views::ViewModel* vm_grid = grid_view->view_model_for_test();
   1437   EXPECT_EQ(2, vm_grid->view_size());
   1438 
   1439   // Test #1: Drag an app list which does not exist yet item into the
   1440   // launcher. Keeping it dragged, see that a new item gets created. Continuing
   1441   // to drag it out should remove it again.
   1442 
   1443   // Get over item #1 of the application list and press the mouse button.
   1444   views::View* item1 = vm_grid->view_at(1);
   1445   gfx::Rect bounds_grid_1 = item1->GetBoundsInScreen();
   1446   generator.MoveMouseTo(bounds_grid_1.CenterPoint().x(),
   1447                         bounds_grid_1.CenterPoint().y());
   1448   base::MessageLoop::current()->RunUntilIdle();
   1449   generator.PressLeftButton();
   1450 
   1451   EXPECT_FALSE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1452 
   1453   // Drag the item into the launcher and check that a new item gets created.
   1454   const views::ViewModel* vm_launcher =
   1455       test.launcher_view()->view_model_for_test();
   1456   views::View* launcher1 = vm_launcher->view_at(1);
   1457   gfx::Rect bounds_launcher_1 = launcher1->GetBoundsInScreen();
   1458   generator.MoveMouseTo(bounds_launcher_1.CenterPoint().x(),
   1459                         bounds_launcher_1.CenterPoint().y());
   1460   base::MessageLoop::current()->RunUntilIdle();
   1461 
   1462   // Check that a new item got created.
   1463   EXPECT_EQ(3, model_->item_count());
   1464   EXPECT_TRUE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1465 
   1466   // Move it where the item originally was and check that it disappears again.
   1467   generator.MoveMouseTo(bounds_grid_1.CenterPoint().x(),
   1468                         bounds_grid_1.CenterPoint().y());
   1469   base::MessageLoop::current()->RunUntilIdle();
   1470   EXPECT_EQ(2, model_->item_count());
   1471   EXPECT_FALSE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1472 
   1473   // Dropping it should keep the launcher as it originally was.
   1474   generator.ReleaseLeftButton();
   1475   base::MessageLoop::current()->RunUntilIdle();
   1476   EXPECT_EQ(2, model_->item_count());
   1477   // There are a few animations which need finishing before we can continue.
   1478   test.RunMessageLoopUntilAnimationsDone();
   1479   // Move the mouse outside of the launcher.
   1480   generator.MoveMouseTo(0, 0);
   1481 
   1482   // Test #2: Check that the unknown item dropped into the launcher will
   1483   // create a new item.
   1484   generator.MoveMouseTo(bounds_grid_1.CenterPoint().x(),
   1485                         bounds_grid_1.CenterPoint().y());
   1486   generator.PressLeftButton();
   1487   generator.MoveMouseTo(bounds_launcher_1.CenterPoint().x(),
   1488                         bounds_launcher_1.CenterPoint().y());
   1489   base::MessageLoop::current()->RunUntilIdle();
   1490   EXPECT_EQ(3, model_->item_count());
   1491   EXPECT_TRUE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1492   generator.ReleaseLeftButton();
   1493   base::MessageLoop::current()->RunUntilIdle();
   1494   EXPECT_FALSE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1495   EXPECT_EQ(3, model_->item_count());  // It should be still there.
   1496   test.RunMessageLoopUntilAnimationsDone();
   1497 
   1498   // Test #3: Check that the now known item dropped into the launcher will
   1499   // not create a new item.
   1500   generator.MoveMouseTo(bounds_grid_1.CenterPoint().x(),
   1501                         bounds_grid_1.CenterPoint().y());
   1502   generator.PressLeftButton();
   1503   generator.MoveMouseTo(bounds_launcher_1.CenterPoint().x(),
   1504                         bounds_launcher_1.CenterPoint().y());
   1505   base::MessageLoop::current()->RunUntilIdle();
   1506   EXPECT_EQ(3, model_->item_count());  // No new item got added.
   1507   EXPECT_TRUE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1508   generator.ReleaseLeftButton();
   1509   base::MessageLoop::current()->RunUntilIdle();
   1510   EXPECT_FALSE(grid_view->forward_events_to_drag_and_drop_host_for_test());
   1511   EXPECT_EQ(3, model_->item_count());  // And it remains that way.
   1512 }
   1513 
   1514 // Check that clicking on an app launcher item launches a new browser.
   1515 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTest, ClickItem) {
   1516   // Get a number of interfaces we need.
   1517   aura::test::EventGenerator generator(
   1518       ash::Shell::GetPrimaryRootWindow(), gfx::Point());
   1519   ash::test::LauncherViewTestAPI test(launcher_->GetLauncherViewForTest());
   1520   AppListService* service = AppListService::Get();
   1521   // There should be two items in our launcher by this time.
   1522   EXPECT_EQ(2, model_->item_count());
   1523   EXPECT_FALSE(service->IsAppListVisible());
   1524 
   1525   // Open the app list menu and check that the drag and drop host was set.
   1526   gfx::Rect app_list_bounds =
   1527       test.launcher_view()->GetAppListButtonView()->GetBoundsInScreen();
   1528   generator.MoveMouseTo(app_list_bounds.CenterPoint().x(),
   1529                         app_list_bounds.CenterPoint().y());
   1530   generator.ClickLeftButton();
   1531   base::MessageLoop::current()->RunUntilIdle();
   1532 
   1533   EXPECT_TRUE(service->IsAppListVisible());
   1534   app_list::AppsGridView* grid_view =
   1535       app_list::AppsGridView::GetLastGridViewForTest();
   1536   ASSERT_TRUE(grid_view);
   1537   const views::ViewModel* vm_grid = grid_view->view_model_for_test();
   1538   EXPECT_EQ(2, vm_grid->view_size());
   1539   gfx::Rect bounds_grid_1 = vm_grid->view_at(1)->GetBoundsInScreen();
   1540   // Test now that a click does create a new application tab.
   1541   TabStripModel* tab_strip = browser()->tab_strip_model();
   1542   int tab_count = tab_strip->count();
   1543   generator.MoveMouseTo(bounds_grid_1.CenterPoint().x(),
   1544                         bounds_grid_1.CenterPoint().y());
   1545   generator.ClickLeftButton();
   1546   base::MessageLoop::current()->RunUntilIdle();
   1547   EXPECT_EQ(tab_count + 1, tab_strip->count());
   1548 }
   1549 
   1550 // Check LauncherItemController of Browser Shortcut functionality.
   1551 IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserTestNoDefaultBrowser,
   1552     BrowserShortcutLauncherItemController) {
   1553   ChromeLauncherControllerPerApp* controller =
   1554       static_cast<ChromeLauncherControllerPerApp*>(launcher_->delegate());
   1555   LauncherItemController* item_controller =
   1556       controller->GetBrowserShortcutLauncherItemController();
   1557 
   1558   // Get the number of browsers.
   1559   size_t running_browser = chrome::GetTotalBrowserCount();
   1560   EXPECT_EQ(0u, running_browser);
   1561   EXPECT_FALSE(item_controller->IsOpen());
   1562 
   1563   // Activate. This creates new browser
   1564   item_controller->Activate();
   1565   // New Window is created.
   1566   running_browser = chrome::GetTotalBrowserCount();
   1567   EXPECT_EQ(1u, running_browser);
   1568   EXPECT_TRUE(item_controller->IsOpen());
   1569 
   1570   // Minimize Window.
   1571   aura::Window* window = ash::wm::GetActiveWindow();
   1572   ash::wm::MinimizeWindow(window);
   1573   EXPECT_TRUE(ash::wm::IsWindowMinimized(window));
   1574 
   1575   // Activate again. This doesn't create new browser.
   1576   // It activates window.
   1577   item_controller->Activate();
   1578   running_browser = chrome::GetTotalBrowserCount();
   1579   EXPECT_EQ(1u, running_browser);
   1580   EXPECT_TRUE(item_controller->IsOpen());
   1581   EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
   1582 }
   1583