app_shortcut_launcher_item_controller.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/extensions/native_app_window.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Extension; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Item controller for an app shortcut. Shortcuts track app and launcher ids, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// but do not have any associated windows (opening a shortcut will replace the 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// item with the appropriate LauncherItemController type). 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppShortcutLauncherItemController::AppShortcutLauncherItemController( 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& app_id, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeLauncherControllerPerApp* controller) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : LauncherItemController(TYPE_SHORTCUT, app_id, controller), 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_controller_(controller) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To detect V1 applications we use their domain and match them against the 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // used URL. This will also work with applications like Google Drive. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_controller()->GetExtensionForAppID(app_id); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Some unit tests have no real extension and will set their 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_refocus_url(GURL(extension->launch_web_url() + "*")); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppShortcutLauncherItemController::~AppShortcutLauncherItemController() { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 AppShortcutLauncherItemController::GetTitle() { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetAppTitle(); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AppShortcutLauncherItemController::HasWindow(aura::Window* window) const { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<content::WebContents*> content = 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_controller_->GetV1ApplicationsFromAppId(app_id()); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < content.size(); i++) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(content[i]); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser && browser->window()->GetNativeWindow() == window) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AppShortcutLauncherItemController::IsOpen() const { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !app_controller_->GetV1ApplicationsFromAppId(app_id()).empty(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AppShortcutLauncherItemController::IsVisible() const { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Return true if any browser window associated with the app is visible. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<content::WebContents*> content = 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_controller_->GetV1ApplicationsFromAppId(app_id()); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < content.size(); i++) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(content[i]); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser && browser->window()->GetNativeWindow()->IsVisible()) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::Launch(int event_flags) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_controller_->LaunchApp(app_id(), event_flags); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::Activate() { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* content = GetLRUApplication(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!content) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Launch(ui::EF_NONE); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(content); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(content); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(TabStripModel::kNoTab, index); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip->ActivateTabAt(index, false); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->window()->Show(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ash::wm::ActivateWindow(browser->window()->GetNativeWindow()); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::Close() { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close all running 'programs' of this type. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<content::WebContents*> content = 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_controller_->GetV1ApplicationsFromAppId(app_id()); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < content.size(); i++) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(content[i]); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(content[i]); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(index != TabStripModel::kNoTab); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip->CloseWebContentsAt(index, TabStripModel::CLOSE_NONE); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::Clicked(const ui::Event& event) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Activate(); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::OnRemoved() { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // AppShortcutLauncherItemController is unowned; delete on removal. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppShortcutLauncherItemController::LauncherItemChanged( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int model_index, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ash::LauncherItem& old_item) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ChromeLauncherAppMenuItems 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppShortcutLauncherItemController::GetApplicationList() { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeLauncherAppMenuItems items; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the application name to the menu. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false)); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<content::WebContents*> content_list = 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRunningApplications(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < content_list.size(); i++) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* web_contents = content_list[i]; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get the icon. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image app_icon = app_controller_->GetAppListIcon(web_contents); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string16 title = app_controller_->GetAppListTitle(web_contents); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) items.push_back(new ChromeLauncherAppMenuItemTab( 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) title, &app_icon, web_contents, i == 0)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return items.Pass(); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<content::WebContents*> 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppShortcutLauncherItemController::GetRunningApplications() { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<content::WebContents*> items; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLPattern refocus_pattern(URLPattern::SCHEME_ALL); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.SetMatchAllURLs(true); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!refocus_url_.is_empty()) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.SetMatchAllURLs(false); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.Parse(refocus_url_.spec()); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_controller()->GetExtensionForAppID(app_id()); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It is possible to come here While an extension gets loaded. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return items; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BrowserList* ash_browser_list = 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (BrowserList::const_iterator it = ash_browser_list->begin(); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != ash_browser_list->end(); ++it) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = *it; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int index = 0; index < tab_strip->count(); index++) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* web_contents = tab_strip->GetWebContentsAt(index); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (WebContentMatchesApp(extension, refocus_pattern, web_contents)) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) items.push_back(web_contents); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return items; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebContents* AppShortcutLauncherItemController::GetLRUApplication() { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLPattern refocus_pattern(URLPattern::SCHEME_ALL); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.SetMatchAllURLs(true); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!refocus_url_.is_empty()) { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.SetMatchAllURLs(false); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.Parse(refocus_url_.spec()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_controller()->GetExtensionForAppID(app_id()); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We may get here while the extension is loading (and NULL). 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BrowserList* ash_browser_list = 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (BrowserList::const_reverse_iterator 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it = ash_browser_list->begin_last_active(); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != ash_browser_list->end_last_active(); ++it) { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = *it; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We start to enumerate from the active index. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int active_index = tab_strip->active_index(); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int index = 0; index < tab_strip->count(); index++) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* web_contents = tab_strip->GetWebContentsAt( 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (index + active_index) % tab_strip->count()); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (WebContentMatchesApp(extension, refocus_pattern, web_contents)) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AppShortcutLauncherItemController::WebContentMatchesApp( 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension* extension, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const URLPattern& refocus_pattern, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* web_contents) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL tab_url = web_contents->GetURL(); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are three ways to identify the association of a URL with this 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extension: 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The refocus pattern is matched (needed for apps like drive). 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The extension's origin + extent gets matched. 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The launcher controller knows that the tab got created for this app. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ((!refocus_pattern.match_all_urls() && 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refocus_pattern.MatchesURL(tab_url)) || 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (extension->OverlapsWithOrigin(tab_url) && 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->web_extent().MatchesURL(tab_url)) || 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_controller()->GetPerAppInterface()-> 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IsWebContentHandledByApplication(web_contents, app_id())); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 231