Merge "Change CodeType from enum to string (HAL)"
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index 8f8a888..0a8d75b 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -416,9 +416,9 @@
     OUT_2POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT |
                          OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT |
                          OUT_LOW_FREQUENCY),
-    OUT_3POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_CENTER | OUT_FRONT_RIGHT |
+    OUT_3POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER |
                          OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT),
-    OUT_3POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_CENTER | OUT_FRONT_RIGHT |
+    OUT_3POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER |
                         OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT |
                         OUT_LOW_FREQUENCY),
     OUT_QUAD     = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT |
@@ -517,7 +517,23 @@
     INDEX_MASK_5 = INDEX_HDR | ((1 << 5) - 1),
     INDEX_MASK_6 = INDEX_HDR | ((1 << 6) - 1),
     INDEX_MASK_7 = INDEX_HDR | ((1 << 7) - 1),
-    INDEX_MASK_8 = INDEX_HDR | ((1 << 8) - 1)
+    INDEX_MASK_8 = INDEX_HDR | ((1 << 8) - 1),
+    INDEX_MASK_9 = INDEX_HDR | ((1 << 9) - 1),
+    INDEX_MASK_10 = INDEX_HDR | ((1 << 10) - 1),
+    INDEX_MASK_11 = INDEX_HDR | ((1 << 11) - 1),
+    INDEX_MASK_12 = INDEX_HDR | ((1 << 12) - 1),
+    INDEX_MASK_13 = INDEX_HDR | ((1 << 13) - 1),
+    INDEX_MASK_14 = INDEX_HDR | ((1 << 14) - 1),
+    INDEX_MASK_15 = INDEX_HDR | ((1 << 15) - 1),
+    INDEX_MASK_16 = INDEX_HDR | ((1 << 16) - 1),
+    INDEX_MASK_17 = INDEX_HDR | ((1 << 17) - 1),
+    INDEX_MASK_18 = INDEX_HDR | ((1 << 18) - 1),
+    INDEX_MASK_19 = INDEX_HDR | ((1 << 19) - 1),
+    INDEX_MASK_20 = INDEX_HDR | ((1 << 20) - 1),
+    INDEX_MASK_21 = INDEX_HDR | ((1 << 21) - 1),
+    INDEX_MASK_22 = INDEX_HDR | ((1 << 22) - 1),
+    INDEX_MASK_23 = INDEX_HDR | ((1 << 23) - 1),
+    INDEX_MASK_24 = INDEX_HDR | ((1 << 24) - 1),
 };
 
 /**
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 3444d34..435e19c 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2434,7 +2434,7 @@
     ERROR = 4,
 };
 
-enum VehicleApPowerStateConfigFlag : int32_t /* NOTE: type is guessed */ {
+enum VehicleApPowerStateConfigFlag : int32_t {
     /**
      * AP can enter deep sleep state. If not set, AP will always shutdown from
      * VehicleApPowerState#SHUTDOWN_PREPARE power state.
diff --git a/biometrics/face/1.0/IBiometricsFace.hal b/biometrics/face/1.0/IBiometricsFace.hal
index cd368fa..180d829 100644
--- a/biometrics/face/1.0/IBiometricsFace.hal
+++ b/biometrics/face/1.0/IBiometricsFace.hal
@@ -59,7 +59,9 @@
      *
      * @param userId A non-negative user identifier that must be unique and
      *     persistent for a given user.
-     * @param storePath filesystem path to the template storage directory.
+     * @param storePath absolute filesystem path to the template storage
+     *     directory. This must be the /data/vendor_de/<user>/facedata
+     *     directory specified by the SeLinux policy.
      */
     @callflow(next={"authenticate", "generateChallenge", "enumerate", "remove"})
     setActiveUser(int32_t userId, string storePath) generates (Status status);
@@ -159,8 +161,8 @@
      * @param enabled True to enable the feature, false to disable.
      * @param hat A valid Hardware Authentication Token, generated as a result
      *     of getChallenge().
-     * @param faceId the ID of the enrollment returned by enroll() for the
-     *     feature to update.
+     * @param faceId the ID of the enrollment returned by onEnrollResult() for
+     *     the feature to update.
      * @return status The status of this method call.
      */
     setFeature(Feature feature, bool enabled, vec<uint8_t> hat, uint32_t faceId)
diff --git a/biometrics/face/1.0/IBiometricsFaceClientCallback.hal b/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
index 969bc68..d7c317d 100644
--- a/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
+++ b/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
@@ -95,13 +95,10 @@
      *
      * @param deviceId A unique id associated with the HAL implementation
      *     service that processed this removal.
-     * @param faceId The id of the face template that was removed.
+     * @param removed A list of ids that were removed.
      * @param userId The active user id for the removed face template.
-     * @param remaining The number of face templates remaining after this
-     *     removal, or 0 if there are no more.
      */
-    oneway onRemoved(uint64_t deviceId, uint32_t faceId, int32_t userId,
-        uint32_t remaining);
+    oneway onRemoved(uint64_t deviceId, vec<uint32_t> removed, int32_t userId);
 
     /**
      * A callback invoked to enumerate all current face templates.
diff --git a/biometrics/face/1.0/types.hal b/biometrics/face/1.0/types.hal
index 8c4a4e9..de6b99e 100644
--- a/biometrics/face/1.0/types.hal
+++ b/biometrics/face/1.0/types.hal
@@ -340,9 +340,14 @@
     START = 20,
 
     /**
+     * The sensor is dirty. The user should be informed to clean the sensor.
+     */
+    SENSOR_DIRTY = 21,
+
+    /**
      * Used to enable a vendor-specific acquisition message.
      */
-    VENDOR = 21
+    VENDOR = 22
 };
 
 /**
@@ -375,4 +380,4 @@
      * This value is only meaningful if status is OK.
      */
     bool value;
-};
\ No newline at end of file
+};
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index 795a1ae..40961f7 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -104,7 +104,7 @@
         return Return<void>();
     }
 
-    Return<void> onRemoved(uint64_t, uint32_t, int32_t, uint32_t) override {
+    Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
         ALOGD("Removed callback called.");
         return Return<void>();
     }
@@ -155,12 +155,9 @@
   public:
     explicit RemoveCallback(int32_t userId) : removeUserId(userId) {}
 
-    Return<void> onRemoved(uint64_t, uint32_t, int32_t userId, uint32_t remaining) override {
+    Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
         EXPECT_EQ(removeUserId, userId);
         promise.set_value();
-        if (remaining == 0UL) {
-            promise.set_value();
-        }
         return Return<void>();
     }
 
diff --git a/camera/common/1.0/default/OWNERS b/camera/common/1.0/default/OWNERS
index 369b204..f112576 100644
--- a/camera/common/1.0/default/OWNERS
+++ b/camera/common/1.0/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av/camera:/OWNERS
diff --git a/camera/device/1.0/default/OWNERS b/camera/device/1.0/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/device/1.0/default/OWNERS
+++ b/camera/device/1.0/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.2/default/OWNERS b/camera/device/3.2/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/device/3.2/default/OWNERS
+++ b/camera/device/3.2/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.3/default/OWNERS b/camera/device/3.3/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/device/3.3/default/OWNERS
+++ b/camera/device/3.3/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 0f23657..3f04751 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -38,9 +38,8 @@
 // Other formats to consider in the future:
 // * V4L2_PIX_FMT_YVU420 (== YV12)
 // * V4L2_PIX_FMT_YVYU (YVYU: can be converted to YV12 or other YUV420_888 formats)
-const std::array<uint32_t, /*size*/1> kSupportedFourCCs {{
-    V4L2_PIX_FMT_MJPEG
-}}; // double braces required in C++11
+const std::array<uint32_t, /*size*/ 2> kSupportedFourCCs{
+    {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_Z16}};  // double braces required in C++11
 
 constexpr int MAX_RETRY = 5; // Allow retry v4l2 open failures a few times.
 constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds
@@ -231,6 +230,13 @@
             mCameraCharacteristics.clear();
             return ret;
         }
+
+        ret = initAvailableCapabilities(&mCameraCharacteristics);
+        if (ret != OK) {
+            ALOGE("%s: init available capabilities key failed: errorno %d", __FUNCTION__, ret);
+            mCameraCharacteristics.clear();
+            return ret;
+        }
     }
     return OK;
 }
@@ -244,6 +250,39 @@
   }                                                \
 } while (0)
 
