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
13using android::dvr::display::DisplayProtocol;
14using android::pdx::Channel;
15using android::pdx::ErrorStatus;
16using android::pdx::Message;
17using android::pdx::Status;
18using android::pdx::default_transport::Endpoint;
19using android::pdx::rpc::DispatchRemoteMethod;
20
21namespace android {
22namespace dvr {
23
24DisplayService::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
33bool DisplayService::IsInitialized() const {
34  return BASE::IsInitialized() && hardware_composer_.IsInitialized();
35}
36
37std::string DisplayService::DumpState(size_t /*max_length*/) {
38  return hardware_composer_.Dump();
39}
40
41void 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.
55Status<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
89Status<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.
107Status<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
146void 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
158pdx::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.
170Status<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
181std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
182    int surface_id) const {
183  return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
184}
185
186std::vector<std::shared_ptr<DisplaySurface>>
187DisplayService::GetDisplaySurfaces() const {
188  return GetChannels<DisplaySurface>();
189}
190
191std::vector<std::shared_ptr<DirectDisplaySurface>>
192DisplayService::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
208void 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
224pdx::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
238void DisplayService::OnHardwareComposerRefresh() {
239  hardware_composer_.OnHardwareComposerRefresh();
240}
241
242void DisplayService::SetDisplayConfigurationUpdateNotifier(
243    DisplayConfigurationUpdateNotifier update_notifier) {
244  update_notifier_ = update_notifier;
245}
246
247void DisplayService::NotifyDisplayConfigurationUpdate() {
248  if (update_notifier_)
249    update_notifier_();
250}
251
252Status<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