multi_user_window_manager_impl.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright 2018 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. #ifndef ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_
  5. #define ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_
  6. #include <map>
  7. #include <memory>
  8. #include "ash/ash_export.h"
  9. #include "ash/public/cpp/multi_user_window_manager.h"
  10. #include "ash/public/cpp/session/session_observer.h"
  11. #include "ash/public/cpp/tablet_mode_observer.h"
  12. #include "base/containers/flat_map.h"
  13. #include "base/observer_list.h"
  14. #include "base/time/time.h"
  15. #include "components/account_id/account_id.h"
  16. #include "ui/aura/window_observer.h"
  17. #include "ui/wm/core/transient_window_observer.h"
  18. namespace ash {
  19. class MultiUserWindowManagerDelegate;
  20. class UserSwitchAnimator;
  21. // MultiUserWindowManager associates windows with users and ensures the
  22. // appropriate set of windows are visible at the right time.
  23. // MultiUserWindowManager must be explicitly told about the windows to manage.
  24. // This is done by way of SetWindowOwner().
  25. //
  26. // Each window may be associated with two accounts. The owning account (the
  27. // account supplied to SetWindowOwner()), and an account the window is shown
  28. // with when the account is active. Typically the 'shown' account and 'owning'
  29. // account are the same, but the user may choose to show a window from an other
  30. // account, in which case the 'shown' account changes.
  31. //
  32. // Note:
  33. // - aura::Window::Hide() is currently hiding the window and all owned transient
  34. // children. However aura::Window::Show() is only showing the window itself.
  35. // To address that, all transient children (and their children) are remembered
  36. // in |transient_window_to_visibility_| and monitored to keep track of the
  37. // visibility changes from the owning user. This way the visibility can be
  38. // changed back to its requested state upon showing by us - or when the window
  39. // gets detached from its current owning parent.
  40. class ASH_EXPORT MultiUserWindowManagerImpl
  41. : public MultiUserWindowManager,
  42. public SessionObserver,
  43. public aura::WindowObserver,
  44. public ::wm::TransientWindowObserver,
  45. public TabletModeObserver {
  46. public:
  47. // The speed which should be used to perform animations.
  48. enum AnimationSpeed {
  49. ANIMATION_SPEED_NORMAL, // The normal animation speed.
  50. ANIMATION_SPEED_FAST, // Unit test speed which test animations.
  51. ANIMATION_SPEED_DISABLED // Unit tests which do not require animations.
  52. };
  53. MultiUserWindowManagerImpl(MultiUserWindowManagerDelegate* delegate,
  54. const AccountId& account_id);
  55. MultiUserWindowManagerImpl(const MultiUserWindowManagerImpl&) = delete;
  56. MultiUserWindowManagerImpl& operator=(const MultiUserWindowManagerImpl&) =
  57. delete;
  58. ~MultiUserWindowManagerImpl() override;
  59. static MultiUserWindowManagerImpl* Get();
  60. // MultiUserWindowManager:
  61. void SetWindowOwner(aura::Window* window,
  62. const AccountId& account_id) override;
  63. void ShowWindowForUser(aura::Window* window,
  64. const AccountId& account_id) override;
  65. const AccountId& GetWindowOwner(const aura::Window* window) const override;
  66. bool AreWindowsSharedAmongUsers() const override;
  67. std::set<AccountId> GetOwnersOfVisibleWindows() const override;
  68. const AccountId& GetUserPresentingWindow(
  69. const aura::Window* window) const override;
  70. const AccountId& CurrentAccountId() const override;
  71. // SessionObserver:
  72. void OnActiveUserSessionChanged(const AccountId& account_id) override;
  73. // WindowObserver overrides:
  74. void OnWindowDestroyed(aura::Window* window) override;
  75. void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
  76. void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
  77. // TransientWindowObserver overrides:
  78. void OnTransientChildAdded(aura::Window* window,
  79. aura::Window* transient) override;
  80. void OnTransientChildRemoved(aura::Window* window,
  81. aura::Window* transient) override;
  82. // TabletModeObserver:
  83. void OnTabletModeStarted() override;
  84. // Disable any animations for unit tests.
  85. void SetAnimationSpeedForTest(AnimationSpeed speed);
  86. // Returns true when a user switch animation is running. For unit tests.
  87. bool IsAnimationRunningForTest();
  88. // Returns the current user for unit tests.
  89. const AccountId& GetCurrentUserForTest() const;
  90. private:
  91. friend class MultiProfileSupportTest;
  92. friend class UserSwitchAnimator;
  93. class WindowEntry {
  94. public:
  95. explicit WindowEntry(const AccountId& account_id);
  96. WindowEntry(const WindowEntry&) = delete;
  97. WindowEntry& operator=(const WindowEntry&) = delete;
  98. ~WindowEntry();
  99. // Returns the owner of this window. This cannot be changed.
  100. const AccountId& owner() const { return owner_; }
  101. // Returns the user for which this should be shown.
  102. const AccountId& show_for_user() const { return show_for_user_; }
  103. // Returns if the window should be shown for the "show user" or not.
  104. bool show() const { return show_; }
  105. // Set the user which will display the window on the owned desktop. If
  106. // an empty user id gets passed the owner will be used.
  107. void set_show_for_user(const AccountId& account_id) {
  108. show_for_user_ = account_id.is_valid() ? account_id : owner_;
  109. }
  110. // Sets if the window gets shown for the active user or not.
  111. void set_show(bool show) { show_ = show; }
  112. private:
  113. // The user id of the owner of this window.
  114. const AccountId owner_;
  115. // The user id of the user on which desktop the window gets shown.
  116. AccountId show_for_user_;
  117. // True if the window should be visible for the user which shows the window.
  118. bool show_ = true;
  119. };
  120. using TransientWindowToVisibility = base::flat_map<aura::Window*, bool>;
  121. using WindowToEntryMap =
  122. std::map<aura::Window*, std::unique_ptr<WindowEntry>>;
  123. // Returns true if the 'shown' owner of |window| is |account_id|.
  124. bool IsWindowOnDesktopOfUser(aura::Window* window,
  125. const AccountId& account_id) const;
  126. // Returns the 'shown' owner.
  127. const AccountId& GetUserPresentingWindow(aura::Window* window) const;
  128. // Show a window for a user without switching the user.
  129. // Returns true when the window moved to a new desktop.
  130. bool ShowWindowForUserIntern(aura::Window* window,
  131. const AccountId& account_id);
  132. // Show / hide the given window. Note: By not doing this within the functions,
  133. // this allows to either switching to different ways to show/hide and / or to
  134. // distinguish state changes performed by this class vs. state changes
  135. // performed by the others. Note furthermore that system modal dialogs will
  136. // not get hidden. We will switch instead to the owners desktop.
  137. // The |animation_time| is the time the animation should take, an empty value
  138. // switches instantly.
  139. void SetWindowVisibility(aura::Window* window,
  140. bool visible,
  141. base::TimeDelta animation_time = base::TimeDelta());
  142. const WindowToEntryMap& window_to_entry() { return window_to_entry_; }
  143. // Show the window and its transient children. However - if a transient child
  144. // was turned invisible by some other operation, it will stay invisible.
  145. // |animation_time| is the amount of time to animate.
  146. void ShowWithTransientChildrenRecursive(aura::Window* window,
  147. base::TimeDelta animation_time);
  148. // Find the first owned window in the chain.
  149. // Returns NULL when the window itself is owned.
  150. aura::Window* GetOwningWindowInTransientChain(aura::Window* window) const;
  151. // A |window| and its children were attached as transient children to an
  152. // |owning_parent| and need to be registered. Note that the |owning_parent|
  153. // itself will not be registered, but its children will.
  154. void AddTransientOwnerRecursive(aura::Window* window,
  155. aura::Window* owning_parent);
  156. // A window and its children were removed from its parent and can be
  157. // unregistered.
  158. void RemoveTransientOwnerRecursive(aura::Window* window);
  159. // Animate a |window| to be |visible| over a time of |animation_time|.
  160. void SetWindowVisible(aura::Window* window,
  161. bool visible,
  162. base::TimeDelta aimation_time);
  163. // Returns the time for an animation.
  164. base::TimeDelta GetAdjustedAnimationTime(base::TimeDelta default_time) const;
  165. MultiUserWindowManagerDelegate* delegate_;
  166. // A lookup to see to which user the given window belongs to, where and if it
  167. // should get shown.
  168. WindowToEntryMap window_to_entry_;
  169. // A map which remembers for owned transient windows their own visibility.
  170. TransientWindowToVisibility transient_window_to_visibility_;
  171. // The currently selected active user. It is used to find the proper
  172. // visibility state in various cases. The state is stored here instead of
  173. // being read from the user manager to be in sync while a switch occurs.
  174. AccountId current_account_id_;
  175. // Suppress changes to the visibility flag while we are changing it ourselves.
  176. bool suppress_visibility_changes_ = false;
  177. // The speed which is used to perform any animations.
  178. AnimationSpeed animation_speed_ = ANIMATION_SPEED_NORMAL;
  179. // The animation between users.
  180. std::unique_ptr<UserSwitchAnimator> animation_;
  181. };
  182. } // namespace ash
  183. #endif // ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_IMPL_H_