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