1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file. 4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/browser_status_monitor.h" 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_util.h" 8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shell.h" 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/wm/window_util.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/stl_util.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/web_contents.h" 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/aura/client/activation_client.h" 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/aura/root_window.h" 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/aura/window.h" 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/screen.h" 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)BrowserStatusMonitor::LocalWebContentsObserver::LocalWebContentsObserver( 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents, 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrowserStatusMonitor* monitor) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : content::WebContentsObserver(contents), 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) monitor_(monitor) { 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)BrowserStatusMonitor::LocalWebContentsObserver::~LocalWebContentsObserver() { 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::LocalWebContentsObserver::DidNavigateMainFrame( 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const content::LoadCommittedDetails& details, 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const content::FrameNavigateParams& params) { 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::AppState state = 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_INACTIVE; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (browser->window()->IsActive() && 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents() == web_contents()) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE; 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else if (browser->window()->IsActive()) 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state = ChromeLauncherController::APP_STATE_ACTIVE; 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) monitor_->UpdateAppItemState(web_contents(), state); 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) monitor_->UpdateBrowserItemState(); 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Navigating may change the LauncherID associated with the WebContents. 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (browser->tab_strip_model()->GetActiveWebContents() == web_contents()) { 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::SetLauncherIDForWindow( 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) monitor_->GetLauncherIDForWebContents(web_contents()), 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser->window()->GetNativeWindow()); 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)BrowserStatusMonitor::BrowserStatusMonitor( 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ChromeLauncherController* launcher_controller) 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : launcher_controller_(launcher_controller), 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_activation_clients_(this), 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_root_windows_(this) { 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(launcher_controller_); 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BrowserList::AddObserver(this); 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This check needs for win7_aura. Without this, all tests in 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ChromeLauncherController will fail in win7_aura. 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ash::Shell::HasInstance()) { 69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We can't assume all RootWindows have the same ActivationClient. 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Add a RootWindow and its ActivationClient to the observed list. 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows::const_iterator iter = root_windows.begin(); 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (; iter != root_windows.end(); ++iter) { 74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // |observed_activation_clients_| can have the same activation client 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // multiple times - which would be handled by the used 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // |ScopedObserverWithDuplicatedSources|. 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_activation_clients_.Add( 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) aura::client::GetActivationClient(*iter)); 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_root_windows_.Add(static_cast<aura::Window*>(*iter)); 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ash::Shell::GetInstance()->GetScreen()->AddObserver(this); 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)BrowserStatusMonitor::~BrowserStatusMonitor() { 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This check needs for win7_aura. Without this, all tests in 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ChromeLauncherController will fail in win7_aura. 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ash::Shell::HasInstance()) 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ash::Shell::GetInstance()->GetScreen()->RemoveObserver(this); 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) BrowserList::RemoveObserver(this); 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserList* browser_list = 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (BrowserList::const_iterator i = browser_list->begin(); 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) i != browser_list->end(); ++i) { 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OnBrowserRemoved(*i); 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) STLDeleteContainerPairSecondPointers(webcontents_to_observer_map_.begin(), 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webcontents_to_observer_map_.end()); 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::UpdateAppItemState( 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents, 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::AppState app_state) { 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(contents); 1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // It is possible to come here from Browser::SwapTabContent where the contents 1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // cannot be associated with a browser. 1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(contents); 1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (browser && launcher_controller_->IsBrowserFromActiveUser(browser)) 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) launcher_controller_->UpdateAppState(contents, app_state); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::UpdateBrowserItemState() { 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) launcher_controller_->GetBrowserShortcutLauncherItemController()-> 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateBrowserItemState(); 118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnWindowActivated(aura::Window* gained_active, 121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) aura::Window* lost_active) { 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Browser* browser = NULL; 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents_from_gained = NULL; 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents_from_lost = NULL; 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update active webcontents's app item state of |lost_active|, if existed. 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (lost_active) { 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser = chrome::FindBrowserWithWindow(lost_active); 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (browser) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents_from_lost = browser->tab_strip_model()->GetActiveWebContents(); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (contents_from_lost) { 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState( 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents_from_lost, 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_INACTIVE); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update active webcontents's app item state of |gained_active|, if existed. 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (gained_active) { 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser = chrome::FindBrowserWithWindow(gained_active); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (browser) 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents_from_gained = browser->tab_strip_model()->GetActiveWebContents(); 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (contents_from_gained) { 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState( 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents_from_gained, 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_WINDOW_ACTIVE); 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (contents_from_lost || contents_from_gained) 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateBrowserItemState(); 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnWindowDestroyed(aura::Window* window) { 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Remove RootWindow and its ActivationClient from observed list. 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_root_windows_.Remove(window); 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observed_activation_clients_.Remove( 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::client::GetActivationClient(window)); 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnBrowserAdded(Browser* browser) { 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (browser->is_type_popup() && browser->is_app()) { 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Note: A V1 application will set the tab strip observer when the app gets 1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // added to the shelf. This makes sure that in the multi user case we will 1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // only set the observer while the app item exists in the shelf. 1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddV1AppToShelf(browser); 1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser->tab_strip_model()->AddObserver(this); 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnBrowserRemoved(Browser* browser) { 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (browser->is_type_popup() && browser->is_app()) 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) RemoveV1AppFromShelf(browser); 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser->tab_strip_model()->RemoveObserver(this); 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UpdateBrowserItemState(); 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayBoundsChanged( 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const gfx::Display& display) { 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Do nothing here. 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayAdded(const gfx::Display& new_display) { 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Add a new RootWindow and its ActivationClient to observed list. 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window = ash::Shell::GetInstance()-> 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) display_controller()->GetRootWindowForDisplayId(new_display.id()); 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When the primary root window's display get removed, the existing root 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // window is taken over by the new display and the observer is already set. 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!observed_root_windows_.IsObserving(root_window)) { 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_root_windows_.Add(static_cast<aura::Window*>(root_window)); 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) observed_activation_clients_.Add( 200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) aura::client::GetActivationClient(root_window)); 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayRemoved(const gfx::Display& old_display) { 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When this is called, RootWindow of |old_display| is already removed. 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Instead, we can remove RootWindow and its ActivationClient in the 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // OnWindowRemoved(). 208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Do nothing here. 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::ActiveTabChanged(content::WebContents* old_contents, 212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) content::WebContents* new_contents, 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int index, 214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int reason) { 215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Browser* browser = NULL; 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Use |new_contents|. |old_contents| could be NULL. 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(new_contents); 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser = chrome::FindBrowserWithWebContents(new_contents); 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser && browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::AppState state = 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_INACTIVE; 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Update immediately on a tab change. 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (old_contents && 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (TabStripModel::kNoTab != 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser->tab_strip_model()->GetIndexOfWebContents(old_contents))) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(old_contents, state); 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (new_contents) { 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state = browser->window()->IsActive() ? 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_WINDOW_ACTIVE : 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_ACTIVE; 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(new_contents, state); 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateBrowserItemState(); 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::SetLauncherIDForWindow( 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetLauncherIDForWebContents(new_contents), 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser->window()->GetNativeWindow()); 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::TabReplacedAt(TabStripModel* tab_strip_model, 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* old_contents, 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* new_contents, 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int index) { 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(old_contents && new_contents); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(new_contents); 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (browser && browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(old_contents, 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_REMOVED); 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RemoveWebContentsObserver(old_contents); 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::AppState state = 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_ACTIVE; 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (browser->window()->IsActive() && 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (tab_strip_model->GetActiveWebContents() == new_contents)) 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE; 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(new_contents, state); 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateBrowserItemState(); 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (tab_strip_model->GetActiveWebContents() == new_contents) { 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::SetLauncherIDForWindow( 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetLauncherIDForWebContents(new_contents), 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser->window()->GetNativeWindow()); 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddWebContentsObserver(new_contents); 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::TabInsertedAt(content::WebContents* contents, 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int index, 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool foreground) { 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // An inserted tab is not active - ActiveTabChanged() will be called to 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // activate. We initialize therefore with |APP_STATE_INACTIVE|. 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(contents, 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_INACTIVE); 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddWebContentsObserver(contents); 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::TabClosingAt(TabStripModel* tab_strip_mode, 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents, 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int index) { 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateAppItemState(contents, 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ChromeLauncherController::APP_STATE_REMOVED); 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RemoveWebContentsObserver(contents); 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void BrowserStatusMonitor::AddV1AppToShelf(Browser* browser) { 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(browser->is_type_popup() && browser->is_app()); 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser->tab_strip_model()->AddObserver(this); 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string app_id = 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) web_app::GetExtensionIdFromApplicationName(browser->app_name()); 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!app_id.empty()) { 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_to_app_id_map_[browser] = app_id; 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) launcher_controller_->LockV1AppWithID(app_id); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void BrowserStatusMonitor::RemoveV1AppFromShelf(Browser* browser) { 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(browser->is_type_popup() && browser->is_app()); 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser->tab_strip_model()->RemoveObserver(this); 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end()) { 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) launcher_controller_->UnlockV1AppWithID(browser_to_app_id_map_[browser]); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_to_app_id_map_.erase(browser); 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool BrowserStatusMonitor::IsV1AppInShelf(Browser* browser) { 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end(); 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::AddWebContentsObserver( 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) content::WebContents* contents) { 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (webcontents_to_observer_map_.find(contents) == 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webcontents_to_observer_map_.end()) { 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webcontents_to_observer_map_[contents] = 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new LocalWebContentsObserver(contents, this); 327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::RemoveWebContentsObserver( 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::WebContents* contents) { 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(webcontents_to_observer_map_.find(contents) != 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webcontents_to_observer_map_.end()); 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delete webcontents_to_observer_map_[contents]; 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webcontents_to_observer_map_.erase(contents); 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ash::LauncherID BrowserStatusMonitor::GetLauncherIDForWebContents( 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* contents) { 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return launcher_controller_->GetLauncherIDForWebContents(contents); 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 342