4f44d57bebc0f11ea05a9d61525bca35132e693b
[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 "apps/app_window.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/profiles/profile_manager.h"
10 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
11 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
12 #include "chrome/browser/ui/host_desktop.h"
13 #include "ui/aura/window.h"
14
15 namespace {
16
17 bool ControlsWindow(aura::Window* window) {
18   return chrome::GetHostDesktopTypeForNativeWindow(window) ==
19          chrome::HOST_DESKTOP_TYPE_ASH;
20 }
21
22 }  // namespace
23
24 MultiProfileAppWindowLauncherController::
25     MultiProfileAppWindowLauncherController(ChromeLauncherController* owner)
26     : AppWindowLauncherController(owner) {}
27
28 MultiProfileAppWindowLauncherController::
29     ~MultiProfileAppWindowLauncherController() {
30   // We need to remove all Registry observers for added users.
31   for (AppWindowRegistryList::iterator it = multi_user_registry_.begin();
32        it != multi_user_registry_.end();
33        ++it)
34     (*it)->RemoveObserver(this);
35 }
36
37 void MultiProfileAppWindowLauncherController::ActiveUserChanged(
38     const std::string& user_email) {
39   // The active user has changed and we need to traverse our list of items to
40   // show / hide them one by one. To avoid that a user dependent state
41   // "survives" in a launcher item, we first delete all items making sure that
42   // nothing remains and then re-create them again.
43   for (AppWindowList::iterator it = app_window_list_.begin();
44        it != app_window_list_.end();
45        ++it) {
46     apps::AppWindow* app_window = *it;
47     Profile* profile =
48         Profile::FromBrowserContext(app_window->browser_context());
49     if (!multi_user_util::IsProfileFromActiveUser(profile) &&
50         IsRegisteredApp(app_window->GetNativeWindow()))
51       UnregisterApp(app_window->GetNativeWindow());
52   }
53   for (AppWindowList::iterator it = app_window_list_.begin();
54        it != app_window_list_.end();
55        ++it) {
56     apps::AppWindow* app_window = *it;
57     Profile* profile =
58         Profile::FromBrowserContext(app_window->browser_context());
59     if (multi_user_util::IsProfileFromActiveUser(profile) &&
60         !IsRegisteredApp(app_window->GetNativeWindow()))
61       RegisterApp(*it);
62   }
63 }
64
65 void MultiProfileAppWindowLauncherController::AdditionalUserAddedToSession(
66     Profile* profile) {
67   // Each users AppWindowRegistry needs to be observed.
68   apps::AppWindowRegistry* registry = apps::AppWindowRegistry::Get(profile);
69   multi_user_registry_.push_back(registry);
70   registry->AddObserver(this);
71 }
72
73 void MultiProfileAppWindowLauncherController::OnAppWindowAdded(
74     apps::AppWindow* app_window) {
75   if (!ControlsWindow(app_window->GetNativeWindow()))
76     return;
77   app_window_list_.push_back(app_window);
78   Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
79   if (multi_user_util::IsProfileFromActiveUser(profile)) {
80     RegisterApp(app_window);
81   } else {
82     // If the window got created for a non active user but the user allowed to
83     // teleport to the current user's desktop, we teleport it now.
84     if (UserHasAppOnActiveDesktop(app_window)) {
85       chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
86           app_window->GetNativeWindow(),
87           multi_user_util::GetCurrentUserId());
88       if (app_window->GetNativeWindow()->type() == ui::wm::WINDOW_TYPE_PANEL &&
89           !app_window->GetNativeWindow()->layer()->GetTargetOpacity()) {
90         // The panel layout manager only manages windows which are anchored.
91         // Since this window did never had an anchor, it would stay hidden. We
92         // therefore make it visible now.
93         app_window->GetNativeWindow()->layer()->SetOpacity(1.0f);
94       }
95     }
96   }
97 }
98
99 void MultiProfileAppWindowLauncherController::OnAppWindowRemoved(
100     apps::AppWindow* app_window) {
101   if (!ControlsWindow(app_window->GetNativeWindow()))
102     return;
103
104   // If the application is registered with AppWindowLauncher (because the user
105   // is currently active), the OnWindowDestroying observer has already (or will
106   // soon) unregister it independently from the shelf. If it was not registered
107   // we don't need to do anything anyways. As such, all which is left to do here
108   // is to get rid of our own reference.
109   AppWindowList::iterator it =
110       std::find(app_window_list_.begin(), app_window_list_.end(), app_window);
111   DCHECK(it != app_window_list_.end());
112   app_window_list_.erase(it);
113 }
114
115 bool MultiProfileAppWindowLauncherController::UserHasAppOnActiveDesktop(
116     apps::AppWindow* app_window) {
117   const std::string& app_id = app_window->extension_id();
118   content::BrowserContext* app_context = app_window->browser_context();
119   DCHECK(!app_context->IsOffTheRecord());
120   const std::string& current_user = multi_user_util::GetCurrentUserId();
121   chrome::MultiUserWindowManager* manager =
122       chrome::MultiUserWindowManager::GetInstance();
123   for (AppWindowList::iterator it = app_window_list_.begin();
124        it != app_window_list_.end();
125        ++it) {
126     apps::AppWindow* other_window = *it;
127     DCHECK(!other_window->browser_context()->IsOffTheRecord());
128     if (manager->IsWindowOnDesktopOfUser(other_window->GetNativeWindow(),
129                                          current_user) &&
130         app_id == other_window->extension_id() &&
131         app_context == other_window->browser_context()) {
132       return true;
133     }
134   }
135   return false;
136 }