Merge "wifi: Add new HAL API: getBridgedInstances" into sc-dev
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 6740bb5..2116e21 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -4,6 +4,7 @@
 [Builtin Hooks]
 bpfmt = true
 clang_format = true
+aidl_format = true
 
 [Hook Scripts]
 aosp_hook_confirmationui = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} confirmationui
diff --git a/audio/5.0/config/api/current.txt b/audio/5.0/config/api/current.txt
index a1d8e1e..8458a56 100644
--- a/audio/5.0/config/api/current.txt
+++ b/audio/5.0/config/api/current.txt
@@ -133,6 +133,7 @@
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LDAC;
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LHDC;
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LHDC_LL;
+    enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT;
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_1_0;
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_2_0;
     enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_2_1;
diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd
index 284d2e2..b0d1e20 100644
--- a/audio/5.0/config/audio_policy_configuration.xsd
+++ b/audio/5.0/config/audio_policy_configuration.xsd
@@ -361,6 +361,7 @@
             <xs:enumeration value="AUDIO_FORMAT_AC4"/>
             <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
             <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index 6b49e5e..f5d4798 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -133,6 +133,7 @@
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LDAC;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LHDC;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LHDC_LL;
+    enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_1_0;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_2_0;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_2_1;
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index 341c6b3..ead1cc2 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -363,6 +363,7 @@
             <xs:enumeration value="AUDIO_FORMAT_AC4"/>
             <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
             <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
             <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index ab9aa7d..393e38f 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -73,14 +73,14 @@
 
     /**
      * Sets stream parameters. Only sets parameters that are specified.
-     * See the description of AudioConfigBase for the details.
      *
      * Optional method. If implemented, only called on a stopped stream.
      *
      * @param config basic stream configuration.
      * @return retval operation completion status.
      */
-    setAudioProperties(AudioConfigBase config) generates (Result retval);
+    setAudioProperties(AudioConfigBaseOptional config)
+            generates (Result retval);
 
     /**
      * Applies audio effect to the stream.
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index 0b2e4a4..f585d8e 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -198,6 +198,7 @@
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS;
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index a735c6d..87e5774 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -330,6 +330,7 @@
     </xs:simpleType>
     <xs:simpleType name="audioFormat">
         <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
             <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
             <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
             <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp
index 27f28c6..5788811 100644
--- a/audio/common/7.0/example/Effect.cpp
+++ b/audio/common/7.0/example/Effect.cpp
@@ -107,14 +107,13 @@
 }
 
 Return<void> Effect::getConfig(getConfig_cb _hidl_cb) {
-    const EffectConfig config = {
-            {} /* inputCfg */,
-            // outputCfg
-            {{} /* buffer */,
-             {toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), 48000 /* samplingRateHz */,
-              toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)}, /* base */
-             EffectBufferAccess::ACCESS_ACCUMULATE,
-             0 /* mask */}};
+    EffectConfig config;
+    // inputCfg left unspecified.
+    config.outputCfg.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT));
+    config.outputCfg.base.sampleRateHz.value(48000);
+    config.outputCfg.base.channelMask.value(
+            toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO));
+    config.outputCfg.accessMode.value(EffectBufferAccess::ACCESS_ACCUMULATE);
     _hidl_cb(Result::OK, config);
     return Void();
 }
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index ed6d94f..3903a0b 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -118,9 +118,28 @@
  * Base configuration attributes applicable to any stream of audio.
  */
 struct AudioConfigBase {
-    AudioFormat format;                 // empty means 'unspecified'
-    uint32_t sampleRateHz;              // 0 means 'unspecified'
-    AudioChannelMask channelMask;       // empty means 'unspecified'
+    AudioFormat format;
+    uint32_t sampleRateHz;
+    AudioChannelMask channelMask;
+};
+
+/**
+ * Base configuration attributes applicable to any stream of audio.
+ * Any attribute may be left unspecified.
+ */
+struct AudioConfigBaseOptional {
+    safe_union Format {
+        Monostate unspecified;
+        AudioFormat value;
+    } format;
+    safe_union SampleRate {
+        Monostate unspecified;
+        uint32_t value;
+    } sampleRateHz;
+    safe_union ChannelMask {
+        Monostate unspecified;
+        AudioChannelMask value;
+    } channelMask;
 };
 
 /**
@@ -439,11 +458,9 @@
      */
     AudioPortHandle id;
     /**
-     * Basic parameters: sampling rate, format, channel mask. Only some of the
-     * parameters (or none) may be set. See the documentation of the
-     * AudioConfigBase struct.
+     * Basic parameters: sampling rate, format, channel mask.
      */
-    AudioConfigBase base;
+    AudioConfigBaseOptional base;
     /** Associated gain control. */
     safe_union OptionalGain {
         Monostate unspecified;
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index de19faf..f09db5e 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -147,6 +147,59 @@
     return result;
 }
 
+status_t HidlUtils::audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
+                                                   bool isInput, bool formatSpecified,
+                                                   bool sampleRateSpecified,
+                                                   bool channelMaskSpecified,
+                                                   AudioConfigBaseOptional* configBase) {
+    status_t result = NO_ERROR;
+    if (formatSpecified) {
+        AudioFormat value;
+        CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &value), result);
+        configBase->format.value(std::move(value));
+    } else {
+        configBase->format.unspecified({});
+    }
+    if (sampleRateSpecified) {
+        configBase->sampleRateHz.value(halConfigBase.sample_rate);
+    } else {
+        configBase->sampleRateHz.unspecified({});
+    }
+    if (channelMaskSpecified) {
+        AudioChannelMask value;
+        CONVERT_CHECKED(audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &value),
+                        result);
+        configBase->channelMask.value(std::move(value));
+    }
+    return result;
+}
+
+status_t HidlUtils::audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
+                                                 audio_config_base_t* halConfigBase,
+                                                 bool* formatSpecified, bool* sampleRateSpecified,
+                                                 bool* channelMaskSpecified) {
+    status_t result = NO_ERROR;
+    *formatSpecified = configBase.format.getDiscriminator() ==
+                       AudioConfigBaseOptional::Format::hidl_discriminator::value;
+    if (*formatSpecified) {
+        CONVERT_CHECKED(audioFormatToHal(configBase.format.value(), &halConfigBase->format),
+                        result);
+    }
+    *sampleRateSpecified = configBase.sampleRateHz.getDiscriminator() ==
+                           AudioConfigBaseOptional::SampleRate::hidl_discriminator::value;
+    if (*sampleRateSpecified) {
+        halConfigBase->sample_rate = configBase.sampleRateHz.value();
+    }
+    *channelMaskSpecified = configBase.channelMask.getDiscriminator() ==
+                            AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value;
+    if (*channelMaskSpecified) {
+        CONVERT_CHECKED(
+                audioChannelMaskToHal(configBase.channelMask.value(), &halConfigBase->channel_mask),
+                result);
+    }
+    return result;
+}
+
 status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType,
                                             AudioContentType* contentType) {
     *contentType = audio_content_type_to_string(halContentType);
@@ -508,23 +561,14 @@
               audio_port_config_has_input_direction(&halConfig), isInput);
         result = BAD_VALUE;
     }
-    if (halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-        config->base.sampleRateHz = halConfig.sample_rate;
-    } else {
-        config->base.sampleRateHz = {};
-    }
-    if (halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-        CONVERT_CHECKED(
-                audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->base.channelMask),
-                result);
-    } else {
-        config->base.channelMask = {};
-    }
-    if (halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-        CONVERT_CHECKED(audioFormatFromHal(halConfig.format, &config->base.format), result);
-    } else {
-        config->base.format = {};
-    }
+    audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask,
+                                         halConfig.format};
+    CONVERT_CHECKED(
+            audioConfigBaseOptionalFromHal(
+                    halConfigBase, isInput, halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT,
+                    halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE,
+                    halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK, &config->base),
+            result);
     if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) {
         config->gain.config({});
         CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()),
@@ -540,19 +584,23 @@
     status_t result = NO_ERROR;
     memset(halConfig, 0, sizeof(audio_port_config));
     halConfig->id = config.id;
-    halConfig->config_mask = {};
-    if (config.base.sampleRateHz != 0) {
+    halConfig->config_mask = 0;
+    audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+    bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
+    CONVERT_CHECKED(audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
+                                                 &sRateSpecified, &channelMaskSpecified),
+                    result);
+    if (sRateSpecified) {
         halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
-        halConfig->sample_rate = config.base.sampleRateHz;
+        halConfig->sample_rate = halConfigBase.sample_rate;
     }
-    if (!config.base.channelMask.empty()) {
+    if (channelMaskSpecified) {
         halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
-        CONVERT_CHECKED(audioChannelMaskToHal(config.base.channelMask, &halConfig->channel_mask),
-                        result);
+        halConfig->channel_mask = halConfigBase.channel_mask;
     }
-    if (!config.base.format.empty()) {
+    if (formatSpecified) {
         halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
-        CONVERT_CHECKED(audioFormatToHal(config.base.format, &halConfig->format), result);
+        halConfig->format = halConfigBase.format;
     }
     if (config.gain.getDiscriminator() ==
         AudioPortConfig::OptionalGain::hidl_discriminator::config) {
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 8e9275c..cc4fbf2 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -89,6 +89,15 @@
                                            AudioConfigBase* configBase);
     static status_t audioConfigBaseToHal(const AudioConfigBase& configBase,
                                          audio_config_base_t* halConfigBase);
+    static status_t audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
+                                                   bool isInput, bool formatSpecified,
+                                                   bool sampleRateSpecified,
+                                                   bool channelMaskSpecified,
+                                                   AudioConfigBaseOptional* configBase);
+    static status_t audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
+                                                 audio_config_base_t* halConfigBase,
+                                                 bool* formatSpecified, bool* sampleRateSpecified,
+                                                 bool* channelMaskSpecified);
     static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device);
     static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice);
     static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format);
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index fef88b4..642ece3 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -35,30 +35,27 @@
 using namespace ::android::audio::policy::configuration::V7_0;
 }
 
-static constexpr audio_channel_mask_t kInvalidHalChannelMask =
-        static_cast<audio_channel_mask_t>(0xFFFFFFFFU);
+static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
 static constexpr audio_content_type_t kInvalidHalContentType =
         static_cast<audio_content_type_t>(0xFFFFFFFFU);
 static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU);
-static constexpr audio_format_t kInvalidHalFormat = static_cast<audio_format_t>(0xFFFFFFFFU);
+static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID;
 static constexpr audio_gain_mode_t kInvalidHalGainMode =
         static_cast<audio_gain_mode_t>(0xFFFFFFFFU);
-static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(0xFFFFFFFFU);
+// AUDIO_SOURCE_INVALID is framework-only.
+static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1);
 static constexpr audio_stream_type_t kInvalidHalStreamType =
         static_cast<audio_stream_type_t>(0xFFFFFFFFU);
 static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU);
 
 TEST(HidlUtils, ConvertInvalidChannelMask) {
     AudioChannelMask invalid;
-    EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID,
-                                                            false /*isInput*/, &invalid));
-    EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, true /*isInput*/,
-                                                            &invalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask,
                                                             false /*isInput*/, &invalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask,
                                                             true /*isInput*/, &invalid));
     audio_channel_mask_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("", &halInvalid));
     // INVALID channel mask is not in XSD thus it's not allowed for transfer over HIDL.
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("AUDIO_CHANNEL_INVALID", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("random string", &halInvalid));
@@ -148,40 +145,241 @@
     }
 }
 
+static AudioConfigBase generateValidConfigBase(bool isInput) {
+    AudioConfigBase configBase;
+    configBase.sampleRateHz = 44100;
+    configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+    configBase.channelMask = isInput ? toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_STEREO)
+                                     : toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
+    return configBase;
+}
+
 TEST(HidlUtils, ConvertInvalidConfigBase) {
     AudioConfigBase invalid;
-    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0,
-                                                            .channel_mask = kInvalidHalChannelMask,
-                                                            .format = kInvalidHalFormat},
-                                                           false /*isInput*/, &invalid));
-    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0,
-                                                            .channel_mask = kInvalidHalChannelMask,
-                                                            .format = kInvalidHalFormat},
-                                                           true /*isInput*/, &invalid));
+    audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER;
+    halInvalidChannelMask.channel_mask = kInvalidHalChannelMask;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, false /*isInput*/,
+                                                           &invalid));
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, true /*isInput*/, &invalid));
+    audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER;
+    halInvalidFormat.format = kInvalidHalFormat;
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseFromHal(halInvalidFormat, false /*isInput*/, &invalid));
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseFromHal(halInvalidFormat, true /*isInput*/, &invalid));
+
     audio_config_base_t halInvalid;
-    invalid.sampleRateHz = 0;
-    invalid.channelMask = "random string";
-    invalid.format = "random string";
-    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalid, &halInvalid));
+    AudioConfigBase invalidChannelMask = generateValidConfigBase(false /*isInput*/);
+    invalidChannelMask.channelMask = "random string";
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidChannelMask, &halInvalid));
+    AudioConfigBase invalidFormat = generateValidConfigBase(false /*isInput*/);
+    invalidFormat.format = "random string";
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidFormat, &halInvalid));
+}
+
+TEST(HidlUtils, ConvertConfigBaseDefault) {
+    audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER;
+    AudioConfigBase baseDefaultOut, baseDefaultIn;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halBaseDefault, false /*isInput*/,
+                                                          &baseDefaultOut));
+    EXPECT_EQ(NO_ERROR,
+              HidlUtils::audioConfigBaseFromHal(halBaseDefault, true /*isInput*/, &baseDefaultIn));
+    EXPECT_EQ(baseDefaultOut, baseDefaultIn);
+    audio_config_base_t halBaseDefaultBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(baseDefaultOut, &halBaseDefaultBack));
+    EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultBack.sample_rate);
+    EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultBack.channel_mask);
+    EXPECT_EQ(halBaseDefault.format, halBaseDefaultBack.format);
 }
 
 TEST(HidlUtils, ConvertConfigBase) {
-    AudioConfigBase configBase;
-    configBase.sampleRateHz = 44100;
-    configBase.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
-    configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
-    audio_config_base_t halConfigBase;
-    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBase, &halConfigBase));
-    AudioConfigBase configBaseBack;
+    AudioConfigBase configBaseOut = generateValidConfigBase(false /*isInput*/);
+    audio_config_base_t halConfigBaseOut;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseOut, &halConfigBaseOut));
+    AudioConfigBase configBaseOutBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseOut, false /*isInput*/,
+                                                          &configBaseOutBack));
+    EXPECT_EQ(configBaseOut, configBaseOutBack);
+
+    AudioConfigBase configBaseIn = generateValidConfigBase(true /*isInput*/);
+    audio_config_base_t halConfigBaseIn;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseIn, &halConfigBaseIn));
+    AudioConfigBase configBaseInBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseIn, true /*isInput*/,
+                                                          &configBaseInBack));
+    EXPECT_EQ(configBaseIn, configBaseInBack);
+}
+
+TEST(HidlUtils, ConvertInvalidConfigBaseOptional) {
+    AudioConfigBaseOptional invalid;
+    audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER;
+    halInvalidChannelMask.channel_mask = kInvalidHalChannelMask;
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid));
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid));
+    // Unspecified invalid values are ignored
+    AudioConfigBaseOptional unspecified;
     EXPECT_EQ(NO_ERROR,
-              HidlUtils::audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &configBaseBack));
-    EXPECT_EQ(configBase, configBaseBack);
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+    EXPECT_EQ(NO_ERROR,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+    audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER;
+    halInvalidFormat.format = kInvalidHalFormat;
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidFormat, false /*isInput*/, true /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid));
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidFormat, true /*isInput*/, true /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid));
+    EXPECT_EQ(NO_ERROR,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidFormat, false /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+    EXPECT_EQ(NO_ERROR,
+              HidlUtils::audioConfigBaseOptionalFromHal(
+                      halInvalidFormat, true /*isInput*/, false /*formatSpecified*/,
+                      false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+
+    audio_config_base_t halInvalid;
+    AudioConfigBaseOptional invalidChannelMask;
+    bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+    invalidChannelMask.channelMask.value("random string");
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseOptionalToHal(
+                                 invalidChannelMask, &halInvalid, &formatSpecified,
+                                 &sampleRateSpecified, &channelMaskSpecified));
+    AudioConfigBaseOptional invalidFormat;
+    invalidFormat.format.value("random string");
+    EXPECT_EQ(BAD_VALUE,
+              HidlUtils::audioConfigBaseOptionalToHal(invalidFormat, &halInvalid, &formatSpecified,
+                                                      &sampleRateSpecified, &channelMaskSpecified));
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptionalDefault) {
+    audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER;
+    AudioConfigBaseOptional baseDefaultUnspecOut, baseDefaultUnspecIn;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halBaseDefault, false /*isInput*/, false /*formatSpecified*/,
+                                false /*sampleRateSpecified*/, false /*channelMaskSpecified*/,
+                                &baseDefaultUnspecOut));
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halBaseDefault, true /*isInput*/, false /*formatSpecified*/,
+                                false /*sampleRateSpecified*/, false /*channelMaskSpecified*/,
+                                &baseDefaultUnspecIn));
+    EXPECT_EQ(baseDefaultUnspecOut, baseDefaultUnspecIn);
+    audio_config_base_t halBaseDefaultUnspecBack = AUDIO_CONFIG_BASE_INITIALIZER;
+    bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+                                baseDefaultUnspecOut, &halBaseDefaultUnspecBack, &formatSpecified,
+                                &sampleRateSpecified, &channelMaskSpecified));
+    EXPECT_FALSE(formatSpecified);
+    EXPECT_FALSE(sampleRateSpecified);
+    EXPECT_FALSE(channelMaskSpecified);
+    EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultUnspecBack.sample_rate);
+    EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultUnspecBack.channel_mask);
+    EXPECT_EQ(halBaseDefault.format, halBaseDefaultUnspecBack.format);
+
+    AudioConfigBaseOptional baseDefaultSpecOut, baseDefaultSpecIn;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halBaseDefault, false /*isInput*/, true /*formatSpecified*/,
+                                true /*sampleRateSpecified*/, true /*channelMaskSpecified*/,
+                                &baseDefaultSpecOut));
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halBaseDefault, true /*isInput*/, true /*formatSpecified*/,
+                                true /*sampleRateSpecified*/, true /*channelMaskSpecified*/,
+                                &baseDefaultSpecIn));
+    EXPECT_EQ(baseDefaultSpecOut, baseDefaultSpecIn);
+    audio_config_base_t halBaseDefaultSpecBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+                                baseDefaultSpecOut, &halBaseDefaultSpecBack, &formatSpecified,
+                                &sampleRateSpecified, &channelMaskSpecified));
+    EXPECT_TRUE(formatSpecified);
+    EXPECT_TRUE(sampleRateSpecified);
+    EXPECT_TRUE(channelMaskSpecified);
+    EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultSpecBack.sample_rate);
+    EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultSpecBack.channel_mask);
+    EXPECT_EQ(halBaseDefault.format, halBaseDefaultSpecBack.format);
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptionalEmpty) {
+    AudioConfigBaseOptional empty;
+    bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+    audio_config_base_t halEmpty = AUDIO_CONFIG_BASE_INITIALIZER;
+    EXPECT_EQ(NO_ERROR,
+              HidlUtils::audioConfigBaseOptionalToHal(empty, &halEmpty, &formatSpecified,
+                                                      &sampleRateSpecified, &channelMaskSpecified));
+    EXPECT_FALSE(formatSpecified);
+    EXPECT_FALSE(sampleRateSpecified);
+    EXPECT_FALSE(channelMaskSpecified);
+    AudioConfigBaseOptional emptyOutBack, emptyInBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halEmpty, false /*isInput*/, formatSpecified, sampleRateSpecified,
+                                channelMaskSpecified, &emptyOutBack));
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halEmpty, true /*isInput*/, formatSpecified, sampleRateSpecified,
+                                channelMaskSpecified, &emptyInBack));
+    EXPECT_EQ(emptyOutBack, emptyInBack);
+    EXPECT_EQ(empty, emptyOutBack);
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptional) {
+    AudioConfigBase validBaseOut = generateValidConfigBase(false /*isInput*/);
+    AudioConfigBaseOptional configBaseOut;
+    configBaseOut.format.value(validBaseOut.format);
+    configBaseOut.sampleRateHz.value(validBaseOut.sampleRateHz);
+    configBaseOut.channelMask.value(validBaseOut.channelMask);
+    audio_config_base_t halConfigBaseOut;
+    bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+                                configBaseOut, &halConfigBaseOut, &formatSpecified,
+                                &sampleRateSpecified, &channelMaskSpecified));
+    EXPECT_TRUE(formatSpecified);
+    EXPECT_TRUE(sampleRateSpecified);
+    EXPECT_TRUE(channelMaskSpecified);
+    AudioConfigBaseOptional configBaseOutBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halConfigBaseOut, false /*isInput*/, formatSpecified,
+                                sampleRateSpecified, channelMaskSpecified, &configBaseOutBack));
+    EXPECT_EQ(configBaseOut, configBaseOutBack);
+
+    AudioConfigBase validBaseIn = generateValidConfigBase(true /*isInput*/);
+    AudioConfigBaseOptional configBaseIn;
+    configBaseIn.format.value(validBaseIn.format);
+    configBaseIn.sampleRateHz.value(validBaseIn.sampleRateHz);
+    configBaseIn.channelMask.value(validBaseIn.channelMask);
+    audio_config_base_t halConfigBaseIn;
+    formatSpecified = false;
+    sampleRateSpecified = false;
+    channelMaskSpecified = false;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+                                configBaseIn, &halConfigBaseIn, &formatSpecified,
+                                &sampleRateSpecified, &channelMaskSpecified));
+    EXPECT_TRUE(formatSpecified);
+    EXPECT_TRUE(sampleRateSpecified);
+    EXPECT_TRUE(channelMaskSpecified);
+    AudioConfigBaseOptional configBaseInBack;
+    EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+                                halConfigBaseIn, true /*isInput*/, formatSpecified,
+                                sampleRateSpecified, channelMaskSpecified, &configBaseInBack));
+    EXPECT_EQ(configBaseIn, configBaseInBack);
 }
 
 TEST(HidlUtils, ConvertInvalidContentType) {
     AudioContentType invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeFromHal(kInvalidHalContentType, &invalid));
     audio_content_type_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("random string", &halInvalid));
 }
 
@@ -202,6 +400,7 @@
     AudioDevice invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid));
     audio_devices_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("random string", &halInvalid));
 }
 
@@ -233,6 +432,7 @@
 // The enums module is too small to have unit tests on its own.
 TEST(HidlUtils, VendorExtension) {
     EXPECT_TRUE(xsd::isVendorExtension("VX_GOOGLE_VR_42"));
+    EXPECT_FALSE(xsd::isVendorExtension(""));
     EXPECT_FALSE(xsd::isVendorExtension("random string"));
     EXPECT_FALSE(xsd::isVendorExtension("VX_"));
     EXPECT_FALSE(xsd::isVendorExtension("VX_GOOGLE_$$"));
@@ -347,6 +547,9 @@
     AudioFormat invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatFromHal(kInvalidHalFormat, &invalid));
     audio_format_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("", &halInvalid));
+    // INVALID format is not in XSD thus it's not allowed for transfer over HIDL.
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("AUDIO_FORMAT_INVALID", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("random string", &halInvalid));
 }
 
@@ -357,8 +560,9 @@
         AudioFormat formatBack;
         EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatToHal(format, &halFormat))
                 << "Conversion of \"" << format << "\" failed";
-        EXPECT_TRUE(audio_is_valid_format(halFormat))
-                << "Converted format \"" << format << "\" is invalid";
+        EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT,
+                  audio_is_valid_format(halFormat))
+                << "Validity of \"" << format << "\" is not as expected";
         EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatFromHal(halFormat, &formatBack))
                 << "Conversion of format " << halFormat << " failed";
         EXPECT_EQ(format, formatBack);
@@ -430,6 +634,9 @@
     AudioSource invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceFromHal(kInvalidHalSource, &invalid));
     audio_source_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("", &halInvalid));
+    // INVALID source is not in XSD thus it's not allowed for transfer over HIDL.
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("AUDIO_SOURCE_INVALID", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("random string", &halInvalid));
 }
 
@@ -453,6 +660,7 @@
     AudioStreamType invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeFromHal(kInvalidHalStreamType, &invalid));
     audio_stream_type_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("random string", &halInvalid));
 }
 
@@ -524,6 +732,7 @@
     AudioUsage invalid;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageFromHal(kInvalidHalUsage, &invalid));
     audio_usage_t halInvalid;
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("", &halInvalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("random string", &halInvalid));
 }
 
@@ -543,7 +752,7 @@
 TEST(HidlUtils, ConvertInvalidOffloadInfo) {
     AudioOffloadInfo invalid;
     audio_offload_info_t halInvalid = AUDIO_INFO_INITIALIZER;
-    halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+    halInvalid.channel_mask = kInvalidHalChannelMask;
     halInvalid.format = kInvalidHalFormat;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioOffloadInfoFromHal(halInvalid, &invalid));
     invalid.base.channelMask = "random string";
@@ -575,7 +784,7 @@
 TEST(HidlUtils, ConvertInvalidConfig) {
     AudioConfig invalid;
     audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER;
-    halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+    halInvalid.channel_mask = kInvalidHalChannelMask;
     halInvalid.format = kInvalidHalFormat;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid));
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid));
@@ -655,18 +864,18 @@
     halInvalid.type = AUDIO_PORT_TYPE_MIX;
     halInvalid.role = AUDIO_PORT_ROLE_NONE;  // note: this is valid.
     halInvalid.config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK;