+status_t ExternalCameraDevice::initAvailableCapabilities(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+
+    if (mSupportedFormats.empty()) {
+        ALOGE("%s: Supported formats list is empty", __FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    bool hasDepth = false;
+    bool hasColor = false;
+    for (const auto& fmt : mSupportedFormats) {
+        switch (fmt.fourcc) {
+            case V4L2_PIX_FMT_Z16: hasDepth = true; break;
+            case V4L2_PIX_FMT_MJPEG: hasColor = true; break;
+            default: ALOGW("%s: Unsupported format found", __FUNCTION__);
+        }
+    }
+
+    std::vector<uint8_t> availableCapabilities;
+    if (hasDepth) {
+        availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
+    }
+    if (hasColor) {
+        availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+    }
+    if(!availableCapabilities.empty()) {
+        UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities.data(),
+            availableCapabilities.size());
+    }
+
+    return OK;
+}
+
 status_t ExternalCameraDevice::initDefaultCharsKeys(
         ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
     const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
@@ -330,12 +369,6 @@
            &noiseReductionMode, 1);
     UPDATE(ANDROID_NOISE_REDUCTION_MODE, &noiseReductionMode, 1);
 
-    // android.request
-    const uint8_t availableCapabilities[] = {
-        ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE};
-    UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities,
-           ARRAY_SIZE(availableCapabilities));
-
     const int32_t partialResultCount = 1;
     UPDATE(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, 1);
 
@@ -544,9 +577,11 @@
     return OK;
 }
 
-status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
-        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
-    initSupportedFormatsLocked(fd);
+template <size_t SIZE>
+status_t ExternalCameraDevice::initOutputCharskeysByFormat(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata,
+        uint32_t fourcc, const std::array<int, SIZE>& halFormats,
+        int streamConfigTag, int streamConfiguration, int minFrameDuration, int stallDuration) {
     if (mSupportedFormats.empty()) {
         ALOGE("%s: Init supported format list failed", __FUNCTION__);
         return UNKNOWN_ERROR;
@@ -555,22 +590,17 @@
     std::vector<int32_t> streamConfigurations;
     std::vector<int64_t> minFrameDurations;
     std::vector<int64_t> stallDurations;
-    int32_t maxFps = std::numeric_limits<int32_t>::min();
-    int32_t minFps = std::numeric_limits<int32_t>::max();
-    std::set<int32_t> framerates;
-
-    std::array<int, /*size*/3> halFormats{{
-        HAL_PIXEL_FORMAT_BLOB,
-        HAL_PIXEL_FORMAT_YCbCr_420_888,
-        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}};
 
     for (const auto& supportedFormat : mSupportedFormats) {
+        if (supportedFormat.fourcc != fourcc) {
+            // Skip 4CCs not meant for the halFormats
+            continue;
+        }
         for (const auto& format : halFormats) {
             streamConfigurations.push_back(format);
             streamConfigurations.push_back(supportedFormat.width);
             streamConfigurations.push_back(supportedFormat.height);
-            streamConfigurations.push_back(
-                    ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
+            streamConfigurations.push_back(streamConfigTag);
         }
 
         int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
@@ -582,14 +612,6 @@
             if (frameDuration < minFrameDuration) {
                 minFrameDuration = frameDuration;
             }
-            int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
-            if (minFps > frameRateInt) {
-                minFps = frameRateInt;
-            }
-            if (maxFps < frameRateInt) {
-                maxFps = frameRateInt;
-            }
-            framerates.insert(frameRateInt);
         }
 
         for (const auto& format : halFormats) {
@@ -613,6 +635,30 @@
         }
     }
 
+    UPDATE(streamConfiguration, streamConfigurations.data(), streamConfigurations.size());
+
+    UPDATE(minFrameDuration, minFrameDurations.data(), minFrameDurations.size());
+
+    UPDATE(stallDuration, stallDurations.data(), stallDurations.size());
+
+    return true;
+}
+
+bool ExternalCameraDevice::calculateMinFps(
+    ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    std::set<int32_t> framerates;
+    int32_t minFps = std::numeric_limits<int32_t>::max();
+
+    for (const auto& supportedFormat : mSupportedFormats) {
+        for (const auto& fr : supportedFormat.frameRates) {
+            int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
+            if (minFps > frameRateInt) {
+                minFps = frameRateInt;
+            }
+            framerates.insert(frameRateInt);
+        }
+    }
+
     std::vector<int32_t> fpsRanges;
     // FPS ranges
     for (const auto& framerate : framerates) {
@@ -626,17 +672,60 @@
     UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(),
            fpsRanges.size());
 
-    UPDATE(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
-           streamConfigurations.data(), streamConfigurations.size());
-
-    UPDATE(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
-           minFrameDurations.data(), minFrameDurations.size());
-
-    UPDATE(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, stallDurations.data(),
-           stallDurations.size());
-
     UPDATE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &maxFrameDuration, 1);
 
+    return true;
+}
+
+status_t ExternalCameraDevice::initOutputCharsKeys(
+    int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    initSupportedFormatsLocked(fd);
+    if (mSupportedFormats.empty()) {
+        ALOGE("%s: Init supported format list failed", __FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    bool hasDepth = false;
+    bool hasColor = false;
+
+    // For V4L2_PIX_FMT_Z16
+    std::array<int, /*size*/ 1> halDepthFormats{{HAL_PIXEL_FORMAT_Y16}};
+    // For V4L2_PIX_FMT_MJPEG
+    std::array<int, /*size*/ 3> halFormats{{HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
+                                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}};
+
+    for (const auto& supportedFormat : mSupportedFormats) {
+        switch (supportedFormat.fourcc) {
+            case V4L2_PIX_FMT_Z16:
+                hasDepth = true;
+                break;
+            case V4L2_PIX_FMT_MJPEG:
+                hasColor = true;
+                break;
+            default:
+                ALOGW("%s: format %c%c%c%c is not supported!", __FUNCTION__,
+                      supportedFormat.fourcc & 0xFF, (supportedFormat.fourcc >> 8) & 0xFF,
+                      (supportedFormat.fourcc >> 16) & 0xFF, (supportedFormat.fourcc >> 24) & 0xFF);
+        }
+    }
+
+    if (hasDepth) {
+        initOutputCharskeysByFormat(metadata, V4L2_PIX_FMT_Z16, halDepthFormats,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
+    }
+    if (hasColor) {
+        initOutputCharskeysByFormat(metadata, V4L2_PIX_FMT_MJPEG, halFormats,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+                ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+                ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+    }
+
+    calculateMinFps(metadata);
+
     SupportedV4L2Format maximumFormat {.width = 0, .height = 0};
     for (const auto& supportedFormat : mSupportedFormats) {
         if (supportedFormat.width >= maximumFormat.width &&
@@ -758,11 +847,12 @@
     sortedFmts = out;
 }
 
-std::vector<SupportedV4L2Format>
-ExternalCameraDevice::getCandidateSupportedFormatsLocked(
-        int fd, CroppingType cropType,
-        const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
-        const Size& minStreamSize) {
+std::vector<SupportedV4L2Format> ExternalCameraDevice::getCandidateSupportedFormatsLocked(
+    int fd, CroppingType cropType,
+    const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+    const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+    const Size& minStreamSize,
+    bool depthEnabled) {
     std::vector<SupportedV4L2Format> outFmts;
     struct v4l2_fmtdesc fmtdesc {
         .index = 0,
@@ -808,28 +898,10 @@
                             .fourcc = fmtdesc.pixelformat
                         };
 
-                        double fpsUpperBound = -1.0;
-                        for (const auto& limit : fpsLimits) {
-                            if (cropType == VERTICAL) {
-                                if (format.width <= limit.size.width) {
-                                    fpsUpperBound = limit.fpsUpperBound;
-                                    break;
-                                }
-                            } else { // HORIZONTAL
-                                if (format.height <= limit.size.height) {
-                                    fpsUpperBound = limit.fpsUpperBound;
-                                    break;
-                                }
-                            }
-
-                        }
-                        if (fpsUpperBound < 0.f) {
-                            continue;
-                        }
-
-                        getFrameRateList(fd, fpsUpperBound, &format);
-                        if (!format.frameRates.empty()) {
-                            outFmts.push_back(format);
+                        if (format.fourcc == V4L2_PIX_FMT_Z16 && depthEnabled) {
+                            updateFpsBounds(fd, cropType, depthFpsLimits, format, outFmts);
+                        } else {
+                            updateFpsBounds(fd, cropType, fpsLimits, format, outFmts);
                         }
                     }
                 }
@@ -841,12 +913,39 @@
     return outFmts;
 }
 
-void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+void ExternalCameraDevice::updateFpsBounds(
+    int fd, CroppingType cropType,
+    const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits, SupportedV4L2Format format,
+    std::vector<SupportedV4L2Format>& outFmts) {
+    double fpsUpperBound = -1.0;
+    for (const auto& limit : fpsLimits) {
+        if (cropType == VERTICAL) {
+            if (format.width <= limit.size.width) {
+                fpsUpperBound = limit.fpsUpperBound;
+                break;
+            }
+        } else {  // HORIZONTAL
+            if (format.height <= limit.size.height) {
+                fpsUpperBound = limit.fpsUpperBound;
+                break;
+            }
+        }
+    }
+    if (fpsUpperBound < 0.f) {
+        return;
+    }
 
-    std::vector<SupportedV4L2Format> horizontalFmts =
-            getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits, mCfg.minStreamSize);
-    std::vector<SupportedV4L2Format> verticalFmts =
-            getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits, mCfg.minStreamSize);
+    getFrameRateList(fd, fpsUpperBound, &format);
+    if (!format.frameRates.empty()) {
+        outFmts.push_back(format);
+    }
+}
+
+void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+    std::vector<SupportedV4L2Format> horizontalFmts = getCandidateSupportedFormatsLocked(
+        fd, HORIZONTAL, mCfg.fpsLimits, mCfg.depthFpsLimits, mCfg.minStreamSize, mCfg.depthEnabled);
+    std::vector<SupportedV4L2Format> verticalFmts = getCandidateSupportedFormatsLocked(
+        fd, VERTICAL, mCfg.fpsLimits, mCfg.depthFpsLimits, mCfg.minStreamSize, mCfg.depthEnabled);
 
     size_t horiSize = horizontalFmts.size();
     size_t vertSize = verticalFmts.size();
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 66b17db..32da968 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -1819,7 +1819,7 @@
         return false;
     };
 
-    if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) {
+    if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) {
         return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
                 req->frameIn->mFourcc & 0xFF,
                 (req->frameIn->mFourcc >> 8) & 0xFF,
@@ -1844,29 +1844,26 @@
     }
 
     // TODO: in some special case maybe we can decode jpg directly to gralloc output?
-    ATRACE_BEGIN("MJPGtoI420");
-    res = libyuv::MJPGToI420(
-            inData, inDataSize,
-            static_cast<uint8_t*>(mYu12FrameLayout.y),
-            mYu12FrameLayout.yStride,
-            static_cast<uint8_t*>(mYu12FrameLayout.cb),
-            mYu12FrameLayout.cStride,
-            static_cast<uint8_t*>(mYu12FrameLayout.cr),
-            mYu12FrameLayout.cStride,
-            mYu12Frame->mWidth, mYu12Frame->mHeight,
-            mYu12Frame->mWidth, mYu12Frame->mHeight);
-    ATRACE_END();
+    if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) {
+        ATRACE_BEGIN("MJPGtoI420");
+        int res = libyuv::MJPGToI420(
+            inData, inDataSize, static_cast<uint8_t*>(mYu12FrameLayout.y), mYu12FrameLayout.yStride,
+            static_cast<uint8_t*>(mYu12FrameLayout.cb), mYu12FrameLayout.cStride,
+            static_cast<uint8_t*>(mYu12FrameLayout.cr), mYu12FrameLayout.cStride,
+            mYu12Frame->mWidth, mYu12Frame->mHeight, mYu12Frame->mWidth, mYu12Frame->mHeight);
+        ATRACE_END();
 
-    if (res != 0) {
-        // For some webcam, the first few V4L2 frames might be malformed...
-        ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
-        lk.unlock();
-        Status st = parent->processCaptureRequestError(req);
-        if (st != Status::OK) {
-            return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+        if (res != 0) {
+            // For some webcam, the first few V4L2 frames might be malformed...
+            ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
+            lk.unlock();
+            Status st = parent->processCaptureRequestError(req);
+            if (st != Status::OK) {
+                return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+            }
+            signalRequestDone();
+            return true;
         }
-        signalRequestDone();
-        return true;
     }
 
     ATRACE_BEGIN("Wait for BufferRequest done");
@@ -1910,6 +1907,16 @@
                           __FUNCTION__, ret);
                 }
             } break;
