1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/ash/launcher/multi_profile_browser_status_monitor.h"
6
7#include "ash/shelf/shelf_util.h"
8#include "chrome/browser/profiles/profile.h"
9#include "chrome/browser/profiles/profile_manager.h"
10#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
11#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/browser/ui/browser_list.h"
14#include "chrome/browser/ui/browser_tabstrip.h"
15#include "chrome/browser/ui/browser_window.h"
16#include "chrome/browser/ui/settings_window_manager.h"
17#include "chrome/browser/ui/tabs/tab_strip_model.h"
18#include "grit/ash_resources.h"
19
20MultiProfileBrowserStatusMonitor::MultiProfileBrowserStatusMonitor(
21    ChromeLauncherController* launcher_controller)
22    : BrowserStatusMonitor(launcher_controller),
23      launcher_controller_(launcher_controller) {
24}
25
26MultiProfileBrowserStatusMonitor::~MultiProfileBrowserStatusMonitor() {
27}
28
29void MultiProfileBrowserStatusMonitor::ActiveUserChanged(
30    const std::string& user_email) {
31  // Handle windowed apps.
32  for (AppList::iterator it = app_list_.begin(); it != app_list_.end(); ++it) {
33    bool owned = multi_user_util::IsProfileFromActiveUser((*it)->profile());
34    bool shown = IsV1AppInShelf(*it);
35    if (owned && !shown)
36      ConnectV1AppToLauncher(*it);
37    else if (!owned && shown)
38      DisconnectV1AppFromLauncher(*it);
39  }
40
41  // Handle apps in browser tabs: Add the new applications.
42  BrowserList* browser_list =
43      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
44
45  // Remove old (tabbed V1) applications.
46  for (BrowserList::const_iterator it = browser_list->begin();
47       it != browser_list->end(); ++it) {
48    Browser* browser = *it;
49    if (!browser->is_app() &&
50        browser->is_type_tabbed() &&
51        !multi_user_util::IsProfileFromActiveUser(browser->profile())) {
52      for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
53        launcher_controller_->UpdateAppState(
54            browser->tab_strip_model()->GetWebContentsAt(i),
55            ChromeLauncherController::APP_STATE_REMOVED);
56      }
57    }
58  }
59
60  // Handle apps in browser tabs: Add new (tabbed V1) applications.
61  for (BrowserList::const_iterator it = browser_list->begin();
62       it != browser_list->end(); ++it) {
63    Browser* browser = *it;
64    if (!browser->is_app() &&
65        browser->is_type_tabbed() &&
66        multi_user_util::IsProfileFromActiveUser(browser->profile())) {
67      int active_index = browser->tab_strip_model()->active_index();
68      for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
69        launcher_controller_->UpdateAppState(
70            browser->tab_strip_model()->GetWebContentsAt(i),
71            browser->window()->IsActive() && i == active_index ?
72                ChromeLauncherController::APP_STATE_WINDOW_ACTIVE :
73                ChromeLauncherController::APP_STATE_INACTIVE);
74      }
75    }
76  }
77
78  // Remove settings window icons not associated with this profile and create
79  // icons for windows associated with the current profile.
80  for (BrowserList::const_iterator it = browser_list->begin();
81       it != browser_list->end(); ++it) {
82    Browser* browser = *it;
83    if (!chrome::SettingsWindowManager::GetInstance()->IsSettingsBrowser(
84            browser)) {
85      continue;
86    }
87    if (multi_user_util::IsProfileFromActiveUser(browser->profile())) {
88      ash::SetShelfItemDetailsForDialogWindow(
89          browser->window()->GetNativeWindow(),
90          IDR_ASH_SHELF_ICON_SETTINGS);
91    } else {
92      ash::ClearShelfItemDetailsForWindow(browser->window()->GetNativeWindow());
93    }
94  }
95
96  // Update the browser state since some of the removals / adds above might have
97  // had an impact on the browser item.
98  UpdateBrowserItemState();
99}
100
101void MultiProfileBrowserStatusMonitor::AddV1AppToShelf(Browser* browser) {
102  DCHECK(browser->is_type_popup() && browser->is_app());
103  DCHECK(std::find(app_list_.begin(), app_list_.end(), browser) ==
104             app_list_.end());
105  app_list_.push_back(browser);
106  if (multi_user_util::IsProfileFromActiveUser(browser->profile())) {
107    BrowserStatusMonitor::AddV1AppToShelf(browser);
108  }
109}
110
111void MultiProfileBrowserStatusMonitor::RemoveV1AppFromShelf(Browser* browser) {
112  DCHECK(browser->is_type_popup() && browser->is_app());
113  AppList::iterator it = std::find(app_list_.begin(), app_list_.end(), browser);
114  DCHECK(it != app_list_.end());
115  app_list_.erase(it);
116  if (multi_user_util::IsProfileFromActiveUser(browser->profile())) {
117    BrowserStatusMonitor::RemoveV1AppFromShelf(browser);
118  }
119}
120
121void MultiProfileBrowserStatusMonitor::ConnectV1AppToLauncher(
122    Browser* browser) {
123  // Adding a V1 app to the launcher consists of two actions: Add the browser
124  // (launcher item) and add the content (launcher item status).
125  BrowserStatusMonitor::AddV1AppToShelf(browser);
126  launcher_controller_->UpdateAppState(
127      browser->tab_strip_model()->GetActiveWebContents(),
128      ChromeLauncherController::APP_STATE_INACTIVE);
129}
130
131void MultiProfileBrowserStatusMonitor::DisconnectV1AppFromLauncher(
132    Browser* browser) {
133  // Removing a V1 app from the launcher requires to remove the content and
134  // the launcher item.
135  launcher_controller_->UpdateAppState(
136      browser->tab_strip_model()->GetActiveWebContents(),
137      ChromeLauncherController::APP_STATE_REMOVED);
138  BrowserStatusMonitor::RemoveV1AppFromShelf(browser);
139}
140