Merge "AttestationKey documentation"
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index b5b3925..c2585bd 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -106,6 +106,7 @@
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_FM_TUNER;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_IP;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LINE;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LOOPBACK;
@@ -140,6 +141,7 @@
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_FM;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_IP;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_LINE;
@@ -208,9 +210,11 @@
     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_DRA;
     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;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_UHD;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRC;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCB;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCNW;
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index 4f5614b..e0df359 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -252,6 +252,7 @@
             <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
@@ -303,6 +304,7 @@
             <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
             <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
             <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_EARC"/>
             <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
             <xs:enumeration value="AUDIO_DEVICE_IN_BLE_HEADSET"/>
             <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
@@ -411,6 +413,8 @@
             <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/>
             <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
             <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_UHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_DRA"/>
         </xs:restriction>
     </xs:simpleType>
     <xs:simpleType name="extendableAudioFormat">
diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
index fe3e4ea..a92a277 100644
--- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
+++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
@@ -157,6 +157,7 @@
         case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
         case AudioDevice::AUDIO_DEVICE_OUT_LINE:
         case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
+        case AudioDevice::AUDIO_DEVICE_OUT_HDMI_EARC:
         case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
         case AudioDevice::AUDIO_DEVICE_OUT_FM:
         case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
@@ -199,6 +200,7 @@
         case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
         case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
         case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
+        case AudioDevice::AUDIO_DEVICE_IN_HDMI_EARC:
         case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
         case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET:
         case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
diff --git a/current.txt b/current.txt
index f446754..0b6f698 100644
--- a/current.txt
+++ b/current.txt
@@ -793,5 +793,45 @@
 2b5afef68e3e2ff1dab63e4f2ee57337ef2635ec812f49080cadfce966d33b52 android.hardware.radio@1.2::IRadio
 
 # HALs released in Android S
-# NOTE: waiting to freeze HALs until later in the release
-# NOTE: new HALs are recommended to be in AIDL
+59fa68432e374c8d3b7ec098a91a1e023a2c728110bb733237c551afa5929725 android.hardware.audio@7.0::IDevice
+2207948ca127b801c94f667c99dfd139f150b50671e1408d3e855d03efbf631d android.hardware.audio@7.0::IDevicesFactory
+1d201e15c553cd44c62864ac8d7039351ddf048a7ee61e380f6efb0904442eb8 android.hardware.audio@7.0::IPrimaryDevice
+38afa920e6d36013b5a800e8c82eefeebd24602de24441e2f8ce5b3bdf62d3af android.hardware.audio@7.0::IStream
+77d84330418abba5a92b0cdc4e27fa7c85c27344eaf7eeef441b8e88829ee475 android.hardware.audio@7.0::IStreamIn
+9e4d79ed8f3c7e18455f371342ea1802f080bae38f64db746cc433305ee1978b android.hardware.audio@7.0::IStreamOut
+54cbc3c637fe8d4b889ccb5690e5e3069ca8efd9c6607ce1d021a3f47576c67e android.hardware.audio@7.0::IStreamOutCallback
+8036ae0a68a698a79207218018de5f41aed344723f644112ffc99e20e5e2e9ff android.hardware.audio@7.0::IStreamOutEventCallback
+84978dbd15d4fa8be6073d0974755f7718ee0cde519ce71449fb734f53cee46b android.hardware.audio@7.0::types
+6a03a9d8cc917da00e8b88f4abc42db2f741e2d50901e8ab6dea32084a238fbd android.hardware.audio.common@7.0::types
+842b4485a00005fb938f674b12445cb592cd1636f56c7cc447966119070811bd android.hardware.audio.effect@7.0::IAcousticEchoCancelerEffect
+b62a85e5d745dc35b5a60464c6b33a5bb7a2b8b95863a1374aee77ea29cf8f49 android.hardware.audio.effect@7.0::IAutomaticGainControlEffect
+c8d5e30848191713db7cffccc482e4427816f33c98a24734c8769962f79f855b android.hardware.audio.effect@7.0::IBassBoostEffect
+7d021ecdf5bb6a61eb9ad193585d4986d1a64cb7fb4b52f219d7380145f2c6f1 android.hardware.audio.effect@7.0::IDownmixEffect
+7fee1e7c7bb3d513a524c8963d1f8f7c2ad856f26c745b4ebc286b40d503264a android.hardware.audio.effect@7.0::IEffect
+7596050ccc00234458dcb4e692056ed3c16f3618c11d7b17cb749cfd5713705d android.hardware.audio.effect@7.0::IEffectBufferProviderCallback
+f2e41467bcf1140a11b219c2e8f77981b955c2941befe66e1cc685b7863ae4c9 android.hardware.audio.effect@7.0::IEffectsFactory
+af66fb4addbc477f9fea65fb63475203122a9189624ca8d14e757bc7826d60a4 android.hardware.audio.effect@7.0::IEnvironmentalReverbEffect
+2878d007ed55e1a4149ddcd29606962c948d8610642276f91dffd5ed32281824 android.hardware.audio.effect@7.0::IEqualizerEffect
+0260ef9e2a3e077de366ebebc0c117c7ee13f46a1eabd4abd66cc6245d0bed98 android.hardware.audio.effect@7.0::ILoudnessEnhancerEffect
+3586bbc3a7cbe30f9aff0a522524eea9b78eea78280f09c35d43dbab48a1193e android.hardware.audio.effect@7.0::INoiseSuppressionEffect
+a7d74d7e7e0b1e3b739f233b7776bf01e868856a536f5cdac0f307e9c2850e64 android.hardware.audio.effect@7.0::IPresetReverbEffect
+b4cbc1f2d38787f2ad069a8e4d10c0896287531a2596f0de0283e390b0ecf05d android.hardware.audio.effect@7.0::IVirtualizerEffect
+2b5681e1ea6a2db0dc1e84edb96d3de2f7daf306046543e7956be76dcb8f20fb android.hardware.audio.effect@7.0::IVisualizerEffect
+fa1e2d78e66fd662de93cb479ffd55947fe54f51cb53915814b3d3e3036c86a5 android.hardware.audio.effect@7.0::types
+4baf8e0eca4aa896cc9ceb7bb676aaf4fa21372ef8b49eed68eced1221c3dc0d android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvider
+d417a9212c8f96e3a06a2f221c8c5756c765355b2b81de2b2a65d4c9eee85401 android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory
+c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardware.bluetooth.audio@2.1::types
+6763dd2273b1b47f3ac68af9b66870287eba33fb5b4d66e8fe1d30ae18ce24cb android.hardware.boot@1.2::IBootControl
+0c0657fad2239c2c7ec363d3b13f2e002d1c267ca89d2cc96d2b1de0475386cb android.hardware.fastboot@1.1::IFastboot
+3e8866987de4ecb48807c09d4c88ec38365930a22415f1b74edf8b14da17846b android.hardware.radio@1.6::IRadio
+715789427a44cc78f9d123b0ceb9e035e4ac2b1049501337c23a512e85b87850 android.hardware.radio@1.6::IRadioIndication
+2e9c08c4bc9539d8da28d7de33500f87148f7fa2e377238ee898b41752ac4f29 android.hardware.radio@1.6::IRadioResponse
+6475887a9cd5cc8cb803e3a78956d84d7a5fde571407ede2396f3ea5e0c0d3ad android.hardware.radio@1.6::types
+f22813615be1445ddd817655c054fc69dc9efea56c9035cd0757f3cbed190641 android.hardware.radio.config@1.3::IRadioConfig
+c9ad18729268593d14681d88ffad1c97e707444a45e1b4ed804dab949edbd84f android.hardware.radio.config@1.3::IRadioConfigResponse
+78dcb9a6975e8b377cb90bbe952078162960941468c992dcd2e1830a477b8c03 android.hardware.radio.config@1.3::types
+fd43298c43f70130c747a642ee43b0c242ac0cebffb377faa24f2725f0aa6caf android.hardware.tetheroffload.control@1.1::IOffloadControl
+fe18c9032e4063efca3fff3c377dd69780de1f96e8e2bc3f7d100a5d8bd467b4 android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback
+e34b4c7bec5e032c14804707ca924dd6b99ed5ba139da7505fe7d698d0fe178f android.hardware.tetheroffload.control@1.1::types
+
+# There should be no more HIDL HALs - please use AIDL instead.
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HardwareBufferDescription.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HardwareBufferDescription.aidl
index 8b12169..232e023 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HardwareBufferDescription.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HardwareBufferDescription.aidl
@@ -21,7 +21,7 @@
   int width;
   int height;
   int layers;
-  android.hardware.graphics.common.PixelFormat format;
-  android.hardware.graphics.common.BufferUsage usage;
+  android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED;
+  android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER;
   int stride;
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl b/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl
index e1e3492..078c512 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl
@@ -29,7 +29,7 @@
     int width;
     int height;
     int layers;
-    PixelFormat format;
-    BufferUsage usage;
+    PixelFormat format = PixelFormat.UNSPECIFIED;
+    BufferUsage usage = BufferUsage.CPU_READ_NEVER;
     int stride;
 }
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 a097895..3224e4b 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
@@ -43,8 +43,8 @@
   void startRetrieval(in android.hardware.identity.SecureAccessControlProfile[] accessControlProfiles, in android.hardware.keymaster.HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob, in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
   void startRetrieveEntryValue(in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize, in int[] accessControlProfileIds);
   byte[] retrieveEntryValue(in byte[] encryptedContent);
-  void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
-  android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
+  @SuppressWarnings(value={"out-array"}) void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
+  @SuppressWarnings(value={"out-array"}) 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);
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 a713462..19a29ec 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
@@ -38,6 +38,6 @@
   android.hardware.identity.SecureAccessControlProfile addAccessControlProfile(in int id, in android.hardware.identity.Certificate readerCertificate, in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
   void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize);
   byte[] addEntryValue(in byte[] content);
-  void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
+  @SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
   void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index d23f88c..8ae293b 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -324,6 +324,7 @@
      *
      * @param out deviceNameSpaces the bytes of DeviceNameSpaces.
      */
+    @SuppressWarnings(value={"out-array"})
     void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
 
     /**
@@ -376,6 +377,7 @@
      *
      * @return an X.509 certificate for the new signing key, signed by the credential key.
      */
+    @SuppressWarnings(value={"out-array"})
     Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
 
     /**
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 5f878ee..22bcf61 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -320,6 +320,7 @@
      *              "accessControlProfiles" : [ * uint ],
      *          }
      */
+    @SuppressWarnings(value={"out-array"})
     void finishAddingEntries(out byte[] credentialData,
         out byte[] proofOfProvisioningSignature);
 
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
index db1df2b..4f21cba 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -21,7 +21,7 @@
   long challenge;
   long userId;
   long authenticatorId;
-  android.hardware.keymaster.HardwareAuthenticatorType authenticatorType;
+  android.hardware.keymaster.HardwareAuthenticatorType authenticatorType = android.hardware.keymaster.HardwareAuthenticatorType.NONE;
   android.hardware.keymaster.Timestamp timestamp;
   byte[] mac;
 }
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
index 0633765..b116dac 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
@@ -20,6 +20,6 @@
 parcelable VerificationToken {
   long challenge;
   android.hardware.keymaster.Timestamp timestamp;
-  android.hardware.keymaster.SecurityLevel securityLevel;
+  android.hardware.keymaster.SecurityLevel securityLevel = android.hardware.keymaster.SecurityLevel.SOFTWARE;
   byte[] mac;
 }
diff --git a/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
index 58602aa..99b036a 100644
--- a/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -55,7 +55,7 @@
      * authenticatorType describes the type of authentication that took place, e.g. password or
      * fingerprint.
      */
-    HardwareAuthenticatorType authenticatorType;
+    HardwareAuthenticatorType authenticatorType = HardwareAuthenticatorType.NONE;
 
     /**
      * timestamp indicates when the user authentication took place, in milliseconds since some
diff --git a/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
index f053254..5efd937 100644
--- a/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
@@ -43,7 +43,7 @@
     /**
      * SecurityLevel of the secure environment that generated the token.
      */
-    SecurityLevel securityLevel;
+    SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
 
     /**
      * 32-byte HMAC-SHA256 of the above values, computed as:
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operand.aidl
index 5a9f4ff..1d9bdd8 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operand.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operand.aidl
@@ -34,11 +34,11 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 parcelable Operand {
-  android.hardware.neuralnetworks.OperandType type;
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
   int[] dimensions;
   float scale;
   int zeroPoint;
-  android.hardware.neuralnetworks.OperandLifeTime lifetime;
+  android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE;
   android.hardware.neuralnetworks.DataLocation location;
   @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperandPerformance.aidl
index de93d8b..ebb361b 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperandPerformance.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -34,6 +34,6 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 parcelable OperandPerformance {
-  android.hardware.neuralnetworks.OperandType type;
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
   android.hardware.neuralnetworks.PerformanceInfo info;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operation.aidl
index 33fcd60..a4a3fbe 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Operation.aidl
@@ -34,7 +34,7 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 parcelable Operation {
-  android.hardware.neuralnetworks.OperationType type;
+  android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD;
   int[] inputs;
   int[] outputs;
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/Operand.aidl
index 4d2260f..998e06d 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/Operand.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/Operand.aidl
@@ -33,7 +33,7 @@
      * {@link IDevice::OPERAND_TYPE_BASE_MAX} is possible and should be interpreted as an extension
      * type according to {@link Model::extensionNameToPrefix}.
      */
-    OperandType type;
+    OperandType type = OperandType.FLOAT32;
     /**
      * Dimensions of the operand.
      *
@@ -86,7 +86,7 @@
     /**
      * How the operand is used.
      */