-    halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+    halInvalid.channel_mask = kInvalidHalChannelMask;
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigFromHal(halInvalid, &invalid));
-    invalid.base.channelMask = "random string";
+    invalid.base.channelMask.value("random string");
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigToHal(invalid, &halInvalid));
 }
 
 TEST(HidlUtils, ConvertAudioPortConfig) {
     AudioPortConfig config = {};
     config.id = 42;
-    config.base.sampleRateHz = 44100;
-    config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
-    config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+    config.base.sampleRateHz.value(44100);
+    config.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO));
+    config.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT));
     config.gain.config({});
     config.gain.config().channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
     config.ext.device({});
@@ -734,7 +943,7 @@
             {std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1, HidlUtils::sAudioTagSeparator)}};
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(tagSeparator, halTag));
 
-    hidl_vec<AudioTag> notExtensions = {{"random string", "VX_", "VX_GOOGLE_$$"}};
+    hidl_vec<AudioTag> notExtensions = {{"", "random string", "VX_", "VX_GOOGLE_$$"}};
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(notExtensions, halTag));
 }
 
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index f964cbb..3f8efd2 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -278,23 +278,36 @@
     return Void();
 }
 
-Return<Result> Stream::setAudioProperties(const AudioConfigBase& config) {
-    audio_config_base_t halConfigBase = {};
-    status_t status = HidlUtils::audioConfigBaseToHal(config, &halConfigBase);
+Return<Result> Stream::setAudioProperties(const AudioConfigBaseOptional& config) {
+    audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+    bool formatSpecified, sRateSpecified, channelMaskSpecified;
+    status_t status = HidlUtils::audioConfigBaseOptionalToHal(
+            config, &halConfigBase, &formatSpecified, &sRateSpecified, &channelMaskSpecified);
     if (status != NO_ERROR) {
         return Stream::analyzeStatus("set_audio_properties", status);
     }
-    if (Result result = setParam(AudioParameter::keySamplingRate,
-                                 static_cast<int>(halConfigBase.sample_rate));
-        result != Result::OK) {
-        return result;
+    if (sRateSpecified) {
+        if (Result result = setParam(AudioParameter::keySamplingRate,
+                                     static_cast<int>(halConfigBase.sample_rate));
+            result != Result::OK) {
+            return result;
+        }
     }
-    if (Result result =
-                setParam(AudioParameter::keyChannels, static_cast<int>(halConfigBase.channel_mask));
-        result != Result::OK) {
-        return result;
+    if (channelMaskSpecified) {
+        if (Result result = setParam(AudioParameter::keyChannels,
+                                     static_cast<int>(halConfigBase.channel_mask));
+            result != Result::OK) {
+            return result;
+        }
     }
-    return setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format));
+    if (formatSpecified) {
+        if (Result result =
+                    setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format));
+            result != Result::OK) {
+            return result;
+        }
+    }
+    return Result::OK;
 }
 
 #endif  // MAJOR_VERSION <= 6
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 2c5e9f1..c670a4d 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -233,7 +233,7 @@
     return mStreamCommon->getSupportedProfiles(_hidl_cb);
 }
 
-Return<Result> StreamIn::setAudioProperties(const AudioConfigBase& config) {
+Return<Result> StreamIn::setAudioProperties(const AudioConfigBaseOptional& config) {
     return mStreamCommon->setAudioProperties(config);
 }
 
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index b5ddba0..c2ad720 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -239,7 +239,7 @@
     return mStreamCommon->getSupportedProfiles(_hidl_cb);
 }
 
-Return<Result> StreamOut::setAudioProperties(const AudioConfigBase& config) {
+Return<Result> StreamOut::setAudioProperties(const AudioConfigBaseOptional& config) {
     return mStreamCommon->setAudioProperties(config);
 }
 
diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h
index 0865992..66d60e3 100644
--- a/audio/core/all-versions/default/include/core/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/default/Stream.h
@@ -77,7 +77,7 @@
     Return<Result> setFormat(AudioFormat format) override;
 #else
     Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
-    Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+    Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
 #endif  // MAJOR_VERSION <= 6
     Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
     Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index 651b3a6..a980f3f 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -72,7 +72,7 @@
     Return<Result> setFormat(AudioFormat format) override;
 #else
     Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
-    Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+    Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
 #endif  // MAJOR_VERSION <= 6
     Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
     Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index 02d8e89..0b07972 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -73,7 +73,7 @@
     Return<Result> setFormat(AudioFormat format) override;
 #else
     Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
-    Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+    Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
 #endif  // MAJOR_VERSION <= 6
     Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
     Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 7fca610..be1ffbb 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -367,10 +367,10 @@
     static std::vector<AudioPortConfig> invalids = [&] {
         std::vector<AudioPortConfig> result;
         AudioPortConfig invalidBaseChannelMask = valids[PORT_CONF_MINIMAL];
-        invalidBaseChannelMask.base.channelMask = "random_string";
+        invalidBaseChannelMask.base.channelMask.value("random_string");
         result.push_back(std::move(invalidBaseChannelMask));
         AudioPortConfig invalidBaseFormat = valids[PORT_CONF_MINIMAL];
-        invalidBaseFormat.base.format = "random_string";
+        invalidBaseFormat.base.format.value("random_string");
         result.push_back(std::move(invalidBaseFormat));
         AudioPortConfig invalidGainMode = valids[PORT_CONF_WITH_GAIN];
         invalidGainMode.gain.config().mode = {{"random_string"}};
@@ -724,19 +724,19 @@
         areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
                                    : testSetDevicesInvalidDeviceAddress(stream.get()));
 
-static void testSetAudioPropertiesInvalidArguments(IStream* stream, const AudioConfigBase& base) {
-    AudioConfigBase invalidFormat = base;
-    invalidFormat.format = "random_string";
+static void testSetAudioPropertiesInvalidArguments(IStream* stream) {
+    AudioConfigBaseOptional invalidFormat;
+    invalidFormat.format.value("random_string");
     ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidFormat));
 
-    AudioConfigBase invalidChannelMask = base;
-    invalidChannelMask.channelMask = "random_string";
+    AudioConfigBaseOptional invalidChannelMask;
+    invalidChannelMask.channelMask.value("random_string");
     ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidChannelMask));
 }
 TEST_SINGLE_CONFIG_IO_STREAM(
         SetAudioPropertiesInvalidArguments,
         "Verify that invalid arguments are rejected by IStream::setAudioProperties",
-        testSetAudioPropertiesInvalidArguments(stream.get(), audioConfig.base));
+        testSetAudioPropertiesInvalidArguments(stream.get()));
 
 TEST_P(SingleConfigOutputStreamTest, UpdateInvalidSourceMetadata) {
     doc::test("Verify that invalid metadata is rejected by IStreamOut::updateSourceMetadata");
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index a809a92..8021bd9 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -22,7 +22,7 @@
         "libxml2",
     ],
     shared_libs: [
-        "audioclient-types-aidl-unstable-cpp",
+        "audioclient-types-aidl-cpp",
         "libaudioclient_aidl_conversion",
         "libbinder",
         "libfmq",
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index f145b60..2b9e336 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1155,13 +1155,14 @@
     for (const auto& profile : profiles) {
         for (const auto& sampleRate : profile.sampleRates) {
             for (const auto& channelMask : profile.channelMasks) {
-                AudioConfigBase config{.format = profile.format,
-                                       .sampleRateHz = sampleRate,
-                                       .channelMask = {{channelMask}}};
+                AudioConfigBaseOptional config;
+                config.format.value(profile.format);
+                config.sampleRateHz.value(sampleRate);
+                config.channelMask.value(channelMask);
                 auto ret = stream->setAudioProperties(config);
                 EXPECT_TRUE(ret.isOk());
-                EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; "
-                                           << toString(config.channelMask);
+                EXPECT_EQ(Result::OK, ret)
+                        << profile.format << "; " << sampleRate << "; " << channelMask;
             }
         }
     }
@@ -1169,7 +1170,7 @@
 
 TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles",
                testSetAudioProperties(stream.get()))
-#endif
+#endif  // MAJOR_VERSION <= 6
 
 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
 #if MAJOR_VERSION <= 6
diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal
index c4cb213..bb2d7b3 100644
--- a/audio/effect/7.0/types.hal
+++ b/audio/effect/7.0/types.hal
@@ -17,6 +17,7 @@
 package android.hardware.audio.effect@7.0;
 
 import android.hardware.audio.common@7.0;
+import android.hidl.safe_union@1.0;
 
 enum Result : int32_t {
     OK,
@@ -248,32 +249,19 @@
 };
 
 /**
- * Determines what fields of EffectBufferConfig need to be considered.
- */
-@export(name="", value_prefix="EFFECT_CONFIG_")
-enum EffectConfigParameters : int32_t {
-    /** Buffer field. */
-    BUFFER = 0x0001,
-    /** Sampling rate. */
-    SMP_RATE = 0x0002,
-    /** Channels. */
-    CHANNELS = 0x0004,
-    /** Format. */
-    FORMAT = 0x0008,
-    /** Access mode. */
-    ACC_MODE = 0x0010,
-    // Note that the 2.0 ALL have been moved to an helper function
-};
-
-/**
  * The buffer config structure specifies the input or output audio format
  * to be used by the effect engine.
  */
 struct EffectBufferConfig {
-    AudioBuffer buffer;
-    AudioConfigBase base;
-    EffectBufferAccess accessMode;
-    bitfield<EffectConfigParameters> mask;
+    safe_union OptionalBuffer {
+        Monostate unspecified;
+        AudioBuffer buf;
+    } buffer;
+    AudioConfigBaseOptional base;
+    safe_union OptionalAccessMode {
+        Monostate unspecified;
+        EffectBufferAccess value;
+    } accessMode;
 };
 
 struct EffectConfig {
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index edd364c..58f1779 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -249,14 +249,17 @@
 
 void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig,
                                        EffectBufferConfig* config) {
-    config->buffer.id = 0;
-    config->buffer.frameCount = 0;
+    config->buffer.unspecified();
     audio_config_base_t halConfigBase = {halConfig.samplingRate,
                                          static_cast<audio_channel_mask_t>(halConfig.channels),
                                          static_cast<audio_format_t>(halConfig.format)};
-    (void)HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &config->base);
-    config->accessMode = EffectBufferAccess(halConfig.accessMode);
-    config->mask = static_cast<decltype(config->mask)>(halConfig.mask);
+    (void)HidlUtils::audioConfigBaseOptionalFromHal(
+            halConfigBase, mIsInput, halConfig.mask & EFFECT_CONFIG_FORMAT,
+            halConfig.mask & EFFECT_CONFIG_SMP_RATE, halConfig.mask & EFFECT_CONFIG_CHANNELS,
+            &config->base);
+    if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) {
+        config->accessMode.value(EffectBufferAccess(halConfig.accessMode));
+    }
 }
 
 // static
@@ -265,17 +268,32 @@
     // using 'setProcessBuffers'.
     halConfig->buffer.frameCount = 0;
     halConfig->buffer.raw = nullptr;
-    audio_config_base_t halConfigBase;
-    (void)HidlUtils::audioConfigBaseToHal(config.base, &halConfigBase);
-    halConfig->samplingRate = halConfigBase.sample_rate;
-    halConfig->channels = halConfigBase.channel_mask;
-    halConfig->format = halConfigBase.format;
+    audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+    bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
+    (void)HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
+                                                  &sRateSpecified, &channelMaskSpecified);
+    halConfig->mask = 0;
+    if (sRateSpecified) {
+        halConfig->mask |= EFFECT_CONFIG_SMP_RATE;
+        halConfig->samplingRate = halConfigBase.sample_rate;
+    }
+    if (channelMaskSpecified) {
+        halConfig->mask |= EFFECT_CONFIG_CHANNELS;
+        halConfig->channels = halConfigBase.channel_mask;
+    }
+    if (formatSpecified) {
+        halConfig->mask |= EFFECT_CONFIG_FORMAT;
+        halConfig->format = halConfigBase.format;
+    }
     // Note: The framework code does not use BP.
     halConfig->bufferProvider.cookie = nullptr;
     halConfig->bufferProvider.getBuffer = nullptr;
     halConfig->bufferProvider.releaseBuffer = nullptr;
-    halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
-    halConfig->mask = static_cast<uint8_t>(config.mask);
+    if (config.accessMode.getDiscriminator() ==
+        EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) {
+        halConfig->mask |= EFFECT_CONFIG_ACC_MODE;
+        halConfig->accessMode = static_cast<uint8_t>(config.accessMode.value());
+    }
 }
 
 #endif  // MAJOR_VERSION <= 6
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 35ff869..15a2fd9 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -264,8 +264,10 @@
     *channelCount = audio_channel_count_from_out_mask(
         static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
 #else
+    ASSERT_EQ(AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value,
+              currentConfig.outputCfg.base.channelMask.getDiscriminator());
     *channelCount = android::audio::policy::configuration::V7_0::getChannelCount(
-            currentConfig.outputCfg.base.channelMask);
+            currentConfig.outputCfg.base.channelMask.value());
     ASSERT_NE(*channelCount, 0);
 #endif
 }
@@ -315,10 +317,10 @@
 std::vector<EffectBufferConfig> generateInvalidConfigs(const EffectBufferConfig& src) {
     std::vector<EffectBufferConfig> result;
     EffectBufferConfig invalidFormat = src;
-    invalidFormat.base.format = "random_string";
+    invalidFormat.base.format.value("random_string");
     result.push_back(std::move(invalidFormat));
     EffectBufferConfig invalidChannelMask = src;
-    invalidChannelMask.base.channelMask = "random_string";
+    invalidChannelMask.base.channelMask.value("random_string");
     result.push_back(std::move(invalidChannelMask));
     return result;
 }
@@ -395,17 +397,22 @@
            rhs.data.handle() == nullptr;
 }
 
+#if MAJOR_VERSION <= 6
 inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) {
     return lhs.buffer == rhs.buffer &&
-#if MAJOR_VERSION <= 6
            lhs.samplingRateHz == rhs.samplingRateHz && lhs.channels == rhs.channels &&
            lhs.format == rhs.format &&
-#else
-           lhs.base.sampleRateHz == rhs.base.sampleRateHz &&
-           lhs.base.channelMask == rhs.base.channelMask && lhs.base.format == rhs.base.format &&
-#endif
            lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask;
 }
+#else
+inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) {
+    return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() &&
+           (lhs.buffer.getDiscriminator() ==
+                    EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified ||
+            lhs.buffer.buf() == rhs.buffer.buf()) &&
+           lhs.base == rhs.base && lhs.accessMode == rhs.accessMode;
+}
+#endif  // MAJOR_VERSION <= 6
 
 inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) {
     return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg;
diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp
index d598344..44e0711 100644
--- a/authsecret/aidl/default/Android.bp
+++ b/authsecret/aidl/default/Android.bp
@@ -25,7 +25,7 @@
         "AuthSecret.cpp",
     ],
     shared_libs: [
-        "android.hardware.authsecret-ndk_platform",
+        "android.hardware.authsecret-V1-ndk_platform",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp
index 83a85b2..29b3bcc 100644
--- a/authsecret/aidl/vts/Android.bp
+++ b/authsecret/aidl/vts/Android.bp
@@ -21,7 +21,7 @@
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: ["VtsHalAuthSecretTargetTest.cpp"],
-    static_libs: ["android.hardware.authsecret-ndk_platform"],
+    static_libs: ["android.hardware.authsecret-V1-ndk_platform"],
     shared_libs: ["libbinder_ndk"],
     test_suites: [
         "general-tests",
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index 427709a..05fec79 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -22,8 +22,8 @@
     generated_sources: ["audio_policy_configuration_V7_0"],
     header_libs: ["libxsdc-utils"],
     shared_libs: [
-        "android.frameworks.automotive.powerpolicy-ndk_platform",
-        "android.hardware.automotive.audiocontrol-ndk_platform",
+        "android.frameworks.automotive.powerpolicy-V1-ndk_platform",
+        "android.hardware.automotive.audiocontrol-V1-ndk_platform",
         "libbase",
         "libbinder_ndk",
         "libcutils",
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index 3d81e00..89f5f92 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -28,7 +28,7 @@
         "libxml2",
     ],
     static_libs: [
-        "android.hardware.automotive.audiocontrol-cpp",
+        "android.hardware.automotive.audiocontrol-V1-cpp",
         "libgmock",
     ],
     test_suites: [
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index 1b2fba2..1e50930 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -27,6 +27,6 @@
         "libbase",
         "libbinder_ndk",
         "libutils",
-        "android.hardware.automotive.occupant_awareness-ndk_platform",
+        "android.hardware.automotive.occupant_awareness-V1-ndk_platform",
     ],
 }
diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp
index 4b30866..64ca733 100644
--- a/automotive/occupant_awareness/aidl/mock/Android.bp
+++ b/automotive/occupant_awareness/aidl/mock/Android.bp
@@ -27,6 +27,6 @@
         "libbase",
         "libbinder_ndk",
         "libutils",
-        "android.hardware.automotive.occupant_awareness-ndk_platform",
+        "android.hardware.automotive.occupant_awareness-V1-ndk_platform",
     ],
 }
diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
index 514b0af..dbd0538 100644
--- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp
+++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
@@ -9,7 +9,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.automotive.occupant_awareness-cpp",
+        "android.hardware.automotive.occupant_awareness-V1-cpp",
     ],
     test_suites: [
         "vts",
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index bbb48e1..c66c9cc 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",
-        "android.automotive.watchdog-ndk_platform",
+        "android.automotive.watchdog-V2-ndk_platform",
     ],
 }
 
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 51a8ef4..a13b8cb 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -7,8 +7,8 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.biometrics.face-ndk_platform",
-        "android.hardware.biometrics.common-unstable-ndk_platform",
+        "android.hardware.biometrics.face-V1-ndk_platform",
+        "android.hardware.biometrics.common-V1-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index 427b878..a4c76f5 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -7,7 +7,7 @@
     srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
