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