-    OperandLifeTime lifetime;
+    OperandLifeTime lifetime = OperandLifeTime.TEMPORARY_VARIABLE;
     /**
      * Where to find the data for this operand.
      * If the lifetime is TEMPORARY_VARIABLE, SUBGRAPH_INPUT, SUBGRAPH_OUTPUT, or NO_VALUE:
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperandPerformance.aidl
index 7fd86f9..7f53967 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperandPerformance.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -25,6 +25,6 @@
  */
 @VintfStability
 parcelable OperandPerformance {
-    OperandType type;
+    OperandType type = OperandType.FLOAT32;
     PerformanceInfo info;
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/Operation.aidl
index 0c6032f..366d9a4 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/Operation.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/Operation.aidl
@@ -30,7 +30,7 @@
      * {@link IDevice::OPERATION_TYPE_BASE_MAX} is possible and should be interpreted as an
      * extension type according to {@link Model::extensionNameToPrefix}.
      */
-    OperationType type;
+    OperationType type = OperationType.ADD;
     /**
      * Describes the table that contains the indexes of the inputs of the operation. The offset is
      * the index in the operandIndexes table.
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 bf30999..fa643fc 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
@@ -44,10 +44,10 @@
   void deleteKey(in byte[] keyBlob);
   void deleteAllKeys();
   void destroyAttestationIds();
-  android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in android.hardware.security.keymint.HardwareAuthToken authToken);
+  android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken);
   void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
   void earlyBootEnded();
   byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
-  byte[] performOperation(in byte[] request);
+  android.hardware.security.keymint.KeyCharacteristics[] getKeyCharacteristics(in byte[] keyBlob, in byte[] appId, in byte[] appData);
   const int AUTH_TOKEN_MAC_LENGTH = 32;
 }
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 7591318..e310b44 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
@@ -48,7 +48,6 @@
   RSA_PUBLIC_EXPONENT = 1342177480,
   INCLUDE_UNIQUE_ID = 1879048394,
   RSA_OAEP_MGF_DIGEST = 536871115,
-  BLOB_USAGE_REQUIREMENTS = 268435757,
   BOOTLOADER_ONLY = 1879048494,
   ROLLBACK_RESISTANCE = 1879048495,
   HARDWARE_TYPE = 268435760,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl
index 2304a58..b5336b9 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl
@@ -25,7 +25,10 @@
  */
 @VintfStability
 parcelable BeginResult {
-    /* This is the challenge used in verifyAuthorization.  It must be a nonce. */
+    /**
+     * This is the challenge used to verify authorization of an operation.
+     * See IKeyMintOperation.aidl entrypoints updateAad() and update().
+     */
     long challenge;
 
     /**
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index ddbeafc..c6f89bd 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -20,6 +20,7 @@
 import android.hardware.security.keymint.BeginResult;
 import android.hardware.security.keymint.HardwareAuthToken;
 import android.hardware.security.keymint.IKeyMintOperation;
+import android.hardware.security.keymint.KeyCharacteristics;
 import android.hardware.security.keymint.KeyCreationResult;
 import android.hardware.security.keymint.KeyFormat;
 import android.hardware.security.keymint.KeyMintHardwareInfo;
@@ -107,7 +108,6 @@
  *
  *      - 168-bit keys.
  *      - CBC and ECB mode.
-
  *      - CBC and ECB modes must support unpadded and PKCS7 padding modes.  With no padding CBC and
  *        ECB-mode operations must fail with ErrorCode::INVALID_INPUT_LENGTH if the input isn't a
  *        multiple of the DES block size.
@@ -150,8 +150,8 @@
  *
  * The IKeyMintDevice must ignore unknown tags.
  *
- * The caller must always provide the current date time in the keyParameter CREATION_DATETIME
- * tags.
+ * The caller may provide the current date time in the keyParameter CREATION_DATETIME tag, but
+ * this is optional and informational only.
  *
  * All authorization tags and their values enforced by an IKeyMintDevice must be cryptographically
  * bound to the private/secret key material such that any modification of the portion of the key
@@ -185,7 +185,7 @@
  * startup, preferably by the bootloader.  This bitstring must be cryptographically bound to every
  * key managed by the IKeyMintDevice.  As above, the recommended mechanism for this cryptographic
  * binding is to include the Root of Trust data in the input to the key derivation function used to
- * derive a key that is used to encryp the private/secret key material.
+ * derive a key that is used to encrypt the private/secret key material.
  *
  * The root of trust consists of a bitstring that must be derived from the public key used by
  * Verified Boot to verify the signature on the boot image and from the lock state of the
@@ -247,7 +247,7 @@
      * Generates a new cryptographic key, specifying associated parameters, which must be
      * cryptographically bound to the key.  IKeyMintDevice implementations must disallow any use
      * of a key in any way inconsistent with the authorizations specified at generation time.  With
-     * respect to parameters that the secure environment cannot enforce, the secure envionment's
+     * respect to parameters that the secure environment cannot enforce, the secure environment's
      * obligation is limited to ensuring that the unenforceable parameters associated with the key
      * cannot be modified.  In addition, the characteristics returned by generateKey places
      * parameters correctly in the tee-enforced and strongbox-enforced lists.
@@ -257,9 +257,6 @@
      *
      * o Tag::ORIGIN with the value KeyOrigin::GENERATED.
      *
-     * o Tag::BLOB_USAGE_REQUIREMENTS with the appropriate value (see KeyBlobUsageRequirements in
-     *   Tag.aidl).
-     *
      * o Tag::OS_VERSION, Tag::OS_PATCHLEVEL, Tag::VENDOR_PATCHLEVEL and Tag::BOOT_PATCHLEVEL with
      *   appropriate values.
      *
@@ -271,7 +268,7 @@
      *
      * The following parameters are required to generate an RSA key:
      *
-     * o Tag::Key_SIZE specifies the size of the public modulus, in bits.  If omitted, generateKey
+     * o Tag::KEY_SIZE specifies the size of the public modulus, in bits.  If omitted, generateKey
      *   must return ErrorCode::UNSUPPORTED_KEY_SIZE.  Required values for TEE IKeyMintDevice
      *   implementations are 1024, 2048, 3072 and 4096.  StrongBox IKeyMintDevice implementations
      *   must support 2048.
@@ -288,7 +285,7 @@
      *   except AGREE_KEY must be supported for RSA keys.
      *
      * o Tag::DIGEST specifies digest algorithms that may be used with the new key.  TEE
-     *   IKeyMintDevice implementatiosn must support all Digest values (see digest.aidl) for RSA
+     *   IKeyMintDevice implementations must support all Digest values (see digest.aidl) for RSA
      *   keys.  StrongBox IKeyMintDevice implementations must support SHA_2_256.
      *
      * o Tag::PADDING specifies the padding modes that may be used with the new
@@ -298,11 +295,9 @@
      *
      * == ECDSA Keys ==
      *
-     * Either Tag::KEY_SIZE or Tag::EC_CURVE must be provided to generate an ECDSA key.  If neither
-     * is provided, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE.  If Tag::KEY_SIZE is
-     * provided, the possible values are 224, 256, 384 and 521, and must be mapped to Tag::EC_CURVE
-     * values P_224, P_256, P_384 and P_521, respectively.  TEE IKeyMintDevice implementations
-     * must support all curves.  StrongBox implementations must support P_256.
+     * Tag::EC_CURVE must be provided to generate an ECDSA key.  If it is not provided, generateKey
+     * must return ErrorCode::UNSUPPORTED_KEY_SIZE. TEE IKeyMintDevice implementations must support
+     * all curves.  StrongBox implementations must support P_256.
      *
      * == AES Keys ==
      *
@@ -312,6 +307,10 @@
      * If Tag::BLOCK_MODE is specified with value BlockMode::GCM, then the caller must also provide
      * Tag::MIN_MAC_LENGTH.  If omitted, generateKey must return ErrorCode::MISSING_MIN_MAC_LENGTH.
      *
+     * == 3DES Keys ==
+     *
+     * Only Tag::KEY_SIZE is required to generate an 3DES key, and its value must be 168.  If
+     * omitted, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE.
      *
      * @param keyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
      *        provided in params.  See above for detailed specifications of which tags are required
@@ -352,13 +351,12 @@
      *
      * o Tag::ORIGIN (returned in keyCharacteristics) must have the value KeyOrigin::IMPORTED.
      *
-     * @param inKeyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
+     * @param keyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
      *        provided in params.
      *
-     * @param inKeyFormat The format of the key material to import.  See KeyFormat in
-     *        keyformat.aidl.
+     * @param keyFormat The format of the key material to import.  See KeyFormat in keyformat.aidl.
      *
-     * @param inKeyData The key material to import, in the format specified in keyFormat.
+     * @param keyData The key material to import, in the format specified in keyFormat.
      *
      * @param attestationKey, if provided, specifies the key that must be used to sign the
      *        attestation certificate.  If `keyParams` does not contain a Tag::ATTESTATION_CHALLENGE
@@ -381,9 +379,8 @@
      * Securely imports a key, or key pair, returning a key blob and a description of the imported
      * key.
      *
-     * @param inWrappedKeyData The wrapped key material to import.
-     *     TODO(seleneh) Decide if we want the wrapped key in DER-encoded ASN.1 format or CBOR
-     *     format or both.  And specify the standarized format.
+     * @param wrappedKeyData The wrapped key material to import, as ASN.1 DER-encoded data
+     *        corresponding to the following schema.
      *
      *     KeyDescription ::= SEQUENCE(
      *         keyFormat INTEGER,                   # Values from KeyFormat enum.
@@ -401,20 +398,20 @@
      *
      *     Where:
      *
-     *     o keyFormat is an integer from the KeyFormat enum, defining the format of the plaintext
+     *     - keyFormat is an integer from the KeyFormat enum, defining the format of the plaintext
      *       key material.
-     *     o keyParams is the characteristics of the key to be imported (as with generateKey or
+     *     - keyParams is the characteristics of the key to be imported (as with generateKey or
      *       importKey).  If the secure import is successful, these characteristics must be
      *       associated with the key exactly as if the key material had been insecurely imported
-     *       with the IKeyMintDevice::importKey.  See attestKey() for documentation of the
-     *       AuthorizationList schema.
-     *     o encryptedTransportKey is a 256-bit AES key, XORed with a masking key and then encrypted
+     *       with the IKeyMintDevice::importKey.  See KeyCreationResult.aidl for documentation of
+     *       the AuthorizationList schema.
+     *     - encryptedTransportKey is a 256-bit AES key, XORed with a masking key and then encrypted
      *       with the wrapping key specified by wrappingKeyBlob.
-     *     o keyDescription is a KeyDescription, above.
-     *     o encryptedKey is the key material of the key to be imported, in format keyFormat, and
+     *     - keyDescription is a KeyDescription, above.
+     *     - encryptedKey is the key material of the key to be imported, in format keyFormat, and
      *       encrypted with encryptedEphemeralKey in AES-GCM mode, with the DER-encoded
      *       representation of keyDescription provided as additional authenticated data.
-     *     o tag is the tag produced by the AES-GCM encryption of encryptedKey.
+     *     - tag is the tag produced by the AES-GCM encryption of encryptedKey.
      *
      * So, importWrappedKey does the following:
      *
@@ -443,7 +440,7 @@
      *
      * @param passwordSid specifies the password secure ID (SID) of the user that owns the key being
      *        installed.  If the authorization list in wrappedKeyData contains a
-     *        Tag::USER_SECURE_IDwith a value that has the HardwareAuthenticatorType::PASSWORD bit
+     *        Tag::USER_SECURE_ID with a value that has the HardwareAuthenticatorType::PASSWORD bit
      *        set, the constructed key must be bound to the SID value provided by this argument.  If
      *        the wrappedKeyData does not contain such a tag and value, this argument must be
      *        ignored.
@@ -486,9 +483,9 @@
      * patch level and OS version.  This requirement is relaxed for 4.0::IKeymasterDevice and
      * IKeyMintDevice, and the OS version in the boot image footer is no longer used.
      *
-     * @param inKeyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+     * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey().
      *
-     * @param inUpgradeParams A parameter list containing any parameters needed to complete the
+     * @param upgradeParams A parameter list containing any parameters needed to complete the
      *        upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
      *
      * @return A new key blob that references the same key as keyBlobToUpgrade, but is in the new
@@ -502,7 +499,9 @@
      * render the key permanently unusable.  Keys without Tag::ROLLBACK_RESISTANCE may or
      * may not be rendered unusable.
      *
-     * @param inKeyBlob The opaque descriptor returned by generateKey() or importKey();
+     * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+     *
+     * @return error See the ErrorCode enum.
      */
     void deleteKey(in byte[] keyBlob);
 
@@ -511,8 +510,6 @@
      * this function is called all keys with Tag::ROLLBACK_RESISTANCE in their hardware-enforced
      * authorization lists must be rendered permanently unusable.  Keys without
      * Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
-     *
-     * @return error See the ErrorCode enum.
      */
     void deleteAllKeys();
 
@@ -531,28 +528,27 @@
 
     /**
      * Begins a cryptographic operation using the specified key.  If all is well, begin() must
-     * return ErrorCode::OK and create an operation handle which must be passed to subsequent calls
-     * to update(), finish() or abort().
+     * return ErrorCode::OK and create an IKeyMintOperation handle which will be used to perform
+     * the cryptographic operation.
      *
-     * It is critical that each call to begin() be paired with a subsequent call to finish() or
-     * abort(), to allow the IKeyMintDevice implementation to clean up any internal operation
-     * state.  The caller's failure to do this may leak internal state space or other internal
-     * resources and may eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it
-     * runs out of space for operations.  Any result other than ErrorCode::OK from begin(), update()
-     * or finish() implicitly aborts the operation, in which case abort() need not be called (and
-     * must return ErrorCode::INVALID_OPERATION_HANDLE if called).  IKeyMintDevice implementations
-     * must support 32 concurrent operations.
+     * It is critical that each successful call to begin() be paired with a subsequent call to
+     * finish() or abort() on the resulting IKeyMintOperation, to allow the IKeyMintDevice
+     * implementation to clean up any internal operation state.  The caller's failure to do this may
+     * leak internal state space or other internal resources and may eventually cause begin() to
+     * return ErrorCode::TOO_MANY_OPERATIONS when it runs out of space for operations.  Any result
+     * other than ErrorCode::OK from begin() will not return an IKeyMintOperation (in which case
+     * calling finish() or abort() is neither possible nor necessary). IKeyMintDevice
+     * implementations must support 32 concurrent operations.
      *
      * If Tag::APPLICATION_ID or Tag::APPLICATION_DATA were specified during key generation or
      * import, calls to begin must include those tags with the originally-specified values in the
-     * inParams argument to this method.  If not, begin() must return ErrorCode::INVALID_KEY_BLOB.
+     * params argument to this method.  If not, begin() must return ErrorCode::INVALID_KEY_BLOB.
      *
      * == Authorization Enforcement ==
      *
      * The following key authorization parameters must be enforced by the IKeyMintDevice secure
      * environment if the tags were returned in the "hardwareEnforced" list in the
-     * KeyCharacteristics.  Public key operations, meaning KeyPurpose::ENCRYPT and
-     * KeyPurpose::VERIFY must be allowed to succeed even if authorization requirements are not met.
+     * KeyCharacteristics.
      *
      * -- All Key Types --
      *
@@ -581,9 +577,9 @@
      *
      * o Tag::USER_SECURE_ID must be enforced by this method if and only if the key also has
      *   Tag::AUTH_TIMEOUT (if it does not have Tag::AUTH_TIMEOUT, the Tag::USER_SECURE_ID
-     *   requirement must be enforced by update() and finish()).  If the key has both, then this
-     *   method must receive a non-empty HardwareAuthToken in the authToken argument.  For the auth
-     *   token to be valid, all of the following have to be true:
+     *   requirement must be enforced by updateAad(), update() and finish()).  If the key has both,
+     *   then this method must receive a non-empty HardwareAuthToken in the authToken argument.  For
+     *   the auth token to be valid, all of the following have to be true:
      *
      *   o The HMAC field must validate correctly.
      *
@@ -610,32 +606,30 @@
      *
      * -- RSA Keys --
      *
-     * All RSA key operations must specify exactly one padding mode in inParams.  If unspecified or
+     * All RSA key operations must specify exactly one padding mode in params.  If unspecified or
      * specified more than once, the begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
      *
-     * RSA signing and verification operations need a digest, as do RSA encryption and decryption
-     * operations with OAEP padding mode.  For those cases, the caller must specify exactly one
-     * digest in inParams.  If unspecified or specified more than once, begin() must return
+     * RSA signing operations need a digest, as do RSA encryption and decryption operations with
+     * OAEP padding mode.  For those cases, the caller must specify exactly one digest in params.
+     * If unspecified or specified more than once, begin() must return
      * ErrorCode::UNSUPPORTED_DIGEST.
      *
      * Private key operations (KeyPurpose::DECRYPT and KeyPurpose::SIGN) need authorization of
      * digest and padding, which means that the key authorizations need to contain the specified
      * values.  If not, begin() must return ErrorCode::INCOMPATIBLE_DIGEST or
-     * ErrorCode::INCOMPATIBLE_PADDING, as appropriate.  Public key operations (KeyPurpose::ENCRYPT
-     * and KeyPurpose::VERIFY) are permitted with unauthorized digest or padding modes.
+     * ErrorCode::INCOMPATIBLE_PADDING_MODE, as appropriate.
      *
      * With the exception of PaddingMode::NONE, all RSA padding modes are applicable only to certain
      * purposes.  Specifically, PaddingMode::RSA_PKCS1_1_5_SIGN and PaddingMode::RSA_PSS only
-     * support signing and verification, while PaddingMode::RSA_PKCS1_1_5_ENCRYPT and
-     * PaddingMode::RSA_OAEP only support encryption and decryption.  begin() must return
-     * ErrorCode::UNSUPPORTED_PADDING_MODE if the specified mode does not support the specified
-     * purpose.
+     * support signing, while PaddingMode::RSA_PKCS1_1_5_ENCRYPT and PaddingMode::RSA_OAEP only
+     * support encryption and decryption.  begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE
+     * if the specified mode does not support the specified purpose.
      *
      * There are some important interactions between padding modes and digests:
      *
-     * o PaddingMode::NONE indicates that a "raw" RSA operation is performed.  If signing or
-     *   verifying, Digest::NONE is specified for the digest.  No digest is necessary for unpadded
-     *   encryption or decryption.
+     * o PaddingMode::NONE indicates that a "raw" RSA operation is performed.  If signing,
+     *   Digest::NONE is specified for the digest.  No digest is necessary for unpadded encryption
+     *   or decryption.
      *
      * o PaddingMode::RSA_PKCS1_1_5_SIGN padding requires a digest.  The digest may be Digest::NONE,
      *   in which case the KeyMint implementation cannot build a proper PKCS#1 v1.5 signature
@@ -647,37 +641,37 @@
      *
      * o PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT padding does not require a digest.
      *
-     * o PaddingMode::RSA_PSS padding requires a digest, which may not be Digest::NONE.  If
-     *   Digest::NONE is specified, the begin() must return ErrorCode::INCOMPATIBLE_DIGEST.  In
-     *   addition, the size of the RSA key must be at least 2 + D bytes larger than the output size
-     *   of the digest, where D is the size of the digest, in bytes.  Otherwise begin() must
-     *   return ErrorCode::INCOMPATIBLE_DIGEST.  The salt size must be D.
+     * o PaddingMode::RSA_PSS padding requires a digest, which must match one of the padding values
+     *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
+     *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  In addition, the size of the RSA
+     *   key must be at least 2 + D bytes larger than the output size of the digest, where D is the
+     *   size of the digest, in bytes.  Otherwise begin() must return
+     *   ErrorCode::INCOMPATIBLE_DIGEST.  The salt size must be D.
      *
-     * o PaddingMode::RSA_OAEP padding requires a digest, which may not be Digest::NONE.  If
-     *   Digest::NONE is specified, begin() must return ErrorCode::INCOMPATIBLE_DIGEST.  The OAEP
-     *   mask generation function must be MGF1 and the MGF1 digest must be SHA1, regardless of the
-     *   OAEP digest specified.
+     * o PaddingMode::RSA_OAEP padding requires a digest, which must match one of the padding values
+     *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
+     *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  RSA_OAEP padding also requires an
+     *   MGF1 digest, specified with Tag::RSA_OAEP_MGF_DIGEST, which must match one of the MGF1
+     *   padding values in the key authorizations and which may not be Digest::NONE.  begin() must
+     *   return ErrorCode::INCOMPATIBLE_MGF_DIGEST if this is not the case. The OAEP mask generation
+     *   function must be MGF1.
      *
      * -- EC Keys --
      *
-     * EC key operations must specify exactly one padding mode in inParams.  If unspecified or
-     * specified more than once, begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
-     *
      * Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
      * means that the key authorizations must contain the specified values.  If not, begin() must
-     * return ErrorCode::INCOMPATIBLE_DIGEST.  Public key operations (KeyPurpose::VERIFY) are
-     * permitted with unauthorized digest or padding.
+     * return ErrorCode::INCOMPATIBLE_DIGEST.
      *
      * -- AES Keys --
      *
      * AES key operations must specify exactly one block mode (Tag::BLOCK_MODE) and one padding mode
-     * (Tag::PADDING) in inParams.  If either value is unspecified or specified more than once,
+     * (Tag::PADDING) in params.  If either value is unspecified or specified more than once,
      * begin() must return ErrorCode::UNSUPPORTED_BLOCK_MODE or
      * ErrorCode::UNSUPPORTED_PADDING_MODE.  The specified modes must be authorized by the key,
      * otherwise begin() must return ErrorCode::INCOMPATIBLE_BLOCK_MODE or
      * ErrorCode::INCOMPATIBLE_PADDING_MODE.
      *
-     * If the block mode is BlockMode::GCM, inParams must specify Tag::MAC_LENGTH, and the specified
+     * If the block mode is BlockMode::GCM, params must specify Tag::MAC_LENGTH, and the specified
      * value must be a multiple of 8 that is not greater than 128 or less than the value of
      * Tag::MIN_MAC_LENGTH in the key authorizations.  For MAC lengths greater than 128 or
      * non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH.  For values less
@@ -690,48 +684,66 @@
      *
      * If the block mode is BlockMode::CBC, BlockMode::CTR, or BlockMode::GCM, an initialization
      * vector or nonce is required.  In most cases, callers shouldn't provide an IV or nonce and the
-     * IKeyMintDevice implementation must generate a random IV or nonce and return it via
-     * Tag::NONCE in outParams.  CBC and CTR IVs are 16 bytes.  GCM nonces are 12 bytes.  If the key
+     * IKeyMintDevice implementation must generate a random IV or nonce and return it via Tag::NONCE
+     * in outParams.  CBC and CTR IVs are 16 bytes.  GCM nonces are 12 bytes.  If the key
      * authorizations contain Tag::CALLER_NONCE, then the caller may provide an IV/nonce with
-     * Tag::NONCE in inParams.  If a nonce is provided when Tag::CALLER_NONCE is not authorized,
+     * Tag::NONCE in params, which must be of the correct size (if not, return
+     * ErrorCode::INVALID_NONCE).  If a nonce is provided when Tag::CALLER_NONCE is not authorized,
      * begin() must return ErrorCode::CALLER_NONCE_PROHIBITED.  If a nonce is not provided when
-     * Tag::CALLER_NONCE is authorized, IKeyMintDevice msut generate a random IV/nonce.
+     * Tag::CALLER_NONCE is authorized, IKeyMintDevice must generate a random IV/nonce.
+     *
+     * -- 3DES Keys --
+     *
+     * 3DES key operations must specify exactly one block mode (Tag::BLOCK_MODE) and one padding
+     * mode (Tag::PADDING) in params.  If either value is unspecified or specified more than once,
+     * begin() must return ErrorCode::UNSUPPORTED_BLOCK_MODE or
+     * ErrorCode::UNSUPPORTED_PADDING_MODE.  The specified modes must be authorized by the key,
+     * otherwise begin() must return ErrorCode::INCOMPATIBLE_BLOCK_MODE or
+     * ErrorCode::INCOMPATIBLE_PADDING_MODE.
+     *
+     * If the block mode is BlockMode::CBC, an initialization vector or nonce is required.  In most
+     * cases, callers shouldn't provide an IV or nonce and the IKeyMintDevice implementation must
+     * generate a random IV or nonce and return it via Tag::NONCE in outParams.  CBC IVs are 8
+     * bytes.  If the key authorizations contain Tag::CALLER_NONCE, then the caller may provide an
+     * IV/nonce with Tag::NONCE in params, which must be of the correct size (if not, return
+     * ErrorCode::INVALID_NONCE).  If a nonce is provided when Tag::CALLER_NONCE is not authorized,
+     * begin() must return ErrorCode::CALLER_NONCE_PROHIBITED.  If a nonce is not provided when
+     * Tag::CALLER_NONCE is authorized, IKeyMintDevice must generate a random IV/nonce.
+     *
      *
      * -- HMAC keys --
      *
-     * HMAC key operations must specify Tag::MAC_LENGTH in inParams.  The specified value must be a
+     * HMAC key operations must specify Tag::MAC_LENGTH in params.  The specified value must be a
      * multiple of 8 that is not greater than the digest length or less than the value of
      * Tag::MIN_MAC_LENGTH in the key authorizations.  For MAC lengths greater than the digest
      * length or non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH.  For
      * 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, 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 purpose The purpose of the operation, one of KeyPurpose::ENCRYPT, 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
+     * @param keyBlob 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
      *        satisfied, or begin() must return an appropriate error code (see above).
      *
-     * @param inParams Additional parameters for the operation.  If Tag::APPLICATION_ID or
+     * @param params Additional parameters for the operation.  If Tag::APPLICATION_ID or
      *        Tag::APPLICATION_DATA were provided during generation, they must be provided here, or
      *        the operation must fail with ErrorCode::INVALID_KEY_BLOB.  For operations that require
-     *        a nonce or IV, on keys that were generated with Tag::CALLER_NONCE, inParams may
+     *        a nonce or IV, on keys that were generated with Tag::CALLER_NONCE, params may
      *        contain a tag Tag::NONCE.  If Tag::NONCE is provided for a key without
      *        Tag:CALLER_NONCE, ErrorCode::CALLER_NONCE_PROHIBITED must be returned.
      *
-     * @param inAuthToken Authentication token.  Callers that provide no token must set all numeric
-     *        fields to zero and the MAC must be an empty vector.  TODO: make this field nullable.
-     *        b/173483024.
+     * @param authToken Authentication token.
      *
      * @return BeginResult as output, which contains the challenge, KeyParameters which haves
      *         additional data from the operation initialization, notably to return the IV or nonce
      *         from operations that generate an IV or nonce, and IKeyMintOperation object pointer
-     *         which is used to perform update(), finish() or abort() operations.
+     *         which is used to perform updateAad(), update(), finish() or abort() operations.
      */
     BeginResult begin(in KeyPurpose purpose, in byte[] keyBlob, in KeyParameter[] params,
-            in HardwareAuthToken authToken);
+            in @nullable HardwareAuthToken authToken);
 
     /**
      * Called by client to notify the IKeyMintDevice that the device is now locked, and keys with
@@ -745,7 +757,7 @@
      * Note that the IKeyMintDevice UNLOCKED_DEVICE_REQUIRED semantics are slightly different from
      * the UNLOCKED_DEVICE_REQUIRED semantics enforced by keystore.  Keystore handles device locking
      * on a per-user basis.  Because auth tokens do not contain an Android user ID, it's not
-     * possible to replicate the keystore enformcement logic in IKeyMintDevice.  So from the
+     * possible to replicate the keystore enforcement logic in IKeyMintDevice.  So from the
      * IKeyMintDevice perspective, any user unlock unlocks all UNLOCKED_DEVICE_REQUIRED keys.
      * Keystore will continue enforcing the per-user device locking.
      *
@@ -771,7 +783,7 @@
      */
     void earlyBootEnded();
 
-    /*
+    /**
      * Called by the client to get a wrapped per-boot ephemeral key from a wrapped storage key.
      * Clients will then use the returned per-boot ephemeral key in place of the wrapped storage
      * key. Whenever the hardware is presented with a per-boot ephemeral key for an operation, it
@@ -793,16 +805,24 @@
     byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
 
     /**
-     * Called by the client to perform a KeyMint operation.
+     * Returns parameters associated with the provided key. This should match the
+     * KeyCharacteristics present in the KeyCreationResult returned by generateKey(),
+     * importKey(), or importWrappedKey().
      *
-     *  This method is added primarily as a placeholder.  Details will be fleshed before the KeyMint
-     *  V1 interface is frozen.  Until then, implementations must return ErrorCode::UNIMPLEMENTED.
+     * @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey.
      *
-     * @param request is an encrypted buffer containing a description of the operation the client
-     *        wishes to perform.  Structure, content and encryption are TBD.
+     * @param appId An opaque byte string identifying the client.  This value must match the
+     *        Tag::APPLICATION_ID data provided during key generation/import.  Without the correct
+     *        value, it must be computationally infeasible for the secure hardware to obtain the
+     *        key material.
      *
-     * @return an encrypted buffer containing the result of the operation.  Structure, content and
-     *         encryption are TBD.
+     * @param appData An opaque byte string provided by the application.  This value must match the
+     *        Tag::APPLICATION_DATA data provided during key generation/import.  Without the
+     *        correct value, it must be computationally infeasible for the secure hardware to
+     *        obtain the key material.
+     *
+     * @return Characteristics of the generated key. See KeyCreationResult for details.
      */
-    byte[] performOperation(in byte[] request);
+    KeyCharacteristics[] getKeyCharacteristics(
+            in byte[] keyBlob, in byte[] appId, in byte[] appData);
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index d2a993f..aa7b492 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -31,12 +31,12 @@
      * update() is called.  If updateAad() is called after update(), it must return
      * ErrorCode::INVALID_TAG.
      *
-     * If operation is in an invalid state (was aborted or had an error) update() must return
+     * If the operation is in an invalid state (was aborted or had an error) update() must return
      * ErrorCode::INVALID_OPERATION_HANDLE.
      *
      * If this method returns an error code other than ErrorCode::OK, the operation is aborted and
-     * the operation handle must be invalidated.  Any future use of the handle, with this method,
-     * finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
+     * the operation handle must be invalidated.  Any future use of this object must return
+     * ErrorCode::INVALID_OPERATION_HANDLE.
      *
      * == Authorization Enforcement ==
      *
@@ -58,9 +58,10 @@
      *
      *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
      *
-     *   o The challenge field in the auth token must contain the operationHandle
+     *   o The challenge field in the auth token must contain the value returned from
+     *     IKeyMintDevice::begin(), given by the challenge field of the BeginResult structure.
      *
-     *   If any of these conditions are not met, update() must return
+     *   If any of these conditions are not met, updateAad() must return
      *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
      *
      * The caller must provide the auth token on every call to updateAad(), update() and finish().
@@ -74,7 +75,7 @@
      *
      * @param input Additional Authentication Data to be processed.
      *
-     * @param authToken Authentication token. Can be nullable if not provided.
+     * @param authToken Authentication token, if provided.
      *
      * @param timeStampToken timestamp token, certifies the freshness of an auth token in case
      *        the security domain of this KeyMint instance has a different clock than the
@@ -93,18 +94,9 @@
      * If operation is in an invalid state (was aborted or had an error) update() must return
      * ErrorCode::INVALID_OPERATION_HANDLE.
      *
-     * To provide more flexibility for buffer handling, implementations of this method have the
-     * option of consuming less data than was provided.  The caller is responsible for looping to
-     * feed the rest of the data in subsequent calls.  The amount of input consumed must be returned
-     * in the inputConsumed parameter.  Implementations must always consume at least one byte,
-     * unless the operation cannot accept any more; if more than zero bytes are provided and zero
-     * bytes are consumed, callers must consider this an error and abort the operation.
-     * TODO(seleneh) update the code to always consume alll the input data. b/168665179.
-     *
-     * Implementations may also choose how much data to return, as a result of the update.  This is
-     * only relevant for encryption and decryption operations, because signing and verification
-     * return no data until finish.  It is recommended to return data as early as possible, rather
-     * than buffer it.
+     * Implementations may choose how much data to return as a result of the update.  This is
+     * only relevant for encryption and decryption operations, because signing returns no data
+     * until finish.  It is recommended to return data as early as possible, rather than buffer it.
      *
      * If this method returns an error code other than ErrorCode::OK, the operation is aborted and
      * the operation handle must be invalidated.  Any future use of the handle, with this method,
@@ -112,8 +104,8 @@
      *
      * == Authorization Enforcement ==
      *
-     * Key authorization enforcement is performed primarily in begin().  The one exception is the
-     * case where the key has:
+     * Key authorization enforcement is performed primarily in IKeyMintDevice::begin().  The one
+     * exception is the case where the key has:
      *
      * o One or more Tag::USER_SECURE_IDs, and
      *
@@ -130,7 +122,8 @@
      *
      *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
      *
-     *   o The challenge field in the auth token must contain the operationHandle
+     *   o The challenge field in the auth token must contain the challenge value contained in the
+     *     BeginResult returned from IKeyMintDevice::begin().
      *
      *   If any of these conditions are not met, update() must return
      *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
@@ -139,22 +132,20 @@
      *
      * -- RSA keys --
      *
-     * For signing and verification operations with Digest::NONE, this method must accept the entire
-     * block to be signed or verified in a single update.  It may not consume only a portion of the
-     * block in these cases.  However, the caller may choose to provide the data in multiple
-     * updates, and update() must accept the data this way as well.  If the caller provides more
-     * data to sign than can be used (length of data exceeds RSA key size), update() must return
-     * ErrorCode::INVALID_INPUT_LENGTH.
+     * For signing operations with Digest::NONE, this method must accept the entire block to be
+     * signed in a single update.  It may not consume only a portion of the block in these cases.
+     * However, the caller may choose to provide the data in multiple updates, and update() must
+     * accept the data this way as well.  If the caller provides more data to sign than can be used
+     * (length of data exceeds RSA key size), update() must return ErrorCode::INVALID_INPUT_LENGTH.
      *
      * -- ECDSA keys --
      *
-     * For signing and verification operations with Digest::NONE, this method must accept the entire
-     * block to be signed or verified in a single update.  This method may not consume only a
-     * portion of the block.  However, the caller may choose to provide the data in multiple updates
-     * and update() must accept the data this way as well.  If the caller provides more data to sign
-     * than can be used, the data is silently truncated.  (This differs from the handling of excess
-     * data provided in similar RSA operations.  The reason for this is compatibility with legacy
-     * clients.)
+     * For signing operations with Digest::NONE, this method must accept the entire block to be
+     * signed in a single update.  This method may not consume only a portion of the block.
+     * However, the caller may choose to provide the data in multiple updates and update() must
+     * accept the data this way as well.  If the caller provides more data to sign than can be used,
+     * the data is silently truncated.  (This differs from the handling of excess data provided in
+     * similar RSA operations.  The reason for this is compatibility with legacy clients.)
      *
      * -- AES keys --
      *
@@ -182,7 +173,7 @@
             in @nullable TimeStampToken timeStampToken);
 
     /**
-     * Finalizes a cryptographic operation begun with begin() and invalidates operation.
+     * Finalizes a cryptographic operation begun with begin() and invalidates the operation.
      *
      * This method is the last one called in an operation, so all processed data must be returned.
      *
@@ -190,8 +181,7 @@
      * Any future use of the operation, with finish(), update(), or abort(), must return
      * ErrorCode::INVALID_OPERATION_HANDLE.
      *
-     * Signing operations return the signature as the output.  Verification operations accept the
-     * signature in the signature parameter, and return no output.
+     * Signing operations return the signature as the output.
      *
      * == Authorization enforcement ==
      *
@@ -230,44 +220,35 @@
      * Some additional requirements, depending on the padding mode:
      *
      * o PaddingMode::NONE.  For unpadded signing and encryption operations, if the provided data is
-     *   shorter than the key, the data must be zero-padded on the left before
-     *   signing/encryption.  If the data is the same length as the key, but numerically larger,
-     *   finish() must return ErrorCode::INVALID_ARGUMENT.  For verification and decryption
-     *   operations, the data must be exactly as long as the key.  Otherwise, return
-     *   ErrorCode::INVALID_INPUT_LENGTH.
+     *   shorter than the key, the data must be zero-padded on the left before signing/encryption.
+     *   If the data is the same length as the key, but numerically larger, finish() must return
+     *   ErrorCode::INVALID_ARGUMENT.  For decryption operations, the data must be exactly as long
+     *   as the key.  Otherwise, return ErrorCode::INVALID_INPUT_LENGTH.
      *
      * o PaddingMode::RSA_PSS.  For PSS-padded signature operations, the PSS salt length must match
-     *   the size of the PSS digest selected.  The digest specified with Tag::DIGEST in inputParams
+     *   the size of the PSS digest selected.  The digest specified with Tag::DIGEST in params
      *   on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
      *   generation function and SHA1 must be used as the MGF1 digest algorithm.
      *
-     * o PaddingMode::RSA_OAEP.  The digest specified with Tag::DIGEST in inputParams on begin is
-     *   used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and
-     *   and SHA1 must be used as the MGF1 digest algorithm.
-     *
      * -- ECDSA keys --
      *
-     * If the data provided for unpadded signing or verification is too long, truncate it.
+     * If the data provided for undigested signing is too long, truncate it.
      *
      * -- AES keys --
      *
      * Some additional conditions, depending on block mode:
      *
      * o BlockMode::ECB or BlockMode::CBC.  If padding is PaddingMode::NONE and the data length is
-     *  not a multiple of the AES block size, finish() must return
-     *  ErrorCode::INVALID_INPUT_LENGTH.  If padding is PaddingMode::PKCS7, pad the data per the
-     *  PKCS#7 specification, including adding an additional padding block if the data is a multiple
-     *  of the block length.
+     *   not a multiple of the AES block size, finish() must return
+     *   ErrorCode::INVALID_INPUT_LENGTH.  If padding is PaddingMode::PKCS7, pad the data per the
+     *   PKCS#7 specification, including adding an additional padding block if the data is a
+     *   multiple of the block length.
      *
      * o BlockMode::GCM.  During encryption, after processing all plaintext, compute the tag
      *   (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext.  During decryption,
      *   process the last Tag::MAC_LENGTH bytes as the tag.  If tag verification fails, finish()
      *   must return ErrorCode::VERIFICATION_FAILED.
      *
-     * TODO: update() will need to be refactored into 2 function. b/168665179.
-     *
-     * @param inParams Additional parameters for the operation.
-     *
      * @param input Data to be processed, per the parameters established in the call to begin().
      *        finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
      *
@@ -281,11 +262,9 @@
      *        token.
      *
      * @param confirmationToken is the confirmation token required by keys with
-     * Tag::TRUSTED_CONFIRMATION_REQUIRED.
+     *        Tag::TRUSTED_CONFIRMATION_REQUIRED.
      *
      * @return The output data, if any.
-     *
-     * @return outParams Any output parameters generated by finish().
      */
     byte[] finish(in @nullable byte[] input, in @nullable byte[] signature,
             in @nullable HardwareAuthToken authToken,
@@ -293,13 +272,10 @@
             in @nullable byte[] confirmationToken);
 
     /**
-     * Aborts a cryptographic operation begun with begin(), freeing all internal resources. If an
-     * operation was finalized, calling update, finish, or abort yields
-     * ErrorCode::INVALID_OPERATION_HANDLE. An operation is finalized if finish or abort was
-     * called on it, or if update returned an ErrorCode.
-     *
-     * @param operationHandle The operation handle returned by begin().  This handle must be
-     *        invalid when abort() returns.
+     * Aborts a cryptographic operation begun with IKeyMintDevice::begin(), freeing all internal
+     * resources.  If an operation was finalized, calling updateAad, update, finish, or abort yields
+     * ErrorCode::INVALID_OPERATION_HANDLE. An operation is finalized if finish or abort was called
+     * on it, or if updateAad or update returned an ErrorCode.
      *
      * @return error See the ErrorCode enum in ErrorCode.aidl.
      */
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index b6285d9..04d91d0 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -78,7 +78,7 @@
  * While a proper BCC, as described above, reflects the complete boot sequence from boot ROM to the
  * secure area image of the IRemotelyProvisionedComponent, it's also possible to use a "degenerate"
  * BCC which consists only of a single, self-signed certificate containing the public key of a
