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"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/ui/settings_window_manager.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/ui/settings_window_manager_observer.h"
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/web_contents.h"
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/browser/web_contents_observer.h"
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "grit/ash_resources.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "grit/generated_resources.h"
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/aura/window.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/l10n/l10n_util.h"
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/screen.h"
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This class monitors the WebContent of the all tab and notifies a navigation
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// to the BrowserStatusMonitor.
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass BrowserStatusMonitor::LocalWebContentsObserver
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : public content::WebContentsObserver {
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  LocalWebContentsObserver(content::WebContents* contents,
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                           BrowserStatusMonitor* monitor)
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : content::WebContentsObserver(contents),
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        monitor_(monitor) {}
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~LocalWebContentsObserver() {}
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // content::WebContentsObserver
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void DidNavigateMainFrame(
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const content::LoadCommittedDetails& details,
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const content::FrameNavigateParams& params) OVERRIDE {
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ChromeLauncherController::AppState state =
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ChromeLauncherController::APP_STATE_INACTIVE;
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (browser->window()->IsActive() &&
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        browser->tab_strip_model()->GetActiveWebContents() == web_contents())
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE;
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    else if (browser->window()->IsActive())
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      state = ChromeLauncherController::APP_STATE_ACTIVE;
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    monitor_->UpdateAppItemState(web_contents(), state);
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    monitor_->UpdateBrowserItemState();
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Navigating may change the ShelfID associated with the WebContents.
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (browser->tab_strip_model()->GetActiveWebContents() == web_contents())
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      monitor_->SetShelfIDForBrowserWindowContents(browser, web_contents());
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void WebContentsDestroyed() OVERRIDE {
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // We can only come here when there was a non standard termination like
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // an app got un-installed while running, etc.
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    monitor_->WebContentsDestroyed(web_contents());
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // |this| is gone now.
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserStatusMonitor* monitor_;
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LocalWebContentsObserver);
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Observes any new settings windows and sets their shelf icon (since they
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// are excluded from BrowserShortcutLauncherItem).
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass BrowserStatusMonitor::SettingsWindowObserver
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : public chrome::SettingsWindowManagerObserver {
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SettingsWindowObserver() {}
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~SettingsWindowObserver() {}
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // SettingsWindowManagerObserver
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnNewSettingsWindow(Browser* settings_browser) OVERRIDE {
876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ash::SetShelfItemDetailsForDialogWindow(
886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        settings_browser->window()->GetNativeWindow(),
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        IDR_ASH_SHELF_ICON_SETTINGS,
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE));
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SettingsWindowObserver);
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)BrowserStatusMonitor::BrowserStatusMonitor(
98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ChromeLauncherController* launcher_controller)
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : launcher_controller_(launcher_controller),
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      observed_activation_clients_(this),
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      observed_root_windows_(this),
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      settings_window_observer_(new SettingsWindowObserver) {
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(launcher_controller_);
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BrowserList::AddObserver(this);
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  chrome::SettingsWindowManager::GetInstance()->AddObserver(
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      settings_window_observer_.get());
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // This check needs for win7_aura. Without this, all tests in
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // ChromeLauncherController will fail in win7_aura.
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (ash::Shell::HasInstance()) {
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // We can't assume all RootWindows have the same ActivationClient.
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Add a RootWindow and its ActivationClient to the observed list.
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    aura::Window::Windows::const_iterator iter = root_windows.begin();
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    for (; iter != root_windows.end(); ++iter) {
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // |observed_activation_clients_| can have the same activation client
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // multiple times - which would be handled by the used
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // |ScopedObserverWithDuplicatedSources|.
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      observed_activation_clients_.Add(
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          aura::client::GetActivationClient(*iter));
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      observed_root_windows_.Add(static_cast<aura::Window*>(*iter));
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ash::Shell::GetInstance()->GetScreen()->AddObserver(this);
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)BrowserStatusMonitor::~BrowserStatusMonitor() {
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // This check needs for win7_aura. Without this, all tests in
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // ChromeLauncherController will fail in win7_aura.
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (ash::Shell::HasInstance())
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ash::Shell::GetInstance()->GetScreen()->RemoveObserver(this);
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BrowserList::RemoveObserver(this);
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserList* browser_list =
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (BrowserList::const_iterator i = browser_list->begin();
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       i != browser_list->end(); ++i) {
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OnBrowserRemoved(*i);
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  STLDeleteContainerPairSecondPointers(webcontents_to_observer_map_.begin(),
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       webcontents_to_observer_map_.end());
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::UpdateAppItemState(
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::WebContents* contents,
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ChromeLauncherController::AppState app_state) {
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(contents);
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // It is possible to come here from Browser::SwapTabContent where the contents
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // cannot be associated with a browser. A removal however should be properly
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // processed.
1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  Browser* browser = chrome::FindBrowserWithWebContents(contents);
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (app_state == ChromeLauncherController::APP_STATE_REMOVED ||
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      (browser && launcher_controller_->IsBrowserFromActiveUser(browser)))
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    launcher_controller_->UpdateAppState(contents, app_state);
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::UpdateBrowserItemState() {
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  launcher_controller_->GetBrowserShortcutLauncherItemController()->
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      UpdateBrowserItemState();
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnWindowActivated(aura::Window* gained_active,
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                             aura::Window* lost_active) {
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Browser* browser = NULL;
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::WebContents* contents_from_gained = NULL;
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::WebContents* contents_from_lost = NULL;
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update active webcontents's app item state of |lost_active|, if existed.
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (lost_active) {
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    browser = chrome::FindBrowserWithWindow(lost_active);
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (browser)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      contents_from_lost = browser->tab_strip_model()->GetActiveWebContents();
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (contents_from_lost) {
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      UpdateAppItemState(
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          contents_from_lost,
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          ChromeLauncherController::APP_STATE_INACTIVE);
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update active webcontents's app item state of |gained_active|, if existed.
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (gained_active) {
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    browser = chrome::FindBrowserWithWindow(gained_active);
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (browser)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      contents_from_gained = browser->tab_strip_model()->GetActiveWebContents();
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (contents_from_gained) {
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      UpdateAppItemState(
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          contents_from_gained,
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          ChromeLauncherController::APP_STATE_WINDOW_ACTIVE);
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (contents_from_lost || contents_from_gained)
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateBrowserItemState();
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnWindowDestroyed(aura::Window* window) {
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Remove RootWindow and its ActivationClient from observed list.
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  observed_root_windows_.Remove(window);
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  observed_activation_clients_.Remove(
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      aura::client::GetActivationClient(window));
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnBrowserAdded(Browser* browser) {
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (browser->is_type_popup() && browser->is_app()) {
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Note: A V1 application will set the tab strip observer when the app gets
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // added to the shelf. This makes sure that in the multi user case we will
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // only set the observer while the app item exists in the shelf.
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    AddV1AppToShelf(browser);
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    browser->tab_strip_model()->AddObserver(this);
215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnBrowserRemoved(Browser* browser) {
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (browser->is_type_popup() && browser->is_app())
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RemoveV1AppFromShelf(browser);
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  else
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    browser->tab_strip_model()->RemoveObserver(this);
226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UpdateBrowserItemState();
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayAdded(const gfx::Display& new_display) {
231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Add a new RootWindow and its ActivationClient to observed list.
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = ash::Shell::GetInstance()->
233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      display_controller()->GetRootWindowForDisplayId(new_display.id());
234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // When the primary root window's display get removed, the existing root
235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // window is taken over by the new display and the observer is already set.
236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!observed_root_windows_.IsObserving(root_window)) {
237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    observed_root_windows_.Add(static_cast<aura::Window*>(root_window));
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    observed_activation_clients_.Add(
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        aura::client::GetActivationClient(root_window));
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayRemoved(const gfx::Display& old_display) {
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // When this is called, RootWindow of |old_display| is already removed.
245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Instead, we can remove RootWindow and its ActivationClient in the
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // OnWindowRemoved().
247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Do nothing here.
248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BrowserStatusMonitor::OnDisplayMetricsChanged(const gfx::Display&,
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                   uint32_t) {
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do nothing here.
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::ActiveTabChanged(content::WebContents* old_contents,
256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                            content::WebContents* new_contents,
257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                            int index,
258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                            int reason) {
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Browser* browser = NULL;
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Use |new_contents|. |old_contents| could be NULL.
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(new_contents);
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  browser = chrome::FindBrowserWithWebContents(new_contents);
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (browser && browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromeLauncherController::AppState state =
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ChromeLauncherController::APP_STATE_INACTIVE;
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Update immediately on a tab change.
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (old_contents &&
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      (TabStripModel::kNoTab !=
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)           browser->tab_strip_model()->GetIndexOfWebContents(old_contents)))
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateAppItemState(old_contents, state);
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (new_contents) {
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    state = browser->window()->IsActive() ?
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ChromeLauncherController::APP_STATE_WINDOW_ACTIVE :
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ChromeLauncherController::APP_STATE_ACTIVE;
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateAppItemState(new_contents, state);
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateBrowserItemState();
2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SetShelfIDForBrowserWindowContents(browser, new_contents);
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::TabReplacedAt(TabStripModel* tab_strip_model,
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         content::WebContents* old_contents,
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         content::WebContents* new_contents,
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         int index) {
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(old_contents && new_contents);
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithWebContents(new_contents);
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (browser && browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAppItemState(old_contents,
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     ChromeLauncherController::APP_STATE_REMOVED);
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RemoveWebContentsObserver(old_contents);
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromeLauncherController::AppState state =
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ChromeLauncherController::APP_STATE_ACTIVE;
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (browser->window()->IsActive() &&
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      (tab_strip_model->GetActiveWebContents() == new_contents))
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE;
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAppItemState(new_contents, state);
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateBrowserItemState();
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (tab_strip_model->GetActiveWebContents() == new_contents)
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SetShelfIDForBrowserWindowContents(browser, new_contents);
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddWebContentsObserver(new_contents);
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BrowserStatusMonitor::TabInsertedAt(content::WebContents* contents,
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                         int index,
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                         bool foreground) {
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // An inserted tab is not active - ActiveTabChanged() will be called to
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // activate. We initialize therefore with |APP_STATE_INACTIVE|.
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAppItemState(contents,
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     ChromeLauncherController::APP_STATE_INACTIVE);
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddWebContentsObserver(contents);
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::TabClosingAt(TabStripModel* tab_strip_mode,
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        content::WebContents* contents,
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        int index) {
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateAppItemState(contents,
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     ChromeLauncherController::APP_STATE_REMOVED);
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RemoveWebContentsObserver(contents);
330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BrowserStatusMonitor::WebContentsDestroyed(
333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    content::WebContents* contents) {
334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  UpdateAppItemState(contents, ChromeLauncherController::APP_STATE_REMOVED);
335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RemoveWebContentsObserver(contents);
336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void BrowserStatusMonitor::AddV1AppToShelf(Browser* browser) {
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(browser->is_type_popup() && browser->is_app());
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  browser->tab_strip_model()->AddObserver(this);
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string app_id =
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      web_app::GetExtensionIdFromApplicationName(browser->app_name());
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!app_id.empty()) {
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    browser_to_app_id_map_[browser] = app_id;
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    launcher_controller_->LockV1AppWithID(app_id);
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void BrowserStatusMonitor::RemoveV1AppFromShelf(Browser* browser) {
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(browser->is_type_popup() && browser->is_app());
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  browser->tab_strip_model()->RemoveObserver(this);
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end()) {
3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    launcher_controller_->UnlockV1AppWithID(browser_to_app_id_map_[browser]);
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    browser_to_app_id_map_.erase(browser);
3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool BrowserStatusMonitor::IsV1AppInShelf(Browser* browser) {
3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end();
3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::AddWebContentsObserver(
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    content::WebContents* contents) {
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (webcontents_to_observer_map_.find(contents) ==
3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          webcontents_to_observer_map_.end()) {
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    webcontents_to_observer_map_[contents] =
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new LocalWebContentsObserver(contents, this);
372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserStatusMonitor::RemoveWebContentsObserver(
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::WebContents* contents) {
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(webcontents_to_observer_map_.find(contents) !=
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      webcontents_to_observer_map_.end());
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delete webcontents_to_observer_map_[contents];
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  webcontents_to_observer_map_.erase(contents);
381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID BrowserStatusMonitor::GetShelfIDForWebContents(
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WebContents* contents) {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return launcher_controller_->GetShelfIDForWebContents(contents);
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid BrowserStatusMonitor::SetShelfIDForBrowserWindowContents(
3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Browser* browser,
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    content::WebContents* web_contents) {
3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  launcher_controller_->GetBrowserShortcutLauncherItemController()->
3920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      SetShelfIDForBrowserWindowContents(browser, web_contents);
3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
394