Fix issues in wrapper classes

- AidlCamera's constructor takes an additional parameter that makes it
  use android::hardware::automotive::evs::V1_0 methods even if a passed
  IEvsCamera object implements
  android::hardware::automotive::evs::V1_1::IEvsCamera. This makes it
  work properly when cameras are open via AidlEnumerator object.
- AidlEnumerator stores a weak pointer of an active display handle and
  use it to check the status of current display client.
- HidlCameraStream::deliverFrame() method programs a timestamp and
  a device id, which is stored in AidlCamera object. These two fields
  make a frame delivery logic handle frame buffers properly through
  android::hardware::automotive::evs::V1_0 methods.
- Fix a logic to count number of stream configurations in camera
  metadata.
- Initialize a vector container with a proper size in
  HidlCamera::setExtendedInfo() method.
- Check an wrapped object before making a call.
- Modify HIDL EVS method implementations to return a proper status code
  if they do not return a EvsResult.
- Introduce kDisplayIdUnavailable and use it to support HIDL
  IEvsEnumerator::openDisplay() method properly.

Bug: 263438927
Bug: 263896317
Test: atest evsmanagerd_test VtsHalEvsTargetTest VtsHalEvsV1_1TargetTest
Change-Id: I5dcaa9375d93665c3519080abb36ddd7174aebe3
diff --git a/cpp/evs/manager/aidl/Android.bp b/cpp/evs/manager/aidl/Android.bp
index 4b47daf..f3f8207 100644
--- a/cpp/evs/manager/aidl/Android.bp
+++ b/cpp/evs/manager/aidl/Android.bp
@@ -156,7 +156,10 @@
 cc_test_library {
     name: "libmockevshal",
     defaults: ["android.hardware.graphics.common-ndk_static"],
-    local_include_dirs: ["tests/include"],
+    local_include_dirs: [
+        "include",
+        "tests/include"
+    ],
     export_include_dirs: ["tests/include"],
     srcs: ["tests/src/MockEvsHal.cpp"],
     shared_libs: [
diff --git a/cpp/evs/manager/aidl/include/Constants.h b/cpp/evs/manager/aidl/include/Constants.h
new file mode 100644
index 0000000..39d2548
--- /dev/null
+++ b/cpp/evs/manager/aidl/include/Constants.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cinttypes>
+#include <limits>
+
+inline constexpr int32_t kDisplayIdUnavailable = std::numeric_limits<int32_t>::min();
+inline constexpr int32_t kExclusiveDisplayId = std::numeric_limits<uint8_t>::max();
diff --git a/cpp/evs/manager/aidl/include/Enumerator.h b/cpp/evs/manager/aidl/include/Enumerator.h
index a81c314..07fbec1 100644
--- a/cpp/evs/manager/aidl/include/Enumerator.h
+++ b/cpp/evs/manager/aidl/include/Enumerator.h
@@ -117,7 +117,7 @@
     std::vector<uint8_t> mDisplayPorts;
 
     // Display port the internal display is connected to.
-    uint8_t mInternalDisplayPort;
+    int32_t mInternalDisplayPort;
 
     // Collecting camera usage statistics from clients
     ::android::sp<StatsCollector> mClientsMonitor;
diff --git a/cpp/evs/manager/aidl/include/HalDisplay.h b/cpp/evs/manager/aidl/include/HalDisplay.h
index bb2c01b..94cfd89 100644
--- a/cpp/evs/manager/aidl/include/HalDisplay.h
+++ b/cpp/evs/manager/aidl/include/HalDisplay.h
@@ -17,17 +17,15 @@
 #ifndef CPP_EVS_MANAGER_AIDL_INCLUDE_HALDISPLAY_H
 #define CPP_EVS_MANAGER_AIDL_INCLUDE_HALDISPLAY_H
 
+#include "Constants.h"
+
 #include <aidl/android/hardware/automotive/evs/BnEvsDisplay.h>
 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
 #include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
 #include <aidl/android/hardware/automotive/evs/DisplayState.h>
 
-#include <limits>
-
 namespace aidl::android::automotive::evs::implementation {
 
-inline constexpr int32_t kInvalidDisplayId = std::numeric_limits<int32_t>::min();
-
 namespace aidlevs = ::aidl::android::hardware::automotive::evs;
 
 class HalDisplay : public ::aidl::android::hardware::automotive::evs::BnEvsDisplay {
@@ -40,7 +38,7 @@
     ::ndk::ScopedAStatus setDisplayState(aidlevs::DisplayState state) override;
 
     explicit HalDisplay(std::shared_ptr<aidlevs::IEvsDisplay> display,
-                        int32_t port = kInvalidDisplayId);
+                        int32_t port = kDisplayIdUnavailable);
     virtual ~HalDisplay();
 
     inline void shutdown();
diff --git a/cpp/evs/manager/aidl/src/Enumerator.cpp b/cpp/evs/manager/aidl/src/Enumerator.cpp
index da6a42a..ad6d4d4 100644
--- a/cpp/evs/manager/aidl/src/Enumerator.cpp
+++ b/cpp/evs/manager/aidl/src/Enumerator.cpp
@@ -64,9 +64,6 @@
 constexpr int kOptionDumpCameraCommandIndex = 3;
 constexpr int kOptionDumpCameraArgsStartIndex = 4;
 
-// Display ID 255 is reserved for the special purpose.
-constexpr int kExclusiveMainDisplayId = 255;
-
 // Parameters for HAL connection
 constexpr int64_t kSleepTimeMilliseconds = 1000;
 constexpr int64_t kTimeoutMilliseconds = 30000;
@@ -159,20 +156,25 @@
     }
 
     // Get a list of available displays and identify the internal display
-    if (!mHwEnumerator->getDisplayIdList(&mDisplayPorts).isOk() || mDisplayPorts.empty()) {
-        LOG(ERROR) << "Failed to get a list of available displays";
-        return false;
+    if (!mHwEnumerator->getDisplayIdList(&mDisplayPorts).isOk()) {
+        LOG(WARNING)
+                << "Failed to get a list of available displays. EVS Display may not work properly "
+                   "if an active EVS HAL service implements HIDL v1.1 or AIDL EVS interface.";
     }
 
-    // The first element is the internal display
-    mInternalDisplayPort = mDisplayPorts.front();
-
-    auto it = std::find(mDisplayPorts.begin(), mDisplayPorts.end(), kExclusiveMainDisplayId);
-    if (it != mDisplayPorts.end()) {
-        LOG(WARNING) << kExclusiveMainDisplayId << " is reserved for the special purpose "
-                     << "so will not be available for EVS service.";
-        mDisplayPorts.erase(it);
+    const size_t numDisplays = mDisplayPorts.size();
+    mDisplayPorts.erase(std::remove_if(mDisplayPorts.begin(), mDisplayPorts.end(),
+                                       [](const auto id) { return id == kExclusiveDisplayId; }),
+                        mDisplayPorts.end());
+    if (numDisplays != mDisplayPorts.size()) {
+        LOG(WARNING)
+                << kExclusiveDisplayId
+                << " is reserved for the special purpose so will not be available for EVS service.";
     }
+
+    // The first element is the internal display if a returned list is not
+    // empty.
+    mInternalDisplayPort = mDisplayPorts.empty() ? kDisplayIdUnavailable : mDisplayPorts.front();
     mDisplayOwnedExclusively = false;
 
     // Starts the statistics collection
@@ -449,19 +451,28 @@
             if (!mActiveDisplay.expired()) {
                 LOG(ERROR) << "Display is owned exclusively by another client.";
                 return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_BUSY);
-            } else {
-                mDisplayOwnedExclusively = false;
             }
+
+            mDisplayOwnedExclusively = false;
         }
 
-        if (id == kExclusiveMainDisplayId) {
+        bool flagExclusive = false;
+        if (id == kExclusiveDisplayId) {
             // The client requests to open the primary display exclusively.
             id = mInternalDisplayPort;
-            mDisplayOwnedExclusively = true;
+            flagExclusive = true;
             LOG(DEBUG) << "EvsDisplay is now owned exclusively by process "
                        << AIBinder_getCallingPid();
+        } else if (id == kDisplayIdUnavailable || mDisplayPorts.empty()) {
+            // If any display port is not available, it's possible that a
+            // running EVS HAL service implements HIDL EVS v1.0 interfaces.
+            id = mInternalDisplayPort;
+            LOG(WARNING) << "No display port is listed; Does a running EVS HAL service implement "
+                            "HIDL EVS v1.0 interfaces?";
         } else if (std::find(mDisplayPorts.begin(), mDisplayPorts.end(), id) ==
                    mDisplayPorts.end()) {
+            // If we know any available display port, a given display ID must be
+            // one of them.
             LOG(ERROR) << "No display is available on the port " << id;
             return Utils::buildScopedAStatusFromEvsResult(EvsResult::INVALID_ARG);
         }
@@ -475,6 +486,13 @@
         std::shared_ptr<IEvsDisplay> displayHandle;
         if (auto status = mHwEnumerator->openDisplay(id, &displayHandle);
             !status.isOk() || !displayHandle) {
+            // We may fail to open the display in following cases:
+            // 1) If a running EVS HAL service implements HIDL EVS interfaces,
+            // AidlEnumerator validates a given display ID and return a null if
+            // it's out of [0, 255].
+            // 2) If a running EVS HAL service implements AIDL EVS interfaces,
+            // EVS HAL service will return a null if no display is associated
+            // with a given display ID.
             LOG(ERROR) << "EVS Display unavailable";
             return status;
         }
@@ -485,6 +503,7 @@
                 ::ndk::SharedRefBase::make<HalDisplay>(displayHandle, id);
         *displayObj = pHalDisplay;
         mActiveDisplay = pHalDisplay;
+        mDisplayOwnedExclusively = flagExclusive;
 
         return ScopedAStatus::ok();
     }
@@ -863,20 +882,25 @@
     }
 
     // Get a list of available displays and identify the internal display
-    if (!hwEnumerator->getDisplayIdList(&mDisplayPorts).isOk() || mDisplayPorts.empty()) {
-        LOG(ERROR) << "Failed to get a list of available displays";
-        return false;
+    if (!hwEnumerator->getDisplayIdList(&mDisplayPorts).isOk()) {
+        LOG(WARNING)
+                << "Failed to get a list of available displays. EVS Display may not work properly "
+                   "if an active EVS HAL service implements HIDL v1.1 or AIDL EVS interface.";
     }
 
-    // The first element is the internal display
-    mInternalDisplayPort = mDisplayPorts.front();
-
-    auto it = std::find(mDisplayPorts.begin(), mDisplayPorts.end(), kExclusiveMainDisplayId);
-    if (it != mDisplayPorts.end()) {
-        LOG(WARNING) << kExclusiveMainDisplayId << " is reserved for the special purpose "
-                     << "so will not be available for EVS service.";
-        mDisplayPorts.erase(it);
+    const size_t numDisplays = mDisplayPorts.size();
+    mDisplayPorts.erase(std::remove_if(mDisplayPorts.begin(), mDisplayPorts.end(),
+                                       [](const auto id) { return id == kExclusiveDisplayId; }),
+                        mDisplayPorts.end());
+    if (numDisplays != mDisplayPorts.size()) {
+        LOG(WARNING)
+                << kExclusiveDisplayId
+                << " is reserved for the special purpose so will not be available for EVS service.";
     }
+
+    // The first element is the internal display if a returned list is not
+    // empty.
+    mInternalDisplayPort = mDisplayPorts.empty() ? kDisplayIdUnavailable : mDisplayPorts.front();
     mDisplayOwnedExclusively = false;
     mHwEnumerator = hwEnumerator;
 
diff --git a/cpp/evs/manager/aidl/src/HalDisplay.cpp b/cpp/evs/manager/aidl/src/HalDisplay.cpp
index 62e4395..7c62211 100644
--- a/cpp/evs/manager/aidl/src/HalDisplay.cpp
+++ b/cpp/evs/manager/aidl/src/HalDisplay.cpp
@@ -115,7 +115,7 @@
 
 std::string HalDisplay::toString(const char* indent) {
     std::string buffer;
-    if (mId == kInvalidDisplayId) {
+    if (mId == kDisplayIdUnavailable) {
         // Display identifier has not set
         StringAppendF(&buffer, "HalDisplay: Display port is unknown.\n");
     } else {
diff --git a/cpp/evs/manager/aidl/wrappers/include/AidlCamera.h b/cpp/evs/manager/aidl/wrappers/include/AidlCamera.h
index 182ba2a..4d0ccf5 100644
--- a/cpp/evs/manager/aidl/wrappers/include/AidlCamera.h
+++ b/cpp/evs/manager/aidl/wrappers/include/AidlCamera.h
@@ -69,7 +69,8 @@
     ::ndk::ScopedAStatus stopVideoStream() override;
     ::ndk::ScopedAStatus unsetPrimaryClient() override;
 
-    explicit AidlCamera(const ::android::sp<hidlevs::V1_0::IEvsCamera>& camera);
+    explicit AidlCamera(const ::android::sp<hidlevs::V1_0::IEvsCamera>& camera,
+                        bool forceV1_0 = false);
     virtual ~AidlCamera() { mImpl = nullptr; }
 
     const ::android::sp<hidlevs::V1_0::IEvsCamera> getHidlCamera() const;
@@ -124,6 +125,7 @@
     // The low level camera interface that backs this proxy
     ::android::sp<hidlevs::V1_0::IEvsCamera> mHidlCamera;
     ::android::sp<HidlCameraStream> mHidlStream;
+    std::string mId;
 };
 
 class AidlCamera::ImplV0 final : public IHidlCamera {
@@ -157,7 +159,7 @@
     ::ndk::ScopedAStatus unsetPrimaryClient() override;
 
     explicit ImplV0(const ::android::sp<hidlevs::V1_0::IEvsCamera>& camera);
-    virtual ~ImplV0(){};
+    virtual ~ImplV0() { mHidlCamera = nullptr; };
 
     const ::android::sp<hidlevs::V1_0::IEvsCamera> getHidlCamera() const override {
         return mHidlCamera;
diff --git a/cpp/evs/manager/aidl/wrappers/include/AidlCameraStream.h b/cpp/evs/manager/aidl/wrappers/include/AidlCameraStream.h
index bfdd2e1..a30fb80 100644
--- a/cpp/evs/manager/aidl/wrappers/include/AidlCameraStream.h
+++ b/cpp/evs/manager/aidl/wrappers/include/AidlCameraStream.h
@@ -74,7 +74,7 @@
     ::ndk::ScopedAStatus notify(const aidlevs::EvsEventDesc& event) override;
 
     explicit ImplV0(const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& stream);
-    virtual ~ImplV0() {}
+    virtual ~ImplV0() { mStream = nullptr; }
 };
 
 class AidlCameraStream::ImplV1 final : public IHidlCameraStream {
diff --git a/cpp/evs/manager/aidl/wrappers/include/AidlDisplay.h b/cpp/evs/manager/aidl/wrappers/include/AidlDisplay.h
index 61d200a..a6587d7 100644
--- a/cpp/evs/manager/aidl/wrappers/include/AidlDisplay.h
+++ b/cpp/evs/manager/aidl/wrappers/include/AidlDisplay.h
@@ -22,8 +22,6 @@
 #include <aidl/android/hardware/automotive/evs/DisplayState.h>
 #include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
 
-#include <limits>
-
 namespace aidl::android::automotive::evs::implementation {
 
 namespace aidlevs = ::aidl::android::hardware::automotive::evs;
diff --git a/cpp/evs/manager/aidl/wrappers/include/AidlEnumerator.h b/cpp/evs/manager/aidl/wrappers/include/AidlEnumerator.h
index 7e885fc..7e28c3f 100644
--- a/cpp/evs/manager/aidl/wrappers/include/AidlEnumerator.h
+++ b/cpp/evs/manager/aidl/wrappers/include/AidlEnumerator.h
@@ -55,7 +55,8 @@
     ::ndk::ScopedAStatus registerStatusCallback(
             const std::shared_ptr<aidlevs::IEvsEnumeratorStatusCallback>& callback) override;
 
-    explicit AidlEnumerator(const ::android::sp<hidlevs::V1_0::IEvsEnumerator>& svc);
+    explicit AidlEnumerator(const ::android::sp<hidlevs::V1_0::IEvsEnumerator>& svc,
+                            bool forceV1_0 = false);
     virtual ~AidlEnumerator() { mImpl = nullptr; }
 
     // Implementation details
@@ -79,9 +80,6 @@
             const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) = 0;
     virtual ::ndk::ScopedAStatus getCameraList(std::vector<aidlevs::CameraDesc>* _aidl_return) = 0;
     virtual ::ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) = 0;
-    virtual ::android::sp<hidlevs::V1_0::IEvsEnumerator> getHidlEnumerator() {
-        return mHidlEnumerator;
-    };
     virtual ::ndk::ScopedAStatus openCamera(const std::string& cameraId,
                                             const aidlevs::Stream& streamConfig,
                                             std::shared_ptr<aidlevs::IEvsCamera>* obj) = 0;
@@ -93,6 +91,7 @@
 
 protected:
     ::android::sp<hidlevs::V1_0::IEvsEnumerator> mHidlEnumerator;
+    ::android::wp<hidlevs::V1_0::IEvsDisplay> mActiveHidlDisplay;
 };
 
 class AidlEnumerator::ImplV0 final : public IHidlEnumerator {
diff --git a/cpp/evs/manager/aidl/wrappers/include/HidlCameraStream.h b/cpp/evs/manager/aidl/wrappers/include/HidlCameraStream.h
index 7ed3b0a..1150d16 100644
--- a/cpp/evs/manager/aidl/wrappers/include/HidlCameraStream.h
+++ b/cpp/evs/manager/aidl/wrappers/include/HidlCameraStream.h
@@ -39,13 +39,15 @@
             const ::android::hardware::hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) override;
     ::android::hardware::Return<void> notify(const hidlevs::V1_1::EvsEventDesc& event) override;
 
-    HidlCameraStream(const std::shared_ptr<aidlevs::IEvsCameraStream>& camera) :
-          mAidlStream(camera) {}
+    HidlCameraStream(const std::string& id,
+                     const std::shared_ptr<aidlevs::IEvsCameraStream>& camera) :
+          mSourceDeviceId(id), mAidlStream(camera) {}
 
     bool getHidlBuffer(int id, hidlevs::V1_0::BufferDesc* _return);
     bool getHidlBuffer(int id, hidlevs::V1_1::BufferDesc* _return);
 
 private:
+    std::string mSourceDeviceId;
     std::shared_ptr<aidlevs::IEvsCameraStream> mAidlStream;
     std::list<hidlevs::V1_0::BufferDesc> mHidlV0Buffers;
     std::list<hidlevs::V1_1::BufferDesc> mHidlV1Buffers;
diff --git a/cpp/evs/manager/aidl/wrappers/src/AidlCamera.cpp b/cpp/evs/manager/aidl/wrappers/src/AidlCamera.cpp
index fa09815..cc37fa7 100644
--- a/cpp/evs/manager/aidl/wrappers/src/AidlCamera.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/AidlCamera.cpp
@@ -38,17 +38,20 @@
 using ::android::hardware::hidl_vec;
 using ::ndk::ScopedAStatus;
 
-AidlCamera::AidlCamera(const ::android::sp<hidlevs::V1_0::IEvsCamera>& hidlCamera) {
+AidlCamera::AidlCamera(const ::android::sp<hidlevs::V1_0::IEvsCamera>& hidlCamera, bool forceV1_0) {
     auto hidlCameraV1 = hidlevs::V1_1::IEvsCamera::castFrom(hidlCamera).withDefault(nullptr);
-    if (!hidlCameraV1) {
+    if (forceV1_0 || !hidlCameraV1) {
+        // AidlCamera is initialized in V1_0::IEvsCamera support mode in below
+        // three conditions:
+        // 1. A given camera object is an implementation of V1_0::IEvsCamera
+        //    (fails to upcast as V1_1::IEvsCamera).
+        // 2. A caller explicitly creates AidlCamera object in V1_0::IEvsCamera
+        //    mode by setting forceV1_0 as true.
+        // 3. Or, A given camera object is invalid (nullptr).
         mImpl = std::make_shared<ImplV0>(hidlCamera);
     } else {
         mImpl = std::make_shared<ImplV1>(hidlCameraV1);
     }
-
-    if (!mImpl) {
-        LOG(ERROR) << "Failed to initialize AidlCamera instance";
-    }
 }
 
 const ::android::sp<hidlevs::V1_0::IEvsCamera> AidlCamera::getHidlCamera() const {
@@ -132,7 +135,18 @@
 }
 
 AidlCamera::ImplV0::ImplV0(const ::android::sp<hidlevs::V1_0::IEvsCamera>& camera) :
-      IHidlCamera(camera) {}
+      IHidlCamera(camera) {
+    if (!camera) {
+        LOG(WARNING) << "AidlCamera object is instantiated with an invalid IEvsCamera object.";
+        return;
+    }
+
+    // Because android::hardware::automotive::evs::V1_0::BufferDesc does not
+    // contain a device id while it is required to handle received frames
+    // properly, we are retrieving it from the camera descriptor and store
+    // locally.
+    camera->getCameraInfo([this](const auto& read) { mId = read.cameraId; });
+}
 
 ScopedAStatus AidlCamera::ImplV0::doneWithFrame(const std::vector<BufferDesc>& buffers) {
     if (!mHidlStream) {
@@ -160,7 +174,7 @@
     }
 
     (void)mHidlCamera->getCameraInfo(
-            [&_aidl_return](auto& desc) { *_aidl_return = std::move(Utils::makeFromHidl(desc)); });
+            [_aidl_return](auto& desc) { *_aidl_return = std::move(Utils::makeFromHidl(desc)); });
 
     return ScopedAStatus::ok();
 }
@@ -213,6 +227,10 @@
 
 ScopedAStatus AidlCamera::ImplV0::setExtendedInfo(int32_t opaqueIdentifier,
                                                   const std::vector<uint8_t>& opaqueValue) {
+    if (opaqueValue.size() < sizeof(int32_t)) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::INVALID_ARG);
+    }
+
     int32_t v = *(reinterpret_cast<const int32_t*>(opaqueValue.data()));
     return Utils::buildScopedAStatusFromEvsResult(
             mHidlCamera->setExtendedInfo(opaqueIdentifier, v));
@@ -245,7 +263,7 @@
     }
 
     // Creates a wrapper object and requests a video stream
-    mHidlStream = new (std::nothrow) HidlCameraStream(listener);
+    mHidlStream = new (std::nothrow) HidlCameraStream(mId, listener);
     return Utils::buildScopedAStatusFromEvsResult(mHidlCamera->startVideoStream(mHidlStream));
 }
 
@@ -264,7 +282,14 @@
 }
 
 AidlCamera::ImplV1::ImplV1(const ::android::sp<hidlevs::V1_1::IEvsCamera>& camera) :
-      IHidlCamera(camera), mHidlCamera(camera) {}
+      IHidlCamera(camera), mHidlCamera(camera) {
+    if (!camera) {
+        LOG(WARNING) << "AidlCamera object is instantiated with an invalid IEvsCamera object.";
+        return;
+    }
+
+    camera->getCameraInfo_1_1([this](const auto& read) { mId = read.v1.cameraId; });
+}
 
 ScopedAStatus AidlCamera::ImplV1::doneWithFrame(const std::vector<BufferDesc>& buffers) {
     if (!mHidlStream) {
@@ -300,7 +325,7 @@
     }
 
     (void)mHidlCamera->getCameraInfo_1_1(
-            [&_aidl_return](auto& desc) { *_aidl_return = std::move(Utils::makeFromHidl(desc)); });
+            [_aidl_return](auto& desc) { *_aidl_return = std::move(Utils::makeFromHidl(desc)); });
 
     return ScopedAStatus::ok();
 }
@@ -313,8 +338,8 @@
 
     hidlevs::V1_0::EvsResult hidlStatus = hidlevs::V1_0::EvsResult::OK;
     (void)mHidlCamera->getExtendedInfo_1_1(opaqueIdentifier,
-                                           [&hidlStatus, &value](auto status,
-                                                                 const hidl_vec<uint8_t>& hwValue) {
+                                           [&hidlStatus, value](auto status,
+                                                                const hidl_vec<uint8_t>& hwValue) {
                                                hidlStatus = status;
                                                *value = hwValue;
                                            });
@@ -328,8 +353,8 @@
 
     hidlevs::V1_0::EvsResult hidlStatus = hidlevs::V1_0::EvsResult::OK;
     (void)mHidlCamera->getIntParameter(Utils::makeToHidl(id),
-                                       [&hidlStatus, &value](auto status,
-                                                             const hidl_vec<int32_t>& hidlValues) {
+                                       [&hidlStatus, value](auto status,
+                                                            const hidl_vec<int32_t>& hidlValues) {
                                            hidlStatus = status;
                                            *value = hidlValues;
                                        });
@@ -343,7 +368,7 @@
     }
 
     (void)mHidlCamera->getIntParameterRange(Utils::makeToHidl(id),
-                                            [&_aidl_return](auto min, auto max, auto step) {
+                                            [_aidl_return](auto min, auto max, auto step) {
                                                 _aidl_return->min = min;
                                                 _aidl_return->max = max;
                                                 _aidl_return->step = step;
@@ -357,7 +382,7 @@
     }
 
     (void)mHidlCamera->getParameterList(
-            [&_aidl_return](const hidl_vec<hidlevs::V1_1::CameraParam>& list) {
+            [_aidl_return](const hidl_vec<hidlevs::V1_1::CameraParam>& list) {
                 _aidl_return->reserve(list.size());
                 for (auto i = 0; i < list.size(); ++i) {
                     _aidl_return->push_back(std::move(Utils::makeFromHidl(list[i])));
@@ -372,7 +397,7 @@
         return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
     }
 
-    (void)mHidlCamera->getPhysicalCameraInfo(deviceId, [&_aidl_return](const auto& hidlDesc) {
+    (void)mHidlCamera->getPhysicalCameraInfo(deviceId, [_aidl_return](const auto& hidlDesc) {
         *_aidl_return = std::move(Utils::makeFromHidl(hidlDesc));
     });
     return ScopedAStatus::ok();
@@ -391,7 +416,7 @@
     }
     hidlevs::V1_0::EvsResult hidlStatus = hidlevs::V1_0::EvsResult::OK;
     (void)mHidlCamera->importExternalBuffers(hidlBuffers,
-                                             [&hidlStatus, &_aidl_return](auto status, auto delta) {
+                                             [&hidlStatus, _aidl_return](auto status, auto delta) {
                                                  hidlStatus = status;
                                                  *_aidl_return = delta;
                                              });
@@ -466,7 +491,7 @@
     }
 
     // Creates a wrapper object and requests a video stream
-    mHidlStream = new (std::nothrow) HidlCameraStream(listener);
+    mHidlStream = new (std::nothrow) HidlCameraStream(mId, listener);
     return Utils::buildScopedAStatusFromEvsResult(mHidlCamera->startVideoStream(mHidlStream));
 }
 
diff --git a/cpp/evs/manager/aidl/wrappers/src/AidlCameraStream.cpp b/cpp/evs/manager/aidl/wrappers/src/AidlCameraStream.cpp
index 224c378..f8cf243 100644
--- a/cpp/evs/manager/aidl/wrappers/src/AidlCameraStream.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/AidlCameraStream.cpp
@@ -41,10 +41,6 @@
     } else {
         mImpl = std::make_shared<ImplV1>(hidlStreamV1);
     }
-
-    if (!mImpl) {
-        LOG(ERROR) << "Failed to initialize AidlCameraStream instance";
-    }
 }
 
 ScopedAStatus AidlCameraStream::deliverFrame(const std::vector<BufferDesc>& buffers) {
@@ -75,22 +71,32 @@
       IHidlCameraStream(stream) {}
 
 ScopedAStatus AidlCameraStream::ImplV0::deliverFrame(const std::vector<BufferDesc>& buffers) {
+    if (!mStream) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
+    }
+
     auto hidlBuffer = Utils::makeToHidlV1_0(buffers[0], /* doDup= */ false);
     mBuffers.push_back(std::move(Utils::dupBufferDesc(buffers[0], /* doDup= */ true)));
     if (auto status = mStream->deliverFrame(std::move(hidlBuffer)); !status.isOk()) {
         LOG(ERROR) << "Failed to forward a frame to HIDL v1.0 client";
-        return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+        return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
     }
 
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus AidlCameraStream::ImplV0::notify(const EvsEventDesc& event) {
+    if (!mStream) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
+    }
+
     switch (event.aType) {
         case EvsEventType::STREAM_STOPPED:
             if (auto status = mStream->deliverFrame({}); !status.isOk()) {
                 LOG(ERROR) << "Error delivering the end of stream marker";
-                return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+                return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
             }
             break;
 
@@ -118,13 +124,18 @@
 
     if (auto status = mStream->deliverFrame_1_1(hidlBuffers); !status.isOk()) {
         LOG(ERROR) << "Failed to forward a frame to HIDL v1.1 client";
-        return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+        return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
     }
 
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus AidlCameraStream::ImplV1::notify(const EvsEventDesc& event) {
+    if (!mStream) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
+    }
+
     hidlevs::V1_1::EvsEventDesc hidlEvent;
     if (!Utils::makeToHidl(event, &hidlEvent)) {
         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
@@ -132,7 +143,7 @@
 
     if (auto status = mStream->notify(hidlEvent); !status.isOk()) {
         LOG(ERROR) << "Failed to forward an event, " << Utils::toString(event.aType);
-        return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+        return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
     }
 
     return ScopedAStatus::ok();
diff --git a/cpp/evs/manager/aidl/wrappers/src/AidlDisplay.cpp b/cpp/evs/manager/aidl/wrappers/src/AidlDisplay.cpp
index 529ab9a..ca659f8 100644
--- a/cpp/evs/manager/aidl/wrappers/src/AidlDisplay.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/AidlDisplay.cpp
@@ -30,6 +30,7 @@
 using ::aidl::android::hardware::automotive::evs::BufferDesc;
 using ::aidl::android::hardware::automotive::evs::DisplayDesc;
 using ::aidl::android::hardware::automotive::evs::DisplayState;
+using ::aidl::android::hardware::automotive::evs::EvsResult;
 using ::aidl::android::hardware::automotive::evs::Rotation;
 using ::ndk::ScopedAStatus;
 
@@ -42,6 +43,10 @@
  * Gets basic display information from a hardware display object and returns.
  */
 ScopedAStatus AidlDisplay::getDisplayInfo(DisplayDesc* _aidl_return) {
+    if (!mHidlDisplay) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     mHidlDisplay->getDisplayInfo([_aidl_return](const hidlevs::V1_0::DisplayDesc& info) {
         _aidl_return->id = info.displayId;
         _aidl_return->vendorFlags = info.vendorFlags;
@@ -70,6 +75,10 @@
  * Gets current display state from a hardware display object and return.
  */
 ScopedAStatus AidlDisplay::getDisplayState(DisplayState* _aidl_return) {
+    if (!mHidlDisplay) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     *_aidl_return = std::move(Utils::makeFromHidl(mHidlDisplay->getDisplayState()));
     return ScopedAStatus::ok();
 }
@@ -78,7 +87,11 @@
  * Returns a handle to a frame buffer associated with the display.
  */
 ScopedAStatus AidlDisplay::getTargetBuffer(BufferDesc* _aidl_return) {
-    mHidlDisplay->getTargetBuffer([this, &_aidl_return](auto& hidlBuffer) {
+    if (!mHidlDisplay) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
+    mHidlDisplay->getTargetBuffer([this, _aidl_return](auto& hidlBuffer) {
         *_aidl_return = std::move(Utils::makeFromHidl(hidlBuffer, /* doDup= */ true));
         mHeldBuffer = std::move(hidlBuffer);
     });
@@ -89,6 +102,10 @@
  * Notifies the display that the buffer is ready to be used.
  */
 ScopedAStatus AidlDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer) {
+    if (!mHidlDisplay) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     if (buffer.bufferId != mHeldBuffer.bufferId) {
         LOG(WARNING) << "Ignores a request to return a buffer " << buffer.bufferId << "; a buffer "
                      << mHeldBuffer.bufferId << " is held.";
@@ -103,6 +120,10 @@
  * Sets the display state as what the clients wants.
  */
 ScopedAStatus AidlDisplay::setDisplayState(DisplayState state) {
+    if (!mHidlDisplay) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     return Utils::buildScopedAStatusFromEvsResult(
             mHidlDisplay->setDisplayState(std::move(Utils::makeToHidl(state))));
 }
diff --git a/cpp/evs/manager/aidl/wrappers/src/AidlEnumerator.cpp b/cpp/evs/manager/aidl/wrappers/src/AidlEnumerator.cpp
index 02dee26..dc197f4 100644
--- a/cpp/evs/manager/aidl/wrappers/src/AidlEnumerator.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/AidlEnumerator.cpp
@@ -18,6 +18,7 @@
 
 #include "AidlCamera.h"
 #include "AidlDisplay.h"
+#include "Constants.h"
 #include "utils/include/Utils.h"
 
 #include <aidl/android/hardware/automotive/evs/Rotation.h>
@@ -25,6 +26,8 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 
+#include <limits>
+
 namespace {
 
 using ::aidl::android::hardware::automotive::evs::CameraDesc;
@@ -57,16 +60,22 @@
 
 namespace hidlevs = ::android::hardware::automotive::evs;
 
-AidlEnumerator::AidlEnumerator(const ::android::sp<hidlevs::V1_0::IEvsEnumerator>& service) {
+AidlEnumerator::AidlEnumerator(const ::android::sp<hidlevs::V1_0::IEvsEnumerator>& service,
+                               bool forceV1_0) {
     auto serviceV1 = hidlevs::V1_1::IEvsEnumerator::castFrom(service).withDefault(nullptr);
-    if (!serviceV1) {
+    if (forceV1_0 || !serviceV1) {
+        // AidlEnumerator is initialized in V1_0::IEvsEnumerator support mode in
+        // below conditions:
+        // 1. A given camera object is an implementation of V1_0::IEvsEnumerator
+        //    (fails to upcast as V1_1::IEvsEnumertor).
+        // 2. A caller explicitly creates AidlEnumerator object in
+        //    V1_0::IEvsEnumerator mode by setting forceV1_0 as true.
+        // 3. Or, A given camera object is invalid (nullptr).
         mImpl = std::make_shared<ImplV0>(service);
+        LOG(DEBUG) << "Initialized in HIDL V1.0 support mode.";
     } else {
         mImpl = std::make_shared<ImplV1>(serviceV1);
-    }
-
-    if (!mImpl) {
-        LOG(ERROR) << "Failed to initialize AidlEnumerator instance";
+        LOG(DEBUG) << "Initialized in HIDL V1.1 support mode.";
     }
 }
 
@@ -110,11 +119,10 @@
         return ScopedAStatus::ok();
     }
 
-    const unsigned numStreamConfigs = streamConfig.count / sizeof(StreamConfiguration);
-    _aidl_return->resize(numStreamConfigs);
+    _aidl_return->resize(streamConfig.count);
     const StreamConfiguration* pCurrentConfig =
             reinterpret_cast<StreamConfiguration*>(streamConfig.data.i32);
-    for (unsigned i = 0; i < numStreamConfigs; ++i, ++pCurrentConfig) {
+    for (unsigned i = 0; i < streamConfig.count; ++i, ++pCurrentConfig) {
         Stream current = {
                 .id = pCurrentConfig->id,
                 .streamType =
@@ -160,7 +168,6 @@
     }
 
     mHidlDisplay = hidlDisplay;
-
     auto aidlDisplay = ::ndk::SharedRefBase::make<AidlDisplay>(hidlDisplay);
     mAidlDisplay = aidlDisplay;
     *_aidl_return = std::move(aidlDisplay);
@@ -232,7 +239,11 @@
 }
 
 ScopedAStatus AidlEnumerator::ImplV0::getCameraList(std::vector<CameraDesc>* _aidl_return) {
-    mHidlEnumerator->getCameraList([&_aidl_return](auto hidl_cameras) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
+    mHidlEnumerator->getCameraList([_aidl_return](auto hidl_cameras) {
         _aidl_return->resize(hidl_cameras.size());
         auto it = _aidl_return->begin();
         for (const auto& camera : hidl_cameras) {
@@ -245,45 +256,95 @@
 
 ScopedAStatus AidlEnumerator::ImplV0::closeCamera(
         const ::android::sp<hidlevs::V1_0::IEvsCamera>& cameraObj) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     mHidlEnumerator->closeCamera(cameraObj);
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus AidlEnumerator::ImplV0::openCamera(const std::string& id, const Stream& /*cfg*/,
                                                  std::shared_ptr<IEvsCamera>* _aidl_return) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     ::android::sp<hidlevs::V1_0::IEvsCamera> hidlCamera = mHidlEnumerator->openCamera(id);
     if (!hidlCamera) {
         LOG(ERROR) << "Failed to open a camera " << id;
         return Utils::buildScopedAStatusFromEvsResult(EvsResult::INVALID_ARG);
     }
 
-    *_aidl_return = std::move(::ndk::SharedRefBase::make<AidlCamera>(hidlCamera));
+    *_aidl_return =
+            std::move(::ndk::SharedRefBase::make<AidlCamera>(hidlCamera, /* forceV1_0= */ true));
 
     return ScopedAStatus::ok();
 }
 
-::android::sp<hidlevs::V1_0::IEvsDisplay> AidlEnumerator::ImplV0::openDisplay(int32_t /*id*/) {
-    return mHidlEnumerator->openDisplay();
+::android::sp<hidlevs::V1_0::IEvsDisplay> AidlEnumerator::ImplV0::openDisplay(int32_t id) {
+    if (!mHidlEnumerator) {
+        LOG(ERROR) << "AidlEnumerator is not initialized yet.";
+        return nullptr;
+    }
+
+    if (id != kDisplayIdUnavailable &&
+        (id < std::numeric_limits<uint8_t>::min() || id > std::numeric_limits<uint8_t>::max())) {
+        LOG(ERROR) << "A given display ID, " << id << ", is invalid.";
+        return nullptr;
+    }
+
+    LOG(DEBUG) << "A given display ID is ignored because HIDL IEvsEnumerator::openDisplay() opens "
+                  "the default display always.";
+    ::android::sp<hidlevs::V1_0::IEvsDisplay> hidlDisplay = mHidlEnumerator->openDisplay();
+    mActiveHidlDisplay = hidlDisplay;
+    return hidlDisplay;
 }
 
 ScopedAStatus AidlEnumerator::ImplV0::closeDisplay(
         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
+    if (display != mActiveHidlDisplay.promote()) {
+        LOG(WARNING) << "Ignore a request to close a display with an incorrect display handle.";
+        return ScopedAStatus::ok();
+    }
+
     mHidlEnumerator->closeDisplay(display);
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus AidlEnumerator::ImplV0::getDisplayIdList(std::vector<uint8_t>* /*_aidl_return*/) {
-    return ScopedAStatus::ok();
+ScopedAStatus AidlEnumerator::ImplV0::getDisplayIdList(
+        [[maybe_unused]] std::vector<uint8_t>* _aidl_return) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
+    // android::hardware::automotive::evs::V1_0::IEvsEnumerator does not declare
+    // a method that returns any display ID because
+    // android::hardware::automotive::evs::V1_0::IEvsDisplay always uses the
+    // default (internal) display; hence, we return a NOT_SUPPORTED.
+    return Utils::buildScopedAStatusFromEvsResult(EvsResult::NOT_SUPPORTED);
 }
 
 ScopedAStatus AidlEnumerator::ImplV1::closeCamera(
         const ::android::sp<hidlevs::V1_0::IEvsCamera>& cameraObj) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     mHidlEnumerator->closeCamera(cameraObj);
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus AidlEnumerator::ImplV1::getCameraList(std::vector<CameraDesc>* _aidl_return) {
-    mHidlEnumerator->getCameraList_1_1([&_aidl_return](auto hidl_cameras) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
+    mHidlEnumerator->getCameraList_1_1([_aidl_return](auto hidl_cameras) {
         _aidl_return->resize(hidl_cameras.size());
         auto it = _aidl_return->begin();
         for (const auto& camera : hidl_cameras) {
@@ -296,6 +357,10 @@
 
 ScopedAStatus AidlEnumerator::ImplV1::openCamera(const std::string& id, const Stream& cfg,
                                                  std::shared_ptr<IEvsCamera>* _aidl_return) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     auto hidlStreamConfig = std::move(Utils::makeToHidl(cfg));
     ::android::sp<hidlevs::V1_1::IEvsCamera> hidlCamera =
             mHidlEnumerator->openCamera_1_1(id, hidlStreamConfig);
@@ -310,19 +375,37 @@
 }
 
 ::android::sp<hidlevs::V1_0::IEvsDisplay> AidlEnumerator::ImplV1::openDisplay(int32_t id) {
+    if (!mHidlEnumerator) {
+        LOG(ERROR) << "AidlEnumerator is not initialized yet.";
+        return nullptr;
+    }
+
+    if (id < std::numeric_limits<uint8_t>::min() || id > std::numeric_limits<uint8_t>::max()) {
+        LOG(ERROR) << "A given display ID, " << id << ", is invalid.";
+        return nullptr;
+    }
+
     ::android::sp<hidlevs::V1_1::IEvsDisplay> hidlDisplay = mHidlEnumerator->openDisplay_1_1(id);
     return hidlDisplay;
 }
 
 ScopedAStatus AidlEnumerator::ImplV1::closeDisplay(
         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     mHidlEnumerator->closeDisplay(display);
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus AidlEnumerator::ImplV1::getDisplayIdList(std::vector<uint8_t>* _aidl_return) {
+    if (!mHidlEnumerator) {
+        return Utils::buildScopedAStatusFromEvsResult(EvsResult::RESOURCE_NOT_AVAILABLE);
+    }
+
     mHidlEnumerator->getDisplayIdList(
-            [&_aidl_return](auto& list) { *_aidl_return = std::move(list); });
+            [_aidl_return](auto& list) { *_aidl_return = std::move(list); });
     return ScopedAStatus::ok();
 }
 
diff --git a/cpp/evs/manager/aidl/wrappers/src/HidlCamera.cpp b/cpp/evs/manager/aidl/wrappers/src/HidlCamera.cpp
index 12d14d0..5311bbd 100644
--- a/cpp/evs/manager/aidl/wrappers/src/HidlCamera.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/HidlCamera.cpp
@@ -47,10 +47,18 @@
 }
 
 Return<void> HidlCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     CameraDesc aidlDesc;
     if (auto status = mAidlCamera->getCameraInfo(&aidlDesc); !status.isOk()) {
-        LOG(WARNING) << "Failed to get a camera information, status = "
-                     << status.getServiceSpecificError();
+        LOG(ERROR) << "Failed to get a camera information, status = "
+                   << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
+        _hidl_cb({});
+        return {};
     }
 
     _hidl_cb(std::move(Utils::makeToHidlV1_0(aidlDesc)));
@@ -58,9 +66,14 @@
 }
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::setMaxFramesInFlight(uint32_t bufferCount) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     auto status = mAidlCamera->setMaxFramesInFlight(static_cast<int32_t>(bufferCount));
     if (!status.isOk()) {
-        return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
+        return hidlevs::V1_0::EvsResult::BUFFER_NOT_AVAILABLE;
     }
 
     return hidlevs::V1_0::EvsResult::OK;
@@ -68,9 +81,14 @@
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::startVideoStream(
         const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& stream) {
-    if (!stream) {
-        return hidlevs::V1_0::EvsResult::INVALID_ARG;
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    } else if (!stream) {
+        LOG(ERROR) << "A given HIDL IEvsCameraStream object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
     } else if (mAidlStream) {
+        LOG(WARNING) << "A video stream is already running.";
         return hidlevs::V1_0::EvsResult::STREAM_ALREADY_RUNNING;
     }
 
@@ -84,9 +102,14 @@
 }
 
 Return<void> HidlCamera::doneWithFrame(const hidlevs::V1_0::BufferDesc& buffer) {
+    if (!mAidlStream) {
+        LOG(ERROR) << "A reference to AIDL IEvsCameraStream object is invalid.";
+        return {};
+    }
+
     BufferDesc aidlBuffer;
     if (!mAidlStream->getBuffer(buffer.bufferId, &aidlBuffer)) {
-        LOG(WARNING) << "Ignores an unknown buffer " << buffer.bufferId;
+        LOG(ERROR) << "Ignores an unknown buffer " << buffer.bufferId;
         return {};
     }
 
@@ -94,15 +117,17 @@
     int bufferId = aidlBuffer.bufferId;  // save pre move() for log message.
     buffersToReturn[0] = std::move(aidlBuffer);
     if (auto status = mAidlCamera->doneWithFrame(std::move(buffersToReturn)); !status.isOk()) {
-        LOG(WARNING) << "Failed to return a buffer " << bufferId
-                     << ", status = " << status.getServiceSpecificError();
+        LOG(WARNING) << "Failed to return a buffer " << bufferId << ", status = "
+                     << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
+        return {};
     }
 
     return {};
 }
 
 Return<void> HidlCamera::stopVideoStream() {
-    if (!mAidlStream) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
         return {};
     }
 
@@ -111,8 +136,14 @@
 }
 
 Return<int32_t> HidlCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return 0;
+    }
+
     std::vector<uint8_t> value;
-    if (!mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value).isOk()) {
+    if (!mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value).isOk() ||
+        value.size() < sizeof(int32_t)) {
         return 0;
     }
 
@@ -121,7 +152,12 @@
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo(uint32_t opaqueIdentifier,
                                                              int32_t opaqueValue) {
-    std::vector<uint8_t> value;
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
+    std::vector<uint8_t> value(sizeof(int32_t));
     *reinterpret_cast<int32_t*>(value.data()) = opaqueValue;
     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
     if (!status.isOk()) {
@@ -132,10 +168,17 @@
 
 // Methods from ::android::hardware::automotive::evs::V1_1::IEvsCamera follow.
 Return<void> HidlCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     CameraDesc aidlDesc;
     if (auto status = mAidlCamera->getCameraInfo(&aidlDesc); !status.isOk()) {
-        LOG(WARNING) << "Failed to get a camera information, status = "
-                     << status.getServiceSpecificError();
+        LOG(ERROR) << "Failed to get a camera information, status = "
+                   << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
+        _hidl_cb({});
         return {};
     }
 
@@ -145,20 +188,31 @@
 
 Return<void> HidlCamera::getPhysicalCameraInfo(const hidl_string& deviceId,
                                                getPhysicalCameraInfo_cb _hidl_cb) {
-    CameraDesc aidlDesc;
-    if (auto status = mAidlCamera->getPhysicalCameraInfo(deviceId, &aidlDesc); !status.isOk()) {
-        LOG(WARNING) << "Failed to read information of a camera " << deviceId
-                     << ", status = " << status.getServiceSpecificError();
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
         _hidl_cb({});
-    } else {
-        _hidl_cb(Utils::makeToHidlV1_1(aidlDesc));
+        return {};
     }
 
+    CameraDesc aidlDesc;
+    if (auto status = mAidlCamera->getPhysicalCameraInfo(deviceId, &aidlDesc); !status.isOk()) {
+        LOG(ERROR) << "Failed to read information of a camera " << deviceId << ", status = "
+                   << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
+        _hidl_cb({});
+        return {};
+    }
+
+    _hidl_cb(Utils::makeToHidlV1_1(aidlDesc));
     return {};
 }
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::doneWithFrame_1_1(
         const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) {
+    if (!mAidlStream) {
+        LOG(WARNING) << "A reference to AIDL IEvsCameraStream object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     std::vector<BufferDesc> buffersToReturn(buffers.size());
     for (auto i = 0; i < buffers.size(); ++i) {
         BufferDesc aidlBuffer;
@@ -179,6 +233,11 @@
 }
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::setMaster() {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     if (auto status = mAidlCamera->setPrimaryClient(); !status.isOk()) {
         EvsResult err = static_cast<EvsResult>(status.getServiceSpecificError());
         if (err == EvsResult::PERMISSION_DENIED) {
@@ -194,6 +253,11 @@
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::forceMaster(
         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     auto status = mAidlCamera->forcePrimaryClient(::ndk::SharedRefBase::make<AidlDisplay>(display));
     if (!status.isOk()) {
         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
@@ -203,6 +267,11 @@
 }
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::unsetMaster() {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     if (auto status = mAidlCamera->unsetPrimaryClient(); !status.isOk()) {
         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
     }
@@ -211,10 +280,16 @@
 }
 
 Return<void> HidlCamera::getParameterList(getParameterList_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     std::vector<CameraParam> aidlList;
     if (auto status = mAidlCamera->getParameterList(&aidlList); !status.isOk()) {
-        LOG(WARNING) << "Failed to get a parameter list, status = "
-                     << status.getServiceSpecificError();
+        LOG(ERROR) << "Failed to get a parameter list, status = "
+                   << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
         _hidl_cb({});
         return {};
     }
@@ -230,9 +305,17 @@
 
 Return<void> HidlCamera::getIntParameterRange(hidlevs::V1_1::CameraParam id,
                                               getIntParameterRange_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb(0, 0, 0);
+        return {};
+    }
+
     ParameterRange aidlRange;
     if (auto status = mAidlCamera->getIntParameterRange(Utils::makeFromHidl(id), &aidlRange);
         !status.isOk()) {
+        LOG(ERROR) << "Failed to get a parameter range, status = "
+                   << toString(static_cast<EvsResult>(status.getServiceSpecificError()));
         _hidl_cb(0, 0, 0);
         return {};
     }
@@ -243,6 +326,12 @@
 
 Return<void> HidlCamera::setIntParameter(hidlevs::V1_1::CameraParam id, int32_t value,
                                          setIntParameter_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
+        return {};
+    }
+
     std::vector<int32_t> aidlValues;
     auto status = mAidlCamera->setIntParameter(Utils::makeFromHidl(id), value, &aidlValues);
     if (!status.isOk()) {
@@ -262,6 +351,12 @@
 
 Return<void> HidlCamera::getIntParameter(hidlevs::V1_1::CameraParam id,
                                          getIntParameter_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
+        return {};
+    }
+
     std::vector<int32_t> aidlValues;
     auto status = mAidlCamera->getIntParameter(Utils::makeFromHidl(id), &aidlValues);
     if (!status.isOk()) {
@@ -275,6 +370,11 @@
 
 Return<hidlevs::V1_0::EvsResult> HidlCamera::setExtendedInfo_1_1(
         uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     std::vector<uint8_t> value(opaqueValue);
     auto status = mAidlCamera->setExtendedInfo(static_cast<int32_t>(opaqueIdentifier), value);
     if (!status.isOk()) {
@@ -286,19 +386,31 @@
 
 Return<void> HidlCamera::getExtendedInfo_1_1(uint32_t opaqueIdentifier,
                                              getExtendedInfo_1_1_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, {});
+        return {};
+    }
+
     std::vector<uint8_t> value;
     auto status = mAidlCamera->getExtendedInfo(static_cast<int32_t>(opaqueIdentifier), &value);
     if (!status.isOk()) {
         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())), {});
-    } else {
-        _hidl_cb(hidlevs::V1_0::EvsResult::OK, value);
+        return {};
     }
 
+    _hidl_cb(hidlevs::V1_0::EvsResult::OK, value);
     return {};
 }
 
 Return<void> HidlCamera::importExternalBuffers(const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers,
                                                importExternalBuffers_cb _hidl_cb) {
+    if (!mAidlCamera) {
+        LOG(ERROR) << "A reference to AIDL IEvsCamera object is invalid.";
+        _hidl_cb(hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR, 0);
+        return {};
+    }
+
     std::vector<BufferDesc> aidlBuffers(buffers.size());
     for (auto i = 0; i < buffers.size(); ++i) {
         aidlBuffers[i] = std::move(Utils::makeFromHidl(buffers[i]));
@@ -308,10 +420,10 @@
     if (auto status = mAidlCamera->importExternalBuffers(aidlBuffers, &delta); !status.isOk()) {
         _hidl_cb(Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError())),
                  delta);
-    } else {
-        _hidl_cb(hidlevs::V1_0::EvsResult::OK, delta);
+        return {};
     }
 
+    _hidl_cb(hidlevs::V1_0::EvsResult::OK, delta);
     return {};
 }
 
diff --git a/cpp/evs/manager/aidl/wrappers/src/HidlCameraStream.cpp b/cpp/evs/manager/aidl/wrappers/src/HidlCameraStream.cpp
index 2583488..fd53cfc 100644
--- a/cpp/evs/manager/aidl/wrappers/src/HidlCameraStream.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/HidlCameraStream.cpp
@@ -20,6 +20,7 @@
 #include "utils/include/Utils.h"
 
 #include <android-base/logging.h>
+#include <utils/SystemClock.h>
 
 namespace aidl::android::automotive::evs::implementation {
 
@@ -32,14 +33,23 @@
 using ::ndk::ScopedAStatus;
 
 Return<void> HidlCameraStream::deliverFrame(const hidlevs::V1_0::BufferDesc& buffer) {
+    if (!mAidlStream) {
+        LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
+        return {};
+    }
+
     std::vector<BufferDesc> aidlBuffers(1);
     aidlBuffers[0] = std::move(Utils::makeFromHidl(buffer, /* doDup= */ true));
 
+    // android::hardware::automotive::evs::V1_0::BufferDesc does not contain a
+    // timestamp so we need to fill it here.
+    aidlBuffers[0].timestamp = static_cast<int64_t>(::android::elapsedRealtimeNano() * 1e+3);
+    aidlBuffers[0].deviceId = mSourceDeviceId;
+
     mHidlV0Buffers.push_back(buffer);
     auto aidlStatus = mAidlStream->deliverFrame(std::move(aidlBuffers));
     if (!aidlStatus.isOk()) {
         LOG(ERROR) << "Failed to forward frames to AIDL client";
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
     }
 
     return {};
@@ -47,6 +57,11 @@
 
 Return<void> HidlCameraStream::deliverFrame_1_1(
         const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) {
+    if (!mAidlStream) {
+        LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
+        return {};
+    }
+
     std::vector<BufferDesc> aidlBuffers(buffers.size());
     for (auto i = 0; i < buffers.size(); ++i) {
         hidlevs::V1_1::BufferDesc buffer = std::move(buffers[i]);
@@ -56,16 +71,19 @@
 
     if (!mAidlStream->deliverFrame(std::move(aidlBuffers)).isOk()) {
         LOG(ERROR) << "Failed to forward frames to AIDL client";
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
     }
 
     return {};
 }
 
 Return<void> HidlCameraStream::notify(const hidlevs::V1_1::EvsEventDesc& event) {
+    if (!mAidlStream) {
+        LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
+        return {};
+    }
+
     if (!mAidlStream->notify(std::move(Utils::makeFromHidl(event))).isOk()) {
         LOG(ERROR) << "Failed to forward events to AIDL client";
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
     }
 
     return {};
diff --git a/cpp/evs/manager/aidl/wrappers/src/HidlDisplay.cpp b/cpp/evs/manager/aidl/wrappers/src/HidlDisplay.cpp
index 5e8beed..acc7800 100644
--- a/cpp/evs/manager/aidl/wrappers/src/HidlDisplay.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/HidlDisplay.cpp
@@ -42,9 +42,15 @@
 }
 
 Return<void> HidlDisplay::getDisplayInfo(getDisplayInfo_cb _hidl_cb) {
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     DisplayDesc aidlDesc;
     if (auto status = mAidlDisplay->getDisplayInfo(&aidlDesc); !status.isOk()) {
-        LOG(WARNING) << "Failed to read a display information";
+        LOG(ERROR) << "Failed to read a display information";
         _hidl_cb({});
         return {};
     }
@@ -58,6 +64,11 @@
 }
 
 Return<hidlevs::V1_0::EvsResult> HidlDisplay::setDisplayState(hidlevs::V1_0::DisplayState state) {
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     if (auto status = mAidlDisplay->setDisplayState(Utils::makeFromHidl(state)); !status.isOk()) {
         return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
     }
@@ -65,6 +76,11 @@
 }
 
 Return<hidlevs::V1_0::DisplayState> HidlDisplay::getDisplayState() {
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        return Utils::makeToHidl(DisplayState::DEAD);
+    }
+
     DisplayState aidlState;
     if (auto status = mAidlDisplay->getDisplayState(&aidlState); !status.isOk()) {
         return Utils::makeToHidl(DisplayState::DEAD);
@@ -74,6 +90,12 @@
 }
 
 Return<void> HidlDisplay::getTargetBuffer(getTargetBuffer_cb _hidl_cb) {
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     BufferDesc aidlBuffer;
     auto status = mAidlDisplay->getTargetBuffer(&aidlBuffer);
     if (!status.isOk()) {
@@ -92,6 +114,11 @@
 
 Return<hidlevs::V1_0::EvsResult> HidlDisplay::returnTargetBufferForDisplay(
         const hidlevs::V1_0::BufferDesc& buffer) {
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
+    }
+
     if (buffer.bufferId != mHeldBuffer.bufferId) {
         LOG(WARNING) << "Ignores a request to return a buffer " << buffer.bufferId << "; a buffer "
                      << mHeldBuffer.bufferId << " is held.";
@@ -106,15 +133,22 @@
 }
 
 Return<void> HidlDisplay::getDisplayInfo_1_1(getDisplayInfo_1_1_cb _hidl_cb) {
-    DisplayDesc aidlDesc;
-    if (auto status = mAidlDisplay->getDisplayInfo(&aidlDesc); !status.isOk()) {
-        LOG(WARNING) << "Failed to read a display information";
-        _hidl_cb({}, {});
+    ::android::hardware::hidl_vec<uint8_t> hidlMode(sizeof(::android::ui::DisplayMode));
+    ::android::hardware::hidl_vec<uint8_t> hidlState(sizeof(::android::ui::DisplayState));
+
+    if (!mAidlDisplay) {
+        LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
+        _hidl_cb(hidlMode, hidlState);
         return {};
     }
 
-    ::android::hardware::hidl_vec<uint8_t> hidlMode(sizeof(::android::ui::DisplayMode));
-    ::android::hardware::hidl_vec<uint8_t> hidlState(sizeof(::android::ui::DisplayState));
+    DisplayDesc aidlDesc;
+    if (auto status = mAidlDisplay->getDisplayInfo(&aidlDesc); !status.isOk()) {
+        LOG(ERROR) << "Failed to read a display information";
+        _hidl_cb(hidlMode, hidlState);
+        return {};
+    }
+
     ::android::ui::DisplayMode* pMode =
             reinterpret_cast<::android::ui::DisplayMode*>(hidlMode.data());
     ::android::ui::DisplayState* pState =
diff --git a/cpp/evs/manager/aidl/wrappers/src/HidlEnumerator.cpp b/cpp/evs/manager/aidl/wrappers/src/HidlEnumerator.cpp
index c36651d..767e3aa 100644
--- a/cpp/evs/manager/aidl/wrappers/src/HidlEnumerator.cpp
+++ b/cpp/evs/manager/aidl/wrappers/src/HidlEnumerator.cpp
@@ -16,6 +16,7 @@
 
 #include "HidlEnumerator.h"
 
+#include "Constants.h"
 #include "HidlCamera.h"
 #include "HidlDisplay.h"
 #include "utils/include/Utils.h"
@@ -46,12 +47,18 @@
 }
 
 Return<void> HidlEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     std::vector<CameraDesc> aidlCameras;
     if (auto status = mEnumerator->getCameraList(&aidlCameras); !status.isOk()) {
         LOG(ERROR) << "Failed to get a list of cameras, status = "
                    << status.getServiceSpecificError();
         _hidl_cb({});
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
+        return {};
     }
 
     ::android::hardware::hidl_vec<hidlevs::V1_0::CameraDesc> hidlCameras(aidlCameras.size());
@@ -65,6 +72,11 @@
 
 Return<::android::sp<hidlevs::V1_0::IEvsCamera>> HidlEnumerator::openCamera(
         const hidl_string& cameraId) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return nullptr;
+    }
+
     std::shared_ptr<IEvsCamera> aidlCamera;
     // IEvsEnumerator will open a camera with its default configuration.
     auto status = mEnumerator->openCamera(cameraId, {}, &aidlCamera);
@@ -84,6 +96,11 @@
 
 Return<void> HidlEnumerator::closeCamera(
         const ::android::sp<hidlevs::V1_0::IEvsCamera>& cameraObj) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return {};
+    }
+
     if (!cameraObj) {
         LOG(WARNING) << "Ignoring a call with an invalid camera object";
         return {};
@@ -95,16 +112,22 @@
 }
 
 Return<::android::sp<hidlevs::V1_0::IEvsDisplay>> HidlEnumerator::openDisplay() {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return nullptr;
+    }
+
+    auto displayId = kDisplayIdUnavailable;
     if (mAidlDisplayIds.empty()) {
-        auto status = mEnumerator->getDisplayIdList(&mAidlDisplayIds);
-        if (!status.isOk()) {
-            LOG(ERROR) << "Failed to get a display list";
-            return nullptr;
+        if (auto status = mEnumerator->getDisplayIdList(&mAidlDisplayIds);
+            !status.isOk() || mAidlDisplayIds.empty()) {
+            LOG(WARNING) << "Use the default display ID because we failed to get a display list.";
+        } else {
+            displayId = mAidlDisplayIds[0];
         }
     }
 
     std::shared_ptr<IEvsDisplay> aidlDisplay;
-    auto displayId = mAidlDisplayIds[0];
     if (auto status = mEnumerator->openDisplay(displayId, &aidlDisplay); !status.isOk()) {
         LOG(ERROR) << "Failed to open a display " << displayId;
         return nullptr;
@@ -123,6 +146,11 @@
 
 Return<void> HidlEnumerator::closeDisplay(
         const ::android::sp<hidlevs::V1_0::IEvsDisplay>& display) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return {};
+    }
+
     if (display != mHidlDisplay.promote()) {
         LOG(DEBUG) << "Ignores an invalid request to close the display";
         return {};
@@ -133,9 +161,14 @@
 }
 
 Return<hidlevs::V1_0::DisplayState> HidlEnumerator::getDisplayState() {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return hidlevs::V1_0::DisplayState::DEAD;
+    }
+
     DisplayState aidlState;
     if (auto status = mEnumerator->getDisplayState(&aidlState); !status.isOk()) {
-        return hidlevs::V1_0::DisplayState::DEAD;
+        return hidlevs::V1_0::DisplayState::NOT_OPEN;
     }
 
     return Utils::makeToHidl(aidlState);
@@ -143,12 +176,18 @@
 
 // Methods from hardware::automotive::evs::V1_1::IEvsEnumerator follow.
 Return<void> HidlEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        _hidl_cb({});
+        return {};
+    }
+
     std::vector<CameraDesc> aidlCameras;
     if (auto status = mEnumerator->getCameraList(&aidlCameras); !status.isOk()) {
         LOG(ERROR) << "Failed to get a list of cameras, status = "
                    << status.getServiceSpecificError();
         _hidl_cb({});
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
+        return {};
     }
 
     ::android::hardware::hidl_vec<hidlevs::V1_1::CameraDesc> hidlCameras(aidlCameras.size());
@@ -163,17 +202,22 @@
 Return<::android::sp<hidlevs::V1_1::IEvsCamera>> HidlEnumerator::openCamera_1_1(
         const hidl_string& cameraId,
         const ::android::hardware::camera::device::V3_2::Stream& hidlCfg) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return nullptr;
+    }
+
     Stream cfg = std::move(Utils::makeFromHidl(hidlCfg));
     std::shared_ptr<IEvsCamera> aidlCamera;
-    auto status = mEnumerator->openCamera(cameraId, cfg, &aidlCamera);
-    if (!status.isOk()) {
-        LOG(ERROR) << "Failed to open a camera " << cameraId;
+    if (auto status = mEnumerator->openCamera(cameraId, cfg, &aidlCamera); !status.isOk()) {
+        LOG(ERROR) << "Failed to open a camera " << cameraId
+                   << ", error = " << status.getServiceSpecificError();
         return nullptr;
     }
 
     auto hidlCamera = new (std::nothrow) HidlCamera(aidlCamera);
     if (hidlCamera == nullptr) {
-        LOG(ERROR) << "Failed to open a camera " << cameraId;
+        LOG(ERROR) << "Failed to create a HidlCamera object " << cameraId;
         return nullptr;
     }
 
@@ -181,9 +225,16 @@
 }
 
 Return<void> HidlEnumerator::getDisplayIdList(getDisplayIdList_cb _list_cb) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        _list_cb({});
+        return {};
+    }
+
     if (auto status = mEnumerator->getDisplayIdList(&mAidlDisplayIds); !status.isOk()) {
         LOG(ERROR) << "Failed to get a display list";
-        return Status::fromExceptionCode(Status::EX_TRANSACTION_FAILED);
+        _list_cb({});
+        return {};
     }
 
     _list_cb(mAidlDisplayIds);
@@ -191,6 +242,11 @@
 }
 
 Return<::android::sp<hidlevs::V1_1::IEvsDisplay>> HidlEnumerator::openDisplay_1_1(uint8_t id) {
+    if (!mEnumerator) {
+        LOG(ERROR) << "A reference to AIDL IEvsEnumerator is invalid.";
+        return nullptr;
+    }
+
     std::shared_ptr<IEvsDisplay> aidlDisplay;
     auto status = mEnumerator->openDisplay(id, &aidlDisplay);
     if (!status.isOk()) {
@@ -209,7 +265,8 @@
     return hidlDisplay;
 }
 
-Return<void> HidlEnumerator::getUltrasonicsArrayList(getUltrasonicsArrayList_cb _hidl_cb) {
+Return<void> HidlEnumerator::getUltrasonicsArrayList(
+        [[maybe_unused]] getUltrasonicsArrayList_cb _hidl_cb) {
     // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
     _hidl_cb({});
     return {};