- * hardware-bound key pair. This is an appopriate solution for devices which haven't implemented
+ * hardware-bound key pair. This is an appropriate solution for devices which haven't implemented
  * everything necessary to produce a proper BCC, but can derive a unique key pair in the secure
  * area.  In this degenerate case, DK_pub is the same as KM_pub.
  *
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index 972a6a5..f93dbba 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -58,7 +58,7 @@
      * There are a few variations in what is contained in `certificateChain`, depending on whether
      * the caller requested attestation, whether they provided an attestation key (via the
      * `attestationKey` parameter of `generateKey()`, `importKey()` or `importWrappedKey()`), and in
-     * the non-attestaion case, whether the key can self-sign.
+     * the non-attestation case, whether the key can self-sign.
      *
      * 1.  Asymmetric key attestation with factory key.  If Tag::ATTESTATION_CHALLENGE is provided
      *     and the `attestationKey` parameter on the generate/import call is null, the returned
@@ -70,7 +70,7 @@
      *     attestation keys.
      *
      * 2.  Asymmetric key attestation with caller-provided key.  If Tag::ATTESTATION_CHALLENGE is
-     *     provided and the `attestationKey` parameter on the generat/import call is non-null and
+     *     provided and the `attestationKey` parameter on the generate/import call is non-null and
      *     contains the key blob of a key with KeyPurpose::ATTEST_KEY, the returned certificate
      *     chain must contain only an attestation certificate signed with the specified key.  The
      *     caller must know the certificate chain for the provided key.  Tag::
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl
index f896125..5840c6b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl
@@ -20,7 +20,7 @@
  * The origin of a key (or pair), i.e. where it was generated.  Note that ORIGIN can be found in
  * either the hardware-enforced or software-enforced list for a key, indicating whether the key is
  * hardware or software-based.  Specifically, a key with GENERATED in the hardware-enforced list
