Snap for 8426163 from db5579e3419c8c61ef7f2094ec5fa7e38a6e4267 to mainline-tzdata2-release

Change-Id: I5aa27508e0e759a40098970ee9f7100328bfd053
diff --git a/Android.bp b/Android.bp
index ebdd254..0b340a1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,35 +1,5 @@
 // Copyright 2006 The Android Open Source Project
 
-package {
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
-    name: "hardware_libhardware_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-        "SPDX-license-identifier-BSD",
-    ],
-    license_text: [
-        "NOTICE",
-    ],
-}
-
 cc_library_headers {
     name: "libhardware_headers",
     header_libs: [
@@ -59,7 +29,6 @@
         },
     },
     min_sdk_version: "29",
-    host_supported: true,
 
 }
 
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
-  license_type: NOTICE
-}
diff --git a/OWNERS b/OWNERS
index b6b18da..da2454a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,4 @@
-zachoverflow@google.com
+eisenbach@google.com
 elaurent@google.com
 jpawlowski@google.com
 malchev@google.com
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index adec3da..b87d3bb 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -57,8 +57,7 @@
 #define AUDIO_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0)
 #define AUDIO_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)
 #define AUDIO_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)
-#define AUDIO_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)
-#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_2
+#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_1
 /* Minimal audio HAL version supported by the audio framework */
 #define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0
 
@@ -233,20 +232,6 @@
     struct record_track_metadata* tracks;
 } sink_metadata_t;
 
-/* HAL version 3.2 and higher only. */
-typedef struct source_metadata_v7 {
-    size_t track_count;
-    /** Array of metadata of each track connected to this source. */
-    struct playback_track_metadata_v7* tracks;
-} source_metadata_v7_t;
-
-/* HAL version 3.2 and higher only. */
-typedef struct sink_metadata_v7 {
-    size_t track_count;
-    /** Array of metadata of each track connected to this sink. */
-    struct record_track_metadata_v7* tracks;
-} sink_metadata_v7_t;
-
 /**
  * audio_stream_out is the abstraction interface for the audio output hardware.
  *
@@ -451,88 +436,6 @@
     int (*set_event_callback)(struct audio_stream_out *stream,
                               stream_event_callback_t callback,
                               void *cookie);
-
-    /**
-     * Called when the metadata of the stream's source has been changed.
-     * HAL version 3.2 and higher only.
-     * @param source_metadata Description of the audio that is played by the clients.
-     */
-    void (*update_source_metadata_v7)(struct audio_stream_out *stream,
-                                      const struct source_metadata_v7* source_metadata);
-
-    /**
-     * Returns the Dual Mono mode presentation setting.
-     *
-     * \param[in] stream the stream object.
-     * \param[out] mode current setting of Dual Mono mode.
-     *
-     * \return 0 if the position is successfully returned.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*get_dual_mono_mode)(struct audio_stream_out *stream, audio_dual_mono_mode_t *mode);
-
-    /**
-     * Sets the Dual Mono mode presentation on the output device.
-     *
-     * \param[in] stream the stream object.
-     * \param[in] mode selected Dual Mono mode.
-     *
-     * \return 0 in case of success.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*set_dual_mono_mode)(struct audio_stream_out *stream, const audio_dual_mono_mode_t mode);
-
-    /**
-     * Returns the Audio Description Mix level in dB.
-     *
-     * \param[in] stream the stream object.
-     * \param[out] leveldB the current Audio Description Mix Level in dB.
-     *
-     * \return 0 in case of success.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*get_audio_description_mix_level)(struct audio_stream_out *stream, float *leveldB);
-
-    /**
-     * Sets the Audio Description Mix level in dB.
-     *
-     * \param[in] stream the stream object.
-     * \param[in] leveldB Audio Description Mix Level in dB.
-     *
-     * \return 0 in case of success.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*set_audio_description_mix_level)(struct audio_stream_out *stream, const float leveldB);
-
-    /**
-     * Retrieves current playback rate parameters.
-     *
-     * \param[in] stream the stream object.
-     * \param[out] playbackRate current playback parameters.
-     *
-     * \return 0 in case of success.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*get_playback_rate_parameters)(struct audio_stream_out *stream,
-                                        audio_playback_rate_t *playbackRate);
-
-    /**
-     * Sets the playback rate parameters that control playback behavior.
-     *
-     * \param[in] stream the stream object.
-     * \param[in] playbackRate playback parameters.
-     *
-     * \return 0 in case of success.
-     *         -EINVAL if the arguments are invalid
-     *         -ENOSYS if the function is not available
-     */
-    int (*set_playback_rate_parameters)(struct audio_stream_out *stream,
-                                        const audio_playback_rate_t *playbackRate);
 };
 typedef struct audio_stream_out audio_stream_out_t;
 
@@ -697,14 +600,6 @@
      */
     void (*update_sink_metadata)(struct audio_stream_in *stream,
                                  const struct sink_metadata* sink_metadata);
-
-    /**
-     * Called when the metadata of the stream's sink has been changed.
-     * HAL version 3.2 and higher only.
-     * @param sink_metadata Description of the audio that is recorded by the clients.
-     */
-    void (*update_sink_metadata_v7)(struct audio_stream_in *stream,
-                                    const struct sink_metadata_v7* sink_metadata);
 };
 typedef struct audio_stream_in audio_stream_in_t;
 
@@ -970,18 +865,6 @@
      */
     int (*remove_device_effect)(struct audio_hw_device *dev,
                         audio_port_handle_t device, effect_handle_t effect);
-
-    /**
-     * Fills the list of supported attributes for a given audio port.
-     * As input, "port" contains the information (type, role, address etc...)
-     * needed by the HAL to identify the port.
-     * As output, "port" contains possible attributes (sampling rates, formats,
-     * channel masks, gain controllers...) for this port. The possible attributes
-     * are saved as audio profiles, which contains audio format and the supported
-     * sampling rates and channel masks.
-     */
-    int (*get_audio_port_v7)(struct audio_hw_device *dev,
-                             struct audio_port_v7 *port);
 };
 typedef struct audio_hw_device audio_hw_device_t;
 
diff --git a/include/hardware/audio_alsaops.h b/include/hardware/audio_alsaops.h
index 476c311..6a17a35 100644
--- a/include/hardware/audio_alsaops.h
+++ b/include/hardware/audio_alsaops.h
@@ -60,7 +60,7 @@
     case AUDIO_FORMAT_PCM_FLOAT:  /* there is no equivalent for float */
     default:
         LOG_ALWAYS_FATAL("pcm_format_from_audio_format: invalid audio format %#x", format);
-        return PCM_FORMAT_INVALID;  /* doesn't get here, assert called above */
+        return 0;
     }
 }
 
@@ -94,7 +94,7 @@
 #endif
     default:
         LOG_ALWAYS_FATAL("audio_format_from_pcm_format: invalid pcm format %#x", format);
-        return AUDIO_FORMAT_INVALID;  /* doesn't get here, assert called above */
+        return 0;
     }
 }
 
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index afa0eef..3fe6aa8 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -258,25 +258,19 @@
     void *val;
 } bt_property_t;
 
-/** Represents the actual Out of Band data itself */
-typedef struct {
-    // Both
-    uint8_t address[7]; /* Bluetooth Device Address (6) plus Address Type (1) */
-    uint8_t c[16];      /* Simple Pairing Hash C-192/256 (Classic or LE) */
-    uint8_t r[16];      /* Simple Pairing Randomizer R-192/256 (Classic or LE) */
-    uint8_t device_name[256]; /* Name of the device */
+/** Bluetooth Out Of Band data for bonding */
+typedef struct
+{
+   uint8_t le_bt_dev_addr[7]; /* LE Bluetooth Device Address */
+   uint8_t c192[16]; /* Simple Pairing Hash C-192 */
+   uint8_t r192[16]; /* Simple Pairing Randomizer R-192 */
+   uint8_t c256[16]; /* Simple Pairing Hash C-256 */
+   uint8_t r256[16]; /* Simple Pairing Randomizer R-256 */
+   uint8_t sm_tk[16]; /* Security Manager TK Value */
+   uint8_t le_sc_c[16]; /* LE Secure Connections Confirmation Value */
+   uint8_t le_sc_r[16]; /* LE Secure Connections Random Value */
+} bt_out_of_band_data_t;
 
-    // Classic
-    uint8_t oob_data_length[2]; /* Classic only data Length. Value includes this
-                                   in length */
-    uint8_t class_of_device[2]; /* Class of Device (Classic or LE) */
-
-    // LE
-    uint8_t le_device_role;   /* Supported and preferred role of device */
-    uint8_t sm_tk[16];        /* Security Manager TK Value (LE Only) */
-    uint8_t le_flags;         /* LE Flags for discoverability and features */
-    uint8_t le_appearance[2]; /* For the appearance of the device */
-} bt_oob_data_t;
 
 
 /** Bluetooth Device Type */
@@ -514,8 +508,7 @@
 
     /** Create Bluetooth Bond using out of band data */
     int (*create_bond_out_of_band)(const RawAddress *bd_addr, int transport,
-                                   const bt_oob_data_t *p192_data,
-                                   const bt_oob_data_t *p256_data);
+                                   const bt_out_of_band_data_t *oob_data);
 
     /** Remove Bond */
     int (*remove_bond)(const RawAddress *bd_addr);
diff --git a/include/hardware/boot_control.h b/include/hardware/boot_control.h
index abbf3f1..36a867d 100644
--- a/include/hardware/boot_control.h
+++ b/include/hardware/boot_control.h
@@ -125,14 +125,7 @@
      */
     int (*isSlotMarkedSuccessful)(struct boot_control_module *module, unsigned slot);
 
-    /**
-     * Returns the active slot to boot into on the next boot. If
-     * setActiveBootSlot() has been called, the getter function should return
-     * the same slot as the one provided in the last setActiveBootSlot() call.
-     */
-    unsigned (*getActiveBootSlot)(struct boot_control_module *module);
-
-    void* reserved[30];
+    void* reserved[31];
 } boot_control_module_t;
 
 
diff --git a/include/hardware/keymaster0.h b/include/hardware/keymaster0.h
new file mode 100644
index 0000000..52ac64b
--- /dev/null
+++ b/include/hardware/keymaster0.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_KEYMASTER_0_H
+#define ANDROID_HARDWARE_KEYMASTER_0_H
+
+#include <hardware/keymaster_common.h>
+
+__BEGIN_DECLS
+
+/**
+ * Keymaster0 device definition.
+ */
+struct keymaster0_device {
+    /**
+     * Common methods of the keymaster device.  This *must* be the first member of
+     * keymaster0_device as users of this structure will cast a hw_device_t to
+     * keymaster0_device pointer in contexts where it's known the hw_device_t references a
+     * keymaster0_device.
+     */
+    struct hw_device_t common;
+
+    /**
+     * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version"
+     * fields in the keymaster_module initialization instead.
+     */
+    uint32_t client_version;
+
+    /**
+     * See flags defined for keymaster0_device::flags in keymaster_common.h
+     */
+    uint32_t flags;
+
+    void* context;
+
+    /**
+     * Generates a public and private key. The key-blob returned is opaque
+     * and must subsequently provided for signing and verification.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*generate_keypair)(const struct keymaster0_device* dev,
+            const keymaster_keypair_t key_type, const void* key_params,
+            uint8_t** key_blob, size_t* key_blob_length);
+
+    /**
+     * Imports a public and private key pair. The imported keys will be in
+     * PKCS#8 format with DER encoding (Java standard). The key-blob
+     * returned is opaque and will be subsequently provided for signing
+     * and verification.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*import_keypair)(const struct keymaster0_device* dev,
+            const uint8_t* key, const size_t key_length,
+            uint8_t** key_blob, size_t* key_blob_length);
+
+    /**
+     * Gets the public key part of a key pair. The public key must be in
+     * X.509 format (Java standard) encoded byte array.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     * On error, x509_data should not be allocated.
+     */
+    int (*get_keypair_public)(const struct keymaster0_device* dev,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            uint8_t** x509_data, size_t* x509_data_length);
+
+    /**
+     * Deletes the key pair associated with the key blob.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
+     */
+    int (*delete_keypair)(const struct keymaster0_device* dev,
+            const uint8_t* key_blob, const size_t key_blob_length);
+
+    /**
+     * Deletes all keys in the hardware keystore. Used when keystore is
+     * reset completely.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
+     */
+    int (*delete_all)(const struct keymaster0_device* dev);
+
+    /**
+     * Signs data using a key-blob generated before. This can use either
+     * an asymmetric key or a secret key.
+     *
+     * Returns: 0 on success or an error code less than 0.
+     */
+    int (*sign_data)(const struct keymaster0_device* dev,
+            const void* signing_params,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            const uint8_t* data, const size_t data_length,
+            uint8_t** signed_data, size_t* signed_data_length);
+
+    /**
+     * Verifies data signed with a key-blob. This can use either
+     * an asymmetric key or a secret key.
+     *
+     * Returns: 0 on successful verification or an error code less than 0.
+     */
+    int (*verify_data)(const struct keymaster0_device* dev,
+            const void* signing_params,
+            const uint8_t* key_blob, const size_t key_blob_length,
+            const uint8_t* signed_data, const size_t signed_data_length,
+            const uint8_t* signature, const size_t signature_length);
+};
+typedef struct keymaster0_device keymaster0_device_t;
+
+
+/* Convenience API for opening and closing keymaster devices */
+
+static inline int keymaster0_open(const struct hw_module_t* module,
+        keymaster0_device_t** device)
+{
+    int rc = module->methods->open(module, KEYSTORE_KEYMASTER,
+            TO_HW_DEVICE_T_OPEN(device));
+
+    return rc;
+}
+
+static inline int keymaster0_close(keymaster0_device_t* device)
+{
+    return device->common.close(&device->common);
+}
+
+__END_DECLS
+
+#endif  // ANDROID_HARDWARE_KEYMASTER_0_H
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index c0b3800..2fbfe46 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -71,7 +71,6 @@
     KM_TAG_INCLUDE_UNIQUE_ID = KM_BOOL | 202,      /* If true, attestation certificates for this key
                                                     * will contain an application-scoped and
                                                     * time-bounded device-unique ID. (keymaster2) */
-    KM_TAG_RSA_OAEP_MGF_DIGEST = KM_ENUM_REP | 203, /* keymaster_digest_t. */
 
     /* Other hardware-enforced. */
     KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 301, /* keymaster_key_blob_usage_requirements_t */
@@ -95,8 +94,6 @@
                                                            cryptographic operations with the key. */
     KM_TAG_MAX_USES_PER_BOOT = KM_UINT | 404,           /* Number of times the key can be used per
                                                            boot. */
-    KM_TAG_USAGE_COUNT_LIMIT = KM_UINT | 405,           /* Number of cryptographic operations left
-                                                           with the key.*/
 
     /* User authentication */
     KM_TAG_ALL_USERS = KM_BOOL | 500,           /* Reserved for future use -- ignore */
@@ -118,10 +115,8 @@
     KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout
                                                  * if device is still on-body (requires secure
                                                  * on-body sensor. */
-    KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507,/* Require test of user presence
-                                                           * to use this key. */
     KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508, /* Require user confirmation through a
-                                                           * trusted UI to use this key. */
+                                                           * trusted UI to use this key */
     KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509, /* Require the device screen to be unlocked if the
                                                       * key is used. */
 
@@ -167,14 +162,10 @@
                                                             attestation */
     KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717,  /* Used to provide the device's model name to be
                                                       included in attestation */
-    KM_TAG_VENDOR_PATCHLEVEL =  KM_UINT | 718,     /* specifies the vendor image security patch
-                                                      level with which the key may be used */
-    KM_TAG_BOOT_PATCHLEVEL =  KM_UINT | 719,       /* specifies the boot image (kernel) security
-                                                      patch level with which the key may be used */
-    KM_TAG_DEVICE_UNIQUE_ATTESTATION = KM_BOOL | 720,  /* Indicates StrongBox device-unique
-                                                          attestation is requested. */
+    KM_TAG_DEVICE_UNIQUE_ATTESTATION = KM_BOOL | 720,  /* Indicates StrongBox device-unique attestation
+                                                          is requested. */
     KM_TAG_IDENTITY_CREDENTIAL_KEY = KM_BOOL | 721, /* This is an identity credential key */
-    KM_TAG_STORAGE_KEY = KM_BOOL | 722,             /* storage encryption key */
+
 
     /* Tags used only to provide data to or receive data from operations */
     KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000, /* Used to provide associated data for AEAD modes. */
@@ -186,34 +177,8 @@
                                                * bits. */
 
     KM_TAG_RESET_SINCE_ID_ROTATION = KM_BOOL | 1004, /* Whether the device has beeen factory reset
-                                                        since the last unique ID rotation.  Used
-                                                        for key attestation. */
-
-    KM_TAG_CONFIRMATION_TOKEN = KM_BYTES | 1005,     /* used to deliver a cryptographic token
-                                                        proving that the user confirmed a signing
-                                                        request. */
-
-    KM_TAG_CERTIFICATE_SERIAL = KM_BIGNUM | 1006,      /* The serial number that should be
-                                                        set in the attestation certificate
-                                                        to be generated. */
-
-    KM_TAG_CERTIFICATE_SUBJECT = KM_BYTES | 1007,    /* A DER-encoded X.500 subject that should be
-                                                        set in the attestation certificate
-                                                        to be generated. */
-
-    KM_TAG_CERTIFICATE_NOT_BEFORE = KM_DATE | 1008,  /* Epoch time in milliseconds of the start of
-                                                        the to be generated certificate's validity.
-                                                        The value should interpreted as too's
-                                                        complement signed integer. Negative values
-                                                        indicate dates before Jan 1970 */
-
-    KM_TAG_CERTIFICATE_NOT_AFTER = KM_DATE | 1009,  /*  Epoch time in milliseconds of the end of
-                                                        the to be generated certificate's validity.
-                                                        The value should interpreted as too's
-                                                        complement signed integer. Negative values
-                                                        indicate dates before Jan 1970 */
-    KM_TAG_MAX_BOOT_LEVEL = KM_UINT | 1010, /* Specifies a maximum boot level at which a key
-                                               should function. */
+                                                        since the last unique ID rotation.  Used for
+                                                        key attestation. */
 } keymaster_tag_t;
 
 /**
@@ -344,8 +309,7 @@
     KM_PURPOSE_VERIFY = 3,     /* Usable with RSA, EC and HMAC keys. */
     KM_PURPOSE_DERIVE_KEY = 4, /* Usable with EC keys. */
     KM_PURPOSE_WRAP = 5,       /* Usable with wrapped keys. */
