MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / ui / display / chromeos / display_configurator.h
blobf4b10d0904ef92503900df84e4b489193e162be2
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.
5 #ifndef UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_
6 #define UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_
8 #include <stdint.h>
10 #include <map>
11 #include <string>
12 #include <vector>
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"
24 namespace gfx {
25 class Point;
26 class Size;
29 namespace ui {
30 class DisplayMode;
31 class DisplaySnapshot;
32 class NativeDisplayDelegate;
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;
40 struct DisplayState {
41 DisplayState();
43 DisplaySnapshot* display; // Not owned.
45 // User-selected mode for the display.
46 const DisplayMode* selected_mode;
48 // Mode used when displaying the same desktop on multiple displays.
49 const DisplayMode* mirror_mode;
52 typedef std::vector<DisplayState> DisplayStateList;
54 class Observer {
55 public:
56 virtual ~Observer() {}
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) {}
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) {}
71 // Interface for classes that make decisions about which display state
72 // should be used.
73 class StateController {
74 public:
75 virtual ~StateController() {}
77 // Called when displays are detected.
78 virtual MultipleDisplayState GetStateForDisplayIds(
79 const std::vector<int64_t>& display_ids) const = 0;
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;
87 // Interface for classes that implement software based mirroring.
88 class SoftwareMirroringController {
89 public:
90 virtual ~SoftwareMirroringController() {}
92 // Called when the hardware mirroring failed.
93 virtual void SetSoftwareMirroring(bool enabled) = 0;
94 virtual bool SoftwareMirroringEnabled() const = 0;
97 // Helper class used by tests.
98 class TestApi {
99 public:
100 TestApi(DisplayConfigurator* configurator) : configurator_(configurator) {}
101 ~TestApi() {}
103 // If |configure_timer_| is started, stops the timer, runs
104 // ConfigureDisplays(), and returns true; returns false otherwise.
105 bool TriggerConfigureTimeout() WARN_UNUSED_RESULT;
107 private:
108 DisplayConfigurator* configurator_; // not owned
110 DISALLOW_COPY_AND_ASSIGN(TestApi);
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;
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;
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);
136 DisplayConfigurator();
137 virtual ~DisplayConfigurator();
139 MultipleDisplayState display_state() const { return display_state_; }
140 chromeos::DisplayPowerState requested_power_state() const {
141 return requested_power_state_;
143 const gfx::Size framebuffer_size() const { return framebuffer_size_; }
144 const std::vector<DisplayState>& cached_displays() const {
145 return cached_displays_;
148 void set_state_controller(StateController* controller) {
149 state_controller_ = controller;
151 void set_mirroring_controller(SoftwareMirroringController* controller) {
152 mirroring_controller_ = controller;
155 // Replaces |native_display_delegate_| with the delegate passed in and sets
156 // |configure_display_| to true. Should be called before Init().
157 void SetDelegateForTesting(
158 scoped_ptr<NativeDisplayDelegate> display_delegate);
160 // Sets the initial value of |power_state_|. Must be called before Start().
161 void SetInitialDisplayPower(chromeos::DisplayPowerState power_state);
163 // Initialization, must be called right after constructor.
164 // |is_panel_fitting_enabled| indicates hardware panel fitting support.
165 void Init(bool is_panel_fitting_enabled);
167 // Does initial configuration of displays during startup.
168 // If |background_color_argb| is non zero and there are multiple displays,
169 // DisplayConfigurator sets the background color of X's RootWindow to this
170 // color.
171 void ForceInitialConfigure(uint32_t background_color_argb);
173 // Stop handling display configuration events/requests.
174 void PrepareForExit();
176 // Called when powerd notifies us that some set of displays should be turned
177 // on or off. This requires enabling or disabling the CRTC associated with
178 // the display(s) in question so that the low power state is engaged.
179 // |flags| contains bitwise-or-ed kSetDisplayPower* values. Returns true if
180 // the system successfully enters (or was already in) |power_state|.
181 bool SetDisplayPower(chromeos::DisplayPowerState power_state, int flags);
183 // Force switching the display mode to |new_state|. Returns false if
184 // switching failed (possibly because |new_state| is invalid for the
185 // current set of connected displays).
186 bool SetDisplayMode(MultipleDisplayState new_state);
188 // NativeDisplayDelegate::Observer overrides:
189 virtual void OnConfigurationChanged() override;
191 void AddObserver(Observer* observer);
192 void RemoveObserver(Observer* observer);
194 // Sets all the displays into pre-suspend mode; usually this means
195 // configure them for their resume state. This allows faster resume on
196 // machines where display configuration is slow.
197 void SuspendDisplays();
199 // Reprobes displays to handle changes made while the system was
200 // suspended.
201 void ResumeDisplays();
203 // Registers a client for display protection and requests a client id. Returns
204 // 0 if requesting failed.
205 ContentProtectionClientId RegisterContentProtectionClient();
207 // Unregisters the client.
208 void UnregisterContentProtectionClient(ContentProtectionClientId client_id);
210 // Queries link status and protection status.
211 // |link_mask| is the type of connected display links, which is a bitmask of
212 // DisplayConnectionType values. |protection_mask| is the desired protection
213 // methods, which is a bitmask of the ContentProtectionMethod values.
214 // Returns true on success.
215 bool QueryContentProtectionStatus(ContentProtectionClientId client_id,
216 int64_t display_id,
217 uint32_t* link_mask,
218 uint32_t* protection_mask);
220 // Requests the desired protection methods.
221 // |protection_mask| is the desired protection methods, which is a bitmask
222 // of the ContentProtectionMethod values.
223 // Returns true when the protection request has been made.
224 bool EnableContentProtection(ContentProtectionClientId client_id,
225 int64_t display_id,
226 uint32_t desired_protection_mask);
228 // Checks the available color profiles for |display_id| and fills the result
229 // into |profiles|.
230 std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
231 int64_t display_id);
233 // Updates the color calibration to |new_profile|.
234 bool SetColorCalibrationProfile(int64_t display_id,
235 ui::ColorCalibrationProfile new_profile);
237 private:
238 // Mapping a display_id to a protection request bitmask.
239 typedef std::map<int64_t, uint32_t> ContentProtections;
240 // Mapping a client to its protection request.
241 typedef std::map<ContentProtectionClientId, ContentProtections>
242 ProtectionRequests;
244 // Performs platform specific delegate initialization.
245 scoped_ptr<NativeDisplayDelegate> CreatePlatformNativeDisplayDelegate();
247 // Updates |cached_displays_| to contain currently-connected displays. Calls
248 // |delegate_->GetDisplays()| and then does additional work, like finding the
249 // mirror mode and setting user-preferred modes. Note that the server must be
250 // grabbed via |delegate_->GrabServer()| first.
251 void UpdateCachedDisplays();
253 // Helper method for UpdateCachedDisplays() that initializes the passed-in
254 // displays' |mirror_mode| fields by looking for a mode in |internal_display|
255 // and |external_display| having the same resolution. Returns false if a
256 // shared
257 // mode wasn't found or created.
259 // |try_panel_fitting| allows creating a panel-fitting mode for
260 // |internal_display| instead of only searching for a matching mode (note that
261 // it may lead to a crash if |internal_info| is not capable of panel fitting).
263 // |preserve_aspect| limits the search/creation only to the modes having the
264 // native aspect ratio of |external_display|.
265 bool FindMirrorMode(DisplayState* internal_display,
266 DisplayState* external_display,
267 bool try_panel_fitting,
268 bool preserve_aspect);
270 // Configures displays. Invoked by |configure_timer_|.
271 void ConfigureDisplays();
273 // Restores |requested_power_state_| after the system has resumed,
274 // additionally forcing a probe. Invoked by |configure_timer_|.
275 void RestoreRequestedPowerStateAfterResume();
277 // Notifies observers about an attempted state change.
278 void NotifyObservers(bool success, MultipleDisplayState attempted_state);
280 // Switches to the state specified in |display_state| and |power_state|.
281 // If the hardware mirroring failed and |mirroring_controller_| is set,
282 // it switches to |STATE_DUAL_EXTENDED| and calls |SetSoftwareMirroring()|
283 // to enable software based mirroring.
284 // On success, updates |display_state_|, |power_state_|, and
285 // |cached_displays_| and returns true.
286 bool EnterStateOrFallBackToSoftwareMirroring(
287 MultipleDisplayState display_state,
288 chromeos::DisplayPowerState power_state);
290 // Switches to the state specified in |display_state| and |power_state|.
291 // On success, updates |display_state_|, |power_state_|, and
292 // |cached_displays_| and returns true.
293 bool EnterState(MultipleDisplayState display_state,
294 chromeos::DisplayPowerState power_state);
296 // Returns the display state that should be used with |cached_displays_| while
297 // in |power_state|.
298 MultipleDisplayState ChooseDisplayState(
299 chromeos::DisplayPowerState power_state) const;
301 // Returns the ratio between mirrored mode area and native mode area:
302 // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height)
303 float GetMirroredDisplayAreaRatio(const DisplayState& display);
305 // Returns true if in either hardware or software mirroring mode.
306 bool IsMirroring() const;
308 // Applies display protections according to requests.
309 bool ApplyProtections(const ContentProtections& requests);
311 StateController* state_controller_;
312 SoftwareMirroringController* mirroring_controller_;
313 scoped_ptr<NativeDisplayDelegate> native_display_delegate_;
315 // Used to enable modes which rely on panel fitting.
316 bool is_panel_fitting_enabled_;
318 // This is detected by the constructor to determine whether or not we should
319 // be enabled. If we aren't running on ChromeOS, we can't assume that the
320 // Xrandr X11 extension is supported.
321 // If this flag is set to false, any attempts to change the display
322 // configuration to immediately fail without changing the state.
323 bool configure_display_;
325 // The current display state.
326 MultipleDisplayState display_state_;
328 gfx::Size framebuffer_size_;
330 // The last-requested and current power state. These may differ if
331 // configuration fails: SetDisplayMode() needs the last-requested state while
332 // SetDisplayPower() needs the current state.
333 chromeos::DisplayPowerState requested_power_state_;
334 chromeos::DisplayPowerState current_power_state_;
336 // Most-recently-used display configuration. Note that the actual
337 // configuration changes asynchronously.
338 DisplayStateList cached_displays_;
340 ObserverList<Observer> observers_;
342 // The timer to delay configuring displays. This is used to aggregate multiple
343 // display configuration events when they are reported in short time spans.
344 // See comment for NativeDisplayEventDispatcherX11 for more details.
345 base::OneShotTimer<DisplayConfigurator> configure_timer_;
347 // Id for next display protection client.
348 ContentProtectionClientId next_display_protection_client_id_;
350 // Display protection requests of each client.
351 ProtectionRequests client_protection_requests_;
353 DISALLOW_COPY_AND_ASSIGN(DisplayConfigurator);
356 } // namespace ui
358 #endif // UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_