- * must be guaranteed never to have existed outide the secure hardware.
+ * must be guaranteed never to have existed outside the secure hardware.
  * @hide
  */
 @VintfStability
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
index c874fc3..e141e55 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
@@ -23,10 +23,10 @@
 @VintfStability
 @Backing(type="int")
 enum KeyPurpose {
-    /* Usable with RSA, EC and AES keys. */
+    /* Usable with RSA, 3DES and AES keys. */
     ENCRYPT = 0,
 
-    /* Usable with RSA, EC and AES keys. */
+    /* Usable with RSA, 3DES and AES keys. */
     DECRYPT = 1,
 
     /* Usable with RSA, EC and HMAC keys. */
@@ -36,6 +36,7 @@
     VERIFY = 3,
 
     /* 4 is reserved */
+
     /* Usable with wrapping keys. */
     WRAP_KEY = 5,
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 2a1ec5c..1e101ab 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -19,7 +19,7 @@
 import android.hardware.security.keymint.TagType;
 
 // TODO(seleneh) : note aidl currently does not support double nested enum definitions such as
-// ROOT_OF_TRUST = TagType:BYTES | 704.  So we are forced to write definations as
+// ROOT_OF_TRUST = TagType:BYTES | 704.  So we are forced to write definitions as
 // ROOT_OF_TRUST = (9 << 28) for now.  Will need to flip this back later when aidl support is added.
 
 /**
@@ -59,7 +59,7 @@
     ALGORITHM = (1 << 28) /* TagType:ENUM */ | 2,
 
     /**
-     * Tag::KEY_SIZE pecifies the size, in bits, of the key, measuring in the normal way for the
+     * Tag::KEY_SIZE specifies the size, in bits, of the key, measuring in the normal way for the
      * key's algorithm.  For example, for RSA keys, Tag::KEY_SIZE specifies the size of the public
      * modulus.  For AES keys it specifies the length of the secret key material.  For 3DES keys it
      * specifies the length of the key material, not counting parity bits (though parity bits must
@@ -75,9 +75,9 @@
      * is only relevant to AES and 3DES keys.  Possible values are defined by the BlockMode enum.
      *
      * This tag is repeatable for key generation/import.  For AES and 3DES operations the caller
-     * must specify a Tag::BLOCK_MODE in the additionalParams argument of begin().  If the mode is
-     * missing or the specified mode is not in the modes specified for the key during
-     * generation/import, the operation must fail with ErrorCode::INCOMPATIBLE_BLOCK_MODE.
+     * must specify a Tag::BLOCK_MODE in the params argument of begin().  If the mode is missing or
+     * the specified mode is not in the modes specified for the key during generation/import, the
+     * operation must fail with ErrorCode::INCOMPATIBLE_BLOCK_MODE.
      *
      * Must be hardware-enforced.
      */
@@ -89,9 +89,9 @@
      * values are defined by the Digest enum.
      *
      * This tag is repeatable for key generation/import.  For signing and verification operations,
-     * the caller must specify a digest in the additionalParams argument of begin().  If the digest
-     * is missing or the specified digest is not in the digests associated with the key, the
-     * operation must fail with ErrorCode::INCOMPATIBLE_DIGEST.
+     * the caller must specify a digest in the params argument of begin().  If the digest is missing
+     * or the specified digest is not in the digests associated with the key, the operation must
+     * fail with ErrorCode::INCOMPATIBLE_DIGEST.
      *
      * Must be hardware-enforced.
      */
@@ -145,7 +145,7 @@
      * This value is the minimum MAC length, in bits.  It must be a multiple of 8 bits.  For HMAC
      * keys, the value must be least 64 and no more than 512.  For GCM keys, the value must be at
      * least 96 and no more than 128.  If the provided value violates these requirements,
-     * generateKey() or importKey() must return ErrorCode::UNSUPPORTED_KEY_SIZE.
+     * generateKey() or importKey() must return ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH.
      *
      * Must be hardware-enforced.
      */
@@ -154,9 +154,8 @@
     // Tag 9 reserved
 
     /**
-     * Tag::EC_CURVE specifies the elliptic curve.  EC key generation requests may have
-     * Tag:EC_CURVE, Tag::KEY_SIZE, or both.  If both are provided and the size and curve do not
-     * match, IKeyMintDevice must return ErrorCode::INVALID_ARGUMENT.
+     * Tag::EC_CURVE specifies the elliptic curve.  Possible values are defined in the EcCurve
+     * enumeration.
      *
      * Must be hardware-enforced.
      */
@@ -188,37 +187,19 @@
     INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202,
 
     /**
-     * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with
-     * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP
-     * and this tag is absent then SHA1 digest is selected by default for MGF1.
+     * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with RSA
+     * encryption/decryption with OAEP padding.  Possible values are defined by the Digest enum.
      *
-     * This tag is repeatable for key generation/import.  If this tag is present in the key
-     * characteristics with one or more values from @4.0::Digest, then for RSA cipher
-     * operations with OAEP Padding, the caller must specify a digest in the additionalParams
-     * argument of begin operation. If this tag is missing or the specified digest is not in
-     * the digests associated with the key then begin operation must fail with
-     * ErrorCode::INCOMPATIBLE_MGF_DIGEST.
+     * This tag is repeatable for key generation/import.  RSA cipher operations with OAEP padding
+     * must specify an MGF1 digest in the params argument of begin(). If this tag is missing or the
+     * specified digest is not in the MGF1 digests associated with the key then begin operation must
+     * fail with ErrorCode::INCOMPATIBLE_MGF_DIGEST.
      *
      * Must be hardware-enforced.
      */
     RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203,
 
-    /**
-     * TODO(seleneh) this tag needs to be deleted from all codes.
-     *
-     * Tag::BLOB_USAGE_REQUIREMENTS specifies the necessary system environment conditions for the
-     * generated key to be used.  Possible values are defined by the KeyBlobUsageRequirements enum.
-     *
-     * This tag is specified by the caller during key generation or import to require that the key
-     * is usable in the specified condition.  If the caller specifies Tag::BLOB_USAGE_REQUIREMENTS
-     * with value KeyBlobUsageRequirements::STANDALONE the IKeyMintDevice must return a key blob
-     * that can be used without file system support.  This is critical for devices with encrypted
-     * disks, where the file system may not be available until after a KeyMint key is used to
-     * decrypt the disk.
-     *
-     * Must be hardware-enforced.
-     */
-    BLOB_USAGE_REQUIREMENTS = (1 << 28) /* TagType:ENUM */ | 301,
+    // Tag 301 reserved
 
     /**
      * Tag::BOOTLOADER_ONLY specifies only the bootloader can use the key.
@@ -241,7 +222,7 @@
      * ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE.  IKeyMintDevice implementations are not
      * required to support rollback resistance.
      *
-     * Must be hardwared-enforced.
+     * Must be hardware-enforced.
      */
     ROLLBACK_RESISTANCE = (7 << 28) /* TagType:BOOL */ | 303,
 
@@ -251,7 +232,7 @@
     /**
      * Keys tagged with EARLY_BOOT_ONLY may only be used during early boot, until
      * IKeyMintDevice::earlyBootEnded() is called.  Early boot keys may be created after
-     * early boot.  Early boot keys may not be imprted at all, if Tag::EARLY_BOOT_ONLY is
+     * early boot.  Early boot keys may not be imported at all, if Tag::EARLY_BOOT_ONLY is
      * provided to IKeyMintDevice::importKey, the import must fail with
      * ErrorCode::INVALID_ARGUMENT.
      */
@@ -307,7 +288,7 @@
      * with ErrorCode::KEY_RATE_LIMIT_EXCEEDED.  This implies that the IKeyMintDevice must keep a
      * table of use counters for keys with this tag.  Because memory is often limited, this table
      * may have a fixed maximum size and KeyMint may fail operations that attempt to use keys with
-     * this tag when the table is full.  The table must acommodate at least 8 in-use keys and
+     * this tag when the table is full.  The table must accommodate at least 8 in-use keys and
      * aggressively reuse table slots when key minimum-usage intervals expire.  If an operation
      * fails because the table is full, KeyMint returns ErrorCode::TOO_MANY_OPERATIONS.
      *
@@ -327,7 +308,7 @@
      * device is restarted.  This implies that the IKeyMintDevice must keep a table of use
      * counters for keys with this tag.  Because KeyMint memory is often limited, this table can
      * have a fixed maximum size and KeyMint can fail operations that attempt to use keys with
-     * this tag when the table is full.  The table needs to acommodate at least 8 keys.  If an
+     * this tag when the table is full.  The table needs to accommodate at least 8 keys.  If an
      * operation fails because the table is full, IKeyMintDevice must
      * ErrorCode::TOO_MANY_OPERATIONS.
      *
@@ -386,14 +367,14 @@
      * key, and may only be used if the difference between the current time when begin() is called
      * and the timestamp in the HardwareAuthToken is less than the value in Tag::AUTH_TIMEOUT * 1000
      * (the multiplier is because Tag::AUTH_TIMEOUT is in seconds, but the HardwareAuthToken
-     * timestamp is in milliseconds).  Otherwise the IKeyMintDevice must returrn
+     * timestamp is in milliseconds).  Otherwise the IKeyMintDevice must return
      * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
      *
      * If Tag::AUTH_TIMEOUT is not present, then the key is an "auth-per-operation" key.  In this
      * case, begin() must not require a HardwareAuthToken with appropriate contents.  Instead,
      * update() and finish() must receive a HardwareAuthToken with Tag::USER_SECURE_ID value in
      * userId or authenticatorId fields, and the current operation's operation handle in the
