Merge "audio: Add APTX_TWSP audio format"
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..dc5579a 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -853,7 +853,7 @@
         result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
         if (req->buffers[i].fenceTimeout) {
             result.outputBuffers[i].status = BufferStatus::ERROR;
-            if (req->buffers[i].acquireFence > 0) {
+            if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
                 handle->data[0] = req->buffers[i].acquireFence;
                 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
@@ -862,7 +862,7 @@
         } else {
             result.outputBuffers[i].status = BufferStatus::OK;
             // TODO: refactor
-            if (req->buffers[i].acquireFence > 0) {
+            if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
                 handle->data[0] = req->buffers[i].acquireFence;
                 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
@@ -1778,7 +1778,7 @@
 
     /* Unlock the HAL jpeg code buffer */
     int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
-    if (relFence > 0) {
+    if (relFence >= 0) {
         halBuf.acquireFence = relFence;
     }
 
@@ -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");
@@ -1885,7 +1882,7 @@
         if (*(halBuf.bufPtr) == nullptr) {
             ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
             halBuf.fenceTimeout = true;
-        } else if (halBuf.acquireFence != -1) {
+        } else if (halBuf.acquireFence >= 0) {
             int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
             if (ret) {
                 halBuf.fenceTimeout = true;
@@ -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,
@@ -1950,7 +1957,7 @@
                     return onDeviceError("%s: format coversion failed!", __FUNCTION__);
                 }
                 int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
-                if (relFence > 0) {
+                if (relFence >= 0) {
                     halBuf.acquireFence = relFence;
                 }
             } break;
@@ -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/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/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.4/types.hal b/camera/metadata/3.4/types.hal
index bb630f1..30c3217 100644
--- a/camera/metadata/3.4/types.hal
+++ b/camera/metadata/3.4/types.hal
@@ -22,7 +22,6 @@
 
 package android.hardware.camera.metadata@3.4;
 
-/* Include definitions from all prior minor HAL metadata revisions */
 import android.hardware.camera.metadata@3.2;
 import android.hardware.camera.metadata@3.3;
 
@@ -213,8 +212,10 @@
                                                                  = 0x4,
     ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW
                                                                  = 0x5,
-    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT
                                                                  = 0x6,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END
+                                                                 = 0x7,
     ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START
                                                                  = 0x18,
 };
diff --git a/current.txt b/current.txt
index d552ae0..543c46d 100644
--- a/current.txt
+++ b/current.txt
@@ -447,7 +447,7 @@
 06237de53c42890029e3f8fe7d1480d078469c0d07608e51c37b4d485d342992 android.hardware.camera.device@3.5::ICameraDeviceCallback
 08c68b196e2fc4e5ba67ba0d0917bde828a87cbe2cffec19d04733972da9eb49 android.hardware.camera.device@3.5::ICameraDeviceSession
 a848f7cb3cb3d080cf175bf08412322bfddb535168253796cdf777afdbf05b38 android.hardware.camera.device@3.5::types
-74ec7732fdacb22292c907b49f8f933510851ea1b3ed195c4dcdff35a20387f5 android.hardware.camera.metadata@3.4::types
+f727d5f350f55a6d3354aad2feb64e43200de77c10d9d642465566bc260bb8ec android.hardware.camera.metadata@3.4::types
 0fb39a7809ad1c52b3efbbed5ef4749b06c2a4f1f19cdc3efa2e3d9b28f1205c android.hardware.camera.provider@2.5::ICameraProvider
 f5777403d65135a5407723671bc7a864cdca83aea13ee3ce2894b95e6588ca3a android.hardware.camera.provider@2.5::types
 44c88954b3c201b26f64fcdb6f278024ab3aae864a9e1ec70e8a74274ae9d6aa android.hardware.cas@1.1::ICas
@@ -465,17 +465,18 @@
 2e5ad983734069e84a760004b32da0d09e4170c05380abe27e6eb80e4aa70d5a android.hardware.gnss@2.0::IAGnssCallback
 1f4ac068a88a72360280d94a7f6fd7c63813c1eea4891a0eb01394d3e7e775f2 android.hardware.gnss@2.0::IAGnssRil
 6e2f9a44375a0ae0b49ca7d711cb88945189d398535078408269e1e85889061d android.hardware.gnss@2.0::IGnss
-d815623a6d1ba4abf21248b84eca70a2bfab03058a88b68a29c063ce8aee6b5c android.hardware.gnss@2.0::IGnssCallback
+782dfc724272f279985de348c824197357941382f73c0083f0344d8ec594d2a8 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
-9e66234e65bcde75733d75d8b5d5cc094c2a5e14b074a25cd3f9ad141dc56f60 android.hardware.gnss@2.0::types
-50623a69a88b1c8a05738e4af7d5f78e905f415ccb0e84c99d0a71ea182e9393 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
+3dd30a3ca77ef5ab109a55ba603ff816ae5019436886093dccf8fd6a068f85f1 android.hardware.gnss@2.0::IGnssMeasurementCallback
+4bcd767dd05304b4722c6521c7ed8d4a05faf6022f228f2c088379c647871f7c android.hardware.gnss@2.0::types
+d4cc8d91930d5a1a62deb0d97d398510a115ce3ede2d2978738651b9d01b11c3 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
+3eec9763db9b101644f14175b77c9954047445a468e9c743fd402d472d4aa97e android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrectionsCallback
 6ef12cd95df73f8f80c25eb035d98ca4594f9cee571fdabea838a0b6016dd908 android.hardware.gnss.measurement_corrections@1.0::types
 0d278956d7fc6fdf9ca9c42962ff2d73967bbb1c9f0b3e0b58d71b7095c286bc android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl
 0d99e34500cfc2d40b684cb4dea7ebd89d4aff9f5315ed36b33442a7a88c138c android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControlCallback
 6b2d8dfa3db505c34a3a19082d8737c86bd859ec00f0e6c5fd19cce3c1ef95d1 android.hardware.graphics.allocator@3.0::IAllocator
-2a81d3132df91614a30ca45dfe088d67ddbb30240ab8c25feb6b8110d7ec3800 android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer
+eb3bcf4e8afacc72fd09821920f277fbbe8b9837513c1f5549fb42588580cbe4 android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer
 b826892686850a9cf2b60ca5845db7185c2196ea4dd765cd80cd163169678a78 android.hardware.graphics.bufferqueue@2.0::IProducerListener
 01c6398c90fc6be0640810e2c5d8a4863b457280132bb3f97dd5682e19632b62 android.hardware.graphics.bufferqueue@2.0::types
 7a2d64095252f85781b2d521f4f11d04ce774544feececcec2088c568656e93c android.hardware.graphics.common@1.2::types
diff --git a/gnss/2.0/IGnssCallback.hal b/gnss/2.0/IGnssCallback.hal
index 7924b64..4c31cf5 100644
--- a/gnss/2.0/IGnssCallback.hal
+++ b/gnss/2.0/IGnssCallback.hal
@@ -21,7 +21,7 @@
 import GnssLocation;
 
 /**
- * The interface is required for the HAL to communicate certain information
+ * This interface is required for the HAL to communicate certain information
  * like status and location info back to the platform, the platform implements
  * the interfaces and passes a handle to the HAL.
  */
@@ -29,17 +29,36 @@
 
     /** Flags for the gnssSetCapabilities callback. */
     @export(name="", value_prefix="GPS_CAPABILITY_")
-    enum Capabilities : @1.0::IGnssCallback.Capabilities {
-        /** GNSS supports line-of-sight satellite identification measurement Corrections */
-        MEASUREMENT_CORRECTIONS_LOS_SATS                        = 1 << 8,
-        /** GNSS supports per satellite excess-path-length measurement Corrections */
-        MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH              = 1 << 9,
-        /** GNSS supports reflecting planes measurement Corrections */
-        MEASUREMENT_CORRECTIONS_REFLECTING_PLANE                = 1 << 10
+    enum Capabilities : uint32_t {
+        /**
+         * GNSS HAL schedules fixes for RECURRENCE_PERIODIC mode.
+         * If this is not set, then the framework will use 1000ms for
+         * minInterval and must call start() and stop() to schedule the GNSS.
+         */
+        SCHEDULING                      = 1 << 0,
+        /** GNSS supports MS-Based AGNSS mode */
+        MSB                             = 1 << 1,
+        /** GNSS supports MS-Assisted AGNSS mode */
+        MSA                             = 1 << 2,
+        /** GNSS supports single-shot fixes */
+        SINGLE_SHOT                     = 1 << 3,
+        /** GNSS supports on demand time injection */
+        ON_DEMAND_TIME                  = 1 << 4,
+        /**
+         * Values for the flags removed from IGnssCallback.hal@1.0 Capabilities
+         * enum are marked as reserved and not reused here to avoid confusion.
+         */
+        RESERVED_1                      = 1 << 5,
+        RESERVED_2                      = 1 << 6,
+        RESERVED_3                      = 1 << 7,
+        /** GNSS supports low power mode */
+        LOW_POWER_MODE                  = 1 << 8,
+        /** GNSS supports blacklisting satellites */
+        SATELLITE_BLACKLIST             = 1 << 9
     };
 
     /**
-     * Callback to inform framework of the GNSS engine's capabilities.
+     * Callback to inform framework of the GNSS HAL implementation's capabilities.
      *
      * @param capabilities Capability parameter is a bit field of the Capabilities enum.
      */
@@ -75,4 +94,4 @@
      *        during-call to E911, or up to 5 minutes after end-of-call or text to E911).
      */
     gnssRequestLocationCb_2_0(bool independentFromGnss, bool isUserEmergency);
-};
\ No newline at end of file
+};
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/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index ee6da53..1dfdadb 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -269,8 +269,9 @@
 
     sGnssCallback_2_0 = callback;
 
-    uint32_t capabilities = static_cast<uint32_t>(V1_0::IGnssCallback::Capabilities::MEASUREMENTS);
-    auto ret = sGnssCallback_2_0->gnssSetCapabilitesCb(capabilities);
+    using Capabilities = V2_0::IGnssCallback::Capabilities;
+    const auto capabilities = Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
+    auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
     if (!ret.isOk()) {
         ALOGE("%s: Unable to invoke callback", __func__);
     }
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/default/GnssMeasurementCorrections.cpp b/gnss/2.0/default/GnssMeasurementCorrections.cpp
index cbf34ba..2bf5601 100644
--- a/gnss/2.0/default/GnssMeasurementCorrections.cpp
+++ b/gnss/2.0/default/GnssMeasurementCorrections.cpp
@@ -54,6 +54,19 @@
     return true;
 }
 
+Return<bool> GnssMeasurementCorrections::setCallback(
+        const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
+    using Capabilities = V1_0::IMeasurementCorrectionsCallback::Capabilities;
+    auto ret =
+            callback->setCapabilitiesCb(Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH |
+                                        Capabilities::REFLECTING_PLANE);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+        return false;
+    }
+    return true;
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace measurement_corrections
diff --git a/gnss/2.0/default/GnssMeasurementCorrections.h b/gnss/2.0/default/GnssMeasurementCorrections.h
index f758bc8..4339bed 100644
--- a/gnss/2.0/default/GnssMeasurementCorrections.h
+++ b/gnss/2.0/default/GnssMeasurementCorrections.h
@@ -38,6 +38,7 @@
 struct GnssMeasurementCorrections : public IMeasurementCorrections {
     // Methods from V1_0::IMeasurementCorrections follow.
     Return<bool> setCorrections(const MeasurementCorrections& corrections) override;
+    Return<bool> setCallback(const sp<V1_0::IMeasurementCorrectionsCallback>& callback) override;
 };
 
 }  // namespace implementation