+            case PixelFormat::Y16: {
+                void* outLayout = sHandleImporter.lock(*(halBuf.bufPtr), halBuf.usage, inDataSize);
+
+                std::memcpy(outLayout, inData, inDataSize);
+
+                int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+                if (relFence >= 0) {
+                    halBuf.acquireFence = relFence;
+                }
+            } break;
             case PixelFormat::YCBCR_420_888:
             case PixelFormat::YV12: {
                 IMapper::Rect outRect {0, 0,
@@ -2164,7 +2171,8 @@
 }
 
 bool ExternalCameraDeviceSession::isSupported(const Stream& stream,
-        const std::vector<SupportedV4L2Format>& supportedFormats) {
+        const std::vector<SupportedV4L2Format>& supportedFormats,
+        const ExternalCameraConfig& devCfg) {
     int32_t ds = static_cast<int32_t>(stream.dataSpace);
     PixelFormat fmt = stream.format;
     uint32_t width = stream.width;
@@ -2181,11 +2189,6 @@
         return false;
     }
 
-    if (ds & Dataspace::DEPTH) {
-        ALOGI("%s: does not support depth output", __FUNCTION__);
-        return false;
-    }
-
     switch (fmt) {
         case PixelFormat::BLOB:
             if (ds != static_cast<int32_t>(Dataspace::V0_JFIF)) {
@@ -2199,6 +2202,16 @@
             // TODO: check what dataspace we can support here.
             // intentional no-ops.
             break;
+        case PixelFormat::Y16:
+            if (!devCfg.depthEnabled) {
+                ALOGI("%s: Depth is not Enabled", __FUNCTION__);
+                return false;
+            }
+            if (!(ds & Dataspace::DEPTH)) {
+                ALOGI("%s: Y16 supports only dataSpace DEPTH", __FUNCTION__);
+                return false;
+            }
+            break;
         default:
             ALOGI("%s: does not support format %x", __FUNCTION__, fmt);
             return false;
@@ -2544,7 +2557,8 @@
 
 Status ExternalCameraDeviceSession::isStreamCombinationSupported(
         const V3_2::StreamConfiguration& config,
-        const std::vector<SupportedV4L2Format>& supportedFormats) {
+        const std::vector<SupportedV4L2Format>& supportedFormats,
+        const ExternalCameraConfig& devCfg) {
     if (config.operationMode != StreamConfigurationMode::NORMAL_MODE) {
         ALOGE("%s: unsupported operation mode: %d", __FUNCTION__, config.operationMode);
         return Status::ILLEGAL_ARGUMENT;
@@ -2559,7 +2573,7 @@
     int numStallStream = 0;
     for (const auto& stream : config.streams) {
         // Check if the format/width/height combo is supported
-        if (!isSupported(stream, supportedFormats)) {
+        if (!isSupported(stream, supportedFormats, devCfg)) {
             return Status::ILLEGAL_ARGUMENT;
         }
         if (stream.format == PixelFormat::BLOB) {
@@ -2590,7 +2604,7 @@
         uint32_t blobBufferSize) {
     ATRACE_CALL();
 
-    Status status = isStreamCombinationSupported(config, mSupportedFormats);
+    Status status = isStreamCombinationSupported(config, mSupportedFormats, mCfg);
     if (status != Status::OK) {
         return status;
     }
@@ -2744,6 +2758,7 @@
             case PixelFormat::BLOB:
             case PixelFormat::YCBCR_420_888:
             case PixelFormat::YV12: // Used by SurfaceTexture
+            case PixelFormat::Y16:
                 // No override
                 out->streams[i].v3_2.overrideFormat = config.streams[i].format;
                 break;
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 0941052..e25deff 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -21,7 +21,6 @@
 #include <sys/mman.h>
 #include <linux/videodev2.h>
 #include "ExternalCameraUtils.h"
-#include "tinyxml2.h" // XML parsing
 
 namespace android {
 namespace hardware {
@@ -245,28 +244,28 @@
     if (fpsList == nullptr) {
         ALOGI("%s: no fps list specified", __FUNCTION__);
     } else {
-        std::vector<FpsLimitation> limits;
-        XMLElement *row = fpsList->FirstChildElement("Limit");
-        while (row != nullptr) {
-            FpsLimitation prevLimit {{0, 0}, 1000.0};
-            FpsLimitation limit;
-            limit.size = {
-                row->UnsignedAttribute("width", /*Default*/0),
-                row->UnsignedAttribute("height", /*Default*/0)};
-            limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/1000.0);
-            if (limit.size.width <= prevLimit.size.width ||
-                    limit.size.height <= prevLimit.size.height ||
-                    limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
-                ALOGE("%s: FPS limit list must have increasing size and decreasing fps!"
-                        " Prev %dx%d@%f, Current %dx%d@%f", __FUNCTION__,
-                        prevLimit.size.width, prevLimit.size.height, prevLimit.fpsUpperBound,
-                        limit.size.width, limit.size.height, limit.fpsUpperBound);
+        if (!updateFpsList(fpsList, ret.fpsLimits)) {
+            return ret;
+        }
+    }
+
+    XMLElement *depth = deviceCfg->FirstChildElement("Depth16Supported");
+    if (depth == nullptr) {
+        ret.depthEnabled = false;
+        ALOGI("%s: depth output is not enabled", __FUNCTION__);
+    } else {
+        ret.depthEnabled = depth->BoolAttribute("enabled", false);
+    }
+
+    if(ret.depthEnabled) {
+        XMLElement *depthFpsList = deviceCfg->FirstChildElement("DepthFpsList");
+        if (depthFpsList == nullptr) {
+            ALOGW("%s: no depth fps list specified", __FUNCTION__);
+        } else {
+            if(!updateFpsList(depthFpsList, ret.depthFpsLimits)) {
                 return ret;
             }
-            limits.push_back(limit);
-            row = row->NextSiblingElement("Limit");
         }
-        ret.fpsLimits = limits;
     }
 
     XMLElement *minStreamSize = deviceCfg->FirstChildElement("MinimumStreamSize");
@@ -293,15 +292,48 @@
         ALOGI("%s: fpsLimitList: %dx%d@%f", __FUNCTION__,
                 limit.size.width, limit.size.height, limit.fpsUpperBound);
     }
+    for (const auto& limit : ret.depthFpsLimits) {
+        ALOGI("%s: depthFpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height,
+              limit.fpsUpperBound);
+    }
     ALOGI("%s: minStreamSize: %dx%d" , __FUNCTION__,
          ret.minStreamSize.width, ret.minStreamSize.height);
     return ret;
 }
 
+bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList,
+        std::vector<FpsLimitation>& fpsLimits) {
+    using namespace tinyxml2;
+    std::vector<FpsLimitation> limits;
+    XMLElement* row = fpsList->FirstChildElement("Limit");
+    while (row != nullptr) {
+        FpsLimitation prevLimit{{0, 0}, 1000.0};
+        FpsLimitation limit;
+        limit.size = {row->UnsignedAttribute("width", /*Default*/ 0),
+                      row->UnsignedAttribute("height", /*Default*/ 0)};
+        limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/ 1000.0);
+        if (limit.size.width <= prevLimit.size.width ||
+            limit.size.height <= prevLimit.size.height ||
+            limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
+            ALOGE(
+                "%s: FPS limit list must have increasing size and decreasing fps!"
+                " Prev %dx%d@%f, Current %dx%d@%f",
+                __FUNCTION__, prevLimit.size.width, prevLimit.size.height, prevLimit.fpsUpperBound,
+                limit.size.width, limit.size.height, limit.fpsUpperBound);
+            return false;
+        }
+        limits.push_back(limit);
+        row = row->NextSiblingElement("Limit");
+    }
+    fpsLimits = limits;
+    return true;
+}
+
 ExternalCameraConfig::ExternalCameraConfig() :
         maxJpegBufSize(kDefaultJpegBufSize),
         numVideoBuffers(kDefaultNumVideoBuffer),
         numStillBuffers(kDefaultNumStillBuffer),
+        depthEnabled(false),
         orientation(kDefaultOrientation) {
     fpsLimits.push_back({/*Size*/{ 640,  480}, /*FPS upper bound*/30.0});
     fpsLimits.push_back({/*Size*/{1280,  720}, /*FPS upper bound*/7.5});
diff --git a/camera/device/3.4/default/OWNERS b/camera/device/3.4/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/device/3.4/default/OWNERS
+++ b/camera/device/3.4/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 9cc55cb..71b7c17 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -194,7 +194,8 @@
     int v4l2StreamOffLocked();
     int setV4l2FpsLocked(double fps);
     static Status isStreamCombinationSupported(const V3_2::StreamConfiguration& config,
-            const std::vector<SupportedV4L2Format>& supportedFormats);
+            const std::vector<SupportedV4L2Format>& supportedFormats,
+            const ExternalCameraConfig& devCfg);
 
     // TODO: change to unique_ptr for better tracking
     sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
@@ -202,7 +203,8 @@
 
     // Check if input Stream is one of supported stream setting on this device
     static bool isSupported(const Stream& stream,
-            const std::vector<SupportedV4L2Format>& supportedFormats);
+            const std::vector<SupportedV4L2Format>& supportedFormats,
+            const ExternalCameraConfig& cfg);
 
     // Validate and import request's output buffers and acquire fence
     virtual Status importRequestLocked(
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index 719a3ed..bd79807 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -104,6 +104,9 @@
 
     // Calls into virtual member function. Do not use it in constructor
     status_t initCameraCharacteristics();
+    // Init available capabilities keys
+    status_t initAvailableCapabilities(
+            ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
     // Init non-device dependent keys
     virtual status_t initDefaultCharsKeys(
             ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
@@ -114,13 +117,30 @@
     status_t initOutputCharsKeys(int fd,
             ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
 
+    // Helper function for initOutputCharskeys
+    template <size_t SIZE>
+    status_t initOutputCharskeysByFormat(
+            ::android::hardware::camera::common::V1_0::helper::CameraMetadata*,
+            uint32_t fourcc, const std::array<int, SIZE>& formats,
+            int scaler_stream_config_tag,
+            int stream_configuration, int min_frame_duration, int stall_duration);
+
+    bool calculateMinFps(::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+
     static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format);
 
+    static void updateFpsBounds(int fd, CroppingType cropType,
+            const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+            SupportedV4L2Format format,
+            std::vector<SupportedV4L2Format>& outFmts);
+
     // Get candidate supported formats list of input cropping type.
     static std::vector<SupportedV4L2Format> getCandidateSupportedFormatsLocked(
             int fd, CroppingType cropType,
             const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
-            const Size& minStreamSize);
+            const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+            const Size& minStreamSize,
+            bool depthEnabled);
     // Trim supported format list by the cropping type. Also sort output formats by width/height
     static void trimSupportedFormats(CroppingType cropType,
             /*inout*/std::vector<SupportedV4L2Format>* pFmts);
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index 3b1ac96..341c622 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -17,12 +17,13 @@
 #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_EXTCAMUTIL_H
 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_EXTCAMUTIL_H
 
-#include <inttypes.h>
-#include "utils/LightRefBase.h"
-#include <mutex>
-#include <vector>
-#include <unordered_set>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <inttypes.h>
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+#include "tinyxml2.h"  // XML parsing
+#include "utils/LightRefBase.h"
 
 using android::hardware::graphics::mapper::V2_0::IMapper;
 using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
@@ -71,11 +72,15 @@
     // Size of v4l2 buffer queue when streaming > kMaxVideoSize
     uint32_t numStillBuffers;
 
+    // Indication that the device connected supports depth output
+    bool depthEnabled;
+
     struct FpsLimitation {
         Size size;
         double fpsUpperBound;
     };
     std::vector<FpsLimitation> fpsLimits;
+    std::vector<FpsLimitation> depthFpsLimits;
 
     // Minimum output stream size
     Size minStreamSize;
@@ -85,6 +90,7 @@
 
 private:
     ExternalCameraConfig();
+    static bool updateFpsList(tinyxml2::XMLElement* fpsList, std::vector<FpsLimitation>& fpsLimits);
 };
 
 } // common
diff --git a/camera/device/3.5/default/ExternalCameraDevice.cpp b/camera/device/3.5/default/ExternalCameraDevice.cpp
index 6a0b51e..d0de1a4 100644
--- a/camera/device/3.5/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.5/default/ExternalCameraDevice.cpp
@@ -103,7 +103,7 @@
     }
     V3_2::StreamConfiguration streamConfig = {streamsV3_2, streams.operationMode};
     auto status = ExternalCameraDeviceSession::isStreamCombinationSupported(streamConfig,
-            mSupportedFormats);
+            mSupportedFormats, mCfg);
     _hidl_cb(Status::OK, Status::OK == status);
     return Void();
 }
diff --git a/camera/device/3.5/default/OWNERS b/camera/device/3.5/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/device/3.5/default/OWNERS
+++ b/camera/device/3.5/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
index d2b5e89..281f93a 100644
--- a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
@@ -91,9 +91,10 @@
     }
 
     static Status isStreamCombinationSupported(const V3_2::StreamConfiguration& config,
-            const std::vector<SupportedV4L2Format>& supportedFormats) {
+            const std::vector<SupportedV4L2Format>& supportedFormats,
+            const ExternalCameraConfig& devCfg) {
         return V3_4::implementation::ExternalCameraDeviceSession::isStreamCombinationSupported(
-                config, supportedFormats);
+                config, supportedFormats, devCfg);
     }
 
 protected:
diff --git a/camera/metadata/3.3/types.hal b/camera/metadata/3.3/types.hal
index 1ed8ed8..ca0c9d6 100644
--- a/camera/metadata/3.3/types.hal
+++ b/camera/metadata/3.3/types.hal
@@ -22,7 +22,6 @@
 
 package android.hardware.camera.metadata@3.3;
 
-/* Include definitions from all prior minor HAL metadata revisions */
 import android.hardware.camera.metadata@3.2;
 
 /**
diff --git a/camera/provider/2.4/default/OWNERS b/camera/provider/2.4/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/provider/2.4/default/OWNERS
+++ b/camera/provider/2.4/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/provider/2.4/vts/OWNERS b/camera/provider/2.4/vts/OWNERS
index 003fe71..b8f6b04 100644
--- a/camera/provider/2.4/vts/OWNERS
+++ b/camera/provider/2.4/vts/OWNERS
@@ -1,10 +1,5 @@
 # Camera team
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
 
 # VTS team
 yim@google.com
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 3949346..d77bb0e 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -782,6 +782,8 @@
     void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
             camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
 
+    bool isDepthOnly(camera_metadata_t* staticMeta);
+
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
@@ -793,6 +795,10 @@
             std::unordered_set<std::string> *physicalIds/*out*/);
     static Status getSupportedKeys(camera_metadata_t *staticMeta,
             uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
+    static void fillOutputStreams(camera_metadata_ro_entry_t* entry,
+            std::vector<AvailableStream>& outputStreams,
+            const AvailableStream *threshold = nullptr,
+            const int32_t availableConfigOutputTag = 0u);
     static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
             const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
             android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
@@ -2845,14 +2851,24 @@
         uint32_t streamConfigCounter = 0;
         for (auto& it : outputStreams) {
             V3_2::Stream stream3_2;
-            bool isJpeg = static_cast<PixelFormat>(it.format) == PixelFormat::BLOB;
+            V3_2::DataspaceFlags dataspaceFlag = 0;
+            switch (static_cast<PixelFormat>(it.format)) {
+                case PixelFormat::BLOB:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
+                    break;
+                case PixelFormat::Y16:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+                    break;
+                default:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+            }
             stream3_2 = {streamId,
                              StreamType::OUTPUT,
                              static_cast<uint32_t>(it.width),
                              static_cast<uint32_t>(it.height),
                              static_cast<PixelFormat>(it.format),
                              GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
-                             (isJpeg) ? static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF) : 0,
+                             dataspaceFlag,
                              StreamRotation::ROTATION_0};
             ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
             ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
@@ -3415,6 +3431,14 @@
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
+        // Check if camera support depth only
+        if (isDepthOnly(staticMeta)) {
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
@@ -3735,6 +3759,14 @@
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
+        // Check if camera support depth only
+        if (isDepthOnly(staticMeta)) {
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
@@ -4723,38 +4755,56 @@
 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
         std::vector<AvailableStream> &outputStreams,
         const AvailableStream *threshold) {
+    AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                             static_cast<int32_t>(PixelFormat::Y16)};
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
     }
 
-    camera_metadata_ro_entry entry;
-    int rc = find_camera_metadata_ro_entry(staticMeta,
-            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
-    if ((0 != rc) || (0 != (entry.count % 4))) {
+    camera_metadata_ro_entry scalarEntry;
+    camera_metadata_ro_entry depthEntry;
+    int foundScalar = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry);
+    int foundDepth = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
+    if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) &&
+        (0 != foundDepth || (0 != (depthEntry.count % 4)))) {
         return Status::ILLEGAL_ARGUMENT;
     }
 
-    for (size_t i = 0; i < entry.count; i+=4) {
-        if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
-                entry.data.i32[i + 3]) {
+    if(foundScalar == 0 && (0 == (scalarEntry.count % 4))) {
+        fillOutputStreams(&scalarEntry, outputStreams, threshold,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
+    }
+
+    if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
+        fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
+    }
+
+    return Status::OK;
+}
+
+void CameraHidlTest::fillOutputStreams(camera_metadata_ro_entry_t* entry,
+        std::vector<AvailableStream>& outputStreams, const AvailableStream* threshold,
+        const int32_t availableConfigOutputTag) {
+    for (size_t i = 0; i < entry->count; i+=4) {
+        if (availableConfigOutputTag == entry->data.i32[i + 3]) {
             if(nullptr == threshold) {
-                AvailableStream s = {entry.data.i32[i+1],
-                        entry.data.i32[i+2], entry.data.i32[i]};
+                AvailableStream s = {entry->data.i32[i+1],
+                        entry->data.i32[i+2], entry->data.i32[i]};
                 outputStreams.push_back(s);
             } else {
-                if ((threshold->format == entry.data.i32[i]) &&
-                        (threshold->width >= entry.data.i32[i+1]) &&
-                        (threshold->height >= entry.data.i32[i+2])) {
-                    AvailableStream s = {entry.data.i32[i+1],
-                            entry.data.i32[i+2], threshold->format};
+                if ((threshold->format == entry->data.i32[i]) &&
+                        (threshold->width >= entry->data.i32[i+1]) &&
+                        (threshold->height >= entry->data.i32[i+2])) {
+                    AvailableStream s = {entry->data.i32[i+1],
+                            entry->data.i32[i+2], threshold->format};
                     outputStreams.push_back(s);
                 }
             }
         }
-
     }
-
-    return Status::OK;
 }
 
 // Get max jpeg buffer size in android.jpeg.maxSize
@@ -5226,6 +5276,37 @@
     ASSERT_TRUE(ret.isOk());
 }
 
+bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry scalarEntry;
+    camera_metadata_ro_entry depthEntry;
+
+    int rc = find_camera_metadata_ro_entry(
+        staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry);
+    if (rc == 0) {
+        for (uint32_t i = 0; i < scalarEntry.count; i++) {
+            if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
+                return false;
+            }
+        }
+    }
+
+    for (uint32_t i = 0; i < scalarEntry.count; i++) {
+        if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
+
+            rc = find_camera_metadata_ro_entry(
+                staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
+            size_t i = 0;
+            if (rc == 0 && depthEntry.data.i32[i] == static_cast<int32_t>(PixelFormat::Y16)) {
+                // only Depth16 format is supported now
+                return true;
+            }
+            break;
+        }
+    }
+
+    return false;
+}
+
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
         sp<ICameraProvider> provider,
