1 #include "display_service.h"
2
3 #include <unistd.h>
4
5 #include <algorithm>
6 #include <sstream>
7 #include <string>
8 #include <vector>
9
10 #include <android-base/file.h>
11 #include <android-base/properties.h>
12 #include <dvr/dvr_display_types.h>
13 #include <pdx/default_transport/service_endpoint.h>
14 #include <pdx/rpc/remote_method.h>
15 #include <private/android_filesystem_config.h>
16 #include <private/dvr/display_protocol.h>
17 #include <private/dvr/numeric.h>
18 #include <private/dvr/trusted_uids.h>
19 #include <private/dvr/types.h>
20
21 using android::dvr::display::DisplayProtocol;
22 using android::pdx::Channel;
23 using android::pdx::ErrorStatus;
24 using android::pdx::Message;
25 using android::pdx::Status;
26 using android::pdx::default_transport::Endpoint;
27 using android::pdx::rpc::DispatchRemoteMethod;
28
29 namespace {
30
31 const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
32 const char kDvrDeviceMetricsProperty[] = "ro.dvr.device_metrics";
33 const char kDvrDeviceConfigProperty[] = "ro.dvr.device_configuration";
34
35 } // namespace
36
37 namespace android {
38 namespace dvr {
39
DisplayService(Hwc2::Composer * hidl,hwc2_display_t primary_display_id,RequestDisplayCallback request_display_callback)40 DisplayService::DisplayService(Hwc2::Composer* hidl,
41 hwc2_display_t primary_display_id,
42 RequestDisplayCallback request_display_callback)
43 : BASE("DisplayService",
44 Endpoint::Create(display::DisplayProtocol::kClientPath)) {
45 hardware_composer_.Initialize(
46 hidl, primary_display_id, request_display_callback);
47 }
48
IsInitialized() const49 bool DisplayService::IsInitialized() const {
50 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
51 }
52
DumpState(size_t)53 std::string DisplayService::DumpState(size_t /*max_length*/) {
54 std::ostringstream stream;
55
56 auto surfaces = GetDisplaySurfaces();
57 std::sort(surfaces.begin(), surfaces.end(), [](const auto& a, const auto& b) {
58 return a->surface_id() < b->surface_id();
59 });
60
61 stream << "Application Surfaces:" << std::endl;
62
63 size_t count = 0;
64 for (const auto& surface : surfaces) {
65 if (surface->surface_type() == SurfaceType::Application) {
66 stream << "Surface " << count++ << ":";
67 stream << " surface_id=" << surface->surface_id()
68 << " process_id=" << surface->process_id()
69 << " user_id=" << surface->user_id()
70 << " visible=" << surface->visible()
71 << " z_order=" << surface->z_order();
72
73 stream << " queue_ids=";
74 auto queue_ids = surface->GetQueueIds();
75 std::sort(queue_ids.begin(), queue_ids.end());
76 for (int32_t id : queue_ids) {
77 if (id != queue_ids[0])
78 stream << ",";
79 stream << id;
80 }
81 stream << std::endl;
82 }
83 }
84 stream << std::endl;
85
86 stream << "Direct Surfaces:" << std::endl;
87
88 count = 0;
89 for (const auto& surface : surfaces) {
90 if (surface->surface_type() == SurfaceType::Direct) {
91 stream << "Surface " << count++ << ":";
92 stream << " surface_id=" << surface->surface_id()
93 << " process_id=" << surface->process_id()
94 << " user_id=" << surface->user_id()
95 << " visible=" << surface->visible()
96 << " z_order=" << surface->z_order();
97
98 stream << " queue_ids=";
99 auto queue_ids = surface->GetQueueIds();
100 std::sort(queue_ids.begin(), queue_ids.end());
101 for (int32_t id : queue_ids) {
102 if (id != queue_ids[0])
103 stream << ",";
104 stream << id;
105 }
106 stream << std::endl;
107 }
108 }
109 stream << std::endl;
110
111 stream << hardware_composer_.Dump();
112 return stream.str();
113 }
114
OnChannelClose(pdx::Message & message,const std::shared_ptr<Channel> & channel)115 void DisplayService::OnChannelClose(pdx::Message& message,
116 const std::shared_ptr<Channel>& channel) {
117 if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
118 surface->OnSetAttributes(message,
119 {{display::SurfaceAttribute::Visible,
120 display::SurfaceAttributeValue{false}}});
121 }
122 }
123
124 // First-level dispatch for display service messages. Directly handles messages
125 // that are independent of the display surface (metrics, creation) and routes
126 // surface-specific messages to the per-instance handlers.
HandleMessage(pdx::Message & message)127 Status<void> DisplayService::HandleMessage(pdx::Message& message) {
128 ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
129 ATRACE_NAME("DisplayService::HandleMessage");
130
131 switch (message.GetOp()) {
132 case DisplayProtocol::GetMetrics::Opcode:
133 DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
134 *this, &DisplayService::OnGetMetrics, message);
135 return {};
136
137 case DisplayProtocol::GetConfigurationData::Opcode:
138 DispatchRemoteMethod<DisplayProtocol::GetConfigurationData>(
139 *this, &DisplayService::OnGetConfigurationData, message);
140 return {};
141
142 case DisplayProtocol::CreateSurface::Opcode:
143 DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
144 *this, &DisplayService::OnCreateSurface, message);
145 return {};
146
147 case DisplayProtocol::SetupGlobalBuffer::Opcode:
148 DispatchRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(
149 *this, &DisplayService::OnSetupGlobalBuffer, message);
150 return {};
151
152 case DisplayProtocol::DeleteGlobalBuffer::Opcode:
153 DispatchRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(
154 *this, &DisplayService::OnDeleteGlobalBuffer, message);
155 return {};
156
157 case DisplayProtocol::GetGlobalBuffer::Opcode:
158 DispatchRemoteMethod<DisplayProtocol::GetGlobalBuffer>(
159 *this, &DisplayService::OnGetGlobalBuffer, message);
160 return {};
161
162 case DisplayProtocol::IsVrAppRunning::Opcode:
163 DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
164 *this, &DisplayService::IsVrAppRunning, message);
165 return {};
166
167 // Direct the surface specific messages to the surface instance.
168 case DisplayProtocol::SetAttributes::Opcode:
169 case DisplayProtocol::CreateQueue::Opcode:
170 case DisplayProtocol::GetSurfaceInfo::Opcode:
171 return HandleSurfaceMessage(message);
172
173 default:
174 return Service::HandleMessage(message);
175 }
176 }
177
OnGetMetrics(pdx::Message &)178 Status<display::Metrics> DisplayService::OnGetMetrics(
179 pdx::Message& /*message*/) {
180 const auto& params = hardware_composer_.GetPrimaryDisplayParams();
181 return {{static_cast<uint32_t>(params.width),
182 static_cast<uint32_t>(params.height),
183 static_cast<uint32_t>(params.dpi.x),
184 static_cast<uint32_t>(params.dpi.y),
185 static_cast<uint32_t>(params.vsync_period_ns),
186 0,
187 0,
188 0,
189 0.0,
190 {},
191 {}}};
192 }
193
OnGetConfigurationData(pdx::Message &,display::ConfigFileType config_type)194 pdx::Status<std::string> DisplayService::OnGetConfigurationData(
195 pdx::Message& /*message*/, display::ConfigFileType config_type) {
196 std::string property_name;
197 switch (config_type) {
198 case display::ConfigFileType::kLensMetrics:
199 property_name = kDvrLensMetricsProperty;
200 break;
201 case display::ConfigFileType::kDeviceMetrics:
202 property_name = kDvrDeviceMetricsProperty;
203 break;
204 case display::ConfigFileType::kDeviceConfiguration:
205 property_name = kDvrDeviceConfigProperty;
206 break;
207 default:
208 return ErrorStatus(EINVAL);
209 }
210 std::string file_path = base::GetProperty(property_name, "");
211 if (file_path.empty()) {
212 return ErrorStatus(ENOENT);
213 }
214
215 std::string data;
216 if (!base::ReadFileToString(file_path, &data)) {
217 return ErrorStatus(errno);
218 }
219
220 return std::move(data);
221 }
222
223 // Creates a new DisplaySurface and associates it with this channel. This may
224 // only be done once per channel.
OnCreateSurface(pdx::Message & message,const display::SurfaceAttributes & attributes)225 Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
226 pdx::Message& message, const display::SurfaceAttributes& attributes) {
227 // A surface may only be created once per channel.
228 if (message.GetChannel())
229 return ErrorStatus(EINVAL);
230
231 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
232 message.GetChannelId());
233
234 // Use the channel id as the unique surface id.
235 const int surface_id = message.GetChannelId();
236 const int process_id = message.GetProcessId();
237 const int user_id = message.GetEffectiveUserId();
238
239 ALOGI_IF(TRACE,
240 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
241 surface_id, process_id);
242
243 auto surface_status =
244 DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
245 if (!surface_status) {
246 ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
247 surface_status.GetErrorMessage().c_str());
248 return ErrorStatus(surface_status.error());
249 }
250 auto surface = surface_status.take();
251 message.SetChannel(surface);
252
253 // Update the surface with the attributes supplied with the create call. For
254 // application surfaces this has the side effect of notifying the display
255 // manager of the new surface. For direct surfaces, this may trigger a mode
256 // change, depending on the value of the visible attribute.
257 surface->OnSetAttributes(message, attributes);
258
259 return {{surface->surface_id(), surface->visible(), surface->z_order()}};
260 }
261
SurfaceUpdated(SurfaceType surface_type,display::SurfaceUpdateFlags update_flags)262 void DisplayService::SurfaceUpdated(SurfaceType surface_type,
263 display::SurfaceUpdateFlags update_flags) {
264 ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
265 update_flags.value());
266 if (update_flags.value() != 0) {
267 if (surface_type == SurfaceType::Application)
268 NotifyDisplayConfigurationUpdate();
269 else
270 UpdateActiveDisplaySurfaces();
271 }
272 }
273
OnSetupGlobalBuffer(pdx::Message & message,DvrGlobalBufferKey key,size_t size,uint64_t usage)274 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnSetupGlobalBuffer(
275 pdx::Message& message, DvrGlobalBufferKey key, size_t size,
276 uint64_t usage) {
277 const int user_id = message.GetEffectiveUserId();
278 const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
279
280 if (!trusted) {
281 ALOGE(
282 "DisplayService::OnSetupGlobalBuffer: Permission denied for user_id=%d",
283 user_id);
284 return ErrorStatus(EPERM);
285 }
286 return SetupGlobalBuffer(key, size, usage);
287 }
288
OnDeleteGlobalBuffer(pdx::Message & message,DvrGlobalBufferKey key)289 pdx::Status<void> DisplayService::OnDeleteGlobalBuffer(pdx::Message& message,
290 DvrGlobalBufferKey key) {
291 const int user_id = message.GetEffectiveUserId();
292 const bool trusted = (user_id == AID_ROOT) || IsTrustedUid(user_id);
293
294 if (!trusted) {
295 ALOGE(
296 "DisplayService::OnDeleteGlobalBuffer: Permission denied for "
297 "user_id=%d",
298 user_id);
299 return ErrorStatus(EPERM);
300 }
301 return DeleteGlobalBuffer(key);
302 }
303
OnGetGlobalBuffer(pdx::Message &,DvrGlobalBufferKey key)304 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetGlobalBuffer(
305 pdx::Message& /* message */, DvrGlobalBufferKey key) {
306 ALOGD_IF(TRACE, "DisplayService::OnGetGlobalBuffer: key=%d", key);
307 auto global_buffer = global_buffers_.find(key);
308 if (global_buffer != global_buffers_.end())
309 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
310 else
311 return pdx::ErrorStatus(EINVAL);
312 }
313
314 // Calls the message handler for the DisplaySurface associated with this
315 // channel.
HandleSurfaceMessage(pdx::Message & message)316 Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
317 auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
318 ALOGW_IF(!surface,
319 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
320
321 if (surface)
322 return surface->HandleMessage(message);
323 else
324 return ErrorStatus(EINVAL);
325 }
326
GetDisplaySurface(int surface_id) const327 std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
328 int surface_id) const {
329 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
330 }
331
332 std::vector<std::shared_ptr<DisplaySurface>>
GetDisplaySurfaces() const333 DisplayService::GetDisplaySurfaces() const {
334 return GetChannels<DisplaySurface>();
335 }
336
337 std::vector<std::shared_ptr<DirectDisplaySurface>>
GetVisibleDisplaySurfaces() const338 DisplayService::GetVisibleDisplaySurfaces() const {
339 std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
340
341 ForEachDisplaySurface(
342 SurfaceType::Direct,
343 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
344 if (surface->visible()) {
345 visible_surfaces.push_back(
346 std::static_pointer_cast<DirectDisplaySurface>(surface));
347 surface->ClearUpdate();
348 }
349 });
350
351 return visible_surfaces;
352 }
353
UpdateActiveDisplaySurfaces()354 void DisplayService::UpdateActiveDisplaySurfaces() {
355 auto visible_surfaces = GetVisibleDisplaySurfaces();
356 ALOGD_IF(TRACE,
357 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
358 visible_surfaces.size());
359 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
360 }
361
SetupGlobalBuffer(DvrGlobalBufferKey key,size_t size,uint64_t usage)362 pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupGlobalBuffer(
363 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
364 auto global_buffer = global_buffers_.find(key);
365 if (global_buffer == global_buffers_.end()) {
366 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
367 HAL_PIXEL_FORMAT_BLOB, usage);
368
369 // Some buffers are used internally. If they were configured with an
370 // invalid size or format, this will fail.
371 int result = hardware_composer_.OnNewGlobalBuffer(key, *ion_buffer.get());
372 if (result < 0)
373 return ErrorStatus(result);
374 global_buffer =
375 global_buffers_.insert(std::make_pair(key, std::move(ion_buffer)))
376 .first;
377 }
378
379 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
380 }
381
DeleteGlobalBuffer(DvrGlobalBufferKey key)382 pdx::Status<void> DisplayService::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
383 auto global_buffer = global_buffers_.find(key);
384 if (global_buffer != global_buffers_.end()) {
385 // Some buffers are used internally.
386 hardware_composer_.OnDeletedGlobalBuffer(key);
387 global_buffers_.erase(global_buffer);
388 }
389
390 return {0};
391 }
392
SetDisplayConfigurationUpdateNotifier(DisplayConfigurationUpdateNotifier update_notifier)393 void DisplayService::SetDisplayConfigurationUpdateNotifier(
394 DisplayConfigurationUpdateNotifier update_notifier) {
395 update_notifier_ = update_notifier;
396 }
397
NotifyDisplayConfigurationUpdate()398 void DisplayService::NotifyDisplayConfigurationUpdate() {
399 if (update_notifier_)
400 update_notifier_();
401 }
402
IsVrAppRunning(pdx::Message &)403 Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
404 bool visible = false;
405 ForEachDisplaySurface(
406 SurfaceType::Application,
407 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
408 if (surface->visible())
409 visible = true;
410 });
411
412 return {visible};
413 }
414
415 } // namespace dvr
416 } // namespace android
417