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.
5 #ifndef CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_CHROMEOS_H_
6 #define CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_CHROMEOS_H_
11 #include "ash/session/session_state_observer.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "ui/aura/window_observer.h"
19 #include "ui/wm/core/transient_window_observer.h"
22 class MultiUserNotificationBlockerChromeOS
;
23 class MultiUserNotificationBlockerChromeOSTest
;
35 class MultiUserWindowManagerChromeOSTest
;
42 class UserSwichAnimatorChromeOS
;
44 // This ChromeOS implementation of the MultiUserWindowManager interface is
45 // detecting app and browser creations, tagging their windows automatically and
46 // using (currently) show and hide to make the owned windows visible - or not.
47 // If it becomes necessary, the function |SetWindowVisibility| can be
48 // overwritten to match new ways of doing this.
50 // - aura::Window::Hide() is currently hiding the window and all owned transient
51 // children. However aura::Window::Show() is only showing the window itself.
52 // To address that, all transient children (and their children) are remembered
53 // in |transient_window_to_visibility_| and monitored to keep track of the
54 // visibility changes from the owning user. This way the visibility can be
55 // changed back to its requested state upon showing by us - or when the window
56 // gets detached from its current owning parent.
57 class MultiUserWindowManagerChromeOS
58 : public MultiUserWindowManager
,
59 public ash::SessionStateObserver
,
60 public aura::WindowObserver
,
61 public content::NotificationObserver
,
62 public wm::TransientWindowObserver
{
64 // The speed which should be used to perform animations.
66 ANIMATION_SPEED_NORMAL
, // The normal animation speed.
67 ANIMATION_SPEED_FAST
, // Unit test speed which test animations.
68 ANIMATION_SPEED_DISABLED
// Unit tests which do not require animations.
71 // Create the manager and use |active_user_id| as the active user.
72 explicit MultiUserWindowManagerChromeOS(const std::string
& active_user_id
);
73 virtual ~MultiUserWindowManagerChromeOS();
75 // MultiUserWindowManager overrides:
76 virtual void SetWindowOwner(
77 aura::Window
* window
, const std::string
& user_id
) OVERRIDE
;
78 virtual const std::string
& GetWindowOwner(
79 aura::Window
* window
) const OVERRIDE
;
80 virtual void ShowWindowForUser(
81 aura::Window
* window
, const std::string
& user_id
) OVERRIDE
;
82 virtual bool AreWindowsSharedAmongUsers() const OVERRIDE
;
83 virtual void GetOwnersOfVisibleWindows(
84 std::set
<std::string
>* user_ids
) const OVERRIDE
;
85 virtual bool IsWindowOnDesktopOfUser(
87 const std::string
& user_id
) const OVERRIDE
;
88 virtual const std::string
& GetUserPresentingWindow(
89 aura::Window
* window
) const OVERRIDE
;
90 virtual void AddUser(content::BrowserContext
* context
) OVERRIDE
;
91 virtual void AddObserver(Observer
* observer
) OVERRIDE
;
92 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
;
94 // SessionStateObserver overrides:
95 virtual void ActiveUserChanged(const std::string
& user_id
) OVERRIDE
;
97 // WindowObserver overrides:
98 virtual void OnWindowDestroyed(aura::Window
* window
) OVERRIDE
;
99 virtual void OnWindowVisibilityChanging(aura::Window
* window
,
100 bool visible
) OVERRIDE
;
101 virtual void OnWindowVisibilityChanged(aura::Window
* window
,
102 bool visible
) OVERRIDE
;
104 // TransientWindowObserver overrides:
105 virtual void OnTransientChildAdded(aura::Window
* window
,
106 aura::Window
* transient
) OVERRIDE
;
107 virtual void OnTransientChildRemoved(aura::Window
* window
,
108 aura::Window
* transient
) OVERRIDE
;
110 // content::NotificationObserver overrides:
111 virtual void Observe(int type
,
112 const content::NotificationSource
& source
,
113 const content::NotificationDetails
& details
) OVERRIDE
;
115 // Disable any animations for unit tests.
116 void SetAnimationSpeedForTest(AnimationSpeed speed
);
118 // Returns true when a user switch animation is running. For unit tests.
119 bool IsAnimationRunningForTest();
121 // Returns the current user for unit tests.
122 const std::string
& GetCurrentUserForTest() const;
125 friend class UserSwichAnimatorChromeOS
;
129 explicit WindowEntry(const std::string
& user_id
)
131 show_for_user_(user_id
),
133 virtual ~WindowEntry() {}
135 // Returns the owner of this window. This cannot be changed.
136 const std::string
& owner() const { return owner_
; }
138 // Returns the user for which this should be shown.
139 const std::string
& show_for_user() const { return show_for_user_
; }
141 // Returns if the window should be shown for the "show user" or not.
142 bool show() const { return show_
; }
144 // Set the user which will display the window on the owned desktop. If
145 // an empty user id gets passed the owner will be used.
146 void set_show_for_user(const std::string
& user_id
) {
147 show_for_user_
= user_id
.empty() ? owner_
: user_id
;
150 // Sets if the window gets shown for the active user or not.
151 void set_show(bool show
) { show_
= show
; }
154 // The user id of the owner of this window.
155 const std::string owner_
;
157 // The user id of the user on which desktop the window gets shown.
158 std::string show_for_user_
;
160 // True if the window should be visible for the user which shows the window.
163 DISALLOW_COPY_AND_ASSIGN(WindowEntry
);
166 typedef std::map
<aura::Window
*, WindowEntry
*> WindowToEntryMap
;
168 // Show a window for a user without switching the user.
169 // Returns true when the window moved to a new desktop.
170 bool ShowWindowForUserIntern(aura::Window
* window
,
171 const std::string
& user_id
);
173 // Show / hide the given window. Note: By not doing this within the functions,
174 // this allows to either switching to different ways to show/hide and / or to
175 // distinguish state changes performed by this class vs. state changes
176 // performed by the others. Note furthermore that system modal dialogs will
177 // not get hidden. We will switch instead to the owners desktop.
178 // The |animation_time_in_ms| is the time the animation should take. Set to 0
179 // if it should get set instantly.
180 void SetWindowVisibility(aura::Window
* window
,
182 int animation_time_in_ms
);
184 const WindowToEntryMap
& window_to_entry() { return window_to_entry_
; }
185 MultiUserNotificationBlockerChromeOS
* notification_blocker() {
186 return notification_blocker_
.get();
190 friend class ::MultiUserNotificationBlockerChromeOSTest
;
191 friend class ash::test::MultiUserWindowManagerChromeOSTest
;
193 typedef std::map
<std::string
, AppObserver
*> UserIDToAppWindowObserver
;
194 typedef std::map
<aura::Window
*, bool> TransientWindowToVisibility
;
196 // Add a browser window to the system so that the owner can be remembered.
197 void AddBrowserWindow(Browser
* browser
);
199 // Show the window and its transient children. However - if a transient child
200 // was turned invisible by some other operation, it will stay invisible.
201 // Use the given |animation_time_in_ms| for transitioning.
202 void ShowWithTransientChildrenRecursive(aura::Window
* window
,
203 int animation_time_in_ms
);
205 // Find the first owned window in the chain.
206 // Returns NULL when the window itself is owned.
207 aura::Window
* GetOwningWindowInTransientChain(aura::Window
* window
) const;
209 // A |window| and its children were attached as transient children to an
210 // |owning_parent| and need to be registered. Note that the |owning_parent|
211 // itself will not be registered, but its children will.
212 void AddTransientOwnerRecursive(aura::Window
* window
,
213 aura::Window
* owning_parent
);
215 // A window and its children were removed from its parent and can be
217 void RemoveTransientOwnerRecursive(aura::Window
* window
);
219 // Animate a |window| to be |visible| in |animation_time_in_ms|.
220 void SetWindowVisible(aura::Window
* window
,
222 int aimation_time_in_ms
);
224 // Get the animation time in milliseconds dependent on the |AnimationSpeed|
225 // from the passed |default_time_in_ms|.
226 int GetAdjustedAnimationTimeInMS(int default_time_in_ms
) const;
228 // A lookup to see to which user the given window belongs to, where and if it
230 WindowToEntryMap window_to_entry_
;
232 // A list of all known users and their app window observers.
233 UserIDToAppWindowObserver user_id_to_app_observer_
;
235 // An observer list to be notified upon window owner changes.
236 ObserverList
<Observer
> observers_
;
238 // A map which remembers for owned transient windows their own visibility.
239 TransientWindowToVisibility transient_window_to_visibility_
;
241 // The currently selected active user. It is used to find the proper
242 // visibility state in various cases. The state is stored here instead of
243 // being read from the user manager to be in sync while a switch occurs.
244 std::string current_user_id_
;
246 // The blocker which controls the desktop notification visibility based on the
247 // current multi-user status.
248 scoped_ptr
<MultiUserNotificationBlockerChromeOS
> notification_blocker_
;
250 // The notification registrar to track the creation of browser windows.
251 content::NotificationRegistrar registrar_
;
253 // Suppress changes to the visibility flag while we are changing it ourselves.
254 bool suppress_visibility_changes_
;
256 // Caching the current multi profile mode since the detection which mode is
257 // used is quite expensive.
258 static MultiProfileMode multi_user_mode_
;
260 // The speed which is used to perform any animations.
261 AnimationSpeed animation_speed_
;
263 // The animation between users.
264 scoped_ptr
<UserSwichAnimatorChromeOS
> animation_
;
266 DISALLOW_COPY_AND_ASSIGN(MultiUserWindowManagerChromeOS
);
269 } // namespace chrome
271 #endif // CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_CHROMEOS_H_