-    KM_PURPOSE_AGREE_KEY = 6,  /* Usable with EC keys. */
-    KM_PURPOSE_ATTEST_KEY = 7  /* Usabe with RSA and EC keys */
+
 } keymaster_purpose_t;
 
 typedef struct {
@@ -506,13 +470,6 @@
     KM_ERROR_EARLY_BOOT_ENDED = -73,
     KM_ERROR_ATTESTATION_KEYS_NOT_PROVISIONED = -74,
     KM_ERROR_ATTESTATION_IDS_NOT_PROVISIONED = -75,
-    KM_ERROR_INCOMPATIBLE_MGF_DIGEST = -78,
-    KM_ERROR_UNSUPPORTED_MGF_DIGEST = -79,
-    KM_ERROR_MISSING_NOT_BEFORE = -80,
-    KM_ERROR_MISSING_NOT_AFTER = -81,
-    KM_ERROR_MISSING_ISSUER_SUBJECT = -82,
-    KM_ERROR_INVALID_ISSUER_SUBJECT = -83,
-    KM_ERROR_BOOT_LEVEL_EXCEEDED = -84,
 
     KM_ERROR_UNIMPLEMENTED = -100,
     KM_ERROR_VERSION_MISMATCH = -101,
diff --git a/modules/audio/Android.bp b/modules/audio/Android.bp
index 1b34336..a7467c2 100644
--- a/modules/audio/Android.bp
+++ b/modules/audio/Android.bp
@@ -18,15 +18,6 @@
 //
 // The format of the name is audio.<type>.<hardware/etc>.so where the only
 // required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "audio.primary.default",
     relative_install_path: "hw",
diff --git a/modules/audio_remote_submix/Android.bp b/modules/audio_remote_submix/Android.bp
index 53555f5..9523438 100644
--- a/modules/audio_remote_submix/Android.bp
+++ b/modules/audio_remote_submix/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "audio.r_submix.default",
     relative_install_path: "hw",
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index b43a44d..103f57d 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -196,7 +196,6 @@
     struct timespec record_start_time;
     // how many frames have been requested to be read
     uint64_t read_counter_frames;
-    uint64_t read_counter_frames_since_standby;
 
 #if ENABLE_LEGACY_INPUT_OPEN
     // Number of references to this input stream.
@@ -676,8 +675,7 @@
 {
     const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
             const_cast<struct audio_stream *>(stream));
-    audio_channel_mask_t channel_mask =
-            out->dev->routes[out->route_handle].config.output_channel_mask;
+    uint32_t channel_mask = out->dev->routes[out->route_handle].config.output_channel_mask;
     SUBMIX_ALOGV("out_get_channels() returns %08x", channel_mask);
     return channel_mask;
 }
@@ -837,7 +835,7 @@
         sp<MonoPipeReader> source = rsxadev->routes[out->route_handle].rsxSource;
         const struct submix_stream_in *in = rsxadev->routes[out->route_handle].input;
         const bool dont_block = (in == NULL)
-                || (in->input_standby && (in->read_counter_frames_since_standby != 0));
+                || (in->input_standby && (in->read_counter_frames != 0));
         if (dont_block && availableToWrite < frames) {
             static uint8_t flush_buffer[64];
             const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size;
@@ -1142,12 +1140,11 @@
         // or when we start recording silence, and reset projected time
         int rc = clock_gettime(CLOCK_MONOTONIC, &in->record_start_time);
         if (rc == 0) {
-            in->read_counter_frames_since_standby = 0;
+            in->read_counter_frames = 0;
         }
     }
 
     in->read_counter_frames += frames_to_read;
-    in->read_counter_frames_since_standby += frames_to_read;
     size_t remaining_frames = frames_to_read;
 
     {
@@ -1326,12 +1323,12 @@
             record_duration.tv_nsec += 1000000000;
         }
 
-        // read_counter_frames_since_standby contains the number of frames that have been read since
-        // the beginning of recording (including this call): it's converted to usec and compared to
+        // read_counter_frames contains the number of frames that have been read since the
+        // beginning of recording (including this call): it's converted to usec and compared to
         // how long we've been recording for, which gives us how long we must wait to sync the
         // projected recording time, and the observed recording time.
         long projected_vs_observed_offset_us =
