1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0 *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
15 #include "utils/include/Utils.h"
16 
17 #include <aidlcommonsupport/NativeHandle.h>
18 #include <android-base/logging.h>
19 #include <android/hardware_buffer.h>
20 
21 namespace aidl::android::automotive::evs::implementation {
22 
23 namespace hidlevs = ::android::hardware::automotive::evs;
24 
25 using ::aidl::android::hardware::automotive::evs::BufferDesc;
26 using ::aidl::android::hardware::automotive::evs::CameraDesc;
27 using ::aidl::android::hardware::automotive::evs::CameraParam;
28 using ::aidl::android::hardware::automotive::evs::DisplayDesc;
29 using ::aidl::android::hardware::automotive::evs::DisplayState;
30 using ::aidl::android::hardware::automotive::evs::EvsEventDesc;
31 using ::aidl::android::hardware::automotive::evs::EvsEventType;
32 using ::aidl::android::hardware::automotive::evs::EvsResult;
33 using ::aidl::android::hardware::automotive::evs::Rotation;
34 using ::aidl::android::hardware::automotive::evs::Stream;
35 using ::aidl::android::hardware::automotive::evs::StreamType;
36 using ::aidl::android::hardware::common::NativeHandle;
37 using ::aidl::android::hardware::graphics::common::BufferUsage;
38 using ::aidl::android::hardware::graphics::common::HardwareBuffer;
39 using ::aidl::android::hardware::graphics::common::HardwareBufferDescription;
40 using ::aidl::android::hardware::graphics::common::PixelFormat;
41 using ::android::hardware::Return;
42 using ::ndk::ScopedAStatus;
43 
44 using HIDLBufferUsage = ::android::hardware::graphics::common::V1_0::BufferUsage;
45 using HIDLHardwareBuffer = ::android::hardware::graphics::common::V1_2::HardwareBuffer;
46 using HIDLHardwareBufferDescription =
47         ::android::hardware::graphics::common::V1_2::HardwareBufferDescription;
48 using HIDLPixelFormat = ::android::hardware::graphics::common::V1_0::PixelFormat;
49 using HIDLStream = ::android::hardware::camera::device::V3_2::Stream;
50 using HIDLStreamType = ::android::hardware::camera::device::V3_2::StreamType;
51 using HIDLStreamRotation = ::android::hardware::camera::device::V3_2::StreamRotation;
52 
makeFromHidl(hidlevs::V1_0::DisplayState hidlState)53 DisplayState Utils::makeFromHidl(hidlevs::V1_0::DisplayState hidlState) {
54     switch (hidlState) {
55         case hidlevs::V1_0::DisplayState::NOT_OPEN:
56             return DisplayState::NOT_OPEN;
57         case hidlevs::V1_0::DisplayState::NOT_VISIBLE:
58             return DisplayState::NOT_VISIBLE;
59         case hidlevs::V1_0::DisplayState::VISIBLE_ON_NEXT_FRAME:
60             return DisplayState::VISIBLE_ON_NEXT_FRAME;
61         case hidlevs::V1_0::DisplayState::VISIBLE:
62             return DisplayState::VISIBLE;
63         case hidlevs::V1_0::DisplayState::DEAD:
64             [[fallthrough]];
65         default:
66             return DisplayState::DEAD;
67     }
68 }
69 
makeToHidl(DisplayState aidlState)70 hidlevs::V1_0::DisplayState Utils::makeToHidl(DisplayState aidlState) {
71     switch (aidlState) {
72         case DisplayState::NOT_OPEN:
73             return hidlevs::V1_0::DisplayState::NOT_OPEN;
74         case DisplayState::NOT_VISIBLE:
75             return hidlevs::V1_0::DisplayState::NOT_VISIBLE;
76         case DisplayState::VISIBLE_ON_NEXT_FRAME:
77             return hidlevs::V1_0::DisplayState::VISIBLE_ON_NEXT_FRAME;
78         case DisplayState::VISIBLE:
79             return hidlevs::V1_0::DisplayState::VISIBLE;
80         case DisplayState::DEAD:
81             [[fallthrough]];
82         default:
83             return hidlevs::V1_0::DisplayState::DEAD;
84     }
85 }
86 
makeHwBufferFromHidlBuffer(const hidlevs::V1_0::BufferDesc & hidlBuffer,bool doDup)87 HardwareBuffer Utils::makeHwBufferFromHidlBuffer(const hidlevs::V1_0::BufferDesc& hidlBuffer,
88                                                  bool doDup) {
89     buffer_handle_t h = hidlBuffer.memHandle.getNativeHandle();
90     if (h == nullptr) {
91         LOG(WARNING) << "Buffer " << hidlBuffer.bufferId << " has an invalid native handle.";
92         return {};
93     }
94 
95     HardwareBuffer hwBuffer = {
96             .description =
97                     {
98                             .width = static_cast<int>(hidlBuffer.width),
99                             .height = static_cast<int>(hidlBuffer.height),
100                             .layers = 1,
101                             .format = static_cast<PixelFormat>(hidlBuffer.format),
102                             .usage = static_cast<BufferUsage>(hidlBuffer.usage),
103                             .stride = static_cast<int>(hidlBuffer.stride),
104                     },
105             .handle = doDup ? ::android::dupToAidl(h) : ::android::makeToAidl(h),
106     };
107 
108     return hwBuffer;
109 }
110 
makeFromHidl(const HIDLHardwareBuffer & hidlBuffer)111 HardwareBufferDescription Utils::makeFromHidl(const HIDLHardwareBuffer& hidlBuffer) {
112     const AHardwareBuffer_Desc* pSrc =
113             reinterpret_cast<const AHardwareBuffer_Desc*>(hidlBuffer.description.data());
114     HardwareBufferDescription desc = {
115             .width = static_cast<int>(pSrc->width),
116             .height = static_cast<int>(pSrc->height),
117             .layers = static_cast<int>(pSrc->layers),
118             .format = static_cast<PixelFormat>(pSrc->format),
119             .usage = static_cast<BufferUsage>(pSrc->usage),
120             .stride = static_cast<int>(pSrc->stride),
121     };
122 
123     return desc;
124 }
125 
makeHwBufferFromHidlBuffer(const hidlevs::V1_1::BufferDesc & hidlBuffer,bool doDup)126 HardwareBuffer Utils::makeHwBufferFromHidlBuffer(const hidlevs::V1_1::BufferDesc& hidlBuffer,
127                                                  bool doDup) {
128     buffer_handle_t h = hidlBuffer.buffer.nativeHandle.getNativeHandle();
129     if (h == nullptr) {
130         LOG(WARNING) << "Buffer " << hidlBuffer.bufferId << " has an invalid native handle.";
131         return {};
132     }
133 
134     HardwareBuffer hwBuffer = {
135             .description = makeFromHidl(hidlBuffer.buffer),
136             .handle = doDup ? std::move(::android::dupToAidl(h))
137                             : std::move(::android::makeToAidl(h)),
138     };
139 
140     return hwBuffer;
141 }
142 
makeFromHidl(const hidlevs::V1_0::BufferDesc & hidlBuffer,bool doDup)143 BufferDesc Utils::makeFromHidl(const hidlevs::V1_0::BufferDesc& hidlBuffer, bool doDup) {
144     BufferDesc aidlBuffer = {
145             .buffer = Utils::makeHwBufferFromHidlBuffer(hidlBuffer, doDup),
146             .pixelSizeBytes = static_cast<int>(hidlBuffer.pixelSize),
147             .bufferId = static_cast<int>(hidlBuffer.bufferId),
148             // EVS v1.0 BufferDesc does not contain deviceId, timestamp, and
149             // metadata.
150     };
151 
152     return aidlBuffer;
153 }
154 
makeFromHidl(const hidlevs::V1_1::BufferDesc & hidlBuffer,bool doDup)155 BufferDesc Utils::makeFromHidl(const hidlevs::V1_1::BufferDesc& hidlBuffer, bool doDup) {
156     BufferDesc aidlBuffer = {
157             .buffer = Utils::makeHwBufferFromHidlBuffer(hidlBuffer, doDup),
158             .pixelSizeBytes = static_cast<int>(hidlBuffer.pixelSize),
159             .bufferId = static_cast<int>(hidlBuffer.bufferId),
160             .deviceId = hidlBuffer.deviceId,
161             .timestamp = hidlBuffer.timestamp,
162             .metadata = hidlBuffer.metadata,
163     };
164 
165     return aidlBuffer;
166 }
167 
makeToHidl(const HardwareBufferDescription & aidlDesc)168 HIDLHardwareBufferDescription Utils::makeToHidl(const HardwareBufferDescription& aidlDesc) {
169     HIDLHardwareBufferDescription hidlDesc;
170     AHardwareBuffer_Desc* pDesc = reinterpret_cast<AHardwareBuffer_Desc*>(hidlDesc.data());
171     pDesc->width = aidlDesc.width;
172     pDesc->height = aidlDesc.height;
173     pDesc->layers = aidlDesc.layers;
174     pDesc->format = static_cast<uint32_t>(aidlDesc.format);
175     pDesc->usage = static_cast<uint64_t>(aidlDesc.usage);
176     pDesc->stride = aidlDesc.stride;
177 
178     return hidlDesc;
179 }
180 
makeToHidl(const HardwareBuffer & aidlBuffer,bool doDup)181 HIDLHardwareBuffer Utils::makeToHidl(const HardwareBuffer& aidlBuffer, bool doDup) {
182     HIDLHardwareBuffer hidlBuffer = {
183             .description = makeToHidl(aidlBuffer.description),
184             .nativeHandle = doDup ? ::android::dupFromAidl(aidlBuffer.handle)
185                                   : ::android::makeFromAidl(aidlBuffer.handle),
186     };
187 
188     return hidlBuffer;
189 }
190 
makeToHidlV1_0(const BufferDesc & aidlBuffer,bool doDup)191 hidlevs::V1_0::BufferDesc Utils::makeToHidlV1_0(const BufferDesc& aidlBuffer, bool doDup) {
192     hidlevs::V1_0::BufferDesc hidlBuffer = {
193             .width = static_cast<uint32_t>(aidlBuffer.buffer.description.width),
194             .height = static_cast<uint32_t>(aidlBuffer.buffer.description.height),
195             .stride = static_cast<uint32_t>(aidlBuffer.buffer.description.stride),
196             .pixelSize = static_cast<uint32_t>(aidlBuffer.pixelSizeBytes),
197             .format = static_cast<uint32_t>(aidlBuffer.buffer.description.format),
198             .usage = static_cast<uint32_t>(aidlBuffer.buffer.description.usage),
199             .bufferId = static_cast<uint32_t>(aidlBuffer.bufferId),
200             .memHandle = doDup ? ::android::dupFromAidl(aidlBuffer.buffer.handle)
201                                : ::android::makeFromAidl(aidlBuffer.buffer.handle),
202     };
203 
204     return hidlBuffer;
205 }
206 
makeToHidlV1_1(const BufferDesc & aidlBuffer,bool doDup)207 hidlevs::V1_1::BufferDesc Utils::makeToHidlV1_1(const BufferDesc& aidlBuffer, bool doDup) {
208     hidlevs::V1_1::BufferDesc hidlBuffer = {
209             .buffer = Utils::makeToHidl(aidlBuffer.buffer, doDup),
210             .pixelSize = static_cast<uint32_t>(aidlBuffer.pixelSizeBytes),
211             .bufferId = static_cast<uint32_t>(aidlBuffer.bufferId),
212             .deviceId = aidlBuffer.deviceId,
213             .timestamp = aidlBuffer.timestamp,
214             .metadata = aidlBuffer.metadata,
215     };
216 
217     return hidlBuffer;
218 }
219 
makeFromHidl(hidlevs::V1_0::EvsResult result)220 EvsResult Utils::makeFromHidl(hidlevs::V1_0::EvsResult result) {
221     switch (result) {
222         case hidlevs::V1_0::EvsResult::OK:
223             return EvsResult::OK;
224         case hidlevs::V1_0::EvsResult::INVALID_ARG:
225             return EvsResult::INVALID_ARG;
226         case hidlevs::V1_0::EvsResult::STREAM_ALREADY_RUNNING:
227             return EvsResult::STREAM_ALREADY_RUNNING;
228         case hidlevs::V1_0::EvsResult::BUFFER_NOT_AVAILABLE:
229             return EvsResult::BUFFER_NOT_AVAILABLE;
230         case hidlevs::V1_0::EvsResult::OWNERSHIP_LOST:
231             return EvsResult::OWNERSHIP_LOST;
232         case hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR:
233             [[fallthrough]];
234         default:
235             return EvsResult::UNDERLYING_SERVICE_ERROR;
236     }
237 }
238 
makeToHidl(EvsResult result)239 hidlevs::V1_0::EvsResult Utils::makeToHidl(EvsResult result) {
240     switch (result) {
241         case EvsResult::OK:
242             return hidlevs::V1_0::EvsResult::OK;
243         case EvsResult::INVALID_ARG:
244             return hidlevs::V1_0::EvsResult::INVALID_ARG;
245         case EvsResult::STREAM_ALREADY_RUNNING:
246             return hidlevs::V1_0::EvsResult::STREAM_ALREADY_RUNNING;
247         case EvsResult::BUFFER_NOT_AVAILABLE:
248             return hidlevs::V1_0::EvsResult::BUFFER_NOT_AVAILABLE;
249         case EvsResult::OWNERSHIP_LOST:
250             return hidlevs::V1_0::EvsResult::OWNERSHIP_LOST;
251         default:
252             LOG(WARNING) << "Received " << toString(result)
253                          << ", which is not recognized by EVS HIDL version";
254             return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
255     }
256 }
257 
makeFromHidl(const hidlevs::V1_0::CameraDesc & hidlDesc)258 CameraDesc Utils::makeFromHidl(const hidlevs::V1_0::CameraDesc& hidlDesc) {
259     CameraDesc aidlDesc = {
260             .id = hidlDesc.cameraId,
261             .vendorFlags = static_cast<int32_t>(hidlDesc.vendorFlags),
262     };
263 
264     return aidlDesc;
265 }
266 
makeFromHidl(const hidlevs::V1_1::CameraDesc & hidlDesc)267 CameraDesc Utils::makeFromHidl(const hidlevs::V1_1::CameraDesc& hidlDesc) {
268     CameraDesc aidlDesc = {
269             .id = hidlDesc.v1.cameraId,
270             .vendorFlags = static_cast<int32_t>(hidlDesc.v1.vendorFlags),
271             .metadata = hidlDesc.metadata,
272     };
273 
274     return aidlDesc;
275 }
276 
makeToHidlV1_0(const CameraDesc & aidlDesc)277 hidlevs::V1_0::CameraDesc Utils::makeToHidlV1_0(const CameraDesc& aidlDesc) {
278     hidlevs::V1_0::CameraDesc hidlDesc = {
279             .cameraId = aidlDesc.id,
280             .vendorFlags = static_cast<uint32_t>(aidlDesc.vendorFlags),
281     };
282 
283     return hidlDesc;
284 }
285 
makeToHidlV1_1(const CameraDesc & aidlDesc)286 hidlevs::V1_1::CameraDesc Utils::makeToHidlV1_1(const CameraDesc& aidlDesc) {
287     hidlevs::V1_1::CameraDesc hidlDesc = {
288             .v1 =
289                     {
290                             .cameraId = aidlDesc.id,
291                             .vendorFlags = static_cast<uint32_t>(aidlDesc.vendorFlags),
292                     },
293     };
294 
295     if (!aidlDesc.metadata.empty()) {
296         const auto n = aidlDesc.metadata.size() * sizeof(decltype(aidlDesc.metadata)::value_type);
297         hidlDesc.metadata.resize(n);
298         memcpy(hidlDesc.metadata.data(), aidlDesc.metadata.data(), n);
299     }
300 
301     return hidlDesc;
302 }
303 
makeToHidl(CameraParam id)304 hidlevs::V1_1::CameraParam Utils::makeToHidl(CameraParam id) {
305     switch (id) {
306         case CameraParam::BRIGHTNESS:
307             return hidlevs::V1_1::CameraParam::BRIGHTNESS;
308         case CameraParam::CONTRAST:
309             return hidlevs::V1_1::CameraParam::CONTRAST;
310         case CameraParam::AUTOGAIN:
311             return hidlevs::V1_1::CameraParam::AUTOGAIN;
312         case CameraParam::GAIN:
313             return hidlevs::V1_1::CameraParam::GAIN;
314         case CameraParam::AUTO_WHITE_BALANCE:
315             return hidlevs::V1_1::CameraParam::AUTO_WHITE_BALANCE;
316         case CameraParam::WHITE_BALANCE_TEMPERATURE:
317             return hidlevs::V1_1::CameraParam::WHITE_BALANCE_TEMPERATURE;
318         case CameraParam::SHARPNESS:
319             return hidlevs::V1_1::CameraParam::SHARPNESS;
320         case CameraParam::AUTO_EXPOSURE:
321             return hidlevs::V1_1::CameraParam::AUTO_EXPOSURE;
322         case CameraParam::ABSOLUTE_EXPOSURE:
323             return hidlevs::V1_1::CameraParam::ABSOLUTE_EXPOSURE;
324         case CameraParam::ABSOLUTE_FOCUS:
325             return hidlevs::V1_1::CameraParam::ABSOLUTE_FOCUS;
326         case CameraParam::AUTO_FOCUS:
327             return hidlevs::V1_1::CameraParam::AUTO_FOCUS;
328         case CameraParam::ABSOLUTE_ZOOM:
329             return hidlevs::V1_1::CameraParam::ABSOLUTE_ZOOM;
330     }
331 }
332 
makeFromHidl(hidlevs::V1_1::CameraParam id)333 CameraParam Utils::makeFromHidl(hidlevs::V1_1::CameraParam id) {
334     switch (id) {
335         case hidlevs::V1_1::CameraParam::BRIGHTNESS:
336             return CameraParam::BRIGHTNESS;
337         case hidlevs::V1_1::CameraParam::CONTRAST:
338             return CameraParam::CONTRAST;
339         case hidlevs::V1_1::CameraParam::AUTOGAIN:
340             return CameraParam::AUTOGAIN;
341         case hidlevs::V1_1::CameraParam::GAIN:
342             return CameraParam::GAIN;
343         case hidlevs::V1_1::CameraParam::AUTO_WHITE_BALANCE:
344             return CameraParam::AUTO_WHITE_BALANCE;
345         case hidlevs::V1_1::CameraParam::WHITE_BALANCE_TEMPERATURE:
346             return CameraParam::WHITE_BALANCE_TEMPERATURE;
347         case hidlevs::V1_1::CameraParam::SHARPNESS:
348             return CameraParam::SHARPNESS;
349         case hidlevs::V1_1::CameraParam::AUTO_EXPOSURE:
350             return CameraParam::AUTO_EXPOSURE;
351         case hidlevs::V1_1::CameraParam::ABSOLUTE_EXPOSURE:
352             return CameraParam::ABSOLUTE_EXPOSURE;
353         case hidlevs::V1_1::CameraParam::ABSOLUTE_FOCUS:
354             return CameraParam::ABSOLUTE_FOCUS;
355         case hidlevs::V1_1::CameraParam::AUTO_FOCUS:
356             return CameraParam::AUTO_FOCUS;
357         case hidlevs::V1_1::CameraParam::ABSOLUTE_ZOOM:
358             return CameraParam::ABSOLUTE_ZOOM;
359     }
360 }
361 
makeFromHidl(const hidlevs::V1_0::DisplayDesc & hidlDesc)362 DisplayDesc Utils::makeFromHidl(const hidlevs::V1_0::DisplayDesc& hidlDesc) {
363     DisplayDesc aidlDesc = {
364             .id = hidlDesc.displayId,
365             .vendorFlags = static_cast<int>(hidlDesc.vendorFlags),
366     };
367 
368     return aidlDesc;
369 }
370 
makeFromHidl(const HIDLStream & config)371 Stream Utils::makeFromHidl(const HIDLStream& config) {
372     Stream aidlStreamConfig = {
373             .id = config.id,
374             .streamType = makeFromHidl(config.streamType),
375             .width = static_cast<int32_t>(config.width),
376             .height = static_cast<int32_t>(config.height),
377             .format = static_cast<PixelFormat>(config.format),
378             .usage = static_cast<BufferUsage>(config.usage),
379             .rotation = makeFromHidl(config.rotation),
380     };
381 
382     return aidlStreamConfig;
383 }
384 
makeFromHidl(HIDLStreamType hidlType)385 StreamType Utils::makeFromHidl(HIDLStreamType hidlType) {
386     switch (hidlType) {
387         case HIDLStreamType::OUTPUT:
388             return StreamType::OUTPUT;
389         case HIDLStreamType::INPUT:
390             return StreamType::INPUT;
391     }
392 }
393 
makeFromHidl(HIDLStreamRotation hidlRotation)394 Rotation Utils::makeFromHidl(HIDLStreamRotation hidlRotation) {
395     switch (hidlRotation) {
396         case HIDLStreamRotation::ROTATION_0:
397             return Rotation::ROTATION_0;
398         case HIDLStreamRotation::ROTATION_90:
399             return Rotation::ROTATION_90;
400         case HIDLStreamRotation::ROTATION_180:
401             return Rotation::ROTATION_180;
402         case HIDLStreamRotation::ROTATION_270:
403             return Rotation::ROTATION_270;
404     }
405 }
406 
makeToHidl(StreamType aidlType)407 HIDLStreamType Utils::makeToHidl(StreamType aidlType) {
408     switch (aidlType) {
409         case StreamType::OUTPUT:
410             return HIDLStreamType::OUTPUT;
411         case StreamType::INPUT:
412             return HIDLStreamType::INPUT;
413     }
414 }
415 
makeToHidl(Rotation aidlRotation)416 HIDLStreamRotation Utils::makeToHidl(Rotation aidlRotation) {
417     switch (aidlRotation) {
418         case Rotation::ROTATION_0:
419             return HIDLStreamRotation::ROTATION_0;
420         case Rotation::ROTATION_90:
421             return HIDLStreamRotation::ROTATION_90;
422         case Rotation::ROTATION_180:
423             return HIDLStreamRotation::ROTATION_180;
424         case Rotation::ROTATION_270:
425             return HIDLStreamRotation::ROTATION_270;
426     }
427 }
428 
makeToHidl(const::aidl::android::hardware::automotive::evs::Stream & config)429 ::android::hardware::camera::device::V3_2::Stream Utils::makeToHidl(
430         const ::aidl::android::hardware::automotive::evs::Stream& config) {
431     HIDLStream hidlStreamConfig = {
432             .id = config.id,
433             .streamType = makeToHidl(config.streamType),
434             .width = static_cast<uint32_t>(config.width),
435             .height = static_cast<uint32_t>(config.height),
436             .format = static_cast<HIDLPixelFormat>(config.format),
437             .usage = static_cast<::android::hardware::hidl_bitfield<HIDLBufferUsage>>(config.usage),
438             // dataSpace is opaque to EVS and therefore we don't fill it.
439             .rotation = makeToHidl(config.rotation),
440     };
441 
442     return hidlStreamConfig;
443 }
444 
makeFromHidl(const hidlevs::V1_1::EvsEventType & hidlType)445 EvsEventType Utils::makeFromHidl(const hidlevs::V1_1::EvsEventType& hidlType) {
446     switch (hidlType) {
447         case hidlevs::V1_1::EvsEventType::STREAM_STARTED:
448             return EvsEventType::STREAM_STARTED;
449         case hidlevs::V1_1::EvsEventType::STREAM_STOPPED:
450             return EvsEventType::STREAM_STOPPED;
451         case hidlevs::V1_1::EvsEventType::FRAME_DROPPED:
452             return EvsEventType::FRAME_DROPPED;
453         case hidlevs::V1_1::EvsEventType::TIMEOUT:
454             return EvsEventType::TIMEOUT;
455         case hidlevs::V1_1::EvsEventType::PARAMETER_CHANGED:
456             return EvsEventType::PARAMETER_CHANGED;
457         case hidlevs::V1_1::EvsEventType::MASTER_RELEASED:
458             return EvsEventType::MASTER_RELEASED;
459         case hidlevs::V1_1::EvsEventType::STREAM_ERROR:
460             return EvsEventType::STREAM_ERROR;
461     }
462 }
463 
makeToHidl(const EvsEventType & aidlType)464 hidlevs::V1_1::EvsEventType Utils::makeToHidl(const EvsEventType& aidlType) {
465     switch (aidlType) {
466         case EvsEventType::STREAM_STARTED:
467             return hidlevs::V1_1::EvsEventType::STREAM_STARTED;
468         case EvsEventType::STREAM_STOPPED:
469             return hidlevs::V1_1::EvsEventType::STREAM_STOPPED;
470         case EvsEventType::FRAME_DROPPED:
471             return hidlevs::V1_1::EvsEventType::FRAME_DROPPED;
472         case EvsEventType::TIMEOUT:
473             return hidlevs::V1_1::EvsEventType::TIMEOUT;
474         case EvsEventType::PARAMETER_CHANGED:
475             return hidlevs::V1_1::EvsEventType::PARAMETER_CHANGED;
476         case EvsEventType::MASTER_RELEASED:
477             return hidlevs::V1_1::EvsEventType::MASTER_RELEASED;
478         case EvsEventType::STREAM_ERROR:
479             return hidlevs::V1_1::EvsEventType::STREAM_ERROR;
480     }
481 }
482 
makeFromHidl(const hidlevs::V1_1::EvsEventDesc & hidlDesc)483 EvsEventDesc Utils::makeFromHidl(const hidlevs::V1_1::EvsEventDesc& hidlDesc) {
484     EvsEventDesc aidlDesc = {
485             .aType = makeFromHidl(hidlDesc.aType),
486             .deviceId = hidlDesc.deviceId,
487     };
488 
489     for (auto i = 0; i < hidlDesc.payload.size(); ++i) {
490         aidlDesc.payload.push_back(hidlDesc.payload[i]);
491     }
492 
493     return aidlDesc;
494 }
495 
makeToHidl(const EvsEventDesc & in,hidlevs::V1_1::EvsEventDesc * out)496 bool Utils::makeToHidl(const EvsEventDesc& in, hidlevs::V1_1::EvsEventDesc* out) {
497     if (in.payload.size() > out->payload.size()) {
498         LOG(ERROR) << "The size of the event payload must not exceed "
499                    << out->payload.size() * sizeof(out->payload[0]) << " bytes.";
500 
501         return false;
502     }
503 
504     out->aType = makeToHidl(in.aType);
505     out->deviceId = in.deviceId;
506 
507     for (int i = 0; i < in.payload.size(); ++i) {
508         out->payload[i] = in.payload[i];
509     }
510 
511     return true;
512 }
513 
validateNativeHandle(const NativeHandle & handle)514 bool Utils::validateNativeHandle(const NativeHandle& handle) {
515     return handle.fds.size() > 0 && handle.ints.size() > 0 &&
516             std::all_of(handle.fds.begin(), handle.fds.end(),
517                         [](const ::ndk::ScopedFileDescriptor& fd) { return fd.get() > 0; });
518 }
519 
dupNativeHandle(const NativeHandle & handle,bool doDup)520 NativeHandle Utils::dupNativeHandle(const NativeHandle& handle, bool doDup) {
521     NativeHandle dup;
522 
523     dup.fds = std::vector<::ndk::ScopedFileDescriptor>(handle.fds.size());
524     if (!doDup) {
525         for (auto i = 0; i < handle.fds.size(); ++i) {
526             dup.fds.at(i).set(handle.fds[i].get());
527         }
528     } else {
529         for (auto i = 0; i < handle.fds.size(); ++i) {
530             dup.fds[i] = handle.fds[i].dup();
531         }
532     }
533     dup.ints = handle.ints;
534 
535     return dup;
536 }
537 
dupHardwareBuffer(const HardwareBuffer & buffer,bool doDup)538 HardwareBuffer Utils::dupHardwareBuffer(const HardwareBuffer& buffer, bool doDup) {
539     HardwareBuffer dup = {
540             .description = buffer.description,
541             .handle = dupNativeHandle(buffer.handle, doDup),
542     };
543 
544     return dup;
545 }
546 
dupBufferDesc(const BufferDesc & src,bool doDup)547 BufferDesc Utils::dupBufferDesc(const BufferDesc& src, bool doDup) {
548     BufferDesc dup = {
549             .buffer = dupHardwareBuffer(src.buffer, doDup),
550             .pixelSizeBytes = src.pixelSizeBytes,
551             .bufferId = src.bufferId,
552             .deviceId = src.deviceId,
553             .timestamp = src.timestamp,
554             .metadata = src.metadata,
555     };
556 
557     return dup;
558 }
559 
buildScopedAStatusFromEvsResult(EvsResult result)560 ScopedAStatus Utils::buildScopedAStatusFromEvsResult(EvsResult result) {
561     if (result != EvsResult::OK) {
562         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(result));
563     } else {
564         return ScopedAStatus::ok();
565     }
566 }
567 
buildScopedAStatusFromEvsResult(hidlevs::V1_0::EvsResult result)568 ScopedAStatus Utils::buildScopedAStatusFromEvsResult(hidlevs::V1_0::EvsResult result) {
569     if (result != hidlevs::V1_0::EvsResult::OK) {
570         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(makeFromHidl(result)));
571     } else {
572         return ScopedAStatus::ok();
573     }
574 }
575 
buildScopedAStatusFromEvsResult(Return<hidlevs::V1_0::EvsResult> & result)576 ScopedAStatus Utils::buildScopedAStatusFromEvsResult(Return<hidlevs::V1_0::EvsResult>& result) {
577     if (!result.isOk()) {
578         return ScopedAStatus::fromServiceSpecificError(
579                 static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
580     }
581 
582     return Utils::buildScopedAStatusFromEvsResult(static_cast<hidlevs::V1_0::EvsResult>(result));
583 }
584 
585 }  // namespace aidl::android::automotive::evs::implementation
586