browser_shortcut_launcher_item_controller.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" 6 7#include <vector> 8 9#include "ash/launcher/launcher.h" 10#include "ash/shell.h" 11#include "ash/wm/window_util.h" 12#include "chrome/browser/profiles/profile.h" 13#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" 14#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h" 15#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" 16#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h" 17#include "chrome/browser/ui/browser.h" 18#include "chrome/browser/ui/browser_finder.h" 19#include "chrome/browser/ui/browser_list.h" 20#include "chrome/browser/ui/browser_window.h" 21#include "chrome/browser/ui/tabs/tab_strip_model.h" 22#include "chrome/common/extensions/extension_constants.h" 23#include "content/public/browser/web_contents.h" 24#include "grit/ash_resources.h" 25#include "grit/chromium_strings.h" 26#include "grit/generated_resources.h" 27#include "ui/aura/window.h" 28#include "ui/base/events/event.h" 29#include "ui/base/l10n/l10n_util.h" 30#include "ui/base/resource/resource_bundle.h" 31#include "ui/gfx/image/image.h" 32#include "ui/views/corewm/window_animations.h" 33 34#if defined(OS_CHROMEOS) 35#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" 36#endif 37 38BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController( 39 ChromeLauncherControllerPerApp* launcher_controller, 40 Profile* profile) 41 : LauncherItemController(TYPE_SHORTCUT, 42 extension_misc::kChromeAppId, 43 launcher_controller), 44 app_controller_(launcher_controller), 45 profile_(profile) { 46} 47 48string16 BrowserShortcutLauncherItemController::GetTitle() { 49 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 50} 51 52bool BrowserShortcutLauncherItemController::HasWindow( 53 aura::Window* window) const { 54 const BrowserList* ash_browser_list = 55 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 56 for (BrowserList::const_iterator it = ash_browser_list->begin(); 57 it != ash_browser_list->end(); ++it) { 58 if ((*it)->window()->GetNativeWindow() == window) 59 return true; 60 } 61 return false; 62} 63 64bool BrowserShortcutLauncherItemController::IsOpen() const { 65 const BrowserList* ash_browser_list = 66 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 67 return ash_browser_list->empty() ? false : true; 68} 69 70bool BrowserShortcutLauncherItemController::IsVisible() const { 71 Browser* last_browser = chrome::FindTabbedBrowser( 72 profile_, 73 true, 74 chrome::HOST_DESKTOP_TYPE_ASH); 75 76 if (!last_browser) { 77 return false; 78 } 79 80 aura::Window* window = last_browser->window()->GetNativeWindow(); 81 return ash::wm::IsActiveWindow(window); 82} 83 84void BrowserShortcutLauncherItemController::Launch(int event_flags) { 85} 86 87void BrowserShortcutLauncherItemController::Activate() { 88 Browser* last_browser = chrome::FindTabbedBrowser( 89 profile_, 90 true, 91 chrome::HOST_DESKTOP_TYPE_ASH); 92 93 if (!last_browser) { 94 launcher_controller()->CreateNewWindow(); 95 return; 96 } 97 98 launcher_controller()->ActivateWindowOrMinimizeIfActive( 99 last_browser->window(), GetApplicationList(0).size() == 2); 100} 101 102void BrowserShortcutLauncherItemController::Close() { 103} 104 105void BrowserShortcutLauncherItemController::LauncherItemChanged( 106 int model_index, 107 const ash::LauncherItem& old_item) { 108} 109 110void BrowserShortcutLauncherItemController::Clicked(const ui::Event& event) { 111 #if defined(OS_CHROMEOS) 112 chromeos::default_pinned_apps_field_trial::RecordShelfClick( 113 chromeos::default_pinned_apps_field_trial::CHROME); 114 #endif 115 116 if (event.flags() & ui::EF_CONTROL_DOWN) { 117 launcher_controller()->CreateNewWindow(); 118 return; 119 } 120 121 // In case of a keyboard event, we were called by a hotkey. In that case we 122 // activate the next item in line if an item of our list is already active. 123 if (event.type() & ui::ET_KEY_RELEASED) { 124 ActivateOrAdvanceToNextBrowser(); 125 return; 126 } 127 128 Activate(); 129} 130 131void BrowserShortcutLauncherItemController::OnRemoved() { 132 // BrowserShortcutLauncherItemController is owned by ChromeLauncherController. 133} 134 135ChromeLauncherAppMenuItems 136BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) { 137 ChromeLauncherAppMenuItems items; 138 bool found_tabbed_browser = false; 139 // Add the application name to the menu. 140 items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false)); 141 const BrowserList* ash_browser_list = 142 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 143 for (BrowserList::const_iterator it = ash_browser_list->begin(); 144 it != ash_browser_list->end(); ++it) { 145 Browser* browser = *it; 146 // Make sure that the browser was already shown and it has a proper window. 147 if (std::find(ash_browser_list->begin_last_active(), 148 ash_browser_list->end_last_active(), 149 browser) == ash_browser_list->end_last_active() || 150 !browser->window()) 151 continue; 152 if (browser->is_type_tabbed()) 153 found_tabbed_browser = true; 154 else if (!app_controller_->IsBrowserRepresentedInBrowserList(browser)) 155 continue; 156 TabStripModel* tab_strip = browser->tab_strip_model(); 157 if (tab_strip->active_index() == -1) 158 continue; 159 if (!(event_flags & ui::EF_SHIFT_DOWN)) { 160 content::WebContents* web_contents = 161 tab_strip->GetWebContentsAt(tab_strip->active_index()); 162 gfx::Image app_icon = GetBrowserListIcon(web_contents); 163 string16 title = GetBrowserListTitle(web_contents); 164 items.push_back(new ChromeLauncherAppMenuItemBrowser( 165 title, &app_icon, browser, items.size() == 1)); 166 } else { 167 for (int index = 0; index < tab_strip->count(); ++index) { 168 content::WebContents* web_contents = 169 tab_strip->GetWebContentsAt(index); 170 gfx::Image app_icon = app_controller_->GetAppListIcon(web_contents); 171 string16 title = app_controller_->GetAppListTitle(web_contents); 172 // Check if we need to insert a separator in front. 173 bool leading_separator = !index; 174 items.push_back(new ChromeLauncherAppMenuItemTab( 175 title, &app_icon, web_contents, leading_separator)); 176 } 177 } 178 } 179 // If only windowed applications are open, we return an empty list to 180 // enforce the creation of a new browser. 181 if (!found_tabbed_browser) 182 items.clear(); 183 return items.Pass(); 184} 185 186gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon( 187 content::WebContents* web_contents) const { 188 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 189 return rb.GetImageNamed(IsIncognito(web_contents) ? 190 IDR_AURA_LAUNCHER_LIST_INCOGNITO_BROWSER : 191 IDR_AURA_LAUNCHER_LIST_BROWSER); 192} 193 194string16 BrowserShortcutLauncherItemController::GetBrowserListTitle( 195 content::WebContents* web_contents) const { 196 string16 title = web_contents->GetTitle(); 197 if (!title.empty()) 198 return title; 199 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); 200} 201 202bool BrowserShortcutLauncherItemController::IsIncognito( 203 content::WebContents* web_contents) const { 204 const Profile* profile = 205 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 206 return profile->IsOffTheRecord() && !profile->IsGuestSession(); 207} 208 209void BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() { 210 // Create a list of all suitable running browsers. 211 std::vector<Browser*> items; 212 // We use the list in the order of how the browsers got created - not the LRU 213 // order. 214 const BrowserList* ash_browser_list = 215 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 216 for (BrowserList::const_iterator it = 217 ash_browser_list->begin(); 218 it != ash_browser_list->end(); ++it) { 219 if (app_controller_->IsBrowserRepresentedInBrowserList(*it)) 220 items.push_back(*it); 221 } 222 // If there are no suitable browsers we create a new one. 223 if (!items.size()) { 224 launcher_controller()->CreateNewWindow(); 225 return; 226 } 227 Browser* browser = chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow()); 228 if (items.size() == 1) { 229 // If there is only one suitable browser, we can either activate it, or 230 // bounce it (if it is already active). 231 if (browser == items[0]) { 232 AnimateWindow(browser->window()->GetNativeWindow(), 233 views::corewm::WINDOW_ANIMATION_TYPE_BOUNCE); 234 return; 235 } 236 browser = items[0]; 237 } else { 238 // If there is more then one suitable browser, we advance to the next if 239 // |current_browser| is already active - or - check the last used browser 240 // if it can be used. 241 std::vector<Browser*>::iterator i = 242 std::find(items.begin(), items.end(), browser); 243 if (i != items.end()) { 244 browser = (++i == items.end()) ? items[0] : *i; 245 } else { 246 browser = chrome::FindTabbedBrowser(profile_, 247 true, 248 chrome::HOST_DESKTOP_TYPE_ASH); 249 if (!browser || 250 !app_controller_->IsBrowserRepresentedInBrowserList(browser)) 251 browser = items[0]; 252 } 253 } 254 DCHECK(browser); 255 browser->window()->Show(); 256 browser->window()->Activate(); 257} 258