Merge "Fix condition in mutateOperationOperandTypeSkip for conv ops."
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.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 c9bcf7b..62f04d0 100644
--- a/current.txt
+++ b/current.txt
@@ -390,7 +390,7 @@
 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
@@ -436,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
@@ -468,7 +468,7 @@
 d815623a6d1ba4abf21248b84eca70a2bfab03058a88b68a29c063ce8aee6b5c android.hardware.gnss@2.0::IGnssCallback
 ecc966c68bddbd95c8dae782b84204cf01c75734675e8769963f3b5106ec128b android.hardware.gnss@2.0::IGnssConfiguration
 c67759f5d6387d273b66729180d03690e827f0b6b8d4e13ce2ff42d31b224065 android.hardware.gnss@2.0::IGnssMeasurement
-089338944c45f66f25ba4ee958c161c42fefeb73ec60e4451f3535a1b3fd10c7 android.hardware.gnss@2.0::IGnssMeasurementCallback
+3dd30a3ca77ef5ab109a55ba603ff816ae5019436886093dccf8fd6a068f85f1 android.hardware.gnss@2.0::IGnssMeasurementCallback
 9e66234e65bcde75733d75d8b5d5cc094c2a5e14b074a25cd3f9ad141dc56f60 android.hardware.gnss@2.0::types
 50623a69a88b1c8a05738e4af7d5f78e905f415ccb0e84c99d0a71ea182e9393 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
 6ef12cd95df73f8f80c25eb035d98ca4594f9cee571fdabea838a0b6016dd908 android.hardware.gnss.measurement_corrections@1.0::types
