• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "EvsEnumerator.h"
18 
19 #include "ConfigManager.h"
20 #include "EvsAllCameras.h"
21 #include "EvsCameraBase.h"
22 #include "EvsGlDisplay.h"
23 
24 #include <aidl/android/hardware/automotive/evs/EvsResult.h>
25 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
26 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
27 #include <cutils/android_filesystem_config.h>
28 
29 #include <set>
30 #include <string_view>
31 
32 namespace {
33 
34 using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
35 using ::aidl::android::hardware::graphics::common::BufferUsage;
36 using ::ndk::ScopedAStatus;
37 using std::chrono_literals::operator""s;
38 
39 // Constants
40 constexpr std::chrono::seconds kEnumerationTimeout = 10s;
41 constexpr uint64_t kInvalidDisplayId = std::numeric_limits<uint64_t>::max();
42 const std::set<uid_t> kAllowedUids = {AID_AUTOMOTIVE_EVS, AID_SYSTEM, AID_ROOT};
43 
44 }  // namespace
45 
46 namespace aidl::android::hardware::automotive::evs::implementation {
47 
48 // NOTE:  All members values are static so that all clients operate on the same state
49 //        That is to say, this is effectively a singleton despite the fact that HIDL
50 //        constructs a new instance for each client.
51 std::unordered_map<std::string, EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
52 std::mutex EvsEnumerator::sLock;
53 std::condition_variable EvsEnumerator::sCameraSignal;
54 std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
55 std::shared_ptr<ICarDisplayProxy> EvsEnumerator::sDisplayProxy;
56 std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
57 
mutableActiveDisplays()58 EvsEnumerator::ActiveDisplays& EvsEnumerator::mutableActiveDisplays() {
59     static ActiveDisplays active_displays;
60     return active_displays;
61 }
62 
EvsEnumerator(const std::shared_ptr<ICarDisplayProxy> & proxyService)63 EvsEnumerator::EvsEnumerator(const std::shared_ptr<ICarDisplayProxy>& proxyService) {
64     LOG(DEBUG) << "EvsEnumerator is created.";
65 
66     if (!sConfigManager) {
67         /* loads and initializes ConfigManager in a separate thread */
68         sConfigManager = ConfigManager::Create();
69     }
70 
71     if (!sDisplayProxy) {
72         /* sets a car-window service handle */
73         sDisplayProxy = proxyService;
74     }
75 
76     // Enumerate existing devices
77     enumerateCameras();
78     mInternalDisplayId = enumerateDisplays();
79 }
80 
checkPermission()81 bool EvsEnumerator::checkPermission() {
82     const auto uid = AIBinder_getCallingUid();
83     if (kAllowedUids.find(uid) == kAllowedUids.end()) {
84         LOG(ERROR) << "EVS access denied: "
85                    << "pid = " << AIBinder_getCallingPid() << ", uid = " << uid;
86         return false;
87     }
88 
89     return true;
90 }
91 
enumerateCameras()92 void EvsEnumerator::enumerateCameras() {
93     if (!sConfigManager) {
94         return;
95     }
96 
97     for (auto id : sConfigManager->getCameraIdList()) {
98         CameraRecord rec(id.data());
99         std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(id);
100         if (pInfo) {
101             uint8_t* ptr = reinterpret_cast<uint8_t*>(pInfo->characteristics);
102             const size_t len = get_camera_metadata_size(pInfo->characteristics);
103             rec.desc.metadata.insert(rec.desc.metadata.end(), ptr, ptr + len);
104         }
105         sCameraList.insert_or_assign(id, std::move(rec));
106     }
107 }
108 
enumerateDisplays()109 uint64_t EvsEnumerator::enumerateDisplays() {
110     LOG(INFO) << __FUNCTION__ << ": Starting display enumeration";
111     uint64_t internalDisplayId = kInvalidDisplayId;
112     if (!sDisplayProxy) {
113         LOG(ERROR) << "ICarDisplayProxy is not available!";
114         return internalDisplayId;
115     }
116 
117     std::vector<int64_t> displayIds;
118     if (auto status = sDisplayProxy->getDisplayIdList(&displayIds); !status.isOk()) {
119         LOG(ERROR) << "Failed to retrieve a display id list"
120                    << ::android::statusToString(status.getStatus());
121         return internalDisplayId;
122     }
123 
124     if (displayIds.size() > 0) {
125         // The first entry of the list is the internal display.  See
126         // SurfaceFlinger::getPhysicalDisplayIds() implementation.
127         internalDisplayId = displayIds[0];
128         for (const auto& id : displayIds) {
129             const auto port = id & 0xFF;
130             LOG(INFO) << "Display " << std::hex << id << " is detected on the port, " << port;
131             sDisplayPortList.insert_or_assign(port, id);
132         }
133     }
134 
135     LOG(INFO) << "Found " << sDisplayPortList.size() << " displays";
136     return internalDisplayId;
137 }
138 
139 // Methods from ::android::hardware::automotive::evs::IEvsEnumerator follow.
getCameraList(std::vector<CameraDesc> * _aidl_return)140 ScopedAStatus EvsEnumerator::getCameraList(std::vector<CameraDesc>* _aidl_return) {
141     LOG(DEBUG) << __FUNCTION__;
142     if (!checkPermission()) {
143         return ScopedAStatus::fromServiceSpecificError(
144                 static_cast<int>(EvsResult::PERMISSION_DENIED));
145     }
146 
147     {
148         std::unique_lock<std::mutex> lock(sLock);
149         if (sCameraList.size() < 1) {
150             // No qualified device has been found.  Wait until new device is ready,
151             // for 10 seconds.
152             if (!sCameraSignal.wait_for(lock, kEnumerationTimeout,
153                                         [] { return sCameraList.size() > 0; })) {
154                 LOG(DEBUG) << "Timer expired.  No new device has been added.";
155             }
156         }
157     }
158 
159     // Build up a packed array of CameraDesc for return
160     _aidl_return->resize(sCameraList.size());
161     unsigned i = 0;
162     for (const auto& [key, cam] : sCameraList) {
163         (*_aidl_return)[i++] = cam.desc;
164     }
165 
166     if (sConfigManager) {
167         // Adding camera groups that represent logical camera devices
168         auto camGroups = sConfigManager->getCameraGroupIdList();
169         for (auto&& id : camGroups) {
170             if (sCameraList.find(id) != sCameraList.end()) {
171                 // Already exists in the _aidl_return
172                 continue;
173             }
174 
175             std::unique_ptr<ConfigManager::CameraGroupInfo>& tempInfo =
176                     sConfigManager->getCameraGroupInfo(id);
177             CameraRecord cam(id.data());
178             if (tempInfo) {
179                 uint8_t* ptr = reinterpret_cast<uint8_t*>(tempInfo->characteristics);
180                 const size_t len = get_camera_metadata_size(tempInfo->characteristics);
181                 cam.desc.metadata.insert(cam.desc.metadata.end(), ptr, ptr + len);
182             }
183 
184             sCameraList.insert_or_assign(id, cam);
185             _aidl_return->push_back(cam.desc);
186         }
187     }
188 
189     // Send back the results
190     LOG(DEBUG) << "Reporting " << sCameraList.size() << " cameras available";
191     return ScopedAStatus::ok();
192 }
193 
getStreamList(const CameraDesc & desc,std::vector<Stream> * _aidl_return)194 ScopedAStatus EvsEnumerator::getStreamList(const CameraDesc& desc,
195                                            std::vector<Stream>* _aidl_return) {
196     using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
197 
198     camera_metadata_t* pMetadata = const_cast<camera_metadata_t*>(
199             reinterpret_cast<const camera_metadata_t*>(desc.metadata.data()));
200     camera_metadata_entry_t streamConfig;
201     if (!find_camera_metadata_entry(pMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
202                                     &streamConfig)) {
203         const unsigned numStreamConfigs = streamConfig.count / sizeof(StreamConfiguration);
204         _aidl_return->resize(numStreamConfigs);
205         const StreamConfiguration* pCurrentConfig =
206                 reinterpret_cast<StreamConfiguration*>(streamConfig.data.i32);
207         for (unsigned i = 0; i < numStreamConfigs; ++i, ++pCurrentConfig) {
208             // Build ::aidl::android::hardware::automotive::evs::Stream from
209             // StreamConfiguration.
210             Stream current = {
211                     .id = pCurrentConfig->id,
212                     .streamType =
213                             pCurrentConfig->type ==
214                                             ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
215                                     ? StreamType::INPUT
216                                     : StreamType::OUTPUT,
217                     .width = pCurrentConfig->width,
218                     .height = pCurrentConfig->height,
219                     .format = static_cast<AidlPixelFormat>(pCurrentConfig->format),
220                     .usage = BufferUsage::CAMERA_INPUT,
221                     .rotation = Rotation::ROTATION_0,
222             };
223 
224             (*_aidl_return)[i] = current;
225         }
226     }
227 
228     return ScopedAStatus::ok();
229 }
230 
openCamera(const std::string & id,const Stream & cfg,std::shared_ptr<IEvsCamera> * obj)231 ScopedAStatus EvsEnumerator::openCamera(const std::string& id, const Stream& cfg,
232                                         std::shared_ptr<IEvsCamera>* obj) {
233     LOG(DEBUG) << __FUNCTION__;
234     if (!checkPermission()) {
235         return ScopedAStatus::fromServiceSpecificError(
236                 static_cast<int>(EvsResult::PERMISSION_DENIED));
237     }
238 
239     // Is this a recognized camera id?
240     CameraRecord* pRecord = findCameraById(id);
241     if (!pRecord) {
242         LOG(ERROR) << id << " does not exist!";
243         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
244     }
245 
246     // Has this camera already been instantiated by another caller?
247     std::shared_ptr<EvsCameraBase> pActiveCamera = pRecord->activeInstance.lock();
248     if (pActiveCamera) {
249         LOG(WARNING) << "Killing previous camera because of new caller";
250         closeCamera(pActiveCamera);
251     }
252 
253     // Construct a camera instance for the caller
254     if (!sConfigManager) {
255         pActiveCamera = EvsMockCamera::Create(id.data());
256     } else {
257         auto& cameraInfo = sConfigManager->getCameraInfo(id);
258         switch (cameraInfo->deviceType) {
259             using DeviceType = ConfigManager::CameraInfo::DeviceType;
260 
261             // Default to MOCK for backward compatibility.
262             case DeviceType::NONE:
263             case DeviceType::MOCK:
264                 pActiveCamera = EvsMockCamera::Create(id.data(), cameraInfo, &cfg);
265                 break;
266 
267             case DeviceType::VIDEO:
268                 pActiveCamera = EvsVideoEmulatedCamera::Create(id.data(), cameraInfo, &cfg);
269                 break;
270 
271             default:
272                 LOG(ERROR) << __func__ << ": camera device type "
273                            << static_cast<std::int32_t>(cameraInfo->deviceType)
274                            << " is not supported.";
275                 break;
276         }
277     }
278 
279     pRecord->activeInstance = pActiveCamera;
280     if (!pActiveCamera) {
281         LOG(ERROR) << "Failed to create new EVS camera object for " << id;
282         return ScopedAStatus::fromServiceSpecificError(
283                 static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
284     }
285 
286     *obj = pActiveCamera;
287     return ScopedAStatus::ok();
288 }
289 
closeCamera(const std::shared_ptr<IEvsCamera> & cameraObj)290 ScopedAStatus EvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& cameraObj) {
291     LOG(DEBUG) << __FUNCTION__;
292 
293     if (!cameraObj) {
294         LOG(ERROR) << "Ignoring call to closeCamera with null camera ptr";
295         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
296     }
297 
298     // Get the camera id so we can find it in our list
299     CameraDesc desc;
300     auto status = cameraObj->getCameraInfo(&desc);
301     if (!status.isOk()) {
302         LOG(ERROR) << "Failed to read a camera descriptor";
303         return ScopedAStatus::fromServiceSpecificError(
304                 static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
305     }
306     auto cameraId = desc.id;
307     closeCamera_impl(cameraObj, cameraId);
308     return ScopedAStatus::ok();
309 }
310 
openDisplay(int32_t id,std::shared_ptr<IEvsDisplay> * displayObj)311 ScopedAStatus EvsEnumerator::openDisplay(int32_t id, std::shared_ptr<IEvsDisplay>* displayObj) {
312     LOG(DEBUG) << __FUNCTION__;
313     if (!checkPermission()) {
314         return ScopedAStatus::fromServiceSpecificError(
315                 static_cast<int>(EvsResult::PERMISSION_DENIED));
316     }
317 
318     auto& displays = mutableActiveDisplays();
319 
320     if (auto existing_display_search = displays.popDisplay(id)) {
321         // If we already have a display active, then we need to shut it down so we can
322         // give exclusive access to the new caller.
323         std::shared_ptr<EvsGlDisplay> pActiveDisplay = existing_display_search->displayWeak.lock();
324         if (pActiveDisplay) {
325             LOG(WARNING) << "Killing previous display because of new caller";
326             pActiveDisplay->forceShutdown();
327         }
328     }
329 
330     // Create a new display interface and return it
331     uint64_t targetDisplayId = mInternalDisplayId;
332     auto it = sDisplayPortList.find(id);
333     if (it != sDisplayPortList.end()) {
334         targetDisplayId = it->second;
335     } else {
336         LOG(WARNING) << "No display is available on the port " << static_cast<int32_t>(id)
337                      << ". The main display " << mInternalDisplayId << " will be used instead";
338     }
339 
340     // Create a new display interface and return it.
341     std::shared_ptr<EvsGlDisplay> pActiveDisplay =
342             ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, targetDisplayId);
343 
344     if (auto insert_result = displays.tryInsert(id, pActiveDisplay); !insert_result) {
345         LOG(ERROR) << "Display ID " << id << " has been used by another caller.";
346         pActiveDisplay->forceShutdown();
347         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::RESOURCE_BUSY));
348     }
349 
350     LOG(DEBUG) << "Returning new EvsGlDisplay object " << pActiveDisplay.get();
351     *displayObj = pActiveDisplay;
352     return ScopedAStatus::ok();
353 }
354 
closeDisplay(const std::shared_ptr<IEvsDisplay> & obj)355 ScopedAStatus EvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& obj) {
356     LOG(DEBUG) << __FUNCTION__;
357 
358     auto& displays = mutableActiveDisplays();
359     const auto display_search = displays.popDisplay(obj);
360 
361     if (!display_search) {
362         LOG(WARNING) << "Ignoring close of previously orphaned display - why did a client steal?";
363         return ScopedAStatus::ok();
364     }
365 
366     auto pActiveDisplay = display_search->displayWeak.lock();
367 
368     if (!pActiveDisplay) {
369         LOG(ERROR) << "Somehow a display is being destroyed "
370                    << "when the enumerator didn't know one existed";
371         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
372     }
373 
374     pActiveDisplay->forceShutdown();
375     return ScopedAStatus::ok();
376 }
377 
getDisplayState(DisplayState * state)378 ScopedAStatus EvsEnumerator::getDisplayState(DisplayState* state) {
379     LOG(DEBUG) << __FUNCTION__;
380     return getDisplayStateImpl(std::nullopt, state);
381 }
382 
getDisplayStateById(int32_t displayId,DisplayState * state)383 ScopedAStatus EvsEnumerator::getDisplayStateById(int32_t displayId, DisplayState* state) {
384     LOG(DEBUG) << __FUNCTION__;
385     return getDisplayStateImpl(displayId, state);
386 }
387 
getDisplayStateImpl(std::optional<int32_t> displayId,DisplayState * state)388 ScopedAStatus EvsEnumerator::getDisplayStateImpl(std::optional<int32_t> displayId,
389                                                  DisplayState* state) {
390     if (!checkPermission()) {
391         *state = DisplayState::DEAD;
392         return ScopedAStatus::fromServiceSpecificError(
393                 static_cast<int>(EvsResult::PERMISSION_DENIED));
394     }
395 
396     const auto& all_displays = mutableActiveDisplays().getAllDisplays();
397 
398     const auto display_search = displayId ? all_displays.find(*displayId) : all_displays.begin();
399 
400     if (display_search == all_displays.end()) {
401         *state = DisplayState::NOT_OPEN;
402         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
403     }
404 
405     std::shared_ptr<IEvsDisplay> pActiveDisplay = display_search->second.displayWeak.lock();
406     if (pActiveDisplay) {
407         return pActiveDisplay->getDisplayState(state);
408     } else {
409         *state = DisplayState::NOT_OPEN;
410         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
411     }
412 }
413 
getDisplayIdList(std::vector<uint8_t> * list)414 ScopedAStatus EvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
415     std::vector<uint8_t>& output = *list;
416     if (sDisplayPortList.size() > 0) {
417         output.resize(sDisplayPortList.size());
418         unsigned i = 0;
419         output[i++] = mInternalDisplayId & 0xFF;
420         for (const auto& [port, id] : sDisplayPortList) {
421             if (mInternalDisplayId != id) {
422                 output[i++] = port;
423             }
424         }
425     }
426 
427     return ScopedAStatus::ok();
428 }
429 
isHardware(bool * flag)430 ScopedAStatus EvsEnumerator::isHardware(bool* flag) {
431     *flag = true;
432     return ScopedAStatus::ok();
433 }
434 
notifyDeviceStatusChange(const std::string_view & deviceName,DeviceStatusType type)435 void EvsEnumerator::notifyDeviceStatusChange(const std::string_view& deviceName,
436                                              DeviceStatusType type) {
437     std::lock_guard lock(sLock);
438     if (!mCallback) {
439         return;
440     }
441 
442     std::vector<DeviceStatus> status{{.id = std::string(deviceName), .status = type}};
443     if (!mCallback->deviceStatusChanged(status).isOk()) {
444         LOG(WARNING) << "Failed to notify a device status change, name = " << deviceName
445                      << ", type = " << static_cast<int>(type);
446     }
447 }
448 
registerStatusCallback(const std::shared_ptr<IEvsEnumeratorStatusCallback> & callback)449 ScopedAStatus EvsEnumerator::registerStatusCallback(
450         const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
451     std::lock_guard lock(sLock);
452     if (mCallback) {
453         LOG(INFO) << "Replacing an existing device status callback";
454     }
455     mCallback = callback;
456     return ScopedAStatus::ok();
457 }
458 
closeCamera_impl(const std::shared_ptr<IEvsCamera> & pCamera,const std::string & cameraId)459 void EvsEnumerator::closeCamera_impl(const std::shared_ptr<IEvsCamera>& pCamera,
460                                      const std::string& cameraId) {
461     // Find the named camera
462     CameraRecord* pRecord = findCameraById(cameraId);
463 
464     // Is the display being destroyed actually the one we think is active?
465     if (!pRecord) {
466         LOG(ERROR) << "Asked to close a camera whose name isn't recognized";
467     } else {
468         std::shared_ptr<EvsCameraBase> pActiveCamera = pRecord->activeInstance.lock();
469         if (!pActiveCamera) {
470             LOG(WARNING) << "Somehow a camera is being destroyed "
471                          << "when the enumerator didn't know one existed";
472         } else if (pActiveCamera != pCamera) {
473             // This can happen if the camera was aggressively reopened,
474             // orphaning this previous instance
475             LOG(WARNING) << "Ignoring close of previously orphaned camera "
476                          << "- why did a client steal?";
477         } else {
478             // Shutdown the active camera
479             pActiveCamera->shutdown();
480         }
481     }
482 
483     return;
484 }
485 
findCameraById(const std::string & cameraId)486 EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
487     // Find the named camera
488     auto found = sCameraList.find(cameraId);
489     if (found != sCameraList.end()) {
490         // Found a match!
491         return &found->second;
492     }
493 
494     // We didn't find a match
495     return nullptr;
496 }
497 
popDisplay(int32_t id)498 std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
499         int32_t id) {
500     std::lock_guard lck(mMutex);
501     const auto search = mIdToDisplay.find(id);
502     if (search == mIdToDisplay.end()) {
503         return std::nullopt;
504     }
505     const auto display_info = search->second;
506     mIdToDisplay.erase(search);
507     mDisplayToId.erase(display_info.internalDisplayRawAddr);
508     return display_info;
509 }
510 
popDisplay(const std::shared_ptr<IEvsDisplay> & display)511 std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
512         const std::shared_ptr<IEvsDisplay>& display) {
513     const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
514     std::lock_guard lck(mMutex);
515     const auto display_to_id_search = mDisplayToId.find(display_ptr_val);
516     if (display_to_id_search == mDisplayToId.end()) {
517         LOG(ERROR) << "Unknown display.";
518         return std::nullopt;
519     }
520     const auto id = display_to_id_search->second;
521     const auto id_to_display_search = mIdToDisplay.find(id);
522     mDisplayToId.erase(display_to_id_search);
523     if (id_to_display_search == mIdToDisplay.end()) {
524         LOG(ERROR) << "No correspsonding ID for the display, probably orphaned.";
525         return std::nullopt;
526     }
527     const auto display_info = id_to_display_search->second;
528     mIdToDisplay.erase(id);
529     return display_info;
530 }
531 
532 std::unordered_map<int32_t, EvsEnumerator::ActiveDisplays::DisplayInfo>
getAllDisplays()533 EvsEnumerator::ActiveDisplays::getAllDisplays() {
534     std::lock_guard lck(mMutex);
535     auto id_to_display_map_copy = mIdToDisplay;
536     return id_to_display_map_copy;
537 }
538 
tryInsert(int32_t id,const std::shared_ptr<EvsGlDisplay> & display)539 bool EvsEnumerator::ActiveDisplays::tryInsert(int32_t id,
540                                               const std::shared_ptr<EvsGlDisplay>& display) {
541     std::lock_guard lck(mMutex);
542     const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
543 
544     auto id_to_display_insert_result =
545             mIdToDisplay.emplace(id, DisplayInfo{
546                                              .id = id,
547                                              .displayWeak = display,
548                                              .internalDisplayRawAddr = display_ptr_val,
549                                      });
550     if (!id_to_display_insert_result.second) {
551         return false;
552     }
553     auto display_to_id_insert_result = mDisplayToId.emplace(display_ptr_val, id);
554     if (!display_to_id_insert_result.second) {
555         mIdToDisplay.erase(id);
556         return false;
557     }
558     return true;
559 }
560 
getUltrasonicsArrayList(std::vector<UltrasonicsArrayDesc> * list)561 ScopedAStatus EvsEnumerator::getUltrasonicsArrayList(
562         [[maybe_unused]] std::vector<UltrasonicsArrayDesc>* list) {
563     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
564     return ScopedAStatus::ok();
565 }
566 
openUltrasonicsArray(const std::string & id,std::shared_ptr<IEvsUltrasonicsArray> * obj)567 ScopedAStatus EvsEnumerator::openUltrasonicsArray(
568         [[maybe_unused]] const std::string& id,
569         [[maybe_unused]] std::shared_ptr<IEvsUltrasonicsArray>* obj) {
570     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
571     return ScopedAStatus::ok();
572 }
573 
closeUltrasonicsArray(const std::shared_ptr<IEvsUltrasonicsArray> & obj)574 ScopedAStatus EvsEnumerator::closeUltrasonicsArray(
575         [[maybe_unused]] const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
576     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
577     return ScopedAStatus::ok();
578 }
579 
580 }  // namespace aidl::android::hardware::automotive::evs::implementation
581