diff --git a/gnss/2.0/types.hal b/gnss/2.0/types.hal
index 4abb604..21b64f9 100644
--- a/gnss/2.0/types.hal
+++ b/gnss/2.0/types.hal
@@ -69,7 +69,7 @@
      *
      * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
      * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
-     * needs to be estimatedd by syncing the notion of time via PTP or some other mechanism. 
+     * needs to be estimated by syncing the notion of time via PTP or some other mechanism.
      */
     ElapsedRealtime elapsedRealtime;
 };
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index c564f41..b2b62fc 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -77,6 +77,16 @@
     EXPECT_EQ(capabilities_called_count_, 1);
     EXPECT_EQ(info_called_count_, 1);
     EXPECT_EQ(name_called_count_, 1);
+
+    // Setup measurement corrections callback.
+    auto measurementCorrections = gnss_hal_->getExtensionMeasurementCorrections();
+    ASSERT_TRUE(measurementCorrections.isOk());
+    sp<IMeasurementCorrections> iMeasurementCorrections = measurementCorrections;
+    if (iMeasurementCorrections != nullptr) {
+        sp<IMeasurementCorrectionsCallback> iMeasurementCorrectionsCallback =
+                new GnssMeasurementCorrectionsCallback(*this);
+        iMeasurementCorrections->setCallback(iMeasurementCorrectionsCallback);
+    }
 }
 
 void GnssHalTest::StopAndClearLocations() {
@@ -176,6 +186,16 @@
     return status;
 }
 
