1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "HidlCamera.h"
18 
19 #include "AidlCameraStream.h"
20 #include "AidlDisplay.h"
21 #include "utils/include/Utils.h"
22 
23 #include <android-base/logging.h>
24 
25 namespace aidl::android::automotive::evs::implementation {
26 
27 namespace hidlevs = ::android::hardware::automotive::evs;
28 
29 using ::aidl::android::hardware::automotive::evs::BufferDesc;
30 using ::aidl::android::hardware::automotive::evs::CameraDesc;
31 using ::aidl::android::hardware::automotive::evs::CameraParam;
32 using ::aidl::android::hardware::automotive::evs::DisplayState;
33 using ::aidl::android::hardware::automotive::evs::EvsEventDesc;
34 using ::aidl::android::hardware::automotive::evs::EvsEventType;
35 using ::aidl::android::hardware::automotive::evs::EvsResult;
36 using ::aidl::android::hardware::automotive::evs::IEvsCameraStream;
37 using ::aidl::android::hardware::automotive::evs::IEvsDisplay;
38 using ::aidl::android::hardware::automotive::evs::ParameterRange;
39 using ::android::hardware::hidl_string;
40 using ::android::hardware::hidl_vec;
41 using ::android::hardware::Return;
42 using ::ndk::ScopedAStatus;
43 
~HidlCamera()44 HidlCamera::~HidlCamera() {
45     mAidlCamera = nullptr;
46     mAidlStream = nullptr;
47 }
48 
getCameraInfo(getCameraInfo_cb _hidl_cb)49 Return<void> HidlCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) {
50     if (!mAidlCamera) {
51         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
52         _hidl_cb({});
53         return {};
54     }
55 
56     CameraDesc aidlDesc;
57     if (auto status = mAidlCamera->getCameraInfo(&aidlDesc); !status.isOk()) {
58         LOG(ERROR) << "Failed to get a camera information, status = "
59                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
60         _hidl_cb({});
61         return {};
62     }
63 
64     _hidl_cb(std::move(Utils::makeToHidlV1_0(aidlDesc)));
65     return {};
66 }
67 
setMaxFramesInFlight(uint32_t bufferCount)68 Return<hidlevs::V1_0::EvsResult> HidlCamera::setMaxFramesInFlight(uint32_t bufferCount) {
69     if (!mAidlCamera) {
70         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
71         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
72     }
73 
74     auto status = mAidlCamera->setMaxFramesInFlight(static_cast<int32_t>(bufferCount));
75     if (!status.isOk()) {
76         return hidlevs::V1_0::EvsResult::BUFFER_NOT_AVAILABLE;
77     }
78 
79     return hidlevs::V1_0::EvsResult::OK;
80 }
81 
startVideoStream(const::android::sp<hidlevs::V1_0::IEvsCameraStream> & stream)82 Return<hidlevs::V1_0::EvsResult> HidlCamera::startVideoStream(
83         const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& stream) {
84     if (!mAidlCamera) {
85         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
86         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
87     } else if (!stream) {
88         LOG(ERROR) << "A given HIDL IEvsCameraStream object is invalid.";
89         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
90     } else if (mAidlStream) {
91         LOG(WARNING) << "A video stream is already running.";
92         return hidlevs::V1_0::EvsResult::STREAM_ALREADY_RUNNING;
93     }
94 
95     // Creates a wrapper object and requests a video stream
96     mAidlStream = ::ndk::SharedRefBase::make<AidlCameraStream>(stream);
97     if (auto status = mAidlCamera->startVideoStream(mAidlStream); !status.isOk()) {
98         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
99     }
100 
101     return hidlevs::V1_0::EvsResult::OK;
102 }
103 
doneWithFrame(const hidlevs::V1_0::BufferDesc & buffer)104 Return<void> HidlCamera::doneWithFrame(const hidlevs::V1_0::BufferDesc& buffer) {
105     if (!mAidlStream) {
106         LOG(ERROR) << "A reference to AIDL IEvsCameraStream object is invalid.";
107         return {};
108     }
109 
110     BufferDesc aidlBuffer;
111     if (!mAidlStream->getBuffer(buffer.bufferId, &aidlBuffer)) {
112         LOG(ERROR) << "Ignores an unknown buffer " << buffer.bufferId;
113         return {};
114     }
115 
116     std::vector<BufferDesc> buffersToReturn(1);
117     int bufferId = aidlBuffer.bufferId;  // save pre move() for log message.
118     buffersToReturn[0] = std::move(aidlBuffer);
119     if (auto status = mAidlCamera->doneWithFrame(std::move(buffersToReturn)); !status.isOk()) {
120         LOG(WARNING) << "Failed to return a buffer " << bufferId << ", status = "
121                      << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
122         return {};
123     }
124 
125     return {};
126 }
127 
stopVideoStream()128 Return<void> HidlCamera::stopVideoStream() {
129     if (!mAidlCamera) {
130         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
131         return {};
132     }
133 
134     mAidlCamera->stopVideoStream();
135     mAidlStream = nullptr;
136     return {};
137 }
138 
getExtendedInfo(uint32_t opaqueIdentifier)139 Return<int32_t> HidlCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
140     if (!mAidlCamera) {
141         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
142         return 0;
143     }
144 
145     std::vector<uint8_t> value;
146     if (!mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value).isOk() ||
147         value.size() < sizeof(int32_t)) {
148         return 0;
149     }
150 
151     return *reinterpret_cast<int32_t*>(value.data());
152 }
153 
setExtendedInfo(uint32_t opaqueIdentifier,int32_t opaqueValue)154 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo(uint32_t opaqueIdentifier,
155                                                              int32_t opaqueValue) {
156     if (!mAidlCamera) {
157         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
158         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
159     }
160 
161     std::vector<uint8_t> value(sizeof(int32_t));
162     *reinterpret_cast<int32_t*>(value.data()) = opaqueValue;
163     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
164     if (!status.isOk()) {
165         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
166     }
167     return hidlevs::V1_0::EvsResult::OK;
168 }
169 
170 // Methods from ::android::hardware::automotive::evs::V1_1::IEvsCamera follow.
getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb)171 Return<void> HidlCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
172     if (!mAidlCamera) {
173         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
174         _hidl_cb({});
175         return {};
176     }
177 
178     CameraDesc aidlDesc;
179     if (auto status = mAidlCamera->getCameraInfo(&aidlDesc); !status.isOk()) {
180         LOG(ERROR) << "Failed to get a camera information, status = "
181                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
182         _hidl_cb({});
183         return {};
184     }
185 
186     _hidl_cb(std::move(Utils::makeToHidlV1_1(aidlDesc)));
187     return {};
188 }
189 
getPhysicalCameraInfo(const hidl_string & deviceId,getPhysicalCameraInfo_cb _hidl_cb)190 Return<void> HidlCamera::getPhysicalCameraInfo(const hidl_string& deviceId,
191                                                getPhysicalCameraInfo_cb _hidl_cb) {
192     if (!mAidlCamera) {
193         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
194         _hidl_cb({});
195         return {};
196     }
197 
198     CameraDesc aidlDesc;
199     if (auto status = mAidlCamera->getPhysicalCameraInfo(deviceId, &aidlDesc); !status.isOk()) {
200         LOG(ERROR) << "Failed to read information of a camera " << deviceId << ", status = "
201                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
202         _hidl_cb({});
203         return {};
204     }
205 
206     _hidl_cb(Utils::makeToHidlV1_1(aidlDesc));
207     return {};
208 }
209 
doneWithFrame_1_1(const hidl_vec<hidlevs::V1_1::BufferDesc> & buffers)210 Return<hidlevs::V1_0::EvsResult> HidlCamera::doneWithFrame_1_1(
211         const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) {
212     if (!mAidlStream) {
213         LOG(WARNING) << "A reference to AIDL IEvsCameraStream object is invalid.";
214         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
215     }
216 
217     std::vector<BufferDesc> buffersToReturn(buffers.size());
218     for (auto i = 0; i < buffers.size(); ++i) {
219         BufferDesc aidlBuffer;
220         if (!mAidlStream->getBuffer(buffers[i].bufferId, &aidlBuffer)) {
221             LOG(WARNING) << "Ignores an unknown buffer " << buffers[i].bufferId;
222             continue;
223         }
224 
225         buffersToReturn[i] = std::move(aidlBuffer);
226     }
227 
228     if (auto status = mAidlCamera->doneWithFrame(std::move(buffersToReturn)); !status.isOk()) {
229         LOG(ERROR) << "Failed to return buffers, status = " << status.getServiceSpecificError();
230         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
231     }
232 
233     return hidlevs::V1_0::EvsResult::OK;
234 }
235 
setMaster()236 Return<hidlevs::V1_0::EvsResult> HidlCamera::setMaster() {
237     if (!mAidlCamera) {
238         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
239         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
240     }
241 
242     if (auto status = mAidlCamera->setPrimaryClient(); !status.isOk()) {
243         EvsResult err = static_cast<EvsResult>(status.getServiceSpecificError());
244         if (err == EvsResult::PERMISSION_DENIED) {
245             // HIDL EvsManager implementations return EvsResult::OWNERSHIP_LOST
246             // if the primary client exists already.
247             err = EvsResult::OWNERSHIP_LOST;
248         }
249         return Utils::makeToHidl(err);
250     }
251 
252     return hidlevs::V1_0::EvsResult::OK;
253 }
254 
forceMaster(const::android::sp<hidlevs::V1_0::IEvsDisplay> & display)255 Return<hidlevs::V1_0::EvsResult> HidlCamera::forceMaster(
256         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
257     if (!mAidlCamera) {
258         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
259         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
260     }
261 
262     auto status = mAidlCamera->forcePrimaryClient(::ndk::SharedRefBase::make<AidlDisplay>(display));
263     if (!status.isOk()) {
264         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
265     }
266 
267     return hidlevs::V1_0::EvsResult::OK;
268 }
269 
unsetMaster()270 Return<hidlevs::V1_0::EvsResult> HidlCamera::unsetMaster() {
271     if (!mAidlCamera) {
272         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
273         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
274     }
275 
276     if (auto status = mAidlCamera->unsetPrimaryClient(); !status.isOk()) {
277         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
278     }
279 
280     return hidlevs::V1_0::EvsResult::OK;
281 }
282 
getParameterList(getParameterList_cb _hidl_cb)283 Return<void> HidlCamera::getParameterList(getParameterList_cb _hidl_cb) {
284     if (!mAidlCamera) {
285         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
286         _hidl_cb({});
287         return {};
288     }
289 
290     std::vector<CameraParam> aidlList;
291     if (auto status = mAidlCamera->getParameterList(&aidlList); !status.isOk()) {
292         LOG(ERROR) << "Failed to get a parameter list, status = "
293                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
294         _hidl_cb({});
295         return {};
296     }
297 
298     hidl_vec<hidlevs::V1_1::CameraParam> hidlList;
299     hidlList.resize(aidlList.size());
300     for (auto i = 0; i < aidlList.size(); ++i) {
301         hidlList[i] = Utils::makeToHidl(aidlList[i]);
302     }
303     _hidl_cb(hidlList);
304     return {};
305 }
306 
getIntParameterRange(hidlevs::V1_1::CameraParam id,getIntParameterRange_cb _hidl_cb)307 Return<void> HidlCamera::getIntParameterRange(hidlevs::V1_1::CameraParam id,
308                                               getIntParameterRange_cb _hidl_cb) {
309     if (!mAidlCamera) {
310         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
311         _hidl_cb(0, 0, 0);
312         return {};
313     }
314 
315     ParameterRange aidlRange;
316     if (auto status = mAidlCamera->getIntParameterRange(Utils::makeFromHidl(id), &aidlRange);
317         !status.isOk()) {
318         LOG(ERROR) << "Failed to get a parameter range, status = "
319                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
320         _hidl_cb(0, 0, 0);
321         return {};
322     }
323 
324     _hidl_cb(aidlRange.min, aidlRange.max, aidlRange.step);
325     return {};
326 }
327 
setIntParameter(hidlevs::V1_1::CameraParam id,int32_t value,setIntParameter_cb _hidl_cb)328 Return<void> HidlCamera::setIntParameter(hidlevs::V1_1::CameraParam id, int32_t value,
329                                          setIntParameter_cb _hidl_cb) {
330     if (!mAidlCamera) {
331         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
332         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
333         return {};
334     }
335 
336     std::vector<int32_t> aidlValues;
337     auto status = mAidlCamera->setIntParameter(Utils::makeFromHidl(id), value, &aidlValues);
338     if (!status.isOk()) {
339         EvsResult err = static_cast<EvsResult>(status.getServiceSpecificError());
340         if (err == EvsResult::PERMISSION_DENIED) {
341             // HIDL EvsManager implementations return EvsResult::INVALID_ARG if
342             // the client is not permitted to change parameters.
343             err = EvsResult::INVALID_ARG;
344         }
345         _hidl_cb(Utils::makeToHidl(err), {value});
346         return {};
347     }
348 
349     _hidl_cb(hidlevs::V1_0::EvsResult::OK, aidlValues);
350     return {};
351 }
352 
getIntParameter(hidlevs::V1_1::CameraParam id,getIntParameter_cb _hidl_cb)353 Return<void> HidlCamera::getIntParameter(hidlevs::V1_1::CameraParam id,
354                                          getIntParameter_cb _hidl_cb) {
355     if (!mAidlCamera) {
356         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
357         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
358         return {};
359     }
360 
361     std::vector<int32_t> aidlValues;
362     auto status = mAidlCamera->getIntParameter(Utils::makeFromHidl(id), &aidlValues);
363     if (!status.isOk()) {
364         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())), {});
365         return {};
366     }
367 
368     _hidl_cb(hidlevs::V1_0::EvsResult::OK, aidlValues);
369     return {};
370 }
371 
setExtendedInfo_1_1(uint32_t opaqueIdentifier,const hidl_vec<uint8_t> & opaqueValue)372 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo_1_1(
373         uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue) {
374     if (!mAidlCamera) {
375         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
376         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
377     }
378 
379     std::vector<uint8_t> value(opaqueValue);
380     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
381     if (!status.isOk()) {
382         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
383     }
384 
385     return hidlevs::V1_0::EvsResult::OK;
386 }
387 
getExtendedInfo_1_1(uint32_t opaqueIdentifier,getExtendedInfo_1_1_cb _hidl_cb)388 Return<void> HidlCamera::getExtendedInfo_1_1(uint32_t opaqueIdentifier,
389                                              getExtendedInfo_1_1_cb _hidl_cb) {
390     if (!mAidlCamera) {
391         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
392         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
393         return {};
394     }
395 
396     std::vector<uint8_t> value;
397     auto status = mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value);
398     if (!status.isOk()) {
399         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())), {});
400         return {};
401     }
402 
403     _hidl_cb(hidlevs::V1_0::EvsResult::OK, value);
404     return {};
405 }
406 
importExternalBuffers(const hidl_vec<hidlevs::V1_1::BufferDesc> & buffers,importExternalBuffers_cb _hidl_cb)407 Return<void> HidlCamera::importExternalBuffers(const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers,
408                                                importExternalBuffers_cb _hidl_cb) {
409     if (!mAidlCamera) {
410         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
411         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, 0);
412         return {};
413     }
414 
415     std::vector<BufferDesc> aidlBuffers(buffers.size());
416     for (auto i = 0; i < buffers.size(); ++i) {
417         aidlBuffers[i] = std::move(Utils::makeFromHidl(buffers[i]));
418     }
419 
420     int32_t delta = 0;
421     if (auto status = mAidlCamera->importExternalBuffers(aidlBuffers, &delta); !status.isOk()) {
422         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())),
423                  delta);
424         return {};
425     }
426 
427     _hidl_cb(hidlevs::V1_0::EvsResult::OK, delta);
428     return {};
429 }
430 
431 }  // namespace aidl::android::automotive::evs::implementation
432