display_controller.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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_DISPLAY_DISPLAY_CONTROLLER_H_
6#define ASH_DISPLAY_DISPLAY_CONTROLLER_H_
7
8#include <map>
9#include <vector>
10
11#include "ash/ash_export.h"
12#include "base/basictypes.h"
13#include "base/compiler_specific.h"
14#include "base/gtest_prod_util.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/observer_list.h"
17#include "base/time.h"
18#include "ui/gfx/display_observer.h"
19#include "ui/gfx/display.h"
20
21namespace aura {
22class Display;
23class RootWindow;
24}
25
26namespace base {
27class Value;
28template <typename T> class JSONValueConverter;
29}
30
31namespace ash {
32namespace internal {
33class DisplayManager;
34class FocusActivationStore;
35class RootWindowController;
36}
37
38typedef std::pair<int64, int64> DisplayIdPair;
39
40struct ASH_EXPORT DisplayLayout {
41  // Layout options where the secondary display should be positioned.
42  enum Position {
43    TOP,
44    RIGHT,
45    BOTTOM,
46    LEFT
47  };
48  // Factory method to create DisplayLayout from ints. The |mirrored| is
49  // set to false and |primary_id| is set to gfx::Display::kInvalidDisplayId.
50  // Used for persistence and webui.
51  static DisplayLayout FromInts(int position, int offsets);
52
53  DisplayLayout();
54  DisplayLayout(Position position, int offset);
55
56  // Returns an inverted display layout.
57  DisplayLayout Invert() const WARN_UNUSED_RESULT;
58
59  // Converter functions to/from base::Value.
60  static bool ConvertFromValue(const base::Value& value, DisplayLayout* layout);
61  static bool ConvertToValue(const DisplayLayout& layout, base::Value* value);
62
63  // This method is used by base::JSONValueConverter, you don't need to call
64  // this directly. Instead consider using converter functions above.
65  static void RegisterJSONConverter(
66      base::JSONValueConverter<DisplayLayout>* converter);
67
68  Position position;
69
70  // The offset of the position of the secondary display.  The offset is
71  // based on the top/left edge of the primary display.
72  int offset;
73
74  // True if displays are mirrored.
75  bool mirrored;
76
77  // The id of the display used as a primary display.
78  int64 primary_id;
79
80  // Returns string representation of the layout for debugging/testing.
81  std::string ToString() const;
82};
83
84// DisplayController owns and maintains RootWindows for each attached
85// display, keeping them in sync with display configuration changes.
86class ASH_EXPORT DisplayController : public gfx::DisplayObserver {
87 public:
88  class ASH_EXPORT Observer {
89   public:
90    // Invoked when the display configuration change is requested,
91    // but before the change is applied to aura/ash.
92    virtual void OnDisplayConfigurationChanging() = 0;
93
94    // Invoked when the all display configuration changes
95    // have been applied.
96    virtual void OnDisplayConfigurationChanged() {};
97
98   protected:
99    virtual ~Observer() {}
100  };
101
102  DisplayController();
103  virtual ~DisplayController();
104
105  void Start();
106  void Shutdown();
107
108  // Returns primary display. This is safe to use after ash::Shell is
109  // deleted.
110  static const gfx::Display& GetPrimaryDisplay();
111
112  // Returns the number of display. This is safe to use after
113  // ash::Shell is deleted.
114  static int GetNumDisplays();
115
116  // True if the primary display has been initialized.
117  static bool HasPrimaryDisplay();
118
119  // Initializes primary display.
120  void InitPrimaryDisplay();
121
122  // Initialize secondary displays.
123  void InitSecondaryDisplays();
124
125  // Add/Remove observers.
126  void AddObserver(Observer* observer);
127  void RemoveObserver(Observer* observer);
128
129  // Returns the root window for primary display.
130  aura::RootWindow* GetPrimaryRootWindow();
131
132  // Returns the root window for |display_id|.
133  aura::RootWindow* GetRootWindowForDisplayId(int64 id);
134
135  // Toggle mirror mode.
136  void ToggleMirrorMode();
137
138  // Swap primary and secondary display.
139  void SwapPrimaryDisplay();
140
141  // Sets the ID of the primary display.  If the display is not connected, it
142  // will switch the primary display when connected.
143  void SetPrimaryDisplayId(int64 id);
144
145  // Sets primary display. This re-assigns the current root
146  // window to given |display|.
147  void SetPrimaryDisplay(const gfx::Display& display);
148
149  // Returns the secondary display.
150  gfx::Display* GetSecondaryDisplay();
151
152  // Closes all child windows in the all root windows.
153  void CloseChildWindows();
154
155  // Returns all root windows. In non extended desktop mode, this
156  // returns the primary root window only.
157  std::vector<aura::RootWindow*> GetAllRootWindows();
158
159  // Returns all oot window controllers. In non extended desktop
160  // mode, this return a RootWindowController for the primary root window only.
161  std::vector<internal::RootWindowController*> GetAllRootWindowControllers();
162
163  // Gets/Sets/Clears the overscan insets for the specified |display_id|. See
164  // display_manager.h for the details.
165  gfx::Insets GetOverscanInsets(int64 display_id) const;
166  void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);
167  void ClearCustomOverscanInsets(int64 display_id);
168
169  const DisplayLayout& default_display_layout() const {
170    return default_display_layout_;
171  }
172  void SetDefaultDisplayLayout(const DisplayLayout& layout);
173
174  // Registeres the display layout info for the specified display(s).
175  void RegisterLayoutForDisplayIdPair(int64 id1,
176                                      int64 id2,
177                                      const DisplayLayout& layout);
178  // OBSOLETE
179  // TODO(oshima): Remove this in m28.
180  void RegisterLayoutForDisplayId(int64 id, const DisplayLayout& layout);
181
182  // Sets the layout for the current display pair. The |layout| specifies
183  // the locaion of the secondary display relative to the primary.
184  void SetLayoutForCurrentDisplays(const DisplayLayout& layout);
185
186  // Returns the display layout used for current displays.
187  DisplayLayout GetCurrentDisplayLayout() const;
188
189  // Returns the current display pair.
190  DisplayIdPair GetCurrentDisplayIdPair() const;
191
192  // Returns the display layout registered for the given display id |pair|.
193  DisplayLayout GetRegisteredDisplayLayout(const DisplayIdPair& pair) const;
194
195  // Checks if the mouse pointer is on one of displays, and moves to
196  // the center of the nearest display if it's outside of all displays.
197  void EnsurePointerInDisplays();
198
199  gfx::Point GetNativeMouseCursorLocation() const;
200
201  // Update the current cursor image that is sutable for the given
202  // |point_in_native|.
203  void UpdateMouseCursor(const gfx::Point& point_in_native);
204
205  // aura::DisplayObserver overrides:
206  virtual void OnDisplayBoundsChanged(
207      const gfx::Display& display) OVERRIDE;
208  virtual void OnDisplayAdded(const gfx::Display& display) OVERRIDE;
209  virtual void OnDisplayRemoved(const gfx::Display& display) OVERRIDE;
210
211 private:
212  friend class internal::DisplayManager;
213
214  // Creates a root window for |display| and stores it in the |root_windows_|
215  // map.
216  aura::RootWindow* AddRootWindowForDisplay(const gfx::Display& display);
217
218  void UpdateDisplayBoundsForLayout();
219
220  void NotifyDisplayConfigurationChanging();
221  void NotifyDisplayConfigurationChanged();
222
223  void SetLayoutForDisplayIdPair(const DisplayIdPair& display_pair,
224                                 const DisplayLayout& layout);
225
226  void RegisterLayoutForDisplayIdPairInternal(
227      int64 id1,
228      int64 id2,
229      const DisplayLayout& layout,
230      bool override);
231
232  void OnFadeOutForSwapDisplayFinished();
233
234  bool in_bootstrap() const { return in_bootstrap_; }
235
236  class DisplayChangeLimiter {
237   public:
238    DisplayChangeLimiter();
239
240    // Sets how long the throttling should last.
241    void SetThrottleTimeout(int64 throttle_ms);
242
243    bool IsThrottled() const;
244
245   private:
246    // The time when the throttling ends.
247    base::Time throttle_timeout_;
248
249    DISALLOW_COPY_AND_ASSIGN(DisplayChangeLimiter);
250  };
251
252  // The limiter to throttle how fast a user can
253  // change the display configuration.
254  scoped_ptr<DisplayChangeLimiter> limiter_;
255
256  // The mapping from display ID to its root window.
257  std::map<int64, aura::RootWindow*> root_windows_;
258
259  // The default display layout.
260  DisplayLayout default_display_layout_;
261
262  // Display layout per pair of devices.
263  std::map<DisplayIdPair, DisplayLayout> paired_layouts_;
264
265  ObserverList<Observer> observers_;
266
267  // Store the primary root window temporarily while replacing
268  // display.
269  aura::RootWindow* primary_root_window_for_replace_;
270
271  bool in_bootstrap_;
272
273  scoped_ptr<internal::FocusActivationStore> focus_activation_store_;
274
275  DISALLOW_COPY_AND_ASSIGN(DisplayController);
276};
277
278}  // namespace ash
279
280#endif  // ASH_DISPLAY_DISPLAY_CONTROLLER_H_
281