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