Merge "Implement NNAPI canonical interfaces"
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 590adc5..8d1693a 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -32,7 +32,7 @@
     defaults: ["vhal_v2_0_defaults"],
     shared_libs: [
         "libbinder_ndk",
-        "carwatchdog_aidl_interface-ndk_platform",
+        "android.automotive.watchdog-ndk_platform",
     ],
 }
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 80a1831..5ecce46 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -417,7 +417,7 @@
                          .minSampleRate = 1.0f,
                          .maxSampleRate = 2.0f,
                  },
-         .initialValue = {.floatValues = {100.0f}}},  // units in meters
+         .initialValue = {.floatValues = {50000.0f}}},  // units in meters
 
         {.config =
                  {
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index 9f977f5..365ae58 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -21,4 +21,9 @@
   android.hardware.biometrics.common.CommonProps commonProps;
   android.hardware.biometrics.face.FaceSensorType sensorType;
   boolean halControlsPreview;
+  int enrollPreviewWidth;
+  int enrollPreviewHeight;
+  float enrollTranslationX;
+  float enrollTranslationY;
+  float enrollPreviewScale;
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index 53cc44e..9c2f9a1 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -39,5 +39,36 @@
      * the framework.
      */
     boolean halControlsPreview;
+
+    /**
+     * For implementations where the HAL manages the preview, this is the width, in pixels, of each
+     * frame that the camera is set up to output.
+     */
+    int enrollPreviewWidth;
+
+    /**
+     * For implementations where the HAL manages the preview, this is the height, in pixels, of
+     * each frame that the camera is set up to output.
+     */
+    int enrollPreviewHeight;
+
+    /**
+     * For implementations where the HAL manages the preview, this is the distance in pixels that
+     * the enrollment preview should be translated. This is typically used by devices where the
+     * camera used for enrollment preview is not centered.
+     */
+    float enrollTranslationX;
+
+    /**
+     * For implementations where the HAL manages the preview, this is the distance in pixels that
+     * the enrollment preview should be translated.
+     */
+    float enrollTranslationY;
+
+    /**
+     * For implementations where the HAL manages the preview, this is the scale factor that should
+     * be applied when configuring the preview texture.
+     */
+    float enrollPreviewScale;
 }
 
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 1526245..929c7e7 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -46,6 +46,11 @@
     props.commonProps = std::move(commonProps);
     props.sensorType = kSensorType;
     props.halControlsPreview = kHalControlsPreview;
+    props.enrollPreviewWidth = 1080;
+    props.enrollPreviewHeight = 1920;
+    props.enrollTranslationX = 100.f;
+    props.enrollTranslationY = 50.f;
+    props.enrollPreviewScale = 1.f;
 
     *return_val = {std::move(props)};
     return ndk::ScopedAStatus::ok();
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index aa5c48f..f1f0f18 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1209,7 +1209,12 @@
             return notify;
         }
 
-        if (physicalCameraMetadata.size() != request->expectedPhysicalResults.size()) {
+        // Physical device results are only expected in the last/final
+        // partial result notification.
+        bool expectPhysicalResults = !(request->usePartialResult &&
+                (results.partialResult < request->numPartialResults));
+        if (expectPhysicalResults &&
+                (physicalCameraMetadata.size() != request->expectedPhysicalResults.size())) {
             ALOGE("%s: Frame %d: Returned physical metadata count %zu "
                     "must be equal to expected count %zu", __func__, frameNumber,
                     physicalCameraMetadata.size(), request->expectedPhysicalResults.size());
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 57f390c..ff925d9 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -521,7 +521,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.usb.gadget</name>
-        <version>1.0-1</version>
+        <version>1.0-2</version>
         <interface>
             <name>IUsbGadget</name>
             <instance>default</instance>
@@ -534,6 +534,13 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.vr</name>
         <version>1.0</version>
diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp
index 252f4e6..39efcd2 100644
--- a/gnss/1.1/default/GnssDebug.cpp
+++ b/gnss/1.1/default/GnssDebug.cpp
@@ -37,8 +37,8 @@
             .latitudeDegrees = gMockLatitudeDegrees,
             .longitudeDegrees = gMockLongitudeDegrees,
             .altitudeMeters = gMockAltitudeMeters,
-            .speedMetersPerSec = kMockSpeedMetersPerSec,
-            .bearingDegrees = kMockBearingDegrees,
+            .speedMetersPerSec = gMockSpeedMetersPerSec,
+            .bearingDegrees = gMockBearingDegrees,
             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index 175bc75..aae3571 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -18,6 +18,7 @@
     name: "VtsHalGnssV2_1TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
+        "gnss_hal_test.cpp",
         "gnss_hal_test_cases.cpp",
         "VtsHalGnssV2_1TargetTest.cpp",
     ],
@@ -31,6 +32,9 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss@common-vts-lib",
     ],
+    shared_libs: [
+        "libvintf",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp
new file mode 100644
index 0000000..1154260
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "GnssHalTest"
+
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+#include <log/log.h>
+#include <vintf/VintfObject.h>
+
+#include "gnss_hal_test.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_2::IServiceManager;
+
+bool GnssHalTest::IsGnssHalVersion_2_1() const {
+    sp<IServiceManager> manager = ::android::hardware::defaultServiceManager1_2();
+    bool hasGnssHalVersion_2_1 = false;
+    manager->listManifestByInterface(
+            "android.hardware.gnss@2.1::IGnss",
+            [&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
+                hasGnssHalVersion_2_1 = registered.size() > 0;
+            });
+
+    auto deviceManifest = ::android::vintf::VintfObject::GetDeviceHalManifest();
+    bool hasGnssAidl =
+            deviceManifest->getAidlInstances("android.hardware.gnss", "IGnss").size() > 0;
+
+    return hasGnssHalVersion_2_1 && !hasGnssAidl;
+}
\ No newline at end of file
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h
index c28e248..7950670 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test.h
+++ b/gnss/2.1/vts/functional/gnss_hal_test.h
@@ -22,4 +22,11 @@
 using android::hardware::gnss::V2_1::IGnss;
 
 // The main test class for GNSS HAL.
-class GnssHalTest : public GnssHalTestTemplate<IGnss> {};
+class GnssHalTest : public GnssHalTestTemplate<IGnss> {
+  public:
+    /**
+     * IsGnssHalVersion_2_1:
+     * returns  true if the GNSS HAL version is exactly 2.1.
+     */
+    bool IsGnssHalVersion_2_1() const;
+};
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
index 2902809..7afd49c 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -87,6 +87,10 @@
  * Gets the GnssConfigurationExtension and verifies that it returns an actual extension.
  */
 TEST_P(GnssHalTest, TestGnssConfigurationExtension) {
+    if (!IsGnssHalVersion_2_1()) {
+        ALOGI("Test TestGnssConfigurationExtension skipped. GNSS HAL version is greater than 2.1.");
+        return;
+    }
     auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1();
     auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0();
     auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1();
@@ -358,20 +362,24 @@
 }
 
 /*
- * BlacklistIndividualSatellites:
+ * BlocklistIndividualSatellites:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus for common satellites (strongest and one other.)
- * 2a & b) Turns off location, and blacklists common satellites.
+ * 2a & b) Turns off location, and blocklists common satellites.
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use those satellites.
- * 4a & b) Turns off location, and send in empty blacklist.
+ * 4a & b) Turns off location, and send in empty blocklist.
  * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does re-use at least the previously strongest satellite
  * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
  * formerly strongest satellite
  */
-TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
+TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
+    if (!IsGnssHalVersion_2_1()) {
+        ALOGI("Test BlocklistIndividualSatellites skipped. GNSS HAL version is greater than 2.1.");
+        return;
+    }
     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
         ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability not "
               "supported.");
@@ -509,16 +517,21 @@
 }
 
 /*
- * BlacklistConstellationLocationOff:
+ * BlocklistConstellationLocationOff:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus for any non-GPS constellations.
- * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 2a & b) Turns off location, and blocklist first non-GPS constellations.
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use any constellation but GPS.
- * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
  */
-TEST_P(GnssHalTest, BlacklistConstellationLocationOff) {
+TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
+    if (!IsGnssHalVersion_2_1()) {
+        ALOGI("Test BlocklistConstellationLocationOff skipped. GNSS HAL version is greater than "
+              "2.1.");
+        return;
+    }
     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
         ALOGI("Test BlacklistConstellationLocationOff skipped. SATELLITE_BLACKLIST capability not "
               "supported.");
@@ -591,16 +604,21 @@
 }
 
 /*
- * BlacklistConstellationLocationOn:
+ * BlocklistConstellationLocationOn:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus for any non-GPS constellations.
- * 2a & b) Blacklist first non-GPS constellation, and turn off location.
+ * 2a & b) Blocklist first non-GPS constellation, and turn off location.
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use any constellation but GPS.
- * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
  */
-TEST_P(GnssHalTest, BlacklistConstellationLocationOn) {
+TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
+    if (!IsGnssHalVersion_2_1()) {
+        ALOGI("Test BlocklistConstellationLocationOn skipped. GNSS HAL version is greater than "
+              "2.1.");
+        return;
+    }
     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
         ALOGI("Test BlacklistConstellationLocationOn skipped. SATELLITE_BLACKLIST capability not "
               "supported.");
diff --git a/gnss/aidl/TEST_MAPPING b/gnss/aidl/TEST_MAPPING
new file mode 100644
index 0000000..c21c3e4
--- /dev/null
+++ b/gnss/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalGnssTargetTest"
+    }
+  ]
+}
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 2b8a447..d621053 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -46,7 +46,7 @@
     ASSERT_TRUE(iGnssPsds != nullptr);
 
     status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
-    ASSERT_TRUE(status.isOk());
+    ASSERT_FALSE(status.isOk());
 }
 
 /*
diff --git a/gnss/common/utils/default/MockLocation.cpp b/gnss/common/utils/default/MockLocation.cpp
index 2d8e7c5..c90075f 100644
--- a/gnss/common/utils/default/MockLocation.cpp
+++ b/gnss/common/utils/default/MockLocation.cpp
@@ -21,5 +21,7 @@
 float gMockLatitudeDegrees{37.4219999};
 float gMockLongitudeDegrees{-122.0840575};
 float gMockAltitudeMeters{1.60062531};
+float gMockBearingDegrees{0};
+float gMockSpeedMetersPerSec{0};
 
 }  // namespace android::hardware::gnss::common
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index fa83634..d336f1b 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -145,8 +145,8 @@
             .latitudeDegrees = gMockLatitudeDegrees,
             .longitudeDegrees = gMockLongitudeDegrees,
             .altitudeMeters = gMockAltitudeMeters,
-            .speedMetersPerSec = kMockSpeedMetersPerSec,
-            .bearingDegrees = kMockBearingDegrees,
+            .speedMetersPerSec = gMockSpeedMetersPerSec,
+            .bearingDegrees = gMockBearingDegrees,
             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index ad4e0eb..a290ed2 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -24,8 +24,6 @@
 namespace gnss {
 namespace common {
 
-const float kMockSpeedMetersPerSec = 0;
-const float kMockBearingDegrees = 0;
 const float kMockHorizontalAccuracyMeters = 5;
 const float kMockVerticalAccuracyMeters = 5;
 const float kMockSpeedAccuracyMetersPerSecond = 1;
diff --git a/gnss/common/utils/default/include/MockLocation.h b/gnss/common/utils/default/include/MockLocation.h
index cd8cb5d..0bfdd1a 100644
--- a/gnss/common/utils/default/include/MockLocation.h
+++ b/gnss/common/utils/default/include/MockLocation.h
@@ -27,6 +27,8 @@
 extern float gMockLatitudeDegrees;
 extern float gMockLongitudeDegrees;
 extern float gMockAltitudeMeters;
+extern float gMockBearingDegrees;
+extern float gMockSpeedMetersPerSec;
 
 }  // namespace common
 }  // namespace gnss
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index cbf3933..4d1baa7 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -651,6 +651,8 @@
     auto lat = gMockLatitudeDegrees;
     auto lon = gMockLongitudeDegrees;
     auto ele = gMockAltitudeMeters;
+    auto bea = gMockBearingDegrees;
+    auto spd = gMockSpeedMetersPerSec;
 
     for (size_t i = 1; i < options.size(); ++i) {
         std::string option = options[i];
@@ -663,6 +665,12 @@
         } else if (option.rfind("ele=", 0) == 0) {
             option = option.substr(4);
             ele = stof(option);
+        } else if (option.rfind("bea=", 0) == 0) {
+            option = option.substr(4);
+            bea = stof(option);
+        } else if (option.rfind("spd=", 0) == 0) {
+            option = option.substr(4);
+            spd = stof(option);
         } else {
             dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str());
         }
@@ -671,9 +679,12 @@
     gMockLatitudeDegrees = lat;
     gMockLongitudeDegrees = lon;
     gMockAltitudeMeters = ele;
+    gMockBearingDegrees = bea;
+    gMockSpeedMetersPerSec = spd;
 
-    dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f\n", gMockLatitudeDegrees,
-            gMockLongitudeDegrees, gMockAltitudeMeters);
+    dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f bea=%f spd=%f\n",
+            gMockLatitudeDegrees, gMockLongitudeDegrees, gMockAltitudeMeters, gMockBearingDegrees,
+            gMockSpeedMetersPerSec);
 
     return Void();
 }
@@ -682,7 +693,7 @@
 Return<void> GnssTemplate<T_IGnss>::help(const hidl_handle& fd) {
     dprintf(fd->data[0],
             "invalid option for Gnss HAL; valid options are:\n"
-            "location lat=.. lon=.. ele=..\n");
+            "location [lat=..] [lon=..] [ele=..] [bea=..] [spd=..]\n");
     return Void();
 }
 
diff --git a/gnss/common/utils/default/v2_1/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp
index d78b0b6..537a90c 100644
--- a/gnss/common/utils/default/v2_1/GnssDebug.cpp
+++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp
@@ -33,8 +33,8 @@
             .latitudeDegrees = gMockLatitudeDegrees,
             .longitudeDegrees = gMockLongitudeDegrees,
             .altitudeMeters = gMockAltitudeMeters,
-            .speedMetersPerSec = kMockSpeedMetersPerSec,
-            .bearingDegrees = kMockBearingDegrees,
+            .speedMetersPerSec = gMockSpeedMetersPerSec,
+            .bearingDegrees = gMockBearingDegrees,
             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
index 341909e..4d56ccf 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -20,5 +20,6 @@
 parcelable EnergyMeasurement {
   int channelId;
   long timestampMs;
+  long durationMs;
   long energyUWs;
 }
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
index f873849..d81914d 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -23,11 +23,15 @@
      */
     int channelId;
     /**
-     * Time since boot in milliseconds
+     * Approximate time of data capture in millseconds since boot
      */
     long timestampMs;
     /**
-     * Accumulated energy since boot in microwatt-seconds (uWs)
+     * Duration in milliseconds that energy has been accumulated
+     */
+    long durationMs;
+    /**
+     * Accumulated energy in microwatt-seconds (uWs)
      */
     long energyUWs;
 }
diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
index 85a2ce0..05e2004 100644
--- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
@@ -96,7 +96,7 @@
     ChannelInfo[] getEnergyMeterInfo();
 
     /**
-     * Reports accumulated energy since boot for each specified channel.
+     * Reports accumulated energy for each specified channel.
      *
      * @param channelIds IDs of channels for which data is requested.
      *     Passing an empty list will return energy measurements for all available channels.
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index a093dee..91709fa 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -320,4 +320,29 @@
      */
     oneway setAllowedNetworkTypeBitmap(
             uint32_t serial, bitfield<RadioAccessFamily> networkTypeBitmap);
+
+    /**
+     * Control data throttling at modem.
+     *   - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing
+     *     data throttling within the requested completion window.
+     *   - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing
+     *     throttling on anchor carrier and achieve maximum data throttling on
+     *     secondary carrier within the requested completion window.
+     *   - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary
+     *     carrier and achieve maximum data throttling on anchor carrier by
+     *     requested completion window.
+     *   - DataThrottlingAction:HOLD: Immediately hold on to current level of
+     *     throttling.
+     *
+     * @param serial Serial number of request.
+     * @param dataThrottlingAction DataThrottlingAction as defined in types.hal
+     * @param completionWindowSecs window, in seconds, in which the requested
+     *     throttling action has to be achieved. This must be 0 when
+     *     dataThrottlingAction is DataThrottlingAction:HOLD.
+     *
+     * Response function is IRadioResponse.setDataThrottlingResponse()
+     */
+    oneway setDataThrottling(int32_t serial,
+            DataThrottlingAction dataThrottlingAction,
+            int32_t completionWindowSecs);
 };
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index c135090..f195c0e 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -18,6 +18,8 @@
 
 import @1.0::RadioIndicationType;
 import @1.5::IRadioIndication;
+import @1.6::SetupDataCallResult;
+import @1.6::LinkCapacityEstimate;
 
 /**
  * Interface declaring unsolicited radio indications.
@@ -53,4 +55,16 @@
      * @param apn Apn to unthrottle
      */
     oneway unthrottleApn(RadioIndicationType type, string apn);
+
+    /**
+     * Indicates current link capacity estimate.
+     * This replaces @1.2::IRadioIndication.currentLinkCapacityEstimate().
+     * This indication is sent whenever the reporting criteria, as set by
+     * @1.2::IRadio.setLinkCapacityReportingCriteria, are met and the indication is not
+     * suppressed by @1.2::IRadio.setIndicationFilter_1_2().
+     *
+     * @param type Type of radio indication
+     * @param lce LinkCapacityEstimate
+     */
+    oneway currentLinkCapacityEstimate_1_6(RadioIndicationType type, LinkCapacityEstimate lce);
 };
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index 0379e00..acae5c7 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -306,4 +306,15 @@
      *   RadioError:NO_RESOURCES
      */
     oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     *  Valid errors returned:
+     *  RadioError:NONE
+     *  RadioError:RADIO_NOT_AVAILABLE
+     *  RadioError:MODEM_ERR
+     *  RadioError:INVALID_ARGUMENTS
+     */
+    oneway setDataThrottlingResponse(RadioResponseInfo info);
 };
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 8f842a3..2cba915 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -350,3 +350,69 @@
      */
     DISABLE_IMMEDIATE= 3,
 };
+
+/**
+ * Overwritten from @1.2::LinkCapacityEstimate to update LinkCapacityEstimate to 1.6 version.
+ */
+struct LinkCapacityEstimate {
+
+   /**
+    * Estimated downlink capacity in kbps. In case of a dual connected network,
+    * this includes capacity of both primary and secondary. This bandwidth estimate shall be
+    * the estimated maximum sustainable link bandwidth (as would be measured
+    * at the Upper PDCP or SNDCP SAP). If the DL Aggregate Maximum Bit Rate is known,
+    * this value shall not exceed the DL-AMBR for the Internet PDN connection.
+    * This must be filled with -1 if network is not connected.
+    */
+   uint32_t downlinkCapacityKbps;
+
+   /**
+    * Estimated uplink capacity in kbps. In case of a dual connected network,
+    * this includes capacity of both primary and secondary. This bandwidth estimate shall be the
+    * estimated maximum sustainable link bandwidth (as would be measured at the
+    * Upper PDCP or SNDCP SAP). If the UL Aggregate Maximum Bit Rate is known,
+    * this value shall not exceed the UL-AMBR for the Internet PDN connection.
+    * This must be filled with -1 if network is not connected.
+    */
+   uint32_t uplinkCapacityKbps;
+
+   /**
+    * Estimated downlink capacity of secondary carrier in a dual connected NR mode in kbps.
+    * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth
+    * (as would be measured at the Upper PDCP or SNDCP SAP). This is valid only
+    * in if device is connected to both primary and secodary in dual connected
+    * mode. This must be filled with -1 if secondary is not connected.
+    */
+   uint32_t secondaryDownlinkCapacityKbps;
+
+   /**
+    * Estimated uplink capacity secondary carrier in a dual connected NR mode in kbps.
+    * This bandwidth estimate shall be the estimated
+    * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+    * This is valid only in if device is connected to both primary and secodary in dual connected
+    * mode.This must be filled with -1 if secondary is not connected.
+    */
+   uint32_t secondaryUplinkCapacityKbps;
+};
+
+enum DataThrottlingAction : int32_t {
+    /* Clear all existing data throttling. */
+    NO_DATA_THROTTLING = 0,
+
+    /**
+     * Enact secondary carrier data throttling and remove any existing data
+     * throttling on anchor carrier.
+     */
+    THROTTLE_SECONDARY_CARRIER = 1,
+
+    /**
+     * Enact anchor carrier data throttling and disable data on secondary
+     * carrier if currently enabled.
+     */
+    THROTTLE_ANCHOR_CARRIER = 2,
+
+    /**
+     * Immediately hold on to current level of throttling.
+     */
+    HOLD = 3
+};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 6547611..ac84417 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -295,3 +295,69 @@
                                   ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
                                   ::android::hardware::radio::V1_6::RadioError::NONE}));
 }
+
+/*
+ * Test IRadio.setDataThrottling() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setDataThrottling) {
+    serial = GetRandomSerialNumber();
+
+    Return<void> res = radio_v1_6->setDataThrottling(
+            serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+                             {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                              ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+                              ::android::hardware::radio::V1_6::RadioError::NONE,
+                              ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+    serial = GetRandomSerialNumber();
+
+    res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER, 60);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+                             {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                              ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+                              ::android::hardware::radio::V1_6::RadioError::NONE,
+                              ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+    serial = GetRandomSerialNumber();
+
+    res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+                             {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                              ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+                              ::android::hardware::radio::V1_6::RadioError::NONE,
+                              ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+    serial = GetRandomSerialNumber();
+
+    res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    ASSERT_TRUE(
+            CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+                             {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                              ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+                              ::android::hardware::radio::V1_6::RadioError::NONE,
+                              ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+}
\ No newline at end of file
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 989ba6d..31bb1d7 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -792,6 +792,9 @@
 
     Return<void> setAllowedNetworkTypeBitmapResponse(
             const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+
+    Return<void> setDataThrottlingResponse(
+            const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
 };
 
 /* Callback class for radio indication */
@@ -865,6 +868,10 @@
             RadioIndicationType type,
             const ::android::hardware::radio::V1_2::LinkCapacityEstimate& lce);
 
+    Return<void> currentLinkCapacityEstimate_1_6(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_6::LinkCapacityEstimate& lce);
+
     Return<void> currentPhysicalChannelConfigs(
             RadioIndicationType type,
             const ::android::hardware::hidl_vec<
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
index b353c82..afde291 100644
--- a/radio/1.6/vts/functional/radio_indication.cpp
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -124,6 +124,12 @@
     return Void();
 }
 
+Return<void> RadioIndication_v1_6::currentLinkCapacityEstimate_1_6(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_6::LinkCapacityEstimate& /*lce*/) {
+    return Void();
+}
+
 Return<void> RadioIndication_v1_6::currentPhysicalChannelConfigs(
         RadioIndicationType /*type*/,
         const ::android::hardware::hidl_vec<
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 18cda6a..09a2bac 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -1156,3 +1156,10 @@
     parent_v1_6.notify(info.serial);
     return Void();
 }
+
+Return<void> RadioResponse_v1_6::setDataThrottlingResponse(
+        const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index 1841dff..870980f 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -57,11 +57,11 @@
     return mSensorInfo;
 }
 
