blob: cb7403a7da6c496fe3fb2345b2772d63c3bcd30b [file] [log] [blame]
Changyeon Jo2400b692019-07-18 21:32:48 -07001/*
2 * Copyright (C) 2019 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#define LOG_TAG "android.hardware.automotive.evs@1.1-service"
18
19#include "EvsEnumerator.h"
20#include "EvsCamera.h"
21#include "EvsDisplay.h"
22
23namespace android {
24namespace hardware {
25namespace automotive {
26namespace evs {
27namespace V1_1 {
28namespace implementation {
29
30
31// NOTE: All members values are static so that all clients operate on the same state
32// That is to say, this is effectively a singleton despite the fact that HIDL
33// constructs a new instance for each client.
34std::list<EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
35wp<EvsDisplay> EvsEnumerator::sActiveDisplay;
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070036unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
Changyeon Jo2400b692019-07-18 21:32:48 -070037
38
39EvsEnumerator::EvsEnumerator() {
40 ALOGD("EvsEnumerator created");
41
42 // Add sample camera data to our list of cameras
43 // In a real driver, this would be expected to can the available hardware
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070044 sConfigManager =
Changyeon Job0e72922020-01-30 09:00:35 -080045 ConfigManager::Create("/vendor/etc/automotive/evs/evs_default_configuration.xml");
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070046 for (auto v : sConfigManager->getCameraList()) {
47 sCameraList.emplace_back(v.c_str());
48 }
Changyeon Jo2400b692019-07-18 21:32:48 -070049}
50
51
52// Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow.
53Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
54 ALOGD("getCameraList");
55
56 const unsigned numCameras = sCameraList.size();
57
58 // Build up a packed array of CameraDesc for return
59 // NOTE: Only has to live until the callback returns
60 std::vector<CameraDesc_1_0> descriptions;
61 descriptions.reserve(numCameras);
62 for (const auto& cam : sCameraList) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070063 descriptions.push_back( cam.desc.v1 );
Changyeon Jo2400b692019-07-18 21:32:48 -070064 }
65
66 // Encapsulate our camera descriptions in the HIDL vec type
67 hidl_vec<CameraDesc_1_0> hidlCameras(descriptions);
68
69 // Send back the results
70 ALOGD("reporting %zu cameras available", hidlCameras.size());
71 _hidl_cb(hidlCameras);
72
73 // HIDL convention says we return Void if we sent our result back via callback
74 return Void();
75}
76
77
78Return<sp<IEvsCamera_1_0>> EvsEnumerator::openCamera(const hidl_string& cameraId) {
79 ALOGD("openCamera");
80
81 // Find the named camera
82 CameraRecord *pRecord = nullptr;
83 for (auto &&cam : sCameraList) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070084 if (cam.desc.v1.cameraId == cameraId) {
Changyeon Jo2400b692019-07-18 21:32:48 -070085 // Found a match!
86 pRecord = &cam;
87 break;
88 }
89 }
90
91 // Is this a recognized camera id?
92 if (!pRecord) {
93 ALOGE("Requested camera %s not found", cameraId.c_str());
94 return nullptr;
95 }
96
97 // Has this camera already been instantiated by another caller?
98 sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
99 if (pActiveCamera != nullptr) {
100 ALOGW("Killing previous camera because of new caller");
101 closeCamera(pActiveCamera);
102 }
103
104 // Construct a camera instance for the caller
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700105 if (sConfigManager == nullptr) {
106 pActiveCamera = EvsCamera::Create(cameraId.c_str());
107 } else {
108 pActiveCamera = EvsCamera::Create(cameraId.c_str(),
109 sConfigManager->getCameraInfo(cameraId));
110 }
Changyeon Jo2400b692019-07-18 21:32:48 -0700111 pRecord->activeInstance = pActiveCamera;
112 if (pActiveCamera == nullptr) {
113 ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
114 }
115
116 return pActiveCamera;
117}
118
119
120Return<void> EvsEnumerator::closeCamera(const ::android::sp<IEvsCamera_1_0>& pCamera) {
121 ALOGD("closeCamera");
122
123 auto pCamera_1_1 = IEvsCamera_1_1::castFrom(pCamera).withDefault(nullptr);
124 if (pCamera_1_1 == nullptr) {
125 ALOGE("Ignoring call to closeCamera with null camera ptr");
126 return Void();
127 }
128
129 // Get the camera id so we can find it in our list
130 std::string cameraId;
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700131 pCamera_1_1->getCameraInfo_1_1([&cameraId](CameraDesc desc) {
132 cameraId = desc.v1.cameraId;
Changyeon Jo2400b692019-07-18 21:32:48 -0700133 }
134 );
135
136 // Find the named camera
137 CameraRecord *pRecord = nullptr;
138 for (auto &&cam : sCameraList) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700139 if (cam.desc.v1.cameraId == cameraId) {
Changyeon Jo2400b692019-07-18 21:32:48 -0700140 // Found a match!
141 pRecord = &cam;
142 break;
143 }
144 }
145
146 // Is the display being destroyed actually the one we think is active?
147 if (!pRecord) {
148 ALOGE("Asked to close a camera who's name isn't recognized");
149 } else {
150 sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
151
152 if (pActiveCamera == nullptr) {
153 ALOGE("Somehow a camera is being destroyed when the enumerator didn't know one existed");
154 } else if (pActiveCamera != pCamera_1_1) {
155 // This can happen if the camera was aggressively reopened, orphaning this previous instance
156 ALOGW("Ignoring close of previously orphaned camera - why did a client steal?");
157 } else {
158 // Drop the active camera
159 pActiveCamera->forceShutdown();
160 pRecord->activeInstance = nullptr;
161 }
162 }
163
164 return Void();
165}
166
167
168Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay() {
169 ALOGD("openDisplay");
170
171 // If we already have a display active, then we need to shut it down so we can
172 // give exclusive access to the new caller.
173 sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
174 if (pActiveDisplay != nullptr) {
175 ALOGW("Killing previous display because of new caller");
176 closeDisplay(pActiveDisplay);
177 }
178
179 // Create a new display interface and return it
180 pActiveDisplay = new EvsDisplay();
181 sActiveDisplay = pActiveDisplay;
182
183 ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
184 return pActiveDisplay;
185}
186
187
188Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay>& pDisplay) {
189 ALOGD("closeDisplay");
190
191 // Do we still have a display object we think should be active?
192 sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
193 if (pActiveDisplay == nullptr) {
194 ALOGE("Somehow a display is being destroyed when the enumerator didn't know one existed");
195 } else if (sActiveDisplay != pDisplay) {
196 ALOGW("Ignoring close of previously orphaned display - why did a client steal?");
197 } else {
198 // Drop the active display
199 pActiveDisplay->forceShutdown();
200 sActiveDisplay = nullptr;
201 }
202
203 return Void();
204}
205
206
207Return<DisplayState> EvsEnumerator::getDisplayState() {
208 ALOGD("getDisplayState");
209
210 // Do we still have a display object we think should be active?
211 sp<IEvsDisplay> pActiveDisplay = sActiveDisplay.promote();
212 if (pActiveDisplay != nullptr) {
213 return pActiveDisplay->getDisplayState();
214 } else {
215 return DisplayState::NOT_OPEN;
216 }
217}
218
219
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700220// Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow.
221Return<void> EvsEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
222 ALOGD("getCameraList");
223
224 const unsigned numCameras = sCameraList.size();
225
226 // Build up a packed array of CameraDesc for return
227 // NOTE: Only has to live until the callback returns
228 std::vector<CameraDesc_1_1> descriptions;
229 descriptions.reserve(numCameras);
230 for (const auto& cam : sCameraList) {
231 descriptions.push_back( cam.desc );
232 }
233
234 // Encapsulate our camera descriptions in the HIDL vec type
235 hidl_vec<CameraDesc_1_1> hidlCameras(descriptions);
236
237 // Send back the results
238 ALOGD("reporting %zu cameras available", hidlCameras.size());
239 _hidl_cb(hidlCameras);
240
241 // HIDL convention says we return Void if we sent our result back via callback
242 return Void();
243}
244
245Return<sp<IEvsCamera_1_1>>
246EvsEnumerator::openCamera_1_1(const hidl_string& cameraId,
247 const Stream& streamCfg) {
248 // Find the named camera
249 CameraRecord *pRecord = nullptr;
250 for (auto &&cam : sCameraList) {
251 if (cam.desc.v1.cameraId == cameraId) {
252 // Found a match!
253 pRecord = &cam;
254 break;
255 }
256 }
257
258 // Is this a recognized camera id?
259 if (!pRecord) {
260 ALOGE("Requested camera %s not found", cameraId.c_str());
261 return nullptr;
262 }
263
264 // Has this camera already been instantiated by another caller?
265 sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
266 if (pActiveCamera != nullptr) {
267 ALOGW("Killing previous camera because of new caller");
268 closeCamera(pActiveCamera);
269 }
270
271 // Construct a camera instance for the caller
272 if (sConfigManager == nullptr) {
273 pActiveCamera = EvsCamera::Create(cameraId.c_str());
274 } else {
275 pActiveCamera = EvsCamera::Create(cameraId.c_str(),
276 sConfigManager->getCameraInfo(cameraId),
277 &streamCfg);
278 }
279
280 pRecord->activeInstance = pActiveCamera;
281 if (pActiveCamera == nullptr) {
282 ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
283 }
284
285 return pActiveCamera;
286}
287
288
289EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
290 // Find the named camera
291 CameraRecord *pRecord = nullptr;
292 for (auto &&cam : sCameraList) {
293 if (cam.desc.v1.cameraId == cameraId) {
294 // Found a match!
295 pRecord = &cam;
296 break;
297 }
298 }
299
300 return pRecord;
301}
302
Changyeon Jo2400b692019-07-18 21:32:48 -0700303} // namespace implementation
304} // namespace V1_1
305} // namespace evs
306} // namespace automotive
307} // namespace hardware
308} // namespace android