• 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   // 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 
OnChannelClose(pdx::Message &,const std::shared_ptr<pdx::Channel> & channel)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 
HandleMessage(pdx::Message & message)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>>
OnGetSurfaceState(pdx::Message &)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 
OnGetSurfaceQueue(pdx::Message &,int surface_id,int queue_id)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>
OnSetupNamedBuffer(pdx::Message & message,const std::string & name,size_t size,uint64_t usage)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 
OnDisplaySurfaceChange()149 void DisplayManagerService::OnDisplaySurfaceChange() {
150   if (display_manager_)
151     display_manager_->SetNotificationsPending(true);
152 }
153 
154 }  // namespace dvr
155 }  // namespace android
156