-void Sensor::batch(int32_t samplingPeriodNs) {
-    if (samplingPeriodNs < mSensorInfo.minDelay * 1000) {
-        samplingPeriodNs = mSensorInfo.minDelay * 1000;
-    } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000) {
-        samplingPeriodNs = mSensorInfo.maxDelay * 1000;
+void Sensor::batch(int64_t samplingPeriodNs) {
+    if (samplingPeriodNs < mSensorInfo.minDelay * 1000ll) {
+        samplingPeriodNs = mSensorInfo.minDelay * 1000ll;
+    } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000ll) {
+        samplingPeriodNs = mSensorInfo.maxDelay * 1000ll;
     }
 
     if (mSamplingPeriodNs != samplingPeriodNs) {
@@ -133,6 +133,11 @@
 }
 
 std::vector<Event> Sensor::readEvents() {
+    // For an accelerometer sensor type, default the z-direction
+    // value to -9.8
+    float zValue = (mSensorInfo.type == SensorType::ACCELEROMETER)
+        ? -9.8 : 0.0;
+
     std::vector<Event> events;
     Event event;
     event.sensorHandle = mSensorInfo.sensorHandle;
@@ -140,7 +145,7 @@
     event.timestamp = ::android::elapsedRealtimeNano();
     event.u.vec3.x = 0;
     event.u.vec3.y = 0;
-    event.u.vec3.z = 0;
+    event.u.vec3.z = zValue;
     event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
     events.push_back(event);
     return events;
@@ -330,25 +335,6 @@
     mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
 };
 
-DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
-    : OnChangeSensor(callback) {
-    mSensorInfo.sensorHandle = sensorHandle;
-    mSensorInfo.name = "Device Temp Sensor";
-    mSensorInfo.vendor = "Vendor String";
-    mSensorInfo.version = 1;
-    mSensorInfo.type = SensorType::TEMPERATURE;
-    mSensorInfo.typeAsString = "";
-    mSensorInfo.maxRange = 80.0f;
-    mSensorInfo.resolution = 0.01f;
-    mSensorInfo.power = 0.001f;
-    mSensorInfo.minDelay = 40 * 1000;  // microseconds
-    mSensorInfo.maxDelay = kDefaultMaxDelayUs;
-    mSensorInfo.fifoReservedEventCount = 0;
-    mSensorInfo.fifoMaxEventCount = 0;
-    mSensorInfo.requiredPermission = "";
-    mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
-}
-
 RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
                                                ISensorsEventCallback* callback)
     : OnChangeSensor(callback) {
diff --git a/sensors/common/default/2.X/Sensor.h b/sensors/common/default/2.X/Sensor.h
index 2f8a143..a792797 100644
--- a/sensors/common/default/2.X/Sensor.h
+++ b/sensors/common/default/2.X/Sensor.h
@@ -32,7 +32,7 @@
 namespace V2_X {
 namespace implementation {
 
-static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000;
+static constexpr int32_t kDefaultMaxDelayUs = 10 * 1000 * 1000;
 
 class ISensorsEventCallback {
   public:
@@ -54,7 +54,7 @@
     virtual ~Sensor();
 
     const SensorInfo& getSensorInfo() const;
-    void batch(int32_t samplingPeriodNs);
+    void batch(int64_t samplingPeriodNs);
     virtual void activate(bool enable);
     Result flush();
 
@@ -113,11 +113,6 @@
     AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
 };
 
-class DeviceTempSensor : public OnChangeSensor {
-  public:
-    DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
 class PressureSensor : public Sensor {
   public:
     PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
diff --git a/sensors/common/default/2.X/Sensors.h b/sensors/common/default/2.X/Sensors.h
index ee8240d..8969c0f 100644
--- a/sensors/common/default/2.X/Sensors.h
+++ b/sensors/common/default/2.X/Sensors.h
@@ -64,7 +64,6 @@
         AddSensor<AccelSensor>();
         AddSensor<GyroSensor>();
         AddSensor<AmbientTempSensor>();
-        AddSensor<DeviceTempSensor>();
         AddSensor<PressureSensor>();
         AddSensor<MagnetometerSensor>();
         AddSensor<LightSensor>();
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
index 1efd971..69debb6 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
@@ -71,9 +71,10 @@
     return mSensorInfo;
 }
 
-void Sensor::batch(int32_t samplingPeriodNs) {
-    samplingPeriodNs =
-            std::clamp(samplingPeriodNs, mSensorInfo.minDelay * 1000, mSensorInfo.maxDelay * 1000);
+void Sensor::batch(int64_t samplingPeriodNs) {
+    samplingPeriodNs = std::clamp(samplingPeriodNs,
+                                  static_cast<int64_t>(mSensorInfo.minDelay) * 1000,
+                                  static_cast<int64_t>(mSensorInfo.maxDelay) * 1000);
 
     if (mSamplingPeriodNs != samplingPeriodNs) {
         mSamplingPeriodNs = samplingPeriodNs;
@@ -323,17 +324,6 @@
     mSensorInfo.minDelay = 40 * 1000;  // microseconds
 }
 
-DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
-    : ContinuousSensor(sensorHandle, callback) {
-    mSensorInfo.name = "Device Temp Sensor";
-    mSensorInfo.type = SensorType::TEMPERATURE;
-    mSensorInfo.typeAsString = SENSOR_STRING_TYPE_TEMPERATURE;
-    mSensorInfo.maxRange = 80.0f;
-    mSensorInfo.resolution = 0.01f;
-    mSensorInfo.power = 0.001f;
-    mSensorInfo.minDelay = 40 * 1000;  // microseconds
-}
-
 RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
                                                ISensorsEventCallback* callback)
     : OnChangeSensor(sensorHandle, callback) {
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
index 5cf9f83..08c8647 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
@@ -49,7 +49,7 @@
     virtual ~Sensor();
 
     const SensorInfo& getSensorInfo() const;
-    void batch(int32_t samplingPeriodNs);
+    void batch(int64_t samplingPeriodNs);
     virtual void activate(bool enable);
     Result flush();
 
@@ -114,11 +114,6 @@
     std::vector<Event> readEvents() override;
 };
 
-class DeviceTempSensor : public ContinuousSensor {
-  public:
-    DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
 class PressureSensor : public ContinuousSensor {
   public:
     PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
index 1a78e84..353563c 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
@@ -206,7 +206,6 @@
         ISensorsSubHalBase::AddSensor<GyroSensor>();
         ISensorsSubHalBase::AddSensor<MagnetometerSensor>();
         ISensorsSubHalBase::AddSensor<PressureSensor>();
-        ISensorsSubHalBase::AddSensor<DeviceTempSensor>();
     }
 };
 
@@ -231,7 +230,6 @@
         ISensorsSubHalBase::AddSensor<GyroSensor>();
         ISensorsSubHalBase::AddSensor<MagnetometerSensor>();
         ISensorsSubHalBase::AddSensor<PressureSensor>();
-        ISensorsSubHalBase::AddSensor<DeviceTempSensor>();
         ISensorsSubHalBase::AddSensor<AmbientTempSensor>();
         ISensorsSubHalBase::AddSensor<LightSensor>();
         ISensorsSubHalBase::AddSensor<ProximitySensor>();
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index e674ddb..f857827 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -845,7 +845,11 @@
         std::shared_ptr<SensorsTestSharedMemory<SensorTypeVersion, EventType>> mem,
         int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) {
     char* buffer = mem->getBuffer();
-    memset(buffer, 0xff, mem->getSize());
+    size_t size = mem->getSize();
+
+    if (supportsSharedMemType) {
+        memset(buffer, 0xff, size);
+    }
 
     registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) {
         if (supportsSharedMemType) {
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index 03bec87..a8e1996 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -109,7 +109,6 @@
         case SensorTypeT::MAGNETIC_FIELD:
         case SensorTypeT::ORIENTATION:
         case SensorTypeT::PRESSURE:
-        case SensorTypeT::TEMPERATURE:
         case SensorTypeT::GRAVITY:
         case SensorTypeT::LINEAR_ACCELERATION:
         case SensorTypeT::ROTATION_VECTOR:
@@ -145,6 +144,10 @@
         case SensorTypeT::DYNAMIC_SENSOR_META:
             return SensorFlagBits::SPECIAL_REPORTING_MODE;
 
+        case SensorTypeT::TEMPERATURE:
+            ALOGW("Device temperature sensor is deprecated, ignoring for test");
+            return (SensorFlagBits)-1;
+
         default:
             ALOGW("Type %d is not implemented in expectedReportModeForType", (int)type);
             return (SensorFlagBits)-1;
@@ -334,7 +337,7 @@
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
         events1 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
 
-        // second collection, without stop sensor
+        // second collection, without stopping the sensor
         ASSERT_EQ(batch(handle, secondCollectionPeriod, batchingPeriodInNs), Result::OK);
 
         usleep(500000);  // sleep 0.5 sec to wait for change rate to happen
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index ed40d25..80f7727 100644
--- a/tests/extension/vibrator/aidl/default/Android.bp
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -19,7 +19,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.vibrator-ndk_platform",
-        "android.hardware.tests.extension.vibrator-ndk_platform",
+        "android.hardware.vibrator-unstable-ndk_platform",
+        "android.hardware.tests.extension.vibrator-unstable-ndk_platform",
     ],
 }
diff --git a/usb/gadget/1.2/Android.bp b/usb/gadget/1.2/Android.bp
new file mode 100644
index 0000000..386f00f
--- /dev/null
+++ b/usb/gadget/1.2/Android.bp
@@ -0,0 +1,17 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.usb.gadget@1.2",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "IUsbGadget.hal",
+        "IUsbGadgetCallback.hal",
+    ],
+    interfaces: [
+        "android.hardware.usb.gadget@1.0",
+        "android.hardware.usb.gadget@1.1",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/usb/gadget/1.2/IUsbGadget.hal b/usb/gadget/1.2/IUsbGadget.hal
new file mode 100644
index 0000000..5c6e930
--- /dev/null
+++ b/usb/gadget/1.2/IUsbGadget.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.usb.gadget@1.2;
+
+import IUsbGadgetCallback;
+import android.hardware.usb.gadget@1.1::IUsbGadget;
+
+interface IUsbGadget extends @1.1::IUsbGadget {
+    /**
+     * The function is used to query current USB speed.
+     *
+     * @param callback IUsbGadgetCallback::getUsbSpeedCb used to propagate
+     *                 current USB speed.
+     */
+    oneway getUsbSpeed(IUsbGadgetCallback callback);
+};
diff --git a/usb/gadget/1.2/IUsbGadgetCallback.hal b/usb/gadget/1.2/IUsbGadgetCallback.hal
new file mode 100644
index 0000000..4170573
--- /dev/null
+++ b/usb/gadget/1.2/IUsbGadgetCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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.usb.gadget@1.2;
+
+import UsbSpeed;
+import android.hardware.usb.gadget@1.0::IUsbGadgetCallback;
+
+interface IUsbGadgetCallback extends @1.0::IUsbGadgetCallback {
+    /**
+     * Used to convey the current USB speed to the caller.
+     * Must be called either when USB state changes due to USB enumeration or
+     * when caller requested for USB speed through getUsbSpeed.
+     *
+     * @param speed USB Speed defined by UsbSpeed showed current USB
+     *              connection speed.
+     */
+    oneway getUsbSpeedCb(UsbSpeed speed);
+};
+
diff --git a/usb/gadget/1.2/default/Android.bp b/usb/gadget/1.2/default/Android.bp
new file mode 100644
index 0000000..9c73a59
--- /dev/null
+++ b/usb/gadget/1.2/default/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_binary {
+    name: "android.hardware.usb.gadget@1.2-service",
+    defaults: ["hidl_defaults"],
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.usb.gadget@1.2-service.rc"],
+    vintf_fragments: ["android.hardware.usb.gadget@1.2-service.xml"],
+    vendor: true,
+    srcs: [
+        "service.cpp",
+        "UsbGadget.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.usb.gadget@1.0",
+        "android.hardware.usb.gadget@1.1",
+        "android.hardware.usb.gadget@1.2",
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["libusbconfigfs-2"],
+}
diff --git a/usb/gadget/1.2/default/UsbGadget.cpp b/usb/gadget/1.2/default/UsbGadget.cpp
new file mode 100644
index 0000000..8dd229e
--- /dev/null
+++ b/usb/gadget/1.2/default/UsbGadget.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget@1.2-service"
+
+#include "UsbGadget.h"
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+namespace V1_2 {
+namespace implementation {
+
+UsbGadget::UsbGadget() {
+    if (access(OS_DESC_PATH, R_OK) != 0) {
+        ALOGE("configfs setup not done yet");
+        abort();
+    }
+}
+
+void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) {
+    UsbGadget* gadget = (UsbGadget*)payload;
+    gadget->mCurrentUsbFunctionsApplied = functionsApplied;
+}
+
+Return<void> UsbGadget::getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback>& callback) {
+    Return<void> ret = callback->getCurrentUsbFunctionsCb(
+            mCurrentUsbFunctions, mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED
+                                                              : Status::FUNCTIONS_NOT_APPLIED);
+    if (!ret.isOk()) ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str());
+
+    return Void();
+}
+
+Return<void> UsbGadget::getUsbSpeed(const sp<V1_2::IUsbGadgetCallback>& callback) {
+    std::string current_speed;
+    if (ReadFileToString(SPEED_PATH, &current_speed)) {
+        current_speed = Trim(current_speed);
+        ALOGI("current USB speed is %s", current_speed.c_str());
+        if (current_speed == "low-speed")
+            mUsbSpeed = UsbSpeed::LOWSPEED;
+        else if (current_speed == "full-speed")
+            mUsbSpeed = UsbSpeed::FULLSPEED;
+        else if (current_speed == "high-speed")
+            mUsbSpeed = UsbSpeed::HIGHSPEED;
+        else if (current_speed == "super-speed")
+            mUsbSpeed = UsbSpeed::SUPERSPEED;
+        else if (current_speed == "super-speed-plus")
+            mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
+        else if (current_speed == "UNKNOWN")
+            mUsbSpeed = UsbSpeed::UNKNOWN;
+        else {
+            /**
+             * This part is used for USB4 or reserved speed.
+             *
+             * If reserved speed is detected, it needs to convert to other speeds.
+             * For example:
+             * If the bandwidth of new speed is 7G, adding new if
+             * statement and set mUsbSpeed to SUPERSPEED.
+             * If the bandwidth of new speed is 80G, adding new if
+             * statement and set mUsbSpeed to USB4_GEN3_40Gb.
+             */
+            mUsbSpeed = UsbSpeed::RESERVED_SPEED;
+        }
+    } else {
+        ALOGE("Fail to read current speed");
+        mUsbSpeed = UsbSpeed::UNKNOWN;
+    }
+
+    if (callback) {
+        Return<void> ret = callback->getUsbSpeedCb(mUsbSpeed);
+
+        if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.description().c_str());
+    }
+
+    return Void();
+}
+
+V1_0::Status UsbGadget::tearDownGadget() {
+    if (resetGadget() != V1_0::Status::SUCCESS) return V1_0::Status::ERROR;
+
+    if (monitorFfs.isMonitorRunning()) {
+        monitorFfs.reset();
+    } else {
+        ALOGI("mMonitor not running");
+    }
+    return V1_0::Status::SUCCESS;
+}
+
+Return<Status> UsbGadget::reset() {
+    if (!WriteStringToFile("none", PULLUP_PATH)) {
+        ALOGI("Gadget cannot be pulled down");
+        return Status::ERROR;
+    }
+
+    usleep(kDisconnectWaitUs);
+
+    if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
+        ALOGI("Gadget cannot be pulled up");
+        return Status::ERROR;
+    }
+
+    return Status::SUCCESS;
+}
+
+static V1_0::Status validateAndSetVidPid(uint64_t functions) {
+    V1_0::Status ret = V1_0::Status::SUCCESS;
+
+    switch (functions) {
+        case static_cast<uint64_t>(V1_2::GadgetFunction::MTP):
+            ret = setVidPid("0x18d1", "0x4ee1");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MTP:
+            ret = setVidPid("0x18d1", "0x4ee2");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::RNDIS):
+            ret = setVidPid("0x18d1", "0x4ee3");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::RNDIS:
+            ret = setVidPid("0x18d1", "0x4ee4");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::PTP):
+            ret = setVidPid("0x18d1", "0x4ee5");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::PTP:
+            ret = setVidPid("0x18d1", "0x4ee6");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::ADB):
+            ret = setVidPid("0x18d1", "0x4ee7");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::MIDI):
+            ret = setVidPid("0x18d1", "0x4ee8");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MIDI:
+            ret = setVidPid("0x18d1", "0x4ee9");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::NCM):
+            ret = setVidPid("0x18d1", "0x4eeb");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::NCM:
+            ret = setVidPid("0x18d1", "0x4eec");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::ACCESSORY):
+            ret = setVidPid("0x18d1", "0x2d00");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY:
+            ret = setVidPid("0x18d1", "0x2d01");
+            break;
+        case static_cast<uint64_t>(V1_2::GadgetFunction::AUDIO_SOURCE):
+            ret = setVidPid("0x18d1", "0x2d02");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::AUDIO_SOURCE:
+            ret = setVidPid("0x18d1", "0x2d03");
+            break;
+        case V1_2::GadgetFunction::ACCESSORY | V1_2::GadgetFunction::AUDIO_SOURCE:
+            ret = setVidPid("0x18d1", "0x2d04");
+            break;
+        case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY |
+                V1_2::GadgetFunction::AUDIO_SOURCE:
+            ret = setVidPid("0x18d1", "0x2d05");
+            break;
+        default:
+            ALOGE("Combination not supported");
+            ret = V1_0::Status::CONFIGURATION_NOT_SUPPORTED;
+    }
+    return ret;
+}
+
+V1_0::Status UsbGadget::setupFunctions(uint64_t functions,
+                                       const sp<V1_0::IUsbGadgetCallback>& callback,
+                                       uint64_t timeout) {
+    bool ffsEnabled = false;
+    int i = 0;
+
+    if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) !=
+        V1_0::Status::SUCCESS)
+        return V1_0::Status::ERROR;
+
+    if ((functions & V1_2::GadgetFunction::ADB) != 0) {
+        ffsEnabled = true;
+        if (addAdb(&monitorFfs, &i) != V1_0::Status::SUCCESS) return V1_0::Status::ERROR;
+    }
+
+    // Pull up the gadget right away when there are no ffs functions.
+    if (!ffsEnabled) {
+        if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) return V1_0::Status::ERROR;
+        mCurrentUsbFunctionsApplied = true;
+        if (callback) callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS);
+        return V1_0::Status::SUCCESS;
+    }
+
+    monitorFfs.registerFunctionsAppliedCallback(&currentFunctionsAppliedCallback, this);
+    // Monitors the ffs paths to pull up the gadget when descriptors are written.
+    // Also takes of the pulling up the gadget again if the userspace process
+    // dies and restarts.
+    monitorFfs.startMonitor();
+
+    if (kDebug) ALOGI("Mainthread in Cv");
+
+    if (callback) {
+        bool pullup = monitorFfs.waitForPullUp(timeout);
+        Return<void> ret = callback->setCurrentUsbFunctionsCb(
+                functions, pullup ? V1_0::Status::SUCCESS : V1_0::Status::ERROR);
+        if (!ret.isOk()) ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str());
+    }
+
+    return V1_0::Status::SUCCESS;
+}
+
+Return<void> UsbGadget::setCurrentUsbFunctions(uint64_t functions,
+                                               const sp<V1_0::IUsbGadgetCallback>& callback,
+                                               uint64_t timeout) {
+    std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
+
+    mCurrentUsbFunctions = functions;
+    mCurrentUsbFunctionsApplied = false;
+
+    // Unlink the gadget and stop the monitor if running.
+    V1_0::Status status = tearDownGadget();
+    if (status != V1_0::Status::SUCCESS) {
+        goto error;
+    }
+
+    ALOGI("Returned from tearDown gadget");
+
+    // Leave the gadget pulled down to give time for the host to sense disconnect.
+    usleep(kDisconnectWaitUs);
+
+    if (functions == static_cast<uint64_t>(V1_2::GadgetFunction::NONE)) {
+        if (callback == NULL) return Void();
+        Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS);
+        if (!ret.isOk())
+            ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
+        return Void();
+    }
+
+    status = validateAndSetVidPid(functions);
+
+    if (status != V1_0::Status::SUCCESS) {
+        goto error;
+    }
+
+    status = setupFunctions(functions, callback, timeout);
+    if (status != V1_0::Status::SUCCESS) {
+        goto error;
+    }
+
+    ALOGI("Usb Gadget setcurrent functions called successfully");
+    return Void();
+
+error:
+    ALOGI("Usb Gadget setcurrent functions failed");
+    if (callback == NULL) return Void();
+    Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status);
+    if (!ret.isOk())
+        ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
+    return Void();
+}
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
diff --git a/usb/gadget/1.2/default/UsbGadget.h b/usb/gadget/1.2/default/UsbGadget.h
new file mode 100644
index 0000000..12ad8ee
--- /dev/null
+++ b/usb/gadget/1.2/default/UsbGadget.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H
+#define ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H
+
+#include <UsbGadgetCommon.h>
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/usb/gadget/1.2/IUsbGadget.h>
+#include <android/hardware/usb/gadget/1.2/types.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::base::GetProperty;
+using ::android::base::ReadFileToString;
+using ::android::base::SetProperty;
+using ::android::base::Trim;
+using ::android::base::unique_fd;
+using ::android::base::WriteStringToFile;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::usb::gadget::addAdb;
+using ::android::hardware::usb::gadget::addEpollFd;
+using ::android::hardware::usb::gadget::getVendorFunctions;
+using ::android::hardware::usb::gadget::kDebug;
+using ::android::hardware::usb::gadget::kDisconnectWaitUs;
+using ::android::hardware::usb::gadget::linkFunction;
+using ::android::hardware::usb::gadget::MonitorFfs;
+using ::android::hardware::usb::gadget::resetGadget;
+using ::android::hardware::usb::gadget::setVidPid;
+using ::android::hardware::usb::gadget::unlinkFunctions;
+using ::std::string;
+
+constexpr char kGadgetName[] = "11110000.usb";
+static MonitorFfs monitorFfs(kGadgetName);
+
+#define UDC_PATH "/sys/class/udc/11110000.usb/"
+#define SPEED_PATH UDC_PATH "current_speed"
+
+struct UsbGadget : public IUsbGadget {
+    UsbGadget();
+
+    // Makes sure that only one request is processed at a time.
+    std::mutex mLockSetCurrentFunction;
+    uint64_t mCurrentUsbFunctions;
+    bool mCurrentUsbFunctionsApplied;
+    UsbSpeed mUsbSpeed;
+
+    Return<void> setCurrentUsbFunctions(uint64_t functions,
+                                        const sp<V1_0::IUsbGadgetCallback>& callback,
+                                        uint64_t timeout) override;
+
+    Return<void> getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback>& callback) override;
+
+    Return<Status> reset() override;
+
+    Return<void> getUsbSpeed(const sp<V1_2::IUsbGadgetCallback>& callback) override;
+
+  private:
+    V1_0::Status tearDownGadget();
+    V1_0::Status setupFunctions(uint64_t functions, const sp<V1_0::IUsbGadgetCallback>& callback,
+                                uint64_t timeout);
+};
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_USB_V1_2_USBGADGET_H
diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc
new file mode 100644
index 0000000..650b085
--- /dev/null
+++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc
@@ -0,0 +1,7 @@
+service vendor.usb-gadget-hal-1-2 /vendor/bin/hw/android.hardware.usb.gadget@1.2-service
+    interface android.hardware.usb.gadget@1.0::IUsbGadget default
+    interface android.hardware.usb.gadget@1.1::IUsbGadget default
+    interface android.hardware.usb.gadget@1.2::IUsbGadget default
+    class hal
+    user system
+    group system shell mtp
diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml
new file mode 100644
index 0000000..8557f6f
--- /dev/null
+++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.usb.gadget</name>
+        <transport>hwbinder</transport>
+        <version>1.2</version>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/usb/gadget/1.2/default/lib/Android.bp b/usb/gadget/1.2/default/lib/Android.bp
new file mode 100644
index 0000000..727de13
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_library_static {
+    name: "libusbconfigfs-2",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+
+    srcs: [
+        "UsbGadgetUtils.cpp",
+        "MonitorFfs.cpp",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "android.hardware.usb.gadget@1.0",
+        "android.hardware.usb.gadget@1.1",
+        "android.hardware.usb.gadget@1.2",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libutils",
+    ],
+}
diff --git a/usb/gadget/1.2/default/lib/MonitorFfs.cpp b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
new file mode 100644
index 0000000..0cdf038
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "libusbconfigfs"
+
+#include "include/UsbGadgetCommon.h"
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+static volatile bool gadgetPullup;
+
+MonitorFfs::MonitorFfs(const char* const gadget)
+    : mWatchFd(),
+      mEndpointList(),
+      mLock(),
+      mCv(),
+      mLockFd(),
+      mCurrentUsbFunctionsApplied(false),
+      mMonitor(),
+      mCallback(NULL),
+      mPayload(NULL),
+      mGadgetName(gadget),
+      mMonitorRunning(false) {
+    unique_fd eventFd(eventfd(0, 0));
+    if (eventFd == -1) {
+        ALOGE("mEventFd failed to create %d", errno);
+        abort();
+    }
+
+    unique_fd epollFd(epoll_create(2));
+    if (epollFd == -1) {
+        ALOGE("mEpollFd failed to create %d", errno);
+        abort();
+    }
+
+    unique_fd inotifyFd(inotify_init());
+    if (inotifyFd < 0) {
+        ALOGE("inotify init failed");
+        abort();
+    }
+
+    if (addEpollFd(epollFd, inotifyFd) == -1) abort();
+
+    if (addEpollFd(epollFd, eventFd) == -1) abort();
+
+    mEpollFd = move(epollFd);
+    mInotifyFd = move(inotifyFd);
+    mEventFd = move(eventFd);
+    gadgetPullup = false;
+}
+
+static void displayInotifyEvent(struct inotify_event* i) {
+    ALOGE("    wd =%2d; ", i->wd);
+    if (i->cookie > 0) ALOGE("cookie =%4d; ", i->cookie);
+
+    ALOGE("mask = ");
+    if (i->mask & IN_ACCESS) ALOGE("IN_ACCESS ");
+    if (i->mask & IN_ATTRIB) ALOGE("IN_ATTRIB ");
+    if (i->mask & IN_CLOSE_NOWRITE) ALOGE("IN_CLOSE_NOWRITE ");
+    if (i->mask & IN_CLOSE_WRITE) ALOGE("IN_CLOSE_WRITE ");
+    if (i->mask & IN_CREATE) ALOGE("IN_CREATE ");
+    if (i->mask & IN_DELETE) ALOGE("IN_DELETE ");
+    if (i->mask & IN_DELETE_SELF) ALOGE("IN_DELETE_SELF ");
+    if (i->mask & IN_IGNORED) ALOGE("IN_IGNORED ");
+    if (i->mask & IN_ISDIR) ALOGE("IN_ISDIR ");
+    if (i->mask & IN_MODIFY) ALOGE("IN_MODIFY ");
+    if (i->mask & IN_MOVE_SELF) ALOGE("IN_MOVE_SELF ");
+    if (i->mask & IN_MOVED_FROM) ALOGE("IN_MOVED_FROM ");
+    if (i->mask & IN_MOVED_TO) ALOGE("IN_MOVED_TO ");
+    if (i->mask & IN_OPEN) ALOGE("IN_OPEN ");
+    if (i->mask & IN_Q_OVERFLOW) ALOGE("IN_Q_OVERFLOW ");
+    if (i->mask & IN_UNMOUNT) ALOGE("IN_UNMOUNT ");
+    ALOGE("\n");
+
+    if (i->len > 0) ALOGE("        name = %s\n", i->name);
+}
+
+void* MonitorFfs::startMonitorFd(void* param) {
+    MonitorFfs* monitorFfs = (MonitorFfs*)param;
+    char buf[kBufferSize];
+    bool writeUdc = true, stopMonitor = false;
+    struct epoll_event events[kEpollEvents];
+    steady_clock::time_point disconnect;
+
+    bool descriptorWritten = true;
+    for (int i = 0; i < static_cast<int>(monitorFfs->mEndpointList.size()); i++) {
+        if (access(monitorFfs->mEndpointList.at(i).c_str(), R_OK)) {
+            descriptorWritten = false;
+            break;
+        }
+    }
+
+    // notify here if the endpoints are already present.
+    if (descriptorWritten) {
+        usleep(kPullUpDelay);
+        if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) {
+            lock_guard<mutex> lock(monitorFfs->mLock);
+            monitorFfs->mCurrentUsbFunctionsApplied = true;
+            monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied, monitorFfs->mPayload);
+            gadgetPullup = true;
+            writeUdc = false;
+            ALOGI("GADGET pulled up");
+            monitorFfs->mCv.notify_all();
+        }
+    }
+
+    while (!stopMonitor) {
+        int nrEvents = epoll_wait(monitorFfs->mEpollFd, events, kEpollEvents, -1);
+
+        if (nrEvents <= 0) {
+            ALOGE("epoll wait did not return descriptor number");
+            continue;
+        }
+
+        for (int i = 0; i < nrEvents; i++) {
+            ALOGI("event=%u on fd=%d\n", events[i].events, events[i].data.fd);
+
+            if (events[i].data.fd == monitorFfs->mInotifyFd) {
+                // Process all of the events in buffer returned by read().
+                int numRead = read(monitorFfs->mInotifyFd, buf, kBufferSize);
+                for (char* p = buf; p < buf + numRead;) {
+                    struct inotify_event* event = (struct inotify_event*)p;
+                    if (kDebug) displayInotifyEvent(event);
+
+                    p += sizeof(struct inotify_event) + event->len;
+
+                    bool descriptorPresent = true;
+                    for (int j = 0; j < static_cast<int>(monitorFfs->mEndpointList.size()); j++) {
+                        if (access(monitorFfs->mEndpointList.at(j).c_str(), R_OK)) {
+                            if (kDebug) ALOGI("%s absent", monitorFfs->mEndpointList.at(j).c_str());
+                            descriptorPresent = false;
+                            break;
+                        }
+                    }
+
+                    if (!descriptorPresent && !writeUdc) {
+                        if (kDebug) ALOGI("endpoints not up");
+                        writeUdc = true;
+                        disconnect = std::chrono::steady_clock::now();
+                    } else if (descriptorPresent && writeUdc) {
+                        steady_clock::time_point temp = steady_clock::now();
+
+                        if (std::chrono::duration_cast<microseconds>(temp - disconnect).count() <
+                            kPullUpDelay)
+                            usleep(kPullUpDelay);
+
+                        if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) {
+                            lock_guard<mutex> lock(monitorFfs->mLock);
+                            monitorFfs->mCurrentUsbFunctionsApplied = true;
+                            monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied,
+                                                  monitorFfs->mPayload);
+                            ALOGI("GADGET pulled up");
+                            writeUdc = false;
+                            gadgetPullup = true;
+                            // notify the main thread to signal userspace.
+                            monitorFfs->mCv.notify_all();
+                        }
+                    }
+                }
+            } else {
+                uint64_t flag;
+                read(monitorFfs->mEventFd, &flag, sizeof(flag));
+                if (flag == 100) {
+                    stopMonitor = true;
+                    break;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+void MonitorFfs::reset() {
+    lock_guard<mutex> lock(mLockFd);
+    uint64_t flag = 100;
+    unsigned long ret;
+
+    if (mMonitorRunning) {
+        // Stop the monitor thread by writing into signal fd.
+        ret = TEMP_FAILURE_RETRY(write(mEventFd, &flag, sizeof(flag)));
+        if (ret < 0) ALOGE("Error writing eventfd errno=%d", errno);
+
+        ALOGI("mMonitor signalled to exit");
+        mMonitor->join();
+        ALOGI("mMonitor destroyed");
+        mMonitorRunning = false;
+    }
+
+    for (std::vector<int>::size_type i = 0; i != mWatchFd.size(); i++)
+        inotify_rm_watch(mInotifyFd, mWatchFd[i]);
+
+    mEndpointList.clear();
+    gadgetPullup = false;
+    mCallback = NULL;
+    mPayload = NULL;
+}
+
+bool MonitorFfs::startMonitor() {
+    mMonitor = unique_ptr<thread>(new thread(this->startMonitorFd, this));
+    mMonitorRunning = true;
+    return true;
+}
+
+bool MonitorFfs::isMonitorRunning() {
+    return mMonitorRunning;
+}
+
+bool MonitorFfs::waitForPullUp(int timeout_ms) {
+    std::unique_lock<std::mutex> lk(mLock);
+
+    if (gadgetPullup) return true;
+
+    if (mCv.wait_for(lk, timeout_ms * 1ms, [] { return gadgetPullup; })) {
+        ALOGI("monitorFfs signalled true");
+        return true;
+    } else {
+        ALOGI("monitorFfs signalled error");
+        // continue monitoring as the descriptors might be written at a later
+        // point.
+        return false;
+    }
+}
+
+bool MonitorFfs::addInotifyFd(string fd) {
+    lock_guard<mutex> lock(mLockFd);
+    int wfd;
+
+    wfd = inotify_add_watch(mInotifyFd, fd.c_str(), IN_ALL_EVENTS);
+    if (wfd == -1)
+        return false;
+    else
+        mWatchFd.push_back(wfd);
+
+    return true;
+}
+
+void MonitorFfs::addEndPoint(string ep) {
+    lock_guard<mutex> lock(mLockFd);
+
+    mEndpointList.push_back(ep);
+}
+
+void MonitorFfs::registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied,
+                                                                   void* payload),
+                                                  void* payload) {
+    mCallback = callback;
+    mPayload = payload;
+}
+
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
new file mode 100644
index 0000000..8986556
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "libusbconfigfs"
+
+#include "include/UsbGadgetCommon.h"
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+int unlinkFunctions(const char* path) {
+    DIR* config = opendir(path);
+    struct dirent* function;
+    char filepath[kMaxFilePathLength];
+    int ret = 0;
+
+    if (config == NULL) return -1;
+
+    // d_type does not seems to be supported in /config
+    // so filtering by name.
+    while (((function = readdir(config)) != NULL)) {
+        if ((strstr(function->d_name, FUNCTION_NAME) == NULL)) continue;
+        // build the path for each file in the folder.
+        sprintf(filepath, "%s/%s", path, function->d_name);
+        ret = remove(filepath);
+        if (ret) {
+            ALOGE("Unable  remove file %s errno:%d", filepath, errno);
+            break;
+        }
+    }
+
+    closedir(config);
+    return ret;
+}
+
+int addEpollFd(const unique_fd& epfd, const unique_fd& fd) {
+    struct epoll_event event;
+    int ret;
+
+    event.data.fd = fd;
+    event.events = EPOLLIN;
+
+    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
+    if (ret) ALOGE("epoll_ctl error %d", errno);
+
+    return ret;
+}
+
+int linkFunction(const char* function, int index) {
+    char functionPath[kMaxFilePathLength];
+    char link[kMaxFilePathLength];
+
+    sprintf(functionPath, "%s%s", FUNCTIONS_PATH, function);
+    sprintf(link, "%s%d", FUNCTION_PATH, index);
+    if (symlink(functionPath, link)) {
+        ALOGE("Cannot create symlink %s -> %s errno:%d", link, functionPath, errno);
+        return -1;
+    }
+    return 0;
+}
+
+Status setVidPid(const char* vid, const char* pid) {
+    if (!WriteStringToFile(vid, VENDOR_ID_PATH)) return Status::ERROR;
+
+    if (!WriteStringToFile(pid, PRODUCT_ID_PATH)) return Status::ERROR;
+
+    return Status::SUCCESS;
+}
+
+std::string getVendorFunctions() {
+    if (GetProperty(kBuildType, "") == "user") return "user";
+
+    std::string bootMode = GetProperty(PERSISTENT_BOOT_MODE, "");
+    std::string persistVendorFunctions = GetProperty(kPersistentVendorConfig, "");
+    std::string vendorFunctions = GetProperty(kVendorConfig, "");
+    std::string ret = "";
+
+    if (vendorFunctions != "") {
+        ret = vendorFunctions;
+    } else if (bootMode == "usbradio" || bootMode == "factory" || bootMode == "ffbm-00" ||
+               bootMode == "ffbm-01") {
+        if (persistVendorFunctions != "")
+            ret = persistVendorFunctions;
+        else
+            ret = "diag";
+        // vendor.usb.config will reflect the current configured functions
+        SetProperty(kVendorConfig, ret);
+    }
+
+    return ret;
+}
+
+Status resetGadget() {
+    ALOGI("setCurrentUsbFunctions None");
+
+    if (!WriteStringToFile("none", PULLUP_PATH)) ALOGI("Gadget cannot be pulled down");
+
+    if (!WriteStringToFile("0", DEVICE_CLASS_PATH)) return Status::ERROR;
+
+    if (!WriteStringToFile("0", DEVICE_SUB_CLASS_PATH)) return Status::ERROR;
+
+    if (!WriteStringToFile("0", DEVICE_PROTOCOL_PATH)) return Status::ERROR;
+
+    if (!WriteStringToFile("0", DESC_USE_PATH)) return Status::ERROR;
+
+    if (unlinkFunctions(CONFIG_PATH)) return Status::ERROR;
+
+    return Status::SUCCESS;
+}
+
+Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled,
+                                  int* functionCount) {
+    if (((functions & GadgetFunction::MTP) != 0)) {
+        *ffsEnabled = true;
+        ALOGI("setCurrentUsbFunctions mtp");
+        if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR;
+
+        if (!monitorFfs->addInotifyFd("/dev/usb-ffs/mtp/")) return Status::ERROR;
+
+        if (linkFunction("ffs.mtp", (*functionCount)++)) return Status::ERROR;
+
+        // Add endpoints to be monitored.
+        monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep1");
+        monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep2");
+        monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep3");
+    } else if (((functions & GadgetFunction::PTP) != 0)) {
+        *ffsEnabled = true;
+        ALOGI("setCurrentUsbFunctions ptp");
+        if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR;
+
+        if (!monitorFfs->addInotifyFd("/dev/usb-ffs/ptp/")) return Status::ERROR;
+
+        if (linkFunction("ffs.ptp", (*functionCount)++)) return Status::ERROR;
+
+        // Add endpoints to be monitored.
+        monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep1");
+        monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep2");
+        monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep3");
+    }
+
+    if ((functions & GadgetFunction::MIDI) != 0) {
+        ALOGI("setCurrentUsbFunctions MIDI");
+        if (linkFunction("midi.gs5", (*functionCount)++)) return Status::ERROR;
+    }
+
+    if ((functions & GadgetFunction::ACCESSORY) != 0) {
+        ALOGI("setCurrentUsbFunctions Accessory");
+        if (linkFunction("accessory.gs2", (*functionCount)++)) return Status::ERROR;
+    }
+
+    if ((functions & GadgetFunction::AUDIO_SOURCE) != 0) {
+        ALOGI("setCurrentUsbFunctions Audio Source");
+        if (linkFunction("audio_source.gs3", (*functionCount)++)) return Status::ERROR;
+    }
+
+    if ((functions & GadgetFunction::RNDIS) != 0) {
+        ALOGI("setCurrentUsbFunctions rndis");
+        if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR;
+        std::string rndisFunction = GetProperty(kVendorRndisConfig, "");
+        if (rndisFunction != "") {
+            if (linkFunction(rndisFunction.c_str(), (*functionCount)++)) return Status::ERROR;
+        } else {
+            // link gsi.rndis for older pixel projects
+            if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR;
+        }
+    }
+
+    if ((functions & GadgetFunction::NCM) != 0) {
+        ALOGI("setCurrentUsbFunctions ncm");
+        if (linkFunction("ncm.gs6", (*functionCount)++)) return Status::ERROR;
+    }
+
+    return Status::SUCCESS;
+}
+
+Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
+    ALOGI("setCurrentUsbFunctions Adb");
+    if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
+
+    if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
+    monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep1");
+    monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep2");
+    ALOGI("Service started");
+    return Status::SUCCESS;
+}
+
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
diff --git a/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h
new file mode 100644
index 0000000..18b8101
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef HARDWARE_USB_USBGADGETCOMMON_H
+#define HARDWARE_USB_USBGADGETCOMMON_H
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+
+#include <android/hardware/usb/gadget/1.2/IUsbGadget.h>
+#include <android/hardware/usb/gadget/1.2/types.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+constexpr int kBufferSize = 512;
+constexpr int kMaxFilePathLength = 256;
+constexpr int kEpollEvents = 10;
+constexpr bool kDebug = false;
+constexpr int kDisconnectWaitUs = 100000;
+constexpr int kPullUpDelay = 500000;
+constexpr int kShutdownMonitor = 100;
+
+constexpr char kBuildType[] = "ro.build.type";
+constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config";
+constexpr char kVendorConfig[] = "vendor.usb.config";
+constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.config";
+
+#define GADGET_PATH "/config/usb_gadget/g1/"
+#define PULLUP_PATH GADGET_PATH "UDC"
+#define PERSISTENT_BOOT_MODE "ro.bootmode"
+#define VENDOR_ID_PATH GADGET_PATH "idVendor"
+#define PRODUCT_ID_PATH GADGET_PATH "idProduct"
+#define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass"
+#define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass"
+#define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol"
+#define DESC_USE_PATH GADGET_PATH "os_desc/use"
+#define OS_DESC_PATH GADGET_PATH "os_desc/b.1"
+#define CONFIG_PATH GADGET_PATH "configs/b.1/"
+#define FUNCTIONS_PATH GADGET_PATH "functions/"
+#define FUNCTION_NAME "function"
+#define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME
+#define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis"
+
+using ::android::base::GetProperty;
+using ::android::base::SetProperty;
+using ::android::base::unique_fd;
+using ::android::base::WriteStringToFile;
+using ::android::hardware::usb::gadget::V1_0::Status;
+using ::android::hardware::usb::gadget::V1_2::GadgetFunction;
+
+using ::std::lock_guard;
+using ::std::move;
+using ::std::mutex;
+using ::std::string;
+using ::std::thread;
+using ::std::unique_ptr;
+using ::std::vector;
+using ::std::chrono::microseconds;
+using ::std::chrono::steady_clock;
+using ::std::literals::chrono_literals::operator""ms;
+
+// MonitorFfs automously manages gadget pullup by monitoring
+// the ep file status. Restarts the usb gadget when the ep
+// owner restarts.
+class MonitorFfs {
+  private:
+    // Monitors the endpoints Inotify events.
+    unique_fd mInotifyFd;
+    // Control pipe for shutting down the mMonitor thread.
+    // mMonitor exits when SHUTDOWN_MONITOR is written into
+    // mEventFd/
+    unique_fd mEventFd;
+    // Pools on mInotifyFd and mEventFd.
+    unique_fd mEpollFd;
+    vector<int> mWatchFd;
+
+    // Maintains the list of Endpoints.
+    vector<string> mEndpointList;
+    // protects the CV.
+    std::mutex mLock;
+    std::condition_variable mCv;
+    // protects mInotifyFd, mEpollFd.
+    std::mutex mLockFd;
+
+    // Flag to maintain the current status of gadget pullup.
+    bool mCurrentUsbFunctionsApplied;
+
+    // Thread object that executes the ep monitoring logic.
+    unique_ptr<thread> mMonitor;
+    // Callback to be invoked when gadget is pulled up.
+    void (*mCallback)(bool functionsApplied, void* payload);
+    void* mPayload;
+    // Name of the USB gadget. Used for pullup.
+    const char* const mGadgetName;
+    // Monitor State
+    bool mMonitorRunning;
+
+  public:
+    MonitorFfs(const char* const gadget);
+    // Inits all the UniqueFds.
+    void reset();
+    // Starts monitoring endpoints and pullup the gadget when
+    // the descriptors are written.
+    bool startMonitor();
+    // Waits for timeout_ms for gadget pull up to happen.
+    // Returns immediately if the gadget is already pulled up.
+    bool waitForPullUp(int timeout_ms);
+    // Adds the given fd to the watch list.
+    bool addInotifyFd(string fd);
+    // Adds the given endpoint to the watch list.
+    void addEndPoint(string ep);
+    // Registers the async callback from the caller to notify the caller
+    // when the gadget pull up happens.
+    void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void*(payload)),
+                                          void* payload);
+    bool isMonitorRunning();
+    // Ep monitoring and the gadget pull up logic.
+    static void* startMonitorFd(void* param);
+};
+
+//**************** Helper functions ************************//
+
+// Adds the given fd to the epollfd(epfd).
+int addEpollFd(const unique_fd& epfd, const unique_fd& fd);
+// Removes all the usb functions link in the specified path.
+int unlinkFunctions(const char* path);
+// Craetes a configfs link for the function.
+int linkFunction(const char* function, int index);
+// Sets the USB VID and PID.
+Status setVidPid(const char* vid, const char* pid);
+// Extracts vendor functions from the vendor init properties.
+std::string getVendorFunctions();
+// Adds Adb to the usb configuration.
+Status addAdb(MonitorFfs* monitorFfs, int* functionCount);
+// Adds all applicable generic android usb functions other than ADB.
+Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled,
+                                  int* functionCount);
+// Pulls down USB gadget.
+Status resetGadget();
+
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+#endif
diff --git a/usb/gadget/1.2/default/service.cpp b/usb/gadget/1.2/default/service.cpp
new file mode 100644
index 0000000..80c56a6
--- /dev/null
+++ b/usb/gadget/1.2/default/service.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget@1.2-service"
+
+#include <hidl/HidlTransportSupport.h>
+#include "UsbGadget.h"
+
+using android::sp;
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::usb::gadget::V1_2::IUsbGadget;
+using android::hardware::usb::gadget::V1_2::implementation::UsbGadget;
+
+using android::OK;
+using android::status_t;
+
+int main() {
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+    android::sp<IUsbGadget> service = new UsbGadget();
+
+    status_t status = service->registerAsService();
+
+    if (status != OK) {
+        ALOGE("Cannot register USB Gadget HAL service");
+        return 1;
+    }
+
+    ALOGI("USB Gadget HAL Ready.");
+    joinRpcThreadpool();
+    // Under noraml cases, execution will not reach this line.
+    ALOGI("USB Gadget HAL failed to join thread pool.");
+    return 1;
+}
diff --git a/usb/gadget/1.2/types.hal b/usb/gadget/1.2/types.hal
new file mode 100644
index 0000000..a5c079d
--- /dev/null
+++ b/usb/gadget/1.2/types.hal
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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.usb.gadget@1.2;
+
+import android.hardware.usb.gadget@1.0::GadgetFunction;
+
+enum GadgetFunction : @1.0::GadgetFunction {
+    /**
+     * NCM - NCM function.
+     */
+    NCM = 1 << 10,
+};
+
+enum UsbSpeed : uint32_t {
+    /**
+     * UNKNOWN - Not Connected or Unsupported Speed
+     */
+    UNKNOWN = -1,
+
+    /**
+     * USB Low Speed
+     */
+    LOWSPEED = 0,
+
+    /**
+     * USB Full Speed
+     */
+    FULLSPEED = 1,
+
+    /**
+     * USB High Speed
+     */
+    HIGHSPEED = 2,
+
+    /**
+     * USB Super Speed
+     */
+    SUPERSPEED = 3,
+
+    /**
+     * USB Super Speed 10Gbps
+     */
+    SUPERSPEED_10Gb = 4,
+
+    /**
+     * USB Super Speed 20Gbps
+     */
+    SUPERSPEED_20Gb = 5,
+
+    /**
+     * USB4 Gen2 x 1 (10Gbps)
+     */
+    USB4_GEN2_10Gb = 6,
+
+    /**
+     * USB4 Gen2 x 2 (20Gbps)
+     */
+    USB4_GEN2_20Gb = 7,
+
+    /**
+     * USB4 Gen3 x 1 (20Gbps)
+     */
+    USB4_GEN3_20Gb = 8,
+
+    /**
+     * USB4 Gen3 x 2 (40Gbps)
+     */
+    USB4_GEN3_40Gb = 9,
+
+    /**
+     * This is a suggestion if needed.
+     *
+     * Reserved Speed -- It is a newer speed after USB4 v1.0 announcement.
+     * If this speed is detected, the HAL implementation should convert current
+     * speed to above speeds which is lower and the closest.
+     */
+    RESERVED_SPEED = 64,
+};
diff --git a/vibrator/aidl/TEST_MAPPING b/vibrator/aidl/TEST_MAPPING
index 5ae32e7..2414b84 100644
--- a/vibrator/aidl/TEST_MAPPING
+++ b/vibrator/aidl/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "VtsHalVibratorTargetTest"
+    },
+    {
+      "name": "VtsHalVibratorManagerTargetTest"
     }
   ]
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
new file mode 100644
index 0000000..99cd448
--- /dev/null
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.vibrator;
+@VintfStability
+interface IVibratorManager {
+  int getCapabilities();
+  int[] getVibratorIds();
+  android.hardware.vibrator.IVibrator getVibrator(in int vibratorId);
+  void prepareSynced(in int[] vibratorIds);
+  void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback);
+  void cancelSynced();
+  const int CAP_SYNC = 1;
+  const int CAP_PREPARE_ON = 2;
+  const int CAP_PREPARE_PERFORM = 4;
+  const int CAP_PREPARE_COMPOSE = 8;
+  const int CAP_MIXED_TRIGGER_ON = 16;
+  const int CAP_MIXED_TRIGGER_PERFORM = 32;
+  const int CAP_MIXED_TRIGGER_COMPOSE = 64;
+  const int CAP_TRIGGER_CALLBACK = 128;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
new file mode 100644
index 0000000..eb5e9cc
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 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.vibrator;
+
+import android.hardware.vibrator.IVibrator;
+import android.hardware.vibrator.IVibratorCallback;
+
+@VintfStability
+interface IVibratorManager {
+    /**
+     * Whether prepare/trigger synced are supported.
+     */
+    const int CAP_SYNC = 1 << 0;
+    /**
+     * Whether IVibrator 'on' can be used with 'prepareSynced' function.
+     */
+    const int CAP_PREPARE_ON = 1 << 1;
+    /**
+     * Whether IVibrator 'perform' can be used with 'prepareSynced' function.
+     */
+    const int CAP_PREPARE_PERFORM = 1 << 2;
+    /**
+     * Whether IVibrator 'compose' can be used with 'prepareSynced' function.
+     */
+    const int CAP_PREPARE_COMPOSE = 1 << 3;
+    /**
+     * Whether IVibrator 'on' can be triggered with other functions in sync with 'triggerSynced'.
+     */
+    const int CAP_MIXED_TRIGGER_ON = 1 << 4;
+    /**
+     * Whether IVibrator 'perform' can be triggered with other functions in sync with 'triggerSynced'.
+     */
+    const int CAP_MIXED_TRIGGER_PERFORM = 1 << 5;
+    /**
+     * Whether IVibrator 'compose' can be triggered with other functions in sync with 'triggerSynced'.
+     */
+    const int CAP_MIXED_TRIGGER_COMPOSE = 1 << 6;
+    /**
+     * Whether on w/ IVibratorCallback can be used w/ 'trigerSynced' function.
+     */
+    const int CAP_TRIGGER_CALLBACK = 1 << 7;
+
+    /**
+     * Determine capabilities of the vibrator manager HAL (CAP_* mask)
+     */
+    int getCapabilities();
+
+    /**
+     * List the id of available vibrators. This result should be static and not change.
+     */
+    int[] getVibratorIds();
+
+    /**
+     * Return an available vibrator identified with given id.
+     */
+    IVibrator getVibrator(in int vibratorId);
+
+    /**
+     * Start preparation for a synced vibration
+     *
+     * This function must only be called after the previous synced vibration was triggered or
+     * canceled (through cancelSynced()).
+     *
+     * Doing this operation while any of the specified vibrators is already on is undefined behavior.
+     * Clients should explicitly call off in each vibrator.
+     *
+     * @param vibratorIds ids of the vibrators to play vibrations in sync.
+     */
+    void prepareSynced(in int[] vibratorIds);
+
+    /**
+     * Trigger a prepared synced vibration
+     *
+     * Trigger a previously-started preparation for synced vibration, if any.
+     * A callback is only expected to be supported when getCapabilities CAP_TRIGGER_CALLBACK
+     * is specified.
+     *
+     * @param callback A callback used to inform Frameworks of state change, if supported.
+     */
+    void triggerSynced(in IVibratorCallback callback);
+
+    /**
+     * Cancel preparation of synced vibration
+     *
+     * Cancel a previously-started preparation for synced vibration, if any.
+     */
+    void cancelSynced();
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index 9e6d9cf..f9d45bb 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -4,10 +4,13 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.vibrator-ndk_platform",
+        "android.hardware.vibrator-unstable-ndk_platform",
     ],
     export_include_dirs: ["include"],