-        "android.hardware.biometrics.face-ndk_platform",
+        "android.hardware.biometrics.face-V1-ndk_platform",
     ],
     test_suites: [
         "general-tests",
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index ce1ff59..c8cb663 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -7,8 +7,8 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.biometrics.fingerprint-ndk_platform",
-        "android.hardware.biometrics.common-unstable-ndk_platform",
+        "android.hardware.biometrics.fingerprint-V1-ndk_platform",
+        "android.hardware.biometrics.common-V1-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index b441eb3..07bccb5 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -7,7 +7,7 @@
     srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
-        "android.hardware.biometrics.fingerprint-ndk_platform",
+        "android.hardware.biometrics.fingerprint-V1-ndk_platform",
     ],
     test_suites: [
         "general-tests",
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index 84f4839..0a4f787 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -22,9 +22,9 @@
 
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
 #include <binder/ProcessState.h>
-#include <cutils/memory.h>
 #include <cutils/properties.h>
 #include <hidl/LegacySupport.h>
+#include <malloc.h>
 
 using android::status_t;
 using android::hardware::defaultLazyPassthroughServiceImplementation;
@@ -46,7 +46,13 @@
 
     // b/166675194
     if (property_get_bool("ro.vendor.camera.provider24.disable_mem_init", false)) {
-        process_disable_memory_mitigations();
+        if (mallopt(M_BIONIC_ZERO_INIT, 0) == 0) {
+            // Note - heap initialization is only present on devices with Scudo.
+            // Devices with jemalloc don't have heap-init, and thus the mallopt
+            // will fail. On these devices, you probably just want to remove the
+            // property.
+            ALOGE("Disabling heap initialization failed.");
+        }
     }
 
     status_t status;
diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp
index f9977ff..70f4371 100644
--- a/cas/1.0/default/Android.bp
+++ b/cas/1.0/default/Android.bp
@@ -12,7 +12,7 @@
       "TypeConvert.cpp",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     shared_libs: [
       "android.hardware.cas@1.0",
diff --git a/cas/1.0/default/FactoryLoader.h b/cas/1.0/default/FactoryLoader.h
index 18c2186..45e515a 100644
--- a/cas/1.0/default/FactoryLoader.h
+++ b/cas/1.0/default/FactoryLoader.h
@@ -92,7 +92,12 @@
     }
 
     // no luck, have to search
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
+
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
@@ -127,7 +132,12 @@
 
     results->clear();
 
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
+
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp
index 66a1eb8..8e1f207 100644
--- a/cas/1.1/default/Android.bp
+++ b/cas/1.1/default/Android.bp
@@ -12,7 +12,7 @@
       "TypeConvert.cpp",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     shared_libs: [
       "android.hardware.cas@1.0",
diff --git a/cas/1.1/default/FactoryLoader.h b/cas/1.1/default/FactoryLoader.h
index c4a48e2..121f90c 100644
--- a/cas/1.1/default/FactoryLoader.h
+++ b/cas/1.1/default/FactoryLoader.h
@@ -85,7 +85,11 @@
     }
 
     // no luck, have to search
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
@@ -118,7 +122,11 @@
 
     results->clear();
 
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp
index 9e53148..d855e85 100644
--- a/cas/1.2/default/Android.bp
+++ b/cas/1.2/default/Android.bp
@@ -12,7 +12,7 @@
       "TypeConvert.cpp",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     shared_libs: [
       "android.hardware.cas@1.0",
diff --git a/cas/1.2/default/FactoryLoader.h b/cas/1.2/default/FactoryLoader.h
index 7403f86..a374b31 100644
--- a/cas/1.2/default/FactoryLoader.h
+++ b/cas/1.2/default/FactoryLoader.h
@@ -85,7 +85,11 @@
     }
 
     // no luck, have to search
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
@@ -118,7 +122,11 @@
 
     results->clear();
 
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
     String8 dirPath("/vendor/lib/mediacas");
+#endif
     DIR* pDir = opendir(dirPath.string());
 
     if (pDir == NULL) {
diff --git a/common/support/Android.bp b/common/support/Android.bp
index 3bb4804..ce3aa3f 100644
--- a/common/support/Android.bp
+++ b/common/support/Android.bp
@@ -6,7 +6,7 @@
     srcs: ["NativeHandle.cpp"],
     export_include_dirs: ["include"],
     shared_libs: [
-        "android.hardware.common-unstable-ndk_platform",
+        "android.hardware.common-V2-ndk_platform",
         "libcutils",
     ],
 }
@@ -17,10 +17,10 @@
     defaults: ["libbinder_ndk_host_user"],
     srcs: ["test.cpp"],
     static_libs: [
+        "android.hardware.common-V2-ndk_platform",
         "libaidlcommonsupport",
     ],
     shared_libs: [
-        "android.hardware.common-unstable-ndk_platform",
         "libcutils",
     ],
     test_suites: ["general-tests"],
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 91ca312..93a46dd 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -82,7 +82,7 @@
         <name>android.hardware.automotive.sv</name>
         <version>1.0</version>
         <interface>
-            <name>ISurroundView</name>
+            <name>ISurroundViewService</name>
             <instance>default</instance>
         </interface>
     </hal>
@@ -287,7 +287,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.identity</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
@@ -525,7 +525,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.tetheroffload.control</name>
-        <version>1.0</version>
+        <version>1.1</version>
         <interface>
             <name>IOffloadControl</name>
             <instance>default</instance>
diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp
index 93b3278..d5063fb 100644
--- a/drm/1.0/default/Android.bp
+++ b/drm/1.0/default/Android.bp
@@ -46,7 +46,7 @@
 
 android_hardware_drm_1_0_multilib {
     name: "android.hardware.drm@1.0-multilib-lib",
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
     soong_config_variables: {
         TARGET_ENABLE_MEDIADRM_64: {
             compile_multilib: "both",
@@ -56,7 +56,7 @@
 
 android_hardware_drm_1_0_multilib {
     name: "android.hardware.drm@1.0-multilib-exe",
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
     soong_config_variables: {
         TARGET_ENABLE_MEDIADRM_64: {
             compile_multilib: "first",
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index ef43a34..6853ad9 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -18,7 +18,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-ndk_platform",
+        "android.hardware.gnss-V1-ndk_platform",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 7da462f..be04553 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -41,7 +41,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-ndk_platform",
+        "android.hardware.gnss-V1-ndk_platform",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index 63e5013..7c4b9c6 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -34,7 +34,7 @@
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
-        "android.hardware.gnss-ndk_platform",
+        "android.hardware.gnss-V1-ndk_platform",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
index 0302676..11cdcfc 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
index 1f713fa..2d21748 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
index 933f659..fbcc8a3 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
index 53ac0ef..15fe2e9 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
index 18fdfa9..f873b87 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
index 73ead10..9e05db7 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
index 3d287e4..728ff68 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
index 5da60f7..b9db343 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
index 358b570..6676e2e 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
index b2a498d..f729d4c 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index bd6f1ff..10b05a7 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -26,4 +40,6 @@
   android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
   android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
   const int ERROR_INVALID_ARGUMENT = 1;
+  const int ERROR_ALREADY_INIT = 2;
+  const int ERROR_GENERIC = 3;
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index a0c4255..9ad9159 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
index eb4ad82..20dd781 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
index 764b896..93894bf 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 7cb7395..07a51ae 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
index c44903e..1cc7f71 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
index 12e6762..01f91dc 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
index cae2ea6..1758792 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
index 6888632..a1af105 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
index d348c63..b387121 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl
index bdba667..4dd45b2 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl
index 550fa4d..c96b2e5 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl
index 4ff025e..95af152 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl
index 7db7ee6..558aec9 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index c815e2d..f99b512 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -34,6 +34,12 @@
      */
     const int ERROR_INVALID_ARGUMENT = 1;
 
+    /** A callback has already been registered. */
+    const int ERROR_ALREADY_INIT = 2;
+
+    /** Any other error. */
+    const int ERROR_GENERIC = 3;
+
     /**
      * Opens the interface and provides the callback routines to the implementation of this
      * interface.
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 04cdf64..08c83a4 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -40,10 +40,9 @@
      * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS
      *     measurements outputs. If false, disable correlation vectors.
      *
-     * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
-     *     already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
-     *     for any other error. The HAL must not generate any other updates upon returning this
-     *     error code.
+     * Returns ok() if successful. Returns ERROR_ALREADY_INIT if a callback has already been
+     * registered without a corresponding call to 'close'. Returns ERROR_GENERIC for any other
+     * error. The HAL must not generate any other updates upon returning this error code.
      */
     void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking,
                      in boolean enableCorrVecOutputs);
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 6694ce6..b56a701 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -42,7 +42,7 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
-        "android.hardware.gnss-ndk_platform",
+        "android.hardware.gnss-V1-ndk_platform",
     ],
     srcs: [
         "Gnss.cpp",
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index c10e809..7cdc339 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.gnss-cpp",
+        "android.hardware.gnss-V1-cpp",
         "android.hardware.gnss@common-vts-lib",
     ],
     test_suites: [
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index be1d532..c44968d 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -42,6 +42,6 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
-        "android.hardware.gnss-ndk_platform",
+        "android.hardware.gnss-V1-ndk_platform",
     ],
 }
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index 8bda425..2d39daa 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -19,7 +19,7 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
     static_libs: [
-        "android.hardware.graphics.common-unstable-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk_platform",
         "android.hardware.graphics.mapper@4.0-vts",
         "libgralloctypes",
         "libsync",
diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp
index 68a8ee2..b53bc35 100644
--- a/health/storage/aidl/default/Android.bp
+++ b/health/storage/aidl/default/Android.bp
@@ -20,7 +20,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.health.storage-unstable-ndk_platform",
+        "android.hardware.health.storage-V1-ndk_platform",
     ],
     static_libs: [
         "libfstab",
diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp
index 86b72a7..0e7671d 100644
--- a/health/storage/aidl/vts/functional/Android.bp
+++ b/health/storage/aidl/vts/functional/Android.bp
@@ -25,7 +25,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.health.storage-ndk_platform",
+        "android.hardware.health.storage-V1-ndk_platform",
     ],
     header_libs: [
         "libhealth_storage_test_common_headers",
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
index 7e3002d..d8a8128 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
index 447203f..2685525 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
index e1296e0..f8d5a9e 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
index 88104d9..a097895 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
@@ -18,6 +33,9 @@
 package android.hardware.identity;
 @VintfStability
 interface IIdentityCredential {
+  /**
+   * @deprecated use deleteCredentalWithChallenge() instead.
+   */
   byte[] deleteCredential();
   byte[] createEphemeralKeyPair();
   void setReaderEphemeralPublicKey(in byte[] publicKey);
@@ -29,4 +47,7 @@
   android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
   void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces);
   void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken);
+  byte[] deleteCredentialWithChallenge(in byte[] challenge);
+  byte[] proveOwnership(in byte[] challenge);
+  android.hardware.identity.IWritableIdentityCredential updateCredential();
 }
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
index 5dafb76..c6fb3c8 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
index c5ac9d6..a713462 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
index 24ec26a..c9c2b9f 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
index af00f3b..aaf1e20 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
index dfc1ad0..695fb3f 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // 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.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file 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
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 702334d..d23f88c 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -19,6 +19,7 @@
 import android.hardware.identity.Certificate;
 import android.hardware.identity.RequestNamespace;
 import android.hardware.identity.SecureAccessControlProfile;
+import android.hardware.identity.IWritableIdentityCredential;
 import android.hardware.keymaster.HardwareAuthToken;
 import android.hardware.keymaster.VerificationToken;
 
@@ -40,7 +41,11 @@
      * After this method has been called, the persistent storage used for credentialData should
      * be deleted.
      *
-     * @return a COSE_Sign1 signature described above.
+     * This method was deprecated in API version 3 because there's no challenge so freshness
+     * can't be checked. Use deleteCredentalWithChallenge() instead.
+     *
+     * @return a COSE_Sign1 signature described above
+     * @deprecated use deleteCredentalWithChallenge() instead.
      */
     byte[] deleteCredential();
 
@@ -353,6 +358,18 @@
      *
      *  - subjectPublicKeyInfo: must contain attested public key.
      *
+     * As of API version 3, the certificate shall also have an X.509 extension at
+     * OID 1.3.6.1.4.1.11129.2.1.26 which shall contain an OCTET STRING with the
+     * bytes of the CBOR with the following CDDL:
+     *
+     *   ProofOfBinding = [
+     *     "ProofOfBinding",
+     *     bstr,              // Contains SHA-256(ProofOfProvisioning)
+     *   ]
+     *
+     * This CBOR enables an issuer to determine the exact state of the credential it
+     * returns issuer-signed data for.
+     *
      * @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType)
      *     where signingKey is an EC private key in uncompressed form. That is, the returned
      *     blob is an encrypted copy of the newly-generated private signing key.
@@ -381,4 +398,63 @@
     *   The verification token. This token is only valid if the timestamp field is non-zero.
     */
     void setVerificationToken(in VerificationToken verificationToken);
+
+    /**
+     * Delete a credential.
+     *
+     * This method returns a COSE_Sign1 data structure signed by CredentialKey
+     * with payload set to the ProofOfDeletion CBOR below:
+     *
+     *     ProofOfDeletion = [
+     *          "ProofOfDeletion",            ; tstr
+     *          tstr,                         ; DocType
+     *          bstr,                         ; Challenge
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *     ]
+     *
+     * After this method has been called, the persistent storage used for credentialData should
+     * be deleted.
+     *
+     * This method was introduced in API version 3.
+     *
+     * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
+     *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+     * @return a COSE_Sign1 signature described above.
+     */
+    byte[] deleteCredentialWithChallenge(in byte[] challenge);
+
+    /**
+     * Prove ownership of credential.
+     *
+     * This method returns a COSE_Sign1 data structure signed by CredentialKey with payload
+     * set to the ProofOfOwnership CBOR below.
+     *
+     *     ProofOfOwnership = [
+     *          "ProofOfOwnership",           ; tstr
+     *          tstr,                         ; DocType
+     *          bstr,                         ; Challenge
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *     ]
+     *
+     * This method was introduced in API version 3.
+     *
+     * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
+     *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+     * @return a COSE_Sign1 signature described above.
+     */
+    byte[] proveOwnership(in byte[] challenge);
+
+    /**
+     * Called to start updating the credential with new data items.
+     *
+     * If the getAttestationCertificate() method is called on the returned object
+     * it fails with the error STATUS_FAILED.
+     *
+     * This method was introduced in API version 3.
+     *
+     * @return an IWritableIdentityCredential
+     */
+    IWritableIdentityCredential updateCredential();
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 33e25b1..638be79 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -104,6 +104,11 @@
  * All binder calls in the HAL may return a ServiceSpecificException with statuses from the
  * STATUS_* integers defined in this interface. Each method states which status can be returned
  * and under which circumstances.
+ *
+ * The API described here is API version 3 which corresponds to feature version 202101
+ * of the android.security.identity Framework API. An XML file declaring the feature
+ * android.hardware.identity_credential (or android.hardware.identity_credential.direct_access
+ * if implementing the Direct Access HAL) should be included declaring this feature version.
  */
 @VintfStability
 interface IIdentityCredentialStore {
@@ -230,6 +235,9 @@
      *     return argument of the same name in finishAddingEntries(), in
      *     IWritableIdentityCredential.
      *
+     *     Note that the format of credentialData may depend on the feature version.
+     *     Implementations must support credentialData created by an earlier feature version.
+     *
      * @return an IIdentityCredential interface that provides operations on the Credential.
      */
     IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData);
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index c48cb66..5f878ee 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -263,7 +263,9 @@
      *
      *     where HBK is a unique hardware-bound key that has never existed outside of the secure
      *     environment (except it's all zeroes if testCredential is True) and CredentialKeys is
-     *     the CBOR-encoded structure (in CDDL notation):
+     *     the CBOR-encoded structure (in CDDL notation) given below.
+     *
+     *     In API versions 1 and 2 it was the following
      *
      *         CredentialKeys = [
      *              bstr,   ; storageKey, a 128-bit AES key
@@ -271,6 +273,17 @@
      *                      ; in uncompressed form
      *         ]
      *
+     *     In API version 3 or later it must be the following
+     *
+     *         CredentialKeys = [
+     *              bstr,   ; storageKey, a 128-bit AES key
+     *              bstr    ; credentialPrivKey, the private key for credentialKey
+     *                      ; in uncompressed form
+     *              bstr    ; SHA-256(ProofOfProvisioning)
+     *         ]
+     *
+     *     Additional elements may be added to the CredentialKeys array in future versions.
+     *
      * @param out proofOfProvisioningSignature proves to the IA that the credential was imported
      *     into the secure hardware without alteration or error.  When the final addEntry() call is
      *     made (when the number of provisioned entries equals the sum of the items in
@@ -321,4 +334,5 @@
      * @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning.
      */
     void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+
 }
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 7f342d0..9659f57 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -12,6 +12,7 @@
     cflags: [
         "-Wall",
         "-Wextra",
+        "-Wno-deprecated-declarations",
     ],
     shared_libs: [
         "liblog",
@@ -28,8 +29,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-ndk_platform",
-        "android.hardware.keymaster-ndk_platform",
+        "android.hardware.identity-V3-ndk_platform",
+        "android.hardware.keymaster-V3-ndk_platform",
     ],
 }
 
@@ -88,8 +89,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-ndk_platform",
-        "android.hardware.keymaster-ndk_platform",
+        "android.hardware.identity-V3-ndk_platform",
+        "android.hardware.keymaster-V3-ndk_platform",
         "android.hardware.identity-libeic-hal-common",
         "android.hardware.identity-libeic-library",
     ],
@@ -97,4 +98,14 @@
         "service.cpp",
         "FakeSecureHardwareProxy.cpp",
     ],
+    required: [
+        "android.hardware.identity_credential.xml",
+    ],
+}
+
+prebuilt_etc {
+    name: "android.hardware.identity_credential.xml",
+    sub_dir: "permissions",
+    vendor: true,
+    src: "android.hardware.identity_credential.xml",
 }
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index 3f2ec8b..8ec4cc9 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -45,6 +45,7 @@
 
 #include "EicOps.h"
 
+using ::std::map;
 using ::std::optional;
 using ::std::string;
 using ::std::tuple;
@@ -212,7 +213,8 @@
         return false;
     }
     if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
-        eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE);
+        eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
+                 (size_t)EIC_P256_PRIV_KEY_SIZE);
         return false;
     }
 
@@ -224,7 +226,7 @@
     }
     // ecKeyPairGetPublicKey() returns 0x04 | x | y, we don't want the leading 0x04.
     if (pubKey.value().size() != EIC_P256_PUB_KEY_SIZE + 1) {
-        eicDebug("Private key is %zd bytes long, expected %zd", pubKey.value().size(),
+        eicDebug("Public key is %zd bytes long, expected %zd", pubKey.value().size(),
                  (size_t)EIC_P256_PRIV_KEY_SIZE + 1);
         return false;
     }
@@ -272,7 +274,8 @@
         return false;
     }
     if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
-        eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE);
+        eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
+                 (size_t)EIC_P256_PRIV_KEY_SIZE);
         return false;
     }
 
@@ -284,8 +287,8 @@
 bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                      const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial,
                      const char* issuerName, const char* subjectName, time_t validityNotBefore,
-                     time_t validityNotAfter, uint8_t* cert,
-                     size_t* certSize) {  // inout
+                     time_t validityNotAfter, const uint8_t* proofOfBinding,
+                     size_t proofOfBindingSize, uint8_t* cert, size_t* certSize) {  // inout
     vector<uint8_t> signingKeyVec(EIC_P256_PRIV_KEY_SIZE);
     memcpy(signingKeyVec.data(), signingKey, EIC_P256_PRIV_KEY_SIZE);
 
@@ -293,12 +296,18 @@
     pubKeyVec[0] = 0x04;
     memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);
 
-    std::string serialDecimal = android::base::StringPrintf("%d", serial);
+    string serialDecimal = android::base::StringPrintf("%d", serial);
+
+    map<string, vector<uint8_t>> extensions;
+    if (proofOfBinding != nullptr) {
+        vector<uint8_t> proofOfBindingVec(proofOfBinding, proofOfBinding + proofOfBindingSize);
+        extensions["1.3.6.1.4.1.11129.2.1.26"] = proofOfBindingVec;
+    }
 
     optional<vector<uint8_t>> certVec =
             android::hardware::identity::support::ecPublicKeyGenerateCertificate(
                     pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName,
-                    validityNotBefore, validityNotAfter);
+                    validityNotBefore, validityNotAfter, extensions);
     if (!certVec) {
         eicDebug("Error generating certificate");
         return false;
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index de6762f..287ffb8 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -67,6 +67,13 @@
     return eicProvisioningInit(&ctx_, testCredential);
 }
 
+bool FakeSecureHardwareProvisioningProxy::initializeForUpdate(
+        bool testCredential, string docType, vector<uint8_t> encryptedCredentialKeys) {
+    return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(),
+                                        encryptedCredentialKeys.data(),
+                                        encryptedCredentialKeys.size());
+}
+
 // Returns public key certificate.
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey(
         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
@@ -140,14 +147,16 @@
     return signatureOfToBeSigned;
 }
 
-// Returns encryptedCredentialKeys (80 bytes).
+// Returns encryptedCredentialKeys.
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData(
         const string& docType) {
-    vector<uint8_t> encryptedCredentialKeys(80);
+    vector<uint8_t> encryptedCredentialKeys(116);
+    size_t size = encryptedCredentialKeys.size();
     if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(),
-                                                encryptedCredentialKeys.data())) {
+                                                encryptedCredentialKeys.data(), &size)) {
         return {};
     }
+    encryptedCredentialKeys.resize(size);
     return encryptedCredentialKeys;
 }
 
@@ -162,7 +171,7 @@
     LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): "
               << sizeof(EicPresentation);
     return eicPresentationInit(&ctx_, testCredential, docType.c_str(),
-                               encryptedCredentialKeys.data());
+                               encryptedCredentialKeys.data(), encryptedCredentialKeys.size());
 }
 
 // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
@@ -312,13 +321,27 @@
 }
 
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential(
-        const string& docType, size_t proofOfDeletionCborSize) {
+        const string& docType, const vector<uint8_t>& challenge, bool includeChallenge,
+        size_t proofOfDeletionCborSize) {
     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
-    if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), proofOfDeletionCborSize,
+    if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), challenge.data(), challenge.size(),
+                                         includeChallenge, proofOfDeletionCborSize,
                                          signatureOfToBeSigned.data())) {
         return {};
     }
     return signatureOfToBeSigned;
 }
 
+optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership(
+        const string& docType, bool testCredential, const vector<uint8_t>& challenge,
+        size_t proofOfOwnershipCborSize) {
+    vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
+    if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), testCredential, challenge.data(),
+                                       challenge.size(), proofOfOwnershipCborSize,
+                                       signatureOfToBeSigned.data())) {
+        return {};
+    }
+    return signatureOfToBeSigned;
+}
+
 }  // namespace android::hardware::identity
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index b858dd4..6852c1a 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -32,6 +32,9 @@
 
     bool initialize(bool testCredential) override;
 
+    bool initializeForUpdate(bool testCredential, string docType,
+                             vector<uint8_t> encryptedCredentialKeys) override;
+
     bool shutdown() override;
 
     // Returns public key certificate.
@@ -122,8 +125,14 @@
     optional<vector<uint8_t>> finishRetrieval() override;
 
     optional<vector<uint8_t>> deleteCredential(const string& docType,
+                                               const vector<uint8_t>& challenge,
+                                               bool includeChallenge,
                                                size_t proofOfDeletionCborSize) override;
 
+    optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential,
+                                             const vector<uint8_t>& challenge,
+                                             size_t proofOfOwnershipCborSize) override;
+
     bool shutdown() override;
 
   protected:
diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml
new file mode 100644
index 0000000..5149792
--- /dev/null
+++ b/identity/aidl/default/android.hardware.identity_credential.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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.
+-->
+<permissions>
+  <feature name="android.hardware.identity_credential" version="202101" />
+</permissions>
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 270fcfa..9477997 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -30,6 +30,7 @@
 #include <cppbor_parse.h>
 
 #include "FakeSecureHardwareProxy.h"
+#include "WritableIdentityCredential.h"
 
 namespace aidl::android::hardware::identity {
 
@@ -70,14 +71,8 @@
     docType_ = docTypeItem->value();
     testCredential_ = testCredentialItem->value();
 
-    const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value();
-
-    if (encryptedCredentialKeys.size() != 80) {
-        LOG(ERROR) << "Unexpected size for encrypted CredentialKeys";
-        return IIdentityCredentialStore::STATUS_INVALID_DATA;
-    }
-
-    if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys)) {
+    encryptedCredentialKeys_ = encryptedCredentialKeysItem->value();
+    if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys_)) {
         LOG(ERROR) << "hwProxy->initialize failed";
         return false;
     }
@@ -87,12 +82,32 @@
 
 ndk::ScopedAStatus IdentityCredential::deleteCredential(
         vector<uint8_t>* outProofOfDeletionSignature) {
+    return deleteCredentialCommon({}, false, outProofOfDeletionSignature);
+}
+
+ndk::ScopedAStatus IdentityCredential::deleteCredentialWithChallenge(
+        const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfDeletionSignature) {
+    return deleteCredentialCommon(challenge, true, outProofOfDeletionSignature);
+}
+
+ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon(
+        const vector<uint8_t>& challenge, bool includeChallenge,
+        vector<uint8_t>* outProofOfDeletionSignature) {
+    if (challenge.size() > 32) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big"));
+    }
+
     cppbor::Array array = {"ProofOfDeletion", docType_, testCredential_};
+    if (includeChallenge) {
+        array = {"ProofOfDeletion", docType_, challenge, testCredential_};
+    }
+
     vector<uint8_t> proofOfDeletionCbor = array.encode();
     vector<uint8_t> podDigest = support::sha256(proofOfDeletionCbor);
 
-    optional<vector<uint8_t>> signatureOfToBeSigned =
-            hwProxy_->deleteCredential(docType_, proofOfDeletionCbor.size());
+    optional<vector<uint8_t>> signatureOfToBeSigned = hwProxy_->deleteCredential(
+            docType_, challenge, includeChallenge, proofOfDeletionCbor.size());
     if (!signatureOfToBeSigned) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED, "Error signing ProofOfDeletion"));
@@ -111,6 +126,38 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredential::proveOwnership(
+        const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfOwnershipSignature) {
+    if (challenge.size() > 32) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big"));
+    }
+
+    cppbor::Array array;
+    array = {"ProofOfOwnership", docType_, challenge, testCredential_};
+    vector<uint8_t> proofOfOwnershipCbor = array.encode();
+    vector<uint8_t> podDigest = support::sha256(proofOfOwnershipCbor);
+
+    optional<vector<uint8_t>> signatureOfToBeSigned = hwProxy_->proveOwnership(
+            docType_, testCredential_, challenge, proofOfOwnershipCbor.size());
+    if (!signatureOfToBeSigned) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error signing ProofOfOwnership"));
+    }
+
+    optional<vector<uint8_t>> signature =
+            support::coseSignEcDsaWithSignature(signatureOfToBeSigned.value(),
+                                                proofOfOwnershipCbor,  // data
+                                                {});                   // certificateChain
+    if (!signature) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error signing data"));
+    }
+
+    *outProofOfOwnershipSignature = signature.value();
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
     optional<vector<uint8_t>> ephemeralPriv = hwProxy_->createEphemeralKeyPair();
     if (!ephemeralPriv) {
@@ -833,4 +880,19 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredential::updateCredential(
+        shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
+    sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
+    shared_ptr<WritableIdentityCredential> wc =
+            ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType_,
+                                                                 testCredential_);
+    if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error initializing WritableIdentityCredential for update"));
+    }
+    *outWritableCredential = wc;
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 2281821..9913b86 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -45,9 +45,11 @@
 
 class IdentityCredential : public BnIdentityCredential {
   public:
-    IdentityCredential(sp<SecureHardwarePresentationProxy> hwProxy,
+    IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
+                       sp<SecureHardwarePresentationProxy> hwProxy,
                        const vector<uint8_t>& credentialData)
-        : hwProxy_(hwProxy),
+        : hwProxyFactory_(hwProxyFactory),
+          hwProxy_(hwProxy),
           credentialData_(credentialData),
           numStartRetrievalCalls_(0),
           expectedDeviceNameSpacesSize_(0) {}
@@ -58,6 +60,11 @@
 
     // Methods from IIdentityCredential follow.
     ndk::ScopedAStatus deleteCredential(vector<uint8_t>* outProofOfDeletionSignature) override;
+    ndk::ScopedAStatus deleteCredentialWithChallenge(
+            const vector<uint8_t>& challenge,
+            vector<uint8_t>* outProofOfDeletionSignature) override;
+    ndk::ScopedAStatus proveOwnership(const vector<uint8_t>& challenge,
+                                      vector<uint8_t>* outProofOfOwnershipSignature) override;
     ndk::ScopedAStatus createEphemeralKeyPair(vector<uint8_t>* outKeyPair) override;
     ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override;
     ndk::ScopedAStatus createAuthChallenge(int64_t* outChallenge) override;
@@ -79,8 +86,16 @@
     ndk::ScopedAStatus generateSigningKeyPair(vector<uint8_t>* outSigningKeyBlob,
                                               Certificate* outSigningKeyCertificate) override;
 
+    ndk::ScopedAStatus updateCredential(
+            shared_ptr<IWritableIdentityCredential>* outWritableCredential) override;
+
   private:
+    ndk::ScopedAStatus deleteCredentialCommon(const vector<uint8_t>& challenge,
+                                              bool includeChallenge,
+                                              vector<uint8_t>* outProofOfDeletionSignature);
+
     // Set by constructor
+    sp<SecureHardwareProxyFactory> hwProxyFactory_;
     sp<SecureHardwarePresentationProxy> hwProxy_;
     vector<uint8_t> credentialData_;
     int numStartRetrievalCalls_;
@@ -88,6 +103,7 @@
     // Set by initialize()
     string docType_;
     bool testCredential_;
+    vector<uint8_t> encryptedCredentialKeys_;
 
     // Set by createEphemeralKeyPair()
     vector<uint8_t> ephemeralPublicKey_;
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
index 13f91aa..e6b5466 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.cpp
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -63,7 +63,7 @@
 
     sp<SecureHardwarePresentationProxy> hwProxy = hwProxyFactory_->createPresentationProxy();
     shared_ptr<IdentityCredential> credential =
-            ndk::SharedRefBase::make<IdentityCredential>(hwProxy, credentialData);
+            ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, hwProxy, credentialData);
     auto ret = credential->initialize();
     if (ret != IIdentityCredentialStore::STATUS_OK) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index b89ad87..a1ed1ef 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -64,6 +64,9 @@
 
     virtual bool initialize(bool testCredential) = 0;
 
+    virtual bool initializeForUpdate(bool testCredential, string docType,
+                                     vector<uint8_t> encryptedCredentialKeys) = 0;
+
     // Returns public key certificate chain with attestation.
     //
     // This must return an entire certificate chain and its implementation must
@@ -164,8 +167,14 @@
     virtual optional<vector<uint8_t>> finishRetrieval();
 
     virtual optional<vector<uint8_t>> deleteCredential(const string& docType,
+                                                       const vector<uint8_t>& challenge,
+                                                       bool includeChallenge,
                                                        size_t proofOfDeletionCborSize) = 0;
 
+    virtual optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential,
+                                                     const vector<uint8_t>& challenge,
+                                                     size_t proofOfOwnershipCborSize) = 0;
+
     virtual bool shutdown() = 0;
 };
 
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index 1328f36..2d897c7 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -40,7 +40,20 @@
 
 bool WritableIdentityCredential::initialize() {
     if (!hwProxy_->initialize(testCredential_)) {
-        LOG(ERROR) << "hwProxy->initialize failed";
+        LOG(ERROR) << "hwProxy->initialize() failed";
+        return false;
+    }
+    startPersonalizationCalled_ = false;
+    firstEntry_ = true;
+
+    return true;
+}
+
+// Used when updating a credential. Returns false on failure.
+bool WritableIdentityCredential::initializeForUpdate(
+        const vector<uint8_t>& encryptedCredentialKeys) {
+    if (!hwProxy_->initializeForUpdate(testCredential_, docType_, encryptedCredentialKeys)) {
+        LOG(ERROR) << "hwProxy->initializeForUpdate() failed";
         return false;
     }
     startPersonalizationCalled_ = false;
diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h
index c6f0628..36ad430 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.h
+++ b/identity/aidl/default/common/WritableIdentityCredential.h
@@ -36,16 +36,22 @@
 
 class WritableIdentityCredential : public BnWritableIdentityCredential {
   public:
+    // For a new credential, call initialize() right after construction.
+    //
+    // For an updated credential, call initializeForUpdate() right after construction.
+    //
     WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
                                bool testCredential)
         : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
 
     ~WritableIdentityCredential();
 
-    // Creates the Credential Key. Returns false on failure. Must be called
-    // right after construction.
+    // Creates the Credential Key. Returns false on failure.
     bool initialize();
 
+    // Used when updating a credential. Returns false on failure.
+    bool initializeForUpdate(const vector<uint8_t>& encryptedCredentialKeys);
+
     // Methods from IWritableIdentityCredential follow.
     ndk::ScopedAStatus getAttestationCertificate(const vector<uint8_t>& attestationApplicationId,
                                                  const vector<uint8_t>& attestationChallenge,
diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml
index 37d5b81..a074250 100644
--- a/identity/aidl/default/identity-default.xml
+++ b/identity/aidl/default/identity-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.identity</name>
-        <version>2</version>
+        <version>3</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
diff --git a/identity/aidl/default/libeic/EicCbor.c b/identity/aidl/default/libeic/EicCbor.c
index ec049b1..fe131eb 100644
--- a/identity/aidl/default/libeic/EicCbor.c
+++ b/identity/aidl/default/libeic/EicCbor.c
@@ -17,6 +17,7 @@
 #include "EicCbor.h"
 
 void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize) {
+    eicMemSet(cbor, '\0', sizeof(EicCbor));
     cbor->size = 0;
     cbor->bufferSize = bufferSize;
     cbor->buffer = buffer;
@@ -26,6 +27,7 @@
 
 void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize,
                            const uint8_t* hmacKey, size_t hmacKeySize) {
+    eicMemSet(cbor, '\0', sizeof(EicCbor));
     cbor->size = 0;
     cbor->bufferSize = bufferSize;
     cbor->buffer = buffer;
@@ -33,6 +35,10 @@
     eicOpsHmacSha256Init(&cbor->digester.hmacSha256, hmacKey, hmacKeySize);
 }
 
+void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256) {
+    cbor->secondaryDigesterSha256 = sha256;
+}
+
 void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
     switch (cbor->digestType) {
         case EIC_CBOR_DIGEST_TYPE_SHA256:
@@ -53,6 +59,9 @@
             eicOpsHmacSha256Update(&cbor->digester.hmacSha256, data, size);
             break;
     }
