Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / ash / launcher / multi_profile_app_window_launcher_controller.cc
blob00e8c7379ed6a1c4c18ac5bd400f9cad9a12356a
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h"
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/profiles/profile_manager.h"
9 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
10 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
11 #include "chrome/browser/ui/host_desktop.h"
12 #include "extensions/browser/app_window/app_window.h"
13 #include "extensions/browser/app_window/native_app_window.h"
14 #include "ui/aura/window.h"
16 namespace {
18 bool ControlsWindow(aura::Window* window) {
19 return chrome::GetHostDesktopTypeForNativeWindow(window) ==
20 chrome::HOST_DESKTOP_TYPE_ASH;
23 } // namespace
25 MultiProfileAppWindowLauncherController::
26 MultiProfileAppWindowLauncherController(ChromeLauncherController* owner)
27 : AppWindowLauncherController(owner) {}
29 MultiProfileAppWindowLauncherController::
30 ~MultiProfileAppWindowLauncherController() {
31 // We need to remove all Registry observers for added users.
32 for (AppWindowRegistryList::iterator it = multi_user_registry_.begin();
33 it != multi_user_registry_.end();
34 ++it)
35 (*it)->RemoveObserver(this);
38 void MultiProfileAppWindowLauncherController::ActiveUserChanged(
39 const std::string& user_email) {
40 // The active user has changed and we need to traverse our list of items to
41 // show / hide them one by one. To avoid that a user dependent state
42 // "survives" in a launcher item, we first delete all items making sure that
43 // nothing remains and then re-create them again.
44 for (AppWindowList::iterator it = app_window_list_.begin();
45 it != app_window_list_.end();
46 ++it) {
47 extensions::AppWindow* app_window = *it;
48 Profile* profile =
49 Profile::FromBrowserContext(app_window->browser_context());
50 if (!multi_user_util::IsProfileFromActiveUser(profile) &&
51 IsRegisteredApp(app_window->GetNativeWindow()))
52 UnregisterApp(app_window->GetNativeWindow());
54 for (AppWindowList::iterator it = app_window_list_.begin();
55 it != app_window_list_.end();
56 ++it) {
57 extensions::AppWindow* app_window = *it;
58 Profile* profile =
59 Profile::FromBrowserContext(app_window->browser_context());
60 if (multi_user_util::IsProfileFromActiveUser(profile) &&
61 !IsRegisteredApp(app_window->GetNativeWindow()) &&
62 (app_window->GetBaseWindow()->IsMinimized() ||
63 app_window->GetNativeWindow()->IsVisible()))
64 RegisterApp(*it);
68 void MultiProfileAppWindowLauncherController::AdditionalUserAddedToSession(
69 Profile* profile) {
70 // Each users AppWindowRegistry needs to be observed.
71 extensions::AppWindowRegistry* registry =
72 extensions::AppWindowRegistry::Get(profile);
73 multi_user_registry_.push_back(registry);
74 registry->AddObserver(this);
77 void MultiProfileAppWindowLauncherController::OnAppWindowAdded(
78 extensions::AppWindow* app_window) {
79 if (!ControlsWindow(app_window->GetNativeWindow()))
80 return;
82 app_window_list_.push_back(app_window);
83 Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
84 // If the window got created for a non active user but the user allowed to
85 // teleport to the current user's desktop, we teleport it now.
86 if (!multi_user_util::IsProfileFromActiveUser(profile) &&
87 UserHasAppOnActiveDesktop(app_window)) {
88 chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
89 app_window->GetNativeWindow(), multi_user_util::GetCurrentUserId());
93 void MultiProfileAppWindowLauncherController::OnAppWindowShown(
94 extensions::AppWindow* app_window,
95 bool was_hidden) {
96 if (!ControlsWindow(app_window->GetNativeWindow()))
97 return;
99 Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
101 if (multi_user_util::IsProfileFromActiveUser(profile) &&
102 !IsRegisteredApp(app_window->GetNativeWindow())) {
103 RegisterApp(app_window);
104 return;
107 // The panel layout manager only manages windows which are anchored.
108 // Since this window did never had an anchor, it would stay hidden. We
109 // therefore make it visible now.
110 if (UserHasAppOnActiveDesktop(app_window) &&
111 app_window->GetNativeWindow()->type() == ui::wm::WINDOW_TYPE_PANEL &&
112 !app_window->GetNativeWindow()->layer()->GetTargetOpacity()) {
113 app_window->GetNativeWindow()->layer()->SetOpacity(1.0f);
117 void MultiProfileAppWindowLauncherController::OnAppWindowHidden(
118 extensions::AppWindow* app_window) {
119 if (!ControlsWindow(app_window->GetNativeWindow()))
120 return;
122 Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
123 if (multi_user_util::IsProfileFromActiveUser(profile) &&
124 IsRegisteredApp(app_window->GetNativeWindow())) {
125 UnregisterApp(app_window->GetNativeWindow());
129 void MultiProfileAppWindowLauncherController::OnAppWindowRemoved(
130 extensions::AppWindow* app_window) {
131 if (!ControlsWindow(app_window->GetNativeWindow()))
132 return;
134 // If the application is registered with AppWindowLauncher (because the user
135 // is currently active), the OnWindowDestroying observer has already (or will
136 // soon) unregister it independently from the shelf. If it was not registered
137 // we don't need to do anything anyways. As such, all which is left to do here
138 // is to get rid of our own reference.
139 AppWindowList::iterator it =
140 std::find(app_window_list_.begin(), app_window_list_.end(), app_window);
141 DCHECK(it != app_window_list_.end());
142 app_window_list_.erase(it);
145 bool MultiProfileAppWindowLauncherController::UserHasAppOnActiveDesktop(
146 extensions::AppWindow* app_window) {
147 const std::string& app_id = app_window->extension_id();
148 content::BrowserContext* app_context = app_window->browser_context();
149 DCHECK(!app_context->IsOffTheRecord());
150 const std::string& current_user = multi_user_util::GetCurrentUserId();
151 chrome::MultiUserWindowManager* manager =
152 chrome::MultiUserWindowManager::GetInstance();
153 for (AppWindowList::iterator it = app_window_list_.begin();
154 it != app_window_list_.end();
155 ++it) {
156 extensions::AppWindow* other_window = *it;
157 DCHECK(!other_window->browser_context()->IsOffTheRecord());
158 if (manager->IsWindowOnDesktopOfUser(other_window->GetNativeWindow(),
159 current_user) &&
160 app_id == other_window->extension_id() &&
161 app_context == other_window->browser_context()) {
162 return true;
165 return false;