1 #include "display_service.h"
2 
3 #include <unistd.h>
4 #include <vector>
5 
6 #include <dvr/dvr_display_types.h>
7 #include <pdx/default_transport/service_endpoint.h>
8 #include <pdx/rpc/remote_method.h>
9 #include <private/dvr/display_protocol.h>
10 #include <private/dvr/numeric.h>
11 #include <private/dvr/types.h>
12 
13 using android::dvr::display::DisplayProtocol;
14 using android::pdx::Channel;
15 using android::pdx::ErrorStatus;
16 using android::pdx::Message;
17 using android::pdx::Status;
18 using android::pdx::default_transport::Endpoint;
19 using android::pdx::rpc::DispatchRemoteMethod;
20 
21 namespace android {
22 namespace dvr {
23 
DisplayService(Hwc2::Composer * hidl,RequestDisplayCallback request_display_callback)24 DisplayService::DisplayService(Hwc2::Composer* hidl,
25                                RequestDisplayCallback request_display_callback)
26     : BASE("DisplayService",
27            Endpoint::Create(display::DisplayProtocol::kClientPath)),
28       hardware_composer_(hidl, request_display_callback),
29       request_display_callback_(request_display_callback) {
30   hardware_composer_.Initialize();
31 }
32 
IsInitialized() const33 bool DisplayService::IsInitialized() const {
34   return BASE::IsInitialized() && hardware_composer_.IsInitialized();
35 }
36 
DumpState(size_t)37 std::string DisplayService::DumpState(size_t /*max_length*/) {
38   return hardware_composer_.Dump();
39 }
40 
OnChannelClose(pdx::Message & message,const std::shared_ptr<Channel> & channel)41 void DisplayService::OnChannelClose(pdx::Message& message,
42                                     const std::shared_ptr<Channel>& channel) {
43   if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
44     surface->OnSetAttributes(message,
45                              {{display::SurfaceAttribute::Visible,
46                                display::SurfaceAttributeValue{false}}});
47     SurfaceUpdated(surface->surface_type(),
48                    display::SurfaceUpdateFlags::VisibilityChanged);
49   }
50 }
51 
52 // First-level dispatch for display service messages. Directly handles messages
53 // that are independent of the display surface (metrics, creation) and routes
54 // surface-specific messages to the per-instance handlers.
HandleMessage(pdx::Message & message)55 Status<void> DisplayService::HandleMessage(pdx::Message& message) {
56   ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
57   switch (message.GetOp()) {
58     case DisplayProtocol::GetMetrics::Opcode:
59       DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
60           *this, &DisplayService::OnGetMetrics, message);
61       return {};
62 
63     case DisplayProtocol::CreateSurface::Opcode:
64       DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
65           *this, &DisplayService::OnCreateSurface, message);
66       return {};
67 
68     case DisplayProtocol::GetNamedBuffer::Opcode:
69       DispatchRemoteMethod<DisplayProtocol::GetNamedBuffer>(
70           *this, &DisplayService::OnGetNamedBuffer, message);
71       return {};
72 
73     case DisplayProtocol::IsVrAppRunning::Opcode:
74       DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
75           *this, &DisplayService::IsVrAppRunning, message);
76       return {};
77 
78     // Direct the surface specific messages to the surface instance.
79     case DisplayProtocol::SetAttributes::Opcode:
80     case DisplayProtocol::CreateQueue::Opcode:
81     case DisplayProtocol::GetSurfaceInfo::Opcode:
82       return HandleSurfaceMessage(message);
83 
84     default:
85       return Service::HandleMessage(message);
86   }
87 }
88 
OnGetMetrics(pdx::Message &)89 Status<display::Metrics> DisplayService::OnGetMetrics(
90     pdx::Message& /*message*/) {
91   return {{static_cast<uint32_t>(GetDisplayMetrics().width),
92            static_cast<uint32_t>(GetDisplayMetrics().height),
93            static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
94            static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
95            static_cast<uint32_t>(
96                hardware_composer_.native_display_metrics().vsync_period_ns),
97            0,
98            0,
99            0,
100            0.0,
101            {},
102            {}}};
103 }
104 
105 // Creates a new DisplaySurface and associates it with this channel. This may
106 // only be done once per channel.
OnCreateSurface(pdx::Message & message,const display::SurfaceAttributes & attributes)107 Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
108     pdx::Message& message, const display::SurfaceAttributes& attributes) {
109   // A surface may only be created once per channel.
110   if (message.GetChannel())
111     return ErrorStatus(EINVAL);
112 
113   ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
114            message.GetChannelId());
115 
116   // Use the channel id as the unique surface id.
117   const int surface_id = message.GetChannelId();
118   const int process_id = message.GetProcessId();
119   const int user_id = message.GetEffectiveUserId();
120 
121   ALOGI_IF(TRACE,
122            "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
123            surface_id, process_id);
124 
125   auto surface_status =
126       DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
127   if (!surface_status) {
128     ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
129           surface_status.GetErrorMessage().c_str());
130     return ErrorStatus(surface_status.error());
131   }
132 
133   SurfaceType surface_type = surface_status.get()->surface_type();
134   display::SurfaceUpdateFlags update_flags =
135       surface_status.get()->update_flags();
136   display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
137                                     surface_status.get()->visible(),
138                                     surface_status.get()->z_order()};
139 
140   message.SetChannel(surface_status.take());
141 
142   SurfaceUpdated(surface_type, update_flags);
143   return {surface_info};
144 }
145 
SurfaceUpdated(SurfaceType surface_type,display::SurfaceUpdateFlags update_flags)146 void DisplayService::SurfaceUpdated(SurfaceType surface_type,
147                                     display::SurfaceUpdateFlags update_flags) {
148   ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
149            update_flags.value());
150   if (update_flags.value() != 0) {
151     if (surface_type == SurfaceType::Application)
152       NotifyDisplayConfigurationUpdate();
153     else
154       UpdateActiveDisplaySurfaces();
155   }
156 }
157 
OnGetNamedBuffer(pdx::Message &,const std::string & name)158 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
159     pdx::Message& /* message */, const std::string& name) {
160   ALOGD_IF(TRACE, "displayService::OnGetNamedBuffer: name=%s", name.c_str());
161   auto named_buffer = named_buffers_.find(name);
162   if (named_buffer != named_buffers_.end())
163     return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
164   else
165     return pdx::ErrorStatus(EINVAL);
166 }
167 
168 // Calls the message handler for the DisplaySurface associated with this
169 // channel.
HandleSurfaceMessage(pdx::Message & message)170 Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
171   auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
172   ALOGW_IF(!surface,
173            "DisplayService::HandleSurfaceMessage: surface is nullptr!");
174 
175   if (surface)
176     return surface->HandleMessage(message);
177   else
178     return ErrorStatus(EINVAL);
179 }
180 
GetDisplaySurface(int surface_id) const181 std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
182     int surface_id) const {
183   return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
184 }
185 
186 std::vector<std::shared_ptr<DisplaySurface>>
GetDisplaySurfaces() const187 DisplayService::GetDisplaySurfaces() const {
188   return GetChannels<DisplaySurface>();
189 }
190 
191 std::vector<std::shared_ptr<DirectDisplaySurface>>
GetVisibleDisplaySurfaces() const192 DisplayService::GetVisibleDisplaySurfaces() const {
193   std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
194 
195   ForEachDisplaySurface(
196       SurfaceType::Direct,
197       [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
198         if (surface->visible()) {
199           visible_surfaces.push_back(
200               std::static_pointer_cast<DirectDisplaySurface>(surface));
201           surface->ClearUpdate();
202         }
203       });
204 
205   return visible_surfaces;
206 }
207 
UpdateActiveDisplaySurfaces()208 void DisplayService::UpdateActiveDisplaySurfaces() {
209   auto visible_surfaces = GetVisibleDisplaySurfaces();
210 
211   std::sort(visible_surfaces.begin(), visible_surfaces.end(),
212             [](const std::shared_ptr<DisplaySurface>& a,
213                const std::shared_ptr<DisplaySurface>& b) {
214               return a->z_order() < b->z_order();
215             });
216 
217   ALOGD_IF(TRACE,
218            "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
219            visible_surfaces.size());
220 
221   hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
222 }
223 
SetupNamedBuffer(const std::string & name,size_t size,uint64_t usage)224 pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
225     const std::string& name, size_t size, uint64_t usage) {
226   auto named_buffer = named_buffers_.find(name);
227   if (named_buffer == named_buffers_.end()) {
228     auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
229                                                   HAL_PIXEL_FORMAT_BLOB, usage);
230     named_buffer =
231         named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
232             .first;
233   }
234 
235   return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
236 }
237 
OnHardwareComposerRefresh()238 void DisplayService::OnHardwareComposerRefresh() {
239   hardware_composer_.OnHardwareComposerRefresh();
240 }
241 
SetDisplayConfigurationUpdateNotifier(DisplayConfigurationUpdateNotifier update_notifier)242 void DisplayService::SetDisplayConfigurationUpdateNotifier(
243     DisplayConfigurationUpdateNotifier update_notifier) {
244   update_notifier_ = update_notifier;
245 }
246 
NotifyDisplayConfigurationUpdate()247 void DisplayService::NotifyDisplayConfigurationUpdate() {
248   if (update_notifier_)
249     update_notifier_();
250 }
251 
IsVrAppRunning(pdx::Message &)252 Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
253   bool visible = false;
254   ForEachDisplaySurface(
255       SurfaceType::Application,
256       [&visible](const std::shared_ptr<DisplaySurface>& surface) {
257         if (surface->visible())
258           visible = true;
259       });
260 
261   return {visible};
262 }
263 
264 }  // namespace dvr
265 }  // namespace android
266