Merge "Camera: Centralize OWNERS"
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 3949346..d77bb0e 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -782,6 +782,8 @@
     void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
             camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
 
+    bool isDepthOnly(camera_metadata_t* staticMeta);
+
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
@@ -793,6 +795,10 @@
             std::unordered_set<std::string> *physicalIds/*out*/);
     static Status getSupportedKeys(camera_metadata_t *staticMeta,
             uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
+    static void fillOutputStreams(camera_metadata_ro_entry_t* entry,
+            std::vector<AvailableStream>& outputStreams,
+            const AvailableStream *threshold = nullptr,
+            const int32_t availableConfigOutputTag = 0u);
     static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
             const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
             android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
@@ -2845,14 +2851,24 @@
         uint32_t streamConfigCounter = 0;
         for (auto& it : outputStreams) {
             V3_2::Stream stream3_2;
-            bool isJpeg = static_cast<PixelFormat>(it.format) == PixelFormat::BLOB;
+            V3_2::DataspaceFlags dataspaceFlag = 0;
+            switch (static_cast<PixelFormat>(it.format)) {
+                case PixelFormat::BLOB:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
+                    break;
+                case PixelFormat::Y16:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+                    break;
+                default:
+                    dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+            }
             stream3_2 = {streamId,
                              StreamType::OUTPUT,
                              static_cast<uint32_t>(it.width),
                              static_cast<uint32_t>(it.height),
                              static_cast<PixelFormat>(it.format),
                              GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
-                             (isJpeg) ? static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF) : 0,
+                             dataspaceFlag,
                              StreamRotation::ROTATION_0};
             ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
             ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
@@ -3415,6 +3431,14 @@
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
+        // Check if camera support depth only
+        if (isDepthOnly(staticMeta)) {
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
@@ -3735,6 +3759,14 @@
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
+        // Check if camera support depth only
+        if (isDepthOnly(staticMeta)) {
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
                   getAvailableOutputStreams(staticMeta, outputBlobStreams,
@@ -4723,38 +4755,56 @@
 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
         std::vector<AvailableStream> &outputStreams,
         const AvailableStream *threshold) {
+    AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                             static_cast<int32_t>(PixelFormat::Y16)};
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
     }
 
-    camera_metadata_ro_entry entry;
-    int rc = find_camera_metadata_ro_entry(staticMeta,
-            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
-    if ((0 != rc) || (0 != (entry.count % 4))) {
+    camera_metadata_ro_entry scalarEntry;
+    camera_metadata_ro_entry depthEntry;
+    int foundScalar = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry);
+    int foundDepth = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
+    if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) &&
+        (0 != foundDepth || (0 != (depthEntry.count % 4)))) {
         return Status::ILLEGAL_ARGUMENT;
     }
 
-    for (size_t i = 0; i < entry.count; i+=4) {
-        if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT ==
-                entry.data.i32[i + 3]) {
+    if(foundScalar == 0 && (0 == (scalarEntry.count % 4))) {
+        fillOutputStreams(&scalarEntry, outputStreams, threshold,
+                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
+    }
+
+    if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
+        fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
+    }
+
+    return Status::OK;
+}
+
+void CameraHidlTest::fillOutputStreams(camera_metadata_ro_entry_t* entry,
+        std::vector<AvailableStream>& outputStreams, const AvailableStream* threshold,
+        const int32_t availableConfigOutputTag) {
+    for (size_t i = 0; i < entry->count; i+=4) {
+        if (availableConfigOutputTag == entry->data.i32[i + 3]) {
             if(nullptr == threshold) {
-                AvailableStream s = {entry.data.i32[i+1],
-                        entry.data.i32[i+2], entry.data.i32[i]};
+                AvailableStream s = {entry->data.i32[i+1],
+                        entry->data.i32[i+2], entry->data.i32[i]};
                 outputStreams.push_back(s);
             } else {
-                if ((threshold->format == entry.data.i32[i]) &&
-                        (threshold->width >= entry.data.i32[i+1]) &&
-                        (threshold->height >= entry.data.i32[i+2])) {
-                    AvailableStream s = {entry.data.i32[i+1],
-                            entry.data.i32[i+2], threshold->format};
+                if ((threshold->format == entry->data.i32[i]) &&
+                        (threshold->width >= entry->data.i32[i+1]) &&
+                        (threshold->height >= entry->data.i32[i+2])) {
+                    AvailableStream s = {entry->data.i32[i+1],
+                            entry->data.i32[i+2], threshold->format};
                     outputStreams.push_back(s);
                 }
             }
         }
-
     }
-
-    return Status::OK;
 }
 
 // Get max jpeg buffer size in android.jpeg.maxSize
@@ -5226,6 +5276,37 @@
     ASSERT_TRUE(ret.isOk());
 }
 
+bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry scalarEntry;
+    camera_metadata_ro_entry depthEntry;
+
+    int rc = find_camera_metadata_ro_entry(
+        staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry);
+    if (rc == 0) {
+        for (uint32_t i = 0; i < scalarEntry.count; i++) {
+            if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
+                return false;
+            }
+        }
+    }
+
+    for (uint32_t i = 0; i < scalarEntry.count; i++) {
+        if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
+
+            rc = find_camera_metadata_ro_entry(
+                staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
+            size_t i = 0;
+            if (rc == 0 && depthEntry.data.i32[i] == static_cast<int32_t>(PixelFormat::Y16)) {
+                // only Depth16 format is supported now
+                return true;
+            }
+            break;
+        }
+    }
+
+    return false;
+}
+
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
         sp<ICameraProvider> provider,
