| OLD | NEW |
| (Empty) |
| 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 <memory> | |
| 12 #include <queue> | |
| 13 #include <string> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "base/event_types.h" | |
| 17 #include "base/macros.h" | |
| 18 #include "base/memory/scoped_vector.h" | |
| 19 #include "base/memory/weak_ptr.h" | |
| 20 #include "base/observer_list.h" | |
| 21 #include "base/timer/timer.h" | |
| 22 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 23 #include "ui/display/chromeos/display_snapshot_virtual.h" | |
| 24 #include "ui/display/chromeos/query_content_protection_task.h" | |
| 25 #include "ui/display/display_export.h" | |
| 26 #include "ui/display/types/display_constants.h" | |
| 27 #include "ui/display/types/native_display_observer.h" | |
| 28 #include "ui/display/util/display_util.h" | |
| 29 #include "ui/gfx/geometry/size.h" | |
| 30 | |
| 31 namespace gfx { | |
| 32 class Size; | |
| 33 } | |
| 34 | |
| 35 namespace ui { | |
| 36 struct GammaRampRGBEntry; | |
| 37 class DisplayLayoutManager; | |
| 38 class DisplayMode; | |
| 39 class DisplaySnapshot; | |
| 40 class NativeDisplayDelegate; | |
| 41 class UpdateDisplayConfigurationTask; | |
| 42 | |
| 43 // This class interacts directly with the system display configurator. | |
| 44 class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { | |
| 45 public: | |
| 46 typedef uint64_t ContentProtectionClientId; | |
| 47 static const ContentProtectionClientId kInvalidClientId = 0; | |
| 48 | |
| 49 typedef base::Callback<void(bool /* success */)> ConfigurationCallback; | |
| 50 | |
| 51 typedef base::Callback<void(bool /* success */)> EnableProtectionCallback; | |
| 52 | |
| 53 struct QueryProtectionResponse { | |
| 54 // True if the query succeeded, false otherwise. | |
| 55 bool success = false; | |
| 56 | |
| 57 // The type of connected display links, which is a bitmask of | |
| 58 // DisplayConnectionType values. | |
| 59 uint32_t link_mask = 0; | |
| 60 | |
| 61 // The desired protection methods, which is a bitmask of the | |
| 62 // ContentProtectionMethod values. | |
| 63 uint32_t protection_mask = 0; | |
| 64 }; | |
| 65 | |
| 66 typedef base::Callback<void(const QueryProtectionResponse&)> | |
| 67 QueryProtectionCallback; | |
| 68 | |
| 69 typedef base::Callback<void(bool /* success */)> DisplayControlCallback; | |
| 70 | |
| 71 typedef std::vector<DisplaySnapshot*> DisplayStateList; | |
| 72 | |
| 73 // Mapping a display_id to a protection request bitmask. | |
| 74 typedef std::map<int64_t, uint32_t> ContentProtections; | |
| 75 | |
| 76 class Observer { | |
| 77 public: | |
| 78 virtual ~Observer() {} | |
| 79 | |
| 80 // Called after the display mode has been changed. |display| contains the | |
| 81 // just-applied configuration. Note that the X server is no longer grabbed | |
| 82 // when this method is called, so the actual configuration could've changed | |
| 83 // already. | |
| 84 virtual void OnDisplayModeChanged( | |
| 85 const DisplayStateList& displays) {} | |
| 86 | |
| 87 // Called after a display mode change attempt failed. |displays| contains | |
| 88 // displays that are detected when failed. | |
| 89 // |failed_new_state| is the new state which the system failed to enter. | |
| 90 virtual void OnDisplayModeChangeFailed( | |
| 91 const DisplayStateList& displays, | |
| 92 MultipleDisplayState failed_new_state) {} | |
| 93 | |
| 94 // Called after the power state has been changed. |power_state| contains | |
| 95 // the just-applied power state. | |
| 96 virtual void OnPowerStateChanged( | |
| 97 chromeos::DisplayPowerState power_state) {} | |
| 98 }; | |
| 99 | |
| 100 // Interface for classes that make decisions about which display state | |
| 101 // should be used. | |
| 102 class StateController { | |
| 103 public: | |
| 104 virtual ~StateController() {} | |
| 105 | |
| 106 // Called when displays are detected. | |
| 107 virtual MultipleDisplayState GetStateForDisplayIds( | |
| 108 const ui::DisplayConfigurator::DisplayStateList& outputs) const = 0; | |
| 109 | |
| 110 // Queries the resolution (|size|) in pixels to select display mode for the | |
| 111 // given display id. | |
| 112 virtual bool GetResolutionForDisplayId(int64_t display_id, | |
| 113 gfx::Size* size) const = 0; | |
| 114 }; | |
| 115 | |
| 116 // Interface for classes that implement software based mirroring. | |
| 117 class SoftwareMirroringController { | |
| 118 public: | |
| 119 virtual ~SoftwareMirroringController() {} | |
| 120 | |
| 121 // Called when the hardware mirroring failed. | |
| 122 virtual void SetSoftwareMirroring(bool enabled) = 0; | |
| 123 virtual bool SoftwareMirroringEnabled() const = 0; | |
| 124 }; | |
| 125 | |
| 126 // Helper class used by tests. | |
| 127 class TestApi { | |
| 128 public: | |
| 129 TestApi(DisplayConfigurator* configurator) : configurator_(configurator) {} | |
| 130 ~TestApi() {} | |
| 131 | |
| 132 // If |configure_timer_| is started, stops the timer, runs | |
| 133 // ConfigureDisplays(), and returns true; returns false otherwise. | |
| 134 bool TriggerConfigureTimeout() WARN_UNUSED_RESULT; | |
| 135 | |
| 136 // Gets the current delay of the |configure_timer_| if it's running, or zero | |
| 137 // time delta otherwise. | |
| 138 base::TimeDelta GetConfigureDelay() const; | |
| 139 | |
| 140 private: | |
| 141 DisplayConfigurator* configurator_; // not owned | |
| 142 | |
| 143 DISALLOW_COPY_AND_ASSIGN(TestApi); | |
| 144 }; | |
| 145 | |
| 146 // Flags that can be passed to SetDisplayPower(). | |
| 147 static const int kSetDisplayPowerNoFlags; | |
| 148 // Configure displays even if the passed-in state matches |power_state_|. | |
| 149 static const int kSetDisplayPowerForceProbe; | |
| 150 // Do not change the state if multiple displays are connected or if the | |
| 151 // only connected display is external. | |
| 152 static const int kSetDisplayPowerOnlyIfSingleInternalDisplay; | |
| 153 | |
| 154 // Gap between screens so cursor at bottom of active display doesn't | |
| 155 // partially appear on top of inactive display. Higher numbers guard | |
| 156 // against larger cursors, but also waste more memory. | |
| 157 // For simplicity, this is hard-coded to avoid the complexity of always | |
| 158 // determining the DPI of the screen and rationalizing which screen we | |
| 159 // need to use for the DPI calculation. | |
| 160 // See crbug.com/130188 for initial discussion. | |
| 161 static const int kVerticalGap = 60; | |
| 162 | |
| 163 // The delay to perform configuration after RRNotify. See the comment for | |
| 164 // |configure_timer_|. | |
| 165 static const int kConfigureDelayMs = 500; | |
| 166 | |
| 167 // The delay to perform configuration after waking up from suspend when in | |
| 168 // multi display mode. Should be bigger than |kConfigureDelayMs|. Generally | |
| 169 // big enough for external displays to be detected and added. | |
| 170 // crbug.com/614624. | |
| 171 static const int kResumeConfigureMultiDisplayDelayMs = 2000; | |
| 172 | |
| 173 // Returns the mode within |display| that matches the given size with highest | |
| 174 // refresh rate. Returns None if no matching display was found. | |
| 175 static const DisplayMode* FindDisplayModeMatchingSize( | |
| 176 const DisplaySnapshot& display, | |
| 177 const gfx::Size& size); | |
| 178 | |
| 179 DisplayConfigurator(); | |
| 180 ~DisplayConfigurator() override; | |
| 181 | |
| 182 MultipleDisplayState display_state() const { return current_display_state_; } | |
| 183 chromeos::DisplayPowerState requested_power_state() const { | |
| 184 return requested_power_state_; | |
| 185 } | |
| 186 const gfx::Size framebuffer_size() const { return framebuffer_size_; } | |
| 187 const std::vector<DisplaySnapshot*>& cached_displays() const { | |
| 188 return cached_displays_; | |
| 189 } | |
| 190 void set_state_controller(StateController* controller) { | |
| 191 state_controller_ = controller; | |
| 192 } | |
| 193 void set_mirroring_controller(SoftwareMirroringController* controller) { | |
| 194 mirroring_controller_ = controller; | |
| 195 } | |
| 196 void set_configure_display(bool configure_display) { | |
| 197 configure_display_ = configure_display; | |
| 198 } | |
| 199 chromeos::DisplayPowerState current_power_state() const { | |
| 200 return current_power_state_; | |
| 201 } | |
| 202 | |
| 203 // Called when an external process no longer needs to control the display | |
| 204 // and Chrome can take control. | |
| 205 void TakeControl(const DisplayControlCallback& callback); | |
| 206 | |
| 207 // Called when an external process needs to control the display and thus | |
| 208 // Chrome should relinquish it. | |
| 209 void RelinquishControl(const DisplayControlCallback& callback); | |
| 210 | |
| 211 // Replaces |native_display_delegate_| with the delegate passed in and sets | |
| 212 // |configure_display_| to true. Should be called before Init(). | |
| 213 void SetDelegateForTesting( | |
| 214 std::unique_ptr<NativeDisplayDelegate> display_delegate); | |
| 215 | |
| 216 // Sets the initial value of |power_state_|. Must be called before Start(). | |
| 217 void SetInitialDisplayPower(chromeos::DisplayPowerState power_state); | |
| 218 | |
| 219 // Initialization, must be called right after constructor. | |
| 220 // |is_panel_fitting_enabled| indicates hardware panel fitting support. | |
| 221 void Init(std::unique_ptr<NativeDisplayDelegate> delegate, | |
| 222 bool is_panel_fitting_enabled); | |
| 223 | |
| 224 // Does initial configuration of displays during startup. | |
| 225 // If |background_color_argb| is non zero and there are multiple displays, | |
| 226 // DisplayConfigurator sets the background color of X's RootWindow to this | |
| 227 // color. | |
| 228 void ForceInitialConfigure(uint32_t background_color_argb); | |
| 229 | |
| 230 // Stop handling display configuration events/requests. | |
| 231 void PrepareForExit(); | |
| 232 | |
| 233 // Called when powerd notifies us that some set of displays should be turned | |
| 234 // on or off. This requires enabling or disabling the CRTC associated with | |
| 235 // the display(s) in question so that the low power state is engaged. | |
| 236 // |flags| contains bitwise-or-ed kSetDisplayPower* values. After the | |
| 237 // configuration finishes |callback| is called with the status of the | |
| 238 // operation. | |
| 239 void SetDisplayPower(chromeos::DisplayPowerState power_state, | |
| 240 int flags, | |
| 241 const ConfigurationCallback& callback); | |
| 242 | |
| 243 // Force switching the display mode to |new_state|. Returns false if | |
| 244 // switching failed (possibly because |new_state| is invalid for the | |
| 245 // current set of connected displays). | |
| 246 void SetDisplayMode(MultipleDisplayState new_state); | |
| 247 | |
| 248 // NativeDisplayDelegate::Observer overrides: | |
| 249 void OnConfigurationChanged() override; | |
| 250 | |
| 251 void AddObserver(Observer* observer); | |
| 252 void RemoveObserver(Observer* observer); | |
| 253 | |
| 254 // Sets all the displays into pre-suspend mode; usually this means | |
| 255 // configure them for their resume state. This allows faster resume on | |
| 256 // machines where display configuration is slow. On completion of the display | |
| 257 // configuration |callback| is executed synchronously or asynchronously. | |
| 258 void SuspendDisplays(const ConfigurationCallback& callback); | |
| 259 | |
| 260 // Reprobes displays to handle changes made while the system was | |
| 261 // suspended. | |
| 262 void ResumeDisplays(); | |
| 263 | |
| 264 // Registers a client for display protection and requests a client id. Returns | |
| 265 // 0 if requesting failed. | |
| 266 ContentProtectionClientId RegisterContentProtectionClient(); | |
| 267 | |
| 268 // Unregisters the client. | |
| 269 void UnregisterContentProtectionClient(ContentProtectionClientId client_id); | |
| 270 | |
| 271 // Queries link status and protection status. |callback| is used to respond | |
| 272 // to the query. | |
| 273 void QueryContentProtectionStatus(ContentProtectionClientId client_id, | |
| 274 int64_t display_id, | |
| 275 const QueryProtectionCallback& callback); | |
| 276 | |
| 277 // Requests the desired protection methods. | |
| 278 // |protection_mask| is the desired protection methods, which is a bitmask | |
| 279 // of the ContentProtectionMethod values. | |
| 280 // Returns true when the protection request has been made. | |
| 281 void EnableContentProtection(ContentProtectionClientId client_id, | |
| 282 int64_t display_id, | |
| 283 uint32_t protection_mask, | |
| 284 const EnableProtectionCallback& callback); | |
| 285 | |
| 286 // Checks the available color profiles for |display_id| and fills the result | |
| 287 // into |profiles|. | |
| 288 std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles( | |
| 289 int64_t display_id); | |
| 290 | |
| 291 // Updates the color calibration to |new_profile|. | |
| 292 bool SetColorCalibrationProfile(int64_t display_id, | |
| 293 ui::ColorCalibrationProfile new_profile); | |
| 294 | |
| 295 // Enables/disables virtual display. | |
| 296 int64_t AddVirtualDisplay(const gfx::Size& display_size); | |
| 297 bool RemoveVirtualDisplay(int64_t display_id); | |
| 298 | |
| 299 // Returns true if there is at least one display on. | |
| 300 bool IsDisplayOn() const; | |
| 301 | |
| 302 // Sets the gamma, degamma and correction matrix for |display_id| to the | |
| 303 // values in |degamma_lut|, |gamma_lut| and |correction_matrix|. | |
| 304 bool SetColorCorrection(int64_t display_id, | |
| 305 const std::vector<GammaRampRGBEntry>& degamma_lut, | |
| 306 const std::vector<GammaRampRGBEntry>& gamma_lut, | |
| 307 const std::vector<float>& correction_matrix); | |
| 308 | |
| 309 private: | |
| 310 class DisplayLayoutManagerImpl; | |
| 311 | |
| 312 // Mapping a client to its protection request. | |
| 313 typedef std::map<ContentProtectionClientId, ContentProtections> | |
| 314 ProtectionRequests; | |
| 315 | |
| 316 // Updates |pending_*| members and applies the passed-in state. |callback| is | |
| 317 // invoked (perhaps synchronously) on completion. | |
| 318 void SetDisplayPowerInternal(chromeos::DisplayPowerState power_state, | |
| 319 int flags, | |
| 320 const ConfigurationCallback& callback); | |
| 321 | |
| 322 // Configures displays. Invoked by |configure_timer_|. | |
| 323 void ConfigureDisplays(); | |
| 324 | |
| 325 // Notifies observers about an attempted state change. | |
| 326 void NotifyDisplayStateObservers(bool success, | |
| 327 MultipleDisplayState attempted_state); | |
| 328 | |
| 329 // Notifies observers about a power state change. | |
| 330 void NotifyPowerStateObservers(); | |
| 331 | |
| 332 // Returns the display state that should be used with |cached_displays_| while | |
| 333 // in |power_state|. | |
| 334 MultipleDisplayState ChooseDisplayState( | |
| 335 chromeos::DisplayPowerState power_state) const; | |
| 336 | |
| 337 // Applies display protections according to requests. | |
| 338 bool ApplyProtections(const ContentProtections& requests); | |
| 339 | |
| 340 // If |configuration_task_| isn't initialized, initializes it and starts the | |
| 341 // configuration task. | |
| 342 void RunPendingConfiguration(); | |
| 343 | |
| 344 // Callback for |configuration_taks_|. When the configuration process finishes | |
| 345 // this is called with the result (|success|) and the updated display state. | |
| 346 void OnConfigured(bool success, | |
| 347 const std::vector<DisplaySnapshot*>& displays, | |
| 348 const gfx::Size& framebuffer_size, | |
| 349 MultipleDisplayState new_display_state, | |
| 350 chromeos::DisplayPowerState new_power_state); | |
| 351 | |
| 352 // Helps in identifying if a configuration task needs to be scheduled. | |
| 353 // Return true if any of the |requested_*| parameters have been updated. False | |
| 354 // otherwise. | |
| 355 bool ShouldRunConfigurationTask() const; | |
| 356 | |
| 357 // Helper functions which will call the callbacks in | |
| 358 // |in_progress_configuration_callbacks_| and | |
| 359 // |queued_configuration_callbacks_| and clear the lists after. |success| is | |
| 360 // the configuration status used when calling the callbacks. | |
| 361 void CallAndClearInProgressCallbacks(bool success); | |
| 362 void CallAndClearQueuedCallbacks(bool success); | |
| 363 | |
| 364 // Content protection callbacks called by the tasks when they finish. These | |
| 365 // are responsible for destroying the task, replying to the caller that made | |
| 366 // the task and starting the a new content protection task if one is queued. | |
| 367 void OnContentProtectionQueried( | |
| 368 ContentProtectionClientId client_id, | |
| 369 int64_t display_id, | |
| 370 QueryContentProtectionTask::Response response); | |
| 371 void OnContentProtectionEnabled(ContentProtectionClientId client_id, | |
| 372 int64_t display_id, | |
| 373 uint32_t desired_method_mask, | |
| 374 bool success); | |
| 375 void OnContentProtectionClientUnregistered(bool success); | |
| 376 | |
| 377 // Callbacks used to signal when the native platform has released/taken | |
| 378 // display control. | |
| 379 void OnDisplayControlTaken(const DisplayControlCallback& callback, | |
| 380 bool success); | |
| 381 void OnDisplayControlRelinquished(const DisplayControlCallback& callback, | |
| 382 bool success); | |
| 383 | |
| 384 // Helper function that sends the actual command. | |
| 385 // |callback| is called upon completion of the relinquish command. | |
| 386 // |success| is the result from calling SetDisplayPowerInternal() in | |
| 387 // RelinquishDisplay(). | |
| 388 void SendRelinquishDisplayControl(const DisplayControlCallback& callback, | |
| 389 bool success); | |
| 390 | |
| 391 StateController* state_controller_; | |
| 392 SoftwareMirroringController* mirroring_controller_; | |
| 393 std::unique_ptr<NativeDisplayDelegate> native_display_delegate_; | |
| 394 | |
| 395 // Used to enable modes which rely on panel fitting. | |
| 396 bool is_panel_fitting_enabled_; | |
| 397 | |
| 398 // This is detected by the constructor to determine whether or not we should | |
| 399 // be enabled. If we aren't running on Chrome OS, we can't assume that the | |
| 400 // Xrandr X11 extension or the Ozone underlying display hotplug system are | |
| 401 // supported. | |
| 402 // If this flag is set to false, any attempts to change the display | |
| 403 // configuration to immediately fail without changing the state. | |
| 404 bool configure_display_; | |
| 405 | |
| 406 // Current configuration state. | |
| 407 MultipleDisplayState current_display_state_; | |
| 408 chromeos::DisplayPowerState current_power_state_; | |
| 409 | |
| 410 // Pending requests. These values are used when triggering the next display | |
| 411 // configuration. | |
| 412 // | |
| 413 // Stores the user requested state or INVALID if nothing was requested. | |
| 414 MultipleDisplayState requested_display_state_; | |
| 415 | |
| 416 // Stores the requested power state. | |
| 417 chromeos::DisplayPowerState requested_power_state_; | |
| 418 | |
| 419 // The power state used by RunPendingConfiguration(). May be | |
| 420 // |requested_power_state_| or DISPLAY_POWER_ALL_OFF for suspend. | |
| 421 chromeos::DisplayPowerState pending_power_state_; | |
| 422 | |
| 423 // True if |pending_power_state_| has been changed. | |
| 424 bool has_pending_power_state_; | |
| 425 | |
| 426 // Bitwise-or value of the |kSetDisplayPower*| flags defined above. | |
| 427 int pending_power_flags_; | |
| 428 | |
| 429 // List of callbacks from callers waiting for the display configuration to | |
| 430 // start/finish. Note these callbacks belong to the pending request, not a | |
| 431 // request currently active. | |
| 432 std::vector<ConfigurationCallback> queued_configuration_callbacks_; | |
| 433 | |
| 434 // List of callbacks belonging to the currently running display configuration | |
| 435 // task. | |
| 436 std::vector<ConfigurationCallback> in_progress_configuration_callbacks_; | |
| 437 | |
| 438 std::queue<base::Closure> content_protection_tasks_; | |
| 439 std::queue<QueryProtectionCallback> query_protection_callbacks_; | |
| 440 std::queue<EnableProtectionCallback> enable_protection_callbacks_; | |
| 441 | |
| 442 // True if the caller wants to force the display configuration process. | |
| 443 bool force_configure_; | |
| 444 | |
| 445 // Most-recently-used display configuration. Note that the actual | |
| 446 // configuration changes asynchronously. | |
| 447 DisplayStateList cached_displays_; | |
| 448 | |
| 449 // Most-recently-used framebuffer size. | |
| 450 gfx::Size framebuffer_size_; | |
| 451 | |
| 452 base::ObserverList<Observer> observers_; | |
| 453 | |
| 454 // The timer to delay configuring displays. This is used to aggregate multiple | |
| 455 // display configuration events when they are reported in short time spans. | |
| 456 // See comment for NativeDisplayEventDispatcherX11 for more details. | |
| 457 base::OneShotTimer configure_timer_; | |
| 458 | |
| 459 // Id for next display protection client. | |
| 460 ContentProtectionClientId next_display_protection_client_id_; | |
| 461 | |
| 462 // Display protection requests of each client. | |
| 463 ProtectionRequests client_protection_requests_; | |
| 464 | |
| 465 // Display controlled by an external entity. | |
| 466 bool display_externally_controlled_; | |
| 467 | |
| 468 // True if a TakeControl or RelinquishControl has been called but the response | |
| 469 // hasn't arrived yet. | |
| 470 bool display_control_changing_; | |
| 471 | |
| 472 // Whether the displays are currently suspended. | |
| 473 bool displays_suspended_; | |
| 474 | |
| 475 // Virtual display control. | |
| 476 ScopedVector<DisplaySnapshot> virtual_display_snapshots_; | |
| 477 | |
| 478 // Last used virtual display id. | |
| 479 uint8_t last_virtual_display_id_ = 0; | |
| 480 | |
| 481 std::unique_ptr<DisplayLayoutManager> layout_manager_; | |
| 482 | |
| 483 std::unique_ptr<UpdateDisplayConfigurationTask> configuration_task_; | |
| 484 | |
| 485 // This must be the last variable. | |
| 486 base::WeakPtrFactory<DisplayConfigurator> weak_ptr_factory_; | |
| 487 | |
| 488 DISALLOW_COPY_AND_ASSIGN(DisplayConfigurator); | |
| 489 }; | |
| 490 | |
| 491 } // namespace ui | |
| 492 | |
| 493 #endif // UI_DISPLAY_CHROMEOS_DISPLAY_CONFIGURATOR_H_ | |
| OLD | NEW |