@@ -5316,11 +5397,20 @@
     ASSERT_EQ(Status::OK, rc);
     ASSERT_FALSE(outputPreviewStreams.empty());
 
+    V3_2::DataspaceFlags dataspaceFlag = 0;
+    switch (static_cast<PixelFormat>(outputPreviewStreams[0].format)) {
+        case PixelFormat::Y16:
+            dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+            break;
+        default:
+            dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+    }
+
     V3_2::Stream stream3_2 = {0, StreamType::OUTPUT,
             static_cast<uint32_t> (outputPreviewStreams[0].width),
             static_cast<uint32_t> (outputPreviewStreams[0].height),
             static_cast<PixelFormat> (outputPreviewStreams[0].format),
-            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
+            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, dataspaceFlag, StreamRotation::ROTATION_0};
     ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
     ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
     ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
diff --git a/camera/provider/2.5/default/OWNERS b/camera/provider/2.5/default/OWNERS
index 369b204..f48a95c 100644
--- a/camera/provider/2.5/default/OWNERS
+++ b/camera/provider/2.5/default/OWNERS
@@ -1,7 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-jchowdhary@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/current.txt b/current.txt
index a1c5fec..62f04d0 100644
--- a/current.txt
+++ b/current.txt
@@ -390,15 +390,16 @@
 684702a60deef03a1e8093961dc0a18c555c857ad5a77ba7340b0635ae01eb70 android.hardware.camera.device@3.4::ICameraDeviceSession
 f8a19622cb0cc890913b1ef3e32b675ffb26089a09e02fef4056ebad324d2b5d android.hardware.camera.device@3.4::types
 291638a1b6d4e63283e9e722ab5049d9351717ffa2b66162124f84d1aa7c2835 android.hardware.camera.metadata@3.2::types
