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