-     * challenge field.  Otherwise the IKeyMintDevice must returrn
+     * challenge field.  Otherwise the IKeyMintDevice must return
      * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
      *
      * This tag is repeatable.  If repeated, and any one of the values matches the HardwareAuthToken
@@ -434,7 +415,7 @@
     /**
      * Tag::AUTH_TIMEOUT specifies the time in seconds for which the key is authorized for use,
      * after user authentication.  If
-     * Tag::USER_SECURE_ID is present and this tag is not, then the key requies authentication for
+     * Tag::USER_SECURE_ID is present and this tag is not, then the key requires authentication for
      * every usage (see begin() for the details of the authentication-per-operation flow).
      *
      * The value is a 32-bit integer specifying the time in seconds after a successful
@@ -504,7 +485,7 @@
      * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
      *  specifies that this key must not be usable unless the user provides confirmation of the data
      *  to be signed.  Confirmation is proven to keyMint via an approval token.  See
-     *  CONFIRMATION_TOKEN, as well as the ConfirmatinUI HAL.
+     *  CONFIRMATION_TOKEN, as well as the ConfirmationUI HAL.
      *
      * If an attempt to use a key with this tag does not have a cryptographically valid
      * CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not
@@ -524,10 +505,10 @@
 
     /**
      * Tag::APPLICATION_ID.  When provided to generateKey or importKey, this tag specifies data
-     * that is necessary during all uses of the key.  In particular, calls to exportKey() and
-     * getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
-     * begin must provide this tag and the same associated data as part of the inParams set.  If
-     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * that is necessary during all uses of the key.  In particular, calls to exportKey() must
+     * provide the same value to the clientId parameter, and calls to begin() must provide this
+     * tag and the same associated data as part of the inParams set.  If the correct data is not
+     * provided, the method must return ErrorCode::INVALID_KEY_BLOB.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
@@ -550,7 +531,7 @@
      * provide this tag and the same associated data as part of the inParams set.  If the correct
      * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
      *
-     * The content of this tag msut be bound to the key cryptographically, meaning it must not be
+     * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
      * access to the tag content to decrypt the key without brute-forcing the tag content, which
      * applications can prevent by specifying sufficiently high-entropy content.
@@ -561,10 +542,9 @@
 
     /**
      * Tag::CREATION_DATETIME specifies the date and time the key was created, in milliseconds since
-     * January 1, 1970.  This tag is optional and informational only.
+     * January 1, 1970.  This tag is optional and informational only, and not enforced by anything.
      *
-     * Tag::CREATED is informational only, and not enforced by anything.  Must be in the
-     * software-enforced list, if provided.
+     * Must be in the software-enforced list, if provided.
      */
     CREATION_DATETIME = (6 << 28) /* TagType:DATE */ | 701,
 
@@ -593,8 +573,8 @@
      * Tag::OS_VERSION specifies the system OS version with which the key may be used.  This tag is
      * never sent to the IKeyMintDevice, but is added to the hardware-enforced authorization list
      * by the TA.  Any attempt to use a key with a Tag::OS_VERSION value different from the
-     * currently-running OS version must cause begin(), getKeyCharacteristics() or exportKey() to
-     * return ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for details.
+     * currently-running OS version must cause begin() or exportKey() to return
+     * ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for details.
      *
      * The value of the tag is an integer of the form MMmmss, where MM is the major version number,
      * mm is the minor version number, and ss is the sub-minor version number.  For example, for a
@@ -616,9 +596,8 @@
      * Tag::OS_PATCHLEVEL specifies the system security patch level with which the key may be used.
      * This tag is never sent to the keyMint TA, but is added to the hardware-enforced
      * authorization list by the TA.  Any attempt to use a key with a Tag::OS_PATCHLEVEL value
-     * different from the currently-running system patchlevel must cause begin(),
-     * getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE.  See
-     * upgradeKey() for details.
+     * different from the currently-running system patchlevel must cause begin() or
+     * exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for details.
      *
      * The value of the tag is an integer of the form YYYYMM, where YYYY is the four-digit year of
      * the last update and MM is the two-digit month of the last update.  For example, for a key
@@ -650,10 +629,11 @@
      *      Tag::CREATION_DATETIME by 2592000000, dropping any remainder.  T changes every 30 days
      *      (2592000000 = 30 * 24 * 60 * 60 * 1000).
      *
-     *    C is the value of Tag::ATTESTATION_APPLICATION_ID that is provided to attestKey().
+     *    C is the value of Tag::ATTESTATION_APPLICATION_ID that is provided to attested key
+     *      generation/import operations.
      *
-     *    R is 1 if Tag::RESET_SINCE_ID_ROTATION was provided to attestKey or 0 if the tag was not
-     *      provided.
+     *    R is 1 if Tag::RESET_SINCE_ID_ROTATION was provided to attested key generation/import or 0
+     *      if the tag was not provided.
      *
      *    HBK is a unique hardware-bound secret known to the secure environment and never revealed
      *    by it.  The secret must contain at least 128 bits of entropy and be unique to the
@@ -668,9 +648,9 @@
     UNIQUE_ID = (9 << 28) /* TagType:BYTES */ | 707,
 
     /**
-     * Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attestKey() method,
-     * which must place the value in the KeyDescription SEQUENCE of the attestation extension.  See
-     * attestKey().
+     * Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attested key
+     * generation/import methods, which must place the value in the KeyDescription SEQUENCE of the
+     * attestation extension.
      *
      * Must never appear in KeyCharacteristics.
      */
@@ -678,7 +658,7 @@
 
     /**
      * Tag::ATTESTATION_APPLICATION_ID identifies the set of applications which may use a key, used
-     * only with attestKey().
+     * only with attested key generation/import operations.
      *
      * The content of Tag::ATTESTATION_APPLICATION_ID is a DER-encoded ASN.1 structure, with the
      * following schema:
@@ -704,8 +684,8 @@
 
     /**
      * Tag::ATTESTATION_ID_BRAND provides the device's brand name, as returned by Build.BRAND in
-     * Android, to attestKey().  This field must be set only when requesting attestation of the
-     * device's identifiers.
+     * Android, to attested key generation/import operations.  This field must be set only when
+     * requesting attestation of the device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -717,8 +697,8 @@
 
     /**
      * Tag::ATTESTATION_ID_DEVICE provides the device's device name, as returned by Build.DEVICE in
-     * Android, to attestKey().  This field must be set only when requesting attestation of the
-     * device's identifiers.
+     * Android, to attested key generation/import operations.  This field must be set only when
+     * requesting attestation of the device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -730,8 +710,8 @@
 
     /**
      * Tag::ATTESTATION_ID_PRODUCT provides the device's product name, as returned by Build.PRODUCT
-     * in Android, to attestKey().  This field must be set only when requesting attestation of the
-     * device's identifiers.
+     * in Android, to attested key generation/import operations.  This field must be set only when
+     * requesting attestation of the device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -754,8 +734,9 @@
     ATTESTATION_ID_SERIAL = (9 << 28) /* TagType:BYTES */ | 713,
 
     /**
-     * Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attestKey().
-     * This field must be set only when requesting attestation of the device's identifiers.
+     * Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attested key
+     * generation/import operations.  This field must be set only when requesting attestation of the
+     * device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -766,8 +747,9 @@
     ATTESTATION_ID_IMEI = (9 << 28) /* TagType:BYTES */ | 714,
 
     /**
-     * Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attestKey().
-     * This field must be set only when requesting attestation of the device's identifiers.
+     * Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attested key
+     * generation/import operations.  This field must be set only when requesting attestation of the
+     * device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -779,8 +761,8 @@
 
     /**
      * Tag::ATTESTATION_ID_MANUFACTURER provides the device's manufacturer name, as returned by
-     * Build.MANUFACTURER in Android, to attstKey().  This field must be set only when requesting
-     * attestation of the device's identifiers.
+     * Build.MANUFACTURER in Android, to attested key generation/import operations.  This field must
+     * be set only when requesting attestation of the device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -792,8 +774,8 @@
 
     /**
      * Tag::ATTESTATION_ID_MODEL provides the device's model name, as returned by Build.MODEL in
-     * Android, to attestKey().  This field must be set only when requesting attestation of the
-     * device's identifiers.
+     * Android, to attested key generation/import operations.  This field must be set only when
+     * requesting attestation of the device's identifiers.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -807,9 +789,8 @@
      * Tag::VENDOR_PATCHLEVEL specifies the vendor image security patch level with which the key may
      * be used.  This tag is never sent to the keyMint TA, but is added to the hardware-enforced
      * authorization list by the TA.  Any attempt to use a key with a Tag::VENDOR_PATCHLEVEL value
-     * different from the currently-running system patchlevel must cause begin(),
-     * getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE.  See
-     * upgradeKey() for details.
+     * different from the currently-running system patchlevel must cause begin() or
+     * exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for details.
      *
      * The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
      * the last update, MM is the two-digit month and DD is the two-digit day of the last
@@ -830,8 +811,8 @@
      * key may be used.  This tag is never sent to the keyMint TA, but is added to the
      * hardware-enforced authorization list by the TA.  Any attempt to use a key with a
      * Tag::BOOT_PATCHLEVEL value different from the currently-running system patchlevel must
-     * cause begin(), getKeyCharacteristics() or exportKey() to return
-     * ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for details.
+     * cause begin() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE.  See upgradeKey() for
+     * details.
      *
      * The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
      * the last update, MM is the two-digit month and DD is the two-digit day of the last
@@ -839,20 +820,20 @@
      * the value would be 20180605.  If the day is not known, 00 may be substituted.
      *
      * During each boot, the bootloader must provide the patch level of the boot image to the secure
-     * envirionment (mechanism is implementation-defined).
+     * environment (mechanism is implementation-defined).
      *
      * Must be hardware-enforced.
      */
     BOOT_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 719,
 
     /**
-     * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attestKey().  It indicates that
-     * attestation using a device-unique key is requested, rather than a batch key.  When a
-     * device-unique key is used, only the attestation certificate is returned; no additional
-     * chained certificates are provided.  It's up to the caller to recognize the device-unique
-     * signing key.  Only SecurityLevel::STRONGBOX IKeyMintDevices may support device-unique
-     * attestations.  SecurityLevel::TRUSTED_ENVIRONMENT IKeyMintDevices must return
-     * ErrorCode::INVALID_ARGUMENT if they receive DEVICE_UNIQUE_ATTESTATION.
+     * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import
+     * operations.  It indicates that attestation using a device-unique key is requested, rather
+     * than a batch key.  When a device-unique key is used, only the attestation certificate is
+     * returned; no additional chained certificates are provided.  It's up to the caller to
+     * recognize the device-unique signing key.  Only SecurityLevel::STRONGBOX IKeyMintDevices may
+     * support device-unique attestations.  SecurityLevel::TRUSTED_ENVIRONMENT IKeyMintDevices must
+     * return ErrorCode::INVALID_ARGUMENT if they receive DEVICE_UNIQUE_ATTESTATION.
      * SecurityLevel::STRONGBOX IKeyMintDevices need not support DEVICE_UNIQUE_ATTESTATION, and
      * return ErrorCode::CANNOT_ATTEST_IDS if they do not support it.
      *
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 4e951d6..afb2193 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -44,7 +44,7 @@
 TEST_P(AttestKeyTest, AllRsaSizes) {
     for (auto size : ValidKeySizes(Algorithm::RSA)) {
         /*
-         * Create attestaton key.
+         * Create attestation key.
          */
         AttestationKey attest_key;
         vector<KeyCharacteristics> attest_key_characteristics;
