Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / ui / ash / launcher / browser_shortcut_launcher_item_controller.cc
blobd35a1f80ef82229bde061b7759b98624c76c919b
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.
5 #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
7 #include <vector>
9 #include "ash/shelf/shelf.h"
10 #include "ash/shelf/shelf_model.h"
11 #include "ash/shelf/shelf_util.h"
12 #include "ash/shell.h"
13 #include "ash/wm/window_util.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h"
16 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h"
17 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h"
18 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
19 #include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h"
20 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_finder.h"
23 #include "chrome/browser/ui/browser_list.h"
24 #include "chrome/browser/ui/browser_window.h"
25 #include "chrome/browser/ui/chrome_pages.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/browser/web_applications/web_app.h"
28 #include "chrome/common/extensions/extension_constants.h"
29 #include "content/public/browser/web_contents.h"
30 #include "content/public/common/url_constants.h"
31 #include "grit/ash_resources.h"
32 #include "grit/chromium_strings.h"
33 #include "grit/generated_resources.h"
34 #include "ui/aura/window.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/events/event.h"
38 #include "ui/gfx/image/image.h"
39 #include "ui/wm/core/window_animations.h"
41 BrowserShortcutLauncherItemController::BrowserShortcutLauncherItemController(
42 ChromeLauncherController* launcher_controller)
43 : LauncherItemController(TYPE_SHORTCUT,
44 extension_misc::kChromeAppId,
45 launcher_controller) {
48 BrowserShortcutLauncherItemController::
49 ~BrowserShortcutLauncherItemController() {
52 void BrowserShortcutLauncherItemController::UpdateBrowserItemState() {
53 // The shell will not be available for win7_aura unittests like
54 // ChromeLauncherControllerTest.BrowserMenuGeneration.
55 if (!ash::Shell::HasInstance())
56 return;
58 ash::ShelfModel* model = launcher_controller()->model();
60 // Determine the new browser's active state and change if necessary.
61 int browser_index = model->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
62 DCHECK_GE(browser_index, 0);
63 ash::ShelfItem browser_item = model->items()[browser_index];
64 ash::ShelfItemStatus browser_status = ash::STATUS_CLOSED;
66 aura::Window* window = ash::wm::GetActiveWindow();
67 if (window) {
68 // Check if the active browser / tab is a browser which is not an app,
69 // a windowed app, a popup or any other item which is not a browser of
70 // interest.
71 Browser* browser = chrome::FindBrowserWithWindow(window);
72 if (IsBrowserRepresentedInBrowserList(browser)) {
73 browser_status = ash::STATUS_ACTIVE;
74 // If an app that has item is running in active WebContents, browser item
75 // status cannot be active.
76 content::WebContents* contents =
77 browser->tab_strip_model()->GetActiveWebContents();
78 if (contents &&
79 (launcher_controller()->GetShelfIDForWebContents(contents) !=
80 browser_item.id))
81 browser_status = ash::STATUS_RUNNING;
85 if (browser_status == ash::STATUS_CLOSED) {
86 const BrowserList* ash_browser_list =
87 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
88 for (BrowserList::const_reverse_iterator it =
89 ash_browser_list->begin_last_active();
90 it != ash_browser_list->end_last_active() &&
91 browser_status == ash::STATUS_CLOSED; ++it) {
92 if (IsBrowserRepresentedInBrowserList(*it))
93 browser_status = ash::STATUS_RUNNING;
97 if (browser_status != browser_item.status) {
98 browser_item.status = browser_status;
99 model->Set(browser_index, browser_item);
103 void BrowserShortcutLauncherItemController::SetShelfIDForBrowserWindowContents(
104 Browser* browser,
105 content::WebContents* web_contents) {
106 if (!IsBrowserRepresentedInBrowserList(browser))
107 return;
108 ash::SetShelfIDForWindow(
109 launcher_controller()->GetShelfIDForWebContents(web_contents),
110 browser->window()->GetNativeWindow());
113 bool BrowserShortcutLauncherItemController::IsOpen() const {
114 const BrowserList* ash_browser_list =
115 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
116 for (BrowserList::const_iterator it = ash_browser_list->begin();
117 it != ash_browser_list->end(); ++it) {
118 if (launcher_controller()->IsBrowserFromActiveUser(*it))
119 return true;
121 return false;
124 bool BrowserShortcutLauncherItemController::IsVisible() const {
125 Browser* last_browser = chrome::FindTabbedBrowser(
126 launcher_controller()->profile(),
127 true,
128 chrome::HOST_DESKTOP_TYPE_ASH);
130 if (!last_browser) {
131 return false;
134 aura::Window* window = last_browser->window()->GetNativeWindow();
135 return ash::wm::IsActiveWindow(window);
138 void BrowserShortcutLauncherItemController::Launch(ash::LaunchSource source,
139 int event_flags) {
142 bool BrowserShortcutLauncherItemController::Activate(ash::LaunchSource source) {
143 Browser* last_browser = chrome::FindTabbedBrowser(
144 launcher_controller()->profile(),
145 true,
146 chrome::HOST_DESKTOP_TYPE_ASH);
148 if (!last_browser) {
149 launcher_controller()->CreateNewWindow();
150 return true;
153 launcher_controller()->ActivateWindowOrMinimizeIfActive(
154 last_browser->window(), GetApplicationList(0).size() == 2);
155 return false;
158 void BrowserShortcutLauncherItemController::Close() {
161 ChromeLauncherAppMenuItems
162 BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) {
163 ChromeLauncherAppMenuItems items;
164 bool found_tabbed_browser = false;
165 // Add the application name to the menu.
166 items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false));
167 const BrowserList* ash_browser_list =
168 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
169 for (BrowserList::const_iterator it = ash_browser_list->begin();
170 it != ash_browser_list->end(); ++it) {
171 Browser* browser = *it;
172 // Make sure that the browser was already shown, is from the current user
173 // and has a proper window.
174 if (!launcher_controller()->IsBrowserFromActiveUser(browser) ||
175 std::find(ash_browser_list->begin_last_active(),
176 ash_browser_list->end_last_active(),
177 browser) == ash_browser_list->end_last_active() ||
178 !browser->window())
179 continue;
180 if (browser->is_type_tabbed())
181 found_tabbed_browser = true;
182 else if (!IsBrowserRepresentedInBrowserList(browser))
183 continue;
184 TabStripModel* tab_strip = browser->tab_strip_model();
185 if (tab_strip->active_index() == -1)
186 continue;
187 if (!(event_flags & ui::EF_SHIFT_DOWN)) {
188 content::WebContents* web_contents =
189 tab_strip->GetWebContentsAt(tab_strip->active_index());
190 gfx::Image app_icon = GetBrowserListIcon(web_contents);
191 base::string16 title = GetBrowserListTitle(web_contents);
192 items.push_back(new ChromeLauncherAppMenuItemBrowser(
193 title, &app_icon, browser, items.size() == 1));
194 } else {
195 for (int index = 0; index < tab_strip->count(); ++index) {
196 content::WebContents* web_contents =
197 tab_strip->GetWebContentsAt(index);
198 gfx::Image app_icon =
199 launcher_controller()->GetAppListIcon(web_contents);
200 base::string16 title =
201 launcher_controller()->GetAppListTitle(web_contents);
202 // Check if we need to insert a separator in front.
203 bool leading_separator = !index;
204 items.push_back(new ChromeLauncherAppMenuItemTab(
205 title, &app_icon, web_contents, leading_separator));
209 // If only windowed applications are open, we return an empty list to
210 // enforce the creation of a new browser.
211 if (!found_tabbed_browser)
212 items.clear();
213 return items.Pass();
216 bool BrowserShortcutLauncherItemController::ItemSelected(
217 const ui::Event& event) {
218 if (event.flags() & ui::EF_CONTROL_DOWN) {
219 launcher_controller()->CreateNewWindow();
220 return true;
223 // In case of a keyboard event, we were called by a hotkey. In that case we
224 // activate the next item in line if an item of our list is already active.
225 if (event.type() & ui::ET_KEY_RELEASED) {
226 ActivateOrAdvanceToNextBrowser();
227 return false;
230 return Activate(ash::LAUNCH_FROM_UNKNOWN);
233 base::string16 BrowserShortcutLauncherItemController::GetTitle() {
234 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
237 ui::MenuModel* BrowserShortcutLauncherItemController::CreateContextMenu(
238 aura::Window* root_window) {
239 ash::ShelfItem item =
240 *(launcher_controller()->model()->ItemByID(shelf_id()));
241 return new LauncherContextMenu(launcher_controller(), &item, root_window);
244 ash::ShelfMenuModel*
245 BrowserShortcutLauncherItemController::CreateApplicationMenu(int event_flags) {
246 return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags));
249 bool BrowserShortcutLauncherItemController::IsDraggable() {
250 return launcher_controller()->CanPin() ? true : false;
253 bool BrowserShortcutLauncherItemController::ShouldShowTooltip() {
254 return true;
257 gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon(
258 content::WebContents* web_contents) const {
259 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
260 return rb.GetImageNamed(IsIncognito(web_contents) ?
261 IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER :
262 IDR_ASH_SHELF_LIST_BROWSER);
265 base::string16 BrowserShortcutLauncherItemController::GetBrowserListTitle(
266 content::WebContents* web_contents) const {
267 base::string16 title = web_contents->GetTitle();
268 if (!title.empty())
269 return title;
270 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
273 bool BrowserShortcutLauncherItemController::IsIncognito(
274 content::WebContents* web_contents) const {
275 const Profile* profile =
276 Profile::FromBrowserContext(web_contents->GetBrowserContext());
277 return profile->IsOffTheRecord() && !profile->IsGuestSession();
280 void BrowserShortcutLauncherItemController::ActivateOrAdvanceToNextBrowser() {
281 // Create a list of all suitable running browsers.
282 std::vector<Browser*> items;
283 // We use the list in the order of how the browsers got created - not the LRU
284 // order.
285 const BrowserList* ash_browser_list =
286 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
287 for (BrowserList::const_iterator it =
288 ash_browser_list->begin();
289 it != ash_browser_list->end(); ++it) {
290 if (IsBrowserRepresentedInBrowserList(*it))
291 items.push_back(*it);
293 // If there are no suitable browsers we create a new one.
294 if (items.empty()) {
295 launcher_controller()->CreateNewWindow();
296 return;
298 Browser* browser = chrome::FindBrowserWithWindow(ash::wm::GetActiveWindow());
299 if (items.size() == 1) {
300 // If there is only one suitable browser, we can either activate it, or
301 // bounce it (if it is already active).
302 if (browser == items[0]) {
303 AnimateWindow(browser->window()->GetNativeWindow(),
304 wm::WINDOW_ANIMATION_TYPE_BOUNCE);
305 return;
307 browser = items[0];
308 } else {
309 // If there is more then one suitable browser, we advance to the next if
310 // |browser| is already active - or - check the last used browser if it can
311 // be used.
312 std::vector<Browser*>::iterator i =
313 std::find(items.begin(), items.end(), browser);
314 if (i != items.end()) {
315 browser = (++i == items.end()) ? items[0] : *i;
316 } else {
317 browser = chrome::FindTabbedBrowser(launcher_controller()->profile(),
318 true,
319 chrome::HOST_DESKTOP_TYPE_ASH);
320 if (!browser ||
321 !IsBrowserRepresentedInBrowserList(browser))
322 browser = items[0];
325 DCHECK(browser);
326 browser->window()->Show();
327 browser->window()->Activate();
330 bool BrowserShortcutLauncherItemController::IsBrowserRepresentedInBrowserList(
331 Browser* browser) {
332 // Only Ash desktop browser windows for the active user are represented.
333 if (!browser ||
334 !launcher_controller()->IsBrowserFromActiveUser(browser) ||
335 browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
336 return false;
338 // v1 App popup windows with a valid app id have their own icon.
339 if (browser->is_app() &&
340 browser->is_type_popup() &&
341 launcher_controller()->GetShelfIDForAppID(
342 web_app::GetExtensionIdFromApplicationName(browser->app_name())) > 0)
343 return false;
345 // Stand-alone chrome:// windows (e.g. settings) have their own icon.
346 if (chrome::IsTrustedPopupWindowWithScheme(browser, content::kChromeUIScheme))
347 return false;
349 // Tabbed browser and other popup windows are all represented.
350 return true;