+    if (cbor->secondaryDigesterSha256 != NULL) {
+        eicOpsSha256Update(cbor->secondaryDigesterSha256, data, size);
+    }
 
     if (cbor->size >= cbor->bufferSize) {
         cbor->size += size;
diff --git a/identity/aidl/default/libeic/EicCbor.h b/identity/aidl/default/libeic/EicCbor.h
index 4686b38..9c0f531 100644
--- a/identity/aidl/default/libeic/EicCbor.h
+++ b/identity/aidl/default/libeic/EicCbor.h
@@ -53,6 +53,9 @@
         EicHmacSha256Ctx hmacSha256;
     } digester;
 
+    // The secondary digester, may be unset.
+    EicSha256Ctx* secondaryDigesterSha256;
+
     // The buffer used for building up CBOR or NULL if bufferSize is 0.
     uint8_t* buffer;
 } EicCbor;
@@ -70,6 +73,14 @@
 void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize,
                            const uint8_t* hmacKey, size_t hmacKeySize);
 
+/* Enables a secondary digester.
+ *
+ * May be enabled midway through processing, this can be used to e.g. calculate
+ * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its
+ * payload.
+ */
+void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256);
+
 /* Finishes building CBOR and returns the digest. */
 void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
 
diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h
index da4dabf..d4fcf0e 100644
--- a/identity/aidl/default/libeic/EicOps.h
+++ b/identity/aidl/default/libeic/EicOps.h
@@ -207,14 +207,17 @@
 // Generate an X.509 certificate for the key identified by |publicKey| which
 // must be of the form returned by eicOpsCreateEcKey().
 //
+// If proofOfBinding is not NULL, it will be included as an OCTET_STRING
+// X.509 extension at OID 1.3.6.1.4.1.11129.2.1.26.
+//
 // The certificate will be signed by the key identified by |signingKey| which
 // must be of the form returned by eicOpsCreateEcKey().
 //
 bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                      const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial,
                      const char* issuerName, const char* subjectName, time_t validityNotBefore,
-                     time_t validityNotAfter, uint8_t* cert,
-                     size_t* certSize);  // inout
+                     time_t validityNotAfter, const uint8_t* proofOfBinding,
+                     size_t proofOfBindingSize, uint8_t* cert, size_t* certSize);  // inout
 
 // Uses |privateKey| to create an ECDSA signature of some data (the SHA-256 must
 // be given by |digestOfData|). Returns the signature in |signature|.
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index d3f5556..5e9a280 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -19,13 +19,28 @@
 #include <inttypes.h>
 
 bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType,
-                         const uint8_t encryptedCredentialKeys[80]) {
-    uint8_t credentialKeys[52];
+                         const uint8_t* encryptedCredentialKeys,
+                         size_t encryptedCredentialKeysSize) {
+    uint8_t credentialKeys[86];
+    bool expectPopSha256 = false;
+
+    // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86
+    // bytes (the additional data is the ProofOfProvisioning SHA-256). We need
+    // to support loading all feature versions.
+    //
+    if (encryptedCredentialKeysSize == 52 + 28) {
+        /* do nothing */
+    } else if (encryptedCredentialKeysSize == 86 + 28) {
+        expectPopSha256 = true;
+    } else {
+        eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize);
+        return false;
+    }
 
     eicMemSet(ctx, '\0', sizeof(EicPresentation));
 
     if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys,
-                                80,
+                                encryptedCredentialKeysSize,
                                 // DocType is the additionalAuthenticatedData
                                 (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) {
         eicDebug("Error decrypting CredentialKeys");
@@ -34,25 +49,42 @@
 
     // It's supposed to look like this;
     //
+    // Feature version 202009:
+    //
     //         CredentialKeys = [
     //              bstr,   ; storageKey, a 128-bit AES key
-    //              bstr    ; credentialPrivKey, the private key for credentialKey
+    //              bstr,   ; credentialPrivKey, the private key for credentialKey
     //         ]
     //
-    // where storageKey is 16 bytes and credentialPrivateKey is 32 bytes.
+    // Feature version 202101:
     //
-    // So the first two bytes will be 0x82 0x50 indicating resp. an array of two elements
-    // and a bstr of 16 elements. Sixteen bytes later (offset 18 and 19) there will be
-    // a bstr of 32 bytes. It's encoded as two bytes 0x58 and 0x20.
+    //         CredentialKeys = [
+    //              bstr,   ; storageKey, a 128-bit AES key
+    //              bstr,   ; credentialPrivKey, the private key for credentialKey
+    //              bstr    ; proofOfProvisioning SHA-256
+    //         ]
     //
-    if (credentialKeys[0] != 0x82 || credentialKeys[1] != 0x50 || credentialKeys[18] != 0x58 ||
-        credentialKeys[19] != 0x20) {
+    // where storageKey is 16 bytes, credentialPrivateKey is 32 bytes, and proofOfProvisioning
+    // SHA-256 is 32 bytes.
+    //
+    if (credentialKeys[0] != (expectPopSha256 ? 0x83 : 0x82) ||  // array of two or three elements
+        credentialKeys[1] != 0x50 ||                             // 16-byte bstr
+        credentialKeys[18] != 0x58 || credentialKeys[19] != 0x20) {  // 32-byte bstr
         eicDebug("Invalid CBOR for CredentialKeys");
         return false;
     }
+    if (expectPopSha256) {
+        if (credentialKeys[52] != 0x58 || credentialKeys[53] != 0x20) {  // 32-byte bstr
+            eicDebug("Invalid CBOR for CredentialKeys");
+            return false;
+        }
+    }
     eicMemCpy(ctx->storageKey, credentialKeys + 2, EIC_AES_128_KEY_SIZE);
     eicMemCpy(ctx->credentialPrivateKey, credentialKeys + 20, EIC_P256_PRIV_KEY_SIZE);
     ctx->testCredential = testCredential;
+    if (expectPopSha256) {
+        eicMemCpy(ctx->proofOfProvisioningSha256, credentialKeys + 54, EIC_SHA256_DIGEST_SIZE);
+    }
     return true;
 }
 
@@ -61,6 +93,35 @@
                                            uint8_t signingKeyBlob[60]) {
     uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE];
     uint8_t signingKeyPub[EIC_P256_PUB_KEY_SIZE];
+    uint8_t cborBuf[64];
+
+    // Generate the ProofOfBinding CBOR to include in the X.509 certificate in
+    // IdentityCredentialAuthenticationKeyExtension CBOR. This CBOR is defined
+    // by the following CDDL
+    //
+    //   ProofOfBinding = [
+    //     "ProofOfBinding",
+    //     bstr,                  // Contains the SHA-256 of ProofOfProvisioning
+    //   ]
+    //
+    // This array may grow in the future if other information needs to be
+    // conveyed.
+    //
+    // The bytes of ProofOfBinding is is represented as an OCTET_STRING
+    // and stored at OID 1.3.6.1.4.1.11129.2.1.26.
+    //
+
+    EicCbor cbor;
+    eicCborInit(&cbor, cborBuf, sizeof cborBuf);
+    eicCborAppendArray(&cbor, 2);
+    eicCborAppendString(&cbor, "ProofOfBinding");
+    eicCborAppendByteString(&cbor, ctx->proofOfProvisioningSha256, EIC_SHA256_DIGEST_SIZE);
+    if (cbor.size > sizeof(cborBuf)) {
+        eicDebug("Exceeded buffer size");
+        return false;
+    }
+    const uint8_t* proofOfBinding = cborBuf;
+    size_t proofOfBindingSize = cbor.size;
 
     if (!eicOpsCreateEcKey(signingKeyPriv, signingKeyPub)) {
         eicDebug("Error creating signing key");
@@ -73,7 +134,8 @@
     if (!eicOpsSignEcKey(signingKeyPub, ctx->credentialPrivateKey, 1,
                          "Android Identity Credential Key",                 // issuer CN
                          "Android Identity Credential Authentication Key",  // subject CN
-                         validityNotBefore, validityNotAfter, publicKeyCert, publicKeyCertSize)) {
+                         validityNotBefore, validityNotAfter, proofOfBinding, proofOfBindingSize,
+                         publicKeyCert, publicKeyCertSize)) {
         eicDebug("Error creating certificate for signing key");
         return false;
     }
@@ -674,7 +736,8 @@
 }
 
 bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType,
-                                     size_t proofOfDeletionCborSize,
+                                     const uint8_t* challenge, size_t challengeSize,
+                                     bool includeChallenge, size_t proofOfDeletionCborSize,
                                      uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) {
     EicCbor cbor;
 
@@ -712,9 +775,12 @@
     eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, proofOfDeletionCborSize);
 
     // Finally, the CBOR that we're actually signing.
-    eicCborAppendArray(&cbor, 3);
+    eicCborAppendArray(&cbor, includeChallenge ? 4 : 3);
     eicCborAppendString(&cbor, "ProofOfDeletion");
     eicCborAppendString(&cbor, docType);
+    if (includeChallenge) {
+        eicCborAppendByteString(&cbor, challenge, challengeSize);
+    }
     eicCborAppendBool(&cbor, ctx->testCredential);
 
     uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE];
@@ -726,3 +792,59 @@
 
     return true;
 }
+
+bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential,
+                                   const uint8_t* challenge, size_t challengeSize,
+                                   size_t proofOfOwnershipCborSize,
+                                   uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) {
+    EicCbor cbor;
+
+    eicCborInit(&cbor, NULL, 0);
+
+    // What we're going to sign is the COSE ToBeSigned structure which
+    // looks like the following:
+    //
+    // Sig_structure = [
+    //   context : "Signature" / "Signature1" / "CounterSignature",
+    //   body_protected : empty_or_serialized_map,
+    //   ? sign_protected : empty_or_serialized_map,
+    //   external_aad : bstr,
+    //   payload : bstr
+    //  ]
+    //
+    eicCborAppendArray(&cbor, 4);
+    eicCborAppendString(&cbor, "Signature1");
+
+    // The COSE Encoded protected headers is just a single field with
+    // COSE_LABEL_ALG (1) -> COSE_ALG_ECSDA_256 (-7). For simplicitly we just
+    // hard-code the CBOR encoding:
+    static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x26};
+    eicCborAppendByteString(&cbor, coseEncodedProtectedHeaders,
+                            sizeof(coseEncodedProtectedHeaders));
+
+    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+    // so external_aad is the empty bstr
+    static const uint8_t externalAad[0] = {};
+    eicCborAppendByteString(&cbor, externalAad, sizeof(externalAad));
+
+    // For the payload, the _encoded_ form follows here. We handle this by simply
+    // opening a bstr, and then writing the CBOR. This requires us to know the
+    // size of said bstr, ahead of time.
+    eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, proofOfOwnershipCborSize);
+
+    // Finally, the CBOR that we're actually signing.
+    eicCborAppendArray(&cbor, 4);
+    eicCborAppendString(&cbor, "ProofOfOwnership");
+    eicCborAppendString(&cbor, docType);
+    eicCborAppendByteString(&cbor, challenge, challengeSize);
+    eicCborAppendBool(&cbor, testCredential);
+
+    uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE];
+    eicCborFinal(&cbor, cborSha256);
+    if (!eicOpsEcDsa(ctx->credentialPrivateKey, cborSha256, signatureOfToBeSigned)) {
+        eicDebug("Error signing proofOfDeletion");
+        return false;
+    }
+
+    return true;
+}
diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h
index d798962..7cad068 100644
--- a/identity/aidl/default/libeic/EicPresentation.h
+++ b/identity/aidl/default/libeic/EicPresentation.h
@@ -31,6 +31,8 @@
 #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65
 
 typedef struct {
+    int featureLevel;
+
     uint8_t storageKey[EIC_AES_128_KEY_SIZE];
     uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE];
 
@@ -79,12 +81,17 @@
     // SHA-256 for AdditionalData, updated for each entry.
     uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE];
 
+    // SHA-256 of ProofOfProvisioning. Set to NUL-bytes or initialized from CredentialKeys data
+    // if credential was created with feature version 202101 or later.
+    uint8_t proofOfProvisioningSha256[EIC_SHA256_DIGEST_SIZE];
+
     size_t expectedCborSizeAtEnd;
     EicCbor cbor;
 } EicPresentation;
 
 bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType,
-                         const uint8_t encryptedCredentialKeys[80]);
+                         const uint8_t* encryptedCredentialKeys,
+                         size_t encryptedCredentialKeysSize);
 
 bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, time_t now,
                                            uint8_t* publicKeyCert, size_t* publicKeyCertSize,
@@ -219,9 +226,19 @@
 // where content is set to the ProofOfDeletion CBOR.
 //
 bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType,
-                                     size_t proofOfDeletionCborSize,
+                                     const uint8_t* challenge, size_t challengeSize,
+                                     bool includeChallenge, size_t proofOfDeletionCborSize,
                                      uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]);
 
+// The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
+// the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
+// where content is set to the ProofOfOwnership CBOR.
+//
+bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential,
+                                   const uint8_t* challenge, size_t challengeSize,
+                                   size_t proofOfOwnershipCborSize,
+                                   uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c
index f16605c..3b4148e 100644
--- a/identity/aidl/default/libeic/EicProvisioning.c
+++ b/identity/aidl/default/libeic/EicProvisioning.c
@@ -26,10 +26,84 @@
     return true;
 }
 
+bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType,
+                                  const uint8_t* encryptedCredentialKeys,
+                                  size_t encryptedCredentialKeysSize) {
+    uint8_t credentialKeys[86];
+
+    // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86
+    // bytes (the additional data is the ProofOfProvisioning SHA-256). We need
+    // to support loading all feature versions.
+    //
+    bool expectPopSha256 = false;
+    if (encryptedCredentialKeysSize == 52 + 28) {
+        /* do nothing */
+    } else if (encryptedCredentialKeysSize == 86 + 28) {
+        expectPopSha256 = true;
+    } else {
+        eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize);
+        return false;
+    }
+
+    eicMemSet(ctx, '\0', sizeof(EicProvisioning));
+    ctx->testCredential = testCredential;
+
+    if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys,
+                                encryptedCredentialKeysSize,
+                                // DocType is the additionalAuthenticatedData
+                                (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) {
+        eicDebug("Error decrypting CredentialKeys");
+        return false;
+    }
+
+    // It's supposed to look like this;
+    //
+    // Feature version 202009:
+    //
+    //         CredentialKeys = [
+    //              bstr,   ; storageKey, a 128-bit AES key
+    //              bstr,   ; credentialPrivKey, the private key for credentialKey
+    //         ]
+    //
+    // Feature version 202101:
+    //
+    //         CredentialKeys = [
+    //              bstr,   ; storageKey, a 128-bit AES key
+    //              bstr,   ; credentialPrivKey, the private key for credentialKey
+    //              bstr    ; proofOfProvisioning SHA-256
+    //         ]
+    //
+    // where storageKey is 16 bytes, credentialPrivateKey is 32 bytes, and proofOfProvisioning
+    // SHA-256 is 32 bytes.
+    //
+    if (credentialKeys[0] != (expectPopSha256 ? 0x83 : 0x82) ||  // array of two or three elements
+        credentialKeys[1] != 0x50 ||                             // 16-byte bstr
+        credentialKeys[18] != 0x58 || credentialKeys[19] != 0x20) {  // 32-byte bstr
+        eicDebug("Invalid CBOR for CredentialKeys");
+        return false;
+    }
+    if (expectPopSha256) {
+        if (credentialKeys[52] != 0x58 || credentialKeys[53] != 0x20) {  // 32-byte bstr
+            eicDebug("Invalid CBOR for CredentialKeys");
+            return false;
+        }
+    }
+    eicMemCpy(ctx->storageKey, credentialKeys + 2, EIC_AES_128_KEY_SIZE);
+    eicMemCpy(ctx->credentialPrivateKey, credentialKeys + 20, EIC_P256_PRIV_KEY_SIZE);
+    // Note: We don't care about the previous ProofOfProvisioning SHA-256
+    ctx->isUpdate = true;
+    return true;
+}
+
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
                                         size_t applicationIdSize, uint8_t* publicKeyCert,
                                         size_t* publicKeyCertSize) {
+    if (ctx->isUpdate) {
+        eicDebug("Cannot create CredentialKey on update");
+        return false;
+    }
+
     if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
                                    applicationId, applicationIdSize, ctx->testCredential,
                                    publicKeyCert, publicKeyCertSize)) {
@@ -96,6 +170,9 @@
     eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedProofOfProvisioningSize);
     ctx->expectedCborSizeAtEnd = expectedProofOfProvisioningSize + ctx->cbor.size;
 
+    eicOpsSha256Init(&ctx->proofOfProvisioningDigester);
+    eicCborEnableSecondaryDigesterSha256(&ctx->cbor, &ctx->proofOfProvisioningDigester);
+
     eicCborAppendArray(&ctx->cbor, 5);
     eicCborAppendString(&ctx->cbor, "ProofOfProvisioning");
     eicCborAppendString(&ctx->cbor, docType);
@@ -260,14 +337,23 @@
 }
 
 bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType,
-                                            uint8_t encryptedCredentialKeys[80]) {
+                                            uint8_t* encryptedCredentialKeys,
+                                            size_t* encryptedCredentialKeysSize) {
     EicCbor cbor;
-    uint8_t cborBuf[52];
+    uint8_t cborBuf[86];
+
+    if (*encryptedCredentialKeysSize < 86 + 28) {
+        eicDebug("encryptedCredentialKeysSize is %zd which is insufficient");
+        return false;
+    }
 
     eicCborInit(&cbor, cborBuf, sizeof(cborBuf));
-    eicCborAppendArray(&cbor, 2);
+    eicCborAppendArray(&cbor, 3);
     eicCborAppendByteString(&cbor, ctx->storageKey, EIC_AES_128_KEY_SIZE);
     eicCborAppendByteString(&cbor, ctx->credentialPrivateKey, EIC_P256_PRIV_KEY_SIZE);
+    uint8_t popSha256[EIC_SHA256_DIGEST_SIZE];
+    eicOpsSha256Final(&ctx->proofOfProvisioningDigester, popSha256);
+    eicCborAppendByteString(&cbor, popSha256, EIC_SHA256_DIGEST_SIZE);
     if (cbor.size > sizeof(cborBuf)) {
         eicDebug("Exceeded buffer size");
         return false;
@@ -285,6 +371,7 @@
         eicDebug("Error encrypting CredentialKeys");
         return false;
     }
+    *encryptedCredentialKeysSize = cbor.size + 28;
 
     return true;
 }
diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h
index 836d16e..f064787 100644
--- a/identity/aidl/default/libeic/EicProvisioning.h
+++ b/identity/aidl/default/libeic/EicProvisioning.h
@@ -31,7 +31,7 @@
 #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32
 
 typedef struct {
-    // Set by eicCreateCredentialKey.
+    // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate()
     uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE];
 
     int numEntryCounts;
@@ -43,6 +43,7 @@
     size_t curEntrySize;
     size_t curEntryNumBytesReceived;
 
+    // Set by eicProvisioningInit() OR eicProvisioningInitForUpdate()
     uint8_t storageKey[EIC_AES_128_KEY_SIZE];
 
     size_t expectedCborSizeAtEnd;
@@ -50,13 +51,23 @@
     // SHA-256 for AdditionalData, updated for each entry.
     uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE];
 
+    // Digester just for ProofOfProvisioning (without Sig_structure).
+    EicSha256Ctx proofOfProvisioningDigester;
+
     EicCbor cbor;
 
     bool testCredential;
+
+    // Set to true if this is an update.
+    bool isUpdate;
 } EicProvisioning;
 
 bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential);
 
+bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType,
+                                  const uint8_t* encryptedCredentialKeys,
+                                  size_t encryptedCredentialKeysSize);
+
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
                                         size_t applicationIdSize, uint8_t* publicKeyCert,
@@ -107,14 +118,18 @@
 //   CredentialKeys = [
 //     bstr,   ; storageKey, a 128-bit AES key
 //     bstr    ; credentialPrivKey, the private key for credentialKey
+//     bstr    ; SHA-256(ProofOfProvisioning)
 //   ]
 //
+// for feature version 202101. For feature version 202009 the third field was not present.
+//
 // Since |storageKey| is 16 bytes and |credentialPrivKey| is 32 bytes, the
-// encoded CBOR for CredentialKeys is 52 bytes and consequently
-// |encryptedCredentialKeys| will be 52 + 28 = 80 bytes.
+// encoded CBOR for CredentialKeys is 86 bytes and consequently
+// |encryptedCredentialKeys| will be no longer than 86 + 28 = 114 bytes.
 //
 bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType,
-                                            uint8_t encryptedCredentialKeys[80]);
+                                            uint8_t* encryptedCredentialKeys,
+                                            size_t* encryptedCredentialKeysSize);
 
 #ifdef __cplusplus
 }
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 03966de..f487a64 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -4,13 +4,21 @@
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
+    cflags: [
+        "-Wno-deprecated-declarations",
+    ],
     srcs: [
-        "VtsHalIdentityEndToEndTest.cpp",
         "VtsIWritableIdentityCredentialTests.cpp",
-        "VtsIdentityTestUtils.cpp",
+        "Util.cpp",
         "VtsAttestationTests.cpp",
         "UserAuthTests.cpp",
         "ReaderAuthTests.cpp",
+        "DeleteCredentialTests.cpp",
+        "ProveOwnershipTests.cpp",
+        "UpdateCredentialTests.cpp",
+        "EndToEndTests.cpp",
+        "TestCredentialTests.cpp",
+        "AuthenticationKeyTests.cpp",
     ],
     shared_libs: [
         "libbinder",
@@ -22,9 +30,9 @@
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-cpp",
-        "android.hardware.keymaster-cpp",
-        "android.hardware.keymaster-ndk_platform",
+        "android.hardware.identity-V3-cpp",
+        "android.hardware.keymaster-V3-cpp",
+        "android.hardware.keymaster-V3-ndk_platform",
         "libkeymaster4support",
         "libkeymaster4_1support",
     ],