@@ -482,7 +482,7 @@
 TEST_P(AttestKeyTest, AllEcCurves) {
     for (auto curve : ValidCurves()) {
         /*
-         * Create attestaton key.
+         * Create attestation key.
          */
         AttestationKey attest_key;
         vector<KeyCharacteristics> attest_key_characteristics;
@@ -566,7 +566,7 @@
 }
 
 TEST_P(AttestKeyTest, AttestWithNonAttestKey) {
-    // Create non-attestaton key.
+    // Create non-attestation key.
     AttestationKey non_attest_key;
     vector<KeyCharacteristics> non_attest_key_characteristics;
     vector<Certificate> non_attest_key_cert_chain;
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index ce23f70..f0dfff1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -119,7 +119,6 @@
 // Attestations don't contain everything in key authorization lists, so we need to filter the key
 // lists to produce the lists that we expect to match the attestations.
 auto kTagsToFilter = {
-        Tag::BLOB_USAGE_REQUIREMENTS,  //
         Tag::CREATION_DATETIME,        //
         Tag::EC_CURVE,
         Tag::HARDWARE_TYPE,
@@ -171,6 +170,7 @@
 
     os_version_ = getOsVersion();
     os_patch_level_ = getOsPatchlevel();
+    vendor_patch_level_ = getVendorPatchlevel();
 }
 
 void KeyMintAidlTestBase::SetUp() {
@@ -348,7 +348,7 @@
     SCOPED_TRACE("Begin");
     Status result;
     BeginResult out;
-    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), std::nullopt, &out);
 
     if (result.isOk()) {
         *out_params = out.params;
@@ -366,7 +366,7 @@
     Status result;
     BeginResult out;
 
-    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), std::nullopt, &out);
 
     if (result.isOk()) {
         *out_params = out.params;
@@ -744,6 +744,15 @@
                 return {224, 384, 521};
             case Algorithm::AES:
                 return {192};
+            case Algorithm::TRIPLE_DES:
+                return {56};
+            default:
+                return {};
+        }
+    } else {
+        switch (algorithm) {
+            case Algorithm::TRIPLE_DES:
+                return {56};
             default:
                 return {};
         }
@@ -751,6 +760,68 @@
     return {};
 }
 
+vector<BlockMode> KeyMintAidlTestBase::ValidBlockModes(Algorithm algorithm) {
+    switch (algorithm) {
+        case Algorithm::AES:
+            return {
+                    BlockMode::CBC,
+                    BlockMode::CTR,
+                    BlockMode::ECB,
+                    BlockMode::GCM,
+            };
+        case Algorithm::TRIPLE_DES:
+            return {
+                    BlockMode::CBC,
+                    BlockMode::ECB,
+            };
+        default:
+            return {};
+    }
+}
+
+vector<PaddingMode> KeyMintAidlTestBase::ValidPaddingModes(Algorithm algorithm,
+                                                           BlockMode blockMode) {
+    switch (algorithm) {
+        case Algorithm::AES:
+            switch (blockMode) {
+                case BlockMode::CBC:
+                case BlockMode::ECB:
+                    return {PaddingMode::NONE, PaddingMode::PKCS7};
+                case BlockMode::CTR:
+                case BlockMode::GCM:
+                    return {PaddingMode::NONE};
+                default:
+                    return {};
+            };
+        case Algorithm::TRIPLE_DES:
+            switch (blockMode) {
+                case BlockMode::CBC:
+                case BlockMode::ECB:
+                    return {PaddingMode::NONE, PaddingMode::PKCS7};
+                default:
+                    return {};
+            };
+        default:
+            return {};
+    }
+}
+
+vector<PaddingMode> KeyMintAidlTestBase::InvalidPaddingModes(Algorithm algorithm,
+                                                             BlockMode blockMode) {
+    switch (algorithm) {
+        case Algorithm::AES:
+            switch (blockMode) {
+                case BlockMode::CTR:
+                case BlockMode::GCM:
+                    return {PaddingMode::PKCS7};
+                default:
+                    return {};
+            };
+        default:
+            return {};
+    }
+}
+
 vector<EcCurve> KeyMintAidlTestBase::ValidCurves() {
     if (securityLevel_ == SecurityLevel::STRONGBOX) {
         return {EcCurve::P_256};
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 75a4418..88998d5 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -71,6 +71,7 @@
     IKeyMintDevice& keyMint() { return *keymint_; }
     uint32_t os_version() { return os_version_; }
     uint32_t os_patch_level() { return os_patch_level_; }
+    uint32_t vendor_patch_level() { return vendor_patch_level_; }
 
     ErrorCode GetReturnErrorCode(const Status& result);
 
@@ -230,6 +231,10 @@
     vector<uint32_t> ValidKeySizes(Algorithm algorithm);
     vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
 
+    vector<BlockMode> ValidBlockModes(Algorithm algorithm);
+    vector<PaddingMode> ValidPaddingModes(Algorithm algorithm, BlockMode blockMode);
+    vector<PaddingMode> InvalidPaddingModes(Algorithm algorithm, BlockMode blockMode);
+
     vector<EcCurve> ValidCurves();
     vector<EcCurve> InvalidCurves();
 
@@ -262,6 +267,7 @@
     std::shared_ptr<IKeyMintDevice> keymint_;
     uint32_t os_version_;
     uint32_t os_patch_level_;
+    uint32_t vendor_patch_level_;
 
     SecurityLevel securityLevel_;
     string name_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index aa008f8..f9a99aa 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -67,6 +67,8 @@
 
 namespace {
 
+bool check_patchLevels = false;
+
 template <TagType tag_type, Tag tag, typename ValueT>
 bool contains(const vector<KeyParameter>& set, TypedTag<tag_type, tag> ttag,
               ValueT expected_value) {
@@ -291,37 +293,340 @@
 class NewKeyGenerationTest : public KeyMintAidlTestBase {
   protected:
     void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
-        // TODO(swillden): Distinguish which params should be in which auth list.
-
-        AuthorizationSet auths;
-        for (auto& entry : keyCharacteristics) {
-            auths.push_back(AuthorizationSet(entry.authorizations));
-        }
-
-        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
 
-        // Verify that App data and ROT are NOT included.
-        EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
-        EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA));
-
         // Check that some unexpected tags/values are NOT present.
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT));
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
+    }
+
+    void CheckSymmetricParams(const vector<KeyCharacteristics>& keyCharacteristics) {
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
+        EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT));
+        EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
+
+        EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
+        EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
+    }
+
+    AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics) {
+        // TODO(swillden): Distinguish which params should be in which auth list.
+        AuthorizationSet auths;
+        for (auto& entry : keyCharacteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
+
+        // Verify that App data, ROT and auth timeout are NOT included.
+        EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
+        EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA));
         EXPECT_FALSE(auths.Contains(TAG_AUTH_TIMEOUT, 301U));
 
+        // Check OS details match the original hardware info.
         auto os_ver = auths.GetTagValue(TAG_OS_VERSION);
-        ASSERT_TRUE(os_ver);
+        EXPECT_TRUE(os_ver);
         EXPECT_EQ(*os_ver, os_version());
-
         auto os_pl = auths.GetTagValue(TAG_OS_PATCHLEVEL);
-        ASSERT_TRUE(os_pl);
+        EXPECT_TRUE(os_pl);
         EXPECT_EQ(*os_pl, os_patch_level());
+
+        if (check_patchLevels) {
+            // Should include vendor and boot patchlevels.
+            auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
+            EXPECT_TRUE(vendor_pl);
+            EXPECT_EQ(*vendor_pl, vendor_patch_level());
+            auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+            EXPECT_TRUE(boot_pl);
+        }
+
+        return auths;
     }
 };
 
 /*
+ * NewKeyGenerationTest.Aes
+ *
+ * Verifies that keymint can generate all required AES key sizes, and that the resulting keys
+ * have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, Aes) {
+    for (auto key_size : ValidKeySizes(Algorithm::AES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::AES)) {
+            for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "AES-" << key_size << "-" << block_mode << "-" << padding_mode);
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                auto builder = AuthorizationSetBuilder()
+                                       .AesEncryptionKey(key_size)
+                                       .BlockMode(block_mode)
+                                       .Padding(padding_mode)
+                                       .SetDefaultValidity();
+                if (block_mode == BlockMode::GCM) {
+                    builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
+                }
+                ASSERT_EQ(ErrorCode::OK, GenerateKey(builder, &key_blob, &key_characteristics));
+
+                EXPECT_GT(key_blob.size(), 0U);
+                CheckSymmetricParams(key_characteristics);
+
+                AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+                EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::AES));
+                EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                        << "Key size " << key_size << "missing";
+
+                CheckedDeleteKey(&key_blob);
+            }
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.AesInvalidSize
+ *
+ * Verifies that specifying an invalid key size for AES key generation returns
+ * UNSUPPORTED_KEY_SIZE.
+ */
+TEST_P(NewKeyGenerationTest, AesInvalidSize) {
+    for (auto key_size : InvalidKeySizes(Algorithm::AES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::AES)) {
+            for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "AES-" << key_size << "-" << block_mode << "-" << padding_mode);
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                auto builder = AuthorizationSetBuilder()
+                                       .AesEncryptionKey(key_size)
+                                       .BlockMode(block_mode)
+                                       .Padding(padding_mode)
+                                       .SetDefaultValidity();
+                if (block_mode == BlockMode::GCM) {
+                    builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
+                }
+                EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                          GenerateKey(builder, &key_blob, &key_characteristics));
+            }
+        }
+    }
+
+    for (auto block_mode : ValidBlockModes(Algorithm::AES)) {
+        for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+            vector<uint8_t> key_blob;
+            vector<KeyCharacteristics> key_characteristics;
+            // No key size specified
+            auto builder = AuthorizationSetBuilder()
+                                   .Authorization(TAG_ALGORITHM, Algorithm::AES)
+                                   .BlockMode(block_mode)
+                                   .Padding(padding_mode)
+                                   .SetDefaultValidity();
+            if (block_mode == BlockMode::GCM) {
+                builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
+            }
+            EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                      GenerateKey(builder, &key_blob, &key_characteristics));
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.AesInvalidPadding
+ *
+ * Verifies that specifying an invalid padding on AES keys gives a failure
+ * somewhere along the way.
+ */
+TEST_P(NewKeyGenerationTest, AesInvalidPadding) {
+    for (auto key_size : ValidKeySizes(Algorithm::AES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::AES)) {
+            for (auto padding_mode : InvalidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "AES-" << key_size << "-" << block_mode << "-" << padding_mode);
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                auto builder = AuthorizationSetBuilder()
+                                       .AesEncryptionKey(key_size)
+                                       .BlockMode(block_mode)
+                                       .Padding(padding_mode)
+                                       .SetDefaultValidity();
+                if (block_mode == BlockMode::GCM) {
+                    builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
+                }
+
+                auto result = GenerateKey(builder, &key_blob, &key_characteristics);
+                if (result == ErrorCode::OK) {
+                    // Key creation was OK but has generated a key that cannot be used.
+                    auto params =
+                            AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode);
+                    auto result = Begin(KeyPurpose::ENCRYPT, params);
+                    EXPECT_TRUE(result == ErrorCode::INCOMPATIBLE_PADDING_MODE ||
+                                result == ErrorCode::INVALID_KEY_BLOB);
+                } else {
+                    // The KeyMint implementation detected that the generated key
+                    // is unusable.
+                    EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, result);
+                }
+            }
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.AesGcmMissingMinMac
+ *
+ * Verifies that specifying an invalid key size for AES key generation returns
+ * UNSUPPORTED_KEY_SIZE.
+ */
+TEST_P(NewKeyGenerationTest, AesGcmMissingMinMac) {
+    for (auto key_size : ValidKeySizes(Algorithm::AES)) {
+        BlockMode block_mode = BlockMode::GCM;
+        for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+            SCOPED_TRACE(testing::Message()
+                         << "AES-" << key_size << "-" << block_mode << "-" << padding_mode);
+            vector<uint8_t> key_blob;
+            vector<KeyCharacteristics> key_characteristics;
+            // No MIN_MAC_LENGTH provided.
+            auto builder = AuthorizationSetBuilder()
+                                   .AesEncryptionKey(key_size)
+                                   .BlockMode(block_mode)
+                                   .Padding(padding_mode)
+                                   .SetDefaultValidity();
+            EXPECT_EQ(ErrorCode::MISSING_MIN_MAC_LENGTH,
+                      GenerateKey(builder, &key_blob, &key_characteristics));
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.TripleDes
+ *
+ * Verifies that keymint can generate all required 3DES key sizes, and that the resulting keys
+ * have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, TripleDes) {
+    for (auto key_size : ValidKeySizes(Algorithm::TRIPLE_DES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::TRIPLE_DES)) {
+            for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "3DES-" << key_size << "-" << block_mode << "-" << padding_mode);
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                             .TripleDesEncryptionKey(key_size)
+                                                             .BlockMode(block_mode)
+                                                             .Padding(padding_mode)
+                                                             .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                             .SetDefaultValidity(),
+                                                     &key_blob, &key_characteristics));
+
+                EXPECT_GT(key_blob.size(), 0U);
+                CheckSymmetricParams(key_characteristics);
+
+                AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+                EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
+                EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                        << "Key size " << key_size << "missing";
+
+                CheckedDeleteKey(&key_blob);
+            }
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.TripleDesWithAttestation
+ *
+ * Verifies that keymint can generate all required 3DES key sizes, and that the resulting keys
+ * have correct characteristics.
+ *
+ * Request attestation, which doesn't help for symmetric keys (as there is no public key to
+ * put in a certificate) but which isn't an error.
+ */
+TEST_P(NewKeyGenerationTest, TripleDesWithAttestation) {
+    for (auto key_size : ValidKeySizes(Algorithm::TRIPLE_DES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::TRIPLE_DES)) {
+            for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "3DES-" << key_size << "-" << block_mode << "-" << padding_mode);
+
+                auto challenge = "hello";
+                auto app_id = "foo";
+
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                             .TripleDesEncryptionKey(key_size)
+                                                             .BlockMode(block_mode)
+                                                             .Padding(padding_mode)
+                                                             .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                             .AttestationChallenge(challenge)
+                                                             .AttestationApplicationId(app_id)
+                                                             .SetDefaultValidity(),
+                                                     &key_blob, &key_characteristics));
+
+                EXPECT_GT(key_blob.size(), 0U);
+                CheckSymmetricParams(key_characteristics);
+
+                AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+                EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
+                EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                        << "Key size " << key_size << "missing";
+
+                CheckedDeleteKey(&key_blob);
+            }
+        }
+    }
+}
+
+/*
+ * NewKeyGenerationTest.TripleDesInvalidSize
+ *
+ * Verifies that specifying an invalid key size for 3-DES key generation returns
+ * UNSUPPORTED_KEY_SIZE.
+ */
+TEST_P(NewKeyGenerationTest, TripleDesInvalidSize) {
+    for (auto key_size : InvalidKeySizes(Algorithm::TRIPLE_DES)) {
+        for (auto block_mode : ValidBlockModes(Algorithm::TRIPLE_DES)) {
+            for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+                SCOPED_TRACE(testing::Message()
+                             << "3DES-" << key_size << "-" << block_mode << "-" << padding_mode);
+                vector<uint8_t> key_blob;
+                vector<KeyCharacteristics> key_characteristics;
+                EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                          GenerateKey(AuthorizationSetBuilder()
+                                              .TripleDesEncryptionKey(key_size)
+                                              .BlockMode(block_mode)
+                                              .Padding(padding_mode)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .SetDefaultValidity(),
+                                      &key_blob, &key_characteristics));
+            }
+        }
+    }
+
+    // Omitting the key size fails.
+    for (auto block_mode : ValidBlockModes(Algorithm::TRIPLE_DES)) {
+        for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+            SCOPED_TRACE(testing::Message()
+                         << "3DES-default-" << block_mode << "-" << padding_mode);
+            vector<uint8_t> key_blob;
+            vector<KeyCharacteristics> key_characteristics;
+            ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                      GenerateKey(AuthorizationSetBuilder()
+                                          .Authorization(TAG_ALGORITHM, Algorithm::TRIPLE_DES)
+                                          .BlockMode(block_mode)
+                                          .Padding(padding_mode)
+                                          .Authorization(TAG_NO_AUTH_REQUIRED)
+                                          .SetDefaultValidity(),
+                                  &key_blob, &key_characteristics));
+        }
+    }
+}
+
+/*
  * NewKeyGenerationTest.Rsa
  *
  * Verifies that keymint can generate all required RSA key sizes, and that the resulting keys
@@ -1720,7 +2025,7 @@
 }
 
 /*
- * SigningOperationsTest.RsaPssNoDigest
+ * SigningOperationsTest.RsaPssNoPadding
  *
  * Verifies that RSA operations fail when no padding mode is specified.  PaddingMode::NONE is
  * supported in some cases (as validated in other tests), but a mode must be specified.
@@ -2075,7 +2380,7 @@
 }
 
 /*
- * VerificationOperationsTest.RsaSuccess
+ * VerificationOperationsTest.RsaAllPaddingsAndDigests
  *
  * Verifies RSA signature/verification for all padding modes and digests.
  */
