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