diff --git a/identity/aidl/vts/AuthenticationKeyTests.cpp b/identity/aidl/vts/AuthenticationKeyTests.cpp
new file mode 100644
index 0000000..bda3e70
--- /dev/null
+++ b/identity/aidl/vts/AuthenticationKeyTests.cpp
@@ -0,0 +1,194 @@
+/*
+ * 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 "TestCredentialTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class AuthenticationKeyTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        string halInstanceName = GetParam();
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(halInstanceName.c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+TEST_P(AuthenticationKeyTests, proofOfProvisionInAuthKeyCert) {
+    if (halApiVersion_ < 3) {
+        GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_;
+    }
+
+    string docType = "org.iso.18013-5.2019.mdl";
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_
+                        ->createCredential(docType,
+                                           true,  // testCredential
+                                           &wc)
+                        .isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    vector<uint8_t> credentialPubKey;
+    credentialPubKey = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 112;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    vector<uint8_t> encryptedData;
+    vector<uint8_t> tstrLastName = cppbor::Tstr("Turing").encode();
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk());
+    ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    vector<uint8_t> credentialData;
+    Status status = wc->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 1,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'ns' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Turing',\n"
+            "        'accessControlProfiles' : [1, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+    // Make sure it's signed by the CredentialKey in the returned cert chain.
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey));
+
+    // Now get a credential and have it create AuthenticationKey so we can check
+    // the certificate.
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData, &credential)
+                        .isOk());
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+    optional<vector<uint8_t>> signingPubKey =
+            support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate);
+    EXPECT_TRUE(signingPubKey);
+
+    // SHA-256(ProofOfProvisioning) is embedded in CBOR with the following CDDL
+    //
+    //   ProofOfBinding = [
+    //     "ProofOfBinding",
+    //     bstr,                  // Contains the SHA-256 of ProofOfProvisioning
+    //   ]
+    //
+    // Check that.
+    //
+    optional<vector<uint8_t>> proofOfBinding = support::certificateGetExtension(
+            signingKeyCertificate.encodedCertificate, "1.3.6.1.4.1.11129.2.1.26");
+    ASSERT_TRUE(proofOfBinding);
+    auto [item, _, message] = cppbor::parse(proofOfBinding.value());
+    ASSERT_NE(item, nullptr) << message;
+    const cppbor::Array* arrayItem = item->asArray();
+    ASSERT_NE(arrayItem, nullptr);
+    ASSERT_EQ(arrayItem->size(), 2);
+    const cppbor::Tstr* strItem = (*arrayItem)[0]->asTstr();
+    ASSERT_NE(strItem, nullptr);
+    EXPECT_EQ(strItem->value(), "ProofOfBinding");
+    const cppbor::Bstr* popSha256Item = (*arrayItem)[1]->asBstr();
+    ASSERT_NE(popSha256Item, nullptr);
+    EXPECT_EQ(popSha256Item->value(), support::sha256(proofOfProvisioning.value()));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AuthenticationKeyTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, AuthenticationKeyTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp
new file mode 100644
index 0000000..1d30067
--- /dev/null
+++ b/identity/aidl/vts/DeleteCredentialTests.cpp
@@ -0,0 +1,169 @@
+/*
+ * 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 "DeleteCredentialTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class DeleteCredentialTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(GetParam().c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    void provisionData();
+
+    // Set by provisionData
+    vector<uint8_t> credentialData_;
+    vector<uint8_t> credentialPubKey_;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+void DeleteCredentialTests::provisionData() {
+    string docType = "org.iso.18013-5.2019.mdl";
+    bool testCredential = true;
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    credentialPubKey_ = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 106;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+    vector<uint8_t> encryptedData;
+    ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+}
+
+TEST_P(DeleteCredentialTests, Delete) {
+    provisionData();
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &credential)
+                        .isOk());
+
+    vector<uint8_t> proofOfDeletionSignature;
+    ASSERT_TRUE(credential->deleteCredential(&proofOfDeletionSignature).isOk());
+    optional<vector<uint8_t>> proofOfDeletion =
+            support::coseSignGetPayload(proofOfDeletionSignature);
+    ASSERT_TRUE(proofOfDeletion);
+    string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {});
+    EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', true, ]", cborPretty);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {},  // Additional data
+                                                 credentialPubKey_));
+}
+
+TEST_P(DeleteCredentialTests, DeleteWithChallenge) {
+    if (halApiVersion_ < 3) {
+        GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_;
+    }
+
+    provisionData();
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &credential)
+                        .isOk());
+
+    vector<uint8_t> challenge = {65, 66, 67};
+    vector<uint8_t> proofOfDeletionSignature;
+    ASSERT_TRUE(
+            credential->deleteCredentialWithChallenge(challenge, &proofOfDeletionSignature).isOk());
+    optional<vector<uint8_t>> proofOfDeletion =
+            support::coseSignGetPayload(proofOfDeletionSignature);
+    ASSERT_TRUE(proofOfDeletion);
+    string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {});
+    EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {0x41, 0x42, 0x43}, true, ]",
+              cborPretty);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {},  // Additional data
+                                                 credentialPubKey_));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DeleteCredentialTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, DeleteCredentialTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp b/identity/aidl/vts/EndToEndTests.cpp
similarity index 93%
rename from identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp
rename to identity/aidl/vts/EndToEndTests.cpp
index cdecb97..5798b4c 100644
--- a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp
+++ b/identity/aidl/vts/EndToEndTests.cpp
@@ -29,7 +29,7 @@
 #include <map>
 #include <tuple>
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
 
 namespace android::hardware::identity {
 
@@ -50,18 +50,20 @@
 
 using test_utils::validateAttestationCertificate;
 
-class IdentityAidl : public testing::TestWithParam<std::string> {
+class EndToEndTests : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
         credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
                 String16(GetParam().c_str()));
         ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
     }
 
     sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
 };
 
-TEST_P(IdentityAidl, hardwareInformation) {
+TEST_P(EndToEndTests, hardwareInformation) {
     HardwareInformation info;
     ASSERT_TRUE(credentialStore_->getHardwareInformation(&info).isOk());
     ASSERT_GT(info.credentialStoreName.size(), 0);
@@ -69,20 +71,21 @@
     ASSERT_GE(info.dataChunkSize, 256);
 }
 
-tuple<bool, string, vector<uint8_t>, vector<uint8_t>> extractFromTestCredentialData(
-        const vector<uint8_t>& credentialData) {
+tuple<bool, string, vector<uint8_t>, vector<uint8_t>, vector<uint8_t>>
+extractFromTestCredentialData(const vector<uint8_t>& credentialData) {
     string docType;
     vector<uint8_t> storageKey;
     vector<uint8_t> credentialPrivKey;
+    vector<uint8_t> sha256Pop;
 
     auto [item, _, message] = cppbor::parse(credentialData);
     if (item == nullptr) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
 
     const cppbor::Array* arrayItem = item->asArray();
     if (arrayItem == nullptr || arrayItem->size() != 3) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
 
     const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr();
@@ -92,7 +95,7 @@
     const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr();
     if (docTypeItem == nullptr || testCredentialItem == nullptr ||
         encryptedCredentialKeysItem == nullptr) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
 
     docType = docTypeItem->value();
@@ -103,28 +106,38 @@
     optional<vector<uint8_t>> decryptedCredentialKeys =
             support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec);
     if (!decryptedCredentialKeys) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
 
     auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value());
     if (dckItem == nullptr) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
     const cppbor::Array* dckArrayItem = dckItem->asArray();
-    if (dckArrayItem == nullptr || dckArrayItem->size() != 2) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+    if (dckArrayItem == nullptr) {
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
+    }
+    if (dckArrayItem->size() < 2) {
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
     const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr();
     const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr();
     if (storageKeyItem == nullptr || credentialPrivKeyItem == nullptr) {
-        return make_tuple(false, docType, storageKey, credentialPrivKey);
+        return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
     }
     storageKey = storageKeyItem->value();
     credentialPrivKey = credentialPrivKeyItem->value();
-    return make_tuple(true, docType, storageKey, credentialPrivKey);
+    if (dckArrayItem->size() == 3) {
+        const cppbor::Bstr* sha256PopItem = (*dckArrayItem)[2]->asBstr();
+        if (sha256PopItem == nullptr) {
+            return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop);
+        }
+        sha256Pop = sha256PopItem->value();
+    }
+    return make_tuple(true, docType, storageKey, credentialPrivKey, sha256Pop);
 }
 
-TEST_P(IdentityAidl, createAndRetrieveCredential) {
+TEST_P(EndToEndTests, createAndRetrieveCredential) {
     // First, generate a key-pair for the reader since its public key will be
     // part of the request data.
     vector<uint8_t> readerKey;
@@ -277,8 +290,9 @@
 
     // Extract doctype, storage key, and credentialPrivKey from credentialData... this works
     // only because we asked for a test-credential meaning that the HBK is all zeroes.
-    auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey] =
+    auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey, exSha256Pop] =
             extractFromTestCredentialData(credentialData);
+
     ASSERT_TRUE(exSuccess);
     ASSERT_EQ(exDocType, "org.iso.18013-5.2019.mdl");
     // ... check that the public key derived from the private key matches what was
@@ -291,6 +305,13 @@
     ASSERT_TRUE(exCredentialPubKey);
     ASSERT_EQ(exCredentialPubKey.value(), credentialPubKey.value());
 
+    // Starting with API version 3 (feature version 202101) we require SHA-256(ProofOfProvisioning)
+    // to be in CredentialKeys (which is stored encrypted in CredentialData). Check
+    // that it's there with the expected value.
+    if (halApiVersion_ >= 3) {
+        ASSERT_EQ(exSha256Pop, support::sha256(proofOfProvisioning.value()));
+    }
+
     // Now that the credential has been provisioned, read it back and check the
     // correct data is returned.
     sp<IIdentityCredential> credential;
@@ -498,13 +519,11 @@
     EXPECT_EQ(mac, calculatedMac);
 }
 
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IdentityAidl);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EndToEndTests);
 INSTANTIATE_TEST_SUITE_P(
-        Identity, IdentityAidl,
+        Identity, EndToEndTests,
         testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
         android::PrintInstanceNameToString);
-// INSTANTIATE_TEST_SUITE_P(Identity, IdentityAidl,
-// testing::Values("android.hardware.identity.IIdentityCredentialStore/default"));
 
 }  // namespace android::hardware::identity
 
diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp
new file mode 100644
index 0000000..d1a3d39
--- /dev/null
+++ b/identity/aidl/vts/ProveOwnershipTests.cpp
@@ -0,0 +1,146 @@
+/*
+ * 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 "ProveOwnershipTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class ProveOwnershipTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(GetParam().c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    void provisionData();
+
+    // Set by provisionData
+    vector<uint8_t> credentialData_;
+    vector<uint8_t> credentialPubKey_;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+void ProveOwnershipTests::provisionData() {
+    string docType = "org.iso.18013-5.2019.mdl";
+    bool testCredential = true;
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    credentialPubKey_ = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 106;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+    vector<uint8_t> encryptedData;
+    ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+}
+
+TEST_P(ProveOwnershipTests, proveOwnership) {
+    if (halApiVersion_ < 3) {
+        GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_;
+    }
+
+    provisionData();
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &credential)
+                        .isOk());
+
+    vector<uint8_t> challenge = {17, 18};
+    vector<uint8_t> proofOfOwnershipSignature;
+    ASSERT_TRUE(credential->proveOwnership(challenge, &proofOfOwnershipSignature).isOk());
+    optional<vector<uint8_t>> proofOfOwnership =
+            support::coseSignGetPayload(proofOfOwnershipSignature);
+    ASSERT_TRUE(proofOfOwnership);
+    string cborPretty = support::cborPrettyPrint(proofOfOwnership.value(), 32, {});
+    EXPECT_EQ("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {0x11, 0x12}, true, ]", cborPretty);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfOwnershipSignature, {},  // Additional data
+                                                 credentialPubKey_));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProveOwnershipTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, ProveOwnershipTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/identity/aidl/vts/ReaderAuthTests.cpp b/identity/aidl/vts/ReaderAuthTests.cpp
index 0a9fdc0..7656c8e 100644
--- a/identity/aidl/vts/ReaderAuthTests.cpp
+++ b/identity/aidl/vts/ReaderAuthTests.cpp
@@ -32,7 +32,7 @@
 #include <map>
 #include <utility>
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
 
 namespace android::hardware::identity {
 
@@ -123,9 +123,9 @@
                                    const vector<uint8_t>& signingKey) {
     time_t validityNotBefore = 0;
     time_t validityNotAfter = 0xffffffff;
-    optional<vector<uint8_t>> cert =
-            support::ecPublicKeyGenerateCertificate(publicKey, signingKey, "24601", "Issuer",
-                                                    "Subject", validityNotBefore, validityNotAfter);
+    optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
+            publicKey, signingKey, "24601", "Issuer", "Subject", validityNotBefore,
+            validityNotAfter, {});
     return cert.value();
 }
 
diff --git a/identity/aidl/vts/TestCredentialTests.cpp b/identity/aidl/vts/TestCredentialTests.cpp
new file mode 100644
index 0000000..d53de3b
--- /dev/null
+++ b/identity/aidl/vts/TestCredentialTests.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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 "TestCredentialTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class TestCredentialTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        string halInstanceName = GetParam();
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(halInstanceName.c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+TEST_P(TestCredentialTests, testCredential) {
+    string docType = "org.iso.18013-5.2019.mdl";
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_
+                        ->createCredential(docType,
+                                           true,  // testCredential
+                                           &wc)
+                        .isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    vector<uint8_t> credentialPubKey;
+    credentialPubKey = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 112;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    vector<uint8_t> encryptedData;
+    vector<uint8_t> tstrLastName = cppbor::Tstr("Turing").encode();
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk());
+    ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    vector<uint8_t> credentialData;
+    Status status = wc->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 1,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'ns' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Turing',\n"
+            "        'accessControlProfiles' : [1, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+    // Make sure it's signed by the CredentialKey in the returned cert chain.
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey));
+
+    // Now analyze credentialData..
+    auto [item, _, message] = cppbor::parse(credentialData);
+    ASSERT_NE(item, nullptr);
+    const cppbor::Array* arrayItem = item->asArray();
+    ASSERT_NE(arrayItem, nullptr);
+    ASSERT_EQ(arrayItem->size(), 3);
+    const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr();
+    const cppbor::Bool* testCredentialItem =
+            ((*arrayItem)[1]->asSimple() != nullptr ? ((*arrayItem)[1]->asSimple()->asBool())
+                                                    : nullptr);
+    EXPECT_EQ(docTypeItem->value(), docType);
+    EXPECT_EQ(testCredentialItem->value(), true);
+
+    vector<uint8_t> hardwareBoundKey = support::getTestHardwareBoundKey();
+    const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr();
+    const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value();
+    const vector<uint8_t> docTypeVec(docType.begin(), docType.end());
+    optional<vector<uint8_t>> decryptedCredentialKeys =
+            support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec);
+    ASSERT_TRUE(decryptedCredentialKeys);
+    auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value());
+    ASSERT_NE(dckItem, nullptr) << dckMessage;
+    const cppbor::Array* dckArrayItem = dckItem->asArray();
+    ASSERT_NE(dckArrayItem, nullptr);
+    // In HAL API version 1 and 2 this array has two items, in version 3 and later it has three.
+    if (halApiVersion_ < 3) {
+        ASSERT_EQ(dckArrayItem->size(), 2);
+    } else {
+        ASSERT_EQ(dckArrayItem->size(), 3);
+    }
+    const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr();
+    const vector<uint8_t> storageKey = storageKeyItem->value();
+    // const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr();
+    // const vector<uint8_t> credentialPrivKey = credentialPrivKeyItem->value();
+
+    // Check storageKey can be used to decrypt |encryptedData| to |tstrLastName|
+    vector<uint8_t> additionalData = cppbor::Map()
+                                             .add("Namespace", "ns")
+                                             .add("Name", "Last name")
+                                             .add("AccessControlProfileIds", cppbor::Array().add(1))
+                                             .encode();
+    optional<vector<uint8_t>> decryptedDataItemValue =
+            support::decryptAes128Gcm(storageKey, encryptedData, additionalData);
+    ASSERT_TRUE(decryptedDataItemValue);
+    EXPECT_EQ(decryptedDataItemValue.value(), tstrLastName);
+
+    // Check that SHA-256(ProofOfProvisioning) matches (only in HAL API version 3)
+    if (halApiVersion_ >= 3) {
+        const cppbor::Bstr* popSha256Item = (*dckArrayItem)[2]->asBstr();
+        const vector<uint8_t> popSha256 = popSha256Item->value();
+        ASSERT_EQ(popSha256, support::sha256(proofOfProvisioning.value()));
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TestCredentialTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, TestCredentialTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/identity/aidl/vts/UpdateCredentialTests.cpp b/identity/aidl/vts/UpdateCredentialTests.cpp
new file mode 100644
index 0000000..9c5ca55
--- /dev/null
+++ b/identity/aidl/vts/UpdateCredentialTests.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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 "UpdateCredentialTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class UpdateCredentialTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(GetParam().c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    void provisionData();
+
+    // Set by provisionData
+    vector<uint8_t> credentialData_;
+    vector<uint8_t> credentialPubKey_;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+void UpdateCredentialTests::provisionData() {
+    string docType = "org.iso.18013-5.2019.mdl";
+    bool testCredential = true;
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    credentialPubKey_ = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 112;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    vector<uint8_t> encryptedData;
+    vector<uint8_t> tstrLastName = cppbor::Tstr("Prince").encode();
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk());
+    ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 1,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'ns' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Prince',\n"
+            "        'accessControlProfiles' : [1, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+    // Make sure it's signed by the CredentialKey in the returned cert chain.
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey_));
+}
+
+TEST_P(UpdateCredentialTests, updateCredential) {
+    if (halApiVersion_ < 3) {
+        GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_;
+    }
+
+    provisionData();
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &credential)
+                        .isOk());
+
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credential->updateCredential(&wc).isOk());
+
+    // Getting an attestation cert should fail (because it's an update).
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    Status result = wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                                  &certChain);
+    ASSERT_FALSE(result.isOk());
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    // Now provision some new data...
+    //
+    size_t proofOfProvisioningSize = 117;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(2, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    vector<uint8_t> encryptedData;
+    vector<uint8_t> tstrLastName = cppbor::Tstr("T.A.F.K.A.P").encode();
+    ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Last name", tstrLastName.size()).isOk());
+    ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 2,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'ns' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'T.A.F.K.A.P',\n"
+            "        'accessControlProfiles' : [2, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+    // Make sure it's signed by the same CredentialKey we originally provisioned with.
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey_));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UpdateCredentialTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, UpdateCredentialTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/identity/aidl/vts/UserAuthTests.cpp b/identity/aidl/vts/UserAuthTests.cpp
index 327493c..ef89d1c 100644
--- a/identity/aidl/vts/UserAuthTests.cpp
+++ b/identity/aidl/vts/UserAuthTests.cpp
@@ -32,7 +32,7 @@
 #include <map>
 #include <utility>
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
 
 namespace android::hardware::identity {
 
@@ -145,7 +145,7 @@
     EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
 }
 
-// From ReaderAuthTest.cpp - TODO: consolidate with VtsIdentityTestUtils.h
+// From ReaderAuthTest.cpp - TODO: consolidate with Util.h
 pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey();
 vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey,
                                    const vector<uint8_t>& signingKey);
diff --git a/identity/aidl/vts/VtsIdentityTestUtils.cpp b/identity/aidl/vts/Util.cpp
similarity index 98%
rename from identity/aidl/vts/VtsIdentityTestUtils.cpp
rename to identity/aidl/vts/Util.cpp
index 3b10651..1148cb0 100644
--- a/identity/aidl/vts/VtsIdentityTestUtils.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -14,15 +14,18 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsIdentityTestUtils"
+#define LOG_TAG "Util"
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
+
+#include <android-base/logging.h>
 
 #include <aidl/Gtest.h>
-#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
 #include <keymaster/km_openssl/openssl_utils.h>
 #include <keymasterV4_1/attestation_record.h>
 #include <charconv>
+
 #include <map>
 
 namespace android::hardware::identity::test_utils {
@@ -35,6 +38,7 @@
 
 using ::android::sp;
 using ::android::String16;
+using ::android::base::StringPrintf;
 using ::android::binder::Status;
 using ::keymaster::X509_Ptr;
 
@@ -86,7 +90,7 @@
 
     return support::ecPublicKeyGenerateCertificate(readerPublicKey.value(), readerKey.value(),
                                                    serialDecimal, issuer, subject,
-                                                   validityNotBefore, validityNotAfter);
+                                                   validityNotBefore, validityNotAfter, {});
 }
 
 optional<vector<SecureAccessControlProfile>> addAccessControlProfiles(
diff --git a/identity/aidl/vts/VtsIdentityTestUtils.h b/identity/aidl/vts/Util.h
similarity index 99%
rename from identity/aidl/vts/VtsIdentityTestUtils.h
rename to identity/aidl/vts/Util.h
index 85c24f8..80e52a2 100644
--- a/identity/aidl/vts/VtsIdentityTestUtils.h
+++ b/identity/aidl/vts/Util.h
@@ -21,6 +21,7 @@
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
 #include <cppbor.h>
 #include <cppbor_parse.h>
+#include <gtest/gtest.h>
 
 namespace android::hardware::identity::test_utils {
 
diff --git a/identity/aidl/vts/VtsAttestationTests.cpp b/identity/aidl/vts/VtsAttestationTests.cpp
index 5529853..e12fe05 100644
--- a/identity/aidl/vts/VtsAttestationTests.cpp
+++ b/identity/aidl/vts/VtsAttestationTests.cpp
@@ -29,7 +29,7 @@
 #include <future>
 #include <map>
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
 
 namespace android::hardware::identity {
 
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index 1629a0c..cc63c48 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -29,7 +29,7 @@
 #include <future>
 #include <map>
 
-#include "VtsIdentityTestUtils.h"
+#include "Util.h"
 
 namespace android::hardware::identity {
 
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 3aa5bb6..3b91de6 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -18,6 +18,7 @@
 #define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
 
 #include <cstdint>
+#include <map>
 #include <optional>
 #include <string>
 #include <tuple>
@@ -29,11 +30,12 @@
 namespace identity {
 namespace support {
 
+using ::std::map;
 using ::std::optional;
+using ::std::pair;
 using ::std::string;
 using ::std::tuple;
 using ::std::vector;
-using ::std::pair;
 
 // The semantic tag for a bstr which includes Encoded CBOR (RFC 7049, section 2.4)
 const int kSemanticTagEncodedCbor = 24;
@@ -221,6 +223,11 @@
 //
 optional<pair<time_t, time_t>> certificateGetValidity(const vector<uint8_t>& x509Certificate);
 
+// Looks for an extension with OID in |oidStr| which must be an stored as an OCTET STRING.
+//
+optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate,
+                                                  const string& oidStr);
+
 // Generates a X.509 certificate for |publicKey| (which must be in the format
 // returned by ecKeyPairGetPublicKey()).
 //
@@ -230,7 +237,8 @@
 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
         const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
         const string& serialDecimal, const string& issuer, const string& subject,
-        time_t validityNotBefore, time_t validityNotAfter);
+        time_t validityNotBefore, time_t validityNotAfter,
+        const map<string, vector<uint8_t>>& extensions);
 
 // Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
 // format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 093120d..38348ac 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -344,15 +344,22 @@
 // Crypto functionality / abstraction.
 // ---------------------------------------------------------------------------
 
-struct EVP_CIPHER_CTX_Deleter {
-    void operator()(EVP_CIPHER_CTX* ctx) const {
-        if (ctx != nullptr) {
-            EVP_CIPHER_CTX_free(ctx);
-        }
-    }
-};
-
-using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
+using EvpCipherCtxPtr = bssl::UniquePtr<EVP_CIPHER_CTX>;
+using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>;
+using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
+using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>;
+using EC_GROUP_Ptr = bssl::UniquePtr<EC_GROUP>;
+using EC_POINT_Ptr = bssl::UniquePtr<EC_POINT>;
+using ECDSA_SIG_Ptr = bssl::UniquePtr<ECDSA_SIG>;
+using X509_Ptr = bssl::UniquePtr<X509>;
+using PKCS12_Ptr = bssl::UniquePtr<PKCS12>;
+using BIGNUM_Ptr = bssl::UniquePtr<BIGNUM>;
+using ASN1_INTEGER_Ptr = bssl::UniquePtr<ASN1_INTEGER>;
+using ASN1_TIME_Ptr = bssl::UniquePtr<ASN1_TIME>;
+using ASN1_OCTET_STRING_Ptr = bssl::UniquePtr<ASN1_OCTET_STRING>;
+using ASN1_OBJECT_Ptr = bssl::UniquePtr<ASN1_OBJECT>;
+using X509_NAME_Ptr = bssl::UniquePtr<X509_NAME>;
+using X509_EXTENSION_Ptr = bssl::UniquePtr<X509_EXTENSION>;
 
 // bool getRandom(size_t numBytes, vector<uint8_t>& output) {
 optional<vector<uint8_t>> getRandom(size_t numBytes) {
@@ -534,115 +541,6 @@
     return encryptedData;
 }
 
-struct EC_KEY_Deleter {
-    void operator()(EC_KEY* key) const {
-        if (key != nullptr) {
-            EC_KEY_free(key);
-        }
-    }
-};
-using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
-
-struct EVP_PKEY_Deleter {
-    void operator()(EVP_PKEY* key) const {
-        if (key != nullptr) {
-            EVP_PKEY_free(key);
-        }
-    }
-};
-using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
-
-struct EVP_PKEY_CTX_Deleter {
-    void operator()(EVP_PKEY_CTX* ctx) const {
-        if (ctx != nullptr) {
-            EVP_PKEY_CTX_free(ctx);
-        }
-    }
-};
-using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
-
-struct EC_GROUP_Deleter {
-    void operator()(EC_GROUP* group) const {
-        if (group != nullptr) {
-            EC_GROUP_free(group);
-        }
-    }
-};
-using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
-
-struct EC_POINT_Deleter {
-    void operator()(EC_POINT* point) const {
-        if (point != nullptr) {
-            EC_POINT_free(point);
-        }
-    }
-};
-
-using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
-
-struct ECDSA_SIG_Deleter {
-    void operator()(ECDSA_SIG* sig) const {
-        if (sig != nullptr) {
-            ECDSA_SIG_free(sig);
-        }
-    }
-};
-using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
-
-struct X509_Deleter {
-    void operator()(X509* x509) const {
-        if (x509 != nullptr) {
-            X509_free(x509);
-        }
-    }
-};
-using X509_Ptr = unique_ptr<X509, X509_Deleter>;
-
-struct PKCS12_Deleter {
-    void operator()(PKCS12* pkcs12) const {
-        if (pkcs12 != nullptr) {
-            PKCS12_free(pkcs12);
-        }
-    }
-};
-using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
-
-struct BIGNUM_Deleter {
-    void operator()(BIGNUM* bignum) const {
-        if (bignum != nullptr) {
-            BN_free(bignum);
-        }
-    }
-};
-using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
-
-struct ASN1_INTEGER_Deleter {
-    void operator()(ASN1_INTEGER* value) const {
-        if (value != nullptr) {
-            ASN1_INTEGER_free(value);
-        }
-    }
-};
-using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
-
-struct ASN1_TIME_Deleter {
-    void operator()(ASN1_TIME* value) const {
-        if (value != nullptr) {
-            ASN1_TIME_free(value);
-        }
-    }
-};
-using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
-
-struct X509_NAME_Deleter {
-    void operator()(X509_NAME* value) const {
-        if (value != nullptr) {
-            X509_NAME_free(value);
-        }
-    }
-};
-using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
-
 vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) {
     vector<uint8_t> ret;
     for (const vector<uint8_t>& certificate : certificateChain) {
@@ -1221,8 +1119,19 @@
         return {};
     }
     vector<uint8_t> privateKey;
-    privateKey.resize(BN_num_bytes(bignum));
-    BN_bn2bin(bignum, privateKey.data());
+
+    // Note that this may return fewer than 32 bytes so pad with zeroes since we
+    // want to always return 32 bytes.
+    size_t numBytes = BN_num_bytes(bignum);
+    if (numBytes > 32) {
+        LOG(ERROR) << "Size is " << numBytes << ", expected this to be 32 or less";
+        return {};
+    }
+    privateKey.resize(32);
+    for (size_t n = 0; n < 32 - numBytes; n++) {
+        privateKey[n] = 0x00;
+    }
+    BN_bn2bin(bignum, privateKey.data() + 32 - numBytes);
     return privateKey;
 }
 
@@ -1379,7 +1288,8 @@
 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
         const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
         const string& serialDecimal, const string& issuer, const string& subject,
-        time_t validityNotBefore, time_t validityNotAfter) {
+        time_t validityNotBefore, time_t validityNotAfter,
+        const map<string, vector<uint8_t>>& extensions) {
     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
@@ -1482,6 +1392,32 @@
         return {};
     }
 
+    for (auto const& [oidStr, blob] : extensions) {
+        ASN1_OBJECT_Ptr oid(
+                OBJ_txt2obj(oidStr.c_str(), 1));  // accept numerical dotted string form only
+        if (!oid.get()) {
+            LOG(ERROR) << "Error setting OID";
+            return {};
+        }
+        ASN1_OCTET_STRING_Ptr octetString(ASN1_OCTET_STRING_new());
+        if (!ASN1_OCTET_STRING_set(octetString.get(), blob.data(), blob.size())) {
+            LOG(ERROR) << "Error setting octet string for extension";
+            return {};
+        }
+
+        X509_EXTENSION_Ptr extension = X509_EXTENSION_Ptr(X509_EXTENSION_new());
+        extension.reset(X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */,
+                                                     octetString.get()));
+        if (!extension.get()) {
+            LOG(ERROR) << "Error setting extension";
+            return {};
+        }
+        if (!X509_add_ext(x509.get(), extension.get(), -1)) {
+            LOG(ERROR) << "Error adding extension";
+            return {};
+        }
+    }
+
     if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
         LOG(ERROR) << "Error signing X509 certificate";
         return {};
