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 "HidlEnumerator.h"
18 
19 #include "Constants.h"
20 #include "HidlCamera.h"
21 #include "HidlDisplay.h"
22 #include "utils/include/Utils.h"
23 
24 #include <aidl/android/hardware/automotive/evs/CameraDesc.h>
25 #include <aidl/android/hardware/automotive/evs/DisplayState.h>
26 #include <aidl/android/hardware/automotive/evs/Rotation.h>
27 #include <aidl/android/hardware/automotive/evs/Stream.h>
28 #include <aidl/android/hardware/automotive/evs/StreamType.h>
29 #include <android-base/logging.h>
30 
31 namespace aidl::android::automotive::evs::implementation {
32 
33 namespace hidlevs = ::android::hardware::automotive::evs;
34 
35 using ::aidl::android::hardware::automotive::evs::CameraDesc;
36 using ::aidl::android::hardware::automotive::evs::DisplayState;
37 using ::aidl::android::hardware::automotive::evs::IEvsCamera;
38 using ::aidl::android::hardware::automotive::evs::IEvsDisplay;
39 using ::aidl::android::hardware::automotive::evs::Stream;
40 using ::aidl::android::hardware::graphics::common::PixelFormat;
41 using ::android::hardware::hidl_string;
42 using ::android::hardware::Return;
43 using ::android::hardware::Status;
44 
~HidlEnumerator()45 HidlEnumerator::~HidlEnumerator() {
46     mEnumerator = nullptr;
47 }
48 
getCameraList(getCameraList_cb _hidl_cb)49 Return<void> HidlEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
50     if (!mEnumerator) {
51         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
52         _hidl_cb({});
53         return {};
54     }
55 
56     std::vector<CameraDesc> aidlCameras;
57     if (auto status = mEnumerator->getCameraList(&aidlCameras); !status.isOk()) {
58         LOG(ERROR) << "Failed to get a list of cameras, status = "
59                    << status.getServiceSpecificError();
60         _hidl_cb({});
61         return {};
62     }
63 
64     ::android::hardware::hidl_vec<hidlevs::V1_0::CameraDesc> hidlCameras(aidlCameras.size());
65     for (auto i = 0; i < aidlCameras.size(); ++i) {
66         hidlCameras[i] = Utils::makeToHidlV1_0(aidlCameras[i]);
67     }
68 
69     _hidl_cb(hidlCameras);
70     return {};
71 }
72 
openCamera(const hidl_string & cameraId)73 Return<::android::sp<hidlevs::V1_0::IEvsCamera>> HidlEnumerator::openCamera(
74         const hidl_string& cameraId) {
75     if (!mEnumerator) {
76         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
77         return nullptr;
78     }
79 
80     std::shared_ptr<IEvsCamera> aidlCamera;
81     // IEvsEnumerator will open a camera with its default configuration.
82     auto status = mEnumerator->openCamera(cameraId, {}, &aidlCamera);
83     if (!status.isOk()) {
84         LOG(ERROR) << "Failed to open a camera " << cameraId;
85         return nullptr;
86     }
87 
88     auto hidlCamera = new (std::nothrow) HidlCamera(aidlCamera);
89     if (hidlCamera == nullptr) {
90         LOG(ERROR) << "Failed to open a camera " << cameraId;
91         return nullptr;
92     }
93 
94     return hidlCamera;
95 }
96 
closeCamera(const::android::sp<hidlevs::V1_0::IEvsCamera> & cameraObj)97 Return<void> HidlEnumerator::closeCamera(
98         const ::android::sp<hidlevs::V1_0::IEvsCamera>& cameraObj) {
99     if (!mEnumerator) {
100         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
101         return {};
102     }
103 
104     if (!cameraObj) {
105         LOG(WARNING) << "Ignoring a call with an invalid camera object";
106         return {};
107     }
108 
109     auto hidlCamera = reinterpret_cast<HidlCamera*>(cameraObj.get());
110     mEnumerator->closeCamera(hidlCamera->getAidlCamera());
111     return {};
112 }
113 
openDisplay()114 Return<::android::sp<hidlevs::V1_0::IEvsDisplay>> HidlEnumerator::openDisplay() {
115     if (!mEnumerator) {
116         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
117         return nullptr;
118     }
119 
120     auto displayId = kDisplayIdUnavailable;
121     if (mAidlDisplayIds.empty()) {
122         if (auto status = mEnumerator->getDisplayIdList(&mAidlDisplayIds);
123             !status.isOk() || mAidlDisplayIds.empty()) {
124             LOG(WARNING) << "Use the default display ID because we failed to get a display list.";
125         } else {
126             displayId = mAidlDisplayIds[0];
127         }
128     }
129 
130     std::shared_ptr<IEvsDisplay> aidlDisplay;
131     if (auto status = mEnumerator->openDisplay(displayId, &aidlDisplay); !status.isOk()) {
132         LOG(ERROR) << "Failed to open a display " << displayId;
133         return nullptr;
134     }
135 
136     HidlDisplay* hidlDisplay = new (std::nothrow) HidlDisplay(aidlDisplay);
137     if (hidlDisplay == nullptr) {
138         LOG(ERROR) << "Failed to open a display " << displayId;
139         return nullptr;
140     }
141 
142     mAidlDisplay = aidlDisplay;
143     mHidlDisplay = hidlDisplay;
144     return hidlDisplay;
145 }
146 
closeDisplay(const::android::sp<hidlevs::V1_0::IEvsDisplay> & display)147 Return<void> HidlEnumerator::closeDisplay(
148         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
149     if (!mEnumerator) {
150         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
151         return {};
152     }
153 
154     if (display != mHidlDisplay.promote()) {
155         LOG(DEBUG) << "Ignores an invalid request to close the display";
156         return {};
157     }
158 
159     mEnumerator->closeDisplay(mAidlDisplay.lock());
160     return {};
161 }
162 
getDisplayState()163 Return<hidlevs::V1_0::DisplayState> HidlEnumerator::getDisplayState() {
164     if (!mEnumerator) {
165         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
166         return hidlevs::V1_0::DisplayState::DEAD;
167     }
168 
169     DisplayState aidlState;
170     if (auto status = mEnumerator->getDisplayState(&aidlState); !status.isOk()) {
171         return hidlevs::V1_0::DisplayState::NOT_OPEN;
172     }
173 
174     return Utils::makeToHidl(aidlState);
175 }
176 
177 // Methods from hardware::automotive::evs::V1_1::IEvsEnumerator follow.
getCameraList_1_1(getCameraList_1_1_cb _hidl_cb)178 Return<void> HidlEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
179     if (!mEnumerator) {
180         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
181         _hidl_cb({});
182         return {};
183     }
184 
185     std::vector<CameraDesc> aidlCameras;
186     if (auto status = mEnumerator->getCameraList(&aidlCameras); !status.isOk()) {
187         LOG(ERROR) << "Failed to get a list of cameras, status = "
188                    << status.getServiceSpecificError();
189         _hidl_cb({});
190         return {};
191     }
192 
193     ::android::hardware::hidl_vec<hidlevs::V1_1::CameraDesc> hidlCameras(aidlCameras.size());
194     for (auto i = 0; i < aidlCameras.size(); ++i) {
195         hidlCameras[i] = Utils::makeToHidlV1_1(aidlCameras[i]);
196     }
197 
198     _hidl_cb(hidlCameras);
199     return {};
200 }
201 
openCamera_1_1(const hidl_string & cameraId,const::android::hardware::camera::device::V3_2::Stream & hidlCfg)202 Return<::android::sp<hidlevs::V1_1::IEvsCamera>> HidlEnumerator::openCamera_1_1(
203         const hidl_string& cameraId,
204         const ::android::hardware::camera::device::V3_2::Stream& hidlCfg) {
205     if (!mEnumerator) {
206         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
207         return nullptr;
208     }
209 
210     Stream cfg = std::move(Utils::makeFromHidl(hidlCfg));
211     std::shared_ptr<IEvsCamera> aidlCamera;
212     if (auto status = mEnumerator->openCamera(cameraId, cfg, &aidlCamera); !status.isOk()) {
213         LOG(ERROR) << "Failed to open a camera " << cameraId
214                    << ", error = " << status.getServiceSpecificError();
215         return nullptr;
216     }
217 
218     auto hidlCamera = new (std::nothrow) HidlCamera(aidlCamera);
219     if (hidlCamera == nullptr) {
220         LOG(ERROR) << "Failed to create a HidlCamera object " << cameraId;
221         return nullptr;
222     }
223 
224     return hidlCamera;
225 }
226 
getDisplayIdList(getDisplayIdList_cb _list_cb)227 Return<void> HidlEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
228     if (!mEnumerator) {
229         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
230         _list_cb({});
231         return {};
232     }
233 
234     if (auto status = mEnumerator->getDisplayIdList(&mAidlDisplayIds); !status.isOk()) {
235         LOG(ERROR) << "Failed to get a display list";
236         _list_cb({});
237         return {};
238     }
239 
240     _list_cb(mAidlDisplayIds);
241     return {};
242 }
243 
openDisplay_1_1(uint8_t id)244 Return<::android::sp<hidlevs::V1_1::IEvsDisplay>> HidlEnumerator::openDisplay_1_1(uint8_t id) {
245     if (!mEnumerator) {
246         LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
247         return nullptr;
248     }
249 
250     std::shared_ptr<IEvsDisplay> aidlDisplay;
251     auto status = mEnumerator->openDisplay(id, &aidlDisplay);
252     if (!status.isOk()) {
253         LOG(ERROR) << "Failed to open a display " << id;
254         return nullptr;
255     }
256 
257     HidlDisplay* hidlDisplay = new (std::nothrow) HidlDisplay(aidlDisplay);
258     if (hidlDisplay == nullptr) {
259         LOG(ERROR) << "Failed to open a display " << id;
260         return nullptr;
261     }
262 
263     mAidlDisplay = aidlDisplay;
264     mHidlDisplay = hidlDisplay;
265     return hidlDisplay;
266 }
267 
getUltrasonicsArrayList(getUltrasonicsArrayList_cb _hidl_cb)268 Return<void> HidlEnumerator::getUltrasonicsArrayList(
269         [[maybe_unused]] getUltrasonicsArrayList_cb _hidl_cb) {
270     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
271     _hidl_cb({});
272     return {};
273 }
274 
openUltrasonicsArray(const hidl_string & ultrasonicsArrayId)275 Return<::android::sp<hidlevs::V1_1::IEvsUltrasonicsArray>> HidlEnumerator::openUltrasonicsArray(
276         [[maybe_unused]] const hidl_string& ultrasonicsArrayId) {
277     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
278     return nullptr;
279 }
280 
closeUltrasonicsArray(const::android::sp<hidlevs::V1_1::IEvsUltrasonicsArray> & evsUltrasonicsArray)281 Return<void> HidlEnumerator::closeUltrasonicsArray(
282         [[maybe_unused]] const ::android::sp<hidlevs::V1_1::IEvsUltrasonicsArray>&
283                 evsUltrasonicsArray) {
284     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
285     return {};
286 }
287 
288 }  // namespace aidl::android::automotive::evs::implementation
289