+std::cv_status GnssHalTest::waitForMeasurementCorrectionsCapabilities(int timeout_seconds) {
+    std::unique_lock<std::mutex> lock(mtx_);
+    auto status = std::cv_status::no_timeout;
+    while (measurement_corrections_capabilities_called_count_ == 0) {
+        status = cv_.wait_for(lock, std::chrono::seconds(timeout_seconds));
+        if (status == std::cv_status::timeout) return status;
+    }
+    return status;
+}
+
 Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
     const IGnssCallback::GnssSystemInfo& info) {
     ALOGI("Info received, year %d", info.yearOfHw);
@@ -243,3 +263,12 @@
     parent_.notify();
     return Void();
 }
+
+Return<void> GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb(
+        uint32_t capabilities) {
+    ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities);
+    parent_.measurement_corrections_capabilities_called_count_++;
+    parent_.last_measurement_corrections_capabilities_ = capabilities;
+    parent_.notify();
+    return Void();
+}
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 31750a6..7354aea 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -28,6 +28,7 @@
 using android::hardware::Return;
 using android::hardware::Void;
 
+using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
 using android::hardware::gnss::V1_0::GnssLocationFlags;
 using android::hardware::gnss::V2_0::IGnss;
 using android::hardware::gnss::V2_0::IGnssCallback;