-a31142da4cc87ad50e4e981d12291d4decbb432fcb00f175f0ca904d0fcdbe5b android.hardware.camera.metadata@3.3::types
+23780340c686ee86986aa5a9755c2d8566224fed177bbb22a5ebf06be574b60c android.hardware.camera.metadata@3.3::types
 da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
 21165b8e30c4b2d52980e4728f661420adc16e38bbe73476c06b2085be908f4c android.hardware.gnss@1.0::IGnssCallback
 d702fb01dc2a0733aa820b7eb65435ee3334f75632ef880bafd2fb8803a20a58 android.hardware.gnss@1.0::IGnssMeasurementCallback
+7c7721c0f773fcf422b71a4f558545e9e36acc973e58ca51e5bd53905cf46bc0 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
 d4fea995378bb4f421b4e24ccf68cad2734ab07fe4f874a126ba558b99df5766 android.hardware.graphics.composer@2.1::IComposerClient
 b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
 574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
 417ab60fe1ef786778047e4486f3d868ebce570d91addd8fe4251515213072de android.hardware.neuralnetworks@1.0::types
-e22e8135d061d0e9c4c1a70c25c19fdba10f4d3cda9795ef25b6392fc520317c android.hardware.neuralnetworks@1.1::types
+ec8aa14fe9b03f2b3fb9845346a4005b6d098ebe2277b2564f73a548a0fd14a7 android.hardware.neuralnetworks@1.1::types
 1d4a5776614c08b5d794a5ec5ab04697260cbd4b3441d5935cd53ee71d19da02 android.hardware.radio@1.0::IRadioResponse
 ed9da80ec0c96991fd03f0a46107815d0e50f764656e49dba4980fa5c31d5bc3 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
@@ -419,7 +420,7 @@
 9471b12b1c255bb530695720bc4174bd74987b75b1f820854af8944bc8c215c9 android.hardware.audio@5.0::IStreamOut
 1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
 83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
-894af04bebfe7da5b6791eefeb6eb3627da63d5efea735f16876d11d8ca4f61d android.hardware.audio.common@5.0::types
+c25ae57a9197fdf83aa6f7b31ab1ac4922dea4f19f92cdb1f9013ad49fa56594 android.hardware.audio.common@5.0::types
 f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
 fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
 e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
