blob: f350762e79e8c3432ea2b57060971fbfe2dc4f2c [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",
Steven Thomasd7f49c52017-07-26 18:48:28 -070043 Endpoint::Create(display::DisplayProtocol::kClientPath)) {
44 hardware_composer_.Initialize(hidl, request_display_callback);
Stephen Kiazyk016e5e32017-02-21 17:09:22 -080045}
46
47bool DisplayService::IsInitialized() const {
48 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
49}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080050
Corey Tabaka2251d822017-04-20 16:04:07 -070051std::string DisplayService::DumpState(size_t /*max_length*/) {
Corey Tabaka0b485c92017-05-19 12:02:58 -070052 std::ostringstream stream;
53
54 auto surfaces = GetDisplaySurfaces();
55 std::sort(surfaces.begin(), surfaces.end(), [](const auto& a, const auto& b) {
56 return a->surface_id() < b->surface_id();
57 });
58
59 stream << "Application Surfaces:" << std::endl;
60
61 size_t count = 0;
62 for (const auto& surface : surfaces) {
63 if (surface->surface_type() == SurfaceType::Application) {
64 stream << "Surface " << count++ << ":";
65 stream << " surface_id=" << surface->surface_id()
66 << " process_id=" << surface->process_id()
67 << " user_id=" << surface->user_id()
68 << " visible=" << surface->visible()
69 << " z_order=" << surface->z_order();
70
71 stream << " queue_ids=";
72 auto queue_ids = surface->GetQueueIds();
73 std::sort(queue_ids.begin(), queue_ids.end());
74 for (int32_t id : queue_ids) {
75 if (id != queue_ids[0])
76 stream << ",";
77 stream << id;
78 }
79 stream << std::endl;
80 }
81 }
82 stream << std::endl;
83
84 stream << "Direct Surfaces:" << std::endl;
85
86 count = 0;
87 for (const auto& surface : surfaces) {
88 if (surface->surface_type() == SurfaceType::Direct) {
89 stream << "Surface " << count++ << ":";
90 stream << " surface_id=" << surface->surface_id()
91 << " process_id=" << surface->process_id()
92 << " user_id=" << surface->user_id()
93 << " visible=" << surface->visible()
94 << " z_order=" << surface->z_order();
95
96 stream << " queue_ids=";
97 auto queue_ids = surface->GetQueueIds();
98 std::sort(queue_ids.begin(), queue_ids.end());
99 for (int32_t id : queue_ids) {
100 if (id != queue_ids[0])
101 stream << ",";
102 stream << id;
103 }
104 stream << std::endl;
105 }
106 }
107 stream << std::endl;
108
109 stream << hardware_composer_.Dump();
110 return stream.str();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800111}
112
Corey Tabaka2251d822017-04-20 16:04:07 -0700113void DisplayService::OnChannelClose(pdx::Message& message,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800114 const std::shared_ptr<Channel>& channel) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700115 if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
116 surface->OnSetAttributes(message,
117 {{display::SurfaceAttribute::Visible,
118 display::SurfaceAttributeValue{false}}});
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800119 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800120}
121
122// First-level dispatch for display service messages. Directly handles messages
123// that are independent of the display surface (metrics, creation) and routes
124// surface-specific messages to the per-instance handlers.
Corey Tabaka2251d822017-04-20 16:04:07 -0700125Status<void> DisplayService::HandleMessage(pdx::Message& message) {
126 ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800127 switch (message.GetOp()) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700128 case DisplayProtocol::GetMetrics::Opcode:
129 DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800130 *this, &DisplayService::OnGetMetrics, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700131 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800132
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700133 case DisplayProtocol::GetConfigurationData::Opcode:
134 DispatchRemoteMethod<DisplayProtocol::GetConfigurationData>(
135 *this, &DisplayService::OnGetConfigurationData, message);
136 return {};
137
Corey Tabaka2251d822017-04-20 16:04:07 -0700138 case DisplayProtocol::CreateSurface::Opcode:
139 DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800140 *this, &DisplayService::OnCreateSurface, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700141 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800142
Corey Tabaka99c2d732017-06-07 17:54:33 -0700143 case DisplayProtocol::SetupGlobalBuffer::Opcode:
144 DispatchRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(
145 *this, &DisplayService::OnSetupGlobalBuffer, message);
146 return {};
147
148 case DisplayProtocol::DeleteGlobalBuffer::Opcode:
149 DispatchRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(
150 *this, &DisplayService::OnDeleteGlobalBuffer, message);
151 return {};
152
Okan Arikan36d23802017-05-15 15:20:39 -0700153 case DisplayProtocol::GetGlobalBuffer::Opcode:
154 DispatchRemoteMethod<DisplayProtocol::GetGlobalBuffer>(
155 *this, &DisplayService::OnGetGlobalBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700156 return {};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700157
Corey Tabaka2251d822017-04-20 16:04:07 -0700158 case DisplayProtocol::IsVrAppRunning::Opcode:
159 DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400160 *this, &DisplayService::IsVrAppRunning, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700161 return {};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400162
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800163 // Direct the surface specific messages to the surface instance.
Corey Tabaka2251d822017-04-20 16:04:07 -0700164 case DisplayProtocol::SetAttributes::Opcode:
165 case DisplayProtocol::CreateQueue::Opcode:
166 case DisplayProtocol::GetSurfaceInfo::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800167 return HandleSurfaceMessage(message);
168
169 default:
170 return Service::HandleMessage(message);
171 }
172}
173
Corey Tabaka2251d822017-04-20 16:04:07 -0700174Status<display::Metrics> DisplayService::OnGetMetrics(
175 pdx::Message& /*message*/) {
176 return {{static_cast<uint32_t>(GetDisplayMetrics().width),
177 static_cast<uint32_t>(GetDisplayMetrics().height),
178 static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
179 static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
180 static_cast<uint32_t>(
181 hardware_composer_.native_display_metrics().vsync_period_ns),
182 0,
183 0,
184 0,
185 0.0,
186 {},
187 {}}};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800188}
189
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700190pdx::Status<std::string> DisplayService::OnGetConfigurationData(
191 pdx::Message& /*message*/, display::ConfigFileType config_type) {
192 std::string property_name;
193 switch (config_type) {
194 case display::ConfigFileType::kLensMetrics:
195 property_name = kDvrLensMetricsProperty;
196 break;
197 case display::ConfigFileType::kDeviceMetrics:
198 property_name = kDvrDeviceMetricsProperty;
199 break;
200 case display::ConfigFileType::kDeviceConfiguration:
201 property_name = kDvrDeviceConfigProperty;
202 break;
203 default:
204 return ErrorStatus(EINVAL);
205 }
206 std::string file_path = base::GetProperty(property_name, "");
207 if (file_path.empty()) {
208 return ErrorStatus(ENOENT);
209 }
210
211 std::string data;
212 if (!base::ReadFileToString(file_path, &data)) {
213 return ErrorStatus(errno);
214 }
215
216 return std::move(data);
217}
218
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800219// Creates a new DisplaySurface and associates it with this channel. This may
220// only be done once per channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700221Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
222 pdx::Message& message, const display::SurfaceAttributes& attributes) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800223 // A surface may only be created once per channel.
224 if (message.GetChannel())
Corey Tabaka2251d822017-04-20 16:04:07 -0700225 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800226
227 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
228 message.GetChannelId());
229
230 // Use the channel id as the unique surface id.
231 const int surface_id = message.GetChannelId();
232 const int process_id = message.GetProcessId();
Corey Tabaka2251d822017-04-20 16:04:07 -0700233 const int user_id = message.GetEffectiveUserId();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800234
235 ALOGI_IF(TRACE,
Corey Tabaka2251d822017-04-20 16:04:07 -0700236 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
237 surface_id, process_id);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800238
Corey Tabaka2251d822017-04-20 16:04:07 -0700239 auto surface_status =
240 DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
241 if (!surface_status) {
242 ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
243 surface_status.GetErrorMessage().c_str());
244 return ErrorStatus(surface_status.error());
245 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800246
Corey Tabaka2251d822017-04-20 16:04:07 -0700247 SurfaceType surface_type = surface_status.get()->surface_type();
248 display::SurfaceUpdateFlags update_flags =
249 surface_status.get()->update_flags();
250 display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
251 surface_status.get()->visible(),
252 surface_status.get()->z_order()};
253
254 message.SetChannel(surface_status.take());
255
256 SurfaceUpdated(surface_type, update_flags);
257 return {surface_info};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800258}
259
Corey Tabaka2251d822017-04-20 16:04:07 -0700260void DisplayService::SurfaceUpdated(SurfaceType surface_type,
261 display::SurfaceUpdateFlags update_flags) {
262 ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
263 update_flags.value());
264 if (update_flags.value() != 0) {
265 if (surface_type == SurfaceType::Application)
266 NotifyDisplayConfigurationUpdate();
267 else
268 UpdateActiveDisplaySurfaces();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800269 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800270}
271
Corey Tabaka99c2d732017-06-07 17:54:33 -0700272pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnSetupGlobalBuffer(
273 pdx::Message& message, DvrGlobalBufferKey key, size_t size,
274 uint64_t usage) {
275 const int user_id = message.GetEffectiveUserId();
276 const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
277
278 if (!trusted) {
279 ALOGE(
280 "DisplayService::OnSetupGlobalBuffer: Permission denied for user_id=%d",
281 user_id);
282 return ErrorStatus(EPERM);
283 }
284 return SetupGlobalBuffer(key, size, usage);
285}
286
287pdx::Status<void> DisplayService::OnDeleteGlobalBuffer(pdx::Message& message,
288 DvrGlobalBufferKey key) {
289 const int user_id = message.GetEffectiveUserId();
290 const bool trusted = (user_id == AID_ROOT) || IsTrustedUid(user_id);
291
292 if (!trusted) {
293 ALOGE(
294 "DisplayService::OnDeleteGlobalBuffer: Permission denied for "
295 "user_id=%d",
296 user_id);
297 return ErrorStatus(EPERM);
298 }
299 return DeleteGlobalBuffer(key);
300}
301
Okan Arikan36d23802017-05-15 15:20:39 -0700302pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetGlobalBuffer(
303 pdx::Message& /* message */, DvrGlobalBufferKey key) {
304 ALOGD_IF(TRACE, "DisplayService::OnGetGlobalBuffer: key=%d", key);
305 auto global_buffer = global_buffers_.find(key);
306 if (global_buffer != global_buffers_.end())
307 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
Corey Tabaka2251d822017-04-20 16:04:07 -0700308 else
309 return pdx::ErrorStatus(EINVAL);
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700310}
311
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800312// Calls the message handler for the DisplaySurface associated with this
313// channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700314Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
315 auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800316 ALOGW_IF(!surface,
317 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
318
319 if (surface)
320 return surface->HandleMessage(message);
321 else
Corey Tabaka2251d822017-04-20 16:04:07 -0700322 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800323}
324
325std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
326 int surface_id) const {
327 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
328}
329
330std::vector<std::shared_ptr<DisplaySurface>>
331DisplayService::GetDisplaySurfaces() const {
332 return GetChannels<DisplaySurface>();
333}
334
Corey Tabaka2251d822017-04-20 16:04:07 -0700335std::vector<std::shared_ptr<DirectDisplaySurface>>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800336DisplayService::GetVisibleDisplaySurfaces() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700337 std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800338
339 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700340 SurfaceType::Direct,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800341 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
Corey Tabaka2251d822017-04-20 16:04:07 -0700342 if (surface->visible()) {
343 visible_surfaces.push_back(
344 std::static_pointer_cast<DirectDisplaySurface>(surface));
345 surface->ClearUpdate();
346 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800347 });
348
349 return visible_surfaces;
350}
351
Steven Thomas050b2c82017-03-06 11:45:16 -0800352void DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800353 auto visible_surfaces = GetVisibleDisplaySurfaces();
354
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800355 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
356 [](const std::shared_ptr<DisplaySurface>& a,
357 const std::shared_ptr<DisplaySurface>& b) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700358 return a->z_order() < b->z_order();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800359 });
360
361 ALOGD_IF(TRACE,
362 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
363 visible_surfaces.size());
364
Steven Thomas050b2c82017-03-06 11:45:16 -0800365 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800366}
367
Okan Arikan36d23802017-05-15 15:20:39 -0700368pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupGlobalBuffer(
369 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
370 auto global_buffer = global_buffers_.find(key);
371 if (global_buffer == global_buffers_.end()) {
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700372 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
373 HAL_PIXEL_FORMAT_BLOB, usage);
John Bates954796e2017-05-11 11:00:31 -0700374
375 // Some buffers are used internally. If they were configured with an
376 // invalid size or format, this will fail.
377 int result = hardware_composer_.OnNewGlobalBuffer(key, *ion_buffer.get());
378 if (result < 0)
379 return ErrorStatus(result);
Okan Arikan36d23802017-05-15 15:20:39 -0700380 global_buffer =
381 global_buffers_.insert(std::make_pair(key, std::move(ion_buffer)))
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700382 .first;
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700383 }
384
Okan Arikan36d23802017-05-15 15:20:39 -0700385 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700386}
387
John Bates954796e2017-05-11 11:00:31 -0700388pdx::Status<void> DisplayService::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
389 auto global_buffer = global_buffers_.find(key);
390 if (global_buffer != global_buffers_.end()) {
391 // Some buffers are used internally.
392 hardware_composer_.OnDeletedGlobalBuffer(key);
393 global_buffers_.erase(global_buffer);
394 }
395
396 return {0};
397}
398
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800399void DisplayService::SetDisplayConfigurationUpdateNotifier(
400 DisplayConfigurationUpdateNotifier update_notifier) {
401 update_notifier_ = update_notifier;
402}
403
404void DisplayService::NotifyDisplayConfigurationUpdate() {
405 if (update_notifier_)
406 update_notifier_();
407}
408
Corey Tabaka2251d822017-04-20 16:04:07 -0700409Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
Albert Chaulk356bc372017-04-05 18:01:58 -0400410 bool visible = false;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700411 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700412 SurfaceType::Application,
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700413 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700414 if (surface->visible())
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700415 visible = true;
416 });
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400417
Corey Tabaka2251d822017-04-20 16:04:07 -0700418 return {visible};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400419}
420
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800421} // namespace dvr
422} // namespace android