• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     return {};
136 }
137 
getExtendedInfo(uint32_t opaqueIdentifier)138 Return<int32_t> HidlCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
139     if (!mAidlCamera) {
140         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
141         return 0;
142     }
143 
144     std::vector<uint8_t> value;
145     if (!mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value).isOk() ||
146         value.size() < sizeof(int32_t)) {
147         return 0;
148     }
149 
150     return *reinterpret_cast<int32_t*>(value.data());
151 }
152 
setExtendedInfo(uint32_t opaqueIdentifier,int32_t opaqueValue)153 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo(uint32_t opaqueIdentifier,
154                                                              int32_t opaqueValue) {
155     if (!mAidlCamera) {
156         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
157         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
158     }
159 
160     std::vector<uint8_t> value(sizeof(int32_t));
161     *reinterpret_cast<int32_t*>(value.data()) = opaqueValue;
162     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
163     if (!status.isOk()) {
164         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
165     }
166     return hidlevs::V1_0::EvsResult::OK;
167 }
168 
169 // Methods from ::android::hardware::automotive::evs::V1_1::IEvsCamera follow.
getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb)170 Return<void> HidlCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
171     if (!mAidlCamera) {
172         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
173         _hidl_cb({});
174         return {};
175     }
176 
177     CameraDesc aidlDesc;
178     if (auto status = mAidlCamera->getCameraInfo(&aidlDesc); !status.isOk()) {
179         LOG(ERROR) << "Failed to get a camera information, status = "
180                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
181         _hidl_cb({});
182         return {};
183     }
184 
185     _hidl_cb(std::move(Utils::makeToHidlV1_1(aidlDesc)));
186     return {};
187 }
188 
getPhysicalCameraInfo(const hidl_string & deviceId,getPhysicalCameraInfo_cb _hidl_cb)189 Return<void> HidlCamera::getPhysicalCameraInfo(const hidl_string& deviceId,
190                                                getPhysicalCameraInfo_cb _hidl_cb) {
191     if (!mAidlCamera) {
192         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
193         _hidl_cb({});
194         return {};
195     }
196 
197     CameraDesc aidlDesc;
198     if (auto status = mAidlCamera->getPhysicalCameraInfo(deviceId, &aidlDesc); !status.isOk()) {
199         LOG(ERROR) << "Failed to read information of a camera " << deviceId << ", status = "
200                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
201         _hidl_cb({});
202         return {};
203     }
204 
205     _hidl_cb(Utils::makeToHidlV1_1(aidlDesc));
206     return {};
207 }
208 
doneWithFrame_1_1(const hidl_vec<hidlevs::V1_1::BufferDesc> & buffers)209 Return<hidlevs::V1_0::EvsResult> HidlCamera::doneWithFrame_1_1(
210         const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) {
211     if (!mAidlStream) {
212         LOG(WARNING) << "A reference to AIDL IEvsCameraStream object is invalid.";
213         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
214     }
215 
216     std::vector<BufferDesc> buffersToReturn(buffers.size());
217     for (auto i = 0; i < buffers.size(); ++i) {
218         BufferDesc aidlBuffer;
219         if (!mAidlStream->getBuffer(buffers[i].bufferId, &aidlBuffer)) {
220             LOG(WARNING) << "Ignores an unknown buffer " << buffers[i].bufferId;
221             continue;
222         }
223 
224         buffersToReturn[i] = std::move(aidlBuffer);
225     }
226 
227     if (auto status = mAidlCamera->doneWithFrame(std::move(buffersToReturn)); !status.isOk()) {
228         LOG(ERROR) << "Failed to return buffers, status = " << status.getServiceSpecificError();
229         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
230     }
231 
232     return hidlevs::V1_0::EvsResult::OK;
233 }
234 
setMaster()235 Return<hidlevs::V1_0::EvsResult> HidlCamera::setMaster() {
236     if (!mAidlCamera) {
237         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
238         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
239     }
240 
241     if (auto status = mAidlCamera->setPrimaryClient(); !status.isOk()) {
242         EvsResult err = static_cast<EvsResult>(status.getServiceSpecificError());
243         if (err == EvsResult::PERMISSION_DENIED) {
244             // HIDL EvsManager implementations return EvsResult::OWNERSHIP_LOST
245             // if the primary client exists already.
246             err = EvsResult::OWNERSHIP_LOST;
247         }
248         return Utils::makeToHidl(err);
249     }
250 
251     return hidlevs::V1_0::EvsResult::OK;
252 }
253 
forceMaster(const::android::sp<hidlevs::V1_0::IEvsDisplay> & display)254 Return<hidlevs::V1_0::EvsResult> HidlCamera::forceMaster(
255         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
256     if (!mAidlCamera) {
257         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
258         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
259     }
260 
261     auto status = mAidlCamera->forcePrimaryClient(::ndk::SharedRefBase::make<AidlDisplay>(display));
262     if (!status.isOk()) {
263         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
264     }
265 
266     return hidlevs::V1_0::EvsResult::OK;
267 }
268 
unsetMaster()269 Return<hidlevs::V1_0::EvsResult> HidlCamera::unsetMaster() {
270     if (!mAidlCamera) {
271         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
272         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
273     }
274 
275     if (auto status = mAidlCamera->unsetPrimaryClient(); !status.isOk()) {
276         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
277     }
278 
279     return hidlevs::V1_0::EvsResult::OK;
280 }
281 
getParameterList(getParameterList_cb _hidl_cb)282 Return<void> HidlCamera::getParameterList(getParameterList_cb _hidl_cb) {
283     if (!mAidlCamera) {
284         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
285         _hidl_cb({});
286         return {};
287     }
288 
289     std::vector<CameraParam> aidlList;
290     if (auto status = mAidlCamera->getParameterList(&aidlList); !status.isOk()) {
291         LOG(ERROR) << "Failed to get a parameter list, status = "
292                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
293         _hidl_cb({});
294         return {};
295     }
296 
297     hidl_vec<hidlevs::V1_1::CameraParam> hidlList;
298     hidlList.resize(aidlList.size());
299     for (auto i = 0; i < aidlList.size(); ++i) {
300         hidlList[i] = Utils::makeToHidl(aidlList[i]);
301     }
302     _hidl_cb(hidlList);
303     return {};
304 }
305 
getIntParameterRange(hidlevs::V1_1::CameraParam id,getIntParameterRange_cb _hidl_cb)306 Return<void> HidlCamera::getIntParameterRange(hidlevs::V1_1::CameraParam id,
307                                               getIntParameterRange_cb _hidl_cb) {
308     if (!mAidlCamera) {
309         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
310         _hidl_cb(0, 0, 0);
311         return {};
312     }
313 
314     ParameterRange aidlRange;
315     if (auto status = mAidlCamera->getIntParameterRange(Utils::makeFromHidl(id), &aidlRange);
316         !status.isOk()) {
317         LOG(ERROR) << "Failed to get a parameter range, status = "
318                    << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
319         _hidl_cb(0, 0, 0);
320         return {};
321     }
322 
323     _hidl_cb(aidlRange.min, aidlRange.max, aidlRange.step);
324     return {};
325 }
326 
setIntParameter(hidlevs::V1_1::CameraParam id,int32_t value,setIntParameter_cb _hidl_cb)327 Return<void> HidlCamera::setIntParameter(hidlevs::V1_1::CameraParam id, int32_t value,
328                                          setIntParameter_cb _hidl_cb) {
329     if (!mAidlCamera) {
330         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
331         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
332         return {};
333     }
334 
335     std::vector<int32_t> aidlValues;
336     auto status = mAidlCamera->setIntParameter(Utils::makeFromHidl(id), value, &aidlValues);
337     if (!status.isOk()) {
338         EvsResult err = static_cast<EvsResult>(status.getServiceSpecificError());
339         if (err == EvsResult::PERMISSION_DENIED) {
340             // HIDL EvsManager implementations return EvsResult::INVALID_ARG if
341             // the client is not permitted to change parameters.
342             err = EvsResult::INVALID_ARG;
343         }
344         _hidl_cb(Utils::makeToHidl(err), {value});
345         return {};
346     }
347 
348     _hidl_cb(hidlevs::V1_0::EvsResult::OK, aidlValues);
349     return {};
350 }
351 
getIntParameter(hidlevs::V1_1::CameraParam id,getIntParameter_cb _hidl_cb)352 Return<void> HidlCamera::getIntParameter(hidlevs::V1_1::CameraParam id,
353                                          getIntParameter_cb _hidl_cb) {
354     if (!mAidlCamera) {
355         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
356         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
357         return {};
358     }
359 
360     std::vector<int32_t> aidlValues;
361     auto status = mAidlCamera->getIntParameter(Utils::makeFromHidl(id), &aidlValues);
362     if (!status.isOk()) {
363         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())), {});
364         return {};
365     }
366 
367     _hidl_cb(hidlevs::V1_0::EvsResult::OK, aidlValues);
368     return {};
369 }
370 
setExtendedInfo_1_1(uint32_t opaqueIdentifier,const hidl_vec<uint8_t> & opaqueValue)371 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo_1_1(
372         uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue) {
373     if (!mAidlCamera) {
374         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
375         return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
376     }
377 
378     std::vector<uint8_t> value(opaqueValue);
379     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
380     if (!status.isOk()) {
381         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
382     }
383 
384     return hidlevs::V1_0::EvsResult::OK;
385 }
386 
getExtendedInfo_1_1(uint32_t opaqueIdentifier,getExtendedInfo_1_1_cb _hidl_cb)387 Return<void> HidlCamera::getExtendedInfo_1_1(uint32_t opaqueIdentifier,
388                                              getExtendedInfo_1_1_cb _hidl_cb) {
389     if (!mAidlCamera) {
390         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
391         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
392         return {};
393     }
394 
395     std::vector<uint8_t> value;
396     auto status = mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value);
397     if (!status.isOk()) {
398         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())), {});
399         return {};
400     }
401 
402     _hidl_cb(hidlevs::V1_0::EvsResult::OK, value);
403     return {};
404 }
405 
importExternalBuffers(const hidl_vec<hidlevs::V1_1::BufferDesc> & buffers,importExternalBuffers_cb _hidl_cb)406 Return<void> HidlCamera::importExternalBuffers(const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers,
407                                                importExternalBuffers_cb _hidl_cb) {
408     if (!mAidlCamera) {
409         LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
410         _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, 0);
411         return {};
412     }
413 
414     std::vector<BufferDesc> aidlBuffers(buffers.size());
415     for (auto i = 0; i < buffers.size(); ++i) {
416         aidlBuffers[i] = std::move(Utils::makeFromHidl(buffers[i]));
417     }
418 
419     int32_t delta = 0;
420     if (auto status = mAidlCamera->importExternalBuffers(aidlBuffers, &delta); !status.isOk()) {
421         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())),
422                  delta);
423         return {};
424     }
425 
426     _hidl_cb(hidlevs::V1_0::EvsResult::OK, delta);
427     return {};
428 }
429 
430 }  // namespace aidl::android::automotive::evs::implementation
431