@@ -73,6 +74,8 @@
     /* Test code calls this function to wait for a callback */
     std::cv_status wait(int timeout_seconds);
 
+    std::cv_status waitForMeasurementCorrectionsCapabilities(int timeout_seconds);
+
     /* Callback class for data & Event. */
     class GnssCallback : public IGnssCallback {
        public:
@@ -136,6 +139,17 @@
         Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override;
     };
 
+    /* Callback class for GnssMeasurementCorrections. */
+    class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
+      public:
+        GnssHalTest& parent_;
+        GnssMeasurementCorrectionsCallback(GnssHalTest& parent) : parent_(parent){};
+        virtual ~GnssMeasurementCorrectionsCallback() = default;
+
+        // Methods from V1_0::IMeasurementCorrectionsCallback follow.
+        Return<void> setCapabilitiesCb(uint32_t capabilities) override;
+    };
+
     /*
      * SetUpGnssCallback:
      *   Set GnssCallback and verify the result.
@@ -192,12 +206,14 @@
      */
     int info_called_count_;
     int capabilities_called_count_;
+    int measurement_corrections_capabilities_called_count_;
     int location_called_count_;
     int measurement_called_count_;
     int name_called_count_;
 
     IGnssCallback::GnssSystemInfo last_info_;
     uint32_t last_capabilities_;
+    uint32_t last_measurement_corrections_capabilities_;
     GnssLocation_2_0 last_location_;
     IGnssMeasurementCallback_2_0::GnssData last_measurement_;
     android::hardware::hidl_string last_name_;
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..f3559c5 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -38,6 +38,7 @@
 using android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
 using android::hardware::gnss::V1_0::IGnssNi;
 using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