@@ -5316,11 +5397,20 @@
     ASSERT_EQ(Status::OK, rc);
     ASSERT_FALSE(outputPreviewStreams.empty());
 
+    V3_2::DataspaceFlags dataspaceFlag = 0;
+    switch (static_cast<PixelFormat>(outputPreviewStreams[0].format)) {
+        case PixelFormat::Y16:
+            dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+            break;
+        default:
+            dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+    }
+
     V3_2::Stream stream3_2 = {0, StreamType::OUTPUT,
             static_cast<uint32_t> (outputPreviewStreams[0].width),
             static_cast<uint32_t> (outputPreviewStreams[0].height),
             static_cast<PixelFormat> (outputPreviewStreams[0].format),
-            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
+            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, dataspaceFlag, StreamRotation::ROTATION_0};
     ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
     ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
     ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
diff --git a/current.txt b/current.txt
index 8184523..c9bcf7b 100644
--- a/current.txt
+++ b/current.txt
@@ -394,11 +394,12 @@
 da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
 21165b8e30c4b2d52980e4728f661420adc16e38bbe73476c06b2085be908f4c android.hardware.gnss@1.0::IGnssCallback
 d702fb01dc2a0733aa820b7eb65435ee3334f75632ef880bafd2fb8803a20a58 android.hardware.gnss@1.0::IGnssMeasurementCallback
+7c7721c0f773fcf422b71a4f558545e9e36acc973e58ca51e5bd53905cf46bc0 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
 d4fea995378bb4f421b4e24ccf68cad2734ab07fe4f874a126ba558b99df5766 android.hardware.graphics.composer@2.1::IComposerClient
 b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
 574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
 417ab60fe1ef786778047e4486f3d868ebce570d91addd8fe4251515213072de android.hardware.neuralnetworks@1.0::types
-e22e8135d061d0e9c4c1a70c25c19fdba10f4d3cda9795ef25b6392fc520317c android.hardware.neuralnetworks@1.1::types
+ec8aa14fe9b03f2b3fb9845346a4005b6d098ebe2277b2564f73a548a0fd14a7 android.hardware.neuralnetworks@1.1::types
 1d4a5776614c08b5d794a5ec5ab04697260cbd4b3441d5935cd53ee71d19da02 android.hardware.radio@1.0::IRadioResponse
 ed9da80ec0c96991fd03f0a46107815d0e50f764656e49dba4980fa5c31d5bc3 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
@@ -479,7 +480,7 @@
 01c6398c90fc6be0640810e2c5d8a4863b457280132bb3f97dd5682e19632b62 android.hardware.graphics.bufferqueue@2.0::types
 7a2d64095252f85781b2d521f4f11d04ce774544feececcec2088c568656e93c android.hardware.graphics.common@1.2::types
 3dff04a36b86660b5807414587e530bb0c294ed56fdff06f8915ba0a9b73f974 android.hardware.graphics.composer@2.3::IComposer
