display_manager_service.cpp revision 2251d822dac2a96aad4184a6fdc2690f0a58af7c
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
12using android::dvr::display::DisplayManagerProtocol;
13using android::pdx::Channel;
14using android::pdx::LocalChannelHandle;
15using android::pdx::Message;
16using android::pdx::default_transport::Endpoint;
17using android::pdx::ErrorStatus;
18using android::pdx::rpc::DispatchRemoteMethod;
19using android::pdx::rpc::IfAnyOf;
20using android::pdx::rpc::RemoteMethodError;
21
22namespace android {
23namespace dvr {
24
25void 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
34DisplayManagerService::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
43std::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
60void 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
67pdx::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
91pdx::Status<std::vector<display::SurfaceState>>
92DisplayManagerService::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
110pdx::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
132pdx::Status<BorrowedNativeBufferHandle>
133DisplayManagerService::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
149void DisplayManagerService::OnDisplaySurfaceChange() {
150  if (display_manager_)
151    display_manager_->SetNotificationsPending(true);
152}
153
154}  // namespace dvr
155}  // namespace android
156