@@ -435,9 +436,9 @@
 443659bb9e27221e5da0d16c7a0ecb2dc3a9a03acc8a0b2196b47c50735e2d2e android.hardware.audio.effect@5.0::IVirtualizerEffect
 78fed26a781cdca1b3bcb37520bff705d7764ee81db9cfd37014953c7ad2596e android.hardware.audio.effect@5.0::IVisualizerEffect
 6385b6accab8a544e2ee54ba7bf5aa55dff6153bcedd80fdaae16fe9e0be7050 android.hardware.audio.effect@5.0::types
-baf5a0cbf357035394be02d87334890228338fae715f7ab06e2f0e7d05abe656 android.hardware.biometrics.face@1.0::IBiometricsFace
-6cbf288d6e6a9f6f0c09d1cde66318aa5b6a8c525778a61ccaedddb090f5e9cb android.hardware.biometrics.face@1.0::IBiometricsFaceClientCallback
-ef5d339413d0c94a5b58baafbe3e4bccfd9ed2e7328fbbb5c25471c79923ed2f android.hardware.biometrics.face@1.0::types
+e18ff318f3fc43db37f554696dc4e551abb9b119bde53950f73e28ce33a97a40 android.hardware.biometrics.face@1.0::IBiometricsFace
+b6e55d7795bbafd011fb95a3b6d3954bf66c349e14cf107f3b72032ce3ceb448 android.hardware.biometrics.face@1.0::IBiometricsFaceClientCallback
+95aa2f59e29e2f84d8e84320ace9b6682b426a16e897b4bd241375cbee0e07f3 android.hardware.biometrics.face@1.0::types
 ecedc58dbcdb13503c19c0ab160ac1dd0530bb1471164149282dd1463c684185 android.hardware.bluetooth.audio@2.0::IBluetoothAudioPort
 fb9c40e4deab40be5476477078fe3d8a4a4495fd9deef4321878d169d675c633 android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvider
 f7431f3e3e4e3387fc6f27a6cf423eddcd824a395dc4349d302c995ab44a9895 android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory
@@ -479,7 +480,7 @@
 01c6398c90fc6be0640810e2c5d8a4863b457280132bb3f97dd5682e19632b62 android.hardware.graphics.bufferqueue@2.0::types
 7a2d64095252f85781b2d521f4f11d04ce774544feececcec2088c568656e93c android.hardware.graphics.common@1.2::types
 3dff04a36b86660b5807414587e530bb0c294ed56fdff06f8915ba0a9b73f974 android.hardware.graphics.composer@2.3::IComposer
-daa44e83d7709bf1c9e0bd9a6b552feff496fd14574a9461ee93c21980fc5b15 android.hardware.graphics.composer@2.3::IComposerClient
+54bc1dc874f8bc0781767786075dafd33a0796c1eea7d2317231b8929280e946 android.hardware.graphics.composer@2.3::IComposerClient
 5c8bf8e1af9efe225a4661db8c08ff1b7e13fdc8ed49f35291bd0b6c9436b8f2 android.hardware.graphics.mapper@3.0::IMapper
 7183d9d9acfa41a61a64bdfed548e98299265a7bb1821a3ed204173b5c2cfd4a android.hardware.graphics.mapper@3.0::types
 c3f831a66d5815baf74f5b82fe79cf099542ddae4dfab3f388e1d41828e794fc android.hardware.health.storage@1.0::IGarbageCollectCallback
@@ -507,7 +508,7 @@
 92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
 83885d366f22ada42c00d8854f0b7e7ba4cf73ddf80bb0d8e168ce132cec57ea android.hardware.neuralnetworks@1.2::IPreparedModel
 e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
-896d1827541d620996720a79c6476edb902a58d515bf908f67a5bdef4d2c318c android.hardware.neuralnetworks@1.2::types
+114056b3b9303e0e858f28e718ba45722de5678d1d54eec0dcd10788604bf2bb android.hardware.neuralnetworks@1.2::types
 cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
 abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
 4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp
index 067b5e4..252ebb9 100644
--- a/drm/1.2/vts/functional/drm_hal_test.cpp
+++ b/drm/1.2/vts/functional/drm_hal_test.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "drm_hal_clearkey_test@1.2"
+#define LOG_TAG "drm_hal_test@1.2"
 
 #include <gtest/gtest.h>
 #include <hidl/HidlSupport.h>
@@ -41,8 +41,8 @@
 static const char* const kVideoMp4 = "video/mp4";
 static const char* const kBadMime = "video/unknown";
 static const char* const kDrmErrorTestKey = "drmErrorTest";
-static const char* const kDrmErrorGeneric = "";
-static const char* const kResourceContentionValue = "resourceContention";
+static const char* const kDrmErrorInvalidState = "invalidState";
+static const char* const kDrmErrorResourceContention = "resourceContention";
 static const SecurityLevel kSwSecureCrypto = SecurityLevel::SW_SECURE_CRYPTO;
 
 /**
@@ -180,19 +180,36 @@
 }
 
 /**
- * Test clearkey plugin offline key support
+ * Test drm plugin offline key support
  */
 TEST_P(DrmHalTest, OfflineLicenseTest) {
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
 
-    auto res = drmPlugin->getOfflineLicenseKeySetIds(checkKeySetIds<Status::OK, 1u>);
+    auto res = drmPlugin->getOfflineLicenseKeySetIds(
+            [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
+                bool found = false;
+                EXPECT_EQ(Status::OK, status);
+                for (KeySetId keySetId2: keySetIds) {
+                    if (keySetId == keySetId2) {
+                        found = true;
+                        break;
+                    }
+                }
+                EXPECT_TRUE(found) << "keySetId not found";
+            });
     EXPECT_OK(res);
 
     Status err = drmPlugin->removeOfflineLicense(keySetId);
     EXPECT_EQ(Status::OK, err);
 
-    res = drmPlugin->getOfflineLicenseKeySetIds(checkKeySetIds<Status::OK, 0u>);
+    res = drmPlugin->getOfflineLicenseKeySetIds(
+            [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
+                EXPECT_EQ(Status::OK, status);
+                for (KeySetId keySetId2: keySetIds) {
+                    EXPECT_NE(keySetId, keySetId2);
+                }
+            });
     EXPECT_OK(res);
 
     err = drmPlugin->removeOfflineLicense(keySetId);
@@ -202,7 +219,7 @@
 }
 
 /**
- * Test clearkey plugin offline key state
+ * Test drm plugin offline key state
  */
 TEST_P(DrmHalTest, OfflineLicenseStateTest) {
     auto sessionId = openSession();
@@ -380,7 +397,7 @@
  * Test resource contention during attempt to generate key request
  */
 TEST_P(DrmHalClearkeyTest, GetKeyRequestResourceContention) {
-    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kResourceContentionValue);
+    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorResourceContention);
     EXPECT_EQ(Status::OK, status);
     auto sessionId = openSession();
     hidl_vec<uint8_t> initData;
@@ -403,7 +420,7 @@
 TEST_P(DrmHalClearkeyTest, OfflineLicenseInvalidState) {
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
-    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorGeneric);
+    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorInvalidState);
     EXPECT_EQ(Status::OK, status);
 
     // everything should start failing
@@ -426,7 +443,7 @@
     auto res = drmPlugin->setListener(listener);
     EXPECT_OK(res);
 
-    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorGeneric);
+    Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorInvalidState);
     EXPECT_EQ(Status::OK, status);
 
     auto sessionId = openSession();
diff --git a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
index c59a16c..21cbc2e 100644
--- a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
+++ b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
@@ -546,7 +546,7 @@
      */
     disconnect(
             int32_t api,
-            DisconnectMode mode /* = DisconnectMode::API */
+            DisconnectMode mode
         ) generates (
             Status status
         );
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index 5fcc0e6..1eea306 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -61,6 +61,11 @@
          * PowerMode::DOZE_SUSPEND.
          */
         DOZE = 2,
+
+        /**
+         * Indicates that the display supports brightness operations.
+         */
+        BRIGHTNESS = 3,
     };
 
     /**
@@ -495,4 +500,38 @@
                        float maxLuminance,
                        float maxAverageLuminance,
                        float minLuminance);
+
+    /**
+     * Gets whether brightness operations are supported on a display.
+     *
+     * @param display
+     *      The display.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *      BAD_DISPLAY   when the display is invalid, or
+     *      BAD_PARAMETER when the output parameter is invalid.
+     * @return support
+     *      Whether brightness operations are supported on the display.
+     */
+    getDisplayBrightnessSupport(Display display) generates (Error error, bool support);
+
+    /**
+     * Sets the brightness of a display.
+     *
+     * Ideally, the brightness change should take effect in the next frame post (so that it can be
+     * aligned with color transforms).
+     *
+     * @param display
+     *      The display whose brightness is set.
+     * @param brightness
+     *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0 to
+     *      turn the backlight off.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY   when the display is invalid, or
+     *         UNSUPPORTED   when brightness operations are not supported, or
+     *         BAD_PARAMETER when the brightness is invalid, or
+     *         NO_RESOURCES  when the brightness cannot be applied.
+     */
+    setDisplayBrightness(Display display, float brightness) generates (Error error);
 };
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index a272e72..1b40795 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -172,7 +172,19 @@
         return Void();
     }
 