@@ -1650,6 +1586,44 @@
     return publicKey;
 }
 
+optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate,
+                                                  const string& oidStr) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(x509Certificate, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    ASN1_OBJECT_Ptr oid(
+            OBJ_txt2obj(oidStr.c_str(), 1));  // accept numerical dotted string form only
+    if (!oid.get()) {
+        LOG(ERROR) << "Error setting OID";
+        return {};
+    }
+
+    int location = X509_get_ext_by_OBJ(certs[0].get(), oid.get(), -1 /* search from beginning */);
+    if (location == -1) {
+        return {};
+    }
+
+    X509_EXTENSION* ext = X509_get_ext(certs[0].get(), location);
+    if (ext == nullptr) {
+        return {};
+    }
+
+    ASN1_OCTET_STRING* octetString = X509_EXTENSION_get_data(ext);
+    if (octetString == nullptr) {
+        return {};
+    }
+    vector<uint8_t> result;
+    result.resize(octetString->length);
+    memcpy(result.data(), octetString->data, octetString->length);
+    return result;
+}
+
 optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate) {
     vector<X509_Ptr> certs;
     if (!parseX509Certificates(x509Certificate, certs)) {
diff --git a/identity/support/tests/IdentityCredentialSupportTest.cpp b/identity/support/tests/IdentityCredentialSupportTest.cpp
index 266f263..509133c 100644
--- a/identity/support/tests/IdentityCredentialSupportTest.cpp
+++ b/identity/support/tests/IdentityCredentialSupportTest.cpp
@@ -271,7 +271,7 @@
         optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
 
         optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
-                pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+                pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {});
         certs.push_back(cert.value());
     }
     return support::certificateChainJoin(certs);
@@ -338,7 +338,7 @@
     ASSERT_TRUE(pubKey);
 
     optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
-            pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+            pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {});
 
     optional<vector<uint8_t>> extractedPubKey =
             support::certificateChainGetTopMostKey(cert.value());
@@ -358,7 +358,7 @@
     optional<vector<uint8_t>> otherPubKey = support::ecKeyPairGetPublicKey(keyPair.value());
     ASSERT_TRUE(otherPubKey);
     optional<vector<uint8_t>> otherCert = support::ecPublicKeyGenerateCertificate(
-            otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+            otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {});
 
     // Now both cert and otherCert are two distinct certificates. Let's make a
     // chain and check that certificateChainSplit() works as expected.
diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp
index ae3f463..4e43ba9 100644
--- a/light/aidl/default/Android.bp
+++ b/light/aidl/default/Android.bp
@@ -7,7 +7,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.light-ndk_platform",
+        "android.hardware.light-V1-ndk_platform",
     ],
     srcs: [
         "Lights.cpp",
diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp
index aa4719b..4c9356c 100644
--- a/light/aidl/vts/functional/Android.bp
+++ b/light/aidl/vts/functional/Android.bp
@@ -27,7 +27,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.light-cpp",
+        "android.hardware.light-V1-cpp",
     ],
     test_suites: [
         "vts",
diff --git a/light/utils/Android.bp b/light/utils/Android.bp
index e901129..871f983 100644
--- a/light/utils/Android.bp
+++ b/light/utils/Android.bp
@@ -28,6 +28,6 @@
         "libutils",
     ],
     static_libs: [
-        "android.hardware.light-cpp",
+        "android.hardware.light-V1-cpp",
     ],
 }
diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp
index 52f88c8..8d97bfc 100644
--- a/memtrack/aidl/default/Android.bp
+++ b/memtrack/aidl/default/Android.bp
@@ -21,7 +21,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.memtrack-ndk_platform",
+        "android.hardware.memtrack-V1-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/memtrack/aidl/default/Memtrack.cpp b/memtrack/aidl/default/Memtrack.cpp
index 7361719..000b25c 100644
--- a/memtrack/aidl/default/Memtrack.cpp
+++ b/memtrack/aidl/default/Memtrack.cpp
@@ -35,6 +35,8 @@
 
 ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) {
     _aidl_return->clear();
+    DeviceInfo dev_info = {.id = 0, .name = "virtio_gpu"};
+    _aidl_return->emplace_back(dev_info);
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp
index ea36677..df87db8 100644
--- a/memtrack/aidl/vts/Android.bp
+++ b/memtrack/aidl/vts/Android.bp
@@ -7,9 +7,10 @@
     srcs: ["VtsHalMemtrackTargetTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
+        "libvintf",
     ],
     static_libs: [
-        "android.hardware.memtrack-unstable-ndk_platform",
+        "android.hardware.memtrack-V1-ndk_platform",
     ],
     test_suites: [
         "vts-core",
diff --git a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
index 4d33101..2393c56 100644
--- a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
+++ b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
@@ -21,11 +21,15 @@
 #include <aidl/android/hardware/memtrack/MemtrackType.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <vintf/VintfObject.h>
 
 using aidl::android::hardware::memtrack::DeviceInfo;
 using aidl::android::hardware::memtrack::IMemtrack;
 using aidl::android::hardware::memtrack::MemtrackRecord;
 using aidl::android::hardware::memtrack::MemtrackType;
+using android::vintf::KernelVersion;
+using android::vintf::RuntimeInfo;
+using android::vintf::VintfObject;
 
 class MemtrackAidlTest : public testing::TestWithParam<std::string> {
   public:
@@ -75,7 +79,23 @@
 
     auto status = memtrack_->getGpuDeviceInfo(&device_info);
 
+    // Devices with < 5.10 kernels aren't required to provide an implementation of
+    // getGpuDeviceInfo(), and can return EX_UNSUPPORTED_OPERATION
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        KernelVersion min_kernel_version = KernelVersion(5, 10, 0);
+        KernelVersion kernel_version = VintfObject::GetInstance()
+                                               ->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION)
+                                               ->kernelVersion();
+        EXPECT_LT(kernel_version, min_kernel_version)
+                << "Devices with 5.10 or later kernels must implement getGpuDeviceInfo()";
+        return;
+    }
+
     EXPECT_TRUE(status.isOk());
+    EXPECT_FALSE(device_info.empty());
+    for (auto device : device_info) {
+        EXPECT_FALSE(device.name.empty());
+    }
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemtrackAidlTest);
diff --git a/oemlock/aidl/default/Android.bp b/oemlock/aidl/default/Android.bp
index b9872d7..464b0a3 100644
--- a/oemlock/aidl/default/Android.bp
+++ b/oemlock/aidl/default/Android.bp
@@ -25,7 +25,7 @@
         "OemLock.cpp",
     ],
     shared_libs: [
-        "android.hardware.oemlock-ndk_platform",
+        "android.hardware.oemlock-V1-ndk_platform",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/oemlock/aidl/vts/Android.bp b/oemlock/aidl/vts/Android.bp
index a13dbe2..18b53c2 100644
--- a/oemlock/aidl/vts/Android.bp
+++ b/oemlock/aidl/vts/Android.bp
@@ -25,7 +25,7 @@
         "libbinder_ndk",
         "libbase",
     ],
-    static_libs: ["android.hardware.oemlock-ndk_platform"],
+    static_libs: ["android.hardware.oemlock-V1-ndk_platform"],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index 07cd368..de04bcd 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -21,7 +21,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power-ndk_platform",
+        "android.hardware.power-V1-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index 28b08c7..008073b 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -23,7 +23,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.power-cpp",
+        "android.hardware.power-V1-cpp",
     ],
     test_suites: [
         "vts",
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl
index ac326b5..e0c372b 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -21,4 +35,5 @@
 parcelable Channel {
   int id;
   @utf8InCpp String name;
+  @utf8InCpp String subsystem;
 }
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl
index 9f9a10b..c8d7645 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl
index 53f31b6..2fdc1a5 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
index 773fa28..4937aef 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
index d08d24e..7b05d2f 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
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 fc61c27..2d6ae16 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
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
index 11a2936..0b6387e 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl
index 8fff6c3..38a62ac 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl
index 2a8e6f8..1c5d7c1 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
index cb38df5..7982f02 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
index 9f92253..5bc548e 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/power/stats/aidl/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/android/hardware/power/stats/Channel.aidl
index 09c7d75..5e8962e 100644
--- a/power/stats/aidl/android/hardware/power/stats/Channel.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/Channel.aidl
@@ -26,5 +26,10 @@
      * Unique name of this Channel. Vendor/device specific. Opaque to framework
      */
     @utf8InCpp String name;
+
+    /**
+     * Name of the subsystem associated with this Channel. Opaque to framework
+     */
+    @utf8InCpp String subsystem;
 }
 
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl
index 065d999..2ff1279 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl
@@ -26,8 +26,8 @@
     int id;
 
     /**
-     * For a group of EnergyConsumers of the same logical type, sorting by ordinal should
-     * be give their physical order. No other meaning is carried by it.
+     * For a group of EnergyConsumers of the same logical type, sorting by ordinal
+     * gives their physical order. Ordinals must be consecutive integers starting from 0.
      */
     int ordinal;
 
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 40b9447..595ecd6 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -21,7 +21,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power.stats-ndk_platform",
+        "android.hardware.power.stats-V1-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp
index 930709f..31fb990 100644
--- a/power/stats/aidl/vts/Android.bp
+++ b/power/stats/aidl/vts/Android.bp
@@ -23,7 +23,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.power.stats-ndk_platform",
+        "android.hardware.power.stats-V1-ndk_platform",
     ],
     test_suites: [
         "general-tests",
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index b77272f..e6a4e7a 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -20,7 +20,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.rebootescrow-ndk_platform",
+        "android.hardware.rebootescrow-V1-ndk_platform",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -47,7 +47,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.rebootescrow-ndk_platform",
+        "android.hardware.rebootescrow-V1-ndk_platform",
     ],
     static_libs: [
         "libhadamardutils",
diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp
index 2cc0068..abd4937 100644
--- a/rebootescrow/aidl/vts/functional/Android.bp
+++ b/rebootescrow/aidl/vts/functional/Android.bp
@@ -25,7 +25,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.rebootescrow-cpp",
+        "android.hardware.rebootescrow-V1-cpp",
     ],
     test_suites: [
         "vts",
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
index a6c3e65..29ff8f8 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
index 84395af..4421619 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
index e914823..e9652c3 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
index cef8eca..34f2749 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
index 2277831..5d1cc68 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
index 2e583ce..5055d75 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
index b372822..1a7e9b5 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
index aa8c071..594844a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
index 5858c77..bd304f1 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
index 9ab00c1..ae64110 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index c95145d..132135b 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
index e6ab4c8..a9b9a05 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
index 49ea8af..b430da9 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl
index 4b9ac79..4139436 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (C) 2021 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
index 4eb5a78..1ad7c51 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 0390ec9..93966ea 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -17,7 +31,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.security.keymint;
-@VintfStability
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
 parcelable KeyMintHardwareInfo {
   int versionNumber;
   android.hardware.security.keymint.SecurityLevel securityLevel;
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
index e84cf74..acaf60d 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
index 6829a2b..f534952 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
index 882ca89..2706623 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
index 6c11a92..c79614a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
index ff8d85a..c1e92af 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -24,4 +38,5 @@
   SIGN = 2,
   VERIFY = 3,
   WRAP_KEY = 5,
+  AGREE_KEY = 6,
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
index 6c61312..96b63e1 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
index c4812ed..c720d6d 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -22,4 +36,5 @@
   SOFTWARE = 0,
   TRUSTED_ENVIRONMENT = 1,
   STRONGBOX = 2,
+  KEYSTORE = 100,
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index ce12fed..b924a13 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -42,6 +56,7 @@
   USAGE_EXPIRE_DATETIME = 1610613138,
   MIN_SECONDS_BETWEEN_OPS = 805306771,
   MAX_USES_PER_BOOT = 805306772,
+  USAGE_COUNT_LIMIT = 805306773,
   USER_ID = 805306869,
   USER_SECURE_ID = -1610612234,
   NO_AUTH_REQUIRED = 1879048695,
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
index 41c8832..75a19a3 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
@@ -1,4 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * 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.
+ *////////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 1ca7713..0120a30 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -681,9 +681,9 @@
      * values less than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH.
      *
      * @param inPurpose The purpose of the operation, one of KeyPurpose::ENCRYPT,
-     *        KeyPurpose::DECRYPT, KeyPurpose::SIGN or KeyPurpose::VERIFY.  Note that for AEAD
-     *        modes, encryption and decryption imply signing and verification, respectively, but
-     *        must be specified as KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
+     *        KeyPurpose::DECRYPT, KeyPurpose::SIGN, KeyPurpose::VERIFY, or KeyPurpose::AGREE_KEY.
+     *        Note that for AEAD modes, encryption and decryption imply signing and verification,
+     *        respectively, but must be specified as KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
      *
      * @param inKeyBlob The opaque key descriptor returned by generateKey() or importKey().  The key
      *        must have a purpose compatible with purpose and all of its usage requirements must be
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index b149ac9..69bec2d7 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -36,7 +36,6 @@
      * deciding whether a given tag from `keyParams` argument to the generation/import method should
      * be returned in `keyCharacteristics` are:
      *
-     * - If the IKeyMintDevice cannot fully enforce the semantics of the tag, it should be omitted.
      * - If the semantics of the tag are fully enforced by the IKeyMintDevice, without any
      *   assistance from components running at other security levels, it should be included in an
      *   entry with the SecurityLevel of the IKeyMintDevice.
@@ -45,6 +44,9 @@
      *   SecurityLevel of the involved components.  For example if a StrongBox IKeyMintDevice relies
      *   on a TEE to validate biometric authentication, biometric authentication tags go in an entry
      *   with SecurityLevel::TRUSTED_ENVIRONMENT.
+     * - If the semantics are not enforced by KeyMint at all, SecurityLevel::KEYSTORE is used to
+     *   indicate that Keystore should enforce.  Note that in Keymaster (predecessor to KeyMint),
+     *   these tags would have been in SecurityLevel::SOFTWARE.
      */
     KeyCharacteristics[] keyCharacteristics;
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index d3d7368..1a107ba 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -22,6 +22,7 @@
  * KeyMintHardwareInfo is the hardware information returned by calling KeyMint getHardwareInfo()
  */
 @VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
 parcelable KeyMintHardwareInfo {
     /**
      * Implementation version of the keymint hardware.  The version number is implementation
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
index cb4682e..68c1740 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
@@ -39,5 +39,8 @@
     /* Usable with wrapping keys. */
     WRAP_KEY = 5,
 
-    /* TODO(seleneh) add AGREE_KEY and ATTEST_KEY and their corresponding codes and tests later*/
+    /* Key Agreement, usable with EC keys. */
+    AGREE_KEY = 6,
+
+    /* TODO(seleneh) add ATTEST_KEY and their corresponding codes and tests later*/
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
index 10363e9..c63859c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
@@ -17,16 +17,59 @@
 package android.hardware.security.keymint;
 
 /**
- * Device security levels.
+ * Device security levels.  These enum values are used in two ways:
+ *
+ * 1.  Returned from IKeyMintDevice::getHardwareInfo to identify the security level of the
+ *     IKeyMintDevice.  This characterizes the sort of environment in which the KeyMint
+ *     implementation runs, and therefore the security of its operations.
+ *
+ * 2.  Associated with individual KeyMint authorization Tags in KeyCharacteristics or in attestation
+ *     certificates.  This specifies the security level of the weakest environment involved in
+ *     enforcing that particular tag, i.e. the sort of security environment an attacker would have
+ *     to subvert in order to break the enforcement of that tag.
  */
 @VintfStability
 @Backing(type="int")
 enum SecurityLevel {
+    /**
+     * The SOFTWARE security level represents a KeyMint implementation that runs in an Android
+     * process, or a tag enforced by such an implementation.  An attacker who can compromise that
+     * process, or obtain root, or subvert the kernel on the device can defeat it.
+     *
+     * Note that the distinction between SOFTWARE and KEYSTORE is only relevant on-device.  For
+     * attestation purposes, these categories are combined into the software-enforced authorization
+     * list.
+     */
     SOFTWARE = 0,
+
+    /**
+     * The TRUSTED_ENVIRONMENT security level represents a KeyMint implementation that runs in an
+     * Android process, or a tag enforced by such an implementation.  An attacker who completely
+     * compromises Android, including the Linux kernel, does not have the ability to subvert it.  At
+     * attacker who can find an exploit that gains them control of the trusted environment, or who
+     * has access to the physical device and can mount a sophisticated hardware attack, may be able
+     * to defeat it.
+     */
     TRUSTED_ENVIRONMENT = 1,
     /**
-     * STRONGBOX specifies that the secure hardware satisfies the requirements specified in CDD
-     * 9.11.2.
+     * The STRONGBOX security level represents a KeyMint implementation that runs in security
+     * hardware that satisfies the requirements specified in CDD 9.11.2.  Roughly speaking, these
+     * are discrete, security-focus computing environments that are hardened against physical and
+     * side channel attack, and have had their security formally validated by a competent
+     * penetration testing lab.
      */
     STRONGBOX = 2,
+
+    /**
+     * KeyMint implementations must never return the KEYSTORE security level from getHardwareInfo.
+     * It is used to specify tags that are not enforced by the IKeyMintDevice, but are instead
+     * to be enforced by Keystore.  An attacker who can subvert the keystore process or gain root or
+     * subvert the kernel can prevent proper enforcement of these tags.
+     *
+     *
+     * Note that the distinction between SOFTWARE and KEYSTORE is only relevant on-device.  When
+     * KeyMint generates an attestation certificate, these categories are combined into the
+     * software-enforced authorization list.
+     */
+    KEYSTORE = 100
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index f92bf00..bc07235 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -333,6 +333,35 @@
     MAX_USES_PER_BOOT = (3 << 28) /* TagType:UINT */ | 404,
 
     /**
+     * Tag::USAGE_COUNT_LIMIT specifies the number of times that a key may be used. This can be
+     * used to limit the use of a key.
+     *
+     * The value is a 32-bit integer representing the current number of attempts left.
+     *
+     * When initializing a limited use key, the value of this tag represents the maximum usage
+     * limit for that key. After the key usage is exhausted, the key blob should be invalidated by
+     * finish() call. Any subsequent attempts to use the key must result in a failure with
+     * ErrorCode::INVALID_KEY_BLOB returned by IKeyMintDevice.
+     *
+     * At this point, if the caller specifies count > 1, it is not expected that any TEE will be
+     * able to enforce this feature in the hardware due to limited resources of secure
+     * storage. In this case, the tag with the value of maximum usage must be added to the key
+     * characteristics with SecurityLevel::SOFTWARE by the IKeyMintDevice.
+     *
+     * On the other hand, if the caller specifies count = 1, some TEEs may have the ability
+     * to enforce this feature in the hardware with its secure storage. If the IKeyMintDevice
+     * implementation can enforce this feature, the tag with value = 1 must be added to the key
+     * characteristics with the SecurityLevel of the IKeyMintDevice. If the IKeyMintDevice can't
+     * enforce this feature even when the count = 1, the tag must be added to the key
+     * characteristics with the SecurityLevel::SOFTWARE.
+     *
+     * When the key is attested, this tag with the same value must also be added to the attestation
+     * record. This tag must have the same SecurityLevel as the tag that is added to the key
+     * characteristics.
+     */
+    USAGE_COUNT_LIMIT = (3 << 28) | 405, /* TagType:UINT */
+
+    /**
      * Tag::USER_ID specifies the ID of the Android user that is permitted to use the key.
      *
      * Must not be hardware-enforced.
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 79697c4..b2758ad 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -9,7 +9,7 @@
         "-Wextra",
     ],
     shared_libs: [
-        "android.hardware.security.keymint-unstable-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk_platform",
         "libbase",
         "libbinder_ndk",
         "libcppbor",
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 17a4613..f4ba9e7 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -30,8 +30,8 @@
         "libkeymint_support",
     ],
     static_libs: [
-        "android.hardware.security.keymint-unstable-ndk_platform",
-        "android.hardware.security.secureclock-unstable-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
         "libkeymint_vts_test_utils",
     ],
@@ -60,8 +60,8 @@
         "libkeymint_support",
     ],
     static_libs: [
-        "android.hardware.security.keymint-unstable-ndk_platform",
-        "android.hardware.security.secureclock-unstable-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor",
     ],
 }
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index e7c94f3..c876440 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -20,9 +20,11 @@
 #include <signal.h>
 #include <iostream>
 
+#include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 #include <cutils/properties.h>
 
@@ -560,7 +562,7 @@
 }
 
 /*
- * NewKeyGenerationTest.Rsa
+ * NewKeyGenerationTest.RsaWithAttestation
  *
  * Verifies that keymint can generate all required RSA key sizes, and that the resulting keys
  * have correct characteristics.
@@ -605,6 +607,45 @@
 }
 
 /*
+ * NewKeyGenerationTest.LimitedUsageRsa
+ *
+ * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageRsa) {
+    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .RsaSigningKey(key_size, 65537)
+                                                     .Digest(Digest::NONE)
+                                                     .Padding(PaddingMode::NONE)
+                                                     .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+        EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+        // Check the usage count limit tag appears in the authorizations.
+        AuthorizationSet auths;
+        for (auto& entry : key_characteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+        EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+                << "key usage count limit " << 1U << " missing";
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.NoInvalidRsaSizes
  *
  * Verifies that keymint cannot generate any RSA key sizes that are designated as invalid.
@@ -664,6 +705,43 @@
 }
 
 /*
+ * NewKeyGenerationTest.LimitedUsageEcdsa
+ *
+ * Verifies that KeyMint can generate all required EC key sizes with limited usage, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) {
+    for (auto key_size : ValidKeySizes(Algorithm::EC)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .EcdsaSigningKey(key_size)
+                                                     .Digest(Digest::NONE)
+                                                     .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        // Check the usage count limit tag appears in the authorizations.
+        AuthorizationSet auths;
+        for (auto& entry : key_characteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+        EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+                << "key usage count limit " << 1U << " missing";
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.EcdsaDefaultSize
  *
  * Verifies that failing to specify a key size for EC key generation returns
@@ -778,6 +856,44 @@
 }
 
 /*
+ * NewKeyGenerationTest.LimitedUsageHmac
+ *
+ * Verifies that KeyMint supports all required digests with limited usage Hmac, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageHmac) {
+    for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        constexpr size_t key_size = 128;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .HmacKey(key_size)
+                                                     .Digest(digest)
+                                                     .Authorization(TAG_MIN_MAC_LENGTH, 128)
+                                                     .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        // Check the usage count limit tag appears in the authorizations.
+        AuthorizationSet auths;
+        for (auto& entry : key_characteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+        EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+                << "key usage count limit " << 1U << " missing";
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.HmacCheckKeySizes
  *
  * Verifies that keymint supports all key sizes, and rejects all invalid key sizes.
@@ -4151,7 +4267,7 @@
 }
 
 /*
- * MaxOperationsTest.TestLimitAes
+ * MaxOperationsTest.TestLimitRsa
  *
  * Verifies that the max uses per boot tag works correctly with RSA keys.
  */
@@ -4178,6 +4294,100 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(MaxOperationsTest);
 
+typedef KeyMintAidlTestBase UsageCountLimitTest;
+
+/*
+ * UsageCountLimitTest.TestLimitAes
+ *
+ * Verifies that the usage count limit tag works correctly with AES keys.
+ */
+TEST_P(UsageCountLimitTest, TestLimitAes) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .EcbMode()
+                                                 .Padding(PaddingMode::NONE)
+                                                 .Authorization(TAG_USAGE_COUNT_LIMIT, 1)));
+
+    // Check the usage count limit tag appears in the authorizations.
+    AuthorizationSet auths;
+    for (auto& entry : key_characteristics_) {
+        auths.push_back(AuthorizationSet(entry.authorizations));
+    }
+    EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+            << "key usage count limit " << 1U << " missing";
+
+    string message = "1234567890123456";
+    auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE);
+
+    // First usage of AES key should work.
+    EncryptMessage(message, params);
+
+    AuthorizationSet hardware_auths;
+    for (auto& entry : key_characteristics_) {
+        if (entry.securityLevel != SecurityLevel::SOFTWARE) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+    }
+    if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
+        // Usage count limit tag is enforced by hardware. After using the key, the key blob
+        // must be invalidated from secure storage (such as RPMB partition).
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params));
+    } else {
+        // Usage count limit tag is enforced by software, keymint does nothing.
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+    }
+}
+
+/*
+ * UsageCountLimitTest.TestLimitRsa
+ *
+ * Verifies that the usage count limit tag works correctly with RSA keys.
+ */
+TEST_P(UsageCountLimitTest, TestLimitRsa) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .RsaSigningKey(1024, 65537)
+                                                 .NoDigestOrPadding()
+                                                 .Authorization(TAG_USAGE_COUNT_LIMIT, 1)));
+
+    // Check the usage count limit tag appears in the authorizations.
+    AuthorizationSet auths;
+    for (auto& entry : key_characteristics_) {
+        auths.push_back(AuthorizationSet(entry.authorizations));
+    }
+    EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+            << "key usage count limit " << 1U << " missing";
+
+    string message = "1234567890123456";
+    auto params = AuthorizationSetBuilder().NoDigestOrPadding();
+
+    // First usage of RSA key should work.
+    SignMessage(message, params);
+
+    AuthorizationSet hardware_auths;
+    for (auto& entry : key_characteristics_) {
+        if (entry.securityLevel != SecurityLevel::SOFTWARE) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+    }
+
+    if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
+        // Usage count limit tag is enforced by hardware. After using the key, the key blob
+        // must be invalidated from secure storage (such as RPMB partition).
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params));
+    } else {
+        // Usage count limit tag is enforced by software, keymint does nothing.
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+    }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest);
+
 typedef KeyMintAidlTestBase AddEntropyTest;
 
 /*
@@ -4424,6 +4634,121 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(TransportLimitTest);
 
+typedef KeyMintAidlTestBase KeyAgreementTest;
+
+int CurveToOpenSslCurveName(EcCurve curve) {
+    switch (curve) {
+        case EcCurve::P_224:
+            return NID_secp224r1;
+        case EcCurve::P_256:
+            return NID_X9_62_prime256v1;
+        case EcCurve::P_384:
+            return NID_secp384r1;
+        case EcCurve::P_521:
+            return NID_secp521r1;
+    }
+}
+
+/*
+ * KeyAgreementTest.Ecdh
+ *
+ * Verifies that ECDH works for all curves
+ */
+TEST_P(KeyAgreementTest, Ecdh) {
+    // Because it's possible to use this API with keys on different curves, we
+    // check all N^2 combinations where N is the number of supported
+    // curves.
+    //
+    // This is not a big deal as N is 4 so we only do 16 runs. If we end up with a
+    // lot more curves we can be smart about things and just pick |otherCurve| so
+    // it's not |curve| and that way we end up with only 2*N runs
+    //
+    for (auto curve : ValidCurves()) {
+        for (auto localCurve : ValidCurves()) {
+            // Generate EC key locally (with access to private key material)
+            auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+            int curveName = CurveToOpenSslCurveName(localCurve);
+            auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(curveName));
+            ASSERT_NE(group, nullptr);
+            ASSERT_EQ(EC_KEY_set_group(ecKey.get(), group.get()), 1);
+            ASSERT_EQ(EC_KEY_generate_key(ecKey.get()), 1);
+            auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+            ASSERT_EQ(EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()), 1);
+
+            // Get encoded form of the public part of the locally generated key...
+            unsigned char* p = nullptr;
+            int encodedPublicKeySize = i2d_PUBKEY(pkey.get(), &p);
+            ASSERT_GT(encodedPublicKeySize, 0);
+            vector<uint8_t> encodedPublicKey(
+                    reinterpret_cast<const uint8_t*>(p),
+                    reinterpret_cast<const uint8_t*>(p + encodedPublicKeySize));
+            OPENSSL_free(p);
+
+            // Generate EC key in KeyMint (only access to public key material)
+            vector<uint8_t> challenge = {0x41, 0x42};
+            EXPECT_EQ(
+                    ErrorCode::OK,
+                    GenerateKey(AuthorizationSetBuilder()
+                                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                                        .Authorization(TAG_EC_CURVE, curve)
+                                        .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+                                        .Authorization(TAG_ALGORITHM, Algorithm::EC)
+                                        .Authorization(TAG_ATTESTATION_APPLICATION_ID, {0x61, 0x62})
+                                        .Authorization(TAG_ATTESTATION_CHALLENGE, challenge)))
+                    << "Failed to generate key";
+            ASSERT_GT(cert_chain_.size(), 0);
+            X509_Ptr kmKeyCert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+            ASSERT_NE(kmKeyCert, nullptr);
+            // Check that keyAgreement (bit 4) is set in KeyUsage
+            EXPECT_TRUE((X509_get_key_usage(kmKeyCert.get()) & X509v3_KU_KEY_AGREEMENT) != 0);
+            auto kmPkey = EVP_PKEY_Ptr(X509_get_pubkey(kmKeyCert.get()));
+            ASSERT_NE(kmPkey, nullptr);
+            if (dump_Attestations) {
+                for (size_t n = 0; n < cert_chain_.size(); n++) {
+                    std::cout << bin2hex(cert_chain_[n].encodedCertificate) << std::endl;
+                }
+            }
+
+            // Now that we have the two keys, we ask KeyMint to perform ECDH...
+            if (curve != localCurve) {
+                // If the keys are using different curves KeyMint should fail with
+                // ErrorCode:INVALID_ARGUMENT. Check that.
+                EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+                string ZabFromKeyMintStr;
+                EXPECT_EQ(ErrorCode::INVALID_ARGUMENT,
+                          Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()),
+                                 &ZabFromKeyMintStr));
+
+            } else {
+                // Otherwise if the keys are using the same curve, it should work.
+                EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+                string ZabFromKeyMintStr;
+                EXPECT_EQ(ErrorCode::OK,
+                          Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()),
+                                 &ZabFromKeyMintStr));
+                vector<uint8_t> ZabFromKeyMint(ZabFromKeyMintStr.begin(), ZabFromKeyMintStr.end());
+
+                // Perform local ECDH between the two keys so we can check if we get the same Zab..
+                auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(pkey.get(), nullptr));
+                ASSERT_NE(ctx, nullptr);
+                ASSERT_EQ(EVP_PKEY_derive_init(ctx.get()), 1);
+                ASSERT_EQ(EVP_PKEY_derive_set_peer(ctx.get(), kmPkey.get()), 1);
+                size_t ZabFromTestLen = 0;
+                ASSERT_EQ(EVP_PKEY_derive(ctx.get(), nullptr, &ZabFromTestLen), 1);
+                vector<uint8_t> ZabFromTest;
+                ZabFromTest.resize(ZabFromTestLen);
+                ASSERT_EQ(EVP_PKEY_derive(ctx.get(), ZabFromTest.data(), &ZabFromTestLen), 1);
+
+                EXPECT_EQ(ZabFromKeyMint, ZabFromTest);
+            }
+
+            CheckedDeleteKey();
+        }
+    }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest);
+
 }  // namespace aidl::android::hardware::security::keymint::test
 
 int main(int argc, char** argv) {
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 0cfa798..fde6b57 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -31,7 +31,7 @@
         "include",
     ],
     shared_libs: [
-        "android.hardware.security.keymint-unstable-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk_platform",
         "libbase",
         "libcrypto",
         "libutils",
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 76aecb7..43cfb63 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -119,6 +119,7 @@
 DECLARE_TYPED_TAG(TRUSTED_USER_PRESENCE_REQUIRED);
 DECLARE_TYPED_TAG(UNIQUE_ID);
 DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED);
