1#include "display_service.h"
2
3#include <unistd.h>
4
5#include <algorithm>
6#include <sstream>
7#include <string>
8#include <vector>
9
10#include <android-base/file.h>
11#include <android-base/properties.h>
12#include <dvr/dvr_display_types.h>
13#include <pdx/default_transport/service_endpoint.h>
14#include <pdx/rpc/remote_method.h>
15#include <private/android_filesystem_config.h>
16#include <private/dvr/display_protocol.h>
17#include <private/dvr/numeric.h>
18#include <private/dvr/trusted_uids.h>
19#include <private/dvr/types.h>
20
21using android::dvr::display::DisplayProtocol;
22using android::pdx::Channel;
23using android::pdx::ErrorStatus;
24using android::pdx::Message;
25using android::pdx::Status;
26using android::pdx::default_transport::Endpoint;
27using android::pdx::rpc::DispatchRemoteMethod;
28
29namespace {
30
31const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
32const char kDvrDeviceMetricsProperty[] = "ro.dvr.device_metrics";
33const char kDvrDeviceConfigProperty[] = "ro.dvr.device_configuration";
34
35}  // namespace
36
37namespace android {
38namespace dvr {
39
40DisplayService::DisplayService(Hwc2::Composer* hidl,
41                               hwc2_display_t primary_display_id,
42                               RequestDisplayCallback request_display_callback)
43    : BASE("DisplayService",
44           Endpoint::Create(display::DisplayProtocol::kClientPath)) {
45    hardware_composer_.Initialize(
46        hidl, primary_display_id, request_display_callback);
47}
48
49bool DisplayService::IsInitialized() const {
50  return BASE::IsInitialized() && hardware_composer_.IsInitialized();
51}
52
53std::string DisplayService::DumpState(size_t /*max_length*/) {
54  std::ostringstream stream;
55
56  auto surfaces = GetDisplaySurfaces();
57  std::sort(surfaces.begin(), surfaces.end(), [](const auto& a, const auto& b) {
58    return a->surface_id() < b->surface_id();
59  });
60
61  stream << "Application Surfaces:" << std::endl;
62
63  size_t count = 0;
64  for (const auto& surface : surfaces) {
65    if (surface->surface_type() == SurfaceType::Application) {
66      stream << "Surface " << count++ << ":";
67      stream << " surface_id=" << surface->surface_id()
68             << " process_id=" << surface->process_id()
69             << " user_id=" << surface->user_id()
70             << " visible=" << surface->visible()
71             << " z_order=" << surface->z_order();
72
73      stream << " queue_ids=";
74      auto queue_ids = surface->GetQueueIds();
75      std::sort(queue_ids.begin(), queue_ids.end());
76      for (int32_t id : queue_ids) {
77        if (id != queue_ids[0])
78          stream << ",";
79        stream << id;
80      }
81      stream << std::endl;
82    }
83  }
84  stream << std::endl;
85
86  stream << "Direct Surfaces:" << std::endl;
87
88  count = 0;
89  for (const auto& surface : surfaces) {
90    if (surface->surface_type() == SurfaceType::Direct) {
91      stream << "Surface " << count++ << ":";
92      stream << " surface_id=" << surface->surface_id()
93             << " process_id=" << surface->process_id()
94             << " user_id=" << surface->user_id()
95             << " visible=" << surface->visible()
96             << " z_order=" << surface->z_order();
97
98      stream << " queue_ids=";
99      auto queue_ids = surface->GetQueueIds();
100      std::sort(queue_ids.begin(), queue_ids.end());
101      for (int32_t id : queue_ids) {
102        if (id != queue_ids[0])
103          stream << ",";
104        stream << id;
105      }
106      stream << std::endl;
107    }
108  }
109  stream << std::endl;
110
111  stream << hardware_composer_.Dump();
112  return stream.str();
113}
114
115void DisplayService::OnChannelClose(pdx::Message& message,
116                                    const std::shared_ptr<Channel>& channel) {
117  if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
118    surface->OnSetAttributes(message,
119                             {{display::SurfaceAttribute::Visible,
120                               display::SurfaceAttributeValue{false}}});
121  }
122}
123
124// First-level dispatch for display service messages. Directly handles messages
125// that are independent of the display surface (metrics, creation) and routes
126// surface-specific messages to the per-instance handlers.
127Status<void> DisplayService::HandleMessage(pdx::Message& message) {
128  ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
129  ATRACE_NAME("DisplayService::HandleMessage");
130
131  switch (message.GetOp()) {
132    case DisplayProtocol::GetMetrics::Opcode:
133      DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
134          *this, &DisplayService::OnGetMetrics, message);
135      return {};
136
137    case DisplayProtocol::GetConfigurationData::Opcode:
138      DispatchRemoteMethod<DisplayProtocol::GetConfigurationData>(
139          *this, &DisplayService::OnGetConfigurationData, message);
140      return {};
141
142    case DisplayProtocol::CreateSurface::Opcode:
143      DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
144          *this, &DisplayService::OnCreateSurface, message);
145      return {};
146
147    case DisplayProtocol::SetupGlobalBuffer::Opcode:
148      DispatchRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(
149          *this, &DisplayService::OnSetupGlobalBuffer, message);
150      return {};
151
152    case DisplayProtocol::DeleteGlobalBuffer::Opcode:
153      DispatchRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(
154          *this, &DisplayService::OnDeleteGlobalBuffer, message);
155      return {};
156
157    case DisplayProtocol::GetGlobalBuffer::Opcode:
158      DispatchRemoteMethod<DisplayProtocol::GetGlobalBuffer>(
159          *this, &DisplayService::OnGetGlobalBuffer, message);
160      return {};
161
162    case DisplayProtocol::IsVrAppRunning::Opcode:
163      DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
164          *this, &DisplayService::IsVrAppRunning, message);
165      return {};
166
167    // Direct the surface specific messages to the surface instance.
168    case DisplayProtocol::SetAttributes::Opcode:
169    case DisplayProtocol::CreateQueue::Opcode:
170    case DisplayProtocol::GetSurfaceInfo::Opcode:
171      return HandleSurfaceMessage(message);
172
173    default:
174      return Service::HandleMessage(message);
175  }
176}
177
178Status<display::Metrics> DisplayService::OnGetMetrics(
179    pdx::Message& /*message*/) {
180  const auto& params = hardware_composer_.GetPrimaryDisplayParams();
181  return {{static_cast<uint32_t>(params.width),
182           static_cast<uint32_t>(params.height),
183           static_cast<uint32_t>(params.dpi.x),
184           static_cast<uint32_t>(params.dpi.y),
185           static_cast<uint32_t>(params.vsync_period_ns),
186           0,
187           0,
188           0,
189           0.0,
190           {},
191           {}}};
192}
193
194pdx::Status<std::string> DisplayService::OnGetConfigurationData(
195    pdx::Message& /*message*/, display::ConfigFileType config_type) {
196  std::string property_name;
197  switch (config_type) {
198    case display::ConfigFileType::kLensMetrics:
199      property_name = kDvrLensMetricsProperty;
200      break;
201    case display::ConfigFileType::kDeviceMetrics:
202      property_name = kDvrDeviceMetricsProperty;
203      break;
204    case display::ConfigFileType::kDeviceConfiguration:
205      property_name = kDvrDeviceConfigProperty;
206      break;
207    default:
208      return ErrorStatus(EINVAL);
209  }
210  std::string file_path = base::GetProperty(property_name, "");
211  if (file_path.empty()) {
212    return ErrorStatus(ENOENT);
213  }
214
215  std::string data;
216  if (!base::ReadFileToString(file_path, &data)) {
217    return ErrorStatus(errno);
218  }
219
220  return std::move(data);
221}
222
223// Creates a new DisplaySurface and associates it with this channel. This may
224// only be done once per channel.
225Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
226    pdx::Message& message, const display::SurfaceAttributes& attributes) {
227  // A surface may only be created once per channel.
228  if (message.GetChannel())
229    return ErrorStatus(EINVAL);
230
231  ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
232           message.GetChannelId());
233
234  // Use the channel id as the unique surface id.
235  const int surface_id = message.GetChannelId();
236  const int process_id = message.GetProcessId();
237  const int user_id = message.GetEffectiveUserId();
238
239  ALOGI_IF(TRACE,
240           "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
241           surface_id, process_id);
242
243  auto surface_status =
244      DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
245  if (!surface_status) {
246    ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
247          surface_status.GetErrorMessage().c_str());
248    return ErrorStatus(surface_status.error());
249  }
250  auto surface = surface_status.take();
251  message.SetChannel(surface);
252
253  // Update the surface with the attributes supplied with the create call. For
254  // application surfaces this has the side effect of notifying the display
255  // manager of the new surface. For direct surfaces, this may trigger a mode
256  // change, depending on the value of the visible attribute.
257  surface->OnSetAttributes(message, attributes);
258
259  return {{surface->surface_id(), surface->visible(), surface->z_order()}};
260}
261
262void DisplayService::SurfaceUpdated(SurfaceType surface_type,
263                                    display::SurfaceUpdateFlags update_flags) {
264  ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
265           update_flags.value());
266  if (update_flags.value() != 0) {
267    if (surface_type == SurfaceType::Application)
268      NotifyDisplayConfigurationUpdate();
269    else
270      UpdateActiveDisplaySurfaces();
271  }
272}
273
274pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnSetupGlobalBuffer(
275    pdx::Message& message, DvrGlobalBufferKey key, size_t size,
276    uint64_t usage) {
277  const int user_id = message.GetEffectiveUserId();
278  const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
279
280  if (!trusted) {
281    ALOGE(
282        "DisplayService::OnSetupGlobalBuffer: Permission denied for user_id=%d",
283        user_id);
284    return ErrorStatus(EPERM);
285  }
286  return SetupGlobalBuffer(key, size, usage);
287}
288
289pdx::Status<void> DisplayService::OnDeleteGlobalBuffer(pdx::Message& message,
290                                                       DvrGlobalBufferKey key) {
291  const int user_id = message.GetEffectiveUserId();
292  const bool trusted = (user_id == AID_ROOT) || IsTrustedUid(user_id);
293
294  if (!trusted) {
295    ALOGE(
296        "DisplayService::OnDeleteGlobalBuffer: Permission denied for "
297        "user_id=%d",
298        user_id);
299    return ErrorStatus(EPERM);
300  }
301  return DeleteGlobalBuffer(key);
302}
303
304pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetGlobalBuffer(
305    pdx::Message& /* message */, DvrGlobalBufferKey key) {
306  ALOGD_IF(TRACE, "DisplayService::OnGetGlobalBuffer: key=%d", key);
307  auto global_buffer = global_buffers_.find(key);
308  if (global_buffer != global_buffers_.end())
309    return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
310  else
311    return pdx::ErrorStatus(EINVAL);
312}
313
314// Calls the message handler for the DisplaySurface associated with this
315// channel.
316Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
317  auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
318  ALOGW_IF(!surface,
319           "DisplayService::HandleSurfaceMessage: surface is nullptr!");
320
321  if (surface)
322    return surface->HandleMessage(message);
323  else
324    return ErrorStatus(EINVAL);
325}
326
327std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
328    int surface_id) const {
329  return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
330}
331
332std::vector<std::shared_ptr<DisplaySurface>>
333DisplayService::GetDisplaySurfaces() const {
334  return GetChannels<DisplaySurface>();
335}
336
337std::vector<std::shared_ptr<DirectDisplaySurface>>
338DisplayService::GetVisibleDisplaySurfaces() const {
339  std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
340
341  ForEachDisplaySurface(
342      SurfaceType::Direct,
343      [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
344        if (surface->visible()) {
345          visible_surfaces.push_back(
346              std::static_pointer_cast<DirectDisplaySurface>(surface));
347          surface->ClearUpdate();
348        }
349      });
350
351  return visible_surfaces;
352}
353
354void DisplayService::UpdateActiveDisplaySurfaces() {
355  auto visible_surfaces = GetVisibleDisplaySurfaces();
356  ALOGD_IF(TRACE,
357           "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
358           visible_surfaces.size());
359  hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
360}
361
362pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupGlobalBuffer(
363    DvrGlobalBufferKey key, size_t size, uint64_t usage) {
364  auto global_buffer = global_buffers_.find(key);
365  if (global_buffer == global_buffers_.end()) {
366    auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
367                                                  HAL_PIXEL_FORMAT_BLOB, usage);
368
369    // Some buffers are used internally. If they were configured with an
370    // invalid size or format, this will fail.
371    int result = hardware_composer_.OnNewGlobalBuffer(key, *ion_buffer.get());
372    if (result < 0)
373      return ErrorStatus(result);
374    global_buffer =
375        global_buffers_.insert(std::make_pair(key, std::move(ion_buffer)))
376            .first;
377  }
378
379  return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
380}
381
382pdx::Status<void> DisplayService::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
383  auto global_buffer = global_buffers_.find(key);
384  if (global_buffer != global_buffers_.end()) {
385    // Some buffers are used internally.
386    hardware_composer_.OnDeletedGlobalBuffer(key);
387    global_buffers_.erase(global_buffer);
388  }
389
390  return {0};
391}
392
393void DisplayService::SetDisplayConfigurationUpdateNotifier(
394    DisplayConfigurationUpdateNotifier update_notifier) {
395  update_notifier_ = update_notifier;
396}
397
398void DisplayService::NotifyDisplayConfigurationUpdate() {
399  if (update_notifier_)
400    update_notifier_();
401}
402
403Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
404  bool visible = false;
405  ForEachDisplaySurface(
406      SurfaceType::Application,
407      [&visible](const std::shared_ptr<DisplaySurface>& surface) {
408        if (surface->visible())
409          visible = true;
410      });
411
412  return {visible};
413}
414
415}  // namespace dvr
416}  // namespace android
417