@@ -2171,7 +2476,7 @@
 }
 
 /*
- * VerificationOperationsTest.RsaSuccess
+ * VerificationOperationsTest.RsaAllDigestsAndCurves
  *
  * Verifies ECDSA signature/verification for all digests and curves.
  */
@@ -2571,7 +2876,72 @@
 }
 
 /*
- * ImportKeyTest.AesSuccess
+ * ImportKeyTest.AesFailure
+ *
+ * Verifies that importing an invalid AES key fails.
+ */
+TEST_P(ImportKeyTest, AesFailure) {
+    string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    uint32_t bitlen = key.size() * 8;
+    for (uint32_t key_size : {bitlen - 1, bitlen + 1, bitlen - 8, bitlen + 8}) {
+        ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                  ImportKey(AuthorizationSetBuilder()
+                                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                                    .AesEncryptionKey(key_size)
+                                    .EcbMode()
+                                    .Padding(PaddingMode::PKCS7),
+                            KeyFormat::RAW, key));
+    }
+}
+
+/*
+ * ImportKeyTest.TripleDesSuccess
+ *
+ * Verifies that importing and using a 3DES key works.
+ */
+TEST_P(ImportKeyTest, TripleDesSuccess) {
+    string key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
+    ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
+                                               .Authorization(TAG_NO_AUTH_REQUIRED)
+                                               .TripleDesEncryptionKey(168)
+                                               .EcbMode()
+                                               .Padding(PaddingMode::PKCS7),
+                                       KeyFormat::RAW, key));
+
+    CheckCryptoParam(TAG_ALGORITHM, Algorithm::TRIPLE_DES);
+    CheckCryptoParam(TAG_KEY_SIZE, 168U);
+    CheckCryptoParam(TAG_PADDING, PaddingMode::PKCS7);
+    CheckCryptoParam(TAG_BLOCK_MODE, BlockMode::ECB);
+    CheckOrigin();
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    string ciphertext = EncryptMessage(message, params);
+    string plaintext = DecryptMessage(ciphertext, params);
+    EXPECT_EQ(message, plaintext);
+}
+
+/*
+ * ImportKeyTest.TripleDesFailure
+ *
+ * Verifies that importing an invalid 3DES key fails.
+ */
+TEST_P(ImportKeyTest, TripleDesFailure) {
+    string key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
+    uint32_t bitlen = key.size() * 8;
+    for (uint32_t key_size : {bitlen - 1, bitlen + 1, bitlen - 8, bitlen + 8}) {
+        ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+                  ImportKey(AuthorizationSetBuilder()
+                                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                                    .TripleDesEncryptionKey(key_size)
+                                    .EcbMode()
+                                    .Padding(PaddingMode::PKCS7),
+                            KeyFormat::RAW, key));
+    }
+}
+
+/*
+ * ImportKeyTest.HmacKeySuccess
  *
  * Verifies that importing and using an HMAC key works.
  */
@@ -2881,7 +3251,7 @@
 }
 
 /*
- * EncryptionOperationsTest.RsaOaepInvalidDigest
+ * EncryptionOperationsTest.RsaOaepDecryptWithWrongDigest
  *
  * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt
  * with a different digest than was used to encrypt.
@@ -3165,7 +3535,7 @@
 }
 
 /*
- * EncryptionOperationsTest.AesEcbRoundTripSuccess
+ * EncryptionOperationsTest.AesWrongMode
  *
  * Verifies that AES encryption fails in the correct way when an unauthorized mode is specified.
  */
@@ -3565,7 +3935,7 @@
 }
 
 /*
- * EncryptionOperationsTest.AesCtrInvalidCallerNonce
+ * EncryptionOperationsTest.AesCbcRoundTripSuccess
  *
  * Verifies that keymint fails correctly when the user supplies an incorrect-size nonce.
  */
@@ -4231,11 +4601,8 @@
                                                  .BlockMode(BlockMode::ECB)
                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
                                                  .Padding(PaddingMode::NONE)));
-    for (size_t i = 0; i < 32; ++i) {
-        auto inParams =
-                AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
-        EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, inParams));
-    }
+    auto inParams = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, inParams));
 }
 
 /*
@@ -4912,6 +5279,19 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest);
 
+typedef KeyMintAidlTestBase GetHardwareInfoTest;
+
+TEST_P(GetHardwareInfoTest, GetHardwareInfo) {
+    // Retrieving hardware info should give the same result each time.
+    KeyMintHardwareInfo info;
+    ASSERT_TRUE(keyMint().getHardwareInfo(&info).isOk());
+    KeyMintHardwareInfo info2;
+    ASSERT_TRUE(keyMint().getHardwareInfo(&info2).isOk());
+    EXPECT_EQ(info, info2);
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(GetHardwareInfoTest);
+
 typedef KeyMintAidlTestBase AddEntropyTest;
 
 /*
@@ -4943,6 +5323,16 @@
     EXPECT_TRUE(keyMint().addRngEntropy(AidlBuf(string(2 * 1024, 'a'))).isOk());
 }
 
+/*
+ * AddEntropyTest.AddTooLargeEntropy
+ *
+ * Verifies that the addRngEntropy method rejects more than 2KiB  of data.
+ */
+TEST_P(AddEntropyTest, AddTooLargeEntropy) {
+    ErrorCode rc = GetReturnErrorCode(keyMint().addRngEntropy(AidlBuf(string(2 * 1024 + 1, 'a'))));
+    EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, rc);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(AddEntropyTest);
 
 typedef KeyMintAidlTestBase KeyDeletionTest;
@@ -5122,7 +5512,7 @@
 typedef KeyMintAidlTestBase TransportLimitTest;
 
 /*
- * TransportLimitTest.FinishInput
+ * TransportLimitTest.LargeFinishInput
  *
  * Verifies that passing input data to finish succeeds as expected.
  */
@@ -5372,16 +5762,6 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
 
-using PerformOperationTest = KeyMintAidlTestBase;
-
-TEST_P(PerformOperationTest, RequireUnimplemented) {
-    vector<uint8_t> response;
-    auto result = keymint_->performOperation({} /* request */, &response);
-    ASSERT_EQ(GetReturnErrorCode(result), ErrorCode::UNIMPLEMENTED);
-}
-
-INSTANTIATE_KEYMINT_AIDL_TEST(PerformOperationTest);
-
 }  // namespace aidl::android::hardware::security::keymint::test
 
 int main(int argc, char** argv) {
@@ -5406,6 +5786,10 @@
             } else {
                 std::cout << "NOT dumping attestations" << std::endl;
             }