+DECLARE_TYPED_TAG(USAGE_COUNT_LIMIT);
 DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
 DECLARE_TYPED_TAG(USER_AUTH_TYPE);
 DECLARE_TYPED_TAG(USER_ID);
@@ -135,15 +136,15 @@
         TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t,
         TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t,
         TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
-        TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t, TAG_USER_SECURE_ID_t,
-        TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t,
-        TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t,
-        TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_HARDWARE_TYPE_t,
-        TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t,
-        TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t,
-        TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t, TAG_ATTESTATION_ID_DEVICE_t,
-        TAG_ATTESTATION_ID_PRODUCT_t, TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t,
-        TAG_ATTESTATION_ID_SERIAL_t, TAG_ATTESTATION_ID_IMEI_t, TAG_ATTESTATION_ID_MEID_t,
+        TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USAGE_COUNT_LIMIT_t,
+        TAG_USER_ID_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
+        TAG_ALLOW_WHILE_ON_BODY_t, TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t,
+        TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t,
+        TAG_HARDWARE_TYPE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t,
+        TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t,
+        TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t,
+        TAG_ATTESTATION_ID_DEVICE_t, TAG_ATTESTATION_ID_PRODUCT_t,
+        TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t,
         TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t,
         TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t,
         TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t,
@@ -325,7 +326,9 @@
 inline std::optional<
         std::reference_wrapper<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>>
 authorizationValue(TypedTag<tag_type, tag> ttag, const KeyParameter& param) {
-    if (TypedTag2ValueType<TypedTag<tag_type, tag>>::unionTag != param.value.getTag()) return {};
+    // We only check if the parameter has the correct tag here; accessTagValue checks if the correct
+    // union field was initialized.
+    if (tag != param.tag) return {};
     return accessTagValue(ttag, param);
 }
 
diff --git a/security/keymint/support/include/keymint_support/openssl_utils.h b/security/keymint/support/include/keymint_support/openssl_utils.h
index 9ae7e52..c3bc60b 100644
--- a/security/keymint/support/include/keymint_support/openssl_utils.h
+++ b/security/keymint/support/include/keymint_support/openssl_utils.h
@@ -34,7 +34,10 @@
     typedef std::unique_ptr<type, UniquePtrDeleter<type, type##_free>> type##_Ptr;
 
 MAKE_OPENSSL_PTR_TYPE(ASN1_OBJECT)
+MAKE_OPENSSL_PTR_TYPE(EC_KEY)
+MAKE_OPENSSL_PTR_TYPE(EC_GROUP)
 MAKE_OPENSSL_PTR_TYPE(EVP_PKEY)
+MAKE_OPENSSL_PTR_TYPE(EVP_PKEY_CTX)
 MAKE_OPENSSL_PTR_TYPE(RSA)
 MAKE_OPENSSL_PTR_TYPE(X509)
 MAKE_OPENSSL_PTR_TYPE(BN_CTX)
diff --git a/security/secureclock/aidl/OWNERS b/security/secureclock/aidl/OWNERS
new file mode 100644
index 0000000..a93b171
--- /dev/null
+++ b/security/secureclock/aidl/OWNERS
@@ -0,0 +1,4 @@
+jbires@google.com
+jdanis@google.com
+seleneh@google.com
+swillden@google.com
diff --git a/security/sharedsecret/aidl/OWNERS b/security/sharedsecret/aidl/OWNERS
new file mode 100644
index 0000000..a93b171
--- /dev/null
+++ b/security/sharedsecret/aidl/OWNERS
@@ -0,0 +1,4 @@
+jbires@google.com
+jdanis@google.com
+seleneh@google.com
+swillden@google.com
diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp
index b0d8238..108d000 100644
--- a/tests/extension/vibrator/aidl/client/Android.bp
+++ b/tests/extension/vibrator/aidl/client/Android.bp
@@ -14,11 +14,11 @@
     shared_libs: [
         "libbinder",
         "libutils",
-        "android.hardware.vibrator-cpp",
-        "android.hardware.tests.extension.vibrator-cpp",
+        "android.hardware.vibrator-V1-cpp",
+        "android.hardware.tests.extension.vibrator-V1-cpp",
 
         "libbinder_ndk",
-        "android.hardware.vibrator-ndk_platform",
-        "android.hardware.tests.extension.vibrator-ndk_platform",
+        "android.hardware.vibrator-V1-ndk_platform",
+        "android.hardware.tests.extension.vibrator-V1-ndk_platform",
     ],
 }
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index 80f7727..2486588 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-unstable-ndk_platform",
-        "android.hardware.tests.extension.vibrator-unstable-ndk_platform",
+        "android.hardware.vibrator-V2-ndk_platform",
+        "android.hardware.tests.extension.vibrator-V2-ndk_platform",
     ],
 }
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index a50206b..a0d6f31 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -91,8 +91,8 @@
     // These are static libs only for testing purposes and portability. Shared
     // libs should be used on device.
     static_libs: [
-        "android.hardware.common-unstable-ndk_platform",
-        "android.hardware.common.fmq-unstable-ndk_platform",
+        "android.hardware.common-V2-ndk_platform",
+        "android.hardware.common.fmq-V1-ndk_platform",
         "android.hardware.tests.msgq@1.0",
         "android.fmq.test-ndk_platform",
     ],
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
index c397df4..ddf3826 100644
--- a/tetheroffload/control/1.0/vts/functional/Android.bp
+++ b/tetheroffload/control/1.0/vts/functional/Android.bp
@@ -30,3 +30,17 @@
         "vts",
     ],
 }
+
+cc_test_library {
+    name: "VtsHalTetheroffloadControlV1_0TargetTest-lib",
+    defaults: ["VtsHalTargetTestDefaults"],
+    export_include_dirs: ["include"],
+    static_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "android.hardware.tetheroffload.control@1.0",
+    ],
+    srcs: [
+        "OffloadControlTestBase.cpp",
+        "OffloadControlTestUtils.cpp",
+    ],
+}
diff --git a/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp b/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp
index bd0dad7..e392e96 100644
--- a/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp
+++ b/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp
@@ -53,29 +53,6 @@
     ASSERT_TRUE(ret.isOk());
 }
 
-void OffloadControlTestBase::prepareControlHal() {
-    control = createControl(std::get<1>(GetParam()));
-    ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
-
-    control_cb = new TetheringOffloadCallback();
-    ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
-}
-
-void OffloadControlTestBase::initOffload(const bool expected_result) {
-    auto init_cb = [&](bool success, std::string errMsg) {
-        std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
-                                       success ? "succeeded" : "failed", errMsg.c_str());
-        ASSERT_EQ(expected_result, success) << msg;
-    };
-    const Return<void> ret = control->initOffload(control_cb, init_cb);
-    ASSERT_TRUE(ret.isOk());
-}
-
-void OffloadControlTestBase::setupControlHal() {
-    prepareControlHal();
-    initOffload(true);
-}
-
 void OffloadControlTestBase::stopOffload(const ExpectBoolean value) {
     auto cb = [&](bool success, const hidl_string& errMsg) {
         switch (value) {
diff --git a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h
index 004019a..994c808 100644
--- a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h
+++ b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h
@@ -36,7 +36,6 @@
 using android::hardware::Return;
 using android::hardware::Void;
 using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
-using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
 using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
 using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
 using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
@@ -64,17 +63,21 @@
 
     // Called once in setup stage to retrieve correct version of
     // IOffloadControl object.
-    virtual sp<IOffloadControl> createControl(const std::string& serviceName) = 0;
+    virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
+            const std::string& serviceName) = 0;
 
     // The IOffloadConfig HAL is tested more thoroughly elsewhere. Here the
     // class just setup everything correctly and verify basic readiness.
     void setupConfigHal();
 
-    void prepareControlHal();
+    virtual void prepareControlHal() = 0;
 
-    void initOffload(const bool expected_result);
+    virtual void initOffload(const bool expected_result) = 0;
 
-    void setupControlHal();
+    void setupControlHal() {
+        prepareControlHal();
+        initOffload(true);
+    };
 
     void stopOffload(const ExpectBoolean value);
 
@@ -100,6 +103,6 @@
     };
 
     sp<IOffloadConfig> config;
-    sp<IOffloadControl> control;
+    sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> control;
     sp<TetheringOffloadCallback> control_cb;
 };
\ No newline at end of file
diff --git a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h
index 7492f8a..9189d71 100644
--- a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h
+++ b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h
@@ -26,8 +26,28 @@
         prepareControlHal();
     }
 
-    virtual sp<IOffloadControl> createControl(const std::string& serviceName) override {
-        return IOffloadControl::getService(serviceName);
+    virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
+            const std::string& serviceName) override {
+        return android::hardware::tetheroffload::control::V1_0::IOffloadControl::getService(
+                serviceName);
+    }
+
+    virtual void prepareControlHal() override {
+        control = createControl(std::get<1>(GetParam()));
+        ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
+
+        control_cb = new TetheringOffloadCallback();
+        ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
+    }
+
+    virtual void initOffload(const bool expected_result) override {
+        auto init_cb = [&](bool success, std::string errMsg) {
+            std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
+                                           success ? "succeeded" : "failed", errMsg.c_str());
+            ASSERT_EQ(expected_result, success) << msg;
+        };
+        const Return<void> ret = control->initOffload(control_cb, init_cb);
+        ASSERT_TRUE(ret.isOk());
     }
 };
 
diff --git a/tetheroffload/control/1.1/Android.bp b/tetheroffload/control/1.1/Android.bp
new file mode 100644
index 0000000..18c8ea9
--- /dev/null
+++ b/tetheroffload/control/1.1/Android.bp
@@ -0,0 +1,16 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.tetheroffload.control@1.1",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "IOffloadControl.hal",
+        "ITetheringOffloadCallback.hal",
+    ],
+    interfaces: [
+        "android.hardware.tetheroffload.control@1.0",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/tetheroffload/control/1.1/IOffloadControl.hal b/tetheroffload/control/1.1/IOffloadControl.hal
new file mode 100644
index 0000000..eb5b8a1
--- /dev/null
+++ b/tetheroffload/control/1.1/IOffloadControl.hal
@@ -0,0 +1,82 @@
+/*
+ * 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.tetheroffload.control@1.1;
+
+import @1.0::IOffloadControl;
+
+/**
+ * Interface used to control the lifecycle of tethering offload. Note that callbacks of 1.1 HAL
+ * can be registered with the existing callback registration methods from 1.0 HAL.
+ */
+interface IOffloadControl extends @1.0::IOffloadControl {
+    /**
+     * Instruct hardware to send callbacks after certain number of bytes have been transferred in
+     * either direction on this upstream interface.
+     *
+     * The specified quota bytes must be applied to all traffic on the given upstream interface.
+     * This includes hardware forwarded traffic, software forwarded traffic, and AP-originated
+     * traffic. IPv4 and IPv6 traffic both count towards the same quota. IP headers are included
+     * in the byte count quota, but, link-layer headers are not.
+     *
+     * This API may only be called while offload is occurring on this upstream. The hardware
+     * management process MUST NOT store the values when offload is not started and applies once
+     * offload is started. This is because the quota values would likely become stale over
+     * time and would not reflect any new traffic that has occurred.
+     *
+     * This API replaces {@link @1.0::IOffloadControl::setDataLimit}, the framework would always
+     * calls this API if 1.1 HAL is supported. Otherwise, calls the other one. Thus, no
+     * interaction between the two APIs need to be addressed. However, the hardware implementation
+     * still needs to keep functionality of both in case of shipping with older framework that
+     * doesn't support 1.1 HAL.
+     *
+     * The specified quota bytes MUST replace any previous quotas set by
+     * {@code setDataWarningAndLimit} specified on the same interface. It may be interpreted as
+     * "tell me when either <warningBytes> or <limitBytes> bytes have been transferred
+     * (in either direction), and stop offload when <limitBytes> bytes have been transferred,
+     * starting now and counting from zero on <upstream>."
+     *
+     * Once the {@code warningBytes} is reached, the callback registered in initOffload must be
+     * called with {@code OFFLOAD_WARNING_REACHED} to indicate this event. Once the event fires
+     * for this upstream, no further {@code OFFLOAD_WARNING_REACHED} event will be fired for this
+     * upstream unless this method is called again with the same interface. Note that there is
+     * no need to call initOffload again to resume offload if stopOffload was not called by the
+     * client.
+     *
+     * Similarly, Once the {@code limitBytes} is reached, the callback registered in initOffload
+     * must be called with {@code OFFLOAD_STOPPED_LIMIT_REACHED} to indicate this event. Once
+     * the event fires for this upstream, no further {@code OFFLOAD_STOPPED_LIMIT_REACHED}
+     * event will be fired for this upstream unless this method is called again with the same
+     * interface. However, unlike {@code warningBytes}, when {@code limitBytes} is reached,
+     * all offload must be stopped. If offload is desired again, the hardware management
+     * process must be completely reprogrammed by calling setUpstreamParameters and
+     * addDownstream again.
+     *
+     * Note that when one of the quota bytes is reached, the other one is still considered valid
+     * unless this method is called again with the same interface.
+     *
+     * @param upstream Upstream interface name that quota must apply to.
+     * @param warningBytes The quota of warning, defined as the number of bytes, starting from
+     *                     zero and counting from now.
+     * @param limitBytes The quota of limit, defined as the number of bytes, starting from zero
+     *                   and counting from now.
+     *
+     * @return success true if quota is applied, false otherwise
+     * @return errMsg a human readable string if error has occurred.
+     */
+    setDataWarningAndLimit(string upstream, uint64_t warningBytes, uint64_t limitBytes)
+        generates (bool success, string errMsg);
+};
diff --git a/tetheroffload/control/1.1/ITetheringOffloadCallback.hal b/tetheroffload/control/1.1/ITetheringOffloadCallback.hal
new file mode 100644
index 0000000..7a7d56d
--- /dev/null
+++ b/tetheroffload/control/1.1/ITetheringOffloadCallback.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.tetheroffload.control@1.1;
+
+import @1.0::ITetheringOffloadCallback;
+import OffloadCallbackEvent;
+
+/**
+ * Callback providing information about status of hardware management process
+ * as well as providing a way to keep offloaded connections from timing out.
+ */
+interface ITetheringOffloadCallback extends @1.0::ITetheringOffloadCallback {
+    /**
+     * Called when an asynchronous event is generated by the hardware
+     * management process. Events which are common for 1.0 and 1.1 HAL
+     * MUST be fired on both 1.0 and 1.1 callback.
+     */
+    oneway onEvent_1_1(OffloadCallbackEvent event);
+};
diff --git a/tetheroffload/control/1.1/types.hal b/tetheroffload/control/1.1/types.hal
new file mode 100644
index 0000000..30e6af3
--- /dev/null
+++ b/tetheroffload/control/1.1/types.hal
@@ -0,0 +1,28 @@
+/*
+ * 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.tetheroffload.control@1.1;
+
+import @1.0::OffloadCallbackEvent;
+
+enum OffloadCallbackEvent : @1.0::OffloadCallbackEvent {
+    /**
+     * This event is fired when the quota, applied in setDataWarning, has expired. It is
+     * recommended that the client query for statistics immediately after receiving this event.
+     * Note that hardware acceleration must not be stopped upon receiving this event.
+     */
+    OFFLOAD_WARNING_REACHED = 6,
+};
diff --git a/tetheroffload/control/1.1/vts/functional/Android.bp b/tetheroffload/control/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..ab29350
--- /dev/null
+++ b/tetheroffload/control/1.1/vts/functional/Android.bp
@@ -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.
+
+cc_test {
+    name: "VtsHalTetheroffloadControlV1_1TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["VtsHalTetheroffloadControlV1_1TargetTest.cpp"],
+    local_include_dirs: ["include"],
+    static_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "android.hardware.tetheroffload.control@1.0",
+        "android.hardware.tetheroffload.control@1.1",
+        "VtsHalTetheroffloadControlV1_0TargetTest-lib",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp b/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp
new file mode 100644
index 0000000..b8c9e53
--- /dev/null
+++ b/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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 <OffloadControlTestV1_1.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+using android::hardware::tetheroffload::control::V1_1::IOffloadControl;
+
+const hidl_string TEST_IFACE("rmnet_data0");
+
+// Check that calling setDataWarningAndLimit() without first having called initOffload() returns
+// false.
+TEST_P(OffloadControlTestV1_1_HalNotStarted, SetDataWarningAndLimitWithoutInitReturnsFalse) {
+    const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 5000ULL, 5000ULL,
+                                                                      ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setDataWarningAndLimit().
+ */
+
+// Test that setDataWarningAndLimit() for an empty interface name fails.
+TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitEmptyUpstreamIfaceFails) {
+    const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(
+            hidl_string(""), 12345ULL, 67890ULL, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitNonZeroOk) {
+    const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 4000ULL, 5000ULL,
+                                                                      ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitZeroOk) {
+    const Return<void> ret =
+            getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 0ULL, 0ULL, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalNotStarted);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalStarted);
+
+INSTANTIATE_TEST_CASE_P(
+        PerInstance, OffloadControlTestV1_1_HalNotStarted,
+        testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 IOffloadConfig::descriptor)),
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 IOffloadControl::descriptor))),
+        android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_CASE_P(
+        PerInstance, OffloadControlTestV1_1_HalStarted,
+        testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 IOffloadConfig::descriptor)),
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 IOffloadControl::descriptor))),
+        android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h b/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h
new file mode 100644
index 0000000..a3bc1b4
--- /dev/null
+++ b/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h
@@ -0,0 +1,99 @@
+/*
+ * 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 <OffloadControlTestV1_0.h>
+#include <android/hardware/tetheroffload/control/1.1/IOffloadControl.h>
+#include <android/hardware/tetheroffload/control/1.1/ITetheringOffloadCallback.h>
+#include <gtest/gtest.h>
+
+constexpr char kCallbackOnEvent_1_1[] = "onEvent_1_1";
+
+class TetheringOffloadCallbackArgsV1_1 {
+  public:
+    android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent last_event;
+};
+
+class OffloadControlTestV1_1_HalNotStarted : public OffloadControlTestV1_0_HalNotStarted {
+  public:
+    virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
+            const std::string& serviceName) override {
+        return android::hardware::tetheroffload::control::V1_1::IOffloadControl::getService(
+                serviceName);
+    };
+
+    void prepareControlHal() override {
+        control = createControl(std::get<1>(GetParam()));
+        ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
+
+        control_cb_1_1 = new TetheringOffloadCallbackV1_1();
+        ASSERT_NE(nullptr, control_cb_1_1.get()) << "Could not get offload callback";
+    };
+
+    void initOffload(const bool expected_result) override {
+        auto init_cb = [&](bool success, std::string errMsg) {
+            std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
+                                           success ? "succeeded" : "failed", errMsg.c_str());
+            ASSERT_EQ(expected_result, success) << msg;
+        };
+        auto control = getControlV1_1();
+        ASSERT_NE(control, nullptr);
+        const Return<void> ret = control->initOffload(control_cb_1_1, init_cb);
+        ASSERT_TRUE(ret.isOk());
+    };
+
+    sp<android::hardware::tetheroffload::control::V1_1::IOffloadControl> getControlV1_1() {
+        // The cast is safe since only devices with V1.1+ HAL will be enumerated and pass in to the
+        // test.
+        return android::hardware::tetheroffload::control::V1_1::IOffloadControl::castFrom(control)
+                .withDefault(nullptr);
+    };
+
+    // Callback class for both new events.
+    class TetheringOffloadCallbackV1_1
+        : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgsV1_1>,
+          public android::hardware::tetheroffload::control::V1_1::ITetheringOffloadCallback {
+      public:
+        Return<void> onEvent_1_1(
+                android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent event)
+                override {
+            const TetheringOffloadCallbackArgsV1_1 args{.last_event = event};
+            NotifyFromCallback(kCallbackOnEvent_1_1, args);
+            return Void();
+        };
+
+        Return<void> onEvent([[maybe_unused]] OffloadCallbackEvent event) override {
+            // Tested only in IOffloadControl 1.0.
+            return Void();
+        };
+
+        Return<void> updateTimeout([[maybe_unused]] const NatTimeoutUpdate& params) override {
+            // Tested only in IOffloadControl 1.0.
+            return Void();
+        };
+    };
+
+    sp<TetheringOffloadCallbackV1_1> control_cb_1_1;
+};
+
+class OffloadControlTestV1_1_HalStarted : public OffloadControlTestV1_1_HalNotStarted {
+  public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        setupControlHal();
+    }
+};
\ No newline at end of file
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index f9d45bb..b44f11d 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -4,7 +4,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.vibrator-unstable-ndk_platform",
+        "android.hardware.vibrator-V2-ndk_platform",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -26,7 +26,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.vibrator-unstable-ndk_platform",
+        "android.hardware.vibrator-V2-ndk_platform",
     ],
     static_libs: [
         "libvibratorexampleimpl",
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index d06b50e..b50b3f7 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -9,7 +9,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.vibrator-unstable-cpp",
+        "android.hardware.vibrator-V2-cpp",
     ],
     test_suites: [
         "general-tests",
@@ -28,7 +28,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.vibrator-unstable-cpp",
+        "android.hardware.vibrator-V2-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp
index c7f824d..3d7bdc5 100644
--- a/vibrator/bench/Android.bp
+++ b/vibrator/bench/Android.bp
@@ -20,7 +20,7 @@
         "benchmark.cpp",
     ],
     shared_libs: [
-        "android.hardware.vibrator-cpp",
+        "android.hardware.vibrator-V1-cpp",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
index d936828..8440670 100644
--- a/weaver/aidl/default/Android.bp
+++ b/weaver/aidl/default/Android.bp
@@ -25,7 +25,7 @@
         "Weaver.cpp",
     ],
     shared_libs: [
-        "android.hardware.weaver-ndk_platform",
+        "android.hardware.weaver-V1-ndk_platform",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp
index d7e3ab7..7daad8d 100644
--- a/weaver/aidl/vts/Android.bp
+++ b/weaver/aidl/vts/Android.bp
@@ -25,7 +25,7 @@
         "libbinder_ndk",
         "libbase",
     ],
-    static_libs: ["android.hardware.weaver-ndk_platform"],
+    static_libs: ["android.hardware.weaver-V1-ndk_platform"],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal
index b2960cf..209190a 100644
--- a/wifi/1.5/IWifiChip.hal
+++ b/wifi/1.5/IWifiChip.hal
@@ -234,4 +234,33 @@
      *         |WifiStatusCode.FAILURE_IFACE_INVALID|
      */
     setCountryCode(int8_t[2] code) generates (WifiStatus status);
