Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / ash / launcher / multi_profile_app_window_launcher_controller.cc
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.
4
5 #include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h"
6
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"
15
16 namespace {
17
18 bool ControlsWindow(aura::Window* window) {
19   return chrome::GetHostDesktopTypeForNativeWindow(window) ==
20          chrome::HOST_DESKTOP_TYPE_ASH;
21 }
22
23 }  // namespace
24
25 MultiProfileAppWindowLauncherController::
26     MultiProfileAppWindowLauncherController(ChromeLauncherController* owner)
27     : AppWindowLauncherController(owner) {}
28
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);
36 }
37
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());
53   }
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);
65   }
66 }
67
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);
75 }
76
77 void MultiProfileAppWindowLauncherController::OnAppWindowAdded(
78     extensions::AppWindow* app_window) {
79   if (!ControlsWindow(app_window->GetNativeWindow()))
80     return;
81
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());
90   }
91 }
92
93 void MultiProfileAppWindowLauncherController::OnAppWindowShown(
94     extensions::AppWindow* app_window) {
95   if (!ControlsWindow(app_window->GetNativeWindow()))
96     return;
97
98   Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
99
100   if (multi_user_util::IsProfileFromActiveUser(profile) &&
101       !IsRegisteredApp(app_window->GetNativeWindow())) {
102     RegisterApp(app_window);
103     return;
104   }
105
106   // The panel layout manager only manages windows which are anchored.
107   // Since this window did never had an anchor, it would stay hidden. We
108   // therefore make it visible now.
109   if (UserHasAppOnActiveDesktop(app_window) &&
110       app_window->GetNativeWindow()->type() == ui::wm::WINDOW_TYPE_PANEL &&
111       !app_window->GetNativeWindow()->layer()->GetTargetOpacity()) {
112     app_window->GetNativeWindow()->layer()->SetOpacity(1.0f);
113   }
114 }
115
116 void MultiProfileAppWindowLauncherController::OnAppWindowHidden(
117     extensions::AppWindow* app_window) {
118   if (!ControlsWindow(app_window->GetNativeWindow()))
119     return;
120
121   Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
122   if (multi_user_util::IsProfileFromActiveUser(profile) &&
123       IsRegisteredApp(app_window->GetNativeWindow())) {
124     UnregisterApp(app_window->GetNativeWindow());
125   }
126 }
127
128 void MultiProfileAppWindowLauncherController::OnAppWindowRemoved(
129     extensions::AppWindow* app_window) {
130   if (!ControlsWindow(app_window->GetNativeWindow()))
131     return;
132
133   // If the application is registered with AppWindowLauncher (because the user
134   // is currently active), the OnWindowDestroying observer has already (or will
135   // soon) unregister it independently from the shelf. If it was not registered
136   // we don't need to do anything anyways. As such, all which is left to do here
137   // is to get rid of our own reference.
138   AppWindowList::iterator it =
139       std::find(app_window_list_.begin(), app_window_list_.end(), app_window);
140   DCHECK(it != app_window_list_.end());
141   app_window_list_.erase(it);
142 }
143
144 bool MultiProfileAppWindowLauncherController::UserHasAppOnActiveDesktop(
145     extensions::AppWindow* app_window) {
146   const std::string& app_id = app_window->extension_id();
147   content::BrowserContext* app_context = app_window->browser_context();
148   DCHECK(!app_context->IsOffTheRecord());
149   const std::string& current_user = multi_user_util::GetCurrentUserId();
150   chrome::MultiUserWindowManager* manager =
151       chrome::MultiUserWindowManager::GetInstance();
152   for (AppWindowList::iterator it = app_window_list_.begin();
153        it != app_window_list_.end();
154        ++it) {
155     extensions::AppWindow* other_window = *it;
156     DCHECK(!other_window->browser_context()->IsOffTheRecord());
157     if (manager->IsWindowOnDesktopOfUser(other_window->GetNativeWindow(),
158                                          current_user) &&
159         app_id == other_window->extension_id() &&
160         app_context == other_window->browser_context()) {
161       return true;
162     }
163   }
164   return false;
165 }