blob: 62856dfbf857ed241379a73fa5f10c8e227a8b88 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "include/private/dvr/display_client.h"
2
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <cutils/native_handle.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -08004#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#include <pdx/default_transport/client_channel.h>
6#include <pdx/default_transport/client_channel_factory.h>
7#include <pdx/status.h>
8
9#include <mutex>
10
Corey Tabaka3f82d312017-04-20 14:42:08 -070011#include <private/dvr/display_protocol.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080012
Corey Tabaka2251d822017-04-20 16:04:07 -070013using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080014using android::pdx::LocalHandle;
15using android::pdx::LocalChannelHandle;
16using android::pdx::Status;
17using android::pdx::Transaction;
18using android::pdx::rpc::IfAnyOf;
19
20namespace android {
21namespace dvr {
Corey Tabaka2251d822017-04-20 16:04:07 -070022namespace display {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080023
Corey Tabaka2251d822017-04-20 16:04:07 -070024Surface::Surface(LocalChannelHandle channel_handle, int* error)
25 : BASE{pdx::default_transport::ClientChannel::Create(
26 std::move(channel_handle))} {
27 auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
28 if (!status) {
29 ALOGE("Surface::Surface: Failed to get surface info: %s",
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080030 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080031 Close(status.error());
Corey Tabaka2251d822017-04-20 16:04:07 -070032 if (error)
33 *error = status.error();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034 }
Corey Tabaka2251d822017-04-20 16:04:07 -070035
36 surface_id_ = status.get().surface_id;
37 z_order_ = status.get().z_order;
38 visible_ = status.get().visible;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080039}
40
Corey Tabaka2251d822017-04-20 16:04:07 -070041Surface::Surface(const SurfaceAttributes& attributes, int* error)
42 : BASE{pdx::default_transport::ClientChannelFactory::Create(
43 DisplayProtocol::kClientPath),
44 kInfiniteTimeout} {
45 auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
46 if (!status) {
47 ALOGE("Surface::Surface: Failed to create display surface: %s",
48 status.GetErrorMessage().c_str());
49 Close(status.error());
50 if (error)
51 *error = status.error();
52 }
53
54 surface_id_ = status.get().surface_id;
55 z_order_ = status.get().z_order;
56 visible_ = status.get().visible;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057}
58
Corey Tabaka2251d822017-04-20 16:04:07 -070059Status<void> Surface::SetVisible(bool visible) {
60 return SetAttributes(
61 {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062}
63
Corey Tabaka2251d822017-04-20 16:04:07 -070064Status<void> Surface::SetZOrder(int z_order) {
65 return SetAttributes(
66 {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080067}
68
Corey Tabaka2251d822017-04-20 16:04:07 -070069Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
70 auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080071 if (!status) {
72 ALOGE(
Corey Tabaka2251d822017-04-20 16:04:07 -070073 "Surface::SetAttributes: Failed to set display surface "
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080074 "attributes: %s",
75 status.GetErrorMessage().c_str());
Corey Tabaka2251d822017-04-20 16:04:07 -070076 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080077 }
78
79 // Set the local cached copies of the attributes we care about from the full
80 // set of attributes sent to the display service.
81 for (const auto& attribute : attributes) {
82 const auto& key = attribute.first;
83 const auto* variant = &attribute.second;
84 bool invalid_value = false;
85 switch (key) {
Corey Tabaka2251d822017-04-20 16:04:07 -070086 case SurfaceAttribute::Visible:
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087 invalid_value =
88 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
89 break;
Corey Tabaka2251d822017-04-20 16:04:07 -070090 case SurfaceAttribute::ZOrder:
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080091 invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
92 break;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080093 }
94
95 if (invalid_value) {
96 ALOGW(
Corey Tabaka2251d822017-04-20 16:04:07 -070097 "Surface::SetAttributes: Failed to set display surface "
98 "attribute %d because of incompatible type: %d",
99 key, variant->index());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800100 }
101 }
102
Corey Tabaka2251d822017-04-20 16:04:07 -0700103 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800104}
105
Corey Tabaka99c2d732017-06-07 17:54:33 -0700106Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
107 uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700108 ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -0700109 auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(
110 ProducerQueueConfigBuilder()
111 .SetDefaultWidth(width)
112 .SetDefaultHeight(height)
113 .SetDefaultFormat(format)
Jiwen 'Steve' Cai532e5292017-06-02 15:36:44 -0700114 .SetMetadataSize(metadata_size)
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -0700115 .Build());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800116 if (!status) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700117 ALOGE("Surface::CreateQueue: Failed to create queue: %s",
118 status.GetErrorMessage().c_str());
119 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800120 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700121
122 auto producer_queue = ProducerQueue::Import(status.take());
123 if (!producer_queue) {
124 ALOGE("Surface::CreateQueue: Failed to import producer queue!");
125 return ErrorStatus(ENOMEM);
126 }
127
128 return {std::move(producer_queue)};
129}
130
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700131Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
132 uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
Jiwen 'Steve' Cai532e5292017-06-02 15:36:44 -0700133 uint64_t usage, size_t capacity, size_t metadata_size) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700134 ALOGD_IF(TRACE,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700135 "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
136 "usage=%" PRIx64 " capacity=%zu",
137 width, height, layer_count, format, usage, capacity);
Jiwen 'Steve' Cai532e5292017-06-02 15:36:44 -0700138 auto status = CreateQueue(width, height, format, metadata_size);
Corey Tabaka2251d822017-04-20 16:04:07 -0700139 if (!status)
140 return status.error_status();
141
142 auto producer_queue = status.take();
143
144 ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
Jiwen 'Steve' Cai8fa4e102017-05-24 23:16:54 -0700145 auto allocate_status = producer_queue->AllocateBuffers(
146 width, height, layer_count, format, usage, capacity);
147 if (!allocate_status) {
148 ALOGE("Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700149 producer_queue->id(), allocate_status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai8fa4e102017-05-24 23:16:54 -0700150 return allocate_status.error_status();
Corey Tabaka2251d822017-04-20 16:04:07 -0700151 }
152
153 return {std::move(producer_queue)};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800154}
155
156DisplayClient::DisplayClient(int* error)
157 : BASE(pdx::default_transport::ClientChannelFactory::Create(
Corey Tabaka2251d822017-04-20 16:04:07 -0700158 DisplayProtocol::kClientPath),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800159 kInfiniteTimeout) {
160 if (error)
161 *error = Client::error();
162}
163
Corey Tabaka2251d822017-04-20 16:04:07 -0700164Status<Metrics> DisplayClient::GetDisplayMetrics() {
165 return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166}
167
Hendrik Wagenaarbcb03d02017-05-23 14:59:08 -0700168Status<std::string> DisplayClient::GetConfigurationData(
169 ConfigFileType config_type) {
170 auto status =
171 InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type);
172 if (!status && status.error() != ENOENT) {
173 ALOGE(
174 "DisplayClient::GetConfigurationData: Unable to get"
175 "configuration data. Error: %s",
176 status.GetErrorMessage().c_str());
177 }
178 return status;
179}
180
mamik94e91f62019-08-19 09:11:33 -0700181Status<uint8_t> DisplayClient::GetDisplayIdentificationPort() {
182 return InvokeRemoteMethod<DisplayProtocol::GetDisplayIdentificationPort>();
183}
184
Corey Tabaka2251d822017-04-20 16:04:07 -0700185Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
186 const SurfaceAttributes& attributes) {
187 int error;
188 if (auto client = Surface::Create(attributes, &error))
189 return {std::move(client)};
190 else
191 return ErrorStatus(error);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800192}
193
Corey Tabaka99c2d732017-06-07 17:54:33 -0700194pdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer(
195 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
196 auto status =
197 InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage);
198 if (!status) {
199 ALOGE(
200 "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer "
201 "%s",
202 status.GetErrorMessage().c_str());
203 return status.error_status();
204 }
205
206 auto ion_buffer = std::make_unique<IonBuffer>();
207 auto native_buffer_handle = status.take();
208 const int ret = native_buffer_handle.Import(ion_buffer.get());
209 if (ret < 0) {
210 ALOGE(
211 "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
212 "key=%d; error=%s",
213 key, strerror(-ret));
214 return ErrorStatus(-ret);
215 }
216
217 return {std::move(ion_buffer)};
218}
219
220pdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
221 auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key);
222 if (!status) {
223 ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s",
224 status.GetErrorMessage().c_str());
225 }
226
227 return status;
228}
229
Okan Arikan36d23802017-05-15 15:20:39 -0700230Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer(
231 DvrGlobalBufferKey key) {
232 auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key);
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700233 if (!status) {
234 ALOGE(
Okan Arikan36d23802017-05-15 15:20:39 -0700235 "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; "
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700236 "error=%s",
Okan Arikan36d23802017-05-15 15:20:39 -0700237 key, status.GetErrorMessage().c_str());
Corey Tabaka2251d822017-04-20 16:04:07 -0700238 return status.error_status();
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700239 }
240
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700241 auto ion_buffer = std::make_unique<IonBuffer>();
Corey Tabaka2251d822017-04-20 16:04:07 -0700242 auto native_buffer_handle = status.take();
243 const int ret = native_buffer_handle.Import(ion_buffer.get());
244 if (ret < 0) {
245 ALOGE(
Okan Arikan36d23802017-05-15 15:20:39 -0700246 "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
247 "key=%d; error=%s",
248 key, strerror(-ret));
Corey Tabaka2251d822017-04-20 16:04:07 -0700249 return ErrorStatus(-ret);
250 }
251
252 return {std::move(ion_buffer)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700253}
254
Corey Tabaka2251d822017-04-20 16:04:07 -0700255Status<bool> DisplayClient::IsVrAppRunning() {
256 return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400257}
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700258
Corey Tabaka2251d822017-04-20 16:04:07 -0700259} // namespace display
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800260} // namespace dvr
261} // namespace android