f13d7821d63ed0056a85c7d80704a9c65ce3ee36
[platform/framework/web/crosswalk.git] / src / ui / display / chromeos / display_configurator.h
1 // Copyright 2014 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 UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_
6 #define UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_
7
8 #include <stdint.h>
9
10 #include <map>
11 #include <string>
12 #include <vector>
13
14 #include "base/event_types.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/timer/timer.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19 #include "ui/display/display_export.h"
20 #include "ui/display/types/display_constants.h"
21 #include "ui/display/types/native_display_observer.h"
22 #include "ui/gfx/geometry/size.h"
23
24 namespace gfx {
25 class Point;
26 class Size;
27 }
28
29 namespace ui {
30 class DisplayMode;
31 class DisplaySnapshot;
32 class NativeDisplayDelegate;
33
34 // This class interacts directly with the system display configurator.
35 class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver {
36  public:
37   typedef uint64_t ContentProtectionClientId;
38   static const ContentProtectionClientId kInvalidClientId = 0;
39
40   struct DisplayState {
41     DisplayState();
42
43     DisplaySnapshot* display;  // Not owned.
44
45     // User-selected mode for the display.
46     const DisplayMode* selected_mode;
47
48     // Mode used when displaying the same desktop on multiple displays.
49     const DisplayMode* mirror_mode;
50   };
51
52   typedef std::vector<DisplayState> DisplayStateList;
53
54   class Observer {
55    public:
56     virtual ~Observer() {}
57
58     // Called after the display mode has been changed. |display| contains the
59     // just-applied configuration. Note that the X server is no longer grabbed
60     // when this method is called, so the actual configuration could've changed
61     // already.
62     virtual void OnDisplayModeChanged(
63         const std::vector<DisplayState>& displays) {}
64
65     // Called after a display mode change attempt failed. |failed_new_state| is
66     // the new state which the system failed to enter.
67     virtual void OnDisplayModeChangeFailed(
68         MultipleDisplayState failed_new_state) {}
69   };
70
71   // Interface for classes that make decisions about which display state
72   // should be used.
73   class StateController {
74    public:
75     virtual ~StateController() {}
76
77     // Called when displays are detected.
78     virtual MultipleDisplayState GetStateForDisplayIds(
79         const std::vector<int64_t>& display_ids) const = 0;
80
81     // Queries the resolution (|size|) in pixels to select display mode for the
82     // given display id.
83     virtual bool GetResolutionForDisplayId(int64_t display_id,
84                                            gfx::Size* size) const = 0;
85   };
86
87   // Interface for classes that implement software based mirroring.
88   class SoftwareMirroringController {
89    public:
90     virtual ~SoftwareMirroringController() {}
91
92     // Called when the hardware mirroring failed.
93     virtual void SetSoftwareMirroring(bool enabled) = 0;
94     virtual bool SoftwareMirroringEnabled() const = 0;
95   };
96
97   // Helper class used by tests.
98   class TestApi {
99    public:
100     TestApi(DisplayConfigurator* configurator) : configurator_(configurator) {}
101     ~TestApi() {}
102
103     // If |configure_timer_| is started, stops the timer, runs
104     // ConfigureDisplays(), and returns true; returns false otherwise.
105     bool TriggerConfigureTimeout() WARN_UNUSED_RESULT;
106
107    private:
108     DisplayConfigurator* configurator_;  // not owned
109
110     DISALLOW_COPY_AND_ASSIGN(TestApi);
111   };
112
113   // Flags that can be passed to SetDisplayPower().
114   static const int kSetDisplayPowerNoFlags;
115   // Configure displays even if the passed-in state matches |power_state_|.
116   static const int kSetDisplayPowerForceProbe;
117   // Do not change the state if multiple displays are connected or if the
118   // only connected display is external.
119   static const int kSetDisplayPowerOnlyIfSingleInternalDisplay;
120
121   // Gap between screens so cursor at bottom of active display doesn't
122   // partially appear on top of inactive display. Higher numbers guard
123   // against larger cursors, but also waste more memory.
124   // For simplicity, this is hard-coded to avoid the complexity of always
125   // determining the DPI of the screen and rationalizing which screen we
126   // need to use for the DPI calculation.
127   // See crbug.com/130188 for initial discussion.
128   static const int kVerticalGap = 60;
129
130   // Returns the mode within |display| that matches the given size with highest
131   // refresh rate. Returns None if no matching display was found.
132   static const DisplayMode* FindDisplayModeMatchingSize(
133       const DisplaySnapshot& display,
134       const gfx::Size& size);
135
136   DisplayConfigurator();
137   virtual ~DisplayConfigurator();
138
139   MultipleDisplayState display_state() const { return display_state_; }
140   chromeos::DisplayPowerState requested_power_state() const {
141     return requested_power_state_;
142   }
143   const gfx::Size framebuffer_size() const { return framebuffer_size_; }
144   const std::vector<DisplayState>& cached_displays() const {
145     return cached_displays_;
146   }
147
148   // Called when an external process no longer needs to control the display
149   // and Chrome can take control.
150   void TakeControl();
151
152   // Called when an external process needs to control the display and thus
153   // Chrome should relinquish it.
154   void RelinquishControl();
155
156   void set_state_controller(StateController* controller) {
157     state_controller_ = controller;
158   }
159   void set_mirroring_controller(SoftwareMirroringController* controller) {
160     mirroring_controller_ = controller;
161   }
162
163   // Replaces |native_display_delegate_| with the delegate passed in and sets
164   // |configure_display_| to true. Should be called before Init().
165   void SetDelegateForTesting(
166       scoped_ptr<NativeDisplayDelegate> display_delegate);
167
168   // Sets the initial value of |power_state_|.  Must be called before Start().
169   void SetInitialDisplayPower(chromeos::DisplayPowerState power_state);
170
171   // Initialization, must be called right after constructor.
172   // |is_panel_fitting_enabled| indicates hardware panel fitting support.
173   void Init(bool is_panel_fitting_enabled);
174
175   // Does initial configuration of displays during startup.
176   // If |background_color_argb| is non zero and there are multiple displays,
177   // DisplayConfigurator sets the background color of X's RootWindow to this
178   // color.
179   void ForceInitialConfigure(uint32_t background_color_argb);
180
181   // Stop handling display configuration events/requests.
182   void PrepareForExit();
183
184   // Called when powerd notifies us that some set of displays should be turned
185   // on or off.  This requires enabling or disabling the CRTC associated with
186   // the display(s) in question so that the low power state is engaged.
187   // |flags| contains bitwise-or-ed kSetDisplayPower* values. Returns true if
188   // the system successfully enters (or was already in) |power_state|.
189   bool SetDisplayPower(chromeos::DisplayPowerState power_state, int flags);
190
191   // Force switching the display mode to |new_state|. Returns false if
192   // switching failed (possibly because |new_state| is invalid for the
193   // current set of connected displays).
194   bool SetDisplayMode(MultipleDisplayState new_state);
195
196   // NativeDisplayDelegate::Observer overrides:
197   virtual void OnConfigurationChanged() override;
198
199   void AddObserver(Observer* observer);
200   void RemoveObserver(Observer* observer);
201
202   // Sets all the displays into pre-suspend mode; usually this means
203   // configure them for their resume state. This allows faster resume on
204   // machines where display configuration is slow.
205   void SuspendDisplays();
206
207   // Reprobes displays to handle changes made while the system was
208   // suspended.
209   void ResumeDisplays();
210
211   // Registers a client for display protection and requests a client id. Returns
212   // 0 if requesting failed.
213   ContentProtectionClientId RegisterContentProtectionClient();
214
215   // Unregisters the client.
216   void UnregisterContentProtectionClient(ContentProtectionClientId client_id);
217
218   // Queries link status and protection status.
219   // |link_mask| is the type of connected display links, which is a bitmask of
220   // DisplayConnectionType values. |protection_mask| is the desired protection
221   // methods, which is a bitmask of the ContentProtectionMethod values.
222   // Returns true on success.
223   bool QueryContentProtectionStatus(ContentProtectionClientId client_id,
224                                     int64_t display_id,
225                                     uint32_t* link_mask,
226                                     uint32_t* protection_mask);
227
228   // Requests the desired protection methods.
229   // |protection_mask| is the desired protection methods, which is a bitmask
230   // of the ContentProtectionMethod values.
231   // Returns true when the protection request has been made.
232   bool EnableContentProtection(ContentProtectionClientId client_id,
233                                int64_t display_id,
234                                uint32_t desired_protection_mask);
235
236   // Checks the available color profiles for |display_id| and fills the result
237   // into |profiles|.
238   std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
239       int64_t display_id);
240
241   // Updates the color calibration to |new_profile|.
242   bool SetColorCalibrationProfile(int64_t display_id,
243                                   ui::ColorCalibrationProfile new_profile);
244
245  private:
246   // Mapping a display_id to a protection request bitmask.
247   typedef std::map<int64_t, uint32_t> ContentProtections;
248   // Mapping a client to its protection request.
249   typedef std::map<ContentProtectionClientId, ContentProtections>
250       ProtectionRequests;
251
252   // Performs platform specific delegate initialization.
253   scoped_ptr<NativeDisplayDelegate> CreatePlatformNativeDisplayDelegate();
254
255   // Updates |cached_displays_| to contain currently-connected displays. Calls
256   // |delegate_->GetDisplays()| and then does additional work, like finding the
257   // mirror mode and setting user-preferred modes. Note that the server must be
258   // grabbed via |delegate_->GrabServer()| first.
259   void UpdateCachedDisplays();
260
261   // Helper method for UpdateCachedDisplays() that initializes the passed-in
262   // displays' |mirror_mode| fields by looking for a mode in |internal_display|
263   // and |external_display| having the same resolution. Returns false if a
264   // shared
265   // mode wasn't found or created.
266   //
267   // |try_panel_fitting| allows creating a panel-fitting mode for
268   // |internal_display| instead of only searching for a matching mode (note that
269   // it may lead to a crash if |internal_info| is not capable of panel fitting).
270   //
271   // |preserve_aspect| limits the search/creation only to the modes having the
272   // native aspect ratio of |external_display|.
273   bool FindMirrorMode(DisplayState* internal_display,
274                       DisplayState* external_display,
275                       bool try_panel_fitting,
276                       bool preserve_aspect);
277
278   // Configures displays. Invoked by |configure_timer_|.
279   void ConfigureDisplays();
280
281   // Restores |requested_power_state_| after the system has resumed,
282   // additionally forcing a probe. Invoked by |configure_timer_|.
283   void RestoreRequestedPowerStateAfterResume();
284
285   // Notifies observers about an attempted state change.
286   void NotifyObservers(bool success, MultipleDisplayState attempted_state);
287
288   // Switches to the state specified in |display_state| and |power_state|.
289   // If the hardware mirroring failed and |mirroring_controller_| is set,
290   // it switches to |STATE_DUAL_EXTENDED| and calls |SetSoftwareMirroring()|
291   // to enable software based mirroring.
292   // On success, updates |display_state_|, |power_state_|, and
293   // |cached_displays_| and returns true.
294   bool EnterStateOrFallBackToSoftwareMirroring(
295       MultipleDisplayState display_state,
296       chromeos::DisplayPowerState power_state);
297
298   // Switches to the state specified in |display_state| and |power_state|.
299   // On success, updates |display_state_|, |power_state_|, and
300   // |cached_displays_| and returns true.
301   bool EnterState(MultipleDisplayState display_state,
302                   chromeos::DisplayPowerState power_state);
303
304   // Returns the display state that should be used with |cached_displays_| while
305   // in |power_state|.
306   MultipleDisplayState ChooseDisplayState(
307       chromeos::DisplayPowerState power_state) const;
308
309   // Returns the ratio between mirrored mode area and native mode area:
310   // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height)
311   float GetMirroredDisplayAreaRatio(const DisplayState& display);
312
313   // Returns true if in either hardware or software mirroring mode.
314   bool IsMirroring() const;
315
316   // Applies display protections according to requests.
317   bool ApplyProtections(const ContentProtections& requests);
318
319   StateController* state_controller_;
320   SoftwareMirroringController* mirroring_controller_;
321   scoped_ptr<NativeDisplayDelegate> native_display_delegate_;
322
323   // Used to enable modes which rely on panel fitting.
324   bool is_panel_fitting_enabled_;
325
326   // This is detected by the constructor to determine whether or not we should
327   // be enabled.  If we aren't running on ChromeOS, we can't assume that the
328   // Xrandr X11 extension is supported.
329   // If this flag is set to false, any attempts to change the display
330   // configuration to immediately fail without changing the state.
331   bool configure_display_;
332
333   // The current display state.
334   MultipleDisplayState display_state_;
335
336   gfx::Size framebuffer_size_;
337
338   // The last-requested and current power state. These may differ if
339   // configuration fails: SetDisplayMode() needs the last-requested state while
340   // SetDisplayPower() needs the current state.
341   chromeos::DisplayPowerState requested_power_state_;
342   chromeos::DisplayPowerState current_power_state_;
343
344   // Most-recently-used display configuration. Note that the actual
345   // configuration changes asynchronously.
346   DisplayStateList cached_displays_;
347
348   ObserverList<Observer> observers_;
349
350   // The timer to delay configuring displays. This is used to aggregate multiple
351   // display configuration events when they are reported in short time spans.
352   // See comment for NativeDisplayEventDispatcherX11 for more details.
353   base::OneShotTimer<DisplayConfigurator> configure_timer_;
354
355   // Id for next display protection client.
356   ContentProtectionClientId next_display_protection_client_id_;
357
358   // Display protection requests of each client.
359   ProtectionRequests client_protection_requests_;
360
361   // Display controlled by an external entity.
362   bool display_externally_controlled_;
363
364   DISALLOW_COPY_AND_ASSIGN(DisplayConfigurator);
365 };
366
367 }  // namespace ui
368
369 #endif  // UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_