• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SetNotificationsPending(bool pending)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 
DisplayManagerService(const std::shared_ptr<DisplayService> & display_service)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 
OnChannelOpen(pdx::Message & message)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 
OnChannelClose(pdx::Message &,const std::shared_ptr<pdx::Channel> & channel)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 
HandleMessage(pdx::Message & message)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>>
OnGetSurfaceState(pdx::Message &)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 
OnGetSurfaceQueue(pdx::Message &,int surface_id,int queue_id)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 
OnDisplaySurfaceChange()136 void DisplayManagerService::OnDisplaySurfaceChange() {
137   if (display_manager_)
138     display_manager_->SetNotificationsPending(true);
139 }
140 
141 }  // namespace dvr
142 }  // namespace android
143