Home | History | Annotate | Download | only in libvrflinger
      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 
     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 
     49 bool DisplayService::IsInitialized() const {
     50   return BASE::IsInitialized() && hardware_composer_.IsInitialized();
     51 }
     52 
     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 
    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.
    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 
    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 
    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.
    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 
    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 
    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 
    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 
    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.
    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 
    327 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>>
    333 DisplayService::GetDisplaySurfaces() const {
    334   return GetChannels<DisplaySurface>();
    335 }
    336 
    337 std::vector<std::shared_ptr<DirectDisplaySurface>>
    338 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 
    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 
    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 
    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 
    393 void DisplayService::SetDisplayConfigurationUpdateNotifier(
    394     DisplayConfigurationUpdateNotifier update_notifier) {
    395   update_notifier_ = update_notifier;
    396 }
    397 
    398 void DisplayService::NotifyDisplayConfigurationUpdate() {
    399   if (update_notifier_)
    400     update_notifier_();
    401 }
    402 
    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