Update a default HIDL EVS HAL implementation

This CL modifies a default implementation of HIDL EVS HAL v1.1 to
properly emulate IEvsCamera and generate a test pattern (SMPTE color
bars) on the cuttlefish.

Bug: 147743625
Test: launch_cvd --gpu_mode=gfxstream && atest VtsHalEvsV1_1TargetTest
Change-Id: I36b141c250efcc27e9a455d504fe897c69349ad9
diff --git a/automotive/evs/1.1/default/EvsEnumerator.cpp b/automotive/evs/1.1/default/EvsEnumerator.cpp
index d066471..b84268a 100644
--- a/automotive/evs/1.1/default/EvsEnumerator.cpp
+++ b/automotive/evs/1.1/default/EvsEnumerator.cpp
@@ -14,184 +14,171 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.automotive.evs@1.1-service"
-
 #include "EvsEnumerator.h"
 #include "EvsCamera.h"
 #include "EvsDisplay.h"
 #include "EvsUltrasonicsArray.h"
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace evs {
-namespace V1_1 {
-namespace implementation {
+using android::frameworks::automotive::display::V1_0::IAutomotiveDisplayProxyService;
+using android::hardware::automotive::evs::V1_0::EvsResult;
 
+namespace android::hardware::automotive::evs::V1_1::implementation {
+
+namespace evs_v1_0 = ::android::hardware::automotive::evs::V1_0;
 
 // NOTE:  All members values are static so that all clients operate on the same state
 //        That is to say, this is effectively a singleton despite the fact that HIDL
 //        constructs a new instance for each client.
-std::list<EvsEnumerator::CameraRecord>              EvsEnumerator::sCameraList;
-wp<EvsDisplay>                                      EvsEnumerator::sActiveDisplay;
-unique_ptr<ConfigManager>                           EvsEnumerator::sConfigManager;
-sp<IAutomotiveDisplayProxyService>                  EvsEnumerator::sDisplayProxyService;
-std::unordered_map<uint8_t, uint64_t>               EvsEnumerator::sDisplayPortList;
-std::list<EvsEnumerator::UltrasonicsArrayRecord>    EvsEnumerator::sUltrasonicsArrayRecordList;
+std::list<EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
+wp<EvsDisplay> EvsEnumerator::sActiveDisplay;
+std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
+sp<IAutomotiveDisplayProxyService> EvsEnumerator::sDisplayProxyService;
+std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
+std::list<EvsEnumerator::UltrasonicsArrayRecord> EvsEnumerator::sUltrasonicsArrayRecordList;
+uint64_t EvsEnumerator::sInternalDisplayId;
 
-EvsEnumerator::EvsEnumerator(sp<IAutomotiveDisplayProxyService> windowService) {
-    ALOGD("EvsEnumerator created");
+EvsEnumerator::EvsEnumerator(sp<IAutomotiveDisplayProxyService>& windowService) {
+    ALOGD("%s", __FUNCTION__);
 
     // Add sample camera data to our list of cameras
     // In a real driver, this would be expected to can the available hardware
     sConfigManager =
-        ConfigManager::Create("/vendor/etc/automotive/evs/evs_default_configuration.xml");
+            ConfigManager::Create("/vendor/etc/automotive/evs/evs_default_configuration.xml");
 
     // Add available cameras
     for (auto v : sConfigManager->getCameraList()) {
-        sCameraList.emplace_back(v.c_str());
+        CameraRecord rec(v.data());
+        std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(v);
+        if (pInfo) {
+            rec.desc.metadata.setToExternal(reinterpret_cast<uint8_t*>(pInfo->characteristics),
+                                            get_camera_metadata_size(pInfo->characteristics));
+        }
+        sCameraList.push_back(std::move(rec));
     }
 
-    if (sDisplayProxyService == nullptr) {
+    if (!sDisplayProxyService) {
         /* sets a car-window service handle */
         sDisplayProxyService = windowService;
     }
 
     // Add available displays
-    if (sDisplayProxyService != nullptr) {
+    if (sDisplayProxyService) {
         // Get a display ID list.
-        sDisplayProxyService->getDisplayIdList([](const auto& displayIds) {
-            for (const auto& id : displayIds) {
-                const auto port = id & 0xF;
-                sDisplayPortList.insert_or_assign(port, id);
+        auto status = sDisplayProxyService->getDisplayIdList([](const auto& displayIds) {
+            if (displayIds.size() > 0) {
+                sInternalDisplayId = displayIds[0];
+                for (const auto& id : displayIds) {
+                    const auto port = id & 0xF;
+                    sDisplayPortList.insert_or_assign(port, id);
+                }
             }
         });
+
+        if (!status.isOk()) {
+            ALOGE("Failed to read a display list");
+        }
     }
 
     // Add ultrasonics array desc.
-    sUltrasonicsArrayRecordList.emplace_back(
-            EvsUltrasonicsArray::GetMockArrayDesc("front_array"));
+    sUltrasonicsArrayRecordList.emplace_back(EvsUltrasonicsArray::GetMockArrayDesc("front_array"));
 }
 
-
 // Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow.
-Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb)  {
-    ALOGD("getCameraList");
+Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
+    ALOGD("%s", __FUNCTION__);
 
-    const unsigned numCameras = sCameraList.size();
+    const auto numCameras = sCameraList.size();
 
     // Build up a packed array of CameraDesc for return
     // NOTE:  Only has to live until the callback returns
-    std::vector<CameraDesc_1_0> descriptions;
+    std::vector<evs_v1_0::CameraDesc> descriptions;
     descriptions.reserve(numCameras);
     for (const auto& cam : sCameraList) {
-        descriptions.push_back( cam.desc.v1 );
+        descriptions.push_back(cam.desc.v1);
     }
 
     // Encapsulate our camera descriptions in the HIDL vec type
-    hidl_vec<CameraDesc_1_0> hidlCameras(descriptions);
+    hidl_vec<evs_v1_0::CameraDesc> hidlCameras(descriptions);
 
     // Send back the results
     ALOGD("reporting %zu cameras available", hidlCameras.size());
     _hidl_cb(hidlCameras);
-
-    // HIDL convention says we return Void if we sent our result back via callback
-    return Void();
+    return {};
 }
 
-
-Return<sp<IEvsCamera_1_0>> EvsEnumerator::openCamera(const hidl_string& cameraId) {
-    ALOGD("openCamera");
+Return<sp<evs_v1_0::IEvsCamera>> EvsEnumerator::openCamera(const hidl_string& cameraId) {
+    ALOGD("%s", __FUNCTION__);
 
     // Find the named camera
-    CameraRecord *pRecord = nullptr;
-    for (auto &&cam : sCameraList) {
-        if (cam.desc.v1.cameraId == cameraId) {
-            // Found a match!
-            pRecord = &cam;
-            break;
-        }
-    }
-
-    // Is this a recognized camera id?
-    if (!pRecord) {
+    auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
+        return cameraId == cam.desc.v1.cameraId;
+    });
+    if (it == sCameraList.end()) {
         ALOGE("Requested camera %s not found", cameraId.c_str());
         return nullptr;
     }
 
     // Has this camera already been instantiated by another caller?
-    sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
+    sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
     if (pActiveCamera != nullptr) {
         ALOGW("Killing previous camera because of new caller");
         closeCamera(pActiveCamera);
     }
 
     // Construct a camera instance for the caller
-    if (sConfigManager == nullptr) {
+    if (!sConfigManager) {
         pActiveCamera = EvsCamera::Create(cameraId.c_str());
     } else {
-        pActiveCamera = EvsCamera::Create(cameraId.c_str(),
-                                          sConfigManager->getCameraInfo(cameraId));
+        pActiveCamera =
+                EvsCamera::Create(cameraId.c_str(), sConfigManager->getCameraInfo(cameraId));
     }
-    pRecord->activeInstance = pActiveCamera;
-    if (pActiveCamera == nullptr) {
+    it->activeInstance = pActiveCamera;
+    if (!pActiveCamera) {
         ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
     }
 
     return pActiveCamera;
 }
 
+Return<void> EvsEnumerator::closeCamera(const ::android::sp<evs_v1_0::IEvsCamera>& pCamera) {
+    ALOGD("%s", __FUNCTION__);
 
-Return<void> EvsEnumerator::closeCamera(const ::android::sp<IEvsCamera_1_0>& pCamera) {
-    ALOGD("closeCamera");
-
-    auto pCamera_1_1 = IEvsCamera_1_1::castFrom(pCamera).withDefault(nullptr);
-    if (pCamera_1_1 == nullptr) {
+    auto pCamera_1_1 = IEvsCamera::castFrom(pCamera).withDefault(nullptr);
+    if (!pCamera_1_1) {
         ALOGE("Ignoring call to closeCamera with null camera ptr");
-        return Void();
+        return {};
     }
 
     // Get the camera id so we can find it in our list
     std::string cameraId;
-    pCamera_1_1->getCameraInfo_1_1([&cameraId](CameraDesc desc) {
-                               cameraId = desc.v1.cameraId;
-                           }
-    );
+    pCamera_1_1->getCameraInfo_1_1([&cameraId](CameraDesc desc) { cameraId = desc.v1.cameraId; });
 
     // Find the named camera
-    CameraRecord *pRecord = nullptr;
-    for (auto &&cam : sCameraList) {
-        if (cam.desc.v1.cameraId == cameraId) {
-            // Found a match!
-            pRecord = &cam;
-            break;
-        }
+    auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
+        return cameraId == cam.desc.v1.cameraId;
+    });
+    if (it == sCameraList.end()) {
+        ALOGE("Ignores a request to close unknown camera, %s", cameraId.data());
+        return {};
     }
 
-    // Is the display being destroyed actually the one we think is active?
-    if (!pRecord) {
-        ALOGE("Asked to close a camera who's name isn't recognized");
+    sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
+    if (!pActiveCamera) {
+        ALOGE("Somehow a camera is being destroyed when the enumerator didn't know one existed");
+    } else if (pActiveCamera != pCamera_1_1) {
+        // This can happen if the camera was aggressively reopened, orphaning this previous instance
+        ALOGW("Ignoring close of previously orphaned camera - why did a client steal?");
     } else {
-        sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
-
-        if (pActiveCamera == nullptr) {
-            ALOGE("Somehow a camera is being destroyed when the enumerator didn't know one existed");
-        } else if (pActiveCamera != pCamera_1_1) {
-            // This can happen if the camera was aggressively reopened, orphaning this previous instance
-            ALOGW("Ignoring close of previously orphaned camera - why did a client steal?");
-        } else {
-            // Drop the active camera
-            pActiveCamera->forceShutdown();
-            pRecord->activeInstance = nullptr;
-        }
+        // Drop the active camera
+        pActiveCamera->forceShutdown();
+        it->activeInstance = nullptr;
     }
 
-    return Void();
+    return {};
 }
 
-
-Return<sp<IEvsDisplay_1_0>> EvsEnumerator::openDisplay() {
-    ALOGD("openDisplay");
+Return<sp<V1_0::IEvsDisplay>> EvsEnumerator::openDisplay() {
+    ALOGD("%s", __FUNCTION__);
 
     // If we already have a display active, then we need to shut it down so we can
     // give exclusive access to the new caller.
@@ -202,28 +189,25 @@
     }
 
     // Create a new display interface and return it
-    pActiveDisplay = new EvsDisplay();
+    pActiveDisplay = new EvsDisplay(sDisplayProxyService, sInternalDisplayId);
     sActiveDisplay = pActiveDisplay;
 
     ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
     return pActiveDisplay;
 }
 
-
 Return<void> EvsEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
     hidl_vec<uint8_t> ids;
-
     ids.resize(sDisplayPortList.size());
+
     unsigned i = 0;
-    for (const auto& [port, id] : sDisplayPortList) {
-        ids[i++] = port;
-    }
+    std::for_each(sDisplayPortList.begin(), sDisplayPortList.end(),
+                  [&](const auto& element) { ids[i++] = element.first; });
 
     _list_cb(ids);
-    return Void();
+    return {};
 }
 
-
 Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay_1_1(uint8_t port) {
     ALOGD("%s", __FUNCTION__);
 
@@ -243,10 +227,8 @@
     return pActiveDisplay;
 }
 
-
-
-Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay_1_0>& pDisplay) {
-    ALOGD("closeDisplay");
+Return<void> EvsEnumerator::closeDisplay(const ::android::sp<V1_0::IEvsDisplay>& pDisplay) {
+    ALOGD("%s", __FUNCTION__);
 
     // Do we still have a display object we think should be active?
     sp<EvsDisplay> pActiveDisplay = sActiveDisplay.promote();
@@ -260,123 +242,111 @@
         sActiveDisplay = nullptr;
     }
 
-    return Void();
+    return {};
 }
 
-
-Return<DisplayState> EvsEnumerator::getDisplayState()  {
-    ALOGD("getDisplayState");
+Return<V1_0::DisplayState> EvsEnumerator::getDisplayState() {
+    ALOGD("%s", __FUNCTION__);
 
     // Do we still have a display object we think should be active?
     sp<IEvsDisplay> pActiveDisplay = sActiveDisplay.promote();
     if (pActiveDisplay != nullptr) {
         return pActiveDisplay->getDisplayState();
     } else {
-        return DisplayState::NOT_OPEN;
+        return V1_0::DisplayState::NOT_OPEN;
     }
 }
 
-
 // Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow.
-Return<void> EvsEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb)  {
-    ALOGD("getCameraList");
+Return<void> EvsEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
+    ALOGD("%s", __FUNCTION__);
 
-    const unsigned numCameras = sCameraList.size();
+    const auto numCameras = sCameraList.size();
 
     // Build up a packed array of CameraDesc for return
     // NOTE:  Only has to live until the callback returns
-    std::vector<CameraDesc_1_1> descriptions;
+    std::vector<CameraDesc> descriptions;
     descriptions.reserve(numCameras);
-    for (const auto& cam : sCameraList) {
-        descriptions.push_back( cam.desc );
-    }
+    std::for_each(sCameraList.begin(), sCameraList.end(),
+                  [&](const auto& cam) { descriptions.push_back(cam.desc); });
 
     // Encapsulate our camera descriptions in the HIDL vec type
-    hidl_vec<CameraDesc_1_1> hidlCameras(descriptions);
+    hidl_vec<CameraDesc> hidlCameras(descriptions);
 
     // Send back the results
     ALOGD("reporting %zu cameras available", hidlCameras.size());
     _hidl_cb(hidlCameras);
-
-    // HIDL convention says we return Void if we sent our result back via callback
-    return Void();
+    return {};
 }
 
-Return<sp<IEvsCamera_1_1>>
-EvsEnumerator::openCamera_1_1(const hidl_string& cameraId,
-                              const Stream& streamCfg) {
-    // Find the named camera
-    CameraRecord *pRecord = nullptr;
-    for (auto &&cam : sCameraList) {
-        if (cam.desc.v1.cameraId == cameraId) {
-            // Found a match!
-            pRecord = &cam;
-            break;
-        }
-    }
+Return<sp<IEvsCamera>> EvsEnumerator::openCamera_1_1(const hidl_string& cameraId,
+                                                     const Stream& streamCfg) {
+    ALOGD("%s", __FUNCTION__);
 
-    // Is this a recognized camera id?
-    if (!pRecord) {
+    // Find the named camera
+    auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
+        return cameraId == cam.desc.v1.cameraId;
+    });
+    if (it == sCameraList.end()) {
         ALOGE("Requested camera %s not found", cameraId.c_str());
         return nullptr;
     }
 
     // Has this camera already been instantiated by another caller?
-    sp<EvsCamera> pActiveCamera = pRecord->activeInstance.promote();
+    sp<EvsCamera> pActiveCamera = it->activeInstance.promote();
     if (pActiveCamera != nullptr) {
         ALOGW("Killing previous camera because of new caller");
         closeCamera(pActiveCamera);
     }
 
     // Construct a camera instance for the caller
-    if (sConfigManager == nullptr) {
+    if (!sConfigManager) {
         pActiveCamera = EvsCamera::Create(cameraId.c_str());
     } else {
-        pActiveCamera = EvsCamera::Create(cameraId.c_str(),
-                                          sConfigManager->getCameraInfo(cameraId),
+        pActiveCamera = EvsCamera::Create(cameraId.c_str(), sConfigManager->getCameraInfo(cameraId),
                                           &streamCfg);
     }
 
-    pRecord->activeInstance = pActiveCamera;
-    if (pActiveCamera == nullptr) {
+    it->activeInstance = pActiveCamera;
+    if (!pActiveCamera) {
         ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str());
     }
 
     return pActiveCamera;
 }
 
-
 EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
-    // Find the named camera
-    CameraRecord *pRecord = nullptr;
-    for (auto &&cam : sCameraList) {
-        if (cam.desc.v1.cameraId == cameraId) {
-            // Found a match!
-            pRecord = &cam;
-            break;
-        }
-    }
+    ALOGD("%s", __FUNCTION__);
 
-    return pRecord;
+    // Find the named camera
+    auto it = std::find_if(sCameraList.begin(), sCameraList.end(), [&cameraId](const auto& cam) {
+        return cameraId == cam.desc.v1.cameraId;
+    });
+    return (it != sCameraList.end()) ? &*it : nullptr;
 }
 
 EvsEnumerator::UltrasonicsArrayRecord* EvsEnumerator::findUltrasonicsArrayById(
         const std::string& ultrasonicsArrayId) {
-    auto recordIt = std::find_if(
-            sUltrasonicsArrayRecordList.begin(), sUltrasonicsArrayRecordList.end(),
-                    [&ultrasonicsArrayId](const UltrasonicsArrayRecord& record) {
-                            return ultrasonicsArrayId == record.desc.ultrasonicsArrayId;});
+    ALOGD("%s", __FUNCTION__);
+
+    auto recordIt =
+            std::find_if(sUltrasonicsArrayRecordList.begin(), sUltrasonicsArrayRecordList.end(),
+                         [&ultrasonicsArrayId](const UltrasonicsArrayRecord& record) {
+                             return ultrasonicsArrayId == record.desc.ultrasonicsArrayId;
+                         });
 
     return (recordIt != sUltrasonicsArrayRecordList.end()) ? &*recordIt : nullptr;
 }
 
 Return<void> EvsEnumerator::getUltrasonicsArrayList(getUltrasonicsArrayList_cb _hidl_cb) {
+    ALOGD("%s", __FUNCTION__);
+
     hidl_vec<UltrasonicsArrayDesc> desc;
     desc.resize(sUltrasonicsArrayRecordList.size());
 
     // Copy over desc from sUltrasonicsArrayRecordList.
     for (auto p = std::make_pair(sUltrasonicsArrayRecordList.begin(), desc.begin());
-            p.first != sUltrasonicsArrayRecordList.end(); p.first++, p.second++) {
+         p.first != sUltrasonicsArrayRecordList.end(); p.first++, p.second++) {
         *p.second = p.first->desc;
     }
 
@@ -385,11 +355,13 @@
     _hidl_cb(desc);
 
     // HIDL convention says we return Void if we sent our result back via callback
-    return Void();
+    return {};
 }
 
 Return<sp<IEvsUltrasonicsArray>> EvsEnumerator::openUltrasonicsArray(
         const hidl_string& ultrasonicsArrayId) {
+    ALOGD("%s", __FUNCTION__);
+
     // Find the named ultrasonic array.
     UltrasonicsArrayRecord* pRecord = findUltrasonicsArrayById(ultrasonicsArrayId);
 
@@ -419,10 +391,11 @@
 
 Return<void> EvsEnumerator::closeUltrasonicsArray(
         const sp<IEvsUltrasonicsArray>& pEvsUltrasonicsArray) {
+    ALOGD("%s", __FUNCTION__);
 
     if (pEvsUltrasonicsArray.get() == nullptr) {
         ALOGE("Ignoring call to closeUltrasonicsArray with null ultrasonics array");
-        return Void();
+        return {};
     }
 
     // Get the ultrasonics array id so we can find it in our list.
@@ -435,7 +408,7 @@
     UltrasonicsArrayRecord* pRecord = findUltrasonicsArrayById(ultrasonicsArrayId);
     if (!pRecord) {
         ALOGE("Asked to close a ultrasonics array whose name isnt not found");
-        return Void();
+        return {};
     }
 
     sp<EvsUltrasonicsArray> pActiveUltrasonicsArray = pRecord->activeInstance.promote();
@@ -453,12 +426,7 @@
         pRecord->activeInstance = nullptr;
     }
 
-    return Void();
+    return {};
 }
 
-} // namespace implementation
-} // namespace V1_1
-} // namespace evs
-} // namespace automotive
-} // namespace hardware
-} // namespace android
+}  // namespace android::hardware::automotive::evs::V1_1::implementation