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   // Check if the display_manager_ has a defunct channel.
     49   if (display_manager_ && !HasChannelId(display_manager_->channel_id())) {
     50     ALOGE("DisplayManagerService::OnChannelOpen: Found defunct channel %d with "
     51           "no OnChannelClose, clearing prior display manager.",
     52           display_manager_->channel_id());
     53     display_manager_ = nullptr;
     54   }
     55 
     56   // Prevent more than one display manager from registering at a time or
     57   // untrusted UIDs from connecting.
     58   if (display_manager_ || !trusted) {
     59     RemoteMethodError(message, EPERM);
     60     return nullptr;
     61   }
     62 
     63   display_manager_ =
     64       std::make_shared<DisplayManager>(this, message.GetChannelId());
     65   return display_manager_;
     66 }
     67 
     68 void DisplayManagerService::OnChannelClose(
     69     pdx::Message& /*message*/, const std::shared_ptr<pdx::Channel>& channel) {
     70   // Unregister the display manager when the channel closes.
     71   if (display_manager_ == channel)
     72     display_manager_ = nullptr;
     73 }
     74 
     75 pdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) {
     76   ATRACE_NAME("DisplayManagerService::HandleMessage");
     77   auto channel = std::static_pointer_cast<DisplayManager>(message.GetChannel());
     78 
     79   switch (message.GetOp()) {
     80     case DisplayManagerProtocol::GetSurfaceState::Opcode:
     81       DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceState>(
     82           *this, &DisplayManagerService::OnGetSurfaceState, message);
     83       return {};
     84 
     85     case DisplayManagerProtocol::GetSurfaceQueue::Opcode:
     86       DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
     87           *this, &DisplayManagerService::OnGetSurfaceQueue, message);
     88       return {};
     89 
     90     default:
     91       return Service::DefaultHandleMessage(message);
     92   }
     93 }
     94 
     95 pdx::Status<std::vector<display::SurfaceState>>
     96 DisplayManagerService::OnGetSurfaceState(pdx::Message& /*message*/) {
     97   std::vector<display::SurfaceState> items;
     98 
     99   display_service_->ForEachDisplaySurface(
    100       SurfaceType::Application,
    101       [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
    102         items.push_back({surface->surface_id(), surface->process_id(),
    103                          surface->user_id(), surface->attributes(),
    104                          surface->update_flags(), surface->GetQueueIds()});
    105         surface->ClearUpdate();
    106       });
    107 
    108   // The fact that we're in the message handler implies that display_manager_ is
    109   // not nullptr. No check required, unless this service becomes multi-threaded.
    110   display_manager_->SetNotificationsPending(false);
    111   return items;
    112 }
    113 
    114 pdx::Status<pdx::LocalChannelHandle> DisplayManagerService::OnGetSurfaceQueue(
    115     pdx::Message& /*message*/, int surface_id, int queue_id) {
    116   auto surface = display_service_->GetDisplaySurface(surface_id);
    117   if (!surface || surface->surface_type() != SurfaceType::Application)
    118     return ErrorStatus(EINVAL);
    119 
    120   auto queue =
    121       std::static_pointer_cast<ApplicationDisplaySurface>(surface)->GetQueue(
    122           queue_id);
    123   if (!queue)
    124     return ErrorStatus(EINVAL);
    125 
    126   auto status = queue->CreateConsumerQueueHandle();
    127   ALOGE_IF(
    128       !status,
    129       "DisplayManagerService::OnGetSurfaceQueue: Failed to create consumer "
    130       "queue for queue_id=%d: %s",
    131       queue->id(), status.GetErrorMessage().c_str());
    132 
    133   return status;
    134 }
    135 
    136 void DisplayManagerService::OnDisplaySurfaceChange() {
    137   if (display_manager_)
    138     display_manager_->SetNotificationsPending(true);
    139 }
    140 
    141 }  // namespace dvr
    142 }  // namespace android
    143