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