-    srcs: ["Vibrator.cpp"],
+    srcs: [
+        "Vibrator.cpp",
+        "VibratorManager.cpp",
+    ],
     visibility: [
         ":__subpackages__",
         "//hardware/interfaces/tests/extension/vibrator:__subpackages__",
@@ -23,7 +26,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.vibrator-ndk_platform",
+        "android.hardware.vibrator-unstable-ndk_platform",
     ],
     static_libs: [
         "libvibratorexampleimpl",
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
new file mode 100644
index 0000000..7cf9e6a
--- /dev/null
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "vibrator-impl/VibratorManager.h"
+
+#include <android-base/logging.h>
+#include <thread>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+static constexpr int32_t kDefaultVibratorId = 1;
+
+ndk::ScopedAStatus VibratorManager::getCapabilities(int32_t* _aidl_return) {
+    LOG(INFO) << "Vibrator manager reporting capabilities";
+    *_aidl_return =
+            IVibratorManager::CAP_SYNC | IVibratorManager::CAP_PREPARE_ON |
+            IVibratorManager::CAP_PREPARE_PERFORM | IVibratorManager::CAP_PREPARE_COMPOSE |
+            IVibratorManager::CAP_MIXED_TRIGGER_ON | IVibratorManager::CAP_MIXED_TRIGGER_PERFORM |
+            IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE | IVibratorManager::CAP_TRIGGER_CALLBACK;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::getVibratorIds(std::vector<int32_t>* _aidl_return) {
+    LOG(INFO) << "Vibrator manager getting vibrator ids";
+    *_aidl_return = {kDefaultVibratorId};
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::getVibrator(int32_t vibratorId,
+                                                std::shared_ptr<IVibrator>* _aidl_return) {
+    LOG(INFO) << "Vibrator manager getting vibrator " << vibratorId;
+    if (vibratorId == kDefaultVibratorId) {
+        *_aidl_return = mDefaultVibrator;
+        return ndk::ScopedAStatus::ok();
+    } else {
+        *_aidl_return = nullptr;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+}
+
+ndk::ScopedAStatus VibratorManager::prepareSynced(const std::vector<int32_t>& vibratorIds) {
+    LOG(INFO) << "Vibrator Manager prepare synced";
+    if (vibratorIds.size() == 1 && vibratorIds[0] == kDefaultVibratorId) {
+        return ndk::ScopedAStatus::ok();
+    } else {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+}
+
+ndk::ScopedAStatus VibratorManager::triggerSynced(
+        const std::shared_ptr<IVibratorCallback>& callback) {
+    LOG(INFO) << "Vibrator Manager trigger synced";
+    std::thread([=] {
+        if (callback != nullptr) {
+            LOG(INFO) << "Notifying perform complete";
+            callback->onComplete();
+        }
+    }).detach();
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::cancelSynced() {
+    LOG(INFO) << "Vibrator Manager cancel synced";
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace vibrator
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
new file mode 100644
index 0000000..319eb05
--- /dev/null
+++ b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/vibrator/BnVibratorManager.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+class VibratorManager : public BnVibratorManager {
+  public:
+    VibratorManager(std::shared_ptr<IVibrator> vibrator) : mDefaultVibrator(std::move(vibrator)){};
+    ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getVibratorIds(std::vector<int32_t>* _aidl_return) override;
+    ndk::ScopedAStatus getVibrator(int32_t vibratorId,
+                                   std::shared_ptr<IVibrator>* _aidl_return) override;
+    ndk::ScopedAStatus prepareSynced(const std::vector<int32_t>& vibratorIds) override;
+    ndk::ScopedAStatus triggerSynced(const std::shared_ptr<IVibratorCallback>& callback) override;
+    ndk::ScopedAStatus cancelSynced() override;
+
+  private:
+    std::shared_ptr<IVibrator> mDefaultVibrator;
+};
+
+}  // namespace vibrator
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index ebb0905..bd834d2 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -15,19 +15,29 @@
  */
 
 #include "vibrator-impl/Vibrator.h"
+#include "vibrator-impl/VibratorManager.h"
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 
 using aidl::android::hardware::vibrator::Vibrator;
+using aidl::android::hardware::vibrator::VibratorManager;
 
 int main() {
     ABinderProcess_setThreadPoolMaxThreadCount(0);
-    std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>();
 
-    const std::string instance = std::string() + Vibrator::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
+    // make a default vibrator service
+    auto vib = ndk::SharedRefBase::make<Vibrator>();
+    const std::string vibName = std::string() + Vibrator::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(vib->asBinder().get(), vibName.c_str());
+    CHECK(status == STATUS_OK);
+
+    // make the vibrator manager service with a different vibrator
+    auto managedVib = ndk::SharedRefBase::make<Vibrator>();
+    auto vibManager = ndk::SharedRefBase::make<VibratorManager>(std::move(managedVib));
+    const std::string vibManagerName = std::string() + VibratorManager::descriptor + "/default";
+    status = AServiceManager_addService(vibManager->asBinder().get(), vibManagerName.c_str());
     CHECK(status == STATUS_OK);
 
     ABinderProcess_joinThreadPool();
diff --git a/vibrator/aidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml
index 49b11ec..9f9cd40 100644
--- a/vibrator/aidl/default/vibrator-default.xml
+++ b/vibrator/aidl/default/vibrator-default.xml
@@ -3,4 +3,8 @@
         <name>android.hardware.vibrator</name>
         <fqname>IVibrator/default</fqname>
     </hal>
+    <hal format="aidl">
+        <name>android.hardware.vibrator</name>
+        <fqname>IVibratorManager/default</fqname>
+    </hal>
 </manifest>
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index 28cb4d9..d06b50e 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -9,7 +9,26 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.vibrator-cpp",
+        "android.hardware.vibrator-unstable-cpp",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalVibratorManagerTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalVibratorManagerTargetTest.cpp"],
+    shared_libs: [
+        "libbinder",
+    ],
+    static_libs: [
+        "android.hardware.vibrator-unstable-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
new file mode 100644
index 0000000..9789188
--- /dev/null
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/vibrator/BnVibratorCallback.h>
+#include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <cmath>
+#include <future>
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::vibrator::BnVibratorCallback;
+using android::hardware::vibrator::CompositeEffect;
+using android::hardware::vibrator::CompositePrimitive;
+using android::hardware::vibrator::Effect;
+using android::hardware::vibrator::EffectStrength;
+using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
+using std::chrono::high_resolution_clock;
+
+const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
+                                   android::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
+                                                   android::enum_range<EffectStrength>().end()};
+const std::vector<CompositePrimitive> kPrimitives{android::enum_range<CompositePrimitive>().begin(),
+                                                  android::enum_range<CompositePrimitive>().end()};
+
+class CompletionCallback : public BnVibratorCallback {
+  public:
+    CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
+    Status onComplete() override {
+        mCallback();
+        return Status::ok();
+    }
+
+  private:
+    std::function<void()> mCallback;
+};
+
+class VibratorAidl : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        manager = android::waitForDeclaredService<IVibratorManager>(String16(GetParam().c_str()));
+        ASSERT_NE(manager, nullptr);
+        ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk());
+        EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk());
+    }
+
+    sp<IVibratorManager> manager;
+    int32_t capabilities;
+    std::vector<int32_t> vibratorIds;
+};
+
+TEST_P(VibratorAidl, ValidateExistingVibrators) {
+    sp<IVibrator> vibrator;
+    for (auto& id : vibratorIds) {
+        EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+        ASSERT_NE(vibrator, nullptr);
+    }
+}
+
+TEST_P(VibratorAidl, GetVibratorWithInvalidId) {
+    int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1;
+    sp<IVibrator> vibrator;
+    EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+              manager->getVibrator(invalidId, &vibrator).exceptionCode());
+    ASSERT_EQ(vibrator, nullptr);
+}
+
+TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (vibratorIds.empty()) return;
+    EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    std::vector<int32_t> emptyIds;
+    EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->prepareSynced(vibratorIds).exceptionCode());
+    }
+}
+
+TEST_P(VibratorAidl, PrepareOnNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        uint32_t durationMs = 250;
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                      vibrator->on(durationMs, nullptr).exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, PreparePerformNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            int32_t lengthMs = 0;
+            Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, PrepareComposeNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        std::vector<CompositeEffect> composite;
+        CompositeEffect effect;
+        effect.delayMs = 10;
+        effect.primitive = kPrimitives[0];
+        effect.scale = 1.0f;
+        composite.emplace_back(effect);
+
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            Status status = vibrator->compose(composite, nullptr);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, TriggerWithCallback) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) return;
+    if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> completionPromise;
+    std::future<void> completionFuture{completionPromise.get_future()};
+    sp<CompletionCallback> callback =
+            new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+    uint32_t durationMs = 250;
+    std::chrono::milliseconds timeout{durationMs * 2};
+
+    EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+    sp<IVibrator> vibrator;
+    for (auto& id : vibratorIds) {
+        EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+        ASSERT_NE(vibrator, nullptr);
+        EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk());
+    }
+
+    EXPECT_TRUE(manager->triggerSynced(callback).isOk());
+    EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
+    EXPECT_TRUE(manager->cancelSynced().isOk());
+}
+
+TEST_P(VibratorAidl, TriggerSyncNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->triggerSynced(nullptr).exceptionCode());
+    }
+}
+
+TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) {
+        sp<CompletionCallback> callback = new CompletionCallback([] {});
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->triggerSynced(callback).exceptionCode());
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
+INSTANTIATE_TEST_SUITE_P(
+        Vibrator, VibratorAidl,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 888a403..dfd2524 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -18,6 +18,7 @@
 
 #include <android/hardware/vibrator/BnVibratorCallback.h>
 #include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
@@ -34,6 +35,7 @@
 using android::hardware::vibrator::Effect;
 using android::hardware::vibrator::EffectStrength;
 using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
 using std::chrono::high_resolution_clock;
 
 const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
@@ -77,10 +79,28 @@
     std::function<void()> mCallback;
 };
 