-daa44e83d7709bf1c9e0bd9a6b552feff496fd14574a9461ee93c21980fc5b15 android.hardware.graphics.composer@2.3::IComposerClient
+54bc1dc874f8bc0781767786075dafd33a0796c1eea7d2317231b8929280e946 android.hardware.graphics.composer@2.3::IComposerClient
 5c8bf8e1af9efe225a4661db8c08ff1b7e13fdc8ed49f35291bd0b6c9436b8f2 android.hardware.graphics.mapper@3.0::IMapper
 7183d9d9acfa41a61a64bdfed548e98299265a7bb1821a3ed204173b5c2cfd4a android.hardware.graphics.mapper@3.0::types
 c3f831a66d5815baf74f5b82fe79cf099542ddae4dfab3f388e1d41828e794fc android.hardware.health.storage@1.0::IGarbageCollectCallback
@@ -507,7 +508,7 @@
 92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
 83885d366f22ada42c00d8854f0b7e7ba4cf73ddf80bb0d8e168ce132cec57ea android.hardware.neuralnetworks@1.2::IPreparedModel
 e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
-896d1827541d620996720a79c6476edb902a58d515bf908f67a5bdef4d2c318c android.hardware.neuralnetworks@1.2::types
+114056b3b9303e0e858f28e718ba45722de5678d1d54eec0dcd10788604bf2bb android.hardware.neuralnetworks@1.2::types
 cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
 abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
 4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp
index f37adaf..252ebb9 100644
--- a/drm/1.2/vts/functional/drm_hal_test.cpp
+++ b/drm/1.2/vts/functional/drm_hal_test.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "drm_hal_clearkey_test@1.2"
+#define LOG_TAG "drm_hal_test@1.2"
 
 #include <gtest/gtest.h>
 #include <hidl/HidlSupport.h>
@@ -180,19 +180,36 @@
 }
 
 /**
- * Test clearkey plugin offline key support
+ * Test drm plugin offline key support
  */
 TEST_P(DrmHalTest, OfflineLicenseTest) {
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
 
-    auto res = drmPlugin->getOfflineLicenseKeySetIds(checkKeySetIds<Status::OK, 1u>);
+    auto res = drmPlugin->getOfflineLicenseKeySetIds(
+            [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
+                bool found = false;
+                EXPECT_EQ(Status::OK, status);
+                for (KeySetId keySetId2: keySetIds) {
+                    if (keySetId == keySetId2) {
+                        found = true;
+                        break;
+                    }
+                }
+                EXPECT_TRUE(found) << "keySetId not found";
+            });
     EXPECT_OK(res);
 
     Status err = drmPlugin->removeOfflineLicense(keySetId);
     EXPECT_EQ(Status::OK, err);
 
-    res = drmPlugin->getOfflineLicenseKeySetIds(checkKeySetIds<Status::OK, 0u>);
+    res = drmPlugin->getOfflineLicenseKeySetIds(
+            [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
+                EXPECT_EQ(Status::OK, status);
+                for (KeySetId keySetId2: keySetIds) {
+                    EXPECT_NE(keySetId, keySetId2);
+                }
+            });
     EXPECT_OK(res);
 
     err = drmPlugin->removeOfflineLicense(keySetId);
@@ -202,7 +219,7 @@
 }
 
 /**
- * Test clearkey plugin offline key state
+ * Test drm plugin offline key state
  */
 TEST_P(DrmHalTest, OfflineLicenseStateTest) {
     auto sessionId = openSession();
diff --git a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
index c59a16c..21cbc2e 100644
--- a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
+++ b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
@@ -546,7 +546,7 @@
      */
     disconnect(
             int32_t api,
-            DisconnectMode mode /* = DisconnectMode::API */
+            DisconnectMode mode
         ) generates (
             Status status
         );
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index 5fcc0e6..1eea306 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -61,6 +61,11 @@
          * PowerMode::DOZE_SUSPEND.
          */
         DOZE = 2,
+
+        /**
+         * Indicates that the display supports brightness operations.
+         */
+        BRIGHTNESS = 3,
     };
 
     /**
@@ -495,4 +500,38 @@
                        float maxLuminance,
                        float maxAverageLuminance,
                        float minLuminance);
+
+    /**
+     * Gets whether brightness operations are supported on a display.
+     *
+     * @param display
+     *      The display.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *      BAD_DISPLAY   when the display is invalid, or
+     *      BAD_PARAMETER when the output parameter is invalid.
+     * @return support
+     *      Whether brightness operations are supported on the display.
+     */
+    getDisplayBrightnessSupport(Display display) generates (Error error, bool support);
+
+    /**
+     * Sets the brightness of a display.
+     *
+     * Ideally, the brightness change should take effect in the next frame post (so that it can be
+     * aligned with color transforms).
+     *
+     * @param display
+     *      The display whose brightness is set.
+     * @param brightness
+     *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0 to
+     *      turn the backlight off.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY   when the display is invalid, or
+     *         UNSUPPORTED   when brightness operations are not supported, or
+     *         BAD_PARAMETER when the brightness is invalid, or
+     *         NO_RESOURCES  when the brightness cannot be applied.
+     */
+    setDisplayBrightness(Display display, float brightness) generates (Error error);
 };
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index a272e72..1b40795 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -172,7 +172,19 @@
         return Void();
     }
 
