1 #include "display_service.h"
2
3 #include <unistd.h>
4 #include <vector>
5
6 #include <dvr/dvr_display_types.h>
7 #include <pdx/default_transport/service_endpoint.h>
8 #include <pdx/rpc/remote_method.h>
9 #include <private/dvr/display_protocol.h>
10 #include <private/dvr/numeric.h>
11 #include <private/dvr/types.h>
12
13 using android::dvr::display::DisplayProtocol;
14 using android::pdx::Channel;
15 using android::pdx::ErrorStatus;
16 using android::pdx::Message;
17 using android::pdx::Status;
18 using android::pdx::default_transport::Endpoint;
19 using android::pdx::rpc::DispatchRemoteMethod;
20
21 namespace android {
22 namespace dvr {
23
DisplayService(Hwc2::Composer * hidl,RequestDisplayCallback request_display_callback)24 DisplayService::DisplayService(Hwc2::Composer* hidl,
25 RequestDisplayCallback request_display_callback)
26 : BASE("DisplayService",
27 Endpoint::Create(display::DisplayProtocol::kClientPath)),
28 hardware_composer_(hidl, request_display_callback),
29 request_display_callback_(request_display_callback) {
30 hardware_composer_.Initialize();
31 }
32
IsInitialized() const33 bool DisplayService::IsInitialized() const {
34 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
35 }
36
DumpState(size_t)37 std::string DisplayService::DumpState(size_t /*max_length*/) {
38 return hardware_composer_.Dump();
39 }
40
OnChannelClose(pdx::Message & message,const std::shared_ptr<Channel> & channel)41 void DisplayService::OnChannelClose(pdx::Message& message,
42 const std::shared_ptr<Channel>& channel) {
43 if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
44 surface->OnSetAttributes(message,
45 {{display::SurfaceAttribute::Visible,
46 display::SurfaceAttributeValue{false}}});
47 SurfaceUpdated(surface->surface_type(),
48 display::SurfaceUpdateFlags::VisibilityChanged);
49 }
50 }
51
52 // First-level dispatch for display service messages. Directly handles messages
53 // that are independent of the display surface (metrics, creation) and routes
54 // surface-specific messages to the per-instance handlers.
HandleMessage(pdx::Message & message)55 Status<void> DisplayService::HandleMessage(pdx::Message& message) {
56 ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
57 switch (message.GetOp()) {
58 case DisplayProtocol::GetMetrics::Opcode:
59 DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
60 *this, &DisplayService::OnGetMetrics, message);
61 return {};
62
63 case DisplayProtocol::CreateSurface::Opcode:
64 DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
65 *this, &DisplayService::OnCreateSurface, message);
66 return {};
67
68 case DisplayProtocol::GetNamedBuffer::Opcode:
69 DispatchRemoteMethod<DisplayProtocol::GetNamedBuffer>(
70 *this, &DisplayService::OnGetNamedBuffer, message);
71 return {};
72
73 case DisplayProtocol::IsVrAppRunning::Opcode:
74 DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
75 *this, &DisplayService::IsVrAppRunning, message);
76 return {};
77
78 // Direct the surface specific messages to the surface instance.
79 case DisplayProtocol::SetAttributes::Opcode:
80 case DisplayProtocol::CreateQueue::Opcode:
81 case DisplayProtocol::GetSurfaceInfo::Opcode:
82 return HandleSurfaceMessage(message);
83
84 default:
85 return Service::HandleMessage(message);
86 }
87 }
88
OnGetMetrics(pdx::Message &)89 Status<display::Metrics> DisplayService::OnGetMetrics(
90 pdx::Message& /*message*/) {
91 return {{static_cast<uint32_t>(GetDisplayMetrics().width),
92 static_cast<uint32_t>(GetDisplayMetrics().height),
93 static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
94 static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
95 static_cast<uint32_t>(
96 hardware_composer_.native_display_metrics().vsync_period_ns),
97 0,
98 0,
99 0,
100 0.0,
101 {},
102 {}}};
103 }
104
105 // Creates a new DisplaySurface and associates it with this channel. This may
106 // only be done once per channel.
OnCreateSurface(pdx::Message & message,const display::SurfaceAttributes & attributes)107 Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
108 pdx::Message& message, const display::SurfaceAttributes& attributes) {
109 // A surface may only be created once per channel.
110 if (message.GetChannel())
111 return ErrorStatus(EINVAL);
112
113 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
114 message.GetChannelId());
115
116 // Use the channel id as the unique surface id.
117 const int surface_id = message.GetChannelId();
118 const int process_id = message.GetProcessId();
119 const int user_id = message.GetEffectiveUserId();
120
121 ALOGI_IF(TRACE,
122 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
123 surface_id, process_id);
124
125 auto surface_status =
126 DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
127 if (!surface_status) {
128 ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
129 surface_status.GetErrorMessage().c_str());
130 return ErrorStatus(surface_status.error());
131 }
132
133 SurfaceType surface_type = surface_status.get()->surface_type();
134 display::SurfaceUpdateFlags update_flags =
135 surface_status.get()->update_flags();
136 display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
137 surface_status.get()->visible(),
138 surface_status.get()->z_order()};
139
140 message.SetChannel(surface_status.take());
141
142 SurfaceUpdated(surface_type, update_flags);
143 return {surface_info};
144 }
145
SurfaceUpdated(SurfaceType surface_type,display::SurfaceUpdateFlags update_flags)146 void DisplayService::SurfaceUpdated(SurfaceType surface_type,
147 display::SurfaceUpdateFlags update_flags) {
148 ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
149 update_flags.value());
150 if (update_flags.value() != 0) {
151 if (surface_type == SurfaceType::Application)
152 NotifyDisplayConfigurationUpdate();
153 else
154 UpdateActiveDisplaySurfaces();
155 }
156 }
157
OnGetNamedBuffer(pdx::Message &,const std::string & name)158 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
159 pdx::Message& /* message */, const std::string& name) {
160 ALOGD_IF(TRACE, "displayService::OnGetNamedBuffer: name=%s", name.c_str());
161 auto named_buffer = named_buffers_.find(name);
162 if (named_buffer != named_buffers_.end())
163 return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
164 else
165 return pdx::ErrorStatus(EINVAL);
166 }
167
168 // Calls the message handler for the DisplaySurface associated with this
169 // channel.
HandleSurfaceMessage(pdx::Message & message)170 Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
171 auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
172 ALOGW_IF(!surface,
173 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
174
175 if (surface)
176 return surface->HandleMessage(message);
177 else
178 return ErrorStatus(EINVAL);
179 }
180
GetDisplaySurface(int surface_id) const181 std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
182 int surface_id) const {
183 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
184 }
185
186 std::vector<std::shared_ptr<DisplaySurface>>
GetDisplaySurfaces() const187 DisplayService::GetDisplaySurfaces() const {
188 return GetChannels<DisplaySurface>();
189 }
190
191 std::vector<std::shared_ptr<DirectDisplaySurface>>
GetVisibleDisplaySurfaces() const192 DisplayService::GetVisibleDisplaySurfaces() const {
193 std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
194
195 ForEachDisplaySurface(
196 SurfaceType::Direct,
197 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
198 if (surface->visible()) {
199 visible_surfaces.push_back(
200 std::static_pointer_cast<DirectDisplaySurface>(surface));
201 surface->ClearUpdate();
202 }
203 });
204
205 return visible_surfaces;
206 }
207
UpdateActiveDisplaySurfaces()208 void DisplayService::UpdateActiveDisplaySurfaces() {
209 auto visible_surfaces = GetVisibleDisplaySurfaces();
210
211 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
212 [](const std::shared_ptr<DisplaySurface>& a,
213 const std::shared_ptr<DisplaySurface>& b) {
214 return a->z_order() < b->z_order();
215 });
216
217 ALOGD_IF(TRACE,
218 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
219 visible_surfaces.size());
220
221 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
222 }
223
SetupNamedBuffer(const std::string & name,size_t size,uint64_t usage)224 pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
225 const std::string& name, size_t size, uint64_t usage) {
226 auto named_buffer = named_buffers_.find(name);
227 if (named_buffer == named_buffers_.end()) {
228 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
229 HAL_PIXEL_FORMAT_BLOB, usage);
230 named_buffer =
231 named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
232 .first;
233 }
234
235 return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
236 }
237
OnHardwareComposerRefresh()238 void DisplayService::OnHardwareComposerRefresh() {
239 hardware_composer_.OnHardwareComposerRefresh();
240 }
241
SetDisplayConfigurationUpdateNotifier(DisplayConfigurationUpdateNotifier update_notifier)242 void DisplayService::SetDisplayConfigurationUpdateNotifier(
243 DisplayConfigurationUpdateNotifier update_notifier) {
244 update_notifier_ = update_notifier;
245 }
246
NotifyDisplayConfigurationUpdate()247 void DisplayService::NotifyDisplayConfigurationUpdate() {
248 if (update_notifier_)
249 update_notifier_();
250 }
251
IsVrAppRunning(pdx::Message &)252 Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
253 bool visible = false;
254 ForEachDisplaySurface(
255 SurfaceType::Application,
256 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
257 if (surface->visible())
258 visible = true;
259 });
260
261 return {visible};
262 }
263
264 } // namespace dvr
265 } // namespace android
266