-class VibratorAidl : public testing::TestWithParam<std::string> {
+class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>> {
   public:
     virtual void SetUp() override {
-        vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
+        int32_t managerIdx = std::get<0>(GetParam());
+        int32_t vibratorId = std::get<1>(GetParam());
+        auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+
+        if (managerIdx < 0) {
+            // Testing a unmanaged vibrator, using vibratorId as index from registered HALs
+            auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+            ASSERT_LT(vibratorId, vibratorAidlNames.size());
+            auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
+            vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
+        } else {
+            // Testing a managed vibrator, using vibratorId to retrieve it from the manager
+            ASSERT_LT(managerIdx, managerAidlNames.size());
+            auto managerName = String16(managerAidlNames[managerIdx].c_str());
+            auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+            auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
+            ASSERT_TRUE(vibratorResult.isOk());
+        }
+
         ASSERT_NE(vibrator, nullptr);
         ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
     }
@@ -518,10 +538,41 @@
     }
 }
 
+std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
+    std::vector<std::tuple<int32_t, int32_t>> tuples;
+    auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+    std::vector<int32_t> vibratorIds;
+
+    for (int i = 0; i < managerAidlNames.size(); i++) {
+        auto managerName = String16(managerAidlNames[i].c_str());
+        auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+        if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
+            for (auto& vibratorId : vibratorIds) {
+                tuples.push_back(std::make_tuple(i, vibratorId));
+            }
+        }
+    }
+
+    auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+    for (int i = 0; i < vibratorAidlNames.size(); i++) {
+        tuples.push_back(std::make_tuple(-1, i));
+    }
+
+    return tuples;
+}
+
+std::string PrintGeneratedTest(const testing::TestParamInfo<VibratorAidl::ParamType>& info) {
+    const auto& [managerIdx, vibratorId] = info.param;
+    if (managerIdx < 0) {
+        return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId);
+    }
+    return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" +
+           std::to_string(vibratorId);
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
-INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
-                         testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
-                         android::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()),
+                         PrintGeneratedTest);
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
index fc7dcd6..5b0f173 100644
--- a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -59,7 +59,7 @@
  * code.
  */
 TEST_P(WifiApIfaceHidlTest, SetMacAddress) {
-    const hidl_array<uint8_t, 6> kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}};
+    const hidl_array<uint8_t, 6> kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x44}};
     EXPECT_EQ(WifiStatusCode::SUCCESS,
               HIDL_INVOKE(wifi_ap_iface_, setMacAddress, kMac).code);
 }
diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp
index 9f91bd7..124ba32 100644
--- a/wifi/1.5/default/wifi_feature_flags.cpp
+++ b/wifi/1.5/default/wifi_feature_flags.cpp
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
 #include "wifi_feature_flags.h"
 
 namespace android {
@@ -131,7 +136,7 @@
 #define AP IfaceType::AP
 #define P2P IfaceType::P2P
 #define NAN IfaceType::NAN
-static const std::vector<IWifiChip::ChipMode> kChipModes{
+static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
     {kMainModeId,
      ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
@@ -146,6 +151,50 @@
                              {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
 #endif
 };
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+    "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined interface combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<
+    std::pair<std::string, std::vector<IWifiChip::ChipMode>>>
+    kDebugChipModes{
+        // Legacy combination - No STA/AP concurrencies.
+        // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"No STA/AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + AP concurrency
+        // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"STA + AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency
+        // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+        // AP + AP + STA concurrency
+        // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+        {"Dual AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency and AP + AP + STA concurrency
+        // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA & Dual AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}};
+
 #undef STA
 #undef AP
 #undef P2P
@@ -161,9 +210,31 @@
 
 WifiFeatureFlags::WifiFeatureFlags() {}
 
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty,
+                            buffer.data(), nullptr);
+    // Debug propety not set, use the device preset interface combination.
+    if (res <= 0) return kChipModesPrimary;
+
+    // Debug propety set, use one of the debug preset interface combination.
+    unsigned long idx = std::stoul(buffer.data());
+    if (idx >= kDebugChipModes.size()) {
+        LOG(ERROR) << "Invalid index set in property: "
+                   << kDebugPresetInterfaceCombinationIdxProperty;
+        return kChipModesPrimary;
+    }
+    std::string name;
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    std::tie(name, chip_modes) = kDebugChipModes[idx];
+    LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: "
+              << kDebugPresetInterfaceCombinationIdxProperty;
+    return chip_modes;
+}
+
 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(
     bool is_primary) {
-    return (is_primary) ? kChipModes : kChipModesSecondary;
+    return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
 }
 
 }  // namespace feature_flags
diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h
index cb68b8c..7d561fc 100644
--- a/wifi/1.5/default/wifi_feature_flags.h
+++ b/wifi/1.5/default/wifi_feature_flags.h
@@ -44,6 +44,9 @@
 
     virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(
         bool is_primary);
+
+   private:
+    std::vector<V1_0::IWifiChip::ChipMode> getChipModesForPrimary();
 };
 
 }  // namespace feature_flags
diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
index 9234a5b..bdbe651 100644
--- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
@@ -468,5 +468,5 @@
         testing::ValuesIn(
             android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
-            android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+            android::hardware::wifi::hostapd::V1_3::IHostapd::descriptor))),
     android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 6b85e00..1c3141e 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -22,6 +22,7 @@
 #include <VtsCoreUtil.h>
 #include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaIface.h>
 
 #include "supplicant_hidl_call_util.h"
 #include "supplicant_hidl_test_utils.h"
@@ -73,11 +74,16 @@
         sta_iface_ = getSupplicantStaIface(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
 
+        v1_1 = ::android::hardware::wifi::supplicant::V1_1::
+            ISupplicantStaIface::castFrom(sta_iface_);
+
         memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
     }
 
    protected:
     bool isP2pOn_ = false;
+    sp<::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface> v1_1 =
+        nullptr;
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
     // MAC address to use for various tests.
@@ -175,10 +181,13 @@
  * RegisterCallback
  */
 TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback) {
-    sta_iface_->registerCallback(
-        new IfaceCallback(), [](const SupplicantStatus& status) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
-        });
+    SupplicantStatusCode expectedCode =
+        (nullptr != v1_1) ? SupplicantStatusCode::FAILURE_UNKNOWN
+                          : SupplicantStatusCode::SUCCESS;
+    sta_iface_->registerCallback(new IfaceCallback(),
+                                 [&](const SupplicantStatus& status) {
+                                     EXPECT_EQ(expectedCode, status.code);
+                                 });
 }
 
 /*
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 44b020e..ee80628 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -47,6 +47,7 @@
         "VtsHalWifiSupplicantV1_1TargetTestUtil",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
+        "android.hardware.wifi.supplicant@1.2",
         "android.hardware.wifi@1.0",
         "android.hardware.wifi@1.1",
         "libgmock",
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
index 8d7ea54..a8e72b8 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -75,7 +75,7 @@
  * AddP2pInterface
  */
 TEST_P(SupplicantHidlTest, AddP2pInterface) {
-    if (isP2pOn_) return;
+    if (!isP2pOn_) return;
     ISupplicant::IfaceInfo iface_info;
     iface_info.name = getP2pIfaceName();
     iface_info.type = IfaceType::P2P;
@@ -115,7 +115,7 @@
  * RemoveP2pInterface
  */
 TEST_P(SupplicantHidlTest, RemoveP2pInterface) {
-    if (isP2pOn_) return;
+    if (!isP2pOn_) return;
     ISupplicant::IfaceInfo iface_info;
     iface_info.name = getP2pIfaceName();
     iface_info.type = IfaceType::P2P;
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
index db6323c..418def2 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
 #include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/1.1/IWifi.h>
 #include <android/hardware/wifi/supplicant/1.1/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIface.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -45,11 +46,16 @@
         SupplicantHidlTestBaseV1_1::SetUp();
         sta_iface_ = getSupplicantStaIface_1_1(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
+
+        v1_2 = ::android::hardware::wifi::supplicant::V1_2::
+            ISupplicantStaIface::castFrom(sta_iface_);
     }
 
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
+    sp<::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface> v1_2 =
+        nullptr;
 };
 
 class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -133,10 +139,13 @@
  * RegisterCallback_1_1
  */
 TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_1) {
-    sta_iface_->registerCallback_1_1(
-        new IfaceCallback(), [](const SupplicantStatus& status) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
-        });
+    SupplicantStatusCode expectedCode =
+        (nullptr != v1_2) ? SupplicantStatusCode::FAILURE_UNKNOWN
+                          : SupplicantStatusCode::SUCCESS;
+    sta_iface_->registerCallback_1_1(new IfaceCallback(),
+                                     [&](const SupplicantStatus& status) {
+                                         EXPECT_EQ(expectedCode, status.code);
+                                     });
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
index cd08468..7799390 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -60,6 +60,9 @@
         sta_iface_ = getSupplicantStaIface_1_2(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
         count_ = 0;
+
+        v1_3 = ::android::hardware::wifi::supplicant::V1_3::
+            ISupplicantStaIface::castFrom(sta_iface_);
     }
 
     enum DppCallbackType {
@@ -102,6 +105,7 @@
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
+    sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3;
 
     bool isDppSupported() {
         uint32_t keyMgmtMask = 0;
@@ -262,10 +266,13 @@
  * RegisterCallback_1_2
  */
 TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_2) {
-    sta_iface_->registerCallback_1_2(
-        new IfaceCallback(), [](const SupplicantStatus& status) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
-        });
+    SupplicantStatusCode expectedCode =
+        (nullptr != v1_3) ? SupplicantStatusCode::FAILURE_UNKNOWN
+                          : SupplicantStatusCode::SUCCESS;
+    sta_iface_->registerCallback_1_2(new IfaceCallback(),
+                                     [&](const SupplicantStatus& status) {
+                                         EXPECT_EQ(expectedCode, status.code);
+                                     });
 }
 
 /*
@@ -339,9 +346,6 @@
      * it is waiting for will never be called. Note that this test is also
      * implemented in the 1.3 VTS test.
      */
