browser_shortcut_launcher_item_controller.cc revision f2477e01787aa58f445919b809d89e252beef54f
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <vector>
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/launcher/launcher.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_model.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_util.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/shell.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/wm/window_util.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/web_contents.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "grit/ash_resources.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "grit/chromium_strings.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "grit/generated_resources.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/window.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/image/image.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/corewm/window_animations.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController(
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ChromeLauncherController* launcher_controller)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : LauncherItemController(TYPE_SHORTCUT,
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             extension_misc::kChromeAppId,
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             launcher_controller) {
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochBrowserShortcutLauncherItemController::
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ~BrowserShortcutLauncherItemController() {
52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BrowserShortcutLauncherItemController::UpdateBrowserItemState() {
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The shell will not be available for win7_aura unittests like
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // ChromeLauncherControllerTest.BrowserMenuGeneration.
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ash::Shell::HasInstance())
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ash::ShelfModel* model = launcher_controller()->model();
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Determine the new browser's active state and change if necessary.
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int browser_index = model->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(browser_index, 0);
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ash::LauncherItem browser_item = model->items()[browser_index];
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ash::LauncherItemStatus browser_status = ash::STATUS_CLOSED;
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  aura::Window* window = ash::wm::GetActiveWindow();
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (window) {
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Check if the active browser / tab is a browser which is not an app,
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // a windowed app, a popup or any other item which is not a browser of
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // interest.
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Browser* browser = chrome::FindBrowserWithWindow(window);
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (IsBrowserRepresentedInBrowserList(browser)) {
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      browser_status = ash::STATUS_ACTIVE;
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // If an app that has item is running in active WebContents, browser item
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // status cannot be active.
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::WebContents* contents =
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          browser->tab_strip_model()->GetActiveWebContents();
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (contents &&
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          (launcher_controller()->GetLauncherIDForWebContents(contents) !=
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              browser_item.id))
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        browser_status = ash::STATUS_RUNNING;
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (browser_status == ash::STATUS_CLOSED) {
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const BrowserList* ash_browser_list =
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (BrowserList::const_reverse_iterator it =
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             ash_browser_list->begin_last_active();
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         it != ash_browser_list->end_last_active() &&
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         browser_status == ash::STATUS_CLOSED; ++it) {
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (IsBrowserRepresentedInBrowserList(*it))
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        browser_status = ash::STATUS_RUNNING;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (browser_status != browser_item.status) {
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    browser_item.status = browser_status;
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    model->Set(browser_index, browser_item);
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsOpen() const {
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const BrowserList* ash_browser_list =
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (BrowserList::const_iterator it = ash_browser_list->begin();
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       it != ash_browser_list->end(); ++it) {
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (launcher_controller()->IsBrowserFromActiveUser(*it))
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return true;
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return false;
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsVisible() const {
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Browser* last_browser = chrome::FindTabbedBrowser(
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      launcher_controller()->profile(),
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      true,
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::HOST_DESKTOP_TYPE_ASH);
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!last_browser) {
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  aura::Window* window = last_browser->window()->GetNativeWindow();
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ash::wm::IsActiveWindow(window);
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void BrowserShortcutLauncherItemController::Launch(ash::LaunchSource source,
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                   int event_flags) {
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BrowserShortcutLauncherItemController::Activate(ash::LaunchSource source) {
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Browser* last_browser = chrome::FindTabbedBrowser(
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      launcher_controller()->profile(),
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      true,
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::HOST_DESKTOP_TYPE_ASH);
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!last_browser) {
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    launcher_controller()->CreateNewWindow();
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  launcher_controller()->ActivateWindowOrMinimizeIfActive(
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      last_browser->window(), GetApplicationList(0).size() == 2);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserShortcutLauncherItemController::Close() {
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ChromeLauncherAppMenuItems
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) {
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ChromeLauncherAppMenuItems items;
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool found_tabbed_browser = false;
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Add the application name to the menu.
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false));
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const BrowserList* ash_browser_list =
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BrowserList::const_iterator it = ash_browser_list->begin();
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != ash_browser_list->end(); ++it) {
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Browser* browser = *it;
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Make sure that the browser was already shown, is from the current user
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // and has a proper window.
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!launcher_controller()->IsBrowserFromActiveUser(browser) ||
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        std::find(ash_browser_list->begin_last_active(),
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  ash_browser_list->end_last_active(),
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  browser) == ash_browser_list->end_last_active() ||
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        !browser->window())
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      continue;
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (browser->is_type_tabbed())
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      found_tabbed_browser = true;
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    else if (!IsBrowserRepresentedInBrowserList(browser))
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      continue;
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TabStripModel* tab_strip = browser->tab_strip_model();
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (tab_strip->active_index() == -1)
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      continue;
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!(event_flags & ui::EF_SHIFT_DOWN)) {
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::WebContents* web_contents =
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          tab_strip->GetWebContentsAt(tab_strip->active_index());
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Image app_icon = GetBrowserListIcon(web_contents);
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      string16 title = GetBrowserListTitle(web_contents);
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      items.push_back(new ChromeLauncherAppMenuItemBrowser(
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          title, &app_icon, browser, items.size() == 1));
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      for (int index = 0; index  < tab_strip->count(); ++index) {
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        content::WebContents* web_contents =
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            tab_strip->GetWebContentsAt(index);
1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        gfx::Image app_icon =
1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            launcher_controller()->GetAppListIcon(web_contents);
1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        string16 title = launcher_controller()->GetAppListTitle(web_contents);
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // Check if we need to insert a separator in front.
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        bool leading_separator = !index;
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        items.push_back(new ChromeLauncherAppMenuItemTab(
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            title, &app_icon, web_contents, leading_separator));
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If only windowed applications are open, we return an empty list to
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // enforce the creation of a new browser.
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!found_tabbed_browser)
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    items.clear();
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return items.Pass();
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BrowserShortcutLauncherItemController::ItemSelected(
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ui::Event& event) {
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_CHROMEOS)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  chromeos::default_pinned_apps_field_trial::RecordShelfClick(
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      chromeos::default_pinned_apps_field_trial::CHROME);
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (event.flags() & ui::EF_CONTROL_DOWN) {
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    launcher_controller()->CreateNewWindow();
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // In case of a keyboard event, we were called by a hotkey. In that case we
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // activate the next item in line if an item of our list is already active.
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (event.type() & ui::ET_KEY_RELEASED) {
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ActivateOrAdvanceToNextBrowser();
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return Activate(ash::LAUNCH_FROM_UNKNOWN);
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)string16 BrowserShortcutLauncherItemController::GetTitle() {
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ui::MenuModel* BrowserShortcutLauncherItemController::CreateContextMenu(
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* root_window) {
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ash::LauncherItem item =
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      *(launcher_controller()->model()->ItemByID(launcher_id()));
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new LauncherContextMenu(launcher_controller(), &item, root_window);
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ash::LauncherMenuModel*
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)BrowserShortcutLauncherItemController::CreateApplicationMenu(int event_flags) {
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags));
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsDraggable() {
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return launcher_controller()->CanPin() ? true : false;
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool BrowserShortcutLauncherItemController::ShouldShowTooltip() {
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon(
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::WebContents* web_contents) const {
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return rb.GetImageNamed(IsIncognito(web_contents) ?
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDR_AURA_LAUNCHER_LIST_INCOGNITO_BROWSER :
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDR_AURA_LAUNCHER_LIST_BROWSER);
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)string16 BrowserShortcutLauncherItemController::GetBrowserListTitle(
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::WebContents* web_contents) const {
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  string16 title = web_contents->GetTitle();
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!title.empty())
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return title;
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsIncognito(
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::WebContents* web_contents) const {
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const Profile* profile =
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      Profile::FromBrowserContext(web_contents->GetBrowserContext());
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return profile->IsOffTheRecord() && !profile->IsGuestSession();
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() {
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Create a list of all suitable running browsers.
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<Browser*> items;
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // We use the list in the order of how the browsers got created - not the LRU
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // order.
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const BrowserList* ash_browser_list =
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BrowserList::const_iterator it =
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           ash_browser_list->begin();
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != ash_browser_list->end(); ++it) {
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (IsBrowserRepresentedInBrowserList(*it))
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      items.push_back(*it);
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If there are no suitable browsers we create a new one.
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (items.empty()) {
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    launcher_controller()->CreateNewWindow();
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (items.size() == 1) {
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // If there is only one suitable browser, we can either activate it, or
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // bounce it (if it is already active).
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (browser == items[0]) {
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      AnimateWindow(browser->window()->GetNativeWindow(),
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    views::corewm::WINDOW_ANIMATION_TYPE_BOUNCE);
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    browser = items[0];
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // If there is more then one suitable browser, we advance to the next if
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // |browser| is already active - or - check the last used browser if it can
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // be used.
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::vector<Browser*>::iterator i =
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        std::find(items.begin(), items.end(), browser);
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (i != items.end()) {
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      browser = (++i == items.end()) ? items[0] : *i;
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      browser = chrome::FindTabbedBrowser(launcher_controller()->profile(),
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          true,
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          chrome::HOST_DESKTOP_TYPE_ASH);
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (!browser ||
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          !IsBrowserRepresentedInBrowserList(browser))
31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        browser = items[0];
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(browser);
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  browser->window()->Show();
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  browser->window()->Activate();
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsBrowserRepresentedInBrowserList(
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Browser* browser) {
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return (browser &&
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          launcher_controller()->IsBrowserFromActiveUser(browser) &&
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH &&
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          (browser->is_type_tabbed() ||
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)           !browser->is_app() ||
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)           !browser->is_type_popup() ||
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)           launcher_controller()->
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               GetLauncherIDForAppID(web_app::GetExtensionIdFromApplicationName(
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   browser->app_name())) <= 0));
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
338