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_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_
6 #define UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_
7 
8 #include <stdint.h>
9 #include <map>
10 #include <memory>
11 
12 #include "base/containers/queue.h"
13 #include "base/file_descriptor_posix.h"
14 #include "base/files/scoped_file.h"
15 #include "base/macros.h"
16 #include "base/memory/weak_ptr.h"
17 #include "ui/display/types/native_display_delegate.h"
18 #include "ui/events/ozone/device/device_event.h"
19 #include "ui/events/ozone/device/device_event_observer.h"
20 #include "ui/events/ozone/evdev/event_factory_evdev.h"
21 #include "ui/ozone/platform/drm/host/gpu_thread_observer.h"
22 #include "ui/ozone/public/ozone_platform.h"
23 
24 namespace ui {
25 
26 class DeviceManager;
27 class DrmDeviceHandle;
28 class DrmDisplayHost;
29 class DrmDisplayHostManager;
30 class DrmNativeDisplayDelegate;
31 class GpuThreadAdapter;
32 
33 struct DisplaySnapshot_Params;
34 
35 // The portion of the DrmDisplayHostManager implementation that is agnostic
36 // in how its communication with GPU-specific functionality is implemented.
37 // This is used from both the IPC and the in-process versions in  MUS.
38 class DrmDisplayHostManager : public DeviceEventObserver, GpuThreadObserver {
39  public:
40   DrmDisplayHostManager(
41       GpuThreadAdapter* proxy,
42       DeviceManager* device_manager,
43       OzonePlatform::InitializedHostProperties* host_properties,
44       InputControllerEvdev* input_controller);
45   ~DrmDisplayHostManager() override;
46 
47   DrmDisplayHost* GetDisplay(int64_t display_id);
48 
49   // External API.
50   void AddDelegate(DrmNativeDisplayDelegate* delegate);
51   void RemoveDelegate(DrmNativeDisplayDelegate* delegate);
52   void TakeDisplayControl(display::DisplayControlCallback callback);
53   void RelinquishDisplayControl(display::DisplayControlCallback callback);
54   void UpdateDisplays(display::GetDisplaysCallback callback);
55 
56   // DeviceEventObserver overrides:
57   void OnDeviceEvent(const DeviceEvent& event) override;
58 
59   // GpuThreadObserver overrides:
60   void OnGpuProcessLaunched() override;
61   void OnGpuThreadReady() override;
62   void OnGpuThreadRetired() override;
63 
64   // Communication-free implementations of actions performed in response to
65   // messages from the GPU thread.
66   void GpuHasUpdatedNativeDisplays(
67       const std::vector<DisplaySnapshot_Params>& displays);
68   void GpuConfiguredDisplay(int64_t display_id, bool status);
69   void GpuReceivedHDCPState(int64_t display_id,
70                             bool status,
71                             display::HDCPState state);
72   void GpuUpdatedHDCPState(int64_t display_id, bool status);
73   void GpuTookDisplayControl(bool status);
74   void GpuRelinquishedDisplayControl(bool status);
75 
76  private:
77   struct DisplayEvent {
DisplayEventDisplayEvent78     DisplayEvent(DeviceEvent::ActionType action_type,
79                  const base::FilePath& path)
80         : action_type(action_type), path(path) {}
81 
82     DeviceEvent::ActionType action_type;
83     base::FilePath path;
84   };
85 
86   // Handle hotplug events sequentially.
87   void ProcessEvent();
88 
89   // Called as a result of finishing to process the display hotplug event. These
90   // are responsible for dequing the event and scheduling the next event.
91   void OnAddGraphicsDevice(const base::FilePath& path,
92                            const base::FilePath& sysfs_path,
93                            std::unique_ptr<DrmDeviceHandle> handle);
94   void OnUpdateGraphicsDevice();
95   void OnRemoveGraphicsDevice(const base::FilePath& path);
96 
97   void RunUpdateDisplaysCallback(display::GetDisplaysCallback callback) const;
98 
99   void NotifyDisplayDelegate() const;
100 
101   GpuThreadAdapter* const proxy_;                 // Not owned.
102   DeviceManager* const device_manager_;           // Not owned.
103   InputControllerEvdev* const input_controller_;  // Not owned.
104 
105   DrmNativeDisplayDelegate* delegate_ = nullptr;  // Not owned.
106 
107   // File path for the primary graphics card which is opened by default in the
108   // GPU process. We'll avoid opening this in hotplug events since it will race
109   // with the GPU process trying to open it and aquire DRM master.
110   const base::FilePath primary_graphics_card_path_;
111 
112   // Keeps track if there is a dummy display. This happens on initialization
113   // when there is no connection to the GPU to update the displays.
114   bool has_dummy_display_ = false;
115 
116   std::vector<std::unique_ptr<DrmDisplayHost>> displays_;
117 
118   display::GetDisplaysCallback get_displays_callback_;
119 
120   bool display_externally_controlled_ = false;
121   bool display_control_change_pending_ = false;
122   display::DisplayControlCallback take_display_control_callback_;
123   display::DisplayControlCallback relinquish_display_control_callback_;
124 
125   // Used to serialize display event processing. This is done since
126   // opening/closing DRM devices cannot be done on the UI thread and are handled
127   // on a worker thread. Thus, we need to queue events in order to process them
128   // in the correct order.
129   base::queue<DisplayEvent> event_queue_;
130 
131   // True if a display event is currently being processed on a worker thread.
132   bool task_pending_ = false;
133 
134   // Keeps track of all the active DRM devices. The key is the device path, the
135   // value is the sysfs path which has been resolved from the device path.
136   std::map<base::FilePath, base::FilePath> drm_devices_;
137 
138   // This is used to cache the primary DRM device until the channel is
139   // established.
140   std::unique_ptr<DrmDeviceHandle> primary_drm_device_handle_;
141 
142   base::WeakPtrFactory<DrmDisplayHostManager> weak_ptr_factory_{this};
143 
144   DISALLOW_COPY_AND_ASSIGN(DrmDisplayHostManager);
145 };
146 
147 }  // namespace ui
148 
149 #endif  // UI_OZONE_PLATFORM_DRM_HOST_DRM_DISPLAY_HOST_MANAGER_H_
150