+
+    /**
+     * Retrieve list of usable Wifi channels for the specified band &
+     * operational modes.
+     *
+     * The list of usable Wifi channels in a given band depends on factors
+     * like current country code, operational mode (e.g. STA, SAP, CLI, GO,
+     * TDLS, NAN) and any hard restrictons due to DFS, LTE Coex and
+     * MCC(multi channel-concurrency).
+     *
+     * @param band |WifiBand| for which list of usable channels is requested.
+     * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode|
+     *        Bitmask respresents all the modes that the caller is interested
+     *        in (e.g. STA, SAP, CLI, GO, TDLS, NAN).
+     *        Note: Bitmask does not represent concurrency matrix.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     * @return channels List of channels represented by |WifiUsableChannel|
+     *         Each entry represents a channel frequency, bandwidth and
+     *         bitmask of operational modes (e.g. STA, SAP, CLI, GO, TDLS, NAN)
+     *         allowed on that channel.
+     *         Note: Bitmask does not represent concurrency matrix.
+     */
+    getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask)
+        generates (WifiStatus status, vec<WifiUsableChannel> channels);
 };
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index 8e2e647..7cee4cd 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -356,6 +356,129 @@
     return true;
 }
 
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) {
+    switch (hidl_band) {
+        case V1_5::WifiBand::BAND_24GHZ:
+            return legacy_hal::WLAN_MAC_2_4_BAND;
+        case V1_5::WifiBand::BAND_5GHZ:
+        case V1_5::WifiBand::BAND_5GHZ_DFS:
+        case V1_5::WifiBand::BAND_5GHZ_WITH_DFS:
+            return legacy_hal::WLAN_MAC_5_0_BAND;
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ:
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+            return (legacy_hal::WLAN_MAC_2_4_BAND |
+                    legacy_hal::WLAN_MAC_5_0_BAND);
+        case V1_5::WifiBand::BAND_6GHZ:
+            return legacy_hal::WLAN_MAC_6_0_BAND;
+        case V1_5::WifiBand::BAND_5GHZ_6GHZ:
+            return (legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND);
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+            return (legacy_hal::WLAN_MAC_2_4_BAND |
+                    legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND);
+        case V1_5::WifiBand::BAND_60GHZ:
+            return legacy_hal::WLAN_MAC_60_0_BAND;
+        default:
+            return (
+                legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+                legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+    }
+}
+
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) {
+    uint32_t legacy_iface_mask = 0;
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
+    }
+    return legacy_iface_mask;
+}
+
+uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) {
+    uint32_t hidl_iface_mask = 0;
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS;
+    }
+    return hidl_iface_mask;
+}
+
+bool convertLegacyWifiUsableChannelToHidl(
+    const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+    V1_5::WifiUsableChannel* hidl_usable_channel) {
+    if (!hidl_usable_channel) {
+        return false;
+    }
+    *hidl_usable_channel = {};
+    hidl_usable_channel->channel = legacy_usable_channel.freq;
+    hidl_usable_channel->channelBandwidth =
+        convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
+    hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl(
+        legacy_usable_channel.iface_mode_mask);
+
+    return true;
+}
+
+bool convertLegacyWifiUsableChannelsToHidl(
+    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) {
+    if (!hidl_usable_channels) {
+        return false;
+    }
+    *hidl_usable_channels = {};
+    for (const auto& legacy_usable_channel : legacy_usable_channels) {
+        V1_5::WifiUsableChannel hidl_usable_channel;
+        if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel,
+                                                  &hidl_usable_channel)) {
+            return false;
+        }
+        hidl_usable_channels->push_back(hidl_usable_channel);
+    }
+    return true;
+}
+
 bool convertLegacyWifiMacInfosToHidl(
     const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
     std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>*
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index feb47ef..c0d7bf8 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -206,6 +206,11 @@
 bool convertLegacyVectorOfRttResultToHidl(
     const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
     std::vector<V1_4::RttResult>* hidl_results);
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
+bool convertLegacyWifiUsableChannelsToHidl(
+    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
 }  // namespace hidl_struct_util
 }  // namespace implementation
 }  // namespace V1_5
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 50836cc..2dc7314 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -738,6 +738,14 @@
                            code);
 }
 
+Return<void> WifiChip::getUsableChannels(
+    WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
+    getUsableChannels_cb _hidl_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getUsableChannelsInternal, _hidl_cb, band,
+                           ifaceModeMask);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearBridgedApAll();
     invalidateAndClearAll(ap_ifaces_);
@@ -1036,7 +1044,6 @@
 
 WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
     const std::string& ifname, const std::string& ifInstanceName) {
-    legacy_hal::wifi_error legacy_status;
     const auto iface = findUsingName(ap_ifaces_, ifname);
     if (!iface.get() || ifInstanceName.empty()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
@@ -1048,13 +1055,13 @@
                 if (iface == ifInstanceName) {
                     if (!iface_util_.lock()->removeIfaceFromBridge(it.first,
                                                                    iface)) {
-                        LOG(ERROR) << "Failed to remove interface: " << iface
-                                   << " from " << ifname << ", error: "
-                                   << legacyErrorToString(legacy_status);
+                        LOG(ERROR)
+                            << "Failed to remove interface: " << ifInstanceName
+                            << " from " << ifname;
                         return createWifiStatus(
                             WifiStatusCode::ERROR_NOT_AVAILABLE);
                     }
-                    legacy_status =
+                    legacy_hal::wifi_error legacy_status =
                         legacy_hal_.lock()->deleteVirtualInterface(iface);
                     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
                         LOG(ERROR) << "Failed to del interface: " << iface
@@ -1492,6 +1499,25 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
+std::pair<WifiStatus, std::vector<WifiUsableChannel>>
+WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
+    std::tie(legacy_status, legacy_usable_channels) =
+        legacy_hal_.lock()->getUsableChannels(
+            hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
+            hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask));
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    std::vector<WifiUsableChannel> hidl_usable_channels;
+    if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(
+            legacy_usable_channels, &hidl_usable_channels)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
+}
+
 WifiStatus WifiChip::handleChipConfiguration(
     /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
     ChipModeId mode_id) {
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index 7d7a9b5..d542792 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -180,6 +180,9 @@
         setCoexUnsafeChannels_cb hidl_status_cb) override;
     Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
                                 setCountryCode_cb _hidl_cb) override;
+    Return<void> getUsableChannels(WifiBand band,
+                                   hidl_bitfield<WifiIfaceMode> ifaceModeMask,
+                                   getUsableChannels_cb _hidl_cb) override;
 
    private:
     void invalidateAndRemoveAllIfaces();
@@ -261,6 +264,8 @@
     WifiStatus setCoexUnsafeChannelsInternal(
         std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions);
     WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
+    std::pair<WifiStatus, std::vector<WifiUsableChannel>>
+    getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask);
     WifiStatus handleChipConfiguration(
         std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
     WifiStatus registerDebugRingBufferCallback();
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index 3e65ee0..94603b3 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -36,6 +36,7 @@
 static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
 static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
 static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
 // need a long timeout (1000ms) for chips that unload their driver.
 static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
 static constexpr char kDriverPropName[] = "wlan.driver.status";
@@ -1636,6 +1637,19 @@
                                                    multiplier);
 }
 
+std::pair<wifi_error, std::vector<wifi_usable_channel>>
+WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask) {
+    std::vector<wifi_usable_channel> channels;
+    channels.resize(kMaxWifiUsableChannels);
+    uint32_t size = 0;
+    wifi_error status = global_func_table_.wifi_get_usable_channels(
+        global_handle_, band_mask, iface_mode_mask, channels.size(), &size,
+        reinterpret_cast<wifi_usable_channel*>(channels.data()));
+    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+    channels.resize(size);
+    return {status, std::move(channels)};
+}
+
 void WifiLegacyHal::invalidate() {
     global_handle_ = nullptr;
     iface_name_to_handle_.clear();
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index 0cc1cff..dc641ae 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -36,9 +36,13 @@
 namespace legacy_hal {
 // Import all the types defined inside the legacy HAL header files into this
 // namespace.
+using ::frame_info;
+using ::frame_type;
 using ::FRAME_TYPE_80211_MGMT;
 using ::FRAME_TYPE_ETHERNET_II;
 using ::FRAME_TYPE_UNKNOWN;
+using ::fw_roaming_state_t;
+using ::mac_addr;
 using ::NAN_CHANNEL_24G_BAND;
 using ::NAN_CHANNEL_5G_BAND_HIGH;
 using ::NAN_CHANNEL_5G_BAND_LOW;
@@ -80,8 +84,6 @@
 using ::NAN_RESPONSE_TCA;
 using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
 using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-using ::NAN_SECURITY_KEY_INPUT_PMK;
 using ::NAN_SECURITY_KEY_INPUT_PMK;
 using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
 using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
@@ -154,19 +156,20 @@
 using ::RTT_PEER_P2P_CLIENT;
 using ::RTT_PEER_P2P_GO;
 using ::RTT_PEER_STA;
+using ::rtt_peer_type;
 using ::RTT_STATUS_ABORTED;
-using ::RTT_STATUS_FAILURE;
 using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
 using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
 using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
 using ::RTT_STATUS_FAIL_INVALID_TS;
-using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
 using ::RTT_STATUS_FAIL_NO_CAPABILITY;
 using ::RTT_STATUS_FAIL_NO_RSP;
+using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
 using ::RTT_STATUS_FAIL_PROTOCOL;
 using ::RTT_STATUS_FAIL_REJECTED;
 using ::RTT_STATUS_FAIL_SCHEDULE;
 using ::RTT_STATUS_FAIL_TM_TIMEOUT;
+using ::RTT_STATUS_FAILURE;
 using ::RTT_STATUS_INVALID_REQ;
 using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
 using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
@@ -185,6 +188,8 @@
 using ::RX_PKT_FATE_FW_DROP_OTHER;
 using ::RX_PKT_FATE_FW_QUEUED;
 using ::RX_PKT_FATE_SUCCESS;
+using ::ssid_t;
+using ::transaction_id;
 using ::TX_PKT_FATE_ACKED;
 using ::TX_PKT_FATE_DRV_DROP_INVALID;
 using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
@@ -199,24 +204,31 @@
 using ::WIFI_AC_BK;
 using ::WIFI_AC_VI;
 using ::WIFI_AC_VO;
+using ::wifi_band;
 using ::WIFI_BAND_A;
-using ::WIFI_BAND_ABG;
-using ::WIFI_BAND_ABG_WITH_DFS;
 using ::WIFI_BAND_A_DFS;
 using ::WIFI_BAND_A_WITH_DFS;
+using ::WIFI_BAND_ABG;
+using ::WIFI_BAND_ABG_WITH_DFS;
 using ::WIFI_BAND_BG;
 using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_results;
 using ::WIFI_CHAN_WIDTH_10;
 using ::WIFI_CHAN_WIDTH_160;
 using ::WIFI_CHAN_WIDTH_20;
 using ::WIFI_CHAN_WIDTH_40;
 using ::WIFI_CHAN_WIDTH_5;
-using ::WIFI_CHAN_WIDTH_5;
 using ::WIFI_CHAN_WIDTH_80;
 using ::WIFI_CHAN_WIDTH_80P80;
 using ::WIFI_CHAN_WIDTH_INVALID;
+using ::wifi_channel_info;
+using ::wifi_channel_stat;
+using ::wifi_channel_width;
+using ::wifi_coex_restriction;
+using ::wifi_coex_unsafe_channel;
 using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
 using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+using ::wifi_error;
 using ::WIFI_ERROR_BUSY;
 using ::WIFI_ERROR_INVALID_ARGS;
 using ::WIFI_ERROR_INVALID_REQUEST_ID;
@@ -228,12 +240,29 @@
 using ::WIFI_ERROR_TOO_MANY_REQUESTS;
 using ::WIFI_ERROR_UNINITIALIZED;
 using ::WIFI_ERROR_UNKNOWN;
+using ::wifi_gscan_capabilities;
+using ::wifi_hal_fn;
+using ::wifi_information_element;
+using ::WIFI_INTERFACE_IBSS;
+using ::WIFI_INTERFACE_MESH;
+using ::wifi_interface_mode;
+using ::WIFI_INTERFACE_NAN;
+using ::WIFI_INTERFACE_P2P_CLIENT;
+using ::WIFI_INTERFACE_P2P_GO;
+using ::WIFI_INTERFACE_SOFTAP;
+using ::WIFI_INTERFACE_STA;
+using ::WIFI_INTERFACE_TDLS;
+using ::wifi_interface_type;
 using ::WIFI_INTERFACE_TYPE_AP;
 using ::WIFI_INTERFACE_TYPE_NAN;
 using ::WIFI_INTERFACE_TYPE_P2P;
 using ::WIFI_INTERFACE_TYPE_STA;
+using ::WIFI_INTERFACE_UNKNOWN;
+using ::wifi_latency_mode;
 using ::WIFI_LATENCY_MODE_LOW;
 using ::WIFI_LATENCY_MODE_NORMAL;
+using ::wifi_lci_information;
+using ::wifi_lcr_information;
 using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
 using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
 using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
@@ -242,61 +271,34 @@
 using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
 using ::WIFI_MOTION_EXPECTED;
 using ::WIFI_MOTION_NOT_EXPECTED;
+using ::wifi_motion_pattern;
 using ::WIFI_MOTION_UNKNOWN;
+using ::wifi_multi_sta_use_case;
+using ::wifi_power_scenario;
 using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
 using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
 using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
 using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
 using ::WIFI_POWER_SCENARIO_VOICE_CALL;
-using ::WIFI_RTT_BW_10;
-using ::WIFI_RTT_BW_160;
-using ::WIFI_RTT_BW_20;
-using ::WIFI_RTT_BW_40;
-using ::WIFI_RTT_BW_5;
-using ::WIFI_RTT_BW_80;
-using ::WIFI_RTT_PREAMBLE_HE;
-using ::WIFI_RTT_PREAMBLE_HT;
-using ::WIFI_RTT_PREAMBLE_LEGACY;
-using ::WIFI_RTT_PREAMBLE_VHT;
-using ::WIFI_SCAN_FLAG_INTERRUPTED;
-using ::WIFI_SUCCESS;
-using ::WLAN_MAC_2_4_BAND;
-using ::WLAN_MAC_5_0_BAND;
-using ::WLAN_MAC_6_0_BAND;
-using ::frame_info;
-using ::frame_type;
-using ::fw_roaming_state_t;
-using ::mac_addr;
-using ::rtt_peer_type;
-using ::ssid_t;
-using ::transaction_id;
-using ::wifi_band;
-using ::wifi_cached_scan_results;
-using ::wifi_channel_info;
-using ::wifi_channel_stat;
-using ::wifi_channel_width;
-using ::wifi_coex_restriction;
-using ::wifi_coex_unsafe_channel;
-using ::wifi_error;
-using ::wifi_gscan_capabilities;
-using ::wifi_hal_fn;
-using ::wifi_information_element;
-using ::wifi_interface_type;
-using ::wifi_latency_mode;
-using ::wifi_lci_information;
-using ::wifi_lcr_information;
-using ::wifi_motion_pattern;
-using ::wifi_multi_sta_use_case;
-using ::wifi_power_scenario;
 using ::wifi_rate;
 using ::wifi_request_id;
 using ::wifi_ring_buffer_status;
 using ::wifi_roaming_capabilities;
 using ::wifi_roaming_config;
 using ::wifi_rtt_bw;
+using ::WIFI_RTT_BW_10;
+using ::WIFI_RTT_BW_160;
+using ::WIFI_RTT_BW_20;
+using ::WIFI_RTT_BW_40;
+using ::WIFI_RTT_BW_5;
+using ::WIFI_RTT_BW_80;
 using ::wifi_rtt_capabilities;
 using ::wifi_rtt_config;
 using ::wifi_rtt_preamble;
+using ::WIFI_RTT_PREAMBLE_HE;
+using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_LEGACY;
+using ::WIFI_RTT_PREAMBLE_VHT;
 using ::wifi_rtt_responder;
 using ::wifi_rtt_result;
 using ::wifi_rtt_status;
@@ -305,9 +307,16 @@
 using ::wifi_rx_report;
 using ::wifi_scan_bucket_spec;
 using ::wifi_scan_cmd_params;
+using ::WIFI_SCAN_FLAG_INTERRUPTED;
 using ::wifi_scan_result;
+using ::WIFI_SUCCESS;
 using ::wifi_tx_packet_fate;
 using ::wifi_tx_report;
+using ::wifi_usable_channel;
+using ::WLAN_MAC_2_4_BAND;
+using ::WLAN_MAC_5_0_BAND;
+using ::WLAN_MAC_60_0_BAND;
+using ::WLAN_MAC_6_0_BAND;
 
 // APF capabilities supported by the iface.
 struct PacketFilterCapabilities {
@@ -693,6 +702,11 @@
     wifi_error setDtimConfig(const std::string& iface_name,
                              uint32_t multiplier);
 
+    // Retrieve the list of usable channels in the requested bands
+    // for the requested modes
+    std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
+        uint32_t band_mask, uint32_t iface_mode_mask);
+
    private:
     // Retrieve interface handles for all the available interfaces.
     wifi_error retrieveIfaceHandles();
diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
index 7ba5d9b..6212960 100644
--- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
@@ -159,6 +159,7 @@
     populateStubFor(&hal_fn->wifi_twt_get_stats);
     populateStubFor(&hal_fn->wifi_twt_clear_stats);
     populateStubFor(&hal_fn->wifi_set_dtim_config);
+    populateStubFor(&hal_fn->wifi_get_usable_channels);
     return true;
 }
 }  // namespace legacy_hal
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index 9fa5c80..4dff774 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -24,6 +24,8 @@
 import @1.0::NanCapabilities;
 import @1.2::NanConfigRequestSupplemental;
 import @1.3::StaLinkLayerRadioStats;
+import @1.0::WifiChannelInMhz;
+import @1.0::WifiChannelWidthInMhz;
 
 /**
  * Wifi bands defined in 80211 spec.
@@ -44,6 +46,64 @@
 };
 
 /**
+ * Interface operating modes.
+ */
+enum WifiIfaceMode : uint32_t {
+    /**
+     * Interface operation mode is client.
+     */
+    IFACE_MODE_STA = 1 << 0,
+    /**
+     * Interface operation mode is Hotspot.
+     */
+    IFACE_MODE_SOFTAP = 1 << 1,
+    /**
+     * Interface operation mode is Ad-Hoc network.
+     */
+    IFACE_MODE_IBSS = 1 << 2,
+    /**
+     * Interface operation mode is Wifi Direct Client.
+     */
+    IFACE_MODE_P2P_CLIENT = 1 << 3,
+    /**
+     * Interface operation mode is Wifi Direct Group Owner.
+     */
+    IFACE_MODE_P2P_GO = 1 << 4,
+    /**
+     * Interface operation mode is Aware.
+     */
+    IFACE_MODE_NAN = 1 << 5,
+    /**
+     * Interface operation mode is Mesh network.
+     */
+    IFACE_MODE_MESH = 1 << 6,
+    /**
+     * Interface operation mode is Tunneled Direct Link Setup.
+     */
+    IFACE_MODE_TDLS = 1 << 7,
+};
+
+/**
+ * Wifi usable channel information.
+ */
+struct WifiUsableChannel {
+    /**
+     * Wifi channel freqeuncy in MHz.
+     */
+    WifiChannelInMhz channel;
+
+    /**
+     * Wifi channel bandwidth in MHz.
+     */
+    WifiChannelWidthInMhz channelBandwidth;
+
+    /**
+     * Iface modes feasible on this channel.
+     */
+    bitfield<WifiIfaceMode> ifaceModeMask;
+};
+
+/**
  * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous
  * versions.
  */
diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
index 36a8448..509f1bd 100644
--- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
@@ -45,6 +45,7 @@
 using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
 using ::android::hardware::wifi::V1_5::IWifiChip;
 using ::android::hardware::wifi::V1_5::WifiBand;
+using ::android::hardware::wifi::V1_5::WifiIfaceMode;
 
 /**
  * Fixture to use for all Wifi chip HIDL interface tests.
@@ -187,6 +188,23 @@
               HIDL_INVOKE(wifi_chip_, setCountryCode, kCountryCode).code);
 }
 
+/* getUsableChannels:
+ * Ensure that a call to getUsableChannels will return with a success
+ * status for valid inputs.
+ */
+TEST_P(WifiChipHidlTest, getUsableChannels) {
+    uint32_t ifaceModeMask =
+        WifiIfaceMode::IFACE_MODE_P2P_CLIENT | WifiIfaceMode::IFACE_MODE_P2P_GO;
+    configureChipForIfaceType(IfaceType::STA, true);
+    WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+    const auto& statusNonEmpty =
+        HIDL_INVOKE(wifi_chip_, getUsableChannels, band, ifaceModeMask);
+    if (statusNonEmpty.first.code != WifiStatusCode::SUCCESS) {
+        EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+                  statusNonEmpty.first.code);
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest);
 INSTANTIATE_TEST_SUITE_P(
     PerInstance, WifiChipHidlTest,