display_manager_service.cpp revision f0a7bd033941e26e380232a0515e903cf8e678e5
1#include "display_manager_service.h" 2 3#include <pdx/channel_handle.h> 4#include <pdx/default_transport/service_endpoint.h> 5#include <private/dvr/display_rpc.h> 6#include <sys/poll.h> 7 8#include <array> 9 10using android::pdx::Channel; 11using android::pdx::LocalChannelHandle; 12using android::pdx::Message; 13using android::pdx::default_transport::Endpoint; 14using android::pdx::rpc::DispatchRemoteMethod; 15using android::pdx::rpc::IfAnyOf; 16 17namespace { 18 19// As a first line of defense, the display manager endpoint is only accessible 20// to the user and group. 21 22// TODO(dnicoara): Remove read/write permission for others. This is in here just 23// to allow us to experiment with cast functionality from a plain old app. 24constexpr mode_t kDisplayManagerEndpointFileMode = 25 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 26 27constexpr size_t kMaxSurfacesPerRequest = 32; 28 29} // anonymous namespace 30 31namespace android { 32namespace dvr { 33 34void DisplayManager::SetNotificationsPending(bool pending) { 35 auto status = service_->ModifyChannelEvents(channel_id_, pending ? 0 : POLLIN, 36 pending ? POLLIN : 0); 37 ALOGE_IF(!status, 38 "DisplayManager::SetNotificationPending: Failed to modify channel " 39 "events: %s", 40 status.GetErrorMessage().c_str()); 41} 42 43DisplayManagerService::DisplayManagerService( 44 const std::shared_ptr<DisplayService>& display_service) 45 : BASE("DisplayManagerService", 46 Endpoint::Create(DisplayManagerRPC::kClientPath, 47 kDisplayManagerEndpointFileMode)), 48 display_service_(display_service) { 49 display_service_->SetDisplayConfigurationUpdateNotifier( 50 std::bind(&DisplayManagerService::OnDisplaySurfaceChange, this)); 51} 52 53std::shared_ptr<pdx::Channel> DisplayManagerService::OnChannelOpen( 54 pdx::Message& message) { 55 // Prevent more than one display manager from registering at a time. 56 if (display_manager_) 57 REPLY_ERROR_RETURN(message, EPERM, nullptr); 58 59 display_manager_ = 60 std::make_shared<DisplayManager>(this, message.GetChannelId()); 61 return display_manager_; 62} 63 64void DisplayManagerService::OnChannelClose( 65 pdx::Message& /*message*/, const std::shared_ptr<pdx::Channel>& channel) { 66 // Unregister the display manager when the channel closes. 67 if (display_manager_ == channel) 68 display_manager_ = nullptr; 69} 70 71pdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) { 72 auto channel = std::static_pointer_cast<DisplayManager>(message.GetChannel()); 73 74 switch (message.GetOp()) { 75 case DisplayManagerRPC::GetSurfaceList::Opcode: 76 DispatchRemoteMethod<DisplayManagerRPC::GetSurfaceList>( 77 *this, &DisplayManagerService::OnGetSurfaceList, message); 78 return {}; 79 80 case DisplayManagerRPC::UpdateSurfaces::Opcode: 81 DispatchRemoteMethod<DisplayManagerRPC::UpdateSurfaces>( 82 *this, &DisplayManagerService::OnUpdateSurfaces, message); 83 return {}; 84 85 case DisplayManagerRPC::SetupPoseBuffer::Opcode: 86 DispatchRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>( 87 *this, &DisplayManagerService::OnSetupPoseBuffer, message); 88 return {}; 89 90 default: 91 return Service::DefaultHandleMessage(message); 92 } 93} 94 95std::vector<DisplaySurfaceInfo> DisplayManagerService::OnGetSurfaceList( 96 pdx::Message& /*message*/) { 97 std::vector<DisplaySurfaceInfo> items; 98 99 display_service_->ForEachDisplaySurface( 100 [&items](const std::shared_ptr<DisplaySurface>& surface) mutable { 101 DisplaySurfaceInfo item; 102 103 item.surface_id = surface->surface_id(); 104 item.process_id = surface->process_id(); 105 item.type = surface->type(); 106 item.flags = 0; // TODO(eieio) 107 item.client_attributes = DisplaySurfaceAttributes{ 108 {DisplaySurfaceAttributeEnum::Visible, 109 DisplaySurfaceAttributeValue{surface->client_visible()}}, 110 {DisplaySurfaceAttributeEnum::ZOrder, 111 DisplaySurfaceAttributeValue{surface->client_z_order()}}, 112 {DisplaySurfaceAttributeEnum::Blur, 113 DisplaySurfaceAttributeValue{0.f}}}; 114 item.manager_attributes = DisplaySurfaceAttributes{ 115 {DisplaySurfaceAttributeEnum::Visible, 116 DisplaySurfaceAttributeValue{surface->manager_visible()}}, 117 {DisplaySurfaceAttributeEnum::ZOrder, 118 DisplaySurfaceAttributeValue{surface->manager_z_order()}}, 119 {DisplaySurfaceAttributeEnum::Blur, 120 DisplaySurfaceAttributeValue{surface->manager_blur()}}}; 121 122 items.push_back(item); 123 }); 124 125 // The fact that we're in the message handler implies that display_manager_ is 126 // not nullptr. No check required, unless this service becomes multi-threaded. 127 display_manager_->SetNotificationsPending(false); 128 129 return items; 130} 131 132int DisplayManagerService::OnUpdateSurfaces( 133 pdx::Message& /*message*/, 134 const std::map<int, DisplaySurfaceAttributes>& updates) { 135 for (const auto& surface_update : updates) { 136 const int surface_id = surface_update.first; 137 const DisplaySurfaceAttributes& attributes = surface_update.second; 138 139 std::shared_ptr<DisplaySurface> surface = 140 display_service_->GetDisplaySurface(surface_id); 141 142 if (!surface) 143 return -ENOENT; 144 145 for (const auto& attribute : attributes) { 146 const auto& key = attribute.first; 147 const auto* variant = &attribute.second; 148 bool invalid_value = false; 149 switch (key) { 150 case DisplaySurfaceAttributeEnum::ZOrder: 151 invalid_value = 152 !IfAnyOf<int32_t>::Call(variant, [&surface](const auto& value) { 153 surface->ManagerSetZOrder(value); 154 }); 155 break; 156 case DisplaySurfaceAttributeEnum::Visible: 157 invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call( 158 variant, [&surface](const auto& value) { 159 surface->ManagerSetVisible(value); 160 }); 161 break; 162 case DisplaySurfaceAttributeEnum::Blur: 163 invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call( 164 variant, [&surface](const auto& value) { 165 surface->ManagerSetBlur(value); 166 }); 167 break; 168 default: 169 ALOGW( 170 "DisplayManagerService::OnUpdateSurfaces: Attempt to set invalid " 171 "attribute %u on surface %d", 172 key, surface_id); 173 break; 174 } 175 176 if (invalid_value) { 177 ALOGW( 178 "DisplayManagerService::OnUpdateSurfaces: Failed to set display " 179 "surface attribute '%s' because of incompatible type: %d", 180 DisplaySurfaceAttributeEnum::ToString(key).c_str(), 181 variant->index()); 182 } 183 } 184 } 185 186 // Reconfigure the display layers for any active surface changes. 187 display_service_->UpdateActiveDisplaySurfaces(); 188 return 0; 189} 190 191pdx::BorrowedChannelHandle DisplayManagerService::OnSetupPoseBuffer( 192 pdx::Message& /*message*/, size_t extended_region_size, int usage) { 193 return display_service_->SetupPoseBuffer(extended_region_size, usage); 194} 195 196void DisplayManagerService::OnDisplaySurfaceChange() { 197 if (display_manager_) { 198 display_manager_->SetNotificationsPending(true); 199 } else { 200 // If there isn't a display manager registered, default all display surfaces 201 // to visible. 202 display_service_->ForEachDisplaySurface( 203 [](const std::shared_ptr<DisplaySurface>& surface) { 204 surface->ManagerSetVisible(true); 205 }); 206 display_service_->UpdateActiveDisplaySurfaces(); 207 } 208} 209 210} // namespace dvr 211} // namespace android 212