+using android::hardware::gnss::V2_0::IGnssCallback;
 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
 
 /*
@@ -50,23 +51,21 @@
 
 /*
  * TestGnssMeasurementCallback:
- * Gets the GnssMeasurementExtension and verify that it returns an actual extension.
+ * Gets the GnssMeasurementExtension and verifies that it returns an actual extension.
  */
 TEST_F(GnssHalTest, TestGnssMeasurementCallback) {
     auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0();
     auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
     auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
-    ASSERT_TRUE(gnssMeasurement_2_0.isOk() || gnssMeasurement_1_1.isOk() ||
+    ASSERT_TRUE(gnssMeasurement_2_0.isOk() && gnssMeasurement_1_1.isOk() &&
                 gnssMeasurement_1_0.isOk());
-    if (last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENTS) {
-        sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
-        sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
-        sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
-        // At least one interface is non-null.
-        int numNonNull = (int)(iGnssMeas_2_0 != nullptr) + (int)(iGnssMeas_1_1 != nullptr) +
-                         (int)(iGnssMeas_1_0 != nullptr);
-        ASSERT_TRUE(numNonNull >= 1);
-    }
+    sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
+    sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
+    sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
+    // At least one interface is non-null.
+    int numNonNull = (int)(iGnssMeas_2_0 != nullptr) + (int)(iGnssMeas_1_1 != nullptr) +
+                     (int)(iGnssMeas_1_0 != nullptr);
+    ASSERT_TRUE(numNonNull >= 1);
 }
 
 /*
@@ -190,17 +189,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();
@@ -277,8 +266,30 @@
 }
 
 /*
+ * TestGnssMeasurementCorrectionsCapabilities:
+ * If the GnssMeasurementCorrectionsExtension is not null, verifies that the measurement corrections
+ * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH
+ * capability flag is set.
+ */
+TEST_F(GnssHalTest, TestGnssMeasurementCorrectionsCapabilities) {
+    auto measurementCorrections = gnss_hal_->getExtensionMeasurementCorrections();
+    ASSERT_TRUE(measurementCorrections.isOk());
+    sp<IMeasurementCorrections> iMeasurementCorrections = measurementCorrections;
+    if (iMeasurementCorrections == nullptr) {
+        return;
+    }
+
+    const int kMeasurementCorrectionsCapabilitiesTimeoutSeconds = 5;
+    waitForMeasurementCorrectionsCapabilities(kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
+    ASSERT_TRUE(measurement_corrections_capabilities_called_count_ > 0);
+    using Capabilities = IMeasurementCorrectionsCallback::Capabilities;
+    ASSERT_TRUE((last_measurement_corrections_capabilities_ &
+                 (Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH)) != 0);
+}
+
+/*
  * TestGnssMeasurementCorrections:
- * Gets the GnssMeasurementCorrectionsExtension and verifies that it supports the
+ * If the GnssMeasurementCorrectionsExtension is not null, verifies that it supports the
  * gnss.measurement_corrections@1.0::IMeasurementCorrections interface by invoking a method.
  */
 TEST_F(GnssHalTest, TestGnssMeasurementCorrections) {
@@ -286,8 +297,13 @@
     auto measurementCorrections = gnss_hal_->getExtensionMeasurementCorrections();
     ASSERT_TRUE(measurementCorrections.isOk());
     sp<IMeasurementCorrections> iMeasurementCorrections = measurementCorrections;
-    ASSERT_NE(iMeasurementCorrections, nullptr);
+    if (iMeasurementCorrections == nullptr) {
+        return;
+    }
 
+    const int kMeasurementCorrectionsCapabilitiesTimeoutSeconds = 5;
+    waitForMeasurementCorrectionsCapabilities(kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
+    ASSERT_TRUE(measurement_corrections_capabilities_called_count_ > 0);
     // Set a mock MeasurementCorrections.
     auto result = iMeasurementCorrections->setCorrections(Utils::getMockMeasurementCorrections());
     ASSERT_TRUE(result.isOk());
diff --git a/gnss/measurement_corrections/1.0/Android.bp b/gnss/measurement_corrections/1.0/Android.bp
index 4aac7e0..456b55c 100644
--- a/gnss/measurement_corrections/1.0/Android.bp
+++ b/gnss/measurement_corrections/1.0/Android.bp
@@ -9,6 +9,7 @@
     srcs: [
         "types.hal",
         "IMeasurementCorrections.hal",
+        "IMeasurementCorrectionsCallback.hal",
     ],
     interfaces: [
         "android.hardware.gnss@1.0",
diff --git a/gnss/measurement_corrections/1.0/IMeasurementCorrections.hal b/gnss/measurement_corrections/1.0/IMeasurementCorrections.hal
index 934d10f..1fa32f4 100644
--- a/gnss/measurement_corrections/1.0/IMeasurementCorrections.hal
+++ b/gnss/measurement_corrections/1.0/IMeasurementCorrections.hal
@@ -16,11 +16,12 @@
 
 package android.hardware.gnss.measurement_corrections@1.0;
 
+import IMeasurementCorrectionsCallback;
+
 /**
  * Interface for measurement corrections support.
  */
 interface IMeasurementCorrections {
-
     /**
      * Injects measurement corrections to be used by the HAL to improve the GNSS location output.
      *
@@ -35,5 +36,15 @@
      *
      * @return success Whether the HAL can accept & use these corrections.
      */
-     setCorrections(MeasurementCorrections corrections) generates (bool success);
-};
+    setCorrections(MeasurementCorrections corrections) generates (bool success);
+
+    /**
+     * Opens the interface and provides the callback routines to the implementation of this
+     * interface.
+     *
+     * @param callback Callback interface for IMeasurementCorrections.
+     *
+     * @return success Returns true on success.
+     */
+    setCallback(IMeasurementCorrectionsCallback callback) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.hal b/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.hal
new file mode 100644
index 0000000..91d1311
--- /dev/null
+++ b/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.hal
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.measurement_corrections@1.0;
+
+/**
+ * GNSS measurement corrections callback interface.
+ */
+interface IMeasurementCorrectionsCallback {
+
+    /**
+     * Flags to indicate supported measurement corrections capabilities
+     *
+     * Either the LOS_SATS or the EXCESS_PATH_LENGTH capability must be supported.
+     */
+    enum Capabilities : uint32_t {
+        /** GNSS supports line-of-sight satellite identification measurement corrections */
+        LOS_SATS                        = 1 << 0,
+        /** GNSS supports per satellite excess-path-length measurement corrections */
+        EXCESS_PATH_LENGTH              = 1 << 1,
+        /** GNSS supports reflecting planes measurement corrections */
+        REFLECTING_PLANE                = 1 << 2
+    };
+
+    /**
+     * Callback to inform framework the measurement correction specific capabilities of the GNSS
+     * HAL implementation.
+     *
+     * The GNSS HAL must call this method immediately after the framework opens the measurement
+     * corrections interface.
+     *
+     * @param capabilities Supported measurement corrections capabilities. It is mandatory to
+     *        support either LOS_STATS or EXCESS_PATH_LENGTH capability.
+     *
+     */
+    setCapabilitiesCb(bitfield<Capabilities> capabilities);
+};
\ No newline at end of file
diff --git a/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal b/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal
index 734c0b4..23b360a 100644
--- a/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal
+++ b/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal
@@ -75,12 +75,19 @@
      * @param slot Slot index.
      * @return status Status of the call.
      * @return buffer New buffer associated to the given slot index.
+     * @return generationNumber Generation number of the buffer. If
+     *     requestBuffer() is called immediately after dequeueBuffer() returns
+     *     with `bufferNeedsReallocation` set to `true`, @p generationNumber must
+     *     match the current generation number of the buffer queue previously
+     *     set by setGenerationNumber(). Otherwise, @p generationNumber may not
+     *     match the current generation number of the buffer queue.
      */
     requestBuffer(
             int32_t slot
         ) generates (
             Status status,
-            HardwareBuffer buffer
+            HardwareBuffer buffer,
+            uint32_t generationNumber
         );
 
     /**
@@ -212,9 +219,9 @@
      * parameter.
      *
      * @param input See #DequeueBufferInput for more information.
-     * @param status Status of the call.
-     * @param slot Slot index.
-     * @param output See #DequeueBufferOutput for more information.
+     * @return status Status of the call.
+     * @return slot Slot index.
+     * @return output See #DequeueBufferOutput for more information.
      *
      * @sa queueBuffer(), requestBuffer().
      */
@@ -286,6 +293,9 @@
      * See dequeueBuffer() for conditions that may cause the call to fail.
      *
      * @param buffer Buffer to attach to the buffer queue.
+     * @param generationNumber Generation number of the buffer. If this does not
+     *     match the current generation number of the buffer queue, the call
+     *     must fail with @p status set to `BAD_VALUE`.
      * @return status Status of the call.
      * @return slot Slot index assigned to @p buffer.
      * @return releaseAllBuffers Whether the caller is expected to release all
@@ -294,7 +304,8 @@
      * @sa dequeueBuffer().
      */
     attachBuffer(
-            HardwareBuffer buffer
+            HardwareBuffer buffer,
+            uint32_t generationNumber
         ) generates (
             Status status,
             int32_t slot,
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index 3b8e3dd..c2330b5 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -388,8 +388,9 @@
             case OperationType::GROUPED_CONV_2D:
             case OperationType::DEPTHWISE_CONV_2D:
             case OperationType::CONV_2D: {
-                if (operand == 1 && (type == OperandType::TENSOR_QUANT8_ASYMM ||
-                                     type == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL)) {
+                if (operand == operation.inputs[1] &&
+                    (type == OperandType::TENSOR_QUANT8_ASYMM ||
+                     type == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL)) {
                     return true;
                 }
             } break;
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);
 }