Home | History | Annotate | Download | only in libvrflinger
      1 #include "display_service.h"
      2 
      3 #include <unistd.h>
      4 #include <vector>
      5 
      6 #include <dvr/dvr_display_types.h>
      7 #include <pdx/default_transport/service_endpoint.h>
      8 #include <pdx/rpc/remote_method.h>
      9 #include <private/dvr/display_protocol.h>
     10 #include <private/dvr/numeric.h>
     11 #include <private/dvr/types.h>
     12 
     13 using android::dvr::display::DisplayProtocol;
     14 using android::pdx::Channel;
     15 using android::pdx::ErrorStatus;
     16 using android::pdx::Message;
     17 using android::pdx::Status;
     18 using android::pdx::default_transport::Endpoint;
     19 using android::pdx::rpc::DispatchRemoteMethod;
     20 
     21 namespace android {
     22 namespace dvr {
     23 
     24 DisplayService::DisplayService(Hwc2::Composer* hidl,
     25                                RequestDisplayCallback request_display_callback)
     26     : BASE("DisplayService",
     27            Endpoint::Create(display::DisplayProtocol::kClientPath)),
     28       hardware_composer_(hidl, request_display_callback),
     29       request_display_callback_(request_display_callback) {
     30   hardware_composer_.Initialize();
     31 }
     32 
     33 bool DisplayService::IsInitialized() const {
     34   return BASE::IsInitialized() && hardware_composer_.IsInitialized();
     35 }
     36 
     37 std::string DisplayService::DumpState(size_t /*max_length*/) {
     38   return hardware_composer_.Dump();
     39 }
     40 
     41 void DisplayService::OnChannelClose(pdx::Message& message,
     42                                     const std::shared_ptr<Channel>& channel) {
     43   if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
     44     surface->OnSetAttributes(message,
     45                              {{display::SurfaceAttribute::Visible,
     46                                display::SurfaceAttributeValue{false}}});
     47     SurfaceUpdated(surface->surface_type(),
     48                    display::SurfaceUpdateFlags::VisibilityChanged);
     49   }
     50 }
     51 
     52 // First-level dispatch for display service messages. Directly handles messages
     53 // that are independent of the display surface (metrics, creation) and routes
     54 // surface-specific messages to the per-instance handlers.
     55 Status<void> DisplayService::HandleMessage(pdx::Message& message) {
     56   ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
     57   switch (message.GetOp()) {
     58     case DisplayProtocol::GetMetrics::Opcode:
     59       DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
     60           *this, &DisplayService::OnGetMetrics, message);
     61       return {};
     62 
     63     case DisplayProtocol::CreateSurface::Opcode:
     64       DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
     65           *this, &DisplayService::OnCreateSurface, message);
     66       return {};
     67 
     68     case DisplayProtocol::GetNamedBuffer::Opcode:
     69       DispatchRemoteMethod<DisplayProtocol::GetNamedBuffer>(
     70           *this, &DisplayService::OnGetNamedBuffer, message);
     71       return {};
     72 
     73     case DisplayProtocol::IsVrAppRunning::Opcode:
     74       DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
     75           *this, &DisplayService::IsVrAppRunning, message);
     76       return {};
     77 
     78     // Direct the surface specific messages to the surface instance.
     79     case DisplayProtocol::SetAttributes::Opcode:
     80     case DisplayProtocol::CreateQueue::Opcode:
     81     case DisplayProtocol::GetSurfaceInfo::Opcode:
     82       return HandleSurfaceMessage(message);
     83 
     84     default:
     85       return Service::HandleMessage(message);
     86   }
     87 }
     88 
     89 Status<display::Metrics> DisplayService::OnGetMetrics(
     90     pdx::Message& /*message*/) {
     91   return {{static_cast<uint32_t>(GetDisplayMetrics().width),
     92            static_cast<uint32_t>(GetDisplayMetrics().height),
     93            static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
     94            static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
     95            static_cast<uint32_t>(
     96                hardware_composer_.native_display_metrics().vsync_period_ns),
     97            0,
     98            0,
     99            0,
    100            0.0,
    101            {},
    102            {}}};
    103 }
    104 
    105 // Creates a new DisplaySurface and associates it with this channel. This may
    106 // only be done once per channel.
    107 Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
    108     pdx::Message& message, const display::SurfaceAttributes& attributes) {
    109   // A surface may only be created once per channel.
    110   if (message.GetChannel())
    111     return ErrorStatus(EINVAL);
    112 
    113   ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
    114            message.GetChannelId());
    115 
    116   // Use the channel id as the unique surface id.
    117   const int surface_id = message.GetChannelId();
    118   const int process_id = message.GetProcessId();
    119   const int user_id = message.GetEffectiveUserId();
    120 
    121   ALOGI_IF(TRACE,
    122            "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
    123            surface_id, process_id);
    124 
    125   auto surface_status =
    126       DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
    127   if (!surface_status) {
    128     ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
    129           surface_status.GetErrorMessage().c_str());
    130     return ErrorStatus(surface_status.error());
    131   }
    132 
    133   SurfaceType surface_type = surface_status.get()->surface_type();
    134   display::SurfaceUpdateFlags update_flags =
    135       surface_status.get()->update_flags();
    136   display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
    137                                     surface_status.get()->visible(),
    138                                     surface_status.get()->z_order()};
    139 
    140   message.SetChannel(surface_status.take());
    141 
    142   SurfaceUpdated(surface_type, update_flags);
    143   return {surface_info};
    144 }
    145 
    146 void DisplayService::SurfaceUpdated(SurfaceType surface_type,
    147                                     display::SurfaceUpdateFlags update_flags) {
    148   ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
    149            update_flags.value());
    150   if (update_flags.value() != 0) {
    151     if (surface_type == SurfaceType::Application)
    152       NotifyDisplayConfigurationUpdate();
    153     else
    154       UpdateActiveDisplaySurfaces();
    155   }
    156 }
    157 
    158 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
    159     pdx::Message& /* message */, const std::string& name) {
    160   ALOGD_IF(TRACE, "displayService::OnGetNamedBuffer: name=%s", name.c_str());
    161   auto named_buffer = named_buffers_.find(name);
    162   if (named_buffer != named_buffers_.end())
    163     return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
    164   else
    165     return pdx::ErrorStatus(EINVAL);
    166 }
    167 
    168 // Calls the message handler for the DisplaySurface associated with this
    169 // channel.
    170 Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
    171   auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
    172   ALOGW_IF(!surface,
    173            "DisplayService::HandleSurfaceMessage: surface is nullptr!");
    174 
    175   if (surface)
    176     return surface->HandleMessage(message);
    177   else
    178     return ErrorStatus(EINVAL);
    179 }
    180 
    181 std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
    182     int surface_id) const {
    183   return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
    184 }
    185 
    186 std::vector<std::shared_ptr<DisplaySurface>>
    187 DisplayService::GetDisplaySurfaces() const {
    188   return GetChannels<DisplaySurface>();
    189 }
    190 
    191 std::vector<std::shared_ptr<DirectDisplaySurface>>
    192 DisplayService::GetVisibleDisplaySurfaces() const {
    193   std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
    194 
    195   ForEachDisplaySurface(
    196       SurfaceType::Direct,
    197       [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
    198         if (surface->visible()) {
    199           visible_surfaces.push_back(
    200               std::static_pointer_cast<DirectDisplaySurface>(surface));
    201           surface->ClearUpdate();
    202         }
    203       });
    204 
    205   return visible_surfaces;
    206 }
    207 
    208 void DisplayService::UpdateActiveDisplaySurfaces() {
    209   auto visible_surfaces = GetVisibleDisplaySurfaces();
    210 
    211   std::sort(visible_surfaces.begin(), visible_surfaces.end(),
    212             [](const std::shared_ptr<DisplaySurface>& a,
    213                const std::shared_ptr<DisplaySurface>& b) {
    214               return a->z_order() < b->z_order();
    215             });
    216 
    217   ALOGD_IF(TRACE,
    218            "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
    219            visible_surfaces.size());
    220 
    221   hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
    222 }
    223 
    224 pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
    225     const std::string& name, size_t size, uint64_t usage) {
    226   auto named_buffer = named_buffers_.find(name);
    227   if (named_buffer == named_buffers_.end()) {
    228     auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
    229                                                   HAL_PIXEL_FORMAT_BLOB, usage);
    230     named_buffer =
    231         named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
    232             .first;
    233   }
    234 
    235   return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
    236 }
    237 
    238 void DisplayService::OnHardwareComposerRefresh() {
    239   hardware_composer_.OnHardwareComposerRefresh();
    240 }
    241 
    242 void DisplayService::SetDisplayConfigurationUpdateNotifier(
    243     DisplayConfigurationUpdateNotifier update_notifier) {
    244   update_notifier_ = update_notifier;
    245 }
    246 
    247 void DisplayService::NotifyDisplayConfigurationUpdate() {
    248   if (update_notifier_)
    249     update_notifier_();
    250 }
    251 
    252 Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
    253   bool visible = false;
    254   ForEachDisplaySurface(
    255       SurfaceType::Application,
    256       [&visible](const std::shared_ptr<DisplaySurface>& surface) {
    257         if (surface->visible())
    258           visible = true;
    259       });
    260 
    261   return {visible};
    262 }
    263 
    264 }  // namespace dvr
    265 }  // namespace android
    266