• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MANAGER_H_
6 #define ASH_DISPLAY_DISPLAY_MANAGER_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "ash/ash_export.h"
12 #include "ash/display/display_info.h"
13 #include "ash/display/display_layout.h"
14 #include "base/compiler_specific.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "ui/gfx/display.h"
18 
19 #if defined(OS_CHROMEOS)
20 #include "chromeos/display/output_configurator.h"
21 #endif
22 
23 namespace gfx {
24 class Display;
25 class Insets;
26 class Rect;
27 }
28 
29 namespace ash {
30 class AcceleratorControllerTest;
31 class DisplayController;
32 
33 namespace test {
34 class DisplayManagerTestApi;
35 class SystemGestureEventFilterTest;
36 }
37 namespace internal {
38 class DisplayLayoutStore;
39 
40 // DisplayManager maintains the current display configurations,
41 // and notifies observers when configuration changes.
42 //
43 // TODO(oshima): Make this non internal.
44 class ASH_EXPORT DisplayManager
45 #if defined(OS_CHROMEOS)
46     : public chromeos::OutputConfigurator::SoftwareMirroringController
47 #endif
48       {
49  public:
50   class ASH_EXPORT Delegate {
51    public:
~Delegate()52     virtual ~Delegate() {}
53 
54     // Create or updates the non desktop window with |display_info|.
55     virtual void CreateOrUpdateNonDesktopDisplay(
56         const DisplayInfo& display_info) = 0;
57 
58     // Closes the mirror window if exists.
59     virtual void CloseNonDesktopDisplay() = 0;
60 
61     // Called before and after the display configuration changes.
62     // When |clear_focus| is true, the implementation should
63     // deactivate the active window and set the focus window to NULL.
64     virtual void PreDisplayConfigurationChange(bool clear_focus) = 0;
65     virtual void PostDisplayConfigurationChange() = 0;
66   };
67 
68   // How the second display will be used.
69   // 1) EXTENDED mode extends the desktop to the second dislpay.
70   // 2) MIRRORING mode copies the content of the primary display to
71   //    the 2nd display. (Software Mirroring).
72   // 3) In VIRTUAL_KEYBOARD mode, the 2nd display is used as a
73   //    dedicated display for virtual keyboard, and it is not
74   //    recognized as a part of desktop.
75   enum SecondDisplayMode {
76     EXTENDED,
77     MIRRORING,
78     VIRTUAL_KEYBOARD
79   };
80 
81   // Returns the list of possible UI scales for the display.
82   static std::vector<float> GetScalesForDisplay(const DisplayInfo& info);
83 
84   // Returns next valid UI scale.
85   static float GetNextUIScale(const DisplayInfo& info, bool up);
86 
87   // Updates the bounds of the display given by |secondary_display_id|
88   // according to |layout|.
89   static void UpdateDisplayBoundsForLayoutById(
90       const DisplayLayout& layout,
91       const gfx::Display& primary_display,
92       int64 secondary_display_id);
93 
94   DisplayManager();
95   virtual ~DisplayManager();
96 
layout_store()97   DisplayLayoutStore* layout_store() {
98     return layout_store_.get();
99   }
100 
set_delegate(Delegate * delegate)101   void set_delegate(Delegate* delegate) { delegate_ = delegate; }
102 
103   // When set to true, the MonitorManager calls OnDisplayBoundsChanged
104   // even if the display's bounds didn't change. Used to swap primary
105   // display.
set_force_bounds_changed(bool force_bounds_changed)106   void set_force_bounds_changed(bool force_bounds_changed) {
107     force_bounds_changed_ = force_bounds_changed;
108   }
109 
110   // Returns the display id of the first display in the outupt list.
first_display_id()111   int64 first_display_id() const { return first_display_id_; }
112 
113   // Initializes displays using command line flag. Returns false
114   // if no command line flag was provided.
115   bool InitFromCommandLine();
116 
117   // Initialize default display.
118   void InitDefaultDisplay();
119 
120   // True if the given |display| is currently connected.
121   bool IsActiveDisplay(const gfx::Display& display) const;
122 
123   // True if there is an internal display.
124   bool HasInternalDisplay() const;
125 
126   bool IsInternalDisplayId(int64 id) const;
127 
128   // Returns the display layout used for current displays.
129   DisplayLayout GetCurrentDisplayLayout();
130 
131   // Returns the current display pair.
132   DisplayIdPair GetCurrentDisplayIdPair() const;
133 
134   // Sets the layout for the current display pair. The |layout| specifies
135   // the locaion of the secondary display relative to the primary.
136   void SetLayoutForCurrentDisplays(
137       const DisplayLayout& layout_relative_to_primary);
138 
139   // Returns display for given |id|;
140   const gfx::Display& GetDisplayForId(int64 id) const;
141 
142   // Finds the display that contains |point| in screeen coordinates.
143   // Returns invalid display if there is no display that can satisfy
144   // the condition.
145   const gfx::Display& FindDisplayContainingPoint(
146       const gfx::Point& point_in_screen) const;
147 
148   // Sets the work area's |insets| to the display given by |display_id|.
149   bool UpdateWorkAreaOfDisplay(int64 display_id, const gfx::Insets& insets);
150 
151   // Registers the overscan insets for the display of the specified ID. Note
152   // that the insets size should be specified in DIP size. It also triggers the
153   // display's bounds change.
154   void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);
155 
156   // Sets the display's rotation.
157   void SetDisplayRotation(int64 display_id, gfx::Display::Rotation rotation);
158 
159   // Sets the display's ui scale.
160   void SetDisplayUIScale(int64 display_id, float ui_scale);
161 
162   // Sets the display's resolution.
163   void SetDisplayResolution(int64 display_id, const gfx::Size& resolution);
164 
165   // Register per display properties. |overscan_insets| is NULL if
166   // the display has no custom overscan insets.
167   void RegisterDisplayProperty(int64 display_id,
168                                gfx::Display::Rotation rotation,
169                                float ui_scale,
170                                const gfx::Insets* overscan_insets,
171                                const gfx::Size& resolution_in_pixels);
172 
173   // Returns the display's selected resolution.
174   bool GetSelectedResolutionForDisplayId(int64 display_id,
175                                          gfx::Size* resolution_out) const;
176 
177   // Tells if the virtual resolution feature is enabled.
178   bool IsDisplayUIScalingEnabled() const;
179 
180   // Returns the current overscan insets for the specified |display_id|.
181   // Returns an empty insets (0, 0, 0, 0) if no insets are specified for
182   // the display.
183   gfx::Insets GetOverscanInsets(int64 display_id) const;
184 
185   // Called when display configuration has changed. The new display
186   // configurations is passed as a vector of Display object, which
187   // contains each display's new infomration.
188   void OnNativeDisplaysChanged(
189       const std::vector<DisplayInfo>& display_info_list);
190 
191   // Updates the internal display data and notifies observers about the changes.
192   void UpdateDisplays(const std::vector<DisplayInfo>& display_info_list);
193 
194   // Updates current displays using current |display_info_|.
195   void UpdateDisplays();
196 
197   // Returns the display at |index|. The display at 0 is
198   // no longer considered "primary".
199   const gfx::Display& GetDisplayAt(size_t index) const;
200 
201   const gfx::Display& GetPrimaryDisplayCandidate() const;
202 
203   // Returns the logical number of displays. This returns 1
204   // when displays are mirrored.
205   size_t GetNumDisplays() const;
206 
displays()207   const std::vector<gfx::Display>& displays() const { return displays_; }
208 
209   // Returns the number of connected displays. This returns 2
210   // when displays are mirrored.
num_connected_displays()211   size_t num_connected_displays() const { return num_connected_displays_; }
212 
213   // Returns the mirroring status.
214   bool IsMirrored() const;
mirrored_display_id()215   int64 mirrored_display_id() const { return mirrored_display_id_; }
216 
217   // Returns the display object that is not a part of desktop.
non_desktop_display()218   const gfx::Display& non_desktop_display() const {
219     return non_desktop_display_;
220   }
221 
222   // Retuns the display info associated with |display_id|.
223   const DisplayInfo& GetDisplayInfo(int64 display_id) const;
224 
225   // Returns the human-readable name for the display |id|.
226   std::string GetDisplayNameForId(int64 id);
227 
228   // Returns the display id that is capable of UI scaling. On device,
229   // this returns internal display's ID if its device scale factor is 2,
230   // or invalid ID if such internal display doesn't exist. On linux
231   // desktop, this returns the first display ID.
232   int64 GetDisplayIdForUIScaling() const;
233 
234   // Change the mirror mode.
235   void SetMirrorMode(bool mirrored);
236 
237   // Used to emulate display change when run in a desktop environment instead
238   // of on a device.
239   void AddRemoveDisplay();
240   void ToggleDisplayScaleFactor();
241 
242   // SoftwareMirroringController override:
243 #if defined(OS_CHROMEOS)
244   virtual void SetSoftwareMirroring(bool enabled) OVERRIDE;
245 #endif
software_mirroring_enabled()246   bool software_mirroring_enabled() const {
247     return second_display_mode_ == MIRRORING;
248   };
249 
virtual_keyboard_root_window_enabled()250   bool virtual_keyboard_root_window_enabled() const {
251     return second_display_mode_ == VIRTUAL_KEYBOARD;
252   };
253 
254   // Sets/gets second display mode.
255   void SetSecondDisplayMode(SecondDisplayMode mode);
second_display_mode()256   SecondDisplayMode second_display_mode() const {
257     return second_display_mode_;
258   }
259 
260   // Update the bounds of the display given by |display_id|.
261   bool UpdateDisplayBounds(int64 display_id,
262                            const gfx::Rect& new_bounds);
263 
264   // Creates mirror window if the software mirror mode is enabled.
265   // This is used only for bootstrap.
266   void CreateMirrorWindowIfAny();
267 
268 private:
269   FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint);
270   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged);
271   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest,
272                            NativeDisplaysChangedAfterPrimaryChange);
273   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets);
274   friend class ash::AcceleratorControllerTest;
275   friend class test::DisplayManagerTestApi;
276   friend class test::SystemGestureEventFilterTest;
277   friend class DisplayManagerTest;
278 
279   typedef std::vector<gfx::Display> DisplayList;
280 
set_change_display_upon_host_resize(bool value)281   void set_change_display_upon_host_resize(bool value) {
282     change_display_upon_host_resize_ = value;
283   }
284 
285   gfx::Display* FindDisplayForId(int64 id);
286 
287   // Add the mirror display's display info if the software based
288   // mirroring is in use.
289   void AddMirrorDisplayInfoIfAny(std::vector<DisplayInfo>* display_info_list);
290 
291   // Inserts and update the DisplayInfo according to the overscan
292   // state. Note that The DisplayInfo stored in the |internal_display_info_|
293   // can be different from |new_info| (due to overscan state), so
294   // you must use |GetDisplayInfo| to get the correct DisplayInfo for
295   // a display.
296   void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info);
297 
298   // Creates a display object from the DisplayInfo for |display_id|.
299   gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id);
300 
301   // Updates the bounds of the secondary display in |display_list|
302   // using the layout registered for the display pair and set the
303   // index of display updated to |updated_index|. Returns true
304   // if the secondary display's bounds has been changed from current
305   // value, or false otherwise.
306   bool UpdateSecondaryDisplayBoundsForLayout(DisplayList* display_list,
307                                              size_t* updated_index) const;
308 
309   static void UpdateDisplayBoundsForLayout(
310       const DisplayLayout& layout,
311       const gfx::Display& primary_display,
312       gfx::Display* secondary_display);
313 
314   Delegate* delegate_;  // not owned.
315 
316   scoped_ptr<DisplayLayoutStore> layout_store_;
317 
318   int64 first_display_id_;
319 
320   // List of current active displays.
321   DisplayList displays_;
322 
323   int num_connected_displays_;
324 
325   bool force_bounds_changed_;
326 
327   // The mapping from the display ID to its internal data.
328   std::map<int64, DisplayInfo> display_info_;
329 
330   // Selected resolutions for displays. Key is the displays' ID.
331   std::map<int64, gfx::Size> resolutions_;
332 
333   // When set to true, the host window's resize event updates
334   // the display's size. This is set to true when running on
335   // desktop environment (for debugging) so that resizing the host
336   // window will update the display properly. This is set to false
337   // on device as well as during the unit tests.
338   bool change_display_upon_host_resize_;
339 
340   SecondDisplayMode second_display_mode_;
341   int64 mirrored_display_id_;
342   gfx::Display non_desktop_display_;
343 
344   DISALLOW_COPY_AND_ASSIGN(DisplayManager);
345 };
346 
347 }  // namespace internal
348 }  // namespace ash
349 
350 #endif  // ASH_DISPLAY_DISPLAY_MANAGER_H_
351