blob: dc9807ae11223d71bf4677f0cce2ec4a4bba27e8 [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>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08004#include <vector>
5
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -07006#include <android-base/file.h>
7#include <android-base/properties.h>
Corey Tabaka2251d822017-04-20 16:04:07 -07008#include <dvr/dvr_display_types.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08009#include <pdx/default_transport/service_endpoint.h>
10#include <pdx/rpc/remote_method.h>
Corey Tabaka3f82d312017-04-20 14:42:08 -070011#include <private/dvr/display_protocol.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080012#include <private/dvr/numeric.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080013#include <private/dvr/types.h>
14
Corey Tabaka2251d822017-04-20 16:04:07 -070015using android::dvr::display::DisplayProtocol;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080016using android::pdx::Channel;
Corey Tabaka2251d822017-04-20 16:04:07 -070017using android::pdx::ErrorStatus;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080018using android::pdx::Message;
Corey Tabaka2251d822017-04-20 16:04:07 -070019using android::pdx::Status;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080020using android::pdx::default_transport::Endpoint;
21using android::pdx::rpc::DispatchRemoteMethod;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080022
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -070023namespace {
24
25const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
26const char kDvrDeviceMetricsProperty[] = "ro.dvr.device_metrics";
27const char kDvrDeviceConfigProperty[] = "ro.dvr.device_configuration";
28
29} // namespace
30
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080031namespace android {
32namespace dvr {
33
Corey Tabaka2251d822017-04-20 16:04:07 -070034DisplayService::DisplayService(Hwc2::Composer* hidl,
35 RequestDisplayCallback request_display_callback)
36 : BASE("DisplayService",
37 Endpoint::Create(display::DisplayProtocol::kClientPath)),
38 hardware_composer_(hidl, request_display_callback),
39 request_display_callback_(request_display_callback) {
Stephen Kiazyk016e5e32017-02-21 17:09:22 -080040 hardware_composer_.Initialize();
41}
42
43bool DisplayService::IsInitialized() const {
44 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
45}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080046
Corey Tabaka2251d822017-04-20 16:04:07 -070047std::string DisplayService::DumpState(size_t /*max_length*/) {
48 return hardware_composer_.Dump();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080049}
50
Corey Tabaka2251d822017-04-20 16:04:07 -070051void DisplayService::OnChannelClose(pdx::Message& message,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080052 const std::shared_ptr<Channel>& channel) {
Corey Tabaka2251d822017-04-20 16:04:07 -070053 if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
54 surface->OnSetAttributes(message,
55 {{display::SurfaceAttribute::Visible,
56 display::SurfaceAttributeValue{false}}});
57 SurfaceUpdated(surface->surface_type(),
58 display::SurfaceUpdateFlags::VisibilityChanged);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080059 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080060}
61
62// First-level dispatch for display service messages. Directly handles messages
63// that are independent of the display surface (metrics, creation) and routes
64// surface-specific messages to the per-instance handlers.
Corey Tabaka2251d822017-04-20 16:04:07 -070065Status<void> DisplayService::HandleMessage(pdx::Message& message) {
66 ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080067 switch (message.GetOp()) {
Corey Tabaka2251d822017-04-20 16:04:07 -070068 case DisplayProtocol::GetMetrics::Opcode:
69 DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080070 *this, &DisplayService::OnGetMetrics, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070071 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080072
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -070073 case DisplayProtocol::GetConfigurationData::Opcode:
74 DispatchRemoteMethod<DisplayProtocol::GetConfigurationData>(
75 *this, &DisplayService::OnGetConfigurationData, message);
76 return {};
77
Corey Tabaka2251d822017-04-20 16:04:07 -070078 case DisplayProtocol::CreateSurface::Opcode:
79 DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080080 *this, &DisplayService::OnCreateSurface, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070081 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080082
Okan Arikan36d23802017-05-15 15:20:39 -070083 case DisplayProtocol::GetGlobalBuffer::Opcode:
84 DispatchRemoteMethod<DisplayProtocol::GetGlobalBuffer>(
85 *this, &DisplayService::OnGetGlobalBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070086 return {};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -070087
Corey Tabaka2251d822017-04-20 16:04:07 -070088 case DisplayProtocol::IsVrAppRunning::Opcode:
89 DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -040090 *this, &DisplayService::IsVrAppRunning, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070091 return {};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -040092
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080093 // Direct the surface specific messages to the surface instance.
Corey Tabaka2251d822017-04-20 16:04:07 -070094 case DisplayProtocol::SetAttributes::Opcode:
95 case DisplayProtocol::CreateQueue::Opcode:
96 case DisplayProtocol::GetSurfaceInfo::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080097 return HandleSurfaceMessage(message);
98
99 default:
100 return Service::HandleMessage(message);
101 }
102}
103
Corey Tabaka2251d822017-04-20 16:04:07 -0700104Status<display::Metrics> DisplayService::OnGetMetrics(
105 pdx::Message& /*message*/) {
106 return {{static_cast<uint32_t>(GetDisplayMetrics().width),
107 static_cast<uint32_t>(GetDisplayMetrics().height),
108 static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
109 static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
110 static_cast<uint32_t>(
111 hardware_composer_.native_display_metrics().vsync_period_ns),
112 0,
113 0,
114 0,
115 0.0,
116 {},
117 {}}};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800118}
119
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700120pdx::Status<std::string> DisplayService::OnGetConfigurationData(
121 pdx::Message& /*message*/, display::ConfigFileType config_type) {
122 std::string property_name;
123 switch (config_type) {
124 case display::ConfigFileType::kLensMetrics:
125 property_name = kDvrLensMetricsProperty;
126 break;
127 case display::ConfigFileType::kDeviceMetrics:
128 property_name = kDvrDeviceMetricsProperty;
129 break;
130 case display::ConfigFileType::kDeviceConfiguration:
131 property_name = kDvrDeviceConfigProperty;
132 break;
133 default:
134 return ErrorStatus(EINVAL);
135 }
136 std::string file_path = base::GetProperty(property_name, "");
137 if (file_path.empty()) {
138 return ErrorStatus(ENOENT);
139 }
140
141 std::string data;
142 if (!base::ReadFileToString(file_path, &data)) {
143 return ErrorStatus(errno);
144 }
145
146 return std::move(data);
147}
148
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800149// Creates a new DisplaySurface and associates it with this channel. This may
150// only be done once per channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700151Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
152 pdx::Message& message, const display::SurfaceAttributes& attributes) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800153 // A surface may only be created once per channel.
154 if (message.GetChannel())
Corey Tabaka2251d822017-04-20 16:04:07 -0700155 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800156
157 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
158 message.GetChannelId());
159
160 // Use the channel id as the unique surface id.
161 const int surface_id = message.GetChannelId();
162 const int process_id = message.GetProcessId();
Corey Tabaka2251d822017-04-20 16:04:07 -0700163 const int user_id = message.GetEffectiveUserId();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800164
165 ALOGI_IF(TRACE,
Corey Tabaka2251d822017-04-20 16:04:07 -0700166 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
167 surface_id, process_id);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800168
Corey Tabaka2251d822017-04-20 16:04:07 -0700169 auto surface_status =
170 DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
171 if (!surface_status) {
172 ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
173 surface_status.GetErrorMessage().c_str());
174 return ErrorStatus(surface_status.error());
175 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800176
Corey Tabaka2251d822017-04-20 16:04:07 -0700177 SurfaceType surface_type = surface_status.get()->surface_type();
178 display::SurfaceUpdateFlags update_flags =
179 surface_status.get()->update_flags();
180 display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
181 surface_status.get()->visible(),
182 surface_status.get()->z_order()};
183
184 message.SetChannel(surface_status.take());
185
186 SurfaceUpdated(surface_type, update_flags);
187 return {surface_info};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800188}
189
Corey Tabaka2251d822017-04-20 16:04:07 -0700190void DisplayService::SurfaceUpdated(SurfaceType surface_type,
191 display::SurfaceUpdateFlags update_flags) {
192 ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
193 update_flags.value());
194 if (update_flags.value() != 0) {
195 if (surface_type == SurfaceType::Application)
196 NotifyDisplayConfigurationUpdate();
197 else
198 UpdateActiveDisplaySurfaces();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800199 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800200}
201
Okan Arikan36d23802017-05-15 15:20:39 -0700202pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetGlobalBuffer(
203 pdx::Message& /* message */, DvrGlobalBufferKey key) {
204 ALOGD_IF(TRACE, "DisplayService::OnGetGlobalBuffer: key=%d", key);
205 auto global_buffer = global_buffers_.find(key);
206 if (global_buffer != global_buffers_.end())
207 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
Corey Tabaka2251d822017-04-20 16:04:07 -0700208 else
209 return pdx::ErrorStatus(EINVAL);
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700210}
211
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800212// Calls the message handler for the DisplaySurface associated with this
213// channel.
Corey Tabaka2251d822017-04-20 16:04:07 -0700214Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
215 auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800216 ALOGW_IF(!surface,
217 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
218
219 if (surface)
220 return surface->HandleMessage(message);
221 else
Corey Tabaka2251d822017-04-20 16:04:07 -0700222 return ErrorStatus(EINVAL);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800223}
224
225std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
226 int surface_id) const {
227 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
228}
229
230std::vector<std::shared_ptr<DisplaySurface>>
231DisplayService::GetDisplaySurfaces() const {
232 return GetChannels<DisplaySurface>();
233}
234
Corey Tabaka2251d822017-04-20 16:04:07 -0700235std::vector<std::shared_ptr<DirectDisplaySurface>>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800236DisplayService::GetVisibleDisplaySurfaces() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700237 std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800238
239 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700240 SurfaceType::Direct,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800241 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
Corey Tabaka2251d822017-04-20 16:04:07 -0700242 if (surface->visible()) {
243 visible_surfaces.push_back(
244 std::static_pointer_cast<DirectDisplaySurface>(surface));
245 surface->ClearUpdate();
246 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800247 });
248
249 return visible_surfaces;
250}
251
Steven Thomas050b2c82017-03-06 11:45:16 -0800252void DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800253 auto visible_surfaces = GetVisibleDisplaySurfaces();
254
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800255 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
256 [](const std::shared_ptr<DisplaySurface>& a,
257 const std::shared_ptr<DisplaySurface>& b) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700258 return a->z_order() < b->z_order();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800259 });
260
261 ALOGD_IF(TRACE,
262 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
263 visible_surfaces.size());
264
Steven Thomas050b2c82017-03-06 11:45:16 -0800265 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800266}
267
Okan Arikan36d23802017-05-15 15:20:39 -0700268pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupGlobalBuffer(
269 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
270 auto global_buffer = global_buffers_.find(key);
271 if (global_buffer == global_buffers_.end()) {
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700272 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
273 HAL_PIXEL_FORMAT_BLOB, usage);
John Bates954796e2017-05-11 11:00:31 -0700274
275 // Some buffers are used internally. If they were configured with an
276 // invalid size or format, this will fail.
277 int result = hardware_composer_.OnNewGlobalBuffer(key, *ion_buffer.get());
278 if (result < 0)
279 return ErrorStatus(result);
Okan Arikan36d23802017-05-15 15:20:39 -0700280 global_buffer =
281 global_buffers_.insert(std::make_pair(key, std::move(ion_buffer)))
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700282 .first;
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700283 }
284
Okan Arikan36d23802017-05-15 15:20:39 -0700285 return {BorrowedNativeBufferHandle(*global_buffer->second, 0)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700286}
287
John Bates954796e2017-05-11 11:00:31 -0700288pdx::Status<void> DisplayService::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
289 auto global_buffer = global_buffers_.find(key);
290 if (global_buffer != global_buffers_.end()) {
291 // Some buffers are used internally.
292 hardware_composer_.OnDeletedGlobalBuffer(key);
293 global_buffers_.erase(global_buffer);
294 }
295
296 return {0};
297}
298
Steven Thomas3cfac282017-02-06 12:29:30 -0800299void DisplayService::OnHardwareComposerRefresh() {
300 hardware_composer_.OnHardwareComposerRefresh();
301}
302
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800303void DisplayService::SetDisplayConfigurationUpdateNotifier(
304 DisplayConfigurationUpdateNotifier update_notifier) {
305 update_notifier_ = update_notifier;
306}
307
308void DisplayService::NotifyDisplayConfigurationUpdate() {
309 if (update_notifier_)
310 update_notifier_();
311}
312
Corey Tabaka2251d822017-04-20 16:04:07 -0700313Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
Albert Chaulk356bc372017-04-05 18:01:58 -0400314 bool visible = false;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700315 ForEachDisplaySurface(
Corey Tabaka2251d822017-04-20 16:04:07 -0700316 SurfaceType::Application,
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700317 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700318 if (surface->visible())
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700319 visible = true;
320 });
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400321
Corey Tabaka2251d822017-04-20 16:04:07 -0700322 return {visible};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400323}
324
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800325} // namespace dvr
326} // namespace android