-   protected:
+    Return<void> getDisplayBrightnessSupport(
+            Display display, IComposerClient::getDisplayBrightnessSupport_cb hidl_cb) override {
+        bool support = false;
+        Error error = mHal->getDisplayBrightnessSupport(display, &support);
+        hidl_cb(error, support);
+        return Void();
+    }
+
+    Return<Error> setDisplayBrightness(Display display, float brightness) override {
+        return mHal->setDisplayBrightness(display, brightness);
+    }
+
+  protected:
     std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
         return std::make_unique<ComposerCommandEngine>(
             mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index a0812ad..186b004 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -119,6 +119,8 @@
     virtual Error setLayerPerFrameMetadataBlobs(
         Display display, Layer layer,
         std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) = 0;
+    virtual Error getDisplayBrightnessSupport(Display display, bool* outSupport) = 0;
+    virtual Error setDisplayBrightness(Display display, float brightness) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index 41e333a..070cf80 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -245,7 +245,29 @@
         return static_cast<Error>(err);
     }
 
-   protected:
+    Error getDisplayBrightnessSupport(Display display, bool* outSupport) {
+        if (!mDispatch.getDisplayBrightnessSupport) {
+            return Error::UNSUPPORTED;
+        }
+        bool support = false;
+        int32_t error = mDispatch.getDisplayBrightnessSupport(mDevice, display, &support);
+        *outSupport = support;
+        return static_cast<Error>(error);
+    }
+
+    Error setDisplayBrightness(Display display, float brightness) {
+        if (std::isnan(brightness) || brightness > 1.0f ||
+            (brightness < 0.0f && brightness != -1.0f)) {
+            return Error::BAD_PARAMETER;
+        }
+        if (!mDispatch.setDisplayBrightness) {
+            return Error::UNSUPPORTED;
+        }
+        int32_t error = mDispatch.setDisplayBrightness(mDevice, display, brightness);
+        return static_cast<Error>(error);
+    }
+
+  protected:
     bool initDispatch() override {
         if (!BaseType2_2::initDispatch()) {
             return false;
@@ -265,6 +287,10 @@
                                    &mDispatch.getDisplayCapabilities);
         this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
                                    &mDispatch.setLayerPerFrameMetadataBlobs);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_BRIGHTNESS_SUPPORT,
+                                   &mDispatch.getDisplayBrightnessSupport);
+        this->initOptionalDispatch(HWC2_FUNCTION_SET_DISPLAY_BRIGHTNESS,
+                                   &mDispatch.setDisplayBrightness);
         return true;
     }
 
@@ -277,6 +303,8 @@
         HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
         HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
         HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS setLayerPerFrameMetadataBlobs;
+        HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT getDisplayBrightnessSupport;
+        HWC2_PFN_SET_DISPLAY_BRIGHTNESS setDisplayBrightness;
     } mDispatch = {};
 
     using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index 0e541ed..4de85d6 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -186,6 +186,19 @@
     return capabilities;
 }
 
+bool ComposerClient::getDisplayBrightnessSupport(Display display) {
+    bool support = false;
+    mClient->getDisplayBrightnessSupport(display, [&](const auto& error, const auto& tmpSupport) {
+        ASSERT_EQ(Error::NONE, error) << "failed to get brightness support";
+        support = tmpSupport;
+    });
+    return support;
+}
+
+Error ComposerClient::setDisplayBrightness(Display display, float brightness) {
+    return mClient->setDisplayBrightness(display, brightness);
+}
+
 }  // namespace vts
 }  // namespace V2_3
 }  // namespace composer
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index ad4ef0b..a0e764d 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -52,7 +52,7 @@
 
     std::unique_ptr<ComposerClient> createClient();
 
-   protected:
+  protected:
     explicit Composer(const sp<IComposer>& composer);
 
    private:
@@ -99,7 +99,11 @@
 
     std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys_2_3(Display display);
 
-   private:
+    bool getDisplayBrightnessSupport(Display display);
+
+    Error setDisplayBrightness(Display display, float brightness);
+
+  private:
     const sp<IComposerClient> mClient;
 };
 
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index de74e28..b983e42 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -600,6 +600,36 @@
     }
 }
 
+/*
+ * Test that getDisplayBrightnessSupport works as expected.
+ */
+TEST_F(GraphicsComposerHidlTest, getDisplayBrightnessSupport) {
+    auto capabilities = mComposerClient->getDisplayCapabilities(mPrimaryDisplay);
+    bool brightnessSupport =
+            std::find(capabilities.begin(), capabilities.end(),
+                      IComposerClient::DisplayCapability::BRIGHTNESS) != capabilities.end();
+    EXPECT_EQ(mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay), brightnessSupport);
+}
+
+/*
+ * Test that if brightness operations are supported, setDisplayBrightness works as expected.
+ */
+TEST_F(GraphicsComposerHidlTest, setDisplayBrightness) {
+    if (!mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay)) {
+        EXPECT_EQ(mComposerClient->getRaw()->setDisplayBrightness(mPrimaryDisplay, 0.5f),
+                  Error::UNSUPPORTED);
+        GTEST_SUCCEED() << "Brightness operations are not supported";
+    }
+
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f), Error::NONE);
+
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f), Error::BAD_PARAMETER);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f), Error::BAD_PARAMETER);
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_3
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index 88a9e26..f299e36 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -387,17 +387,28 @@
                                   OMX_StateIdle);
     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
 
+    OMX_PARAM_PORTDEFINITIONTYPE portDefInput;
+    OMX_PARAM_PORTDEFINITIONTYPE portDefOutput;
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, kPortIndexInput, &portDefInput);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, kPortIndexOutput, &portDefOutput);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // Dont switch states until the ports are populated
-    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
-    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    if (portDefInput.nBufferCountActual || portDefOutput.nBufferCountActual) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    }
 
     // allocate buffers on input port
     ASSERT_NO_FATAL_FAILURE(allocatePortBuffers(
         omxNode, iBuffer, kPortIndexInput, pm[0], allocGrap));
 
     // Dont switch states until the ports are populated
-    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
-    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    if (portDefOutput.nBufferCountActual) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    }
 
     // allocate buffers on output port
     ASSERT_NO_FATAL_FAILURE(allocatePortBuffers(
@@ -430,9 +441,18 @@
                                   OMX_StateLoaded);
     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
 
+    OMX_PARAM_PORTDEFINITIONTYPE portDefInput;
+    OMX_PARAM_PORTDEFINITIONTYPE portDefOutput;
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, kPortIndexInput, &portDefInput);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, kPortIndexOutput, &portDefOutput);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // dont change state until all buffers are freed
-    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
-    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    if (portDefInput.nBufferCountActual || portDefOutput.nBufferCountActual) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    }
 
     for (size_t i = 0; i < iBuffer->size(); ++i) {
         status = omxNode->freeBuffer(kPortIndexInput, (*iBuffer)[i].id);
@@ -440,8 +460,10 @@
     }
 
     // dont change state until all buffers are freed
-    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
-    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    if (portDefOutput.nBufferCountActual) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    }
 
     for (size_t i = 0; i < oBuffer->size(); ++i) {
         status = omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
index 4ddc833..1c1d39b 100644
--- a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
+++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
@@ -115,6 +115,7 @@
         }
         if (compClass == unknown_class) disableTest = true;
         isSecure = false;
+        mTunnel = false;
         size_t suffixLen = strlen(".secure");
         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
             isSecure =
@@ -122,6 +123,18 @@
                             strlen(gEnv->getComponent().c_str()) - suffixLen,
                         ".secure");
         }
+        if (compClass == video_decoder) {
+            omxNode->configureVideoTunnelMode(
+                1, OMX_TRUE, 0,
+                [&](android::hardware::media::omx::V1_0::Status _s,
+                    const ::android::hardware::hidl_handle& sidebandHandle) {
+                    (void)sidebandHandle;
+                    if (_s == android::hardware::media::omx::V1_0::Status::OK)
+                        this->mTunnel = true;
+                });
+        }
+        // NOTES: secure components are not covered in these tests.
+        // we are disabling tests for them
         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
     }
 
@@ -149,6 +162,7 @@
     sp<CodecObserver> observer;
     sp<IOmxNode> omxNode;
     standardCompClass compClass;
+    bool mTunnel;
     bool isSecure;
     bool disableTest;
 
@@ -991,7 +1005,8 @@
     ASSERT_NO_FATAL_FAILURE(
         changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1],
                                 kPortIndexInput, kPortIndexOutput, portMode));
