display_manager_service.cpp revision 2251d822dac2a96aad4184a6fdc2690f0a58af7c
1a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "display_manager_service.h"
2a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
3a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <pdx/channel_handle.h>
4a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <pdx/default_transport/service_endpoint.h>
5eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar#include <private/android_filesystem_config.h>
63f82d31341f66d0c58e1ec3360ea5f528ffe0ea4Corey Tabaka#include <private/dvr/display_protocol.h>
7eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar#include <private/dvr/trusted_uids.h>
8a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/poll.h>
9a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
10a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <array>
11a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::DisplayManagerProtocol;
13a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::Channel;
14a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::LocalChannelHandle;
15a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::Message;
16a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::default_transport::Endpoint;
172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::ErrorStatus;
18a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::rpc::DispatchRemoteMethod;
19a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::rpc::IfAnyOf;
202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::rpc::RemoteMethodError;
21a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
22a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace android {
23a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace dvr {
24a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
25a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid DisplayManager::SetNotificationsPending(bool pending) {
26f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  auto status = service_->ModifyChannelEvents(channel_id_, pending ? 0 : POLLIN,
27f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                              pending ? POLLIN : 0);
28f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  ALOGE_IF(!status,
29a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           "DisplayManager::SetNotificationPending: Failed to modify channel "
30a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           "events: %s",
31f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko           status.GetErrorMessage().c_str());
32a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
33a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
34a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoDisplayManagerService::DisplayManagerService(
35a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const std::shared_ptr<DisplayService>& display_service)
36a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    : BASE("DisplayManagerService",
372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka           Endpoint::Create(DisplayManagerProtocol::kClientPath)),
38a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display_service_(display_service) {
39a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_service_->SetDisplayConfigurationUpdateNotifier(
40a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      std::bind(&DisplayManagerService::OnDisplaySurfaceChange, this));
41a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
42a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
43a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkostd::shared_ptr<pdx::Channel> DisplayManagerService::OnChannelOpen(
44a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    pdx::Message& message) {
452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  const int user_id = message.GetEffectiveUserId();
462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  // Prevent more than one display manager from registering at a time or
492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  // untrusted UIDs from connecting.
502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (display_manager_ || !trusted) {
512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    RemoteMethodError(message, EPERM);
522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return nullptr;
532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
54a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
55a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_manager_ =
56a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      std::make_shared<DisplayManager>(this, message.GetChannelId());
57a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return display_manager_;
58a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
59a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
60a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid DisplayManagerService::OnChannelClose(
61a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    pdx::Message& /*message*/, const std::shared_ptr<pdx::Channel>& channel) {
62a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Unregister the display manager when the channel closes.
63a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (display_manager_ == channel)
64a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    display_manager_ = nullptr;
65a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
66a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
67f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkopdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) {
68a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  auto channel = std::static_pointer_cast<DisplayManager>(message.GetChannel());
69a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
70a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  switch (message.GetOp()) {
712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    case DisplayManagerProtocol::GetSurfaceState::Opcode:
722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceState>(
732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          *this, &DisplayManagerService::OnGetSurfaceState, message);
74f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return {};
75a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    case DisplayManagerProtocol::GetSurfaceQueue::Opcode:
772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          *this, &DisplayManagerService::OnGetSurfaceQueue, message);
79f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return {};
80a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    case DisplayManagerProtocol::SetupNamedBuffer::Opcode:
822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      DispatchRemoteMethod<DisplayManagerProtocol::SetupNamedBuffer>(
83eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar          *this, &DisplayManagerService::OnSetupNamedBuffer, message);
84f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return {};
8510e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar
86a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    default:
87a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return Service::DefaultHandleMessage(message);
88a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
89a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
90a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakapdx::Status<std::vector<display::SurfaceState>>
922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaDisplayManagerService::OnGetSurfaceState(pdx::Message& /*message*/) {
932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  std::vector<display::SurfaceState> items;
94a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
9510e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar  display_service_->ForEachDisplaySurface(
962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      SurfaceType::Application,
9710e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar      [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        items.push_back({surface->surface_id(), surface->process_id(),
992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                         surface->user_id(), surface->attributes(),
1002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                         surface->update_flags(), surface->GetQueueIds()});
1012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        surface->ClearUpdate();
10210e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar      });
103a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
104a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // The fact that we're in the message handler implies that display_manager_ is
105a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // not nullptr. No check required, unless this service becomes multi-threaded.
106a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_manager_->SetNotificationsPending(false);
107a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return items;
108a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
109a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakapdx::Status<pdx::LocalChannelHandle> DisplayManagerService::OnGetSurfaceQueue(
1112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    pdx::Message& /*message*/, int surface_id, int queue_id) {
1122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto surface = display_service_->GetDisplaySurface(surface_id);
1132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!surface || surface->surface_type() != SurfaceType::Application)
1142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(EINVAL);
1152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto queue =
1172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      std::static_pointer_cast<ApplicationDisplaySurface>(surface)->GetQueue(
1182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          queue_id);
1192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!queue)
1202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(EINVAL);
1212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = queue->CreateConsumerQueueHandle();
1232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  ALOGE_IF(
1242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      !status,
1252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      "DisplayManagerService::OnGetSurfaceQueue: Failed to create consumer "
1262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      "queue for queue_id=%d: %s",
1272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      queue->id(), status.GetErrorMessage().c_str());
1282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return status;
130a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
131a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
132eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaarpdx::Status<BorrowedNativeBufferHandle>
133eaa5522feac452703a0836310047d4b15702487dHendrik WagenaarDisplayManagerService::OnSetupNamedBuffer(pdx::Message& message,
134eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar                                          const std::string& name, size_t size,
1350057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai                                          uint64_t usage) {
1362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  const int user_id = message.GetEffectiveUserId();
1372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
1382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!trusted) {
1402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE(
1412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "DisplayService::SetupNamedBuffer: Named buffers may only be created "
1422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "by trusted UIDs: user_id=%d",
1432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        user_id);
1442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(EPERM);
145eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar  }
1460057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai  return display_service_->SetupNamedBuffer(name, size, usage);
14710e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar}
14810e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar
149a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid DisplayManagerService::OnDisplaySurfaceChange() {
1502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (display_manager_)
151a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    display_manager_->SetNotificationsPending(true);
152a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
153a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
154a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}  // namespace dvr
155a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}  // namespace android
156