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