blob: 733edc659ce917074dcf98a2bbeb27fd8ca2fbce [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#include "display_service.h"
2
Hendrik Wagenaareaa55222017-04-06 10:56:23 -07003#include <unistd.h>
Corey Tabaka0b485c92017-05-19 12:02:58 -07004
5#include <algorithm>
6#include <sstream>
7#include <string>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08008#include <vector>
9
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -070010#include <android-base/file.h>
11#include <android-base/properties.h>
Corey Tabaka2251d822017-04-20 16:04:07 -070012#include <dvr/dvr_display_types.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080013#include <pdx/default_transport/service_endpoint.h>
14#include <pdx/rpc/remote_method.h>
Corey Tabaka99c2d732017-06-07 17:54:33 -070015#include <private/android_filesystem_config.h>
Corey Tabaka3f82d312017-04-20 14:42:08 -070016#include <private/dvr/display_protocol.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080017#include <private/dvr/numeric.h>
Corey Tabaka99c2d732017-06-07 17:54:33 -070018#include <private/dvr/trusted_uids.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080019#include <private/dvr/types.h>
20
Corey Tabaka2251d822017-04-20 16:04:07 -070021using android::dvr::display::DisplayProtocol;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080022using android::pdx::Channel;
Corey Tabaka2251d822017-04-20 16:04:07 -070023using android::pdx::ErrorStatus;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080024using android::pdx::Message;
Corey Tabaka2251d822017-04-20 16:04:07 -070025using android::pdx::Status;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080026using android::pdx::default_transport::Endpoint;
27using android::pdx::rpc::DispatchRemoteMethod;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080028
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -070029namespace {
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
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080037namespace android {
38namespace dvr {
39
Corey Tabaka2251d822017-04-20 16:04:07 -070040DisplayService::DisplayService(Hwc2::Composer* hidl,
41 RequestDisplayCallback request_display_callback)
42 : BASE("DisplayService",
43 Endpoint::Create(display::DisplayProtocol::kClientPath)),
44 hardware_composer_(hidl, request_display_callback),
45 request_display_callback_(request_display_callback) {
Stephen Kiazyk016e5e32017-02-21 17:09:22 -080046 hardware_composer_.Initialize();
47}
48
49bool DisplayService::IsInitialized() const {
50 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
51}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080052
Corey Tabaka2251d822017-04-20 16:04:07 -070053std::string DisplayService::DumpState(size_t /*max_length*/) {
Corey Tabaka0b485c92017-05-19 12:02:58 -070054 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();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800113}
114
Corey Tabaka2251d822017-04-20 16:04:07 -0700115void DisplayService::OnChannelClose(pdx::Message& message,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800116 const std::shared_ptr<Channel>& channel) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700117 if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
118 surface->OnSetAttributes(message,
119 {{display::SurfaceAttribute::Visible,
120 display::SurfaceAttributeValue{false}}});
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800121 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800122}
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.
Corey Tabaka2251d822017-04-20 16:04:07 -0700127Status<void> DisplayService::HandleMessage(pdx::Message& message) {
128 ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800129 switch (message.GetOp()) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700130 case DisplayProtocol::GetMetrics::Opcode:
131 DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800132 *this, &DisplayService::OnGetMetrics, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700133 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800134
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700135 case DisplayProtocol::GetConfigurationData::Opcode:
136 DispatchRemoteMethod<DisplayProtocol::GetConfigurationData>(
137 *this, &DisplayService::OnGetConfigurationData, message);
138 return {};
139
Corey Tabaka2251d822017-04-20 16:04:07 -0700140 case DisplayProtocol::CreateSurface::Opcode:
141 DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800142 *this, &DisplayService::OnCreateSurface, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700143 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800144
Corey Tabaka99c2d732017-06-07 17:54:33 -0700145 case DisplayProtocol::SetupGlobalBuffer::Opcode:
146 DispatchRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(
147 *this, &DisplayService::OnSetupGlobalBuffer, message);
148 return {};
149
150 case DisplayProtocol::DeleteGlobalBuffer::Opcode:
151 DispatchRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(
152 *this, &DisplayService::OnDeleteGlobalBuffer, message);
153 return {};
154
Okan Arikan36d23802017-05-15 15:20:39 -0700155 case DisplayProtocol::GetGlobalBuffer::Opcode:
156 DispatchRemoteMethod<DisplayProtocol::GetGlobalBuffer>(
157 *this, &DisplayService::OnGetGlobalBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700158 return {};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700159
Corey Tabaka2251d822017-04-20 16:04:07 -0700160 case DisplayProtocol::IsVrAppRunning::Opcode:
161 DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400162 *this, &DisplayService::IsVrAppRunning, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700163 return {};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400164
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800165 // Direct the surface specific messages to the surface instance.
Corey Tabaka2251d822017-04-20 16:04:07 -0700166 case DisplayProtocol::SetAttributes::Opcode:
167 case DisplayProtocol::CreateQueue::Opcode:
168 case DisplayProtocol::GetSurfaceInfo::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800169 return HandleSurfaceMessage(message);
170
171 default:
172 return Service::HandleMessage(message);
173 }
174}
175
Corey Tabaka2251d822017-04-20 16:04:07 -0700176Status<display::Metrics> DisplayService::OnGetMetrics(
177 pdx::Message& /*message*/) {
178 return {{static_cast<uint32_t>(GetDisplayMetrics().width),
179 static_cast<uint32_t>(GetDisplayMetrics().height),
180 static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
181 static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
182 static_cast<uint32_t>(
183 hardware_composer_.native_display_metrics().vsync_period_ns),
184 0,
185 0,
186 0,
187 0.0,
188 {},
189 {}}};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800190}
191
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700192pdx::Status<std::string> DisplayService::OnGetConfigurationData(
193 pdx::Message& /*message*/, display::ConfigFileType config_type) {
194 std::string property_name;
195 switch (config_type) {
196 case display::ConfigFileType::kLensMetrics:
197 property_name = kDvrLensMetricsProperty;
198 break;
199 case display::ConfigFileType::kDeviceMetrics:
200 property_name = kDvrDeviceMetricsProperty;
201 break;
202 case display::ConfigFileType::kDeviceConfiguration:
203 property_name = kDvrDeviceConfigProperty;
204 break;
205 default:
206 return ErrorStatus(EINVAL);
207 }
208 std::string file_path = base::GetProperty(property_name, "");
209 if (file_path.empty()) {
210 return ErrorStatus(ENOENT);
211 }
212
213 std::string data;
214 if (!base::ReadFileToString(file_path, &data)) {
215 return ErrorStatus(errno);
216 }
217
218 return std::move(data);
219}
220
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800221// Creates a new DisplaySurface and associates it with this channel. This may
222// only be done once per channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700223Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
224 pdx::Message& message, const display::SurfaceAttributes& attributes) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800225 // A surface may only be created once per channel.
226 if (message.GetChannel())
Corey Tabaka2251d822017-04-20 16:04:07 -0700227 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800228
229 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
230 message.GetChannelId());
231
232 // Use the channel id as the unique surface id.
233 const int surface_id = message.GetChannelId();
234 const int process_id = message.GetProcessId();
Corey Tabaka2251d822017-04-20 16:04:07 -0700235 const int user_id = message.GetEffectiveUserId();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800236
237 ALOGI_IF(TRACE,
Corey Tabaka2251d822017-04-20 16:04:07 -0700238 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
239 surface_id, process_id);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800240
Corey Tabaka2251d822017-04-20 16:04:07 -0700241 auto surface_status =
242 DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
243 if (!surface_status) {
244 ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
245 surface_status.GetErrorMessage().c_str());
246 return ErrorStatus(surface_status.error());
247 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800248
Corey Tabaka2251d822017-04-20 16:04:07 -0700249 SurfaceType surface_type = surface_status.get()->surface_type();
250 display::SurfaceUpdateFlags update_flags =
251 surface_status.get()->update_flags();
252 display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
253 surface_status.get()->visible(),
254 surface_status.get()->z_order()};
255
256 message.SetChannel(surface_status.take());
257
258 SurfaceUpdated(surface_type, update_flags);
259 return {surface_info};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800260}
261
Corey Tabaka2251d822017-04-20 16:04:07 -0700262void 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();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800271 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800272}
273
Corey Tabaka99c2d732017-06-07 17:54:33 -0700274pdx::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
Okan Arikan36d23802017-05-15 15:20:39 -0700304pdx::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)};
Corey Tabaka2251d822017-04-20 16:04:07 -0700310 else
311 return pdx::ErrorStatus(EINVAL);
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700312}
313
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800314// Calls the message handler for the DisplaySurface associated with this
315// channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700316Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
317 auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800318 ALOGW_IF(!surface,
319 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
320
321 if (surface)
322 return surface->HandleMessage(message);
323 else
Corey Tabaka2251d822017-04-20 16:04:07 -0700324 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800325}
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
Corey Tabaka2251d822017-04-20 16:04:07 -0700337std::vector<std::shared_ptr<DirectDisplaySurface>>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800338DisplayService::GetVisibleDisplaySurfaces() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700339 std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800340
341 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700342 SurfaceType::Direct,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800343 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
Corey Tabaka2251d822017-04-20 16:04:07 -0700344 if (surface->visible()) {
345 visible_surfaces.push_back(
346 std::static_pointer_cast<DirectDisplaySurface>(surface));
347 surface->ClearUpdate();
348 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800349 });
350
351 return visible_surfaces;
352}
353
Steven Thomas050b2c82017-03-06 11:45:16 -0800354void DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800355 auto visible_surfaces = GetVisibleDisplaySurfaces();
356
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800357 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
358 [](const std::shared_ptr<DisplaySurface>& a,
359 const std::shared_ptr<DisplaySurface>& b) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700360 return a->z_order() < b->z_order();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800361 });
362
363 ALOGD_IF(TRACE,
364 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
365 visible_surfaces.size());
366
Steven Thomas050b2c82017-03-06 11:45:16 -0800367 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800368}
369
Okan Arikan36d23802017-05-15 15:20:39 -0700370pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupGlobalBuffer(
371 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
372 auto global_buffer = global_buffers_.find(key);
373 if (global_buffer == global_buffers_.end()) {
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700374 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
375 HAL_PIXEL_FORMAT_BLOB, usage);
John Bates954796e2017-05-11 11:00:31 -0700376
377 // Some buffers are used internally. If they were configured with an
378 // invalid size or format, this will fail.
379 int result = hardware_composer_.OnNewGlobalBuffer(key, *ion_buffer.get());
380 if (result < 0)
381 return ErrorStatus(result);
Okan Arikan36d23802017-05-15 15:20:39 -0700382 global_buffer =
383 global_buffers_.insert(std::make_pair(key, std::move(ion_buffer)))
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700384 .first;
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700385 }
386
Okan Arikan36d23802017-05-15 15:20:39 -0700387 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700388}
389
John Bates954796e2017-05-11 11:00:31 -0700390pdx::Status<void> DisplayService::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
391 auto global_buffer = global_buffers_.find(key);
392 if (global_buffer != global_buffers_.end()) {
393 // Some buffers are used internally.
394 hardware_composer_.OnDeletedGlobalBuffer(key);
395 global_buffers_.erase(global_buffer);
396 }
397
398 return {0};
399}
400
Steven Thomas3cfac282017-02-06 12:29:30 -0800401void DisplayService::OnHardwareComposerRefresh() {
402 hardware_composer_.OnHardwareComposerRefresh();
403}
404
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800405void DisplayService::SetDisplayConfigurationUpdateNotifier(
406 DisplayConfigurationUpdateNotifier update_notifier) {
407 update_notifier_ = update_notifier;
408}
409
410void DisplayService::NotifyDisplayConfigurationUpdate() {
411 if (update_notifier_)
412 update_notifier_();
413}
414
Corey Tabaka2251d822017-04-20 16:04:07 -0700415Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
Albert Chaulk356bc372017-04-05 18:01:58 -0400416 bool visible = false;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700417 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700418 SurfaceType::Application,
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700419 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700420 if (surface->visible())
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700421 visible = true;
422 });
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400423
Corey Tabaka2251d822017-04-20 16:04:07 -0700424 return {visible};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400425}
426
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800427} // namespace dvr
428} // namespace android