1 // Copyright (c) 2012 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 #ifndef ASH_ROOT_WINDOW_CONTROLLER_H_
6 #define ASH_ROOT_WINDOW_CONTROLLER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <vector>
11 
12 #include "ash/ash_export.h"
13 #include "ash/public/cpp/shelf_types.h"
14 #include "ash/wm/workspace/workspace_types.h"
15 #include "base/macros.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_tree_host.h"
18 
19 namespace aura {
20 class Window;
21 }
22 
23 namespace gfx {
24 class Point;
25 }
26 
27 namespace ui {
28 class WindowTreeHost;
29 }
30 
31 namespace views {
32 class MenuRunner;
33 }
34 
35 namespace wm {
36 class ScopedCaptureClient;
37 }
38 
39 namespace ash {
40 class AccessibilityPanelLayoutManager;
41 class AlwaysOnTopController;
42 class AppMenuModelAdapter;
43 class AshWindowTreeHost;
44 class LockScreenActionBackgroundController;
45 enum class LoginStatus;
46 class RootWindowLayoutManager;
47 class Shelf;
48 class ShelfLayoutManager;
49 class SplitViewController;
50 class StackingController;
51 class StatusAreaWidget;
52 class SystemModalContainerLayoutManager;
53 class SystemWallpaperController;
54 class TouchExplorationManager;
55 class TouchHudDebug;
56 class TouchHudProjection;
57 class WallpaperWidgetController;
58 class WorkAreaInsets;
59 
60 // This class maintains the per root window state for ash. This class
61 // owns the root window and other dependent objects that should be
62 // deleted upon the deletion of the root window. This object is
63 // indirectly owned and deleted by |WindowTreeHostManager|.
64 // The RootWindowController for particular root window is stored in
65 // its property (RootWindowSettings) and can be obtained using
66 // |RootWindowController::ForWindow(aura::Window*)| function.
67 class ASH_EXPORT RootWindowController {
68  public:
69   // Enumerates the type of display. If there is only a single display then
70   // it is primary. In a multi-display environment one monitor is deemed the
71   // PRIMARY and all others SECONDARY.
72   enum class RootWindowType { PRIMARY, SECONDARY };
73 
74   ~RootWindowController();
75 
76   // Creates and Initialize the RootWindowController for primary display.
77   // Returns a pointer to the newly created controller.
78   static RootWindowController* CreateForPrimaryDisplay(AshWindowTreeHost* host);
79 
80   // Creates and Initialize the RootWindowController for secondary displays.
81   // Returns a pointer to the newly created controller.
82   static RootWindowController* CreateForSecondaryDisplay(
83       AshWindowTreeHost* host);
84 
85   // Returns a RootWindowController of the window's root window.
86   static RootWindowController* ForWindow(const aura::Window* window);
87 
88   // Returns the RootWindowController of the target root window.
89   static RootWindowController* ForTargetRootWindow();
90 
root_window_controllers()91   static std::vector<RootWindowController*> root_window_controllers() {
92     return root_window_controllers_ ? *root_window_controllers_
93                                     : std::vector<RootWindowController*>();
94   }
95 
ash_host()96   AshWindowTreeHost* ash_host() { return ash_host_.get(); }
ash_host()97   const AshWindowTreeHost* ash_host() const { return ash_host_.get(); }
98 
99   aura::WindowTreeHost* GetHost();
100   const aura::WindowTreeHost* GetHost() const;
101   aura::Window* GetRootWindow();
102   const aura::Window* GetRootWindow() const;
103 
split_view_controller()104   SplitViewController* split_view_controller() const {
105     return split_view_controller_.get();
106   }
107 
shelf()108   Shelf* shelf() const { return shelf_.get(); }
109 
touch_hud_debug()110   TouchHudDebug* touch_hud_debug() const { return touch_hud_debug_; }
touch_hud_projection()111   TouchHudProjection* touch_hud_projection() const {
112     return touch_hud_projection_;
113   }
114 
115   // Set touch HUDs for this root window controller. The root window controller
116   // will not own the HUDs; their lifetimes are managed by themselves. Whenever
117   // the widget showing a HUD is being destroyed (e.g. because of detaching a
118   // display), the HUD deletes itself.
set_touch_hud_debug(TouchHudDebug * hud)119   void set_touch_hud_debug(TouchHudDebug* hud) { touch_hud_debug_ = hud; }
set_touch_hud_projection(TouchHudProjection * hud)120   void set_touch_hud_projection(TouchHudProjection* hud) {
121     touch_hud_projection_ = hud;
122   }
123 
root_window_layout_manager()124   RootWindowLayoutManager* root_window_layout_manager() {
125     return root_window_layout_manager_;
126   }
127 
128   // Returns parameters of the work area associated with this root window.
work_area_insets()129   WorkAreaInsets* work_area_insets() { return work_area_insets_.get(); }
130 
131   // Access the shelf layout manager associated with this root
132   // window controller, NULL if no such shelf exists.
133   ShelfLayoutManager* GetShelfLayoutManager();
134 
135   // Returns the layout manager for the appropriate modal-container. If the
136   // window is inside the lockscreen modal container, then the layout manager
137   // for that is returned. Otherwise the layout manager for the default modal
138   // container is returned.
139   // If no window is specified (i.e. |window| is null), then the lockscreen
140   // modal container is used if the screen is currently locked. Otherwise, the
141   // default modal container is used.
142   SystemModalContainerLayoutManager* GetSystemModalLayoutManager(
143       aura::Window* window);
144 
always_on_top_controller()145   AlwaysOnTopController* always_on_top_controller() {
146     return always_on_top_controller_.get();
147   }
148 
149   // May return null, for example for a secondary monitor at the login screen.
150   StatusAreaWidget* GetStatusAreaWidget();
151 
152   // Returns if system tray and its widget is visible.
153   bool IsSystemTrayVisible();
154 
155   // True if the window can receive events on this root window.
156   bool CanWindowReceiveEvents(aura::Window* window);
157 
158   // Returns the window events will be targeted at for the specified location
159   // (in screen coordinates).
160   //
161   // NOTE: the returned window may not contain the location as resize handles
162   // may extend outside the bounds of the window.
163   aura::Window* FindEventTarget(const gfx::Point& location_in_screen);
164 
165   // Gets the last location seen in a mouse event in this root window's
166   // coordinates. This may return a point outside the root window's bounds.
167   gfx::Point GetLastMouseLocationInRoot();
168 
169   aura::Window* GetContainer(int container_id);
170   const aura::Window* GetContainer(int container_id) const;
171 
wallpaper_widget_controller()172   WallpaperWidgetController* wallpaper_widget_controller() {
173     return wallpaper_widget_controller_.get();
174   }
175 
176   LockScreenActionBackgroundController*
lock_screen_action_background_controller()177   lock_screen_action_background_controller() {
178     return lock_screen_action_background_controller_.get();
179   }
180 
181   // Deletes associated objects and clears the state, but doesn't delete
182   // the root window yet. This is used to delete a secondary displays'
183   // root window safely when the display disconnect signal is received,
184   // which may come while we're in the nested run loop.
185   void Shutdown();
186 
187   // Deletes all child windows and performs necessary cleanup.
188   void CloseChildWindows();
189 
190   // Moves child windows to |dest|.
191   // TODO(afakhry): Consider renaming this function to avoid misuse. It is only
192   // called by WindowTreeHostManager::DeleteHost(), and has destructive side
193   // effects like deleting the workspace controllers, so it shouldn't be called
194   // for something else.
195   void MoveWindowsTo(aura::Window* dest);
196 
197   // Force the shelf to query for it's current visibility state.
198   void UpdateShelfVisibility();
199 
200   // Initialize touch HUDs if necessary.
201   void InitTouchHuds();
202 
203   // Returns the topmost window or one of its transient parents, if any of them
204   // are in fullscreen mode.
205   // TODO(afakhry): Rename this to imply getting the fullscreen window on the
206   // currently active desk on this root.
207   aura::Window* GetWindowForFullscreenMode();
208 
209   // Returns true if window is fulllscreen and the shelf is hidden.
210   bool IsInFullscreenMode();
211 
212   // If touch exploration is enabled, update the touch exploration
213   // controller so that synthesized touch events are anchored at this point.
214   void SetTouchAccessibilityAnchorPoint(const gfx::Point& anchor_point);
215 
216   // Shows a context menu at the |location_in_screen|.
217   void ShowContextMenu(const gfx::Point& location_in_screen,
218                        ui::MenuSourceType source_type);
219   void HideContextMenu();
220   bool IsContextMenuShown() const;
221 
222   // Called when the login status changes after login (such as lock/unlock).
223   void UpdateAfterLoginStatusChange(LoginStatus status);
224 
225   // Returns accessibility panel layout manager for this root window.
226   AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManagerForTest();
227 
228  private:
229   FRIEND_TEST_ALL_PREFIXES(RootWindowControllerTest,
230                            ContextMenuDisappearsInTabletMode);
231 
232   // Takes ownership of |ash_host|.
233   explicit RootWindowController(AshWindowTreeHost* ash_host);
234 
235   // Initializes the RootWindowController based on |root_window_type|.
236   void Init(RootWindowType root_window_type);
237 
238   void InitLayoutManagers();
239 
240   AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManager() const;
241 
242   // Initializes the shelf for this root window and notifies observers.
243   void InitializeShelf();
244 
245   // Creates the containers (aura::Windows) used by the shell.
246   void CreateContainers();
247 
248   // Creates a new window for use as a container.
249   aura::Window* CreateContainer(int window_id,
250                                 const char* name,
251                                 aura::Window* parent);
252 
253   // Initializes |system_wallpaper_| and possibly also |boot_splash_screen_|.
254   // The initial color is determined by the |root_window_type| and whether or
255   // not this is the first boot.
256   void CreateSystemWallpaper(RootWindowType root_window_type);
257 
258   // Callback for MenuRunner.
259   void OnMenuClosed();
260 
261   // Passed as callback to |wallpaper_widget_controller_| - run when the
262   // wallpaper widget is first set.
263   void OnFirstWallpaperWidgetSet();
264 
265   std::unique_ptr<AshWindowTreeHost> ash_host_;
266   // |ash_host_| as a WindowTreeHost.
267   aura::WindowTreeHost* window_tree_host_;
268 
269   // LayoutManagers are owned by the window they are installed on.
270   RootWindowLayoutManager* root_window_layout_manager_ = nullptr;
271 
272   std::unique_ptr<WallpaperWidgetController> wallpaper_widget_controller_;
273 
274   std::unique_ptr<AlwaysOnTopController> always_on_top_controller_;
275 
276   // Manages the context menu.
277   std::unique_ptr<AppMenuModelAdapter> root_window_menu_model_adapter_;
278 
279   std::unique_ptr<StackingController> stacking_controller_;
280 
281   std::unique_ptr<SplitViewController> split_view_controller_;
282 
283   // The shelf controller for this root window. Exists for the entire lifetime
284   // of the RootWindowController so that it is safe for observers to be added
285   // to it during construction of the shelf widget and status tray.
286   std::unique_ptr<Shelf> shelf_;
287 
288   // TODO(jamescook): Eliminate this. It is left over from legacy shelf code and
289   // doesn't mean anything in particular.
290   bool shelf_initialized_ = false;
291 
292   std::unique_ptr<SystemWallpaperController> system_wallpaper_;
293 
294   // Responsible for initializing TouchExplorationController when spoken
295   // feedback is on.
296   std::unique_ptr<TouchExplorationManager> touch_exploration_manager_;
297 
298   // Heads-up displays for touch events. These HUDs are not owned by the root
299   // window controller and manage their own lifetimes.
300   TouchHudDebug* touch_hud_debug_ = nullptr;
301   TouchHudProjection* touch_hud_projection_ = nullptr;
302 
303   std::unique_ptr<::wm::ScopedCaptureClient> capture_client_;
304 
305   std::unique_ptr<LockScreenActionBackgroundController>
306       lock_screen_action_background_controller_;
307 
308   // Whether child windows have been closed during shutdown. Exists to avoid
309   // calling related cleanup code more than once.
310   bool did_close_child_windows_ = false;
311 
312   std::unique_ptr<WorkAreaInsets> work_area_insets_;
313 
314   static std::vector<RootWindowController*>* root_window_controllers_;
315 
316   DISALLOW_COPY_AND_ASSIGN(RootWindowController);
317 };
318 
319 }  // namespace ash
320 
321 #endif  // ASH_ROOT_WINDOW_CONTROLLER_H_
322