diff --git a/gnss/2.0/IGnssMeasurementCallback.hal b/gnss/2.0/IGnssMeasurementCallback.hal
index d5dc038..d9751d3 100644
--- a/gnss/2.0/IGnssMeasurementCallback.hal
+++ b/gnss/2.0/IGnssMeasurementCallback.hal
@@ -22,77 +22,6 @@
 
 /** The callback interface to report measurements from the HAL. */
 interface IGnssMeasurementCallback extends @1.1::IGnssMeasurementCallback {
-    /**
-     * Enumeration of available values for the GNSS Measurement's code type. Similar to the
-     * Attribute field described in RINEX 3.03, e.g., in Tables 4-10, and Table A2 at the RINEX 3.03
-     * Update 1 Document.
-     */
-    enum GnssMeasurementCodeType : uint8_t {
-        /** GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA. */
-        A = 0,
-
-        /** GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB. */
-        B = 1,
-
-        /**
-         *  GPS L1 C/A,  GPS L2 C/A, GLONASS G1 C/A, GLONASS G2 C/A, GALILEO E1C, GALILEO E6C, SBAS
-         *  L1 C/A, QZSS L1 C/A, IRNSS L5C.
-         */
-        C = 2,
-
-        /**
-         * GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, GALILEO E5a+b I, SBAS L5 I, QZSS L5
-         * I, BDS B1 I, BDS B2 I, BDS B3 I.
-         */
-        I = 3,
-
-        /** GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), LEX(6) L. */
-        L = 4,
-
-        /** GPS L1M, GPS L2M. */
-        M = 5,
-
-        /** GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P. */
-        P = 6,
-
-        /**
-         * GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, GALILEO E5a+b Q, SBAS L5 Q, QZSS L5
-         * Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
-         */
-        Q = 7,
-
-        /** GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), LEX(6) S. */
-        S = 8,
-
-        /** GPS L1 Z-tracking, GPS L2 Z-tracking. */
-        W = 9,
-
-        /**
-         * GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q), GALILEO E1 (B+C), GALILEO
-         * E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q), GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS
-         * L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), LEX(6) (S+L), BDS B1 (I+Q), BDS B2 (I+Q), BDS
-         * B3 (I+Q), IRNSS L5 (B+C).
-         */
-        X = 10,
-
-        /** GPS L1Y, GPS L2Y. */
-        Y = 11,
-
-        /** GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF. */
-        Z = 12,
-
-        /** GPS L1 codeless, GPS L2 codeless. */
-        N = 13,
-
-        /**
-         * Other code type that does not belong to any of the above code types.
-         *
-         * This code type is used in the case that the above code types do not cover all the code
-         * types introduced in a new version of RINEX standard. When this code type is set, the
-         * field GnssMeasurement.otherCodeTypeName must specify the new code type.
-         */
-        OTHER = 255
-    };
 
     /**
      * Flags indicating the GNSS measurement state.
@@ -458,12 +387,43 @@
          * The type of code that is currently being tracked in the GNSS measurement.
          *
          * For high precision applications the type of code being tracked needs to be considered
-         * in-order to properly apply code specific corrections to the psuedorange measurements.
-         */
-        GnssMeasurementCodeType codeType;
-
-        /**
-         * The name of the code type when codeType is OTHER.
+         * in-order to properly apply code specific corrections to the pseudorange measurements.
+         *
+         * Value "A" represents GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA.
+         *
+         * Value "B" represents GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB.
+         *
+         * Value "C" represents GPS L1 C/A,  GPS L2 C/A, GLONASS G1 C/A, GLONASS G2 C/A, GALILEO E1C,
+         * GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C.
+         *
+         * Value "I" represents GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, GALILEO E5a+b I,
+         * SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I.
+         *
+         * Value "L" represents GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), LEX(6) L.
+         *
+         * Value "M" represents GPS L1M, GPS L2M.
+         *
+         * Value "N" represents GPS L1 codeless, GPS L2 codeless.
+         *
+         * Value "P" represents GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P.
+         *
+         * Value "Q" represents GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, GALILEO E5a+b Q,
+         * SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
+         *
+         * Value "S" represents GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), LEX(6) S.
+         *
+         * Value "W" represents GPS L1 Z-tracking, GPS L2 Z-tracking.
+         *
+         * Value "X" represents GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q),
+         * GALILEO E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q),
+         * GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q),
+         * LEX(6) (S+L), BDS B1 (I+Q), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
+         *
+         * Value "Y" represents GPS L1Y, GPS L2Y.
+         *
+         * Value "Z" represents GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF.
+         *
+         * Value "UNKNOWN" represents the GNSS Measurement's code type is unknown.
          *
          * This is used to specify the observation descriptor defined in GNSS Observation Data File
          * Header Section Description in the RINEX standard (Version 3.XX). In RINEX Version 3.03,
@@ -471,7 +431,7 @@
          * "A channel"). In the future, if for instance a code "G" was added in the official RINEX
          * standard, "G" could be specified here.
          */
-        string otherCodeTypeName;
+        string codeType;
 
         /**
          * Per satellite sync state. It represents the current sync state for the associated
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 702c9e2..a62c2dd 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -114,8 +114,7 @@
     V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
     V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
             .v1_1 = measurement_1_1,
-            .codeType = IGnssMeasurementCallback::GnssMeasurementCodeType::C,
-            .otherCodeTypeName = "",
+            .codeType = "C",
             .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
                      GnssMeasurementState::STATE_SUBFRAME_SYNC |
                      GnssMeasurementState::STATE_TOW_DECODED |
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index 3703eba..67fda89 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -190,17 +190,7 @@
     EXPECT_EQ(measurement_called_count_, 1);
     ASSERT_TRUE(last_measurement_.measurements.size() > 0);
     for (auto measurement : last_measurement_.measurements) {
-        ASSERT_TRUE(
-                ((int)measurement.codeType >=
-                                (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::A &&
-                        (int)measurement.codeType <=
-                                (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::N) ||
-                (int)measurement.codeType ==
-                        (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::OTHER);
-        if ((int)measurement.codeType ==
-                (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::OTHER) {
-            ASSERT_NE(measurement.otherCodeTypeName, "");
-        }
+        ASSERT_NE(measurement.codeType, "");
     }
 
     iGnssMeasurement->close();
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index d4c0329..3697d50 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -1152,6 +1152,16 @@
         // This probably is not a critical failure?
         LOG(ERROR) << "Failed to register radio mode change callback";
     }
+    // Extract and save the version information into property.
+    std::pair<WifiStatus, IWifiChip::ChipDebugInfo> version_info;
+    version_info = WifiChip::requestChipDebugInfoInternal();
+    if (WifiStatusCode::SUCCESS == version_info.first.code) {
+        property_set("vendor.wlan.firmware.version",
+                     version_info.second.firmwareDescription.c_str());
+        property_set("vendor.wlan.driver.version",
+                     version_info.second.driverDescription.c_str());
+    }
+
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }