Home | History | Annotate | Download | only in libvrflinger
      1 #include "display_manager_service.h"
      2 
      3 #include <pdx/channel_handle.h>
      4 #include <pdx/default_transport/service_endpoint.h>
      5 #include <private/android_filesystem_config.h>
      6 #include <private/dvr/display_protocol.h>
      7 #include <private/dvr/trusted_uids.h>
      8 #include <sys/poll.h>
      9 
     10 #include <array>
     11 
     12 using android::dvr::display::DisplayManagerProtocol;
     13 using android::pdx::Channel;
     14 using android::pdx::LocalChannelHandle;
     15 using android::pdx::Message;
     16 using android::pdx::default_transport::Endpoint;
     17 using android::pdx::ErrorStatus;
     18 using android::pdx::rpc::DispatchRemoteMethod;
     19 using android::pdx::rpc::IfAnyOf;
     20 using android::pdx::rpc::RemoteMethodError;
     21 
     22 namespace android {
     23 namespace dvr {
     24 
     25 void DisplayManager::SetNotificationsPending(bool pending) {
     26   auto status = service_->ModifyChannelEvents(channel_id_, pending ? 0 : POLLIN,
     27                                               pending ? POLLIN : 0);
     28   ALOGE_IF(!status,
     29            "DisplayManager::SetNotificationPending: Failed to modify channel "
     30            "events: %s",
     31            status.GetErrorMessage().c_str());
     32 }
     33 
     34 DisplayManagerService::DisplayManagerService(
     35     const std::shared_ptr<DisplayService>& display_service)
     36     : BASE("DisplayManagerService",
     37            Endpoint::Create(DisplayManagerProtocol::kClientPath)),
     38       display_service_(display_service) {
     39   display_service_->SetDisplayConfigurationUpdateNotifier(
     40       std::bind(&DisplayManagerService::OnDisplaySurfaceChange, this));
     41 }
     42 
     43 std::shared_ptr<pdx::Channel> DisplayManagerService::OnChannelOpen(
     44     pdx::Message& message) {
     45   const int user_id = message.GetEffectiveUserId();
     46   const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
     47 
     48   // Prevent more than one display manager from registering at a time or
     49   // untrusted UIDs from connecting.
     50   if (display_manager_ || !trusted) {
     51     RemoteMethodError(message, EPERM);
     52     return nullptr;
     53   }
     54 
     55   display_manager_ =
     56       std::make_shared<DisplayManager>(this, message.GetChannelId());
     57   return display_manager_;
     58 }
     59 
     60 void DisplayManagerService::OnChannelClose(
     61     pdx::Message& /*message*/, const std::shared_ptr<pdx::Channel>& channel) {
     62   // Unregister the display manager when the channel closes.
     63   if (display_manager_ == channel)
     64     display_manager_ = nullptr;
     65 }
     66 
     67 pdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) {
     68   auto channel = std::static_pointer_cast<DisplayManager>(message.GetChannel());
     69 
     70   switch (message.GetOp()) {
     71     case DisplayManagerProtocol::GetSurfaceState::Opcode:
     72       DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceState>(
     73           *this, &DisplayManagerService::OnGetSurfaceState, message);
     74       return {};
     75 
     76     case DisplayManagerProtocol::GetSurfaceQueue::Opcode:
     77       DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
     78           *this, &DisplayManagerService::OnGetSurfaceQueue, message);
     79       return {};
     80 
     81     case DisplayManagerProtocol::SetupNamedBuffer::Opcode:
     82       DispatchRemoteMethod<DisplayManagerProtocol::SetupNamedBuffer>(
     83           *this, &DisplayManagerService::OnSetupNamedBuffer, message);
     84       return {};
     85 
     86     default:
     87       return Service::DefaultHandleMessage(message);
     88   }
     89 }
     90 
     91 pdx::Status<std::vector<display::SurfaceState>>
     92 DisplayManagerService::OnGetSurfaceState(pdx::Message& /*message*/) {
     93   std::vector<display::SurfaceState> items;
     94 
     95   display_service_->ForEachDisplaySurface(
     96       SurfaceType::Application,
     97       [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
     98         items.push_back({surface->surface_id(), surface->process_id(),
     99                          surface->user_id(), surface->attributes(),
    100                          surface->update_flags(), surface->GetQueueIds()});
    101         surface->ClearUpdate();
    102       });
    103 
    104   // The fact that we're in the message handler implies that display_manager_ is
    105   // not nullptr. No check required, unless this service becomes multi-threaded.
    106   display_manager_->SetNotificationsPending(false);
    107   return items;
    108 }
    109 
    110 pdx::Status<pdx::LocalChannelHandle> DisplayManagerService::OnGetSurfaceQueue(
    111     pdx::Message& /*message*/, int surface_id, int queue_id) {
    112   auto surface = display_service_->GetDisplaySurface(surface_id);
    113   if (!surface || surface->surface_type() != SurfaceType::Application)
    114     return ErrorStatus(EINVAL);
    115 
    116   auto queue =
    117       std::static_pointer_cast<ApplicationDisplaySurface>(surface)->GetQueue(
    118           queue_id);
    119   if (!queue)
    120     return ErrorStatus(EINVAL);
    121 
    122   auto status = queue->CreateConsumerQueueHandle();
    123   ALOGE_IF(
    124       !status,
    125       "DisplayManagerService::OnGetSurfaceQueue: Failed to create consumer "
    126       "queue for queue_id=%d: %s",
    127       queue->id(), status.GetErrorMessage().c_str());
    128 
    129   return status;
    130 }
    131 
    132 pdx::Status<BorrowedNativeBufferHandle>
    133 DisplayManagerService::OnSetupNamedBuffer(pdx::Message& message,
    134                                           const std::string& name, size_t size,
    135                                           uint64_t usage) {
    136   const int user_id = message.GetEffectiveUserId();
    137   const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
    138 
    139   if (!trusted) {
    140     ALOGE(
    141         "DisplayService::SetupNamedBuffer: Named buffers may only be created "
    142         "by trusted UIDs: user_id=%d",
    143         user_id);
    144     return ErrorStatus(EPERM);
    145   }
    146   return display_service_->SetupNamedBuffer(name, size, usage);
    147 }
    148 
    149 void DisplayManagerService::OnDisplaySurfaceChange() {
    150   if (display_manager_)
    151     display_manager_->SetNotificationsPending(true);
    152 }
    153 
    154 }  // namespace dvr
    155 }  // namespace android
    156