-    sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
-        ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
-            castFrom(sta_iface_);
     if (v1_3 != nullptr) {
         GTEST_SKIP() << "Test not supported with this HAL version";
     }
@@ -404,10 +408,6 @@
      * it is waiting for will never be called. Note that this test is also
      * implemented in the 1.3 VTS test.
      */
-    sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
-        ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
-            castFrom(sta_iface_);
-
     if (v1_3 != nullptr) {
         GTEST_SKIP() << "Test not supported with this HAL version";
         return;
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 189e2b9..9ffe0ec 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -325,10 +325,13 @@
  * RegisterCallback_1_3
  */
 TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_3) {
-    sta_iface_->registerCallback_1_3(
-        new IfaceCallback(), [](const SupplicantStatus& status) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
-        });
+    SupplicantStatusCode expectedCode =
+        (nullptr != sta_iface_v1_4_) ? SupplicantStatusCode::FAILURE_UNKNOWN
+                                     : SupplicantStatusCode::SUCCESS;
+    sta_iface_->registerCallback_1_3(new IfaceCallback(),
+                                     [&](const SupplicantStatus& status) {
+                                         EXPECT_EQ(expectedCode, status.code);
+                                     });
 }
 
 /*
@@ -428,6 +431,11 @@
         return;
     }
 
+    if (sta_iface_v1_4_ != nullptr) {
+        GTEST_SKIP() << "Test not supported with this HAL version";
+        return;
+    }
+
     hidl_string uri =
         "DPP:C:81/1,117/"
         "40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
@@ -480,6 +488,11 @@
         return;
     }
 
+    if (sta_iface_v1_4_ != nullptr) {
+        GTEST_SKIP() << "Test not supported with this HAL version";
+        return;
+    }
+
     hidl_string uri =
         "DPP:C:81/1,117/"
         "40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"