1 #include "include/private/dvr/display_client.h"
2
3 #include <cutils/native_handle.h>
4 #include <log/log.h>
5 #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
11 #include <private/dvr/display_protocol.h>
12
13 using android::pdx::ErrorStatus;
14 using android::pdx::LocalHandle;
15 using android::pdx::LocalChannelHandle;
16 using android::pdx::Status;
17 using android::pdx::Transaction;
18 using android::pdx::rpc::IfAnyOf;
19
20 namespace android {
21 namespace dvr {
22 namespace display {
23
Surface(LocalChannelHandle channel_handle,int * error)24 Surface::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",
30 status.GetErrorMessage().c_str());
31 Close(status.error());
32 if (error)
33 *error = status.error();
34 }
35
36 surface_id_ = status.get().surface_id;
37 z_order_ = status.get().z_order;
38 visible_ = status.get().visible;
39 }
40
Surface(const SurfaceAttributes & attributes,int * error)41 Surface::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;
57 }
58
SetVisible(bool visible)59 Status<void> Surface::SetVisible(bool visible) {
60 return SetAttributes(
61 {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
62 }
63
SetZOrder(int z_order)64 Status<void> Surface::SetZOrder(int z_order) {
65 return SetAttributes(
66 {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
67 }
68
SetAttributes(const SurfaceAttributes & attributes)69 Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
70 auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
71 if (!status) {
72 ALOGE(
73 "Surface::SetAttributes: Failed to set display surface "
74 "attributes: %s",
75 status.GetErrorMessage().c_str());
76 return status.error_status();
77 }
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) {
86 case SurfaceAttribute::Visible:
87 invalid_value =
88 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
89 break;
90 case SurfaceAttribute::ZOrder:
91 invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
92 break;
93 }
94
95 if (invalid_value) {
96 ALOGW(
97 "Surface::SetAttributes: Failed to set display surface "
98 "attribute %d because of incompatible type: %d",
99 key, variant->index());
100 }
101 }
102
103 return {};
104 }
105
CreateQueue(uint32_t width,uint32_t height,uint32_t format,size_t metadata_size)106 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
107 uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) {
108 ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
109 auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(
110 ProducerQueueConfigBuilder()
111 .SetDefaultWidth(width)
112 .SetDefaultHeight(height)
113 .SetDefaultFormat(format)
114 .SetMetadataSize(metadata_size)
115 .Build());
116 if (!status) {
117 ALOGE("Surface::CreateQueue: Failed to create queue: %s",
118 status.GetErrorMessage().c_str());
119 return status.error_status();
120 }
121
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
CreateQueue(uint32_t width,uint32_t height,uint32_t layer_count,uint32_t format,uint64_t usage,size_t capacity,size_t metadata_size)131 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
132 uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
133 uint64_t usage, size_t capacity, size_t metadata_size) {
134 ALOGD_IF(TRACE,
135 "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
136 "usage=%" PRIx64 " capacity=%zu",
137 width, height, layer_count, format, usage, capacity);
138 auto status = CreateQueue(width, height, format, metadata_size);
139 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);
145 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",
149 producer_queue->id(), allocate_status.GetErrorMessage().c_str());
150 return allocate_status.error_status();
151 }
152
153 return {std::move(producer_queue)};
154 }
155
DisplayClient(int * error)156 DisplayClient::DisplayClient(int* error)
157 : BASE(pdx::default_transport::ClientChannelFactory::Create(
158 DisplayProtocol::kClientPath),
159 kInfiniteTimeout) {
160 if (error)
161 *error = Client::error();
162 }
163
GetDisplayMetrics()164 Status<Metrics> DisplayClient::GetDisplayMetrics() {
165 return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
166 }
167
GetConfigurationData(ConfigFileType config_type)168 Status<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
CreateSurface(const SurfaceAttributes & attributes)181 Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
182 const SurfaceAttributes& attributes) {
183 int error;
184 if (auto client = Surface::Create(attributes, &error))
185 return {std::move(client)};
186 else
187 return ErrorStatus(error);
188 }
189
SetupGlobalBuffer(DvrGlobalBufferKey key,size_t size,uint64_t usage)190 pdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer(
191 DvrGlobalBufferKey key, size_t size, uint64_t usage) {
192 auto status =
193 InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage);
194 if (!status) {
195 ALOGE(
196 "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer "
197 "%s",
198 status.GetErrorMessage().c_str());
199 return status.error_status();
200 }
201
202 auto ion_buffer = std::make_unique<IonBuffer>();
203 auto native_buffer_handle = status.take();
204 const int ret = native_buffer_handle.Import(ion_buffer.get());
205 if (ret < 0) {
206 ALOGE(
207 "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
208 "key=%d; error=%s",
209 key, strerror(-ret));
210 return ErrorStatus(-ret);
211 }
212
213 return {std::move(ion_buffer)};
214 }
215
DeleteGlobalBuffer(DvrGlobalBufferKey key)216 pdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
217 auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key);
218 if (!status) {
219 ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s",
220 status.GetErrorMessage().c_str());
221 }
222
223 return status;
224 }
225
GetGlobalBuffer(DvrGlobalBufferKey key)226 Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer(
227 DvrGlobalBufferKey key) {
228 auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key);
229 if (!status) {
230 ALOGE(
231 "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; "
232 "error=%s",
233 key, status.GetErrorMessage().c_str());
234 return status.error_status();
235 }
236
237 auto ion_buffer = std::make_unique<IonBuffer>();
238 auto native_buffer_handle = status.take();
239 const int ret = native_buffer_handle.Import(ion_buffer.get());
240 if (ret < 0) {
241 ALOGE(
242 "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
243 "key=%d; error=%s",
244 key, strerror(-ret));
245 return ErrorStatus(-ret);
246 }
247
248 return {std::move(ion_buffer)};
249 }
250
IsVrAppRunning()251 Status<bool> DisplayClient::IsVrAppRunning() {
252 return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
253 }
254
255 } // namespace display
256 } // namespace dvr
257 } // namespace android
258