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