+            // TODO(drysdale): Remove this flag when available KeyMint devices comply with spec
+            if (std::string(argv[i]) == "--check_patchLevels") {
+                aidl::android::hardware::security::keymint::test::check_patchLevels = true;
+            }
         }
     }
     return RUN_ALL_TESTS();
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 6c795f5..54b6fdc 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -228,8 +228,7 @@
                     AuthorizationSet* out_params) {
         Status result;
         BeginResult out;
-        result = keymint_->begin(purpose, key_blob_, in_params.vector_data(), HardwareAuthToken(),
-                                 &out);
+        result = keymint_->begin(purpose, key_blob_, in_params.vector_data(), std::nullopt, &out);
         if (result.isOk()) {
             *out_params = out.params;
             op_ = out.operation;
diff --git a/security/keymint/support/include/keymint_support/keymint_utils.h b/security/keymint/support/include/keymint_support/keymint_utils.h
index 53d5b96..e1ead21 100644
--- a/security/keymint/support/include/keymint_support/keymint_utils.h
+++ b/security/keymint/support/include/keymint_support/keymint_utils.h
@@ -38,5 +38,6 @@
 
 uint32_t getOsVersion();
 uint32_t getOsPatchlevel();
+uint32_t getVendorPatchlevel();
 
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/support/keymint_utils.cpp b/security/keymint/support/keymint_utils.cpp
index e73d602..2dbdfa8 100644
--- a/security/keymint/support/keymint_utils.cpp
+++ b/security/keymint/support/keymint_utils.cpp
@@ -31,10 +31,11 @@
 constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1;
 
 constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch";
-constexpr char kPlatformPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$";
+constexpr char kVendorPatchlevelProp[] = "ro.vendor.build.security_patch";
+constexpr char kPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$";
 constexpr size_t kYearMatch = 1;
 constexpr size_t kMonthMatch = 2;
-constexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1;
+constexpr size_t kPatchlevelMatchCount = kMonthMatch + 1;
 
 uint32_t match_to_uint32(const char* expression, const regmatch_t& match) {
     if (match.rm_so == -1) return 0;
@@ -80,15 +81,14 @@
     return getOsVersion(version.c_str());
 }
 
-uint32_t getOsPatchlevel(const char* patchlevel_str) {
+uint32_t getPatchlevel(const char* patchlevel_str) {
     regex_t regex;
-    if (regcomp(&regex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) {
+    if (regcomp(&regex, kPatchlevelRegex, REG_EXTENDED) != 0) {
         return 0;
     }
 
-    regmatch_t matches[kPlatformPatchlevelMatchCount];
-    int not_match =
-            regexec(&regex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */);
+    regmatch_t matches[kPatchlevelMatchCount];
+    int not_match = regexec(&regex, patchlevel_str, kPatchlevelMatchCount, matches, 0 /* flags */);
     regfree(&regex);
     if (not_match) {
         return 0;
@@ -105,7 +105,12 @@
 
 uint32_t getOsPatchlevel() {
     std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp);
-    return getOsPatchlevel(patchlevel.c_str());
+    return getPatchlevel(patchlevel.c_str());
+}
+
+uint32_t getVendorPatchlevel() {
+    std::string patchlevel = wait_and_get_property(kVendorPatchlevelProp);
+    return getPatchlevel(patchlevel.c_str());
 }
 
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
index 71b4278..2fbd29a 100644
--- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -43,7 +43,7 @@
      *
      * where:
      *
-     *   ``ISecureClock.TIME_STAMP_MAC_LABEL'' is a sting constant defined in ISecureClock.aidl.
+     *   ``ISecureClock.TIME_STAMP_MAC_LABEL'' is a string constant defined in ISecureClock.aidl.
      *
      *   ``H'' is the shared HMAC key (see computeSharedHmac() in ISharedSecret).
      *
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 4c92665..62093cc 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -56,9 +56,6 @@
 }
 
 void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) {
-    if (!timeFilter.support) {
-        return;
-    }
     uint32_t demuxId;
     sp<IDemux> demux;
     DemuxCapabilities caps;
@@ -161,27 +158,36 @@
 
 void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
                                                  FrontendConfig frontendConf, DvrConfig dvrConf) {
-    uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mDvrTests.setDemux(demux);
+
+    DvrConfig dvrSourceConfig;
+    if (mLnbId || record.hasFrontendConnection) {
+        uint32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        if (mLnbId) {
+            ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
+        }
+        if (frontendConf.isSoftwareFe) {
+            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+        }
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        mFrontendTests.setDvrTests(mDvrTests);
+    } else {
+        dvrSourceConfig = dvrMap[record.dvrSourceId];
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
     uint32_t filterId;
     sp<IFilter> filter;
-
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    if (mLnbId) {
-        ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
-    }
-    if (frontendConf.isSoftwareFe) {
-        mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
-    }
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFilterTests.setDemux(demux);
-    mDvrTests.setDemux(demux);
-    mFrontendTests.setDvrTests(mDvrTests);
     ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
     ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
     ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
@@ -195,17 +201,39 @@
     ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
     ASSERT_TRUE(mDvrTests.startDvrRecord());
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
-    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+
+    if (mLnbId || record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    } else {
+        // Start DVR Source
+        mDvrTests.startPlaybackInputThread(dvrSourceConfig.playbackInputFile,
+                                           dvrSourceConfig.settings.playback());
+        ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    }
+
     mDvrTests.testRecordOutput();
     mDvrTests.stopRecordThread();
-    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+
+    if (mLnbId || record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    } else {
+        mDvrTests.stopPlaybackThread();
+        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    }
+
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
     ASSERT_TRUE(mDvrTests.stopDvrRecord());
     ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     mDvrTests.closeDvrRecord();
+
+    if (mLnbId || record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    } else {
+        mDvrTests.closeDvrPlayback();
+    }
+
     ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
 void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
@@ -236,23 +264,28 @@
 void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf,
                                                             FrontendConfig frontendConf,
                                                             DvrConfig dvrConf) {
-    uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+
+    if (record.hasFrontendConnection) {
+        uint32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    }
+
     uint32_t filterId;
     sp<IFilter> filter;
-
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFilterTests.setDemux(demux);
+
     mDvrTests.setDemux(demux);
     ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
     ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
     ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
+
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
     ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
@@ -268,30 +301,42 @@
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     mDvrTests.closeDvrRecord();
     ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
 }
 
 void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
                                                       FrontendConfig frontendConf,
                                                       DescramblerConfig descConfig) {
-    uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+
+    DvrConfig dvrSourceConfig;
+    if (descrambling.hasFrontendConnection) {
+        uint32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        if (frontendConf.isSoftwareFe) {
+            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+        }
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        mFrontendTests.setDemux(demux);
+    } else {
+        dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
     set<uint32_t> filterIds;
     uint32_t filterId;
     set<struct FilterConfig>::iterator config;
     set<uint32_t>::iterator id;
-
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    if (frontendConf.isSoftwareFe) {
-        mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
-    }
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFilterTests.setDemux(demux);
-    mFrontendTests.setDemux(demux);
     for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
         ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize));
         ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
@@ -314,10 +359,26 @@
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
         ASSERT_TRUE(mFilterTests.startFilter(*id));
     }
-    // tune test
-    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+
+    if (descrambling.hasFrontendConnection) {
+        // tune test
+        ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    } else {
+        // Start DVR Source
+        mDvrTests.startPlaybackInputThread(dvrSourceConfig.playbackInputFile,
+                                           dvrSourceConfig.settings.playback());
+        ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    }
+
     ASSERT_TRUE(filterDataOutputTest());
-    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    } else {
+        mDvrTests.stopPlaybackThread();
+        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    }
+
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
         ASSERT_TRUE(mFilterTests.stopFilter(*id));
     }
@@ -328,27 +389,45 @@
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
         ASSERT_TRUE(mFilterTests.closeFilter(*id));
     }
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    } else {
+        mDvrTests.closeDvrPlayback();
+    }
+
     ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
 TEST_P(TunerFrontendHidlTest, TuneFrontend) {
     description("Tune one Frontend with specific setting and check Lock event");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFrontendHidlTest, AutoScanFrontend) {
     description("Run an auto frontend scan with specific setting and check lock scanMessage");
+    if (!scan.hasFrontendConnection) {
+        return;
+    }
     mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
 }
 
 TEST_P(TunerFrontendHidlTest, BlindScanFrontend) {
     description("Run an blind frontend scan with specific setting and check lock scanMessage");
+    if (!scan.hasFrontendConnection) {
+        return;
+    }
     mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
 }
 
 TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) {
     description("Open and configure an Lnb with specific settings then send a diseqc msg to it.");
+    if (!lnbLive.support) {
+        return;
+    }
     if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
         vector<uint32_t> ids;
         ASSERT_TRUE(mLnbTests.getLnbIds(ids));
@@ -370,6 +449,9 @@
 
 TEST_P(TunerDemuxHidlTest, openDemux) {
     description("Open and close a Demux.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
@@ -385,6 +467,9 @@
 
 TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
     description("Get the A/V sync time from a PCR filter.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
         return;
     }
@@ -423,6 +508,9 @@
 
 TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
     description("Open and start a filter in Demux.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     // TODO use paramterized tests
     configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
 }
@@ -457,22 +545,34 @@
 
 TEST_P(TunerFilterHidlTest, testTimeFilter) {
     description("Open a timer filter in Demux and set time stamp.");
+    if (!timeFilter.support) {
+        return;
+    }
     // TODO use paramterized tests
     testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
 }
 
 TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) {
     description("Test Video Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) {
     description("Test Audio Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) {
     description("Test Section Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
         return;
     }
@@ -481,6 +581,9 @@
 
 TEST_P(TunerBroadcastHidlTest, IonBufferTest) {
     description("Test the av filter data bufferring.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
     broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
 }
 
@@ -501,6 +604,22 @@
     playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
 }
 
+TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsAudioFilterTest) {
+    description("Feed ts data from playback and configure Ts audio filter to get output");
+    if (!playback.support) {
+        return;
+    }
+    playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+}
+
+TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsVideoFilterTest) {
+    description("Feed ts data from playback and configure Ts video filter to get output");
+    if (!playback.support) {
+        return;
+    }
+    playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+}
+
 TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) {
     description("Attach a single filter to the record dvr test.");
     // TODO use paramterized tests
@@ -535,19 +654,26 @@
     if (descrambling.support) {
         return;
     }
-    uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
-    mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+
+    if (descrambling.hasFrontendConnection) {
+        uint32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    }
+
     ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
     ASSERT_TRUE(mDescramblerTests.closeDescrambler());
     ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
 }
 
 TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) {
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 65f8615..735bc82 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -148,10 +148,32 @@
 };
 
 inline bool validateConnections() {
-    bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() &&
-                     frontendMap.find(scan.frontendId) != frontendMap.end();
-    feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true;
-    feIsValid &= descrambling.support
+    if ((!live.hasFrontendConnection || !scan.hasFrontendConnection) && !playback.support) {
+        ALOGW("[vts config] VTS must support either a DVR source or a Frontend source.");
+        return false;
+    }
+
+    if (record.support && !record.hasFrontendConnection &&
+        record.dvrSourceId.compare(emptyHardwareId) == 0) {
+        ALOGW("[vts config] Record must support either a DVR source or a Frontend source.");
+        return false;
+    }
+
+    if (descrambling.support && !descrambling.hasFrontendConnection &&
+        descrambling.dvrSourceId.compare(emptyHardwareId) == 0) {
+        ALOGW("[vts config] Descrambling must support either a DVR source or a Frontend source.");
+        return false;
+    }
+
+    bool feIsValid = live.hasFrontendConnection
+                             ? frontendMap.find(live.frontendId) != frontendMap.end()
+                             : true;
+    feIsValid &= scan.hasFrontendConnection ? frontendMap.find(scan.frontendId) != frontendMap.end()
+                                            : true;
+    feIsValid &= record.support && record.hasFrontendConnection
+                         ? frontendMap.find(record.frontendId) != frontendMap.end()
+                         : true;
+    feIsValid &= (descrambling.support && descrambling.hasFrontendConnection)
                          ? frontendMap.find(descrambling.frontendId) != frontendMap.end()
                          : true;
     feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true;
@@ -163,18 +185,28 @@
         return false;
     }
 
-    bool dvrIsValid = frontendMap[live.frontendId].isSoftwareFe
+    bool dvrIsValid = (live.hasFrontendConnection && frontendMap[live.frontendId].isSoftwareFe)
                               ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end()
                               : true;
     dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true;
     if (record.support) {
-        if (frontendMap[record.frontendId].isSoftwareFe) {
-            dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end();
+        if (record.hasFrontendConnection) {
+            if (frontendMap[record.frontendId].isSoftwareFe) {
+                dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end();
+            }
+        } else {
+            dvrIsValid &= dvrMap.find(record.dvrSourceId) != dvrMap.end();
         }
         dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
     }
-    if (descrambling.support && frontendMap[descrambling.frontendId].isSoftwareFe) {
-        dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end();
+    if (descrambling.support) {
+        if (descrambling.hasFrontendConnection) {
+            if (frontendMap[descrambling.frontendId].isSoftwareFe) {
+                dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end();
+            }
+        } else {
+            dvrIsValid &= dvrMap.find(descrambling.dvrSourceId) != dvrMap.end();
+        }
     }
 
     if (!dvrIsValid) {
diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h
index 90499c4..7971fd2 100644
--- a/tv/tuner/config/TunerTestingConfigReader.h
+++ b/tv/tuner/config/TunerTestingConfigReader.h
@@ -120,6 +120,7 @@
 };
 
 struct LiveBroadcastHardwareConnections {
+    bool hasFrontendConnection;
     string frontendId;
     string dvrSoftwareFeId;
     string audioFilterId;
@@ -130,6 +131,7 @@
 };
 
 struct ScanHardwareConnections {
+    bool hasFrontendConnection;
     string frontendId;
 };
 
@@ -145,19 +147,23 @@
 
 struct DvrRecordHardwareConnections {
     bool support;
+    bool hasFrontendConnection;
     string frontendId;
     string dvrRecordId;
     string dvrSoftwareFeId;
     string recordFilterId;
+    string dvrSourceId;
 };
 
 struct DescramblingHardwareConnections {
     bool support;
+    bool hasFrontendConnection;
     string frontendId;
     string dvrSoftwareFeId;
     string audioFilterId;
     string videoFilterId;
     string descramblerId;
+    string dvrSourceId;
     /* list string of extra filters; */
 };
 
@@ -395,7 +401,14 @@
     }
 
     static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) {
-        auto liveConfig = *getDataFlowConfiguration().getFirstClearLiveBroadcast();
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasClearLiveBroadcast()) {
+            live.hasFrontendConnection = true;
+        } else {
+            live.hasFrontendConnection = false;
+            return;
+        }
+        auto liveConfig = *dataFlow.getFirstClearLiveBroadcast();
         live.frontendId = liveConfig.getFrontendConnection();
 
         live.audioFilterId = liveConfig.getAudioFilterConnection();
@@ -416,8 +429,15 @@
     }
 
     static void connectScan(ScanHardwareConnections& scan) {
-        auto scanConfig = getDataFlowConfiguration().getFirstScan();
-        scan.frontendId = scanConfig->getFrontendConnection();
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasScan()) {
+            scan.hasFrontendConnection = true;
+        } else {
+            scan.hasFrontendConnection = false;
+            return;
+        }
+        auto scanConfig = *dataFlow.getFirstScan();
+        scan.frontendId = scanConfig.getFrontendConnection();
     }
 
     static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) {
@@ -425,6 +445,7 @@
         if (dataFlow.hasDvrPlayback()) {
             playback.support = true;
         } else {
+            playback.support = false;
             return;
         }
         auto playbackConfig = *dataFlow.getFirstDvrPlayback();
@@ -443,6 +464,7 @@
         if (dataFlow.hasDvrRecord()) {
             record.support = true;
         } else {
+            record.support = false;
             return;
         }
         auto recordConfig = *dataFlow.getFirstDvrRecord();
@@ -452,6 +474,13 @@
         if (recordConfig.hasDvrSoftwareFeConnection()) {
             record.dvrSoftwareFeId = recordConfig.getDvrSoftwareFeConnection();
         }
+        if (recordConfig.getHasFrontendConnection()) {
+            record.hasFrontendConnection = true;
+            record.dvrSourceId = emptyHardwareId;
+        } else {
+            record.hasFrontendConnection = false;
+            record.dvrSourceId = recordConfig.getDvrSourceConnection();
+        }
     }
 
     static void connectDescrambling(DescramblingHardwareConnections& descrambling) {
@@ -459,6 +488,7 @@
         if (dataFlow.hasDescrambling()) {
             descrambling.support = true;
         } else {
+            descrambling.support = false;
             return;
         }
         auto descConfig = *dataFlow.getFirstDescrambling();
@@ -469,6 +499,13 @@
         if (descConfig.hasDvrSoftwareFeConnection()) {
             descrambling.dvrSoftwareFeId = descConfig.getDvrSoftwareFeConnection();
         }
+        if (descConfig.getHasFrontendConnection()) {
+            descrambling.hasFrontendConnection = true;
+            descrambling.dvrSourceId = emptyHardwareId;
+        } else {
+            descrambling.hasFrontendConnection = false;
+            descrambling.dvrSourceId = descConfig.getDvrSourceConnection();
+        }
     }
 
     static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
@@ -476,6 +513,7 @@
         if (dataFlow.hasLnbLive()) {
             lnbLive.support = true;
         } else {
+            lnbLive.support = false;
             return;
         }
         auto lnbLiveConfig = *dataFlow.getFirstLnbLive();
@@ -495,6 +533,7 @@
         if (dataFlow.hasLnbRecord()) {
             lnbRecord.support = true;
         } else {
+            lnbRecord.support = false;
             return;
         }
         auto lnbRecordConfig = *dataFlow.getFirstLnbRecord();
@@ -514,6 +553,7 @@
         if (dataFlow.hasTimeFilter()) {
             timeFilter.support = true;
         } else {
+            timeFilter.support = false;
             return;
         }
         auto timeFilterConfig = *dataFlow.getFirstTimeFilter();
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 4255a60..abd7155 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -48,12 +48,16 @@
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public String getDescramblerConnection();
     method @Nullable public String getDvrSoftwareFeConnection();
+    method @Nullable public String getDvrSourceConnection();
     method @Nullable public String getFrontendConnection();
+    method @Nullable public boolean getHasFrontendConnection();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDescramblerConnection(@Nullable String);
     method public void setDvrSoftwareFeConnection(@Nullable String);
+    method public void setDvrSourceConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
+    method public void setHasFrontendConnection(@Nullable boolean);
     method public void setVideoFilterConnection(@Nullable String);
   }
 
@@ -73,11 +77,15 @@
     ctor public DataFlowConfiguration.DvrRecord();
     method @Nullable public String getDvrRecordConnection();
     method @Nullable public String getDvrSoftwareFeConnection();
+    method @Nullable public String getDvrSourceConnection();
     method @Nullable public String getFrontendConnection();
+    method @Nullable public boolean getHasFrontendConnection();
     method @Nullable public String getRecordFilterConnection();
     method public void setDvrRecordConnection(@Nullable String);
     method public void setDvrSoftwareFeConnection(@Nullable String);
+    method public void setDvrSourceConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
+    method public void setHasFrontendConnection(@Nullable boolean);
     method public void setRecordFilterConnection(@Nullable String);
   }
 
diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml
index 570171e..2624076 100644
--- a/tv/tuner/config/sample_tuner_vts_config.xml
+++ b/tv/tuner/config/sample_tuner_vts_config.xml
@@ -196,7 +196,8 @@
                             sectionFilterConnection="FILTER_TS_SECTION_0"
                             dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
         <scan frontendConnection="FE_DEFAULT"/>
-        <descrambling frontendConnection="FE_DEFAULT"
+        <descrambling hasFrontendConnection="true"
+                      frontendConnection="FE_DEFAULT"
                       descramblerConnection="DESCRAMBLER_0"
                       audioFilterConnection="FILTER_AUDIO_DEFAULT"
                       videoFilterConnection="FILTER_VIDEO_DEFAULT"
@@ -205,7 +206,8 @@
                      audioFilterConnection="FILTER_AUDIO_DEFAULT"
                      videoFilterConnection="FILTER_VIDEO_DEFAULT"
                      sectionFilterConnection="FILTER_TS_SECTION_0"/>
-        <dvrRecord frontendConnection="FE_DEFAULT"
+        <dvrRecord hasFrontendConnection="true"
+                   frontendConnection="FE_DEFAULT"
                    recordFilterConnection="FILTER_TS_RECORD_0"
                    dvrRecordConnection="DVR_RECORD_0"
                    dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 3fe93ff..e0c3e33 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -534,7 +534,9 @@
     <!-- DATA FLOW CONFIGURATION SESSION -->
     <xs:complexType name="dataFlowConfiguration">
         <xs:sequence>
-            <xs:element name="clearLiveBroadcast" minOccurs="1" maxOccurs="1">
+            <!-- clearLiveBroadcast is only optional when there is no physical frontend. In this
+              case, the dvrPlayback config is required. -->
+            <xs:element name="clearLiveBroadcast" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
                     <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
                     <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
@@ -546,20 +548,27 @@
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
                 </xs:complexType>
             </xs:element>
-            <xs:element name="scan" minOccurs="1" maxOccurs="1">
+            <!-- scan is only optional when there is no physical frontend. In this case, the
+              dvrPlayback config is required. -->
+            <xs:element name="scan" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
                     <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
                 </xs:complexType>
             </xs:element>
             <xs:element name="descrambling" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
+                    <!-- If there is a software or hardware frontend connection or not. If false,
+                      dvrSourceConnection config is required when testing dvrRecord.  -->
+                    <xs:attribute name="hasFrontendConnection" type="xs:boolean" use="required"/>
                     <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
                     <xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
                     <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
                     <!-- TODO: b/182519645 allow the users to insert extra filters -->
-                    <!-- DVR is only required when the frontend is using the software input -->
+                    <!-- This DVR is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
+                    <!-- This Dvr is only required when there's no frontend(sw or hw) connection -->
+                    <xs:attribute name="dvrSourceConnection" type="dvrId" use="optional"/>
                 </xs:complexType>
             </xs:element>
             <xs:element name="dvrPlayback" minOccurs="0" maxOccurs="1">
@@ -573,10 +582,15 @@
             </xs:element>
             <xs:element name="dvrRecord" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
-                    <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+                    <!-- If there is a software or hardware frontend connection or not. If false,
+                      dvrSourceConnection config is required when testing dvrRecord.  -->
+                    <xs:attribute name="hasFrontendConnection" type="xs:boolean" use="required"/>
+                    <xs:attribute name="frontendConnection" type="frontendId" use="optional"/>
                     <xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
-                    <!-- DVR is only required when the frontend is using the software input -->
+                    <!-- This Dvr is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
+                    <!-- This Dvr is only required when there's no frontend(sw or hw) connection -->
+                    <xs:attribute name="dvrSourceConnection" type="dvrId" use="optional"/>
                     <xs:attribute name="recordFilterConnection" type="filterId" use="required"/>
                 </xs:complexType>
             </xs:element>
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl
index 8cb259f..7431804 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl
@@ -19,6 +19,6 @@
 @VintfStability
 parcelable CompositeEffect {
   int delayMs;
-  android.hardware.vibrator.CompositePrimitive primitive;
+  android.hardware.vibrator.CompositePrimitive primitive = android.hardware.vibrator.CompositePrimitive.NOOP;
   float scale;
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
index 406a899..5a990c0 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
@@ -22,7 +22,7 @@
 parcelable CompositeEffect {
     /* Period of silence preceding primitive. */
     int delayMs;
-    CompositePrimitive primitive;
+    CompositePrimitive primitive = CompositePrimitive.NOOP;
     /*
      * 0.0 (inclusive) - 1.0 (inclusive),
      * where 0.0 is minimum "feelable" amplitude.