forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmulti_user_window_manager_impl.h
243 lines (189 loc) · 9.69 KB
/
multi_user_window_manager_impl.h
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
// Copyright 2018 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 ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_
#define ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_
#include <map>
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/cpp/multi_user_window_manager.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/tablet_mode_observer.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "components/account_id/account_id.h"
#include "ui/aura/window_observer.h"
#include "ui/wm/core/transient_window_observer.h"
namespace ash {
class MultiUserWindowManagerDelegate;
class UserSwitchAnimator;
// MultiUserWindowManager associates windows with users and ensures the
// appropriate set of windows are visible at the right time.
// MultiUserWindowManager must be explicitly told about the windows to manage.
// This is done by way of SetWindowOwner().
//
// Each window may be associated with two accounts. The owning account (the
// account supplied to SetWindowOwner()), and an account the window is shown
// with when the account is active. Typically the 'shown' account and 'owning'
// account are the same, but the user may choose to show a window from an other
// account, in which case the 'shown' account changes.
//
// 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 ASH_EXPORT MultiUserWindowManagerImpl
: public MultiUserWindowManager,
public SessionObserver,
public aura::WindowObserver,
public ::wm::TransientWindowObserver,
public TabletModeObserver {
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.
};
MultiUserWindowManagerImpl(MultiUserWindowManagerDelegate* delegate,
const AccountId& account_id);
MultiUserWindowManagerImpl(const MultiUserWindowManagerImpl&) = delete;
MultiUserWindowManagerImpl& operator=(const MultiUserWindowManagerImpl&) =
delete;
~MultiUserWindowManagerImpl() override;
static MultiUserWindowManagerImpl* Get();
// Called when the active account change is complete.
void OnDidSwitchActiveAccount();
// MultiUserWindowManager:
void SetWindowOwner(aura::Window* window,
const AccountId& account_id) override;
void ShowWindowForUser(aura::Window* window,
const AccountId& account_id) override;
const AccountId& GetWindowOwner(const aura::Window* window) const override;
bool AreWindowsSharedAmongUsers() const override;
std::set<AccountId> GetOwnersOfVisibleWindows() const override;
const AccountId& GetUserPresentingWindow(
const aura::Window* window) const override;
const AccountId& CurrentAccountId() const override;
void AddObserver(MultiUserWindowManagerObserver* observer) override;
void RemoveObserver(MultiUserWindowManagerObserver* observer) override;
// SessionObserver:
void OnActiveUserSessionChanged(const AccountId& account_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;
// TabletModeObserver:
void OnTabletModeStarted() 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 AccountId& GetCurrentUserForTest() const;
private:
friend class MultiProfileSupportTest;
friend class UserSwitchAnimator;
class WindowEntry {
public:
explicit WindowEntry(const AccountId& account_id);
WindowEntry(const WindowEntry&) = delete;
WindowEntry& operator=(const WindowEntry&) = delete;
~WindowEntry();
// Returns the owner of this window. This cannot be changed.
const AccountId& owner() const { return owner_; }
// Returns the user for which this should be shown.
const AccountId& 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 AccountId& account_id) {
show_for_user_ = account_id.is_valid() ? account_id : owner_;
}
// 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 AccountId owner_;
// The user id of the user on which desktop the window gets shown.
AccountId show_for_user_;
// True if the window should be visible for the user which shows the window.
bool show_ = true;
};
using TransientWindowToVisibility = base::flat_map<aura::Window*, bool>;
using WindowToEntryMap =
std::map<aura::Window*, std::unique_ptr<WindowEntry>>;
// Returns true if the 'shown' owner of |window| is |account_id|.
bool IsWindowOnDesktopOfUser(aura::Window* window,
const AccountId& account_id) const;
// Returns the 'shown' owner.
const AccountId& GetUserPresentingWindow(aura::Window* window) const;
// 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 AccountId& account_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| is the time the animation should take, an empty value
// switches instantly.
void SetWindowVisibility(aura::Window* window,
bool visible,
base::TimeDelta animation_time = base::TimeDelta());
const WindowToEntryMap& window_to_entry() { return window_to_entry_; }
// Show the window and its transient children. However - if a transient child
// was turned invisible by some other operation, it will stay invisible.
// |animation_time| is the amount of time to animate.
void ShowWithTransientChildrenRecursive(aura::Window* window,
base::TimeDelta animation_time);
// 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| over a time of |animation_time|.
void SetWindowVisible(aura::Window* window,
bool visible,
base::TimeDelta aimation_time);
// Returns the time for an animation.
base::TimeDelta GetAdjustedAnimationTime(base::TimeDelta default_time) const;
MultiUserWindowManagerDelegate* delegate_;
// A lookup to see to which user the given window belongs to, where and if it
// should get shown.
WindowToEntryMap window_to_entry_;
// 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.
AccountId current_account_id_;
// Suppress changes to the visibility flag while we are changing it ourselves.
bool suppress_visibility_changes_ = false;
// The speed which is used to perform any animations.
AnimationSpeed animation_speed_ = ANIMATION_SPEED_NORMAL;
// The animation between users.
std::unique_ptr<UserSwitchAnimator> animation_;
base::ObserverList<MultiUserWindowManagerObserver>::Unchecked observers_;
};
} // namespace ash
#endif // ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_