-   protected:
+    Return<void> getDisplayBrightnessSupport(
+            Display display, IComposerClient::getDisplayBrightnessSupport_cb hidl_cb) override {
+        bool support = false;
+        Error error = mHal->getDisplayBrightnessSupport(display, &support);
+        hidl_cb(error, support);
+        return Void();
+    }
+
+    Return<Error> setDisplayBrightness(Display display, float brightness) override {
+        return mHal->setDisplayBrightness(display, brightness);
+    }
+
+  protected:
     std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
         return std::make_unique<ComposerCommandEngine>(
             mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index a0812ad..186b004 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -119,6 +119,8 @@
     virtual Error setLayerPerFrameMetadataBlobs(
         Display display, Layer layer,
         std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) = 0;
+    virtual Error getDisplayBrightnessSupport(Display display, bool* outSupport) = 0;
+    virtual Error setDisplayBrightness(Display display, float brightness) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index 41e333a..070cf80 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -245,7 +245,29 @@
         return static_cast<Error>(err);
     }
 
-   protected:
+    Error getDisplayBrightnessSupport(Display display, bool* outSupport) {
+        if (!mDispatch.getDisplayBrightnessSupport) {
+            return Error::UNSUPPORTED;
+        }
+        bool support = false;
+        int32_t error = mDispatch.getDisplayBrightnessSupport(mDevice, display, &support);
+        *outSupport = support;
+        return static_cast<Error>(error);
+    }
+
+    Error setDisplayBrightness(Display display, float brightness) {
+        if (std::isnan(brightness) || brightness > 1.0f ||
+            (brightness < 0.0f && brightness != -1.0f)) {
+            return Error::BAD_PARAMETER;
+        }
+        if (!mDispatch.setDisplayBrightness) {
+            return Error::UNSUPPORTED;
+        }
+        int32_t error = mDispatch.setDisplayBrightness(mDevice, display, brightness);
+        return static_cast<Error>(error);
+    }
+
+  protected:
     bool initDispatch() override {
         if (!BaseType2_2::initDispatch()) {
             return false;
@@ -265,6 +287,10 @@
                                    &mDispatch.getDisplayCapabilities);
         this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
                                    &mDispatch.setLayerPerFrameMetadataBlobs);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_BRIGHTNESS_SUPPORT,
+                                   &mDispatch.getDisplayBrightnessSupport);
+        this->initOptionalDispatch(HWC2_FUNCTION_SET_DISPLAY_BRIGHTNESS,
+                                   &mDispatch.setDisplayBrightness);
         return true;
     }
 
@@ -277,6 +303,8 @@
         HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
         HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
         HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS setLayerPerFrameMetadataBlobs;
+        HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT getDisplayBrightnessSupport;
+        HWC2_PFN_SET_DISPLAY_BRIGHTNESS setDisplayBrightness;
     } mDispatch = {};
 
     using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index 0e541ed..4de85d6 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -186,6 +186,19 @@
     return capabilities;
 }
 
+bool ComposerClient::getDisplayBrightnessSupport(Display display) {
+    bool support = false;
+    mClient->getDisplayBrightnessSupport(display, [&](const auto& error, const auto& tmpSupport) {
+        ASSERT_EQ(Error::NONE, error) << "failed to get brightness support";
+        support = tmpSupport;
+    });
+    return support;
+}
+
+Error ComposerClient::setDisplayBrightness(Display display, float brightness) {
+    return mClient->setDisplayBrightness(display, brightness);
+}
+
 }  // namespace vts
 }  // namespace V2_3
 }  // namespace composer
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index ad4ef0b..a0e764d 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -52,7 +52,7 @@
 
     std::unique_ptr<ComposerClient> createClient();
 
-   protected:
+  protected:
     explicit Composer(const sp<IComposer>& composer);
 
    private:
@@ -99,7 +99,11 @@
 
     std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys_2_3(Display display);
 
-   private:
+    bool getDisplayBrightnessSupport(Display display);
+
+    Error setDisplayBrightness(Display display, float brightness);
+
+  private:
     const sp<IComposerClient> mClient;
 };
 
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index de74e28..b983e42 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -600,6 +600,36 @@
     }
 }
 
+/*
+ * Test that getDisplayBrightnessSupport works as expected.
+ */
+TEST_F(GraphicsComposerHidlTest, getDisplayBrightnessSupport) {
+    auto capabilities = mComposerClient->getDisplayCapabilities(mPrimaryDisplay);
+    bool brightnessSupport =
+            std::find(capabilities.begin(), capabilities.end(),
+                      IComposerClient::DisplayCapability::BRIGHTNESS) != capabilities.end();
+    EXPECT_EQ(mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay), brightnessSupport);
+}
+
+/*
+ * Test that if brightness operations are supported, setDisplayBrightness works as expected.
+ */
+TEST_F(GraphicsComposerHidlTest, setDisplayBrightness) {
+    if (!mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay)) {
+        EXPECT_EQ(mComposerClient->getRaw()->setDisplayBrightness(mPrimaryDisplay, 0.5f),
+                  Error::UNSUPPORTED);
+        GTEST_SUCCEED() << "Brightness operations are not supported";
+    }
+
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f), Error::NONE);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f), Error::NONE);
+
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f), Error::BAD_PARAMETER);
+    EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f), Error::BAD_PARAMETER);
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_3
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 7eea7fc..f5cb0d7 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -77,6 +77,13 @@
                   "Number of types in MixedTyped changed, but copy_back function wasn't updated");
 }
 
+static bool isZeroSized(const MixedTyped& example, uint32_t index) {
+    for (auto i : example.operandDimensions.at(index)) {
+        if (i == 0) return true;
+    }
+    return false;
+}
+
 // Top level driver for models and examples generated by test_generator.py
 // Test driver for those generated from ml/nn/runtime/test/spec
 static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>& preparedModel,
@@ -178,17 +185,18 @@
         // Go through all outputs, initialize RequestArgument descriptors
         resize_accordingly(golden, test);
         bool sizeLargerThanOne = true;
-        for_all(golden, [&outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
+        for_all(golden, [&golden, &outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
                                 int index, auto, auto s) {
             if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
             if (index == 0) {
                 // On OutputType::INSUFFICIENT, set the output operand with index 0 with
                 // buffer size one byte less than needed.
                 if (outputType == OutputType::INSUFFICIENT) {
-                    if (s > 1)
+                    if (s > 1 && !isZeroSized(golden, index)) {
                         s -= 1;
-                    else
+                    } else {
                         sizeLargerThanOne = false;
+                    }
                 }
             }
             RequestArgument arg = {
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index c9de76b..99f873a 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -186,7 +186,8 @@
      *      must be >= 1.
      * * 2: A 2-D Tensor of {@link OperandType::TENSOR_INT32}, the paddings
      *      for each spatial dimension of the input tensor. All values must be
-     *      >= 0. The shape of the tensor must be {rank(input0), 2}.
+     *      >= 0. The shape of the tensor must be {M, 2}, where M is the number
+     *      of spatial dimensions.
      *      padding[i, 0] specifies the number of element to be padded in the
      *      front of dimension i.
      *      padding[i, 1] specifies the number of element to be padded after the
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index bb14dec..f2e02b8 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1979,7 +1979,8 @@
      *      must be >= 1.
      * * 2: A 2-D Tensor of {@link OperandType::TENSOR_INT32}, the paddings
      *      for each spatial dimension of the input tensor. All values must be
-     *      >= 0. The shape of the tensor must be {rank(input0), 2}.
+     *      >= 0. The shape of the tensor must be {M, 2}, where M is the number
+     *      of spatial dimensions.
      *      padding[i, 0] specifies the number of element to be padded in the
      *      front of dimension i.
      *      padding[i, 1] specifies the number of element to be padded after the
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
index da78f41..1d79ff6 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
@@ -26,6 +26,10 @@
     sap->connectReq(token, maxMsgSize);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(sapCb->sapResponseToken, token);
+
+    // Modem side need time for connect to finish. Adding a waiting time to prevent
+    // disconnect being requested right after connect request.
+    sleep(1);
 }
 
 /*