-    for (size_t i = portBase; i < portBase + 2; i++) {
+    int range = mTunnel ? 1 : 2;
+    for (size_t i = portBase; i < portBase + range; i++) {
         status =
             omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
@@ -1104,7 +1119,8 @@
             dispatchOutputBuffer(omxNode, &pBuffer[1], i, portMode[1]));
     }
 
-    for (size_t i = portBase; i < portBase + 2; i++) {
+    int range = mTunnel ? 1 : 2;
+    for (size_t i = portBase; i < portBase + range; i++) {
         status =
             omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index 1db9f75..df048c6 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -153,7 +153,17 @@
                         ".secure");
         }
         if (isSecure) disableTest = true;
+        omxNode->configureVideoTunnelMode(
+            1, OMX_TRUE, 0,
+            [&](android::hardware::media::omx::V1_0::Status _s,
+                const ::android::hardware::hidl_handle& sidebandHandle) {
+                (void)sidebandHandle;
+                if (_s == android::hardware::media::omx::V1_0::Status::OK)
+                    this->disableTest = true;
+            });
         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
+        // NOTES: secure and tunneled components are not covered in these tests.
+        // we are disabling tests for them
     }
 
     virtual void TearDown() override {
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 7eea7fc..f5cb0d7 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -77,6 +77,13 @@
                   "Number of types in MixedTyped changed, but copy_back function wasn't updated");
 }
 
+static bool isZeroSized(const MixedTyped& example, uint32_t index) {
+    for (auto i : example.operandDimensions.at(index)) {
+        if (i == 0) return true;
+    }
+    return false;
+}
+
 // Top level driver for models and examples generated by test_generator.py
 // Test driver for those generated from ml/nn/runtime/test/spec
 static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>& preparedModel,
@@ -178,17 +185,18 @@
         // Go through all outputs, initialize RequestArgument descriptors
         resize_accordingly(golden, test);
         bool sizeLargerThanOne = true;
-        for_all(golden, [&outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
+        for_all(golden, [&golden, &outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
                                 int index, auto, auto s) {
             if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
             if (index == 0) {
                 // On OutputType::INSUFFICIENT, set the output operand with index 0 with
                 // buffer size one byte less than needed.
                 if (outputType == OutputType::INSUFFICIENT) {
-                    if (s > 1)
+                    if (s > 1 && !isZeroSized(golden, index)) {
                         s -= 1;
-                    else
+                    } else {
                         sizeLargerThanOne = false;
+                    }
                 }
             }
             RequestArgument arg = {
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index c9de76b..99f873a 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -186,7 +186,8 @@
      *      must be >= 1.
      * * 2: A 2-D Tensor of {@link OperandType::TENSOR_INT32}, the paddings
      *      for each spatial dimension of the input tensor. All values must be
-     *      >= 0. The shape of the tensor must be {rank(input0), 2}.
+     *      >= 0. The shape of the tensor must be {M, 2}, where M is the number
+     *      of spatial dimensions.
      *      padding[i, 0] specifies the number of element to be padded in the
      *      front of dimension i.
      *      padding[i, 1] specifies the number of element to be padded after the
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index bb14dec..f2e02b8 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1979,7 +1979,8 @@
      *      must be >= 1.
      * * 2: A 2-D Tensor of {@link OperandType::TENSOR_INT32}, the paddings
      *      for each spatial dimension of the input tensor. All values must be
-     *      >= 0. The shape of the tensor must be {rank(input0), 2}.
+     *      >= 0. The shape of the tensor must be {M, 2}, where M is the number
+     *      of spatial dimensions.
      *      padding[i, 0] specifies the number of element to be padded in the
      *      front of dimension i.
      *      padding[i, 1] specifies the number of element to be padded after the
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
index da78f41..1d79ff6 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
@@ -26,6 +26,10 @@
     sap->connectReq(token, maxMsgSize);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(sapCb->sapResponseToken, token);
+
+    // Modem side need time for connect to finish. Adding a waiting time to prevent
+    // disconnect being requested right after connect request.
+    sleep(1);
 }
 
 /*
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index 727aac5..d4c0329 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -114,7 +114,7 @@
     std::unique_ptr<DIR, decltype(&closedir)> dir_dump(
         opendir(kTombstoneFolderPath), closedir);
     if (!dir_dump) {
-        LOG(ERROR) << "Failed to open directory: " << strerror(errno);
+        PLOG(ERROR) << "Failed to open directory";
         return false;
     }
     struct dirent* dp;
@@ -128,8 +128,7 @@
         struct stat cur_file_stat;
         std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
         if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
-            LOG(ERROR) << "Failed to get file stat for " << cur_file_path
-                       << ": " << strerror(errno);
+            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
             success = false;
             continue;
         }
@@ -144,7 +143,7 @@
         if (cur_file_count > kMaxRingBufferFileNum ||
             cur_file.first < delete_files_before) {
             if (unlink(cur_file.second.c_str()) != 0) {
-                LOG(ERROR) << "Error deleting file " << strerror(errno);
+                PLOG(ERROR) << "Error deleting file";
                 success = false;
             }
             cur_file_count--;
@@ -168,13 +167,11 @@
                 major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
                 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
     if (write(out_fd, read_buf.data(), llen) == -1) {
-        LOG(ERROR) << "Error writing cpio header to file " << file_name << " "
-                   << strerror(errno);
+        PLOG(ERROR) << "Error writing cpio header to file " << file_name;
         return false;
     }
     if (write(out_fd, file_name, file_name_len) == -1) {
-        LOG(ERROR) << "Error writing filename to file " << file_name << " "
-                   << strerror(errno);
+        PLOG(ERROR) << "Error writing filename to file " << file_name;
         return false;
     }
 
@@ -183,8 +180,7 @@
     if (llen != 0) {
         const uint32_t zero = 0;
         if (write(out_fd, &zero, 4 - llen) == -1) {
-            LOG(ERROR) << "Error padding 0s to file " << file_name << " "
-                       << strerror(errno);
+            PLOG(ERROR) << "Error padding 0s to file " << file_name;
             return false;
         }
     }
@@ -200,17 +196,17 @@
     while (llen > 0) {
         ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
         if (bytes_read == -1) {
-            LOG(ERROR) << "Error reading file " << strerror(errno);
+            PLOG(ERROR) << "Error reading file";
             return ++n_error;
         }
         llen -= bytes_read;
         if (write(out_fd, read_buf.data(), bytes_read) == -1) {
-            LOG(ERROR) << "Error writing data to file " << strerror(errno);
+            PLOG(ERROR) << "Error writing data to file";
             return ++n_error;
         }
         if (bytes_read == 0) {  // this should never happen, but just in case
                                 // to unstuck from while loop
-            LOG(ERROR) << "Unexpected read result for " << strerror(errno);
+            PLOG(ERROR) << "Unexpected read result";
             n_error++;
             break;
         }
@@ -219,7 +215,7 @@
     if (llen != 0) {
         const uint32_t zero = 0;
         if (write(out_fd, &zero, 4 - llen) == -1) {
-            LOG(ERROR) << "Error padding 0s to file " << strerror(errno);
+            PLOG(ERROR) << "Error padding 0s to file";
             return ++n_error;
         }
     }
@@ -234,7 +230,7 @@
               sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1,
                       0x0b, 0) +
                   4) == -1) {
-        LOG(ERROR) << "Error writing trailing bytes " << strerror(errno);
+        PLOG(ERROR) << "Error writing trailing bytes";
         return false;
     }
     return true;
@@ -249,7 +245,7 @@
     std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir),
                                                        closedir);
     if (!dir_dump) {
-        LOG(ERROR) << "Failed to open directory: " << strerror(errno);
+        PLOG(ERROR) << "Failed to open directory";
         return ++n_error;
     }
     while ((dp = readdir(dir_dump.get()))) {
@@ -263,15 +259,13 @@
         struct stat st;
         const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
         if (stat(cur_file_path.c_str(), &st) == -1) {
-            LOG(ERROR) << "Failed to get file stat for " << cur_file_path
-                       << ": " << strerror(errno);
+            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
             n_error++;
             continue;
         }
         const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
         if (fd_read == -1) {
-            LOG(ERROR) << "Failed to open file " << cur_file_path << " "
-                       << strerror(errno);
+            PLOG(ERROR) << "Failed to open file " << cur_file_path;
             n_error++;
             continue;
         }
@@ -1373,14 +1367,14 @@
             kTombstoneFolderPath + item.first + "XXXXXXXXXX";
         const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
         if (dump_fd == -1) {
-            LOG(ERROR) << "create file failed: " << strerror(errno);
+            PLOG(ERROR) << "create file failed";
             return false;
         }
         unique_fd file_auto_closer(dump_fd);
         for (const auto& cur_block : cur_buffer.getData()) {
             if (write(dump_fd, cur_block.data(),
                       sizeof(cur_block[0]) * cur_block.size()) == -1) {
-                LOG(ERROR) << "Error writing to file " << strerror(errno);
+                PLOG(ERROR) << "Error writing to file";
             }
         }
     }