-                ((int64_t)(in->read_counter_frames_since_standby
+                ((int64_t)(in->read_counter_frames
                             - (record_duration.tv_sec*sample_rate)))
                         * 1000000 / sample_rate
                 - (record_duration.tv_nsec / 1000);
@@ -1355,37 +1352,6 @@
     return 0;
 }
 
-static int in_get_capture_position(const struct audio_stream_in *stream,
-                                   int64_t *frames, int64_t *time)
-{
-    if (stream == NULL || frames == NULL || time == NULL) {
-        return -EINVAL;
-    }
-
-    struct submix_stream_in * const in = audio_stream_in_get_submix_stream_in(
-            (struct audio_stream_in*)stream);
-    struct submix_audio_device * const rsxadev = in->dev;
-
-    pthread_mutex_lock(&rsxadev->lock);
-    sp<MonoPipeReader> source = rsxadev->routes[in->route_handle].rsxSource;
-    if (source == NULL) {
-        ALOGW("%s called on released input", __FUNCTION__);
-        pthread_mutex_unlock(&rsxadev->lock);
-        return -ENODEV;
-    }
-    *frames = in->read_counter_frames;
-    const ssize_t frames_in_pipe = source->availableToRead();
-    pthread_mutex_unlock(&rsxadev->lock);
-    if (frames_in_pipe > 0) {
-        *frames += frames_in_pipe;
-    }
-
-    struct timespec timestamp;
-    clock_gettime(CLOCK_MONOTONIC, &timestamp);
-    *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
-    return 0;
-}
-
 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
 {
     (void)stream;
@@ -1704,7 +1670,6 @@
         in->stream.set_gain = in_set_gain;
         in->stream.read = in_read;
         in->stream.get_input_frames_lost = in_get_input_frames_lost;
-        in->stream.get_capture_position = in_get_capture_position;
 
         in->dev = rsxadev;
 #if LOG_STREAMS_TO_FILES
@@ -1714,7 +1679,6 @@
 
     // Initialize the input stream.
     in->read_counter_frames = 0;
-    in->read_counter_frames_since_standby = 0;
     in->input_standby = true;
     if (rsxadev->routes[route_idx].output != NULL) {
         in->output_standby_rec_thr = rsxadev->routes[route_idx].output->output_standby;
diff --git a/modules/audio_remote_submix/tests/Android.bp b/modules/audio_remote_submix/tests/Android.bp
index 490a402..8e4d42d 100644
--- a/modules/audio_remote_submix/tests/Android.bp
+++ b/modules/audio_remote_submix/tests/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_test {
     name: "r_submix_tests",
 
diff --git a/modules/camera/3_0/Android.bp b/modules/camera/3_0/Android.bp
index d8aac4f..6d6d1d7 100644
--- a/modules/camera/3_0/Android.bp
+++ b/modules/camera/3_0/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "camera.default",
     relative_install_path: "hw",
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index aa23097..0a11f68 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -88,14 +88,12 @@
 # ==============================================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := camera.v4l2
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_CFLAGS += $(v4l2_cflags)
 LOCAL_SHARED_LIBRARIES := $(v4l2_shared_libs)
-LOCAL_HEADER_LIBRARIES := libgtest_prod_headers
-LOCAL_STATIC_LIBRARIES := $(v4l2_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+  libgtest_prod \
+  $(v4l2_static_libs) \
 
 LOCAL_C_INCLUDES += $(v4l2_c_includes)
 LOCAL_SRC_FILES := $(v4l2_src_files)
@@ -105,9 +103,6 @@
 # ==============================================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := camera.v4l2_test
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
 LOCAL_CFLAGS += $(v4l2_cflags)
 LOCAL_SHARED_LIBRARIES := $(v4l2_shared_libs)
 LOCAL_STATIC_LIBRARIES := \
diff --git a/modules/consumerir/Android.bp b/modules/consumerir/Android.bp
index f33e4e5..4f700c2 100644
--- a/modules/consumerir/Android.bp
+++ b/modules/consumerir/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "consumerir.default",
     relative_install_path: "hw",
diff --git a/modules/fingerprint/Android.bp b/modules/fingerprint/Android.bp
index 5c95374..22648b1 100644
--- a/modules/fingerprint/Android.bp
+++ b/modules/fingerprint/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "fingerprint.default",
     relative_install_path: "hw",
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index 439c95d..ff5808d 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -31,9 +31,6 @@
 LOCAL_HEADER_LIBRARIES := libhardware_headers
 
 LOCAL_MODULE := gralloc.default
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
 LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
 ifeq ($(TARGET_USE_PAN_DISPLAY),true)
 LOCAL_CFLAGS += -DUSE_PAN_DISPLAY=1
diff --git a/modules/hwcomposer/Android.bp b/modules/hwcomposer/Android.bp
index 6a864c8..4f429be 100644
--- a/modules/hwcomposer/Android.bp
+++ b/modules/hwcomposer/Android.bp
@@ -14,15 +14,6 @@
 
 // HAL module implemenation stored in
 // hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "hwcomposer.default",
     relative_install_path: "hw",
diff --git a/modules/input/evdev/Android.bp b/modules/input/evdev/Android.bp
index 9817c73..26e711f 100644
--- a/modules/input/evdev/Android.bp
+++ b/modules/input/evdev/Android.bp
@@ -13,15 +13,6 @@
 // limitations under the License.
 
 // Evdev module implementation
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "libinput_evdev",
 
@@ -36,7 +27,6 @@
         "SwitchInputMapper.cpp",
     ],
 
-    header_libs: ["jni_headers"],
     shared_libs: [
         "libhardware_legacy",
         "liblog",
diff --git a/modules/input/evdev/SwitchInputMapper.cpp b/modules/input/evdev/SwitchInputMapper.cpp
index 028fc72..1b2e749 100644
--- a/modules/input/evdev/SwitchInputMapper.cpp
+++ b/modules/input/evdev/SwitchInputMapper.cpp
@@ -49,9 +49,9 @@
     {SW_LINEIN_INSERT, INPUT_USAGE_SWITCH_UNKNOWN},
     {SW_MUTE_DEVICE, INPUT_USAGE_SWITCH_UNKNOWN},
     {SW_PEN_INSERTED, INPUT_USAGE_SWITCH_UNKNOWN},
-    {SW_MACHINE_COVER, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x11 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x12 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
+    {SW_HPHL_OVERCURRENT, INPUT_USAGE_SWITCH_UNKNOWN},
+    {SW_HPHR_OVERCURRENT, INPUT_USAGE_SWITCH_UNKNOWN},
+    {SW_UNSUPPORT_INSERT, INPUT_USAGE_SWITCH_UNKNOWN},
     {0x13 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
     {0x14 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
     {0x15 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
@@ -59,21 +59,9 @@
     {0x17 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
     {0x18 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
     {0x19 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1a /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1b /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1c /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1d /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1e /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x1f /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
-    {0x20 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN},
+    {SW_MAX, INPUT_USAGE_SWITCH_UNKNOWN},
 };
 
-static_assert(SW_MAX == SW_MACHINE_COVER, "SW_MAX is not SW_MACHINE_COVER");
-
-// This is the max value that any kernel has ever used. The v5.4 kernels
-// increased SW_MAX to 0x20, while v5.8 decreased the value to 0x10.
-static constexpr int32_t kMaxNumInputCodes = 0x21;
-
 SwitchInputMapper::SwitchInputMapper()
     : InputMapper() {
     // If this gets larger than 64, then the mSwitchValues and mUpdatedSwitchMask
@@ -83,9 +71,9 @@
 
 bool SwitchInputMapper::configureInputReport(InputDeviceNode* devNode,
         InputReportDefinition* report) {
-    InputUsage usages[kMaxNumInputCodes];
+    InputUsage usages[SW_CNT];
     int numUsages = 0;
-    for (int32_t i = 0; i < kMaxNumInputCodes; ++i) {
+    for (int32_t i = 0; i < SW_CNT; ++i) {
         if (devNode->hasSwitch(codeMap[i].scancode)) {
             usages[numUsages++] = codeMap[i].usage;
         }
@@ -117,7 +105,7 @@
 
 void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
     ALOGV("processing switch event. code=%" PRId32 ", value=%" PRId32, switchCode, switchValue);
-    if (switchCode >= 0 && switchCode < kMaxNumInputCodes) {
+    if (switchCode >= 0 && switchCode < SW_CNT) {
         if (switchValue) {
             mSwitchValues.markBit(switchCode);
         } else {
diff --git a/modules/local_time/Android.bp b/modules/local_time/Android.bp
index a4101c0..9f140b3 100644
--- a/modules/local_time/Android.bp
+++ b/modules/local_time/Android.bp
@@ -21,15 +21,6 @@
 // seen in libhardware/hardware.c
 //
 // The format of the name is local_time.<hardware>.so
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "local_time.default",
     relative_install_path: "hw",
diff --git a/modules/nfc-nci/Android.bp b/modules/nfc-nci/Android.bp
index 31d89aa..282e925 100644
--- a/modules/nfc-nci/Android.bp
+++ b/modules/nfc-nci/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "nfc_nci.default",
     relative_install_path: "hw",
diff --git a/modules/nfc/Android.bp b/modules/nfc/Android.bp
index 61fe1b8..7c69f11 100644
--- a/modules/nfc/Android.bp
+++ b/modules/nfc/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "nfc.default",
     relative_install_path: "hw",
diff --git a/modules/power/Android.bp b/modules/power/Android.bp
index 4abcf37..6b0b31f 100644
--- a/modules/power/Android.bp
+++ b/modules/power/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "power.default",
     relative_install_path: "hw",
diff --git a/modules/radio/Android.bp b/modules/radio/Android.bp
index 7240869..7f98f0d 100644
--- a/modules/radio/Android.bp
+++ b/modules/radio/Android.bp
@@ -13,15 +13,6 @@
 // limitations under the License.
 
 // Stub radio HAL module, used for tests
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "radio.fm.default",
     relative_install_path: "hw",
diff --git a/modules/sensors/Android.bp b/modules/sensors/Android.bp
index 61590a5..3d14bdf 100644
--- a/modules/sensors/Android.bp
+++ b/modules/sensors/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_static {
     name: "multihal",
     vendor: true,
diff --git a/modules/sensors/Android.mk b/modules/sensors/Android.mk
index 69889de..2becc97 100644
--- a/modules/sensors/Android.mk
+++ b/modules/sensors/Android.mk
@@ -21,9 +21,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := sensors.$(TARGET_DEVICE)
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
 
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_PROPRIETARY_MODULE := true
diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp
index 1ebc04d..214d97c 100644
--- a/modules/sensors/dynamic_sensor/Android.bp
+++ b/modules/sensors/dynamic_sensor/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_defaults {
     name: "dynamic_sensor_defaults",
 
diff --git a/modules/sensors/dynamic_sensor/HidUtils/Android.bp b/modules/sensors/dynamic_sensor/HidUtils/Android.bp
index bbed032..0eb43f8 100644
--- a/modules/sensors/dynamic_sensor/HidUtils/Android.bp
+++ b/modules/sensors/dynamic_sensor/HidUtils/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_defaults {
     name: "hid_defaults",
     cflags: [
diff --git a/modules/soundtrigger/Android.bp b/modules/soundtrigger/Android.bp
index 86cc593..aa5e804 100644
--- a/modules/soundtrigger/Android.bp
+++ b/modules/soundtrigger/Android.bp
@@ -13,15 +13,6 @@
 // limitations under the License.
 
 // Stub sound_trigger HAL module, used for tests
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "sound_trigger.stub.default",
     relative_install_path: "hw",
diff --git a/modules/thermal/Android.bp b/modules/thermal/Android.bp
index 9ac84d7..ab5c408 100644
--- a/modules/thermal/Android.bp
+++ b/modules/thermal/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "thermal.default",
     relative_install_path: "hw",
diff --git a/modules/tv_input/Android.bp b/modules/tv_input/Android.bp
index 13dd301..b9d8afa 100644
--- a/modules/tv_input/Android.bp
+++ b/modules/tv_input/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "tv_input.default",
     relative_install_path: "hw",
diff --git a/modules/usbaudio/Android.bp b/modules/usbaudio/Android.bp
index 0be27c3..c7d403f 100644
--- a/modules/usbaudio/Android.bp
+++ b/modules/usbaudio/Android.bp
@@ -12,43 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
-cc_defaults {
-    name: "audio.usb_defaults",
+cc_library_shared {
+    name: "audio.usb.default",
     relative_install_path: "hw",
     vendor: true,
     srcs: ["audio_hal.c"],
     shared_libs: [
         "liblog",
         "libcutils",
+        "libtinyalsa",
         "libaudioutils",
+        "libalsautils",
     ],
     cflags: ["-Wno-unused-parameter"],
     header_libs: ["libhardware_headers"],
 }
-
-cc_library_shared {
-    name: "audio.usb.default",
-    defaults: ["audio.usb_defaults"],
-    shared_libs: [
-        "libtinyalsa",
-        "libalsautils",
-    ],
-}
-
-cc_library_shared {
-    name: "audio.usbv2.default",
-    defaults: ["audio.usb_defaults"],
-    shared_libs: [
-        "libtinyalsav2",
-        "libalsautilsv2",
-    ],
-}
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index 39c0fb5..a19a0ae 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -22,7 +22,6 @@
 #include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <string.h>
 #include <sys/time.h>
 #include <unistd.h>
 
@@ -69,8 +68,6 @@
     bool mic_muted;
 
     int32_t inputs_open; /* number of input streams currently open. */
-
-    audio_patch_handle_t next_patch_handle; // Increase 1 when create audio patch
 };
 
 struct stream_lock {
@@ -78,12 +75,6 @@
     pthread_mutex_t pre_lock;           /* acquire before lock to avoid DOS by playback thread */
 };
 
-struct alsa_device_info {
-    alsa_device_profile profile;        /* The profile of the ALSA device */
-    alsa_device_proxy proxy;            /* The state */
-    struct listnode list_node;
-};
-
 struct stream_out {
     struct audio_stream_out stream;
 
@@ -93,7 +84,10 @@
 
     struct audio_device *adev;           /* hardware information - only using this for the lock */
 
-    struct listnode alsa_devices;       /* The ALSA devices connected to the stream. */
+    alsa_device_profile profile;        /* The profile of the ALSA device connected to the stream.
+                                         */
+
+    alsa_device_proxy proxy;            /* state of the stream */
 
     unsigned hal_channel_count;         /* channel count exposed to AudioFlinger.
                                          * This may differ from the device channel count when
@@ -112,12 +106,6 @@
                                          * they could come from here too if
                                          * there was a previous conversion */
     size_t conversion_buffer_size;      /* in bytes */
-
-    struct pcm_config config;
-
-    audio_io_handle_t handle; // Unique constant for a stream
-
-    audio_patch_handle_t patch_handle; // Patch handle for this stream
 };
 
 struct stream_in {
@@ -129,7 +117,10 @@
 
     struct audio_device *adev;           /* hardware information - only using this for the lock */
 
-    struct listnode alsa_devices;       /* The ALSA devices connected to the stream. */
+    alsa_device_profile profile;        /* The profile of the ALSA device connected to the stream.
+                                         */
+
+    alsa_device_proxy proxy;            /* state of the stream */
 
     unsigned hal_channel_count;         /* channel count exposed to AudioFlinger.
                                          * This may differ from the device channel count when
@@ -149,80 +140,8 @@
                                          * they could come from here too if
                                          * there was a previous conversion */
     size_t conversion_buffer_size;      /* in bytes */
-
-    struct pcm_config config;
-
-    audio_io_handle_t handle; // Unique identifier for a stream
-
-    audio_patch_handle_t patch_handle; // Patch handle for this stream
 };
 
-// Map channel count to output channel mask
-static const audio_channel_mask_t OUT_CHANNEL_MASKS_MAP[FCC_24 + 1] = {
-    [0] = AUDIO_CHANNEL_NONE,  // == 0 (so this line is optional and could be omitted)
-                               // != AUDIO_CHANNEL_INVALID == 0xC0000000u
-
-    [1] = AUDIO_CHANNEL_OUT_MONO,
-    [2] = AUDIO_CHANNEL_OUT_STEREO,
-    [3] = AUDIO_CHANNEL_OUT_2POINT1,
-    [4] = AUDIO_CHANNEL_OUT_QUAD,
-    [5] = AUDIO_CHANNEL_OUT_PENTA,
-    [6] = AUDIO_CHANNEL_OUT_5POINT1,
-    [7] = AUDIO_CHANNEL_OUT_6POINT1,
-    [8] = AUDIO_CHANNEL_OUT_7POINT1,
-
-    [9 ... 11] = AUDIO_CHANNEL_NONE,  // == 0 (so this line is optional and could be omitted).
-
-    [12] = AUDIO_CHANNEL_OUT_7POINT1POINT4,
-
-    [13 ... 23] = AUDIO_CHANNEL_NONE,  //  == 0 (so this line is optional and could be omitted).
-
-    [24] = AUDIO_CHANNEL_OUT_22POINT2,
-};
-static const int OUT_CHANNEL_MASKS_SIZE = AUDIO_ARRAY_SIZE(OUT_CHANNEL_MASKS_MAP);
-
-// Map channel count to input channel mask
-static const audio_channel_mask_t IN_CHANNEL_MASKS_MAP[] = {
-    AUDIO_CHANNEL_NONE,       /* 0 */
-    AUDIO_CHANNEL_IN_MONO,    /* 1 */
-    AUDIO_CHANNEL_IN_STEREO,  /* 2 */
-    /* channel counts greater than this are not considered */
-};
-static const int IN_CHANNEL_MASKS_SIZE = AUDIO_ARRAY_SIZE(IN_CHANNEL_MASKS_MAP);
-
-// Map channel count to index mask
-static const audio_channel_mask_t CHANNEL_INDEX_MASKS_MAP[FCC_24 + 1] = {
-    [0] = AUDIO_CHANNEL_NONE,  // == 0 (so this line is optional and could be omitted).
-
-    [1] = AUDIO_CHANNEL_INDEX_MASK_1,
-    [2] = AUDIO_CHANNEL_INDEX_MASK_2,
-    [3] = AUDIO_CHANNEL_INDEX_MASK_3,
-    [4] = AUDIO_CHANNEL_INDEX_MASK_4,
-    [5] = AUDIO_CHANNEL_INDEX_MASK_5,
-    [6] = AUDIO_CHANNEL_INDEX_MASK_6,
-    [7] = AUDIO_CHANNEL_INDEX_MASK_7,
-    [8] = AUDIO_CHANNEL_INDEX_MASK_8,
-
-    [9] = AUDIO_CHANNEL_INDEX_MASK_9,
-    [10] = AUDIO_CHANNEL_INDEX_MASK_10,
-    [11] = AUDIO_CHANNEL_INDEX_MASK_11,
-    [12] = AUDIO_CHANNEL_INDEX_MASK_12,
-    [13] = AUDIO_CHANNEL_INDEX_MASK_13,
-    [14] = AUDIO_CHANNEL_INDEX_MASK_14,
-    [15] = AUDIO_CHANNEL_INDEX_MASK_15,
-    [16] = AUDIO_CHANNEL_INDEX_MASK_16,
-
-    [17] = AUDIO_CHANNEL_INDEX_MASK_17,
-    [18] = AUDIO_CHANNEL_INDEX_MASK_18,
-    [19] = AUDIO_CHANNEL_INDEX_MASK_19,
-    [20] = AUDIO_CHANNEL_INDEX_MASK_20,
-    [21] = AUDIO_CHANNEL_INDEX_MASK_21,
-    [22] = AUDIO_CHANNEL_INDEX_MASK_22,
-    [23] = AUDIO_CHANNEL_INDEX_MASK_23,
-    [24] = AUDIO_CHANNEL_INDEX_MASK_24,
-};
-static const int CHANNEL_INDEX_MASKS_SIZE = AUDIO_ARRAY_SIZE(CHANNEL_INDEX_MASKS_MAP);
-
 /*
  * Locking Helpers
  */
@@ -239,9 +158,6 @@
 }
 
 static void stream_lock(struct stream_lock *lock) {
-    if (lock == NULL) {
-        return;
-    }
     pthread_mutex_lock(&lock->pre_lock);
     pthread_mutex_lock(&lock->lock);
     pthread_mutex_unlock(&lock->pre_lock);
@@ -275,52 +191,13 @@
     device_unlock(adev);
 }
 
-static struct stream_out* adev_get_stream_out_by_io_handle_l(
-        struct audio_device* adev, audio_io_handle_t handle) {
-    struct listnode *node;
-    list_for_each (node, &adev->output_stream_list) {
-        struct stream_out *out = node_to_item(node, struct stream_out, list_node);
-        if (out->handle == handle) {
-            return out;
-        }
-    }
-    return NULL;
-}
+static void adev_remove_stream_from_list(
+    struct audio_device* adev, struct listnode* stream_node) {
+    device_lock(adev);
 
-static struct stream_in* adev_get_stream_in_by_io_handle_l(
-        struct audio_device* adev, audio_io_handle_t handle) {
-    struct listnode *node;
-    list_for_each (node, &adev->input_stream_list) {
-        struct stream_in *in = node_to_item(node, struct stream_in, list_node);
-        if (in->handle == handle) {
-            return in;
-        }
-    }
-    return NULL;
-}
+    list_remove(stream_node);
 
-static struct stream_out* adev_get_stream_out_by_patch_handle_l(
-        struct audio_device* adev, audio_patch_handle_t patch_handle) {
-    struct listnode *node;
-    list_for_each (node, &adev->output_stream_list) {
-        struct stream_out *out = node_to_item(node, struct stream_out, list_node);
-        if (out->patch_handle == patch_handle) {
-            return out;
-        }
-    }
-    return NULL;
-}
-
-static struct stream_in* adev_get_stream_in_by_patch_handle_l(
-        struct audio_device* adev, audio_patch_handle_t patch_handle) {
-    struct listnode *node;
-    list_for_each (node, &adev->input_stream_list) {
-        struct stream_in *in = node_to_item(node, struct stream_in, list_node);
-        if (in->patch_handle == patch_handle) {
-            return in;
-        }
-    }
-    return NULL;
+    device_unlock(adev);
 }
 
 /*
@@ -401,65 +278,6 @@
     return result_str;
 }
 
-static audio_format_t audio_format_from(enum pcm_format format)
-{
-    switch (format) {
-    case PCM_FORMAT_S16_LE:
-        return AUDIO_FORMAT_PCM_16_BIT;
-    case PCM_FORMAT_S32_LE:
-        return AUDIO_FORMAT_PCM_32_BIT;
-    case PCM_FORMAT_S8:
-        return AUDIO_FORMAT_PCM_8_BIT;
-    case PCM_FORMAT_S24_LE:
-        return AUDIO_FORMAT_PCM_8_24_BIT;
-    case PCM_FORMAT_S24_3LE:
-        return AUDIO_FORMAT_PCM_24_BIT_PACKED;
-    default:
-        return AUDIO_FORMAT_INVALID;
-    }
-}
-
-static unsigned int populate_channel_mask_from_profile(const alsa_device_profile* profile,
-                                                       bool is_output,
-                                                       audio_channel_mask_t channel_masks[])
-{
-    unsigned int num_channel_masks = 0;
-    const audio_channel_mask_t* channel_masks_map =
-            is_output ? OUT_CHANNEL_MASKS_MAP : IN_CHANNEL_MASKS_MAP;
-    int channel_masks_size = is_output ? OUT_CHANNEL_MASKS_SIZE : IN_CHANNEL_MASKS_SIZE;
-    if (channel_masks_size > FCC_LIMIT + 1) {
-        channel_masks_size = FCC_LIMIT + 1;
-    }
-    unsigned int channel_count = 0;
-    for (size_t i = 0; i < min(channel_masks_size, AUDIO_PORT_MAX_CHANNEL_MASKS) &&
-            (channel_count = profile->channel_counts[i]) != 0 &&
-            num_channel_masks < AUDIO_PORT_MAX_CHANNEL_MASKS; ++i) {
-        if (channel_count < channel_masks_size &&
-            channel_masks_map[channel_count] != AUDIO_CHANNEL_NONE) {
-            channel_masks[num_channel_masks++] = channel_masks_map[channel_count];
-            if (num_channel_masks >= AUDIO_PORT_MAX_CHANNEL_MASKS) {
-                break;
-            }
-        }
-        if (channel_count < CHANNEL_INDEX_MASKS_SIZE &&
-            CHANNEL_INDEX_MASKS_MAP[channel_count] != AUDIO_CHANNEL_NONE) {
-            channel_masks[num_channel_masks++] = CHANNEL_INDEX_MASKS_MAP[channel_count];
-        }
-    }
-    return num_channel_masks;
-}
-
-static unsigned int populate_sample_rates_from_profile(const alsa_device_profile* profile,
-                                                       unsigned int sample_rates[])
-{
-    unsigned int num_sample_rates = 0;
-    for (;num_sample_rates < min(MAX_PROFILE_SAMPLE_RATES, AUDIO_PORT_MAX_SAMPLING_RATES) &&
-            profile->sample_rates[num_sample_rates] != 0; num_sample_rates++) {
-        sample_rates[num_sample_rates] = profile->sample_rates[num_sample_rates];
-    }
-    return num_sample_rates;
-}
-
 /*
  * HAl Functions
  */
@@ -468,106 +286,12 @@
  * following order: hw device > out stream
  */
 
-static struct alsa_device_info* stream_get_first_alsa_device(const struct listnode *alsa_devices) {
-    if (list_empty(alsa_devices)) {
-        return NULL;
-    }
-    return node_to_item(list_head(alsa_devices), struct alsa_device_info, list_node);
-}
-
-/**
- * Must be called with holding the stream's lock.
- */
-static void stream_standby_l(struct listnode *alsa_devices, bool *standby)
-{
-    if (!*standby) {
-        struct listnode *node;
-        list_for_each (node, alsa_devices) {
-            struct alsa_device_info *device_info =
-                    node_to_item(node, struct alsa_device_info, list_node);
-            proxy_close(&device_info->proxy);
-        }
-        *standby = true;
-    }
-}
-
-static void stream_clear_devices(struct listnode *alsa_devices)
-{
-    struct listnode *node, *temp;
-    struct alsa_device_info *device_info = NULL;
-    list_for_each_safe (node, temp, alsa_devices) {
-        device_info = node_to_item(node, struct alsa_device_info, list_node);
-        if (device_info != NULL) {
-            list_remove(&device_info->list_node);
-            free(device_info);
-        }
-    }
-}
-
-static int stream_set_new_devices(struct pcm_config *config,
-                                  struct listnode *alsa_devices,
-                                  unsigned int num_devices,
-                                  const int cards[],
-                                  const int devices[],
-                                  int direction)
-{
-    int status = 0;
-    stream_clear_devices(alsa_devices);
-
-    for (unsigned int i = 0; i < num_devices; ++i) {
-        struct alsa_device_info *device_info =
-                (struct alsa_device_info *) calloc(1, sizeof(struct alsa_device_info));
-        profile_init(&device_info->profile, direction);
-        device_info->profile.card = cards[i];
-        device_info->profile.device = devices[i];
-        status = profile_read_device_info(&device_info->profile) ? 0 : -EINVAL;
-        if (status != 0) {
-            ALOGE("%s failed to read device info card=%d;device=%d",
-                    __func__, cards[i], devices[i]);
-            goto exit;
-        }
-        status = proxy_prepare(&device_info->proxy, &device_info->profile, config);
-        if (status != 0) {
-            ALOGE("%s failed to prepare device card=%d;device=%d",
-                    __func__, cards[i], devices[i]);
-            goto exit;
-        }
-        list_add_tail(alsa_devices, &device_info->list_node);
-    }
-
-exit:
-    if (status != 0) {
-        stream_clear_devices(alsa_devices);
-    }
-    return status;
-}
-
-static void stream_dump_alsa_devices(const struct listnode *alsa_devices, int fd) {
-    struct listnode *node;
-    size_t i = 0;
-    list_for_each(node, alsa_devices) {
-        struct alsa_device_info *device_info =
-                node_to_item(node, struct alsa_device_info, list_node);
-        dprintf(fd, "Output Profile %zu:\n", i);
-        profile_dump(&device_info->profile, fd);
-
-        dprintf(fd, "Output Proxy %zu:\n", i);
-        proxy_dump(&device_info->proxy, fd);
-    }
-}
-
 /*
  * OUT functions
  */
 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
 {
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(
-            &((struct stream_out*)stream)->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return 0;
-    }
-    uint32_t rate = proxy_get_sample_rate(&device_info->proxy);
+    uint32_t rate = proxy_get_sample_rate(&((struct stream_out*)stream)->proxy);
     ALOGV("out_get_sample_rate() = %d", rate);
     return rate;
 }
@@ -580,12 +304,9 @@
 static size_t out_get_buffer_size(const struct audio_stream *stream)
 {
     const struct stream_out* out = (const struct stream_out*)stream;
-    const struct alsa_device_info* device_info = stream_get_first_alsa_device(&out->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return 0;
-    }
-    return proxy_get_period_size(&device_info->proxy) * audio_stream_out_frame_size(&(out->stream));
+    size_t buffer_size =
+        proxy_get_period_size(&out->proxy) * audio_stream_out_frame_size(&(out->stream));
+    return buffer_size;
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
@@ -600,13 +321,8 @@
      * Relies on the framework to provide data in the specified format.
      * This could change in the future.
      */
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(
-            &((struct stream_out*)stream)->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return AUDIO_FORMAT_DEFAULT;
-    }
-    audio_format_t format = audio_format_from_pcm_format(proxy_get_format(&device_info->proxy));
+    alsa_device_proxy * proxy = &((struct stream_out*)stream)->proxy;
+    audio_format_t format = audio_format_from_pcm_format(proxy_get_format(proxy));
     return format;
 }
 
@@ -620,9 +336,10 @@
     struct stream_out *out = (struct stream_out *)stream;
 
     stream_lock(&out->lock);
-    device_lock(out->adev);
-    stream_standby_l(&out->alsa_devices, &out->standby);
-    device_unlock(out->adev);
+    if (!out->standby) {
+        proxy_close(&out->proxy);
+        out->standby = true;
+    }
     stream_unlock(&out->lock);
     return 0;
 }
@@ -631,44 +348,67 @@
     const struct stream_out* out_stream = (const struct stream_out*) stream;
 
     if (out_stream != NULL) {
-        stream_dump_alsa_devices(&out_stream->alsa_devices, fd);
+        dprintf(fd, "Output Profile:\n");
+        profile_dump(&out_stream->profile, fd);
+
+        dprintf(fd, "Output Proxy:\n");
+        proxy_dump(&out_stream->proxy, fd);
     }
 
     return 0;
 }
 
-static int out_set_parameters(struct audio_stream *stream __unused, const char *kvpairs)
+static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
 {
     ALOGV("out_set_parameters() keys:%s", kvpairs);
 
-    // The set parameters here only matters when the routing devices are changed.
-    // When the device version is not less than 3.0, the framework will use create
-    // audio patch API instead of set parameters to chanage audio routing.
-    return 0;
+    struct stream_out *out = (struct stream_out *)stream;
+
+    int ret_value = 0;
+    int card = -1;
+    int device = -1;
+
+    if (!parse_card_device_params(kvpairs, &card, &device)) {
+        // nothing to do
+        return ret_value;
+    }
+
+    stream_lock(&out->lock);
+    if (!profile_is_cached_for(&out->profile, card, device)) {
+        /* cannot read pcm device info if playback is active */
+        if (!out->standby)
+            ret_value = -ENOSYS;
+        else {
+            int saved_card = out->profile.card;
+            int saved_device = out->profile.device;
+            out->profile.card = card;
+            out->profile.device = device;
+            ret_value = profile_read_device_info(&out->profile) ? 0 : -EINVAL;
+            if (ret_value != 0) {
+                out->profile.card = saved_card;
+                out->profile.device = saved_device;
+            }
+        }
+    }
+
+    stream_unlock(&out->lock);
+
+    return ret_value;
 }
 
 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
 {
     struct stream_out *out = (struct stream_out *)stream;
     stream_lock(&out->lock);
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&out->alsa_devices);
-    char *params_str = NULL;
-    if (device_info != NULL) {
-        params_str =  device_get_parameters(&device_info->profile, keys);
-    }
+    char * params_str =  device_get_parameters(&out->profile, keys);
     stream_unlock(&out->lock);
     return params_str;
 }
 
 static uint32_t out_get_latency(const struct audio_stream_out *stream)
 {
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(
-            &((struct stream_out*)stream)->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return 0;
-    }
-    return proxy_get_latency(&device_info->proxy);
+    alsa_device_proxy * proxy = &((struct stream_out*)stream)->proxy;
+    return proxy_get_latency(proxy);
 }
 
 static int out_set_volume(struct audio_stream_out *stream, float left, float right)
@@ -679,31 +419,9 @@
 /* must be called with hw device and output stream mutexes locked */
 static int start_output_stream(struct stream_out *out)
 {
-    int status = 0;
-    struct listnode *node;
-    list_for_each(node, &out->alsa_devices) {
-        struct alsa_device_info *device_info =
-                node_to_item(node, struct alsa_device_info, list_node);
-        ALOGV("start_output_stream(card:%d device:%d)",
-                device_info->profile.card, device_info->profile.device);
-        status = proxy_open(&device_info->proxy);
-        if (status != 0) {
-            ALOGE("%s failed to open device(card: %d device: %d)",
-                    __func__, device_info->profile.card, device_info->profile.device);
-            goto exit;
-        }
-    }
+    ALOGV("start_output_stream(card:%d device:%d)", out->profile.card, out->profile.device);
 
-exit:
-    if (status != 0) {
-        list_for_each(node, &out->alsa_devices) {
-            struct alsa_device_info *device_info =
-                    node_to_item(node, struct alsa_device_info, list_node);
-            proxy_close(&device_info->proxy);
-        }
-
-    }
-    return status;
+    return proxy_open(&out->proxy);
 }
 
 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes)
@@ -720,37 +438,32 @@
         out->standby = false;
     }
 
-    struct listnode* node;
-    list_for_each(node, &out->alsa_devices) {
-        struct alsa_device_info* device_info =
-                node_to_item(node, struct alsa_device_info, list_node);
-        alsa_device_proxy* proxy = &device_info->proxy;
-        const void * write_buff = buffer;
-        int num_write_buff_bytes = bytes;
-        const int num_device_channels = proxy_get_channel_count(proxy); /* what we told alsa */
-        const int num_req_channels = out->hal_channel_count; /* what we told AudioFlinger */
-        if (num_device_channels != num_req_channels) {
-            /* allocate buffer */
-            const size_t required_conversion_buffer_size =
-                     bytes * num_device_channels / num_req_channels;
-            if (required_conversion_buffer_size > out->conversion_buffer_size) {
-                out->conversion_buffer_size = required_conversion_buffer_size;
-                out->conversion_buffer = realloc(out->conversion_buffer,
-                                                 out->conversion_buffer_size);
-            }
-            /* convert data */
-            const audio_format_t audio_format = out_get_format(&(out->stream.common));
-            const unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
-            num_write_buff_bytes =
-                    adjust_channels(write_buff, num_req_channels,
-                                    out->conversion_buffer, num_device_channels,
-                                    sample_size_in_bytes, num_write_buff_bytes);
-            write_buff = out->conversion_buffer;
+    alsa_device_proxy* proxy = &out->proxy;
+    const void * write_buff = buffer;
+    int num_write_buff_bytes = bytes;
+    const int num_device_channels = proxy_get_channel_count(proxy); /* what we told alsa */
+    const int num_req_channels = out->hal_channel_count; /* what we told AudioFlinger */
+    if (num_device_channels != num_req_channels) {
+        /* allocate buffer */
+        const size_t required_conversion_buffer_size =
+                 bytes * num_device_channels / num_req_channels;
+        if (required_conversion_buffer_size > out->conversion_buffer_size) {
+            out->conversion_buffer_size = required_conversion_buffer_size;
+            out->conversion_buffer = realloc(out->conversion_buffer,
+                                             out->conversion_buffer_size);
         }
+        /* convert data */
+        const audio_format_t audio_format = out_get_format(&(out->stream.common));
+        const unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
+        num_write_buff_bytes =
+                adjust_channels(write_buff, num_req_channels,
+                                out->conversion_buffer, num_device_channels,
+                                sample_size_in_bytes, num_write_buff_bytes);
+        write_buff = out->conversion_buffer;
+    }
 
-        if (write_buff != NULL && num_write_buff_bytes != 0) {
-            proxy_write(proxy, write_buff, num_write_buff_bytes);
-        }
+    if (write_buff != NULL && num_write_buff_bytes != 0) {
+        proxy_write(&out->proxy, write_buff, num_write_buff_bytes);
     }
 
     stream_unlock(&out->lock);
@@ -778,9 +491,9 @@
     struct stream_out *out = (struct stream_out *)stream; // discard const qualifier
     stream_lock(&out->lock);
 
-    const struct alsa_device_info* device_info = stream_get_first_alsa_device(&out->alsa_devices);
-    const int ret = device_info == NULL ? -ENODEV :
-            proxy_get_presentation_position(&device_info->proxy, frames, timestamp);
+    const alsa_device_proxy *proxy = &out->proxy;
+    const int ret = proxy_get_presentation_position(proxy, frames, timestamp);
+
     stream_unlock(&out->lock);
     return ret;
 }
@@ -838,35 +551,30 @@
     out->stream.get_presentation_position = out_get_presentation_position;
     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
 
-    out->handle = handle;
-
     stream_lock_init(&out->lock);
 
     out->adev = (struct audio_device *)hw_dev;
 
-    list_init(&out->alsa_devices);
-    struct alsa_device_info *device_info =
-            (struct alsa_device_info *)calloc(1, sizeof(struct alsa_device_info));
-    profile_init(&device_info->profile, PCM_OUT);
+    profile_init(&out->profile, PCM_OUT);
 
     // build this to hand to the alsa_device_proxy
-    struct pcm_config proxy_config = {};
+    struct pcm_config proxy_config;
+    memset(&proxy_config, 0, sizeof(proxy_config));
 
     /* Pull out the card/device pair */
-    parse_card_device_params(address, &device_info->profile.card, &device_info->profile.device);
+    parse_card_device_params(address, &out->profile.card, &out->profile.device);
 
-    profile_read_device_info(&device_info->profile);
+    profile_read_device_info(&out->profile);
 
     int ret = 0;
 
     /* Rate */
     if (config->sample_rate == 0) {
-        proxy_config.rate = profile_get_default_sample_rate(&device_info->profile);
-    } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) {
+        proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&out->profile);
+    } else if (profile_is_sample_rate_valid(&out->profile, config->sample_rate)) {
         proxy_config.rate = config->sample_rate;
     } else {
-        proxy_config.rate = config->sample_rate =
-                profile_get_default_sample_rate(&device_info->profile);
+        proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&out->profile);
         ret = -EINVAL;
     }
 
@@ -877,14 +585,14 @@
 
     /* Format */
     if (config->format == AUDIO_FORMAT_DEFAULT) {
-        proxy_config.format = profile_get_default_format(&device_info->profile);
+        proxy_config.format = profile_get_default_format(&out->profile);
         config->format = audio_format_from_pcm_format(proxy_config.format);
     } else {
         enum pcm_format fmt = pcm_format_from_audio_format(config->format);
-        if (profile_is_format_valid(&device_info->profile, fmt)) {
+        if (profile_is_format_valid(&out->profile, fmt)) {
             proxy_config.format = fmt;
         } else {
-            proxy_config.format = profile_get_default_format(&device_info->profile);
+            proxy_config.format = profile_get_default_format(&out->profile);
             config->format = audio_format_from_pcm_format(proxy_config.format);
             ret = -EINVAL;
         }
@@ -894,7 +602,7 @@
     bool calc_mask = false;
     if (config->channel_mask == AUDIO_CHANNEL_NONE) {
         /* query case */
-        out->hal_channel_count = profile_get_default_channel_count(&device_info->profile);
+        out->hal_channel_count = profile_get_default_channel_count(&out->profile);
         calc_mask = true;
     } else {
         /* explicit case */
@@ -902,19 +610,19 @@
     }
 
     /* The Framework is currently limited to no more than this number of channels */
-    if (out->hal_channel_count > FCC_LIMIT) {
-        out->hal_channel_count = FCC_LIMIT;
+    if (out->hal_channel_count > FCC_8) {
+        out->hal_channel_count = FCC_8;
         calc_mask = true;
     }
 
     if (calc_mask) {
         /* need to calculate the mask from channel count either because this is the query case
-         * or the specified mask isn't valid for this device, or is more than the FW can handle */
+         * or the specified mask isn't valid for this device, or is more then the FW can handle */
         config->channel_mask = out->hal_channel_count <= FCC_2
-                /* position mask for mono and stereo*/
-                ? audio_channel_out_mask_from_count(out->hal_channel_count)
-                /* otherwise indexed */
-                : audio_channel_mask_for_index_assignment_from_count(out->hal_channel_count);
+            /* position mask for mono and stereo*/
+            ? audio_channel_out_mask_from_count(out->hal_channel_count)
+            /* otherwise indexed */
+            : audio_channel_mask_for_index_assignment_from_count(out->hal_channel_count);
     }
 
     out->hal_channel_mask = config->channel_mask;
@@ -923,11 +631,8 @@
     // if they differ, choose the "actual" number of channels *closest* to the "logical".
     // and store THAT in proxy_config.channels
     proxy_config.channels =
-            profile_get_closest_channel_count(&device_info->profile, out->hal_channel_count);
-    proxy_prepare(&device_info->proxy, &device_info->profile, &proxy_config);
-    out->config = proxy_config;
-
-    list_add_tail(&out->alsa_devices, &device_info->list_node);
+            profile_get_closest_channel_count(&out->profile, out->hal_channel_count);
+    proxy_prepare(&out->proxy, &out->profile, &proxy_config);
 
     /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger
      * So clear any errors that may have occurred above.
@@ -951,22 +656,21 @@
                                      struct audio_stream_out *stream)
 {
     struct stream_out *out = (struct stream_out *)stream;
+    ALOGV("adev_close_output_stream(c:%d d:%d)", out->profile.card, out->profile.device);
 
-    stream_lock(&out->lock);
     /* Close the pcm device */
-    stream_standby_l(&out->alsa_devices, &out->standby);
-    stream_clear_devices(&out->alsa_devices);
+    out_standby(&stream->common);
 
     free(out->conversion_buffer);
 
     out->conversion_buffer = NULL;
     out->conversion_buffer_size = 0;
 
+    adev_remove_stream_from_list(out->adev, &out->list_node);
+
     device_lock(out->adev);
-    list_remove(&out->list_node);
     out->adev->device_sample_rate = 0;
     device_unlock(out->adev);
-    stream_unlock(&out->lock);
 
     free(stream);
 }
@@ -983,13 +687,7 @@
  */
 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
 {
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(
-            &((const struct stream_in *)stream)->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return 0;
-    }
-    uint32_t rate = proxy_get_sample_rate(&device_info->proxy);
+    uint32_t rate = proxy_get_sample_rate(&((const struct stream_in *)stream)->proxy);
     ALOGV("in_get_sample_rate() = %d", rate);
     return rate;
 }
@@ -1003,12 +701,7 @@
 static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
     const struct stream_in * in = ((const struct stream_in*)stream);
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return 0;
-    }
-    return proxy_get_period_size(&device_info->proxy) * audio_stream_in_frame_size(&(in->stream));
+    return proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(in->stream));
 }
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
@@ -1019,13 +712,7 @@
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
 {
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(
-            &((const struct stream_in *)stream)->alsa_devices);
-    if (device_info == NULL) {
-        ALOGW("%s device info is null", __func__);
-        return AUDIO_FORMAT_DEFAULT;
-    }
-     alsa_device_proxy *proxy = &device_info->proxy;
+     alsa_device_proxy *proxy = &((struct stream_in*)stream)->proxy;
      audio_format_t format = audio_format_from_pcm_format(proxy_get_format(proxy));
      return format;
 }
@@ -1042,10 +729,12 @@
     struct stream_in *in = (struct stream_in *)stream;
 
     stream_lock(&in->lock);
-    device_lock(in->adev);
-    stream_standby_l(&in->alsa_devices, &in->standby);
-    device_unlock(in->adev);
+    if (!in->standby) {
+        proxy_close(&in->proxy);
+        in->standby = true;
+    }
     stream_unlock(&in->lock);
+
     return 0;
 }
 
@@ -1053,7 +742,11 @@
 {
   const struct stream_in* in_stream = (const struct stream_in*)stream;
   if (in_stream != NULL) {
-      stream_dump_alsa_devices(&in_stream->alsa_devices, fd);
+      dprintf(fd, "Input Profile:\n");
+      profile_dump(&in_stream->profile, fd);
+
+      dprintf(fd, "Input Proxy:\n");
+      proxy_dump(&in_stream->proxy, fd);
   }
 
   return 0;
@@ -1063,10 +756,42 @@
 {
     ALOGV("in_set_parameters() keys:%s", kvpairs);
 
-    // The set parameters here only matters when the routing devices are changed.
-    // When the device version higher than 3.0, the framework will use create_audio_patch
-    // API instead of set_parameters to change audio routing.
-    return 0;
+    struct stream_in *in = (struct stream_in *)stream;
+
+    int ret_value = 0;
+    int card = -1;
+    int device = -1;
+
+    if (!parse_card_device_params(kvpairs, &card, &device)) {
+        // nothing to do
+        return ret_value;
+    }
+
+    stream_lock(&in->lock);
+    device_lock(in->adev);
+
+    if (card >= 0 && device >= 0 && !profile_is_cached_for(&in->profile, card, device)) {
+        /* cannot read pcm device info if capture is active, or more than one open stream */
+        if (!in->standby || in->adev->inputs_open > 1)
+            ret_value = -ENOSYS;
+        else {
+            int saved_card = in->profile.card;
+            int saved_device = in->profile.device;
+            in->profile.card = card;
+            in->profile.device = device;
+            ret_value = profile_read_device_info(&in->profile) ? 0 : -EINVAL;
+            if (ret_value != 0) {
+                ALOGE("Can't read device profile. card:%d, device:%d", card, device);
+                in->profile.card = saved_card;
+                in->profile.device = saved_device;
+            }
+        }
+    }
+
+    device_unlock(in->adev);
+    stream_unlock(&in->lock);
+
+    return ret_value;
 }
 
 static char * in_get_parameters(const struct audio_stream *stream, const char *keys)
@@ -1074,11 +799,7 @@
     struct stream_in *in = (struct stream_in *)stream;
 
     stream_lock(&in->lock);
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-    char *params_str = NULL;
-    if (device_info != NULL) {
-        params_str =  device_get_parameters(&device_info->profile, keys);
-    }
+    char * params_str =  device_get_parameters(&in->profile, keys);
     stream_unlock(&in->lock);
 
     return params_str;
@@ -1102,15 +823,9 @@
 /* must be called with hw device and output stream mutexes locked */
 static int start_input_stream(struct stream_in *in)
 {
-    // Only care about the first device as only one input device is allowed.
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-    if (device_info == NULL) {
-        return -ENODEV;
-    }
+    ALOGV("start_input_stream(card:%d device:%d)", in->profile.card, in->profile.device);
 
-    ALOGV("start_input_stream(card:%d device:%d)",
-            device_info->profile.card, device_info->profile.device);
-    return proxy_open(&device_info->proxy);
+    return proxy_open(&in->proxy);
 }
 
 /* TODO mutex stuff here (see out_write) */
@@ -1132,18 +847,12 @@
         in->standby = false;
     }
 
-    // Only care about the first device as only one input device is allowed.
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-    if (device_info == NULL) {
-        return 0;
-    }
-
     /*
      * OK, we need to figure out how much data to read to be able to output the requested
      * number of bytes in the HAL format (16-bit, stereo).
      */
     num_read_buff_bytes = bytes;
-    int num_device_channels = proxy_get_channel_count(&device_info->proxy); /* what we told Alsa */
+    int num_device_channels = proxy_get_channel_count(&in->proxy); /* what we told Alsa */
     int num_req_channels = in->hal_channel_count; /* what we told AudioFlinger */
 
     if (num_device_channels != num_req_channels) {
@@ -1161,7 +870,7 @@
         read_buff = in->conversion_buffer;
     }
 
-    ret = proxy_read(&device_info->proxy, read_buff, num_read_buff_bytes);
+    ret = proxy_read(&in->proxy, read_buff, num_read_buff_bytes);
     if (ret == 0) {
         if (num_device_channels != num_req_channels) {
             // ALOGV("chans dev:%d req:%d", num_device_channels, num_req_channels);
@@ -1202,10 +911,8 @@
     struct stream_in *in = (struct stream_in *)stream; // discard const qualifier
     stream_lock(&in->lock);
 
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-
-    const int ret = device_info == NULL ? -ENODEV
-            : proxy_get_capture_position(&device_info->proxy, frames, time);
+    const alsa_device_proxy *proxy = &in->proxy;
+    const int ret = proxy_get_capture_position(proxy, frames, time);
 
     stream_unlock(&in->lock);
     return ret;
@@ -1284,18 +991,14 @@
     in->stream.set_microphone_direction = in_set_microphone_direction;
     in->stream.set_microphone_field_dimension = in_set_microphone_field_dimension;
 
-    in->handle = handle;
-
     stream_lock_init(&in->lock);
 
     in->adev = (struct audio_device *)hw_dev;
 
-    list_init(&in->alsa_devices);
-    struct alsa_device_info *device_info =
-            (struct alsa_device_info *)calloc(1, sizeof(struct alsa_device_info));
-    profile_init(&device_info->profile, PCM_IN);
+    profile_init(&in->profile, PCM_IN);
 
-    memset(&in->config, 0, sizeof(in->config));
+    struct pcm_config proxy_config;
+    memset(&proxy_config, 0, sizeof(proxy_config));
 
     int ret = 0;
     device_lock(in->adev);
@@ -1304,16 +1007,16 @@
 
     /* Check if an input stream is already open */
     if (num_open_inputs > 0) {
-        if (!profile_is_cached_for(&device_info->profile, card, device)) {
+        if (!profile_is_cached_for(&in->profile, card, device)) {
             ALOGW("%s fail - address card:%d device:%d doesn't match existing profile",
                     __func__, card, device);
             ret = -EINVAL;
         }
     } else {
         /* Read input profile only if necessary */
-        device_info->profile.card = card;
-        device_info->profile.device = device;
-        if (!profile_read_device_info(&device_info->profile)) {
+        in->profile.card = card;
+        in->profile.device = device;
+        if (!profile_read_device_info(&in->profile)) {
             ALOGW("%s fail - cannot read profile", __func__);
             ret = -EINVAL;
         }
@@ -1327,19 +1030,19 @@
     /* Rate */
     int request_config_rate = config->sample_rate;
     if (config->sample_rate == 0) {
-        config->sample_rate = profile_get_default_sample_rate(&device_info->profile);
+        config->sample_rate = profile_get_default_sample_rate(&in->profile);
     }
 
     if (in->adev->device_sample_rate != 0 &&   /* we are playing, so lock the rate if possible */
         in->adev->device_sample_rate >= RATELOCK_THRESHOLD) {/* but only for high sample rates */
         if (config->sample_rate != in->adev->device_sample_rate) {
-            unsigned highest_rate = profile_get_highest_sample_rate(&device_info->profile);
+            unsigned highest_rate = profile_get_highest_sample_rate(&in->profile);
             if (highest_rate == 0) {
                 ret = -EINVAL; /* error with device */
             } else {
-                in->config.rate = config->sample_rate =
+                proxy_config.rate = config->sample_rate =
                         min(highest_rate, in->adev->device_sample_rate);
-                if (request_config_rate != 0 && in->config.rate != config->sample_rate) {
+                if (request_config_rate != 0 && proxy_config.rate != config->sample_rate) {
                     /* Changing the requested rate */
                     ret = -EINVAL;
                 } else {
@@ -1348,25 +1051,24 @@
                 }
             }
         }
-    } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) {
-        in->config.rate = config->sample_rate;
+    } else if (profile_is_sample_rate_valid(&in->profile, config->sample_rate)) {
+        proxy_config.rate = config->sample_rate;
     } else {
-        in->config.rate = config->sample_rate =
-                profile_get_default_sample_rate(&device_info->profile);
+        proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&in->profile);
         ret = -EINVAL;
     }
 
     /* Format */
     if (config->format == AUDIO_FORMAT_DEFAULT) {
-        in->config.format = profile_get_default_format(&device_info->profile);
-        config->format = audio_format_from_pcm_format(in->config.format);
+        proxy_config.format = profile_get_default_format(&in->profile);
+        config->format = audio_format_from_pcm_format(proxy_config.format);
     } else {
         enum pcm_format fmt = pcm_format_from_audio_format(config->format);
-        if (profile_is_format_valid(&device_info->profile, fmt)) {
-            in->config.format = fmt;
+        if (profile_is_format_valid(&in->profile, fmt)) {
+            proxy_config.format = fmt;
         } else {
-            in->config.format = profile_get_default_format(&device_info->profile);
-            config->format = audio_format_from_pcm_format(in->config.format);
+            proxy_config.format = profile_get_default_format(&in->profile);
+            config->format = audio_format_from_pcm_format(proxy_config.format);
             ret = -EINVAL;
         }
     }
@@ -1375,7 +1077,7 @@
     bool calc_mask = false;
     if (config->channel_mask == AUDIO_CHANNEL_NONE) {
         /* query case */
-        in->hal_channel_count = profile_get_default_channel_count(&device_info->profile);
+        in->hal_channel_count = profile_get_default_channel_count(&in->profile);
         calc_mask = true;
     } else {
         /* explicit case */
@@ -1383,14 +1085,14 @@
     }
 
     /* The Framework is currently limited to no more than this number of channels */
-    if (in->hal_channel_count > FCC_LIMIT) {
-        in->hal_channel_count = FCC_LIMIT;
+    if (in->hal_channel_count > FCC_8) {
+        in->hal_channel_count = FCC_8;
         calc_mask = true;
     }
 
     if (calc_mask) {
         /* need to calculate the mask from channel count either because this is the query case
-         * or the specified mask isn't valid for this device, or is more than the FW can handle */
+         * or the specified mask isn't valid for this device, or is more then the FW can handle */
         in->hal_channel_mask = in->hal_channel_count <= FCC_2
             /* position mask for mono & stereo */
             ? audio_channel_in_mask_from_count(in->hal_channel_count)
@@ -1411,9 +1113,9 @@
         // Validate the "logical" channel count against support in the "actual" profile.
         // if they differ, choose the "actual" number of channels *closest* to the "logical".
         // and store THAT in proxy_config.channels
-        in->config.channels =
-                profile_get_closest_channel_count(&device_info->profile, in->hal_channel_count);
-        ret = proxy_prepare(&device_info->proxy, &device_info->profile, &in->config);
+        proxy_config.channels =
+                profile_get_closest_channel_count(&in->profile, in->hal_channel_count);
+        ret = proxy_prepare(&in->proxy, &in->profile, &proxy_config);
         if (ret == 0) {
             in->standby = true;
 
@@ -1426,12 +1128,12 @@
             adev_add_stream_to_list(in->adev, &in->adev->input_stream_list, &in->list_node);
         } else {
             ALOGW("proxy_prepare error %d", ret);
-            unsigned channel_count = proxy_get_channel_count(&device_info->proxy);
+            unsigned channel_count = proxy_get_channel_count(&in->proxy);
             config->channel_mask = channel_count <= FCC_2
                 ? audio_channel_in_mask_from_count(channel_count)
                 : audio_channel_mask_for_index_assignment_from_count(channel_count);
-            config->format = audio_format_from_pcm_format(proxy_get_format(&device_info->proxy));
-            config->sample_rate = proxy_get_sample_rate(&device_info->proxy);
+            config->format = audio_format_from_pcm_format(proxy_get_format(&in->proxy));
+            config->sample_rate = proxy_get_sample_rate(&in->proxy);
         }
     }
 
@@ -1443,8 +1145,6 @@
         return ret;
     }
 
-    list_add_tail(&in->alsa_devices, &device_info->list_node);
-
     device_lock(in->adev);
     ++in->adev->inputs_open;
     device_unlock(in->adev);
@@ -1456,25 +1156,18 @@
                                     struct audio_stream_in *stream)
 {
     struct stream_in *in = (struct stream_in *)stream;
+    ALOGV("adev_close_input_stream(c:%d d:%d)", in->profile.card, in->profile.device);
 
-    stream_lock(&in->lock);
+    adev_remove_stream_from_list(in->adev, &in->list_node);
+
     device_lock(in->adev);
-    list_remove(&in->list_node);
     --in->adev->inputs_open;
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(&in->alsa_devices);
-    if (device_info != NULL) {
-        ALOGV("adev_close_input_stream(c:%d d:%d)",
-                device_info->profile.card, device_info->profile.device);
-    }
     LOG_ALWAYS_FATAL_IF(in->adev->inputs_open < 0,
             "invalid inputs_open: %d", in->adev->inputs_open);
-
-    stream_standby_l(&in->alsa_devices, &in->standby);
-
     device_unlock(in->adev);
 
-    stream_clear_devices(&in->alsa_devices);
-    stream_unlock(&in->lock);
+    /* Close the pcm device */
+    in_standby(&stream->common);
 
     free(in->conversion_buffer);
 
@@ -1528,282 +1221,6 @@
     return -ENOSYS;
 }
 
-static int adev_create_audio_patch(struct audio_hw_device *dev,
-                                   unsigned int num_sources,
-                                   const struct audio_port_config *sources,
-                                   unsigned int num_sinks,
-                                   const struct audio_port_config *sinks,
-                                   audio_patch_handle_t *handle) {
-    if (num_sources != 1 || num_sinks == 0 || num_sinks > AUDIO_PATCH_PORTS_MAX) {
-        // Only accept mix->device and device->mix cases. In that case, the number of sources
-        // must be 1. The number of sinks must be in the range of (0, AUDIO_PATCH_PORTS_MAX].
-        return -EINVAL;
-    }
-
-    if (sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        // If source is a device, the number of sinks should be 1.
-        if (num_sinks != 1 || sinks[0].type != AUDIO_PORT_TYPE_MIX) {
-            return -EINVAL;
-        }
-    } else if (sources[0].type == AUDIO_PORT_TYPE_MIX) {
-        // If source is a mix, all sinks should be device.
-        for (unsigned int i = 0; i < num_sinks; i++) {
-            if (sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
-                ALOGE("%s() invalid sink type %#x for mix source", __func__, sinks[i].type);
-                return -EINVAL;
-            }
-        }
-    } else {
-        // All other cases are invalid.
-        return -EINVAL;
-    }
-
-    struct audio_device* adev = (struct audio_device*) dev;
-    bool generatedPatchHandle = false;
-    device_lock(adev);
-    if (*handle == AUDIO_PATCH_HANDLE_NONE) {
-        *handle = ++adev->next_patch_handle;
-        generatedPatchHandle = true;
-    }
-
-    int cards[AUDIO_PATCH_PORTS_MAX];
-    int devices[AUDIO_PATCH_PORTS_MAX];
-    const struct audio_port_config *port_configs =
-            sources[0].type == AUDIO_PORT_TYPE_DEVICE ? sources : sinks;
-    int num_configs = 0;
-    audio_io_handle_t io_handle = 0;
-    bool wasStandby = true;
-    int direction = PCM_OUT;
-    audio_patch_handle_t *patch_handle = NULL;
-    struct listnode *alsa_devices = NULL;
-    struct stream_lock *lock = NULL;
-    struct pcm_config *config = NULL;
-    struct stream_in *in = NULL;
-    struct stream_out *out = NULL;
-
-    unsigned int num_saved_devices = 0;
-    int saved_cards[AUDIO_PATCH_PORTS_MAX];
-    int saved_devices[AUDIO_PATCH_PORTS_MAX];
-
-    struct listnode *node;
-
-    // Only handle patches for mix->devices and device->mix case.
-    if (sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        in = adev_get_stream_in_by_io_handle_l(adev, sinks[0].ext.mix.handle);
-        if (in == NULL) {
-            ALOGE("%s()can not find stream with handle(%d)", __func__, sinks[0].ext.mix.handle);
-            device_unlock(adev);
-            return -EINVAL;
-        }
-
-        direction = PCM_IN;
-        wasStandby = in->standby;
-        io_handle = in->handle;
-        num_configs = num_sources;
-        patch_handle = &in->patch_handle;
-        alsa_devices = &in->alsa_devices;
-        lock = &in->lock;
-        config = &in->config;
-    } else {
-        out = adev_get_stream_out_by_io_handle_l(adev, sources[0].ext.mix.handle);
-        if (out == NULL) {
-            ALOGE("%s()can not find stream with handle(%d)", __func__, sources[0].ext.mix.handle);
-            device_unlock(adev);
-            return -EINVAL;
-        }
-
-        direction = PCM_OUT;
-        wasStandby = out->standby;
-        io_handle = out->handle;
-        num_configs = num_sinks;
-        patch_handle = &out->patch_handle;
-        alsa_devices = &out->alsa_devices;
-        lock = &out->lock;
-        config = &out->config;
-    }
-
-    // Check if the patch handle match the recorded one if a valid patch handle is passed.
-    if (!generatedPatchHandle && *patch_handle != *handle) {
-        ALOGE("%s() the patch handle(%d) does not match recorded one(%d) for stream "
-              "with handle(%d) when creating audio patch",
-              __func__, *handle, *patch_handle, io_handle);
-        device_unlock(adev);
-        return -EINVAL;
-    }
-    device_unlock(adev);
-
-    for (unsigned int i = 0; i < num_configs; ++i) {
-        if (!parse_card_device_params(port_configs[i].ext.device.address, &cards[i], &devices[i])) {
-            ALOGE("%s, failed to parse card and device %s",
-                    __func__, port_configs[i].ext.device.address);
-            return -EINVAL;
-        }
-    }
-
-    stream_lock(lock);
-    list_for_each (node, alsa_devices) {
-        struct alsa_device_info *device_info =
-                node_to_item(node, struct alsa_device_info, list_node);
-        saved_cards[num_saved_devices] = device_info->profile.card;
-        saved_devices[num_saved_devices++] = device_info->profile.device;
-    }
-
-    device_lock(adev);
-    stream_standby_l(alsa_devices, out == NULL ? &in->standby : &out->standby);
-    device_unlock(adev);
-
-    // Timestamps:
-    // Audio timestamps assume continuous PCM frame counts which are maintained
-    // with the device proxy.transferred variable.  Technically it would be better
-    // associated with in or out stream, not the device; here we save and restore
-    // using the first alsa device as a simplification.
-    uint64_t saved_transferred_frames = 0;
-    struct alsa_device_info *device_info = stream_get_first_alsa_device(alsa_devices);
-    if (device_info != NULL) saved_transferred_frames = device_info->proxy.transferred;
-
-    int ret = stream_set_new_devices(config, alsa_devices, num_configs, cards, devices, direction);
-
-    if (ret != 0) {
-        *handle = generatedPatchHandle ? AUDIO_PATCH_HANDLE_NONE : *handle;
-        stream_set_new_devices(
-                config, alsa_devices, num_saved_devices, saved_cards, saved_devices, direction);
-    } else {
-        *patch_handle = *handle;
-    }
-
-    // Timestamps: Restore transferred frames.
-    if (saved_transferred_frames != 0) {
-        device_info = stream_get_first_alsa_device(alsa_devices);
-        if (device_info != NULL) device_info->proxy.transferred = saved_transferred_frames;
-    }
-
-    if (!wasStandby) {
-        device_lock(adev);
-        if (in != NULL) {
-            start_input_stream(in);
-        }
-        if (out != NULL) {
-            start_output_stream(out);
-        }
-        device_unlock(adev);
-    }
-    stream_unlock(lock);
-    return ret;
-}
-
-static int adev_release_audio_patch(struct audio_hw_device *dev,
-                                    audio_patch_handle_t patch_handle)
-{
-    struct audio_device* adev = (struct audio_device*) dev;
-
-    device_lock(adev);
-    struct stream_out *out = adev_get_stream_out_by_patch_handle_l(adev, patch_handle);
-    device_unlock(adev);
-    if (out != NULL) {
-        stream_lock(&out->lock);
-        device_lock(adev);
-        stream_standby_l(&out->alsa_devices, &out->standby);
-        device_unlock(adev);
-        out->patch_handle = AUDIO_PATCH_HANDLE_NONE;
-        stream_unlock(&out->lock);
-        return 0;
-    }
-
-    device_lock(adev);
-    struct stream_in *in = adev_get_stream_in_by_patch_handle_l(adev, patch_handle);
-    device_unlock(adev);
-    if (in != NULL) {
-        stream_lock(&in->lock);
-        device_lock(adev);
-        stream_standby_l(&in->alsa_devices, &in->standby);
-        device_unlock(adev);
-        in->patch_handle = AUDIO_PATCH_HANDLE_NONE;
-        stream_unlock(&in->lock);
-        return 0;
-    }
-
-    ALOGE("%s cannot find stream with patch handle as %d", __func__, patch_handle);
-    return -EINVAL;
-}
-
-static int adev_get_audio_port(struct audio_hw_device *dev, struct audio_port *port)
-{
-    if (port->type != AUDIO_PORT_TYPE_DEVICE) {
-        return -EINVAL;
-    }
-
-    alsa_device_profile profile;
-    const bool is_output = audio_is_output_device(port->ext.device.type);
-    profile_init(&profile, is_output ? PCM_OUT : PCM_IN);
-    if (!parse_card_device_params(port->ext.device.address, &profile.card, &profile.device)) {
-        return -EINVAL;
-    }
-
-    if (!profile_read_device_info(&profile)) {
-        return -ENOENT;
-    }
-
-    port->num_formats = 0;;
-    for (size_t i = 0; i < min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_FORMATS) &&
-            profile.formats[i] != 0; ++i) {
-        audio_format_t format = audio_format_from(profile.formats[i]);
-        if (format != AUDIO_FORMAT_INVALID) {
-            port->formats[port->num_formats++] = format;
-        }
-    }
-
-    port->num_sample_rates = populate_sample_rates_from_profile(&profile, port->sample_rates);
-    port->num_channel_masks = populate_channel_mask_from_profile(
-            &profile, is_output, port->channel_masks);
-
-    return 0;
-}
-
-static int adev_get_audio_port_v7(struct audio_hw_device *dev, struct audio_port_v7 *port)
-{
-    if (port->type != AUDIO_PORT_TYPE_DEVICE) {
-        return -EINVAL;
-    }
-
-    alsa_device_profile profile;
-    const bool is_output = audio_is_output_device(port->ext.device.type);
-    profile_init(&profile, is_output ? PCM_OUT : PCM_IN);
-    if (!parse_card_device_params(port->ext.device.address, &profile.card, &profile.device)) {
-        return -EINVAL;
-    }
-
-    if (!profile_read_device_info(&profile)) {
-        return -ENOENT;
-    }
-
-    audio_channel_mask_t channel_masks[AUDIO_PORT_MAX_CHANNEL_MASKS];
-    unsigned int num_channel_masks = populate_channel_mask_from_profile(
-            &profile, is_output, channel_masks);
-    unsigned int sample_rates[AUDIO_PORT_MAX_SAMPLING_RATES];
-    const unsigned int num_sample_rates =
-            populate_sample_rates_from_profile(&profile, sample_rates);
-    port->num_audio_profiles = 0;;
-    for (size_t i = 0; i < min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_AUDIO_PROFILES) &&
-            profile.formats[i] != 0; ++i) {
-        audio_format_t format = audio_format_from(profile.formats[i]);
-        if (format == AUDIO_FORMAT_INVALID) {
-            continue;
-        }
-        const unsigned int j = port->num_audio_profiles++;
-        port->audio_profiles[j].format = format;
-        port->audio_profiles[j].num_sample_rates = num_sample_rates;
-        memcpy(port->audio_profiles[j].sample_rates,
-               sample_rates,
-               num_sample_rates * sizeof(unsigned int));
-        port->audio_profiles[j].num_channel_masks = num_channel_masks;
-        memcpy(port->audio_profiles[j].channel_masks,
-               channel_masks,
-               num_channel_masks* sizeof(audio_channel_mask_t));
-    }
-
-    return 0;
-}
-
 static int adev_dump(const struct audio_hw_device *device, int fd)
 {
     dprintf(fd, "\nUSB audio module:\n");
@@ -1873,7 +1290,7 @@
     list_init(&adev->input_stream_list);
 
     adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
-    adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_3_2;
+    adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
     adev->hw_device.common.module = (struct hw_module_t *)module;
     adev->hw_device.common.close = adev_close;
 
@@ -1890,10 +1307,6 @@
     adev->hw_device.close_output_stream = adev_close_output_stream;
     adev->hw_device.open_input_stream = adev_open_input_stream;
     adev->hw_device.close_input_stream = adev_close_input_stream;
-    adev->hw_device.create_audio_patch = adev_create_audio_patch;
-    adev->hw_device.release_audio_patch = adev_release_audio_patch;
-    adev->hw_device.get_audio_port = adev_get_audio_port;
-    adev->hw_device.get_audio_port_v7 = adev_get_audio_port_v7;
     adev->hw_device.dump = adev_dump;
 
     *device = &adev->hw_device.common;
diff --git a/modules/usbcamera/Android.bp b/modules/usbcamera/Android.bp
index 07eb85b..5e44d3c 100644
--- a/modules/usbcamera/Android.bp
+++ b/modules/usbcamera/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "camera.usb.default",
     relative_install_path: "hw",
diff --git a/modules/vibrator/Android.bp b/modules/vibrator/Android.bp
index 2412d4d..13ffc83 100644
--- a/modules/vibrator/Android.bp
+++ b/modules/vibrator/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "vibrator.default",
 
diff --git a/modules/vr/Android.bp b/modules/vr/Android.bp
index 121939b..40f4510 100644
--- a/modules/vr/Android.bp
+++ b/modules/vr/Android.bp
@@ -12,15 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_shared {
     name: "vr.default",
     relative_install_path: "hw",
diff --git a/tests/camera3/Android.bp b/tests/camera3/Android.bp
index 6d43066..55486ba 100644
--- a/tests/camera3/Android.bp
+++ b/tests/camera3/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_test {
     name: "camera3_tests",
     srcs: ["camera3tests.cpp"],
diff --git a/tests/fingerprint/Android.bp b/tests/fingerprint/Android.bp
index 9827e89..9524b7b 100644
--- a/tests/fingerprint/Android.bp
+++ b/tests/fingerprint/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_test {
     name: "fingerprint_tests",
     srcs: ["fingerprint_tests.cpp"],
diff --git a/tests/hardware/Android.bp b/tests/hardware/Android.bp
index b137684..2f5db12 100644
--- a/tests/hardware/Android.bp
+++ b/tests/hardware/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_static {
     name: "static-hal-check",
     srcs: [
diff --git a/tests/hwc/Android.bp b/tests/hwc/Android.bp
index 82a00e4..782a314 100644
--- a/tests/hwc/Android.bp
+++ b/tests/hwc/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_library_static {
     name: "libcnativewindow",
     srcs: [
diff --git a/tests/input/evdev/Android.bp b/tests/input/evdev/Android.bp
index 10fa146..fa03a00 100644
--- a/tests/input/evdev/Android.bp
+++ b/tests/input/evdev/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_test {
     name: "libinput_evdevtests",
 
diff --git a/tests/keymaster/Android.bp b/tests/keymaster/Android.bp
new file mode 100644
index 0000000..8c027e0
--- /dev/null
+++ b/tests/keymaster/Android.bp
@@ -0,0 +1,17 @@
+// Build the keymaster unit tests
+cc_test {
+    name: "keymaster_test",
+    srcs: ["keymaster_test.cpp"],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libcrypto",
+        "libhardware",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/tests/keymaster/keymaster_test.cpp b/tests/keymaster/keymaster_test.cpp
new file mode 100644
index 0000000..562c8ed
--- /dev/null
+++ b/tests/keymaster/keymaster_test.cpp
@@ -0,0 +1,1243 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs8.h>
+#include <openssl/x509.h>
+
+#define LOG_TAG "keymaster_test"
+#include <utils/Log.h>
+
+#include <hardware/keymaster0.h>
+
+namespace android {
+
+class UniqueBlob : public std::unique_ptr<uint8_t[]> {
+public:
+    explicit UniqueBlob(size_t length) :
+            mLength(length) {
+    }
+
+    UniqueBlob(uint8_t* bytes, size_t length) :
+            std::unique_ptr<uint8_t[]>(bytes), mLength(length) {
+    }
+
+    bool operator==(const UniqueBlob &other) const {
+        if (other.length() != mLength) {
+            return false;
+        }
+
+        const uint8_t* mine = get();
+        const uint8_t* theirs = other.get();
+
+        for (size_t i = 0; i < mLength; i++) {
+            if (mine[i] != theirs[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    size_t length() const {
+        return mLength;
+    }
+
+    friend std::ostream &operator<<(std::ostream &stream, const UniqueBlob& blob);
+
+private:
+    size_t mLength;
+};
+
+std::ostream &operator<<(std::ostream &stream, const UniqueBlob& blob) {
+    const size_t length = blob.mLength;
+    stream << "Blob length=" << length << " < ";
+
+    const uint8_t* data = blob.get();
+    for (size_t i = 0; i < length; i++) {
+        stream << std::hex << std::setw(2) << std::setfill('0')
+                << static_cast<unsigned int>(data[i]) << ' ';
+    }
+    stream << '>' << std::endl;
+
+    return stream;
+}
+
+class UniqueKey : public UniqueBlob {
+public:
+    UniqueKey(keymaster0_device_t** dev, uint8_t* bytes, size_t length) :
+            UniqueBlob(bytes, length), mDevice(dev) {
+    }
+
+    ~UniqueKey() {
+        if (mDevice != NULL && *mDevice != NULL) {
+            keymaster0_device_t* dev = *mDevice;
+            if (dev->delete_keypair != NULL) {
+                dev->delete_keypair(dev, get(), length());
+            }
+        }
+    }
+
+private:
+    keymaster0_device_t** mDevice;
+};
+
+class UniqueReadOnlyBlob {
+public:
+    UniqueReadOnlyBlob(uint8_t* data, size_t dataSize) :
+            mDataSize(dataSize) {
+        int pageSize = sysconf(_SC_PAGE_SIZE);
+        if (pageSize == -1) {
+            return;
+        }
+
+        int fd = open("/dev/zero", O_RDONLY);
+        if (fd == -1) {
+            return;
+        }
+
+        mBufferSize = (dataSize + pageSize - 1) & ~(pageSize - 1);
+        uint8_t* buffer = (uint8_t*) mmap(NULL, mBufferSize, PROT_READ | PROT_WRITE,
+                                          MAP_PRIVATE, fd, 0);
+        close(fd);
+
+        if (buffer == NULL) {
+            return;
+        }
+
+        memcpy(buffer, data, dataSize);
+        if (mprotect(buffer, mBufferSize, PROT_READ) == -1) {
+            munmap(buffer, mBufferSize);
+            return;
+        }
+
+        mBuffer = buffer;
+    }
+
+    ~UniqueReadOnlyBlob() {
+        munmap(mBuffer, mBufferSize);
+    }
+
+    uint8_t* get() const {
+        return mBuffer;
+    }
+
+    size_t length() const {
+        return mDataSize;
+    }
+
+private:
+    uint8_t* mBuffer;
+    size_t mBufferSize;
+    size_t mDataSize;
+};
+
+
+/*
+ * DER-encoded PKCS#8 format RSA key. Generated using:
+ *
+ * openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1
+ */
+static uint8_t TEST_RSA_KEY_1[] = {
+        0x30, 0x82, 0x04, 0xBE, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+        0x04, 0xA8, 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
+        0x01, 0x00, 0xD8, 0x58, 0xD4, 0x9F, 0xC0, 0xE8, 0xF0, 0xFF, 0x87, 0x27,
+        0x43, 0xE6, 0x2E, 0xE6, 0x9A, 0x42, 0x3B, 0x39, 0x94, 0x84, 0x43, 0x55,
+        0x8D, 0x20, 0x5B, 0x71, 0x88, 0xE6, 0xD1, 0x62, 0xC8, 0xF2, 0x20, 0xD0,
+        0x75, 0x13, 0x83, 0xA3, 0x5D, 0x19, 0xA8, 0x62, 0xD0, 0x5F, 0x3E, 0x8A,
+        0x7C, 0x0E, 0x26, 0xA9, 0xFF, 0xB2, 0x5E, 0x63, 0xAA, 0x3C, 0x8D, 0x13,
+        0x41, 0xAA, 0xD5, 0x03, 0x01, 0x01, 0x53, 0xC9, 0x02, 0x1C, 0xEC, 0xE8,
+        0xC4, 0x70, 0x3F, 0x43, 0xE5, 0x51, 0xD0, 0x6E, 0x52, 0x0B, 0xC4, 0x0A,
+        0xA3, 0x61, 0xDE, 0xE3, 0x72, 0x0C, 0x94, 0xF1, 0x1C, 0x2D, 0x36, 0x77,
+        0xBB, 0x16, 0xA8, 0x63, 0x4B, 0xD1, 0x07, 0x00, 0x42, 0x2D, 0x2B, 0x10,
+        0x80, 0x45, 0xF3, 0x0C, 0xF9, 0xC5, 0xAC, 0xCC, 0x64, 0x87, 0xFD, 0x5D,
+        0xC8, 0x51, 0xD4, 0x1C, 0x9E, 0x6E, 0x9B, 0xC4, 0x27, 0x5E, 0x73, 0xA7,
+        0x2A, 0xF6, 0x90, 0x42, 0x0C, 0x34, 0x93, 0xB7, 0x02, 0x19, 0xA9, 0x64,
+        0x6C, 0x46, 0x3B, 0x40, 0x02, 0x2F, 0x54, 0x69, 0x79, 0x26, 0x7D, 0xF6,
+        0x85, 0x90, 0x01, 0xD0, 0x21, 0x07, 0xD0, 0x14, 0x00, 0x65, 0x9C, 0xAC,
+        0x24, 0xE8, 0x78, 0x42, 0x3B, 0x90, 0x75, 0x19, 0x55, 0x11, 0x4E, 0xD9,
+        0xE6, 0x97, 0x87, 0xBC, 0x8D, 0x2C, 0x9B, 0xF0, 0x1F, 0x14, 0xEB, 0x6A,
+        0x57, 0xCE, 0x78, 0xAD, 0xCE, 0xD9, 0xFB, 0xB9, 0xA1, 0xEF, 0x0C, 0x1F,
+        0xDD, 0xE3, 0x5B, 0x73, 0xA0, 0xEC, 0x37, 0x9C, 0xE1, 0xFD, 0x86, 0x28,
+        0xC3, 0x4A, 0x42, 0xD0, 0xA3, 0xFE, 0x57, 0x09, 0x29, 0xD8, 0xF6, 0xEC,
+        0xE3, 0xC0, 0x71, 0x7C, 0x29, 0x27, 0xC2, 0xD1, 0x3E, 0x22, 0xBC, 0xBD,
+        0x5A, 0x85, 0x41, 0xF6, 0x15, 0xDA, 0x0C, 0x58, 0x5A, 0x61, 0x5B, 0x78,
+        0xB8, 0xAA, 0xEC, 0x5C, 0x1C, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
+        0x82, 0x01, 0x00, 0x1D, 0x10, 0x31, 0xE0, 0x14, 0x26, 0x36, 0xD9, 0xDC,
+        0xEA, 0x25, 0x70, 0xF2, 0xB3, 0xFF, 0xDD, 0x0D, 0xDF, 0xBA, 0x57, 0xDA,
+        0x43, 0xCF, 0xE5, 0x9C, 0xE3, 0x2F, 0xA4, 0xF2, 0x53, 0xF6, 0xF2, 0xAF,
+        0xFD, 0xD0, 0xFC, 0x82, 0x1E, 0x9C, 0x0F, 0x2A, 0x53, 0xBB, 0xF2, 0x4F,
+        0x90, 0x83, 0x01, 0xD3, 0xA7, 0xDA, 0xB5, 0xB7, 0x80, 0x64, 0x0A, 0x26,
+        0x59, 0x83, 0xE4, 0xD3, 0x20, 0xC8, 0x2D, 0xC9, 0x77, 0xA3, 0x55, 0x07,
+        0x6E, 0x6D, 0x95, 0x36, 0xAA, 0x84, 0x4F, 0xED, 0x54, 0x24, 0xA9, 0x77,
+        0xF8, 0x85, 0xE2, 0x4B, 0xF2, 0xFA, 0x0B, 0x3E, 0xA6, 0xF5, 0x46, 0x0D,
+        0x9F, 0x1F, 0xFE, 0xF7, 0x37, 0xFF, 0xA3, 0x60, 0xF1, 0x63, 0xF2, 0x75,
+        0x6A, 0x8E, 0x10, 0xD7, 0x89, 0xD2, 0xB3, 0xFF, 0x76, 0xA5, 0xBA, 0xAF,
+        0x0A, 0xBE, 0x32, 0x5F, 0xF0, 0x48, 0x48, 0x4B, 0x9C, 0x9A, 0x3D, 0x12,
+        0xA7, 0xD2, 0x07, 0xC7, 0x59, 0x32, 0x94, 0x95, 0x65, 0x2F, 0x87, 0x34,
+        0x76, 0xBA, 0x7C, 0x08, 0x4B, 0xAB, 0xA6, 0x24, 0xDF, 0x64, 0xDB, 0x48,
+        0x63, 0x42, 0x06, 0xE2, 0x2C, 0x3D, 0xFB, 0xE5, 0x47, 0x81, 0x94, 0x98,
+        0xF7, 0x32, 0x4B, 0x28, 0xEB, 0x42, 0xB8, 0xE9, 0x8E, 0xFC, 0xC9, 0x43,
+        0xC9, 0x47, 0xE6, 0xE7, 0x1C, 0xDC, 0x71, 0xEF, 0x4D, 0x8A, 0xB1, 0xFC,
+        0x45, 0x37, 0xEC, 0xB3, 0x16, 0x88, 0x5B, 0xE2, 0xEC, 0x8B, 0x6B, 0x75,
+        0x16, 0xBE, 0x6B, 0xF8, 0x2C, 0xF8, 0xC9, 0xD1, 0xF7, 0x55, 0x87, 0x57,
+        0x5F, 0xDE, 0xF4, 0x7E, 0x72, 0x13, 0x06, 0x2A, 0x21, 0xB7, 0x78, 0x21,
+        0x05, 0xFD, 0xE2, 0x5F, 0x7B, 0x7C, 0xF0, 0x26, 0x2B, 0x75, 0x7F, 0x68,
+        0xF9, 0xA6, 0x98, 0xFD, 0x54, 0x0E, 0xCC, 0x22, 0x41, 0x7F, 0x29, 0x81,
+        0x2F, 0xA3, 0x3C, 0x3D, 0x64, 0xC8, 0x41, 0x02, 0x81, 0x81, 0x00, 0xFA,
+        0xFA, 0xE4, 0x2E, 0x30, 0xF0, 0x7A, 0x8D, 0x95, 0xB8, 0x39, 0x58, 0x27,
+        0x0F, 0x89, 0x0C, 0xDF, 0xFE, 0x2F, 0x55, 0x3B, 0x6F, 0xDD, 0x5F, 0x12,
+        0xB3, 0xD1, 0xCF, 0x5B, 0x8D, 0xB6, 0x10, 0x1C, 0x87, 0x0C, 0x30, 0x89,
+        0x2D, 0xBB, 0xB8, 0xA1, 0x78, 0x0F, 0x54, 0xA6, 0x36, 0x46, 0x05, 0x8B,
+        0x5A, 0xFF, 0x48, 0x03, 0x13, 0xAE, 0x95, 0x96, 0x5D, 0x6C, 0xDA, 0x5D,
+        0xF7, 0xAD, 0x1D, 0x33, 0xED, 0x23, 0xF5, 0x4B, 0x03, 0x78, 0xE7, 0x50,
+        0xD1, 0x2D, 0x95, 0x22, 0x35, 0x02, 0x5B, 0x4A, 0x4E, 0x73, 0xC9, 0xB7,
+        0x05, 0xC4, 0x21, 0x86, 0x1F, 0x1E, 0x40, 0x83, 0xBC, 0x8A, 0x3A, 0x95,
+        0x24, 0x62, 0xF4, 0x58, 0x38, 0x64, 0x4A, 0x89, 0x8A, 0x27, 0x59, 0x12,
+        0x9D, 0x21, 0xC3, 0xA6, 0x42, 0x1E, 0x2A, 0x3F, 0xD8, 0x65, 0x1F, 0x6E,
+        0x3E, 0x4D, 0x5C, 0xCC, 0xEA, 0x8E, 0x15, 0x02, 0x81, 0x81, 0x00, 0xDC,
+        0xAC, 0x9B, 0x00, 0xDB, 0xF9, 0xB2, 0xBF, 0xC4, 0x5E, 0xB6, 0xB7, 0x63,
+        0xEB, 0x13, 0x4B, 0xE2, 0xA6, 0xC8, 0x72, 0x90, 0xD8, 0xC2, 0x33, 0x33,
+        0xF0, 0x66, 0x75, 0xBD, 0x50, 0x7C, 0xA4, 0x8F, 0x82, 0xFB, 0xFF, 0x44,
+        0x3B, 0xE7, 0x15, 0x3A, 0x0C, 0x7A, 0xF8, 0x92, 0x86, 0x4A, 0x79, 0x32,
+        0x08, 0x82, 0x1D, 0x6A, 0xBA, 0xAD, 0x8A, 0xB3, 0x3D, 0x7F, 0xA5, 0xB4,
+        0x6F, 0x67, 0x86, 0x7E, 0xB2, 0x9C, 0x2A, 0xF6, 0x7C, 0x49, 0x21, 0xC5,
+        0x3F, 0x00, 0x3F, 0x9B, 0xF7, 0x0F, 0x6C, 0x35, 0x80, 0x75, 0x73, 0xC0,
+        0xF8, 0x3E, 0x30, 0x5F, 0x74, 0x2F, 0x15, 0x41, 0xEA, 0x0F, 0xCE, 0x0E,
+        0x18, 0x17, 0x68, 0xBA, 0xC4, 0x29, 0xF2, 0xE2, 0x2C, 0x1D, 0x55, 0x83,
+        0xB6, 0x64, 0x2E, 0x03, 0x12, 0xA4, 0x0D, 0xBF, 0x4F, 0x2E, 0xBE, 0x7C,
+        0x41, 0xD9, 0xCD, 0xD0, 0x52, 0x91, 0xD5, 0x02, 0x81, 0x81, 0x00, 0xD4,
+        0x55, 0xEB, 0x32, 0xC1, 0x28, 0xD3, 0x26, 0x72, 0x22, 0xB8, 0x31, 0x42,
+        0x6A, 0xBC, 0x52, 0x6E, 0x37, 0x48, 0xA8, 0x5D, 0x6E, 0xD8, 0xE5, 0x14,
+        0x97, 0x99, 0xCC, 0x4A, 0xF2, 0xEB, 0xB3, 0x59, 0xCF, 0x4F, 0x9A, 0xC8,
+        0x94, 0x2E, 0x9B, 0x97, 0xD0, 0x51, 0x78, 0x16, 0x5F, 0x18, 0x82, 0x9C,
+        0x51, 0xD2, 0x64, 0x84, 0x65, 0xE4, 0x70, 0x9E, 0x14, 0x50, 0x81, 0xB6,
+        0xBA, 0x52, 0x75, 0xC0, 0x76, 0xC2, 0xD3, 0x46, 0x31, 0x9B, 0xDA, 0x67,
+        0xDF, 0x71, 0x27, 0x19, 0x17, 0xAB, 0xF4, 0xBC, 0x3A, 0xFF, 0x6F, 0x0B,
+        0x2F, 0x0F, 0xAE, 0x25, 0x20, 0xB2, 0xA1, 0x76, 0x52, 0xCE, 0xC7, 0x9D,
+        0x62, 0x79, 0x6D, 0xAC, 0x2D, 0x99, 0x7C, 0x0E, 0x3D, 0x19, 0xE9, 0x1B,
+        0xFC, 0x60, 0x92, 0x7C, 0x58, 0xB7, 0xD8, 0x9A, 0xC7, 0x63, 0x56, 0x62,
+        0x18, 0xC7, 0xAE, 0xD9, 0x97, 0x1F, 0xB9, 0x02, 0x81, 0x81, 0x00, 0x91,
+        0x40, 0xC4, 0x1E, 0x82, 0xAD, 0x0F, 0x6D, 0x8E, 0xD2, 0x51, 0x2E, 0xD1,
+        0x84, 0x30, 0x85, 0x68, 0xC1, 0x23, 0x7B, 0xD5, 0xBF, 0xF7, 0xC4, 0x40,
+        0x51, 0xE2, 0xFF, 0x69, 0x07, 0x8B, 0xA3, 0xBE, 0x1B, 0x17, 0xC8, 0x64,
+        0x9F, 0x91, 0x71, 0xB5, 0x6D, 0xF5, 0x9B, 0x9C, 0xC6, 0xEC, 0x4A, 0x6E,
+        0x16, 0x8F, 0x9E, 0xD1, 0x5B, 0xE3, 0x53, 0x42, 0xBC, 0x1E, 0x43, 0x72,
+        0x4B, 0x4A, 0x37, 0x8B, 0x3A, 0x01, 0xF5, 0x7D, 0x9D, 0x3D, 0x7E, 0x0F,
+        0x19, 0x73, 0x0E, 0x6B, 0x98, 0xE9, 0xFB, 0xEE, 0x13, 0x8A, 0x3C, 0x11,
+        0x2E, 0xD5, 0xB0, 0x7D, 0x84, 0x3A, 0x61, 0xA1, 0xAB, 0x71, 0x8F, 0xCE,
+        0x53, 0x29, 0x45, 0x74, 0x7A, 0x1E, 0xAA, 0x93, 0x19, 0x3A, 0x8D, 0xC9,
+        0x4E, 0xCB, 0x0E, 0x46, 0x53, 0x84, 0xCC, 0xCF, 0xBA, 0x4D, 0x28, 0x71,
+        0x1D, 0xDF, 0x41, 0xCB, 0xF8, 0x2D, 0xA9, 0x02, 0x81, 0x80, 0x04, 0x8B,
+        0x4A, 0xEA, 0xBD, 0x39, 0x0B, 0x96, 0xC5, 0x1D, 0xA4, 0x47, 0xFD, 0x46,
+        0xD2, 0x8A, 0xEA, 0x2A, 0xF3, 0x9D, 0x3A, 0x7E, 0x16, 0x74, 0xFC, 0x13,
+        0xDE, 0x4D, 0xA9, 0x85, 0x42, 0x33, 0x02, 0x92, 0x0B, 0xB6, 0xDB, 0x7E,
+        0xEA, 0x85, 0xC2, 0x94, 0x43, 0x52, 0x37, 0x5A, 0x77, 0xAB, 0xCB, 0x61,
+        0x88, 0xDE, 0xF8, 0xFA, 0xDB, 0xE8, 0x0B, 0x95, 0x7D, 0x39, 0x19, 0xA2,
+        0x89, 0xB9, 0x32, 0xB2, 0x50, 0x38, 0xF7, 0x88, 0x69, 0xFD, 0xA4, 0x63,
+        0x1F, 0x9B, 0x03, 0xD8, 0xA6, 0x7A, 0x05, 0x76, 0x02, 0x28, 0x93, 0x82,
+        0x73, 0x7F, 0x14, 0xCC, 0xBE, 0x29, 0x10, 0xAD, 0x8A, 0x2E, 0xAC, 0xED,
+        0x11, 0xA7, 0x72, 0x7C, 0x60, 0x78, 0x72, 0xFB, 0x78, 0x20, 0x18, 0xC9,
+        0x7E, 0x63, 0xAD, 0x55, 0x54, 0x51, 0xDB, 0x9F, 0x7B, 0xD4, 0x8F, 0xB2,
+        0xDE, 0x3B, 0xF1, 0x70, 0x23, 0xE5,
+};
+
+/*
+ * DER-encoded PKCS#8 format EC key. Generated using:
+ *
+ * openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1
+ */
+static uint8_t TEST_EC_KEY_1[] = {
+        0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86,
+        0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
+        0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02, 0x01, 0x01, 0x04, 0x20,
+        0x25, 0xAC, 0x77, 0x2B, 0x04, 0x33, 0xC8, 0x16, 0x59, 0xA3, 0xC7, 0xE7,
+        0x11, 0x42, 0xD0, 0x11, 0x71, 0x30, 0x7B, 0xB8, 0xD2, 0x67, 0xFF, 0x9C,
+        0x5F, 0x50, 0x2E, 0xAB, 0x67, 0xD4, 0x17, 0x51, 0xA1, 0x44, 0x03, 0x42,
+        0x00, 0x04, 0xCF, 0xCE, 0xB8, 0x7F, 0x88, 0x36, 0xC4, 0xF8, 0x51, 0x29,
+        0xE2, 0xA7, 0x21, 0xC3, 0x3B, 0xFF, 0x88, 0xE3, 0x87, 0x98, 0xD1, 0xA6,
+        0x4B, 0xB3, 0x4B, 0xD5, 0x44, 0xF8, 0xE0, 0x43, 0x6B, 0x50, 0x74, 0xFB,
+        0xB0, 0xAD, 0x41, 0x1C, 0x11, 0x9D, 0xC6, 0x1E, 0x83, 0x8C, 0x49, 0xCA,
+        0xBE, 0xC6, 0xCE, 0xB6, 0xC9, 0xA1, 0xBF, 0x69, 0xA9, 0xA0, 0xA3, 0x80,
+        0x14, 0x39, 0x57, 0x94, 0xDA, 0x5D
+};
+
+
+/*
+ * Generated using keys on the keyboard and lack of imagination.
+ */
+static unsigned char BOGUS_KEY_1[] = { 0xFF, 0xFF, 0xFF, 0xFF };
+
+
+class KeymasterBaseTest : public ::testing::Test {
+public:
+    static void SetUpTestCase() {
+        const hw_module_t* mod;
+        ASSERT_EQ(0, hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod))
+                << "Should be able to find a keymaster hardware module";
+
+        std::cout << "Using keymaster module: " << mod->name << std::endl;
+
+        ASSERT_EQ(0, keymaster0_open(mod, &sDevice))
+                << "Should be able to open the keymaster device";
+
+        ASSERT_EQ(KEYMASTER_MODULE_API_VERSION_0_2, mod->module_api_version)
+                << "Keymaster should implement API version 2";
+
+        ASSERT_TRUE(sDevice->generate_keypair != NULL)
+                << "Should implement generate_keypair";
+
+        ASSERT_TRUE(sDevice->import_keypair != NULL)
+                << "Should implement import_keypair";
+
+        ASSERT_TRUE(sDevice->get_keypair_public != NULL)
+                << "Should implement get_keypair_public";
+
+        ASSERT_TRUE(sDevice->sign_data != NULL)
+                << "Should implement sign_data";
+
+        ASSERT_TRUE(sDevice->verify_data != NULL)
+                << "Should implement verify_data";
+    }
+
+    static void TearDownTestCase() {
+        ASSERT_EQ(0, keymaster0_close(sDevice));
+    }
+
+protected:
+    static keymaster0_device_t* sDevice;
+};
+
+keymaster0_device_t* KeymasterBaseTest::sDevice = NULL;
+
+class KeymasterTest : public KeymasterBaseTest {
+};
+
+class KeymasterAllTypesTest : public KeymasterBaseTest,
+                              public ::testing::WithParamInterface<keymaster_keypair_t> {
+};
+
+class KeymasterGenerateRSATest : public KeymasterBaseTest,
+                              public ::testing::WithParamInterface<uint32_t> {
+};
+
+class KeymasterGenerateDSATest : public KeymasterBaseTest,
+                              public ::testing::WithParamInterface<uint32_t> {
+};
+
+class KeymasterGenerateECTest : public KeymasterBaseTest,
+                              public ::testing::WithParamInterface<uint32_t> {
+};
+
+TEST_P(KeymasterGenerateRSATest, GenerateKeyPair_RSA_Success) {
+    keymaster_keypair_t key_type = TYPE_RSA;
+    keymaster_rsa_keygen_params_t params = {
+            .modulus_size = GetParam(),
+            .public_exponent = RSA_F4,
+    };
+
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(0,
+            sDevice->generate_keypair(sDevice, key_type, &params, &key_blob, &key_blob_length))
+            << "Should generate an RSA key with " << GetParam() << " bit modulus size";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data = NULL;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+    ASSERT_FALSE(x509_blob.get() == NULL)
+            << "X509 data should be allocated";
+
+    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
+    bssl::UniquePtr<EVP_PKEY> actual(d2i_PUBKEY(NULL, &tmp,
+            static_cast<long>(x509_blob.length())));
+
+    ASSERT_EQ(EVP_PKEY_RSA, EVP_PKEY_type(actual.get()->type))
+            << "Generated key type should be of type RSA";
+
+    bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(actual.get()));
+    ASSERT_FALSE(rsa.get() == NULL)
+            << "Should be able to extract RSA key from EVP_PKEY";
+
+    ASSERT_EQ(static_cast<unsigned long>(RSA_F4), BN_get_word(rsa.get()->e))
+            << "Exponent should be RSA_F4";
+
+    ASSERT_EQ((GetParam() + 7) / 8, static_cast<uint32_t>(RSA_size(rsa.get())))
+            << "Modulus size should be the specified parameter";
+}
+
+INSTANTIATE_TEST_CASE_P(RSA,
+                        KeymasterGenerateRSATest,
+                        ::testing::Values(512U, 1024U, 2048U, 3072U, 4096U));
+
+
+TEST_P(KeymasterGenerateECTest, GenerateKeyPair_EC_Success) {
+    keymaster_keypair_t key_type = TYPE_EC;
+    keymaster_ec_keygen_params_t params = {
+            .field_size = GetParam(),
+    };
+
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(0,
+            sDevice->generate_keypair(sDevice, key_type, &params, &key_blob, &key_blob_length))
+            << "Should generate an EC key with " << GetParam() << " field size";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data = NULL;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve EC public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+    ASSERT_FALSE(x509_blob.get() == NULL)
+            << "X509 data should be allocated";
+
+    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
+    bssl::UniquePtr<EVP_PKEY> actual(d2i_PUBKEY(NULL, &tmp,
+            static_cast<long>(x509_blob.length())));
+
+    ASSERT_EQ(EVP_PKEY_EC, EVP_PKEY_type(actual.get()->type))
+            << "Generated key type should be of type EC";
+
+    bssl::UniquePtr<EC_KEY> ecKey(EVP_PKEY_get1_EC_KEY(actual.get()));
+    ASSERT_FALSE(ecKey.get() == NULL)
+            << "Should be able to extract EC key from EVP_PKEY";
+
+    ASSERT_FALSE(EC_KEY_get0_group(ecKey.get()) == NULL)
+            << "EC key should have a EC_GROUP";
+
+    ASSERT_TRUE(EC_KEY_check_key(ecKey.get()))
+            << "EC key should check correctly";
+}
+
+INSTANTIATE_TEST_CASE_P(EC,
+                        KeymasterGenerateECTest,
+                        ::testing::Values(192U, 224U, 256U, 384U, 521U));
+
+
+TEST_P(KeymasterAllTypesTest, GenerateKeyPair_NullParams_Failure) {
+    keymaster_keypair_t key_type = GetParam();
+
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(-1,
+            sDevice->generate_keypair(sDevice, key_type, NULL, &key_blob, &key_blob_length))
+            << "Should not be able to generate a key with null params";
+}
+
+INSTANTIATE_TEST_CASE_P(Types,
+                        KeymasterAllTypesTest,
+                        ::testing::Values(TYPE_RSA, TYPE_DSA, TYPE_EC));
+
+TEST_F(KeymasterTest, GenerateKeyPair_UnknownType_Failure) {
+    keymaster_keypair_t key_type = static_cast<keymaster_keypair_t>(0xFFFF);
+
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(-1,
+            sDevice->generate_keypair(sDevice, key_type, NULL, &key_blob, &key_blob_length))
+            << "Should not generate an unknown key type";
+}
+
+TEST_F(KeymasterTest, ImportKeyPair_RSA_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+
+    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
+    bssl::UniquePtr<EVP_PKEY> actual(d2i_PUBKEY(NULL, &tmp,
+            static_cast<long>(x509_blob.length())));
+
+    ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_RSA)
+            << "Generated key type should be of type RSA";
+
+    const unsigned char *expectedTmp = static_cast<const unsigned char*>(TEST_RSA_KEY_1);
+    bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> expectedPkcs8(
+            d2i_PKCS8_PRIV_KEY_INFO(NULL, &expectedTmp,
+                    sizeof(TEST_RSA_KEY_1)));
+
+    bssl::UniquePtr<EVP_PKEY> expected(EVP_PKCS82PKEY(expectedPkcs8.get()));
+
+    ASSERT_EQ(1, EVP_PKEY_cmp(expected.get(), actual.get()))
+            << "Expected and actual keys should match";
+}
+
+TEST_F(KeymasterTest, ImportKeyPair_EC_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an EC key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve EC public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+
+    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
+    bssl::UniquePtr<EVP_PKEY> actual(d2i_PUBKEY(NULL, &tmp,
+            static_cast<long>(x509_blob.length())));
+
+    ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_EC)
+            << "Generated key type should be of type EC";
+
+    const unsigned char *expectedTmp = static_cast<const unsigned char*>(TEST_EC_KEY_1);
+    bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> expectedPkcs8(
+            d2i_PKCS8_PRIV_KEY_INFO(NULL, &expectedTmp,
+                    sizeof(TEST_EC_KEY_1)));
+
+    bssl::UniquePtr<EVP_PKEY> expected(EVP_PKCS82PKEY(expectedPkcs8.get()));
+
+    ASSERT_EQ(1, EVP_PKEY_cmp(expected.get(), actual.get()))
+            << "Expected and actual keys should match";
+}
+
+TEST_F(KeymasterTest, ImportKeyPair_BogusKey_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(-1,
+            sDevice->import_keypair(sDevice, BOGUS_KEY_1, sizeof(BOGUS_KEY_1),
+                    &key_blob, &key_blob_length))
+            << "Should not import an unknown key type";
+}
+
+TEST_F(KeymasterTest, ImportKeyPair_NullKey_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(-1,
+            sDevice->import_keypair(sDevice, NULL, 0,
+                    &key_blob, &key_blob_length))
+            << "Should not import a null key";
+}
+
+TEST_F(KeymasterTest, GetKeypairPublic_RSA_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+}
+
+TEST_F(KeymasterTest, GetKeypairPublic_EC_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an EC key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve EC public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+}
+
+TEST_F(KeymasterTest, GetKeypairPublic_NullKey_Failure) {
+    uint8_t* x509_data = NULL;
+    size_t x509_data_length;
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, NULL, 0,
+                    &x509_data, &x509_data_length))
+            << "Should not be able to retrieve public key from null key";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+}
+
+TEST_F(KeymasterTest, GetKeypairPublic_RSA_NullDestination_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key.get(), key.length(),
+                    NULL, NULL))
+            << "Should not be able to succeed with NULL destination blob";
+}
+
+TEST_F(KeymasterTest, GetKeypairPublic_EC_NullDestination_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key.get(), key.length(),
+                    NULL, NULL))
+            << "Should not be able to succeed with NULL destination blob";
+}
+
+TEST_F(KeymasterTest, DeleteKeyPair_RSA_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+}
+
+TEST_F(KeymasterTest, DeleteKeyPair_RSA_DoubleDelete_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    /*
+     * This is only run if the module indicates it implements key deletion
+     * by implementing delete_keypair.
+     */
+    if (sDevice->delete_keypair != NULL) {
+        ASSERT_EQ(0,
+                sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                        &key_blob, &key_blob_length))
+                << "Should successfully import an RSA key";
+        UniqueBlob blob(key_blob, key_blob_length);
+
+        ASSERT_EQ(0, sDevice->delete_keypair(sDevice, key_blob, key_blob_length))
+                << "Should delete key after import";
+
+        ASSERT_EQ(-1, sDevice->delete_keypair(sDevice, key_blob, key_blob_length))
+                << "Should not be able to delete key twice";
+    }
+}
+
+TEST_F(KeymasterTest, DeleteKeyPair_RSA_NullKey_Failure) {
+    /*
+     * This is only run if the module indicates it implements key deletion
+     * by implementing delete_keypair.
+     */
+    if (sDevice->delete_keypair != NULL) {
+        ASSERT_EQ(-1, sDevice->delete_keypair(sDevice, NULL, 0))
+                << "Should not be able to delete null key";
+    }
+}
+
+/*
+ * DER-encoded PKCS#8 format RSA key. Generated using:
+ *
+ * openssl genrsa 512 | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1
+ */
+static uint8_t TEST_SIGN_RSA_KEY_1[] = {
+        0x30, 0x82, 0x01, 0x56, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+        0x01, 0x40, 0x30, 0x82, 0x01, 0x3C, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
+        0xBD, 0xC0, 0x7F, 0xEF, 0x75, 0x1D, 0x63, 0x2A, 0xD0, 0x9A, 0x26, 0xE5,
+        0x5B, 0xB9, 0x84, 0x7C, 0xE5, 0xC7, 0xE7, 0xDE, 0xFE, 0xB6, 0x54, 0xD9,
+        0xF0, 0x9B, 0xC2, 0xCF, 0x36, 0xDA, 0xE5, 0x4D, 0xC5, 0xD9, 0x25, 0x78,
+        0xBD, 0x55, 0x05, 0xBD, 0x86, 0xFB, 0x37, 0x15, 0x33, 0x42, 0x52, 0xED,
+        0xE5, 0xCD, 0xCB, 0xB7, 0xA2, 0x51, 0xFA, 0x36, 0xE9, 0x9C, 0x2E, 0x5D,
+        0xE3, 0xA5, 0x1F, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00,
+        0x96, 0x71, 0xDE, 0xBD, 0x83, 0x94, 0x96, 0x40, 0xA6, 0xFD, 0xE1, 0xA2,
+        0xED, 0xD3, 0xAC, 0x28, 0xBE, 0xA2, 0x7D, 0xC3, 0xFF, 0x1D, 0x9F, 0x2E,
+        0xE0, 0xA7, 0x0E, 0x90, 0xEE, 0x44, 0x25, 0x92, 0xE3, 0x54, 0xDD, 0x55,
+        0xA3, 0xEF, 0x42, 0xF5, 0x52, 0x55, 0x41, 0x47, 0x5E, 0x00, 0xFB, 0x8B,
+        0x47, 0x5E, 0x45, 0x49, 0xEA, 0x3D, 0x2C, 0xFD, 0x9F, 0xEC, 0xC8, 0x4E,
+        0x4E, 0x86, 0x90, 0x31, 0x02, 0x21, 0x00, 0xE6, 0xA5, 0x55, 0xB3, 0x64,
+        0xAB, 0x90, 0x5E, 0xA2, 0xF5, 0x6B, 0x21, 0x4B, 0x15, 0xD6, 0x4A, 0xB6,
+        0x60, 0x24, 0x95, 0x65, 0xA2, 0xBE, 0xBA, 0x2A, 0x73, 0xFB, 0xFF, 0x2C,
+        0x61, 0x88, 0x9D, 0x02, 0x21, 0x00, 0xD2, 0x9C, 0x5B, 0xFE, 0x82, 0xA5,
+        0xFC, 0x52, 0x6A, 0x29, 0x38, 0xDB, 0x22, 0x3B, 0xEB, 0x74, 0x3B, 0xCA,
+        0xB4, 0xDD, 0x1D, 0xE4, 0x48, 0x60, 0x70, 0x19, 0x9B, 0x81, 0xC1, 0x83,
+        0x28, 0xB5, 0x02, 0x21, 0x00, 0x89, 0x2D, 0xFE, 0xF9, 0xF2, 0xBF, 0x43,
+        0xDF, 0xB5, 0xA6, 0xA8, 0x30, 0x26, 0x1B, 0x77, 0xD7, 0xF9, 0xFE, 0xD6,
+        0xE3, 0x70, 0x8E, 0xCA, 0x47, 0xA9, 0xA6, 0x50, 0x54, 0x25, 0xCE, 0x60,
+        0xD5, 0x02, 0x21, 0x00, 0xBE, 0x5A, 0xF8, 0x82, 0xE6, 0xCE, 0xE3, 0x6A,
+        0x11, 0xED, 0xC4, 0x27, 0xBB, 0x9F, 0x70, 0xC6, 0x93, 0xAC, 0x39, 0x20,
+        0x89, 0x7D, 0xE5, 0x34, 0xD4, 0xDD, 0x30, 0x42, 0x6D, 0x07, 0x00, 0xE9,
+        0x02, 0x20, 0x05, 0x91, 0xEF, 0x12, 0xD2, 0xD3, 0x6A, 0xD2, 0x96, 0x6B,
+        0x10, 0x62, 0xF9, 0xBA, 0xA4, 0x91, 0x48, 0x84, 0x40, 0x61, 0x67, 0x80,
+        0x68, 0x68, 0xC8, 0x60, 0xB3, 0x66, 0xC8, 0xF9, 0x08, 0x9A,
+};
+
+/*
+ * DER-encoded PKCS#8 format EC key. Generated using:
+ *
+ * openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1
+ */
+static uint8_t TEST_SIGN_EC_KEY_1[] = {
+        0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86,
+        0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
+        0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02, 0x01, 0x01, 0x04, 0x20,
+        0x9E, 0x66, 0x11, 0x6A, 0x89, 0xF5, 0x78, 0x57, 0xF3, 0x35, 0xA2, 0x46,
+        0x09, 0x06, 0x4B, 0x4D, 0x81, 0xEC, 0xD3, 0x9B, 0x0A, 0xC4, 0x68, 0x06,
+        0xB8, 0x42, 0x24, 0x5E, 0x74, 0x2C, 0x62, 0x79, 0xA1, 0x44, 0x03, 0x42,
+        0x00, 0x04, 0x35, 0xB5, 0x9A, 0x5C, 0xE5, 0x52, 0x35, 0xF2, 0x10, 0x6C,
+        0xD9, 0x98, 0x67, 0xED, 0x5E, 0xCB, 0x6B, 0xB8, 0x96, 0x5E, 0x54, 0x7C,
+        0x34, 0x2A, 0xA3, 0x3B, 0xF3, 0xD1, 0x39, 0x48, 0x36, 0x7A, 0xEA, 0xD8,
+        0xCA, 0xDD, 0x40, 0x8F, 0xE9, 0xE0, 0x95, 0x2E, 0x3F, 0x95, 0x0F, 0x14,
+        0xD6, 0x14, 0x78, 0xB5, 0xAD, 0x17, 0xD2, 0x5A, 0x41, 0x96, 0x99, 0x20,
+        0xC7, 0x5B, 0x0F, 0x60, 0xFD, 0xBA
+};
+
+/*
+ * PKCS#1 v1.5 padded raw "Hello, world"  Can be generated be generated by verifying
+ * the signature below in no padding mode:
+ *
+ * openssl rsautl -keyform der -inkey rsa.der -raw -verify -in test.sig
+ */
+static uint8_t TEST_SIGN_DATA_1[] = {
+        0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x77,
+        0x6F, 0x72, 0x6C, 0x64,
+};
+
+/*
+ * Signature of TEST_SIGN_DATA_1 using TEST_SIGN_RSA_KEY_1. Generated using:
+ *
+ * echo 'Hello, world' | openssl rsautl -keyform der -inkey rsa.der -sign | recode ../x1
+ */
+static uint8_t TEST_SIGN_RSA_SIGNATURE_1[] = {
+        0xA4, 0xBB, 0x76, 0x87, 0xFE, 0x61, 0x0C, 0x9D, 0xD6, 0xFF, 0x4B, 0x76,
+        0x96, 0x08, 0x36, 0x23, 0x11, 0xC6, 0x44, 0x3F, 0x88, 0x77, 0x97, 0xB2,
+        0xA8, 0x3B, 0xFB, 0x9C, 0x3C, 0xD3, 0x20, 0x65, 0xFD, 0x26, 0x3B, 0x2A,
+        0xB8, 0xB6, 0xD4, 0xDC, 0x91, 0xF7, 0xE2, 0xDE, 0x4D, 0xF7, 0x0E, 0xB9,
+        0x72, 0xA7, 0x29, 0x72, 0x82, 0x12, 0x7C, 0x53, 0x23, 0x21, 0xC4, 0xFF,
+        0x79, 0xE4, 0x91, 0x40,
+};
+
+/*
+ * Identical to TEST_SIGN_RSA_SIGNATURE_1 except the last octet is '1' instead of '0'
+ * This should fail any test.
+ */
+static uint8_t TEST_SIGN_SIGNATURE_BOGUS_1[] = {
+        0xA4, 0xBB, 0x76, 0x87, 0xFE, 0x61, 0x0C, 0x9D, 0xD6, 0xFF, 0x4B, 0x76,
+        0x96, 0x08, 0x36, 0x23, 0x11, 0xC6, 0x44, 0x3F, 0x88, 0x77, 0x97, 0xB2,
+        0xA8, 0x3B, 0xFB, 0x9C, 0x3C, 0xD3, 0x20, 0x65, 0xFD, 0x26, 0x3B, 0x2A,
+        0xB8, 0xB6, 0xD4, 0xDC, 0x91, 0xF7, 0xE2, 0xDE, 0x4D, 0xF7, 0x0E, 0xB9,
+        0x72, 0xA7, 0x29, 0x72, 0x82, 0x12, 0x7C, 0x53, 0x23, 0x21, 0xC4, 0xFF,
+        0x79, 0xE4, 0x91, 0x41,
+};
+
+TEST_F(KeymasterTest, SignData_RSA_Raw_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    &sig, &sig_length))
+            << "Should sign data successfully";
+    UniqueBlob sig_blob(sig, sig_length);
+
+    UniqueBlob expected_sig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1));
+
+    ASSERT_EQ(expected_sig, sig_blob)
+            << "Generated signature should match expected signature";
+
+    // The expected signature is actually stack data, so don't let it try to free.
+    uint8_t* unused __attribute__((unused)) = expected_sig.release();
+}
+
+TEST_F(KeymasterTest, SignData_EC_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an EC key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_ec_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    &sig, &sig_length))
+            << "Should sign data successfully";
+    UniqueBlob sig_blob(sig, sig_length);
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(0,
+            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key successfully";
+    UniqueBlob x509_blob(x509_data, x509_data_length);
+
+    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
+    bssl::UniquePtr<EVP_PKEY> expected(d2i_PUBKEY(NULL, &tmp,
+            static_cast<long>(x509_blob.length())));
+
+    bssl::UniquePtr<EC_KEY> ecKey(EVP_PKEY_get1_EC_KEY(expected.get()));
+
+    ASSERT_EQ(1, ECDSA_verify(0, testData.get(), testData.length(), sig_blob.get(), sig_blob.length(), ecKey.get()))
+            << "Signature should verify";
+}
+
+TEST_F(KeymasterTest, SignData_RSA_Raw_InvalidSizeInput_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    &sig, &sig_length))
+            << "Should not be able to do raw signature on incorrect size data";
+}
+
+TEST_F(KeymasterTest, SignData_RSA_Raw_NullKey_Failure) {
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->sign_data(sDevice, &params, NULL, 0,
+                    testData.get(), testData.length(),
+                    &sig, &sig_length))
+            << "Should not be able to do raw signature on incorrect size data";
+}
+
+TEST_F(KeymasterTest, SignData_RSA_Raw_NullInput_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    ASSERT_EQ(-1,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    NULL, 0,
+                    &sig, &sig_length))
+            << "Should error when input data is null";
+}
+
+TEST_F(KeymasterTest, SignData_RSA_Raw_NullOutput_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    NULL, NULL))
+            << "Should error when output is null";
+}
+
+TEST_F(KeymasterTest, VerifyData_RSA_Raw_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    UniqueReadOnlyBlob testSig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1));
+    ASSERT_TRUE(testSig.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->verify_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    testSig.get(), testSig.length()))
+            << "Should verify data successfully";
+}
+
+TEST_F(KeymasterTest, VerifyData_EC_Raw_Success) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_ec_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+    };
+
+    uint8_t* sig;
+    size_t sig_length;
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->sign_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    &sig, &sig_length))
+            << "Should sign data successfully";
+    UniqueBlob sig_blob(sig, sig_length);
+
+    ASSERT_EQ(0,
+            sDevice->verify_data(sDevice, &params, key_blob, key_blob_length,
+                    testData.get(), testData.length(),
+                    sig_blob.get(), sig_blob.length()))
+            << "Should verify data successfully";
+}
+
+TEST_F(KeymasterTest, VerifyData_RSA_Raw_BadSignature_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    ASSERT_EQ(-1,
+            sDevice->verify_data(sDevice, &params, key_blob, key_blob_length,
+                    TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1),
+                    TEST_SIGN_SIGNATURE_BOGUS_1, sizeof(TEST_SIGN_SIGNATURE_BOGUS_1)))
+            << "Should sign data successfully";
+}
+
+TEST_F(KeymasterTest, VerifyData_EC_Raw_BadSignature_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_ec_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+    };
+
+    ASSERT_EQ(-1,
+            sDevice->verify_data(sDevice, &params, key_blob, key_blob_length,
+                    TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1),
+                    TEST_SIGN_SIGNATURE_BOGUS_1, sizeof(TEST_SIGN_SIGNATURE_BOGUS_1)))
+            << "Should sign data successfully";
+}
+
+TEST_F(KeymasterTest, VerifyData_RSA_Raw_NullKey_Failure) {
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    UniqueReadOnlyBlob testSig(TEST_SIGN_SIGNATURE_BOGUS_1, sizeof(TEST_SIGN_SIGNATURE_BOGUS_1));
+    ASSERT_TRUE(testSig.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->verify_data(sDevice, &params, NULL, 0,
+                    testData.get(), testData.length(),
+                    testSig.get(), testSig.length()))
+            << "Should fail when key is null";
+}
+
+TEST_F(KeymasterTest, VerifyData_RSA_NullInput_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    UniqueReadOnlyBlob testSig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1));
+    ASSERT_TRUE(testSig.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->verify_data(sDevice, &params, key_blob, key_blob_length,
+                    NULL, 0,
+                    testSig.get(), testSig.length()))
+            << "Should fail on null input";
+}
+
+TEST_F(KeymasterTest, VerifyData_RSA_NullSignature_Failure) {
+    uint8_t* key_blob;
+    size_t key_blob_length;
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key_blob, &key_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key(&sDevice, key_blob, key_blob_length);
+
+    keymaster_rsa_sign_params_t params = {
+            .digest_type = DIGEST_NONE,
+            .padding_type = PADDING_NONE,
+    };
+
+    UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1));
+    ASSERT_TRUE(testData.get() != NULL);
+
+    ASSERT_EQ(-1,
+            sDevice->verify_data(sDevice, &params, key.get(), key.length(),
+                    testData.get(), testData.length(),
+                    NULL, 0))
+            << "Should fail on null signature";
+}
+
+TEST_F(KeymasterTest, EraseAll_Success) {
+    uint8_t *key1_blob, *key2_blob;
+    size_t key1_blob_length, key2_blob_length;
+
+    // Only test this if the device says it supports delete_all
+    if (sDevice->delete_all == NULL) {
+        return;
+    }
+
+    UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey.get(), testKey.length(),
+                    &key1_blob, &key1_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key1(&sDevice, key1_blob, key1_blob_length);
+
+    UniqueReadOnlyBlob testKey2(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1));
+    ASSERT_TRUE(testKey2.get() != NULL);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, testKey2.get(), testKey2.length(),
+                    &key2_blob, &key2_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key2(&sDevice, key2_blob, key2_blob_length);
+
+    ASSERT_EQ(0, sDevice->delete_all(sDevice))
+            << "Should erase all keys";
+
+    key1.reset();
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key1_blob, key1_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key 1 successfully";
+
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key2_blob, key2_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key 2 successfully";
+}
+
+}
diff --git a/tests/nusensors/Android.bp b/tests/nusensors/Android.bp
index f06cf7a..8b267db 100644
--- a/tests/nusensors/Android.bp
+++ b/tests/nusensors/Android.bp
@@ -1,12 +1,3 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_libhardware_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_libhardware_license"],
-}
-
 cc_binary {
     name: "test-nusensors",