blob: b84268a15cb5af16b19e1bd20bb5cc8183cd3dc0 [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
Changyeon Jo2400b692019-07-18 21:32:48 -070017#include "EvsEnumerator.h"
18#include "EvsCamera.h"
19#include "EvsDisplay.h"
Tanmay Patilb97cceb2020-02-07 16:48:39 -080020#include "EvsUltrasonicsArray.h"
Changyeon Jo2400b692019-07-18 21:32:48 -070021
Changyeon Jo33ba66b2022-01-16 16:33:52 -080022using android::frameworks::automotive::display::V1_0::IAutomotiveDisplayProxyService;
23using android::hardware::automotive::evs::V1_0::EvsResult;
Changyeon Jo2400b692019-07-18 21:32:48 -070024
Changyeon Jo33ba66b2022-01-16 16:33:52 -080025namespace android::hardware::automotive::evs::V1_1::implementation {
26
27namespace evs_v1_0 = ::android::hardware::automotive::evs::V1_0;
Changyeon Jo2400b692019-07-18 21:32:48 -070028
29// NOTE: All members values are static so that all clients operate on the same state
30// That is to say, this is effectively a singleton despite the fact that HIDL
31// constructs a new instance for each client.
Changyeon Jo33ba66b2022-01-16 16:33:52 -080032std::list<EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
33wp<EvsDisplay> EvsEnumerator::sActiveDisplay;
34std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
35sp<IAutomotiveDisplayProxyService> EvsEnumerator::sDisplayProxyService;
36std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
37std::list<EvsEnumerator::UltrasonicsArrayRecord> EvsEnumerator::sUltrasonicsArrayRecordList;
38uint64_t EvsEnumerator::sInternalDisplayId;
Changyeon Jo2400b692019-07-18 21:32:48 -070039
Changyeon Jo33ba66b2022-01-16 16:33:52 -080040EvsEnumerator::EvsEnumerator(sp<IAutomotiveDisplayProxyService>& windowService) {
41 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -070042
43 // Add sample camera data to our list of cameras
44 // In a real driver, this would be expected to can the available hardware
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070045 sConfigManager =
Changyeon Jo33ba66b2022-01-16 16:33:52 -080046 ConfigManager::Create("/vendor/etc/automotive/evs/evs_default_configuration.xml");
Changyeon Jo043a7a02020-01-02 17:55:55 -080047
48 // Add available cameras
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070049 for (auto v : sConfigManager->getCameraList()) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -080050 CameraRecord rec(v.data());
51 std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(v);
52 if (pInfo) {
53 rec.desc.metadata.setToExternal(reinterpret_cast<uint8_t*>(pInfo->characteristics),
54 get_camera_metadata_size(pInfo->characteristics));
55 }
56 sCameraList.push_back(std::move(rec));
Changyeon Joc6fa0ab2019-10-12 05:25:44 -070057 }
Changyeon Jo043a7a02020-01-02 17:55:55 -080058
Changyeon Jo33ba66b2022-01-16 16:33:52 -080059 if (!sDisplayProxyService) {
Changyeon Jo043a7a02020-01-02 17:55:55 -080060 /* sets a car-window service handle */
61 sDisplayProxyService = windowService;
62 }
63
64 // Add available displays
Changyeon Jo33ba66b2022-01-16 16:33:52 -080065 if (sDisplayProxyService) {
Changyeon Jo043a7a02020-01-02 17:55:55 -080066 // Get a display ID list.
Changyeon Jo33ba66b2022-01-16 16:33:52 -080067 auto status = sDisplayProxyService->getDisplayIdList([](const auto& displayIds) {
68 if (displayIds.size() > 0) {
69 sInternalDisplayId = displayIds[0];
70 for (const auto& id : displayIds) {
71 const auto port = id & 0xF;
72 sDisplayPortList.insert_or_assign(port, id);
73 }
Changyeon Jo043a7a02020-01-02 17:55:55 -080074 }
75 });
Changyeon Jo33ba66b2022-01-16 16:33:52 -080076
77 if (!status.isOk()) {
78 ALOGE("Failed to read a display list");
79 }
Changyeon Jo043a7a02020-01-02 17:55:55 -080080 }
Tanmay Patilb97cceb2020-02-07 16:48:39 -080081
82 // Add ultrasonics array desc.
Changyeon Jo33ba66b2022-01-16 16:33:52 -080083 sUltrasonicsArrayRecordList.emplace_back(EvsUltrasonicsArray::GetMockArrayDesc("front_array"));
Changyeon Jo2400b692019-07-18 21:32:48 -070084}
85
Changyeon Jo2400b692019-07-18 21:32:48 -070086// Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow.
Changyeon Jo33ba66b2022-01-16 16:33:52 -080087Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
88 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -070089
Changyeon Jo33ba66b2022-01-16 16:33:52 -080090 const auto numCameras = sCameraList.size();
Changyeon Jo2400b692019-07-18 21:32:48 -070091
92 // Build up a packed array of CameraDesc for return
93 // NOTE: Only has to live until the callback returns
Changyeon Jo33ba66b2022-01-16 16:33:52 -080094 std::vector<evs_v1_0::CameraDesc> descriptions;
Changyeon Jo2400b692019-07-18 21:32:48 -070095 descriptions.reserve(numCameras);
96 for (const auto& cam : sCameraList) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -080097 descriptions.push_back(cam.desc.v1);
Changyeon Jo2400b692019-07-18 21:32:48 -070098 }
99
100 // Encapsulate our camera descriptions in the HIDL vec type
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800101 hidl_vec<evs_v1_0::CameraDesc> hidlCameras(descriptions);
Changyeon Jo2400b692019-07-18 21:32:48 -0700102
103 // Send back the results
104 ALOGD("reporting %zu cameras available", hidlCameras.size());
105 _hidl_cb(hidlCameras);
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800106 return {};
Changyeon Jo2400b692019-07-18 21:32:48 -0700107}
108
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800109Return<sp<evs_v1_0::IEvsCamera>> EvsEnumerator::openCamera(const hidl_string& cameraId) {
110 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -0700111
112 // Find the named camera
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800113 auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
114 return cameraId == cam.desc.v1.cameraId;
115 });
116 if (it == sCameraList.end()) {
Changyeon Jo2400b692019-07-18 21:32:48 -0700117 ALOGE("Requested camera %s not found", cameraId.c_str());
118 return nullptr;
119 }
120
121 // Has this camera already been instantiated by another caller?
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800122 sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
Changyeon Jo2400b692019-07-18 21:32:48 -0700123 if (pActiveCamera != nullptr) {
124 ALOGW("Killing previous camera because of new caller");
125 closeCamera(pActiveCamera);
126 }
127
128 // Construct a camera instance for the caller
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800129 if (!sConfigManager) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700130 pActiveCamera = EvsCamera::Create(cameraId.c_str());
131 } else {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800132 pActiveCamera =
133 EvsCamera::Create(cameraId.c_str(), sConfigManager->getCameraInfo(cameraId));
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700134 }
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800135 it->activeInstance = pActiveCamera;
136 if (!pActiveCamera) {
Changyeon Jo2400b692019-07-18 21:32:48 -0700137 ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
138 }
139
140 return pActiveCamera;
141}
142
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800143Return<void> EvsEnumerator::closeCamera(const ::android::sp<evs_v1_0::IEvsCamera>& pCamera) {
144 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -0700145
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800146 auto pCamera_1_1 = IEvsCamera::castFrom(pCamera).withDefault(nullptr);
147 if (!pCamera_1_1) {
Changyeon Jo2400b692019-07-18 21:32:48 -0700148 ALOGE("Ignoring call to closeCamera with null camera ptr");
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800149 return {};
Changyeon Jo2400b692019-07-18 21:32:48 -0700150 }
151
152 // Get the camera id so we can find it in our list
153 std::string cameraId;
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800154 pCamera_1_1->getCameraInfo_1_1([&cameraId](CameraDesc desc) { cameraId = desc.v1.cameraId; });
Changyeon Jo2400b692019-07-18 21:32:48 -0700155
156 // Find the named camera
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800157 auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
158 return cameraId == cam.desc.v1.cameraId;
159 });
160 if (it == sCameraList.end()) {
161 ALOGE("Ignores a request to close unknown camera, %s", cameraId.data());
162 return {};
Changyeon Jo2400b692019-07-18 21:32:48 -0700163 }
164
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800165 sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
166 if (!pActiveCamera) {
167 ALOGE("Somehow a camera is being destroyed when the enumerator didn't know one existed");
168 } else if (pActiveCamera != pCamera_1_1) {
169 // This can happen if the camera was aggressively reopened, orphaning this previous instance
170 ALOGW("Ignoring close of previously orphaned camera - why did a client steal?");
Changyeon Jo2400b692019-07-18 21:32:48 -0700171 } else {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800172 // Drop the active camera
173 pActiveCamera->forceShutdown();
174 it->activeInstance = nullptr;
Changyeon Jo2400b692019-07-18 21:32:48 -0700175 }
176
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800177 return {};
Changyeon Jo2400b692019-07-18 21:32:48 -0700178}
179
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800180Return<sp<V1_0::IEvsDisplay>> EvsEnumerator::openDisplay() {
181 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -0700182
183 // If we already have a display active, then we need to shut it down so we can
184 // give exclusive access to the new caller.
185 sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
186 if (pActiveDisplay != nullptr) {
187 ALOGW("Killing previous display because of new caller");
188 closeDisplay(pActiveDisplay);
189 }
190
191 // Create a new display interface and return it
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800192 pActiveDisplay = new EvsDisplay(sDisplayProxyService, sInternalDisplayId);
Changyeon Jo2400b692019-07-18 21:32:48 -0700193 sActiveDisplay = pActiveDisplay;
194
195 ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
196 return pActiveDisplay;
197}
198
Changyeon Jo043a7a02020-01-02 17:55:55 -0800199Return<void> EvsEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
200 hidl_vec<uint8_t> ids;
Changyeon Jo043a7a02020-01-02 17:55:55 -0800201 ids.resize(sDisplayPortList.size());
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800202
Changyeon Jo043a7a02020-01-02 17:55:55 -0800203 unsigned i = 0;
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800204 std::for_each(sDisplayPortList.begin(), sDisplayPortList.end(),
205 [&](const auto& element) { ids[i++] = element.first; });
Changyeon Jo043a7a02020-01-02 17:55:55 -0800206
207 _list_cb(ids);
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800208 return {};
Changyeon Jo043a7a02020-01-02 17:55:55 -0800209}
210
Changyeon Jo043a7a02020-01-02 17:55:55 -0800211Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay_1_1(uint8_t port) {
212 ALOGD("%s", __FUNCTION__);
213
214 // If we already have a display active, then we need to shut it down so we can
215 // give exclusive access to the new caller.
216 sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
217 if (pActiveDisplay != nullptr) {
218 ALOGW("Killing previous display because of new caller");
219 closeDisplay(pActiveDisplay);
220 }
221
222 // Create a new display interface and return it
223 pActiveDisplay = new EvsDisplay(sDisplayProxyService, sDisplayPortList[port]);
224 sActiveDisplay = pActiveDisplay;
225
226 ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
227 return pActiveDisplay;
228}
229
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800230Return<void> EvsEnumerator::closeDisplay(const ::android::sp<V1_0::IEvsDisplay>& pDisplay) {
231 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -0700232
233 // Do we still have a display object we think should be active?
234 sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
235 if (pActiveDisplay == nullptr) {
236 ALOGE("Somehow a display is being destroyed when the enumerator didn't know one existed");
237 } else if (sActiveDisplay != pDisplay) {
238 ALOGW("Ignoring close of previously orphaned display - why did a client steal?");
239 } else {
240 // Drop the active display
241 pActiveDisplay->forceShutdown();
242 sActiveDisplay = nullptr;
243 }
244
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800245 return {};
Changyeon Jo2400b692019-07-18 21:32:48 -0700246}
247
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800248Return<V1_0::DisplayState> EvsEnumerator::getDisplayState() {
249 ALOGD("%s", __FUNCTION__);
Changyeon Jo2400b692019-07-18 21:32:48 -0700250
251 // Do we still have a display object we think should be active?
252 sp<IEvsDisplay> pActiveDisplay = sActiveDisplay.promote();
253 if (pActiveDisplay != nullptr) {
254 return pActiveDisplay->getDisplayState();
255 } else {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800256 return V1_0::DisplayState::NOT_OPEN;
Changyeon Jo2400b692019-07-18 21:32:48 -0700257 }
258}
259
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700260// Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow.
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800261Return<void> EvsEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
262 ALOGD("%s", __FUNCTION__);
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700263
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800264 const auto numCameras = sCameraList.size();
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700265
266 // Build up a packed array of CameraDesc for return
267 // NOTE: Only has to live until the callback returns
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800268 std::vector<CameraDesc> descriptions;
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700269 descriptions.reserve(numCameras);
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800270 std::for_each(sCameraList.begin(), sCameraList.end(),
271 [&](const auto& cam) { descriptions.push_back(cam.desc); });
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700272
273 // Encapsulate our camera descriptions in the HIDL vec type
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800274 hidl_vec<CameraDesc> hidlCameras(descriptions);
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700275
276 // Send back the results
277 ALOGD("reporting %zu cameras available", hidlCameras.size());
278 _hidl_cb(hidlCameras);
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800279 return {};
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700280}
281
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800282Return<sp<IEvsCamera>> EvsEnumerator::openCamera_1_1(const hidl_string& cameraId,
283 const Stream& streamCfg) {
284 ALOGD("%s", __FUNCTION__);
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700285
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800286 // Find the named camera
287 auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
288 return cameraId == cam.desc.v1.cameraId;
289 });
290 if (it == sCameraList.end()) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700291 ALOGE("Requested camera %s not found", cameraId.c_str());
292 return nullptr;
293 }
294
295 // Has this camera already been instantiated by another caller?
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800296 sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700297 if (pActiveCamera != nullptr) {
298 ALOGW("Killing previous camera because of new caller");
299 closeCamera(pActiveCamera);
300 }
301
302 // Construct a camera instance for the caller
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800303 if (!sConfigManager) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700304 pActiveCamera = EvsCamera::Create(cameraId.c_str());
305 } else {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800306 pActiveCamera = EvsCamera::Create(cameraId.c_str(), sConfigManager->getCameraInfo(cameraId),
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700307 &streamCfg);
308 }
309
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800310 it->activeInstance = pActiveCamera;
311 if (!pActiveCamera) {
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700312 ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
313 }
314
315 return pActiveCamera;
316}
317
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700318EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800319 ALOGD("%s", __FUNCTION__);
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700320
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800321 // Find the named camera
322 auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
323 return cameraId == cam.desc.v1.cameraId;
324 });
325 return (it != sCameraList.end()) ? &*it : nullptr;
Changyeon Joc6fa0ab2019-10-12 05:25:44 -0700326}
327
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800328EvsEnumerator::UltrasonicsArrayRecord* EvsEnumerator::findUltrasonicsArrayById(
329 const std::string& ultrasonicsArrayId) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800330 ALOGD("%s", __FUNCTION__);
331
332 auto recordIt =
333 std::find_if(sUltrasonicsArrayRecordList.begin(), sUltrasonicsArrayRecordList.end(),
334 [&ultrasonicsArrayId](const UltrasonicsArrayRecord& record) {
335 return ultrasonicsArrayId == record.desc.ultrasonicsArrayId;
336 });
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800337
338 return (recordIt != sUltrasonicsArrayRecordList.end()) ? &*recordIt : nullptr;
339}
340
Tanmay Patil496b86c2020-01-07 17:50:23 -0800341Return<void> EvsEnumerator::getUltrasonicsArrayList(getUltrasonicsArrayList_cb _hidl_cb) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800342 ALOGD("%s", __FUNCTION__);
343
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800344 hidl_vec<UltrasonicsArrayDesc> desc;
345 desc.resize(sUltrasonicsArrayRecordList.size());
346
347 // Copy over desc from sUltrasonicsArrayRecordList.
348 for (auto p = std::make_pair(sUltrasonicsArrayRecordList.begin(), desc.begin());
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800349 p.first != sUltrasonicsArrayRecordList.end(); p.first++, p.second++) {
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800350 *p.second = p.first->desc;
351 }
352
353 // Send back the results
354 ALOGD("reporting %zu ultrasonics arrays available", desc.size());
355 _hidl_cb(desc);
356
357 // HIDL convention says we return Void if we sent our result back via callback
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800358 return {};
Tanmay Patil496b86c2020-01-07 17:50:23 -0800359}
360
Tanmay Patil496b86c2020-01-07 17:50:23 -0800361Return<sp<IEvsUltrasonicsArray>> EvsEnumerator::openUltrasonicsArray(
362 const hidl_string& ultrasonicsArrayId) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800363 ALOGD("%s", __FUNCTION__);
364
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800365 // Find the named ultrasonic array.
366 UltrasonicsArrayRecord* pRecord = findUltrasonicsArrayById(ultrasonicsArrayId);
367
368 // Is this a recognized ultrasonic array id?
369 if (!pRecord) {
370 ALOGE("Requested ultrasonics array %s not found", ultrasonicsArrayId.c_str());
371 return nullptr;
372 }
373
374 // Has this ultrasonic array already been instantiated by another caller?
375 sp<EvsUltrasonicsArray> pActiveUltrasonicsArray = pRecord->activeInstance.promote();
376 if (pActiveUltrasonicsArray != nullptr) {
377 ALOGW("Killing previous ultrasonics array because of new caller");
378 closeUltrasonicsArray(pActiveUltrasonicsArray);
379 }
380
381 // Construct a ultrasonic array instance for the caller
382 pActiveUltrasonicsArray = EvsUltrasonicsArray::Create(ultrasonicsArrayId.c_str());
383 pRecord->activeInstance = pActiveUltrasonicsArray;
384 if (pActiveUltrasonicsArray == nullptr) {
385 ALOGE("Failed to allocate new EvsUltrasonicsArray object for %s\n",
386 ultrasonicsArrayId.c_str());
387 }
388
389 return pActiveUltrasonicsArray;
Tanmay Patil496b86c2020-01-07 17:50:23 -0800390}
391
Tanmay Patil496b86c2020-01-07 17:50:23 -0800392Return<void> EvsEnumerator::closeUltrasonicsArray(
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800393 const sp<IEvsUltrasonicsArray>& pEvsUltrasonicsArray) {
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800394 ALOGD("%s", __FUNCTION__);
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800395
396 if (pEvsUltrasonicsArray.get() == nullptr) {
397 ALOGE("Ignoring call to closeUltrasonicsArray with null ultrasonics array");
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800398 return {};
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800399 }
400
401 // Get the ultrasonics array id so we can find it in our list.
402 std::string ultrasonicsArrayId;
403 pEvsUltrasonicsArray->getUltrasonicArrayInfo([&ultrasonicsArrayId](UltrasonicsArrayDesc desc) {
404 ultrasonicsArrayId.assign(desc.ultrasonicsArrayId);
405 });
406
407 // Find the named ultrasonics array
408 UltrasonicsArrayRecord* pRecord = findUltrasonicsArrayById(ultrasonicsArrayId);
409 if (!pRecord) {
410 ALOGE("Asked to close a ultrasonics array whose name isnt not found");
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800411 return {};
Tanmay Patilb97cceb2020-02-07 16:48:39 -0800412 }
413
414 sp<EvsUltrasonicsArray> pActiveUltrasonicsArray = pRecord->activeInstance.promote();
415
416 if (pActiveUltrasonicsArray.get() == nullptr) {
417 ALOGE("Somehow a ultrasonics array is being destroyed when the enumerator didn't know "
418 "one existed");
419 } else if (pActiveUltrasonicsArray != pEvsUltrasonicsArray) {
420 // This can happen if the ultrasonics array was aggressively reopened,
421 // orphaning this previous instance
422 ALOGW("Ignoring close of previously orphaned ultrasonics array - why did a client steal?");
423 } else {
424 // Drop the active ultrasonics array
425 pActiveUltrasonicsArray->forceShutdown();
426 pRecord->activeInstance = nullptr;
427 }
428
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800429 return {};
Tanmay Patil496b86c2020-01-07 17:50:23 -0800430}
431
Changyeon Jo33ba66b2022-01-16 16:33:52 -0800432} // namespace android::hardware::automotive::evs::V1_1::implementation