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