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) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.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" 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/ui/chrome_pages.h" 266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/ui/settings_window_manager.h" 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/chromium_strings.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/web_contents.h" 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/common/url_constants.h" 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "grit/ash_resources.h" 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/aura/window.h" 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/image/image.h" 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController( 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController* launcher_controller) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : LauncherItemController(TYPE_SHORTCUT, 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_misc::kChromeAppId, 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) launcher_controller) { 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochBrowserShortcutLauncherItemController:: 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ~BrowserShortcutLauncherItemController() { 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BrowserShortcutLauncherItemController::UpdateBrowserItemState() { 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The shell will not be available for win7_aura unittests like 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ChromeLauncherControllerTest.BrowserMenuGeneration. 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ash::Shell::HasInstance()) 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::ShelfModel* model = launcher_controller()->model(); 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Determine the new browser's active state and change if necessary. 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int browser_index = model->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(browser_index, 0); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem browser_item = model->items()[browser_index]; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemStatus browser_status = ash::STATUS_CLOSED; 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) aura::Window* window = ash::wm::GetActiveWindow(); 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (window) { 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Check if the active browser / tab is a browser which is not an app, 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // a windowed app, a popup or any other item which is not a browser of 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // interest. 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWindow(window); 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsBrowserRepresentedInBrowserList(browser)) { 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_status = ash::STATUS_ACTIVE; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If an app that has item is running in active WebContents, browser item 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // status cannot be active. 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* contents = 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (contents && 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (launcher_controller()->GetShelfIDForWebContents(contents) != 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_item.id)) 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_status = ash::STATUS_RUNNING; 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser_status == ash::STATUS_CLOSED) { 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const BrowserList* ash_browser_list = 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (BrowserList::const_reverse_iterator it = 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ash_browser_list->begin_last_active(); 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it != ash_browser_list->end_last_active() && 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_status == ash::STATUS_CLOSED; ++it) { 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsBrowserRepresentedInBrowserList(*it)) 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_status = ash::STATUS_RUNNING; 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser_status != browser_item.status) { 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_item.status = browser_status; 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) model->Set(browser_index, browser_item); 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid BrowserShortcutLauncherItemController::SetShelfIDForBrowserWindowContents( 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Browser* browser, 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::WebContents* web_contents) { 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We need to call SetShelfIDForWindow for V1 applications since they are 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // content which might change and as such change the application type. 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!browser || 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !launcher_controller()->IsBrowserFromActiveUser(browser) || 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH || 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) chrome::IsTrustedPopupWindowWithScheme(browser, content::kChromeUIScheme)) 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ash::SetShelfIDForWindow( 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch launcher_controller()->GetShelfIDForWebContents(web_contents), 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch browser->window()->GetNativeWindow()); 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsOpen() const { 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const BrowserList* ash_browser_list = 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (BrowserList::const_iterator it = ash_browser_list->begin(); 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != ash_browser_list->end(); ++it) { 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (launcher_controller()->IsBrowserFromActiveUser(*it)) 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsVisible() const { 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Browser* last_browser = chrome::FindTabbedBrowser( 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) launcher_controller()->profile(), 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) true, 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!last_browser) { 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) aura::Window* window = last_browser->window()->GetNativeWindow(); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ash::wm::IsActiveWindow(window); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void BrowserShortcutLauncherItemController::Launch(ash::LaunchSource source, 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_flags) { 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BrowserShortcutLauncherItemController::Activate(ash::LaunchSource source) { 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Browser* last_browser = chrome::FindTabbedBrowser( 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) launcher_controller()->profile(), 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) true, 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!last_browser) { 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launcher_controller()->CreateNewWindow(); 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launcher_controller()->ActivateWindowOrMinimizeIfActive( 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_browser->window(), GetApplicationList(0).size() == 2); 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserShortcutLauncherItemController::Close() { 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ChromeLauncherAppMenuItems 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) { 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ChromeLauncherAppMenuItems items; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool found_tabbed_browser = false; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add the application name to the menu. 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false)); 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const BrowserList* ash_browser_list = 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (BrowserList::const_iterator it = ash_browser_list->begin(); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != ash_browser_list->end(); ++it) { 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Browser* browser = *it; 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Make sure that the browser was already shown, is from the current user 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // and has a proper window. 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!launcher_controller()->IsBrowserFromActiveUser(browser) || 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::find(ash_browser_list->begin_last_active(), 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ash_browser_list->end_last_active(), 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser) == ash_browser_list->end_last_active() || 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !browser->window()) 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (browser->is_type_tabbed()) 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) found_tabbed_browser = true; 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (!IsBrowserRepresentedInBrowserList(browser)) 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (tab_strip->active_index() == -1) 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!(event_flags & ui::EF_SHIFT_DOWN)) { 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::WebContents* web_contents = 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tab_strip->GetWebContentsAt(tab_strip->active_index()); 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Image app_icon = GetBrowserListIcon(web_contents); 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title = GetBrowserListTitle(web_contents); 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) items.push_back(new ChromeLauncherAppMenuItemBrowser( 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) title, &app_icon, browser, items.size() == 1)); 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int index = 0; index < tab_strip->count(); ++index) { 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::WebContents* web_contents = 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tab_strip->GetWebContentsAt(index); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Image app_icon = 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) launcher_controller()->GetAppListIcon(web_contents); 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title = 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) launcher_controller()->GetAppListTitle(web_contents); 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check if we need to insert a separator in front. 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool leading_separator = !index; 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) items.push_back(new ChromeLauncherAppMenuItemTab( 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) title, &app_icon, web_contents, leading_separator)); 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If only windowed applications are open, we return an empty list to 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // enforce the creation of a new browser. 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!found_tabbed_browser) 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) items.clear(); 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return items.Pass(); 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool BrowserShortcutLauncherItemController::ItemSelected( 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const ui::Event& event) { 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (event.flags() & ui::EF_CONTROL_DOWN) { 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) launcher_controller()->CreateNewWindow(); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // In case of a keyboard event, we were called by a hotkey. In that case we 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // activate the next item in line if an item of our list is already active. 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (event.type() & ui::ET_KEY_RELEASED) { 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ActivateOrAdvanceToNextBrowser(); 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return Activate(ash::LAUNCH_FROM_UNKNOWN); 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BrowserShortcutLauncherItemController::GetTitle() { 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ui::MenuModel* BrowserShortcutLauncherItemController::CreateContextMenu( 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) { 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *(launcher_controller()->model()->ItemByID(shelf_id())); 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new LauncherContextMenu(launcher_controller(), &item, root_window); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ash::ShelfMenuModel* 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)BrowserShortcutLauncherItemController::CreateApplicationMenu(int event_flags) { 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags)); 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsDraggable() { 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return launcher_controller()->CanPin() ? true : false; 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool BrowserShortcutLauncherItemController::ShouldShowTooltip() { 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon( 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::WebContents* web_contents) const { 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return rb.GetImageNamed(IsIncognito(web_contents) ? 268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER : 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IDR_ASH_SHELF_LIST_BROWSER); 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BrowserShortcutLauncherItemController::GetBrowserListTitle( 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::WebContents* web_contents) const { 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title = web_contents->GetTitle(); 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!title.empty()) 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return title; 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsIncognito( 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::WebContents* web_contents) const { 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const Profile* profile = 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return profile->IsOffTheRecord() && !profile->IsGuestSession(); 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() { 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create a list of all suitable running browsers. 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<Browser*> items; 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We use the list in the order of how the browsers got created - not the LRU 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // order. 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const BrowserList* ash_browser_list = 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (BrowserList::const_iterator it = 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ash_browser_list->begin(); 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != ash_browser_list->end(); ++it) { 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsBrowserRepresentedInBrowserList(*it)) 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) items.push_back(*it); 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If there are no suitable browsers we create a new one. 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (items.empty()) { 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launcher_controller()->CreateNewWindow(); 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()); 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (items.size() == 1) { 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If there is only one suitable browser, we can either activate it, or 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // bounce it (if it is already active). 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (browser == items[0]) { 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AnimateWindow(browser->window()->GetNativeWindow(), 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WINDOW_ANIMATION_TYPE_BOUNCE); 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser = items[0]; 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If there is more then one suitable browser, we advance to the next if 31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |browser| is already active - or - check the last used browser if it can 31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // be used. 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<Browser*>::iterator i = 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::find(items.begin(), items.end(), browser); 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (i != items.end()) { 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser = (++i == items.end()) ? items[0] : *i; 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser = chrome::FindTabbedBrowser(launcher_controller()->profile(), 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) true, 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!browser || 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !IsBrowserRepresentedInBrowserList(browser)) 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser = items[0]; 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(browser); 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser->window()->Show(); 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser->window()->Activate(); 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool BrowserShortcutLauncherItemController::IsBrowserRepresentedInBrowserList( 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Browser* browser) { 3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Only Ash desktop browser windows for the active user are represented. 3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!browser || 3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch !launcher_controller()->IsBrowserFromActiveUser(browser) || 3420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // v1 App popup windows with a valid app id have their own icon. 3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (browser->is_app() && 3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch browser->is_type_popup() && 3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch launcher_controller()->GetShelfIDForAppID( 3490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch web_app::GetExtensionIdFromApplicationName(browser->app_name())) > 0) 3500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 3510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Stand-alone chrome:// windows (e.g. settings) have their own icon. 3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (chrome::IsTrustedPopupWindowWithScheme(browser, content::kChromeUIScheme)) 3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 3550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Tabbed browser and other popup windows are all represented. 3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 359