• 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,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