display_manager_service.cpp revision a8a92784bc5f6a50ce00311c6161fbcfc0898c5a
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 int ret = service_->ModifyChannelEvents(channel_id_, pending ? 0 : POLLIN, 36 pending ? POLLIN : 0); 37 ALOGE_IF(ret < 0, 38 "DisplayManager::SetNotificationPending: Failed to modify channel " 39 "events: %s", 40 strerror(-ret)); 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 71int 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 0; 79 80 case DisplayManagerRPC::GetSurfaceBuffers::Opcode: 81 DispatchRemoteMethod<DisplayManagerRPC::GetSurfaceBuffers>( 82 *this, &DisplayManagerService::OnGetSurfaceBuffers, message); 83 return 0; 84 85 case DisplayManagerRPC::UpdateSurfaces::Opcode: 86 DispatchRemoteMethod<DisplayManagerRPC::UpdateSurfaces>( 87 *this, &DisplayManagerService::OnUpdateSurfaces, message); 88 return 0; 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([&items]( 100 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, DisplaySurfaceAttributeValue{0.f}}}; 113 item.manager_attributes = DisplaySurfaceAttributes{ 114 {DisplaySurfaceAttributeEnum::Visible, 115 DisplaySurfaceAttributeValue{surface->manager_visible()}}, 116 {DisplaySurfaceAttributeEnum::ZOrder, 117 DisplaySurfaceAttributeValue{surface->manager_z_order()}}, 118 {DisplaySurfaceAttributeEnum::Blur, 119 DisplaySurfaceAttributeValue{surface->manager_blur()}}}; 120 121 items.push_back(item); 122 }); 123 124 // The fact that we're in the message handler implies that display_manager_ is 125 // not nullptr. No check required, unless this service becomes multi-threaded. 126 display_manager_->SetNotificationsPending(false); 127 128 return items; 129} 130 131std::vector<LocalChannelHandle> DisplayManagerService::OnGetSurfaceBuffers( 132 pdx::Message& message, int surface_id) { 133 std::shared_ptr<DisplaySurface> surface = 134 display_service_->GetDisplaySurface(surface_id); 135 if (!surface) 136 REPLY_ERROR_RETURN(message, ENOENT, {}); 137 138 std::vector<LocalChannelHandle> consumers; 139 int ret = surface->GetConsumers(&consumers); 140 if (ret < 0) { 141 ALOGE( 142 "DisplayManagerService::OnGetDisplaySurfaceBuffers: Failed to get " 143 "consumers for surface %d: %s", 144 surface_id, strerror(-ret)); 145 REPLY_ERROR_RETURN(message, -ret, {}); 146 } 147 148 return consumers; 149} 150 151int DisplayManagerService::OnUpdateSurfaces( 152 pdx::Message& /*message*/, 153 const std::map<int, DisplaySurfaceAttributes>& updates) { 154 for (const auto& surface_update : updates) { 155 const int surface_id = surface_update.first; 156 const DisplaySurfaceAttributes& attributes = surface_update.second; 157 158 std::shared_ptr<DisplaySurface> surface = 159 display_service_->GetDisplaySurface(surface_id); 160 161 if (!surface) 162 return -ENOENT; 163 164 for (const auto& attribute : attributes) { 165 const auto& key = attribute.first; 166 const auto* variant = &attribute.second; 167 bool invalid_value = false; 168 switch (key) { 169 case DisplaySurfaceAttributeEnum::ZOrder: 170 invalid_value = 171 !IfAnyOf<int32_t>::Call(variant, [&surface](const auto& value) { 172 surface->ManagerSetZOrder(value); 173 }); 174 break; 175 case DisplaySurfaceAttributeEnum::Visible: 176 invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call( 177 variant, [&surface](const auto& value) { 178 surface->ManagerSetVisible(value); 179 }); 180 break; 181 case DisplaySurfaceAttributeEnum::Blur: 182 invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call( 183 variant, [&surface](const auto& value) { 184 surface->ManagerSetBlur(value); 185 }); 186 break; 187 default: 188 ALOGW( 189 "DisplayManagerService::OnUpdateSurfaces: Attempt to set invalid " 190 "attribute %u on surface %d", 191 key, surface_id); 192 break; 193 } 194 195 if (invalid_value) { 196 ALOGW( 197 "DisplayManagerService::OnUpdateSurfaces: Failed to set display " 198 "surface attribute '%s' because of incompatible type: %d", 199 DisplaySurfaceAttributeEnum::ToString(key).c_str(), 200 variant->index()); 201 } 202 } 203 } 204 205 // Reconfigure the display layers for any active surface changes. 206 display_service_->UpdateActiveDisplaySurfaces(); 207 return 0; 208} 209 210void DisplayManagerService::OnDisplaySurfaceChange() { 211 if (display_manager_) { 212 display_manager_->SetNotificationsPending(true); 213 } else { 214 // If there isn't a display manager registered, default all display surfaces 215 // to visible. 216 display_service_->ForEachDisplaySurface( 217 [](const std::shared_ptr<DisplaySurface>& surface) { 218 surface->ManagerSetVisible(true); 219 }); 220 display_service_->UpdateActiveDisplaySurfaces(); 221 } 222} 223 224} // namespace dvr 225} // namespace android 226