diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 02:07:25 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 02:07:25 +0000 |
commit | 1c6b854a7709811bf81a2706ec26cc08125f30d4 (patch) | |
tree | b69723eebf023f54d0e71be94f0d74a98cbcf77e | |
parent | db5579e3419c8c61ef7f2094ec5fa7e38a6e4267 (diff) | |
parent | 07c80fdaa0340d60e5be2ceff31037712859412b (diff) | |
download | libhardware-android-mainline-12.0.0_r52.tar.gz |
Snap for 7550930 from 07c80fdaa0340d60e5be2ceff31037712859412b to mainline-resolv-releaseandroid-mainline-12.0.0_r94android-mainline-12.0.0_r80android-mainline-12.0.0_r65android-mainline-12.0.0_r52android-mainline-12.0.0_r35android-mainline-12.0.0_r16android-mainline-12.0.0_r124android-mainline-12.0.0_r108android12-mainline-resolv-release
Change-Id: I1dcc35b0407904a4215650b1df18ffdb53992f42
46 files changed, 1387 insertions, 1664 deletions
@@ -1,5 +1,35 @@ // 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: [ @@ -29,6 +59,7 @@ cc_library_headers { }, }, min_sdk_version: "29", + host_supported: true, } diff --git a/METADATA b/METADATA new file mode 100644 index 00000000..d97975ca --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} @@ -1,4 +1,4 @@ -eisenbach@google.com +zachoverflow@google.com elaurent@google.com jpawlowski@google.com malchev@google.com diff --git a/include/hardware/audio.h b/include/hardware/audio.h index b87d3bb3..adec3da8 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -57,7 +57,8 @@ __BEGIN_DECLS #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_CURRENT AUDIO_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 /* Minimal audio HAL version supported by the audio framework */ #define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0 @@ -232,6 +233,20 @@ typedef struct sink_metadata { 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. * @@ -436,6 +451,88 @@ struct audio_stream_out { 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; @@ -600,6 +697,14 @@ struct audio_stream_in { */ 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; @@ -865,6 +970,18 @@ struct audio_hw_device { */ 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 6a17a351..476c311f 100644 --- a/include/hardware/audio_alsaops.h +++ b/include/hardware/audio_alsaops.h @@ -60,7 +60,7 @@ static inline enum pcm_format pcm_format_from_audio_format(audio_format_t format 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 0; + return PCM_FORMAT_INVALID; /* doesn't get here, assert called above */ } } @@ -94,7 +94,7 @@ static inline audio_format_t audio_format_from_pcm_format(enum pcm_format format #endif default: LOG_ALWAYS_FATAL("audio_format_from_pcm_format: invalid pcm format %#x", format); - return 0; + return AUDIO_FORMAT_INVALID; /* doesn't get here, assert called above */ } } diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h index 3fe6aa86..afa0eef7 100644 --- a/include/hardware/bluetooth.h +++ b/include/hardware/bluetooth.h @@ -258,19 +258,25 @@ typedef struct void *val; } bt_property_t; -/** 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; +/** 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 */ + + // 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 */ @@ -508,7 +514,8 @@ typedef struct { /** Create Bluetooth Bond using out of band data */ int (*create_bond_out_of_band)(const RawAddress *bd_addr, int transport, - const bt_out_of_band_data_t *oob_data); + const bt_oob_data_t *p192_data, + const bt_oob_data_t *p256_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 36a867da..abbf3f19 100644 --- a/include/hardware/boot_control.h +++ b/include/hardware/boot_control.h @@ -125,7 +125,14 @@ typedef struct boot_control_module { */ int (*isSlotMarkedSuccessful)(struct boot_control_module *module, unsigned slot); - void* reserved[31]; + /** + * 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]; } boot_control_module_t; diff --git a/include/hardware/keymaster0.h b/include/hardware/keymaster0.h deleted file mode 100644 index 52ac64b6..00000000 --- a/include/hardware/keymaster0.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 2fbfe46d..c0b3800e 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -71,6 +71,7 @@ typedef enum { 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 */ @@ -94,6 +95,8 @@ typedef enum { 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 */ @@ -115,8 +118,10 @@ typedef enum { 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. */ @@ -162,10 +167,14 @@ typedef enum { attestation */ KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717, /* Used to provide the device's model name to be included in attestation */ - KM_TAG_DEVICE_UNIQUE_ATTESTATION = KM_BOOL | 720, /* Indicates StrongBox device-unique attestation - is requested. */ + 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_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. */ @@ -177,8 +186,34 @@ typedef enum { * 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. */ + 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. */ } keymaster_tag_t; /** @@ -309,7 +344,8 @@ typedef enum { 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 { @@ -470,6 +506,13 @@ typedef enum { 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 a7467c29..1b343366 100644 --- a/modules/audio/Android.bp +++ b/modules/audio/Android.bp @@ -18,6 +18,15 @@ // // 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 95234380..53555f51 100644 --- a/modules/audio_remote_submix/Android.bp +++ b/modules/audio_remote_submix/Android.bp @@ -12,6 +12,15 @@ // 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 103f57dc..b43a44dc 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -196,6 +196,7 @@ struct submix_stream_in { 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. @@ -675,7 +676,8 @@ static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) { const struct submix_stream_out * const out = audio_stream_get_submix_stream_out( const_cast<struct audio_stream *>(stream)); - uint32_t channel_mask = out->dev->routes[out->route_handle].config.output_channel_mask; + audio_channel_mask_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; } @@ -835,7 +837,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 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 != 0)); + || (in->input_standby && (in->read_counter_frames_since_standby != 0)); if (dont_block && availableToWrite < frames) { static uint8_t flush_buffer[64]; const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size; @@ -1140,11 +1142,12 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, // 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 = 0; + in->read_counter_frames_since_standby = 0; } } in->read_counter_frames += frames_to_read; + in->read_counter_frames_since_standby += frames_to_read; size_t remaining_frames = frames_to_read; { @@ -1323,12 +1326,12 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, record_duration.tv_nsec += 1000000000; } - // 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 + // 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 // 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 + ((int64_t)(in->read_counter_frames_since_standby - (record_duration.tv_sec*sample_rate))) * 1000000 / sample_rate - (record_duration.tv_nsec / 1000); @@ -1352,6 +1355,37 @@ static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 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, ×tamp); + *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; @@ -1670,6 +1704,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, 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 @@ -1679,6 +1714,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, // 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 8e4d42d0..490a4026 100644 --- a/modules/audio_remote_submix/tests/Android.bp +++ b/modules/audio_remote_submix/tests/Android.bp @@ -12,6 +12,15 @@ // 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 6d6d1d78..d8aac4f9 100644 --- a/modules/camera/3_0/Android.bp +++ b/modules/camera/3_0/Android.bp @@ -12,6 +12,15 @@ // 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 0a11f684..aa230977 100644 --- a/modules/camera/3_4/Android.mk +++ b/modules/camera/3_4/Android.mk @@ -88,12 +88,14 @@ v4l2_test_files := \ # ============================================================================== 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_STATIC_LIBRARIES := \ - libgtest_prod \ - $(v4l2_static_libs) \ +LOCAL_HEADER_LIBRARIES := libgtest_prod_headers +LOCAL_STATIC_LIBRARIES := $(v4l2_static_libs) LOCAL_C_INCLUDES += $(v4l2_c_includes) LOCAL_SRC_FILES := $(v4l2_src_files) @@ -103,6 +105,9 @@ include $(BUILD_SHARED_LIBRARY) # ============================================================================== 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 4f700c2a..f33e4e55 100644 --- a/modules/consumerir/Android.bp +++ b/modules/consumerir/Android.bp @@ -12,6 +12,15 @@ // 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 22648b1b..5c95374b 100644 --- a/modules/fingerprint/Android.bp +++ b/modules/fingerprint/Android.bp @@ -12,6 +12,15 @@ // 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 ff5808db..439c95dd 100644 --- a/modules/gralloc/Android.mk +++ b/modules/gralloc/Android.mk @@ -31,6 +31,9 @@ LOCAL_SRC_FILES := \ 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 4f429be1..6a864c8f 100644 --- a/modules/hwcomposer/Android.bp +++ b/modules/hwcomposer/Android.bp @@ -14,6 +14,15 @@ // 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 26e711fd..9817c736 100644 --- a/modules/input/evdev/Android.bp +++ b/modules/input/evdev/Android.bp @@ -13,6 +13,15 @@ // 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", @@ -27,6 +36,7 @@ cc_library_shared { "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 1b2e749f..028fc725 100644 --- a/modules/input/evdev/SwitchInputMapper.cpp +++ b/modules/input/evdev/SwitchInputMapper.cpp @@ -49,9 +49,9 @@ static struct { {SW_LINEIN_INSERT, INPUT_USAGE_SWITCH_UNKNOWN}, {SW_MUTE_DEVICE, INPUT_USAGE_SWITCH_UNKNOWN}, {SW_PEN_INSERTED, 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}, + {SW_MACHINE_COVER, INPUT_USAGE_SWITCH_UNKNOWN}, + {0x11 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, + {0x12 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, {0x13 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, {0x14 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, {0x15 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, @@ -59,9 +59,21 @@ static struct { {0x17 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, {0x18 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, {0x19 /* unused */, INPUT_USAGE_SWITCH_UNKNOWN}, - {SW_MAX, 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}, }; +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 @@ -71,9 +83,9 @@ SwitchInputMapper::SwitchInputMapper() bool SwitchInputMapper::configureInputReport(InputDeviceNode* devNode, InputReportDefinition* report) { - InputUsage usages[SW_CNT]; + InputUsage usages[kMaxNumInputCodes]; int numUsages = 0; - for (int32_t i = 0; i < SW_CNT; ++i) { + for (int32_t i = 0; i < kMaxNumInputCodes; ++i) { if (devNode->hasSwitch(codeMap[i].scancode)) { usages[numUsages++] = codeMap[i].usage; } @@ -105,7 +117,7 @@ void SwitchInputMapper::process(const InputEvent& event) { void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) { ALOGV("processing switch event. code=%" PRId32 ", value=%" PRId32, switchCode, switchValue); - if (switchCode >= 0 && switchCode < SW_CNT) { + if (switchCode >= 0 && switchCode < kMaxNumInputCodes) { if (switchValue) { mSwitchValues.markBit(switchCode); } else { diff --git a/modules/local_time/Android.bp b/modules/local_time/Android.bp index 9f140b34..a4101c02 100644 --- a/modules/local_time/Android.bp +++ b/modules/local_time/Android.bp @@ -21,6 +21,15 @@ // 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 282e925a..31d89aa9 100644 --- a/modules/nfc-nci/Android.bp +++ b/modules/nfc-nci/Android.bp @@ -12,6 +12,15 @@ // 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 7c69f114..61fe1b88 100644 --- a/modules/nfc/Android.bp +++ b/modules/nfc/Android.bp @@ -12,6 +12,15 @@ // 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 6b0b31fb..4abcf375 100644 --- a/modules/power/Android.bp +++ b/modules/power/Android.bp @@ -12,6 +12,15 @@ // 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 7f98f0dc..7240869f 100644 --- a/modules/radio/Android.bp +++ b/modules/radio/Android.bp @@ -13,6 +13,15 @@ // 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 3d14bdf2..61590a5a 100644 --- a/modules/sensors/Android.bp +++ b/modules/sensors/Android.bp @@ -1,3 +1,12 @@ +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 2becc974..69889def 100644 --- a/modules/sensors/Android.mk +++ b/modules/sensors/Android.mk @@ -21,6 +21,9 @@ ifeq ($(USE_SENSOR_MULTI_HAL),true) 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 214d97cf..1ebc04d2 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -12,6 +12,15 @@ // 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 0eb43f8b..bbed0327 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/Android.bp +++ b/modules/sensors/dynamic_sensor/HidUtils/Android.bp @@ -12,6 +12,15 @@ // 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 aa5e8048..86cc593d 100644 --- a/modules/soundtrigger/Android.bp +++ b/modules/soundtrigger/Android.bp @@ -13,6 +13,15 @@ // 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 ab5c4089..9ac84d7f 100644 --- a/modules/thermal/Android.bp +++ b/modules/thermal/Android.bp @@ -12,6 +12,15 @@ // 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 b9d8afa0..13dd301a 100644 --- a/modules/tv_input/Android.bp +++ b/modules/tv_input/Android.bp @@ -12,6 +12,15 @@ // 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 c7d403f5..0be27c37 100644 --- a/modules/usbaudio/Android.bp +++ b/modules/usbaudio/Android.bp @@ -12,18 +12,43 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_library_shared { - name: "audio.usb.default", +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", 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 a19a0ae3..39c0fb5c 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -22,6 +22,7 @@ #include <pthread.h> #include <stdint.h> #include <stdlib.h> +#include <string.h> #include <sys/time.h> #include <unistd.h> @@ -68,6 +69,8 @@ struct audio_device { 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 { @@ -75,6 +78,12 @@ struct stream_lock { 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; @@ -84,10 +93,7 @@ struct stream_out { struct audio_device *adev; /* hardware information - only using this for the lock */ - alsa_device_profile profile; /* The profile of the ALSA device connected to the stream. - */ - - alsa_device_proxy proxy; /* state of the stream */ + struct listnode alsa_devices; /* The ALSA devices connected to the stream. */ unsigned hal_channel_count; /* channel count exposed to AudioFlinger. * This may differ from the device channel count when @@ -106,6 +112,12 @@ struct stream_out { * 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 { @@ -117,10 +129,7 @@ struct stream_in { struct audio_device *adev; /* hardware information - only using this for the lock */ - alsa_device_profile profile; /* The profile of the ALSA device connected to the stream. - */ - - alsa_device_proxy proxy; /* state of the stream */ + struct listnode alsa_devices; /* The ALSA devices connected to the stream. */ unsigned hal_channel_count; /* channel count exposed to AudioFlinger. * This may differ from the device channel count when @@ -140,7 +149,79 @@ struct stream_in { * 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 @@ -158,6 +239,9 @@ static void stream_lock_init(struct stream_lock *lock) { } 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); @@ -191,13 +275,52 @@ static void adev_add_stream_to_list( device_unlock(adev); } -static void adev_remove_stream_from_list( - struct audio_device* adev, struct listnode* stream_node) { - device_lock(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; +} - list_remove(stream_node); +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; +} - device_unlock(adev); +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; } /* @@ -278,6 +401,65 @@ static char *device_get_parameters(const alsa_device_profile *profile, const cha 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 */ @@ -286,12 +468,106 @@ static char *device_get_parameters(const alsa_device_profile *profile, const cha * 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) { - uint32_t rate = proxy_get_sample_rate(&((struct stream_out*)stream)->proxy); + 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); ALOGV("out_get_sample_rate() = %d", rate); return rate; } @@ -304,9 +580,12 @@ static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) static size_t out_get_buffer_size(const struct audio_stream *stream) { const struct stream_out* out = (const struct stream_out*)stream; - size_t buffer_size = - proxy_get_period_size(&out->proxy) * audio_stream_out_frame_size(&(out->stream)); - return buffer_size; + 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)); } static uint32_t out_get_channels(const struct audio_stream *stream) @@ -321,8 +600,13 @@ static audio_format_t out_get_format(const struct audio_stream *stream) * Relies on the framework to provide data in the specified format. * This could change in the future. */ - alsa_device_proxy * proxy = &((struct stream_out*)stream)->proxy; - audio_format_t format = audio_format_from_pcm_format(proxy_get_format(proxy)); + 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)); return format; } @@ -336,10 +620,9 @@ static int out_standby(struct audio_stream *stream) struct stream_out *out = (struct stream_out *)stream; stream_lock(&out->lock); - if (!out->standby) { - proxy_close(&out->proxy); - out->standby = true; - } + device_lock(out->adev); + stream_standby_l(&out->alsa_devices, &out->standby); + device_unlock(out->adev); stream_unlock(&out->lock); return 0; } @@ -348,67 +631,44 @@ static int out_dump(const struct audio_stream *stream, int fd) { const struct stream_out* out_stream = (const struct stream_out*) stream; if (out_stream != NULL) { - dprintf(fd, "Output Profile:\n"); - profile_dump(&out_stream->profile, fd); - - dprintf(fd, "Output Proxy:\n"); - proxy_dump(&out_stream->proxy, fd); + stream_dump_alsa_devices(&out_stream->alsa_devices, fd); } return 0; } -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) +static int out_set_parameters(struct audio_stream *stream __unused, const char *kvpairs) { ALOGV("out_set_parameters() keys:%s", kvpairs); - 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; + // 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; } 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); - char * params_str = device_get_parameters(&out->profile, keys); + 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); + } stream_unlock(&out->lock); return params_str; } static uint32_t out_get_latency(const struct audio_stream_out *stream) { - alsa_device_proxy * proxy = &((struct stream_out*)stream)->proxy; - return proxy_get_latency(proxy); + 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); } static int out_set_volume(struct audio_stream_out *stream, float left, float right) @@ -419,9 +679,31 @@ static int out_set_volume(struct audio_stream_out *stream, float left, float rig /* must be called with hw device and output stream mutexes locked */ static int start_output_stream(struct stream_out *out) { - ALOGV("start_output_stream(card:%d device:%d)", out->profile.card, out->profile.device); + 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; + } + } + +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 proxy_open(&out->proxy); + } + return status; } static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) @@ -438,32 +720,37 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si out->standby = false; } - 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); + 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; } - /* 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(&out->proxy, write_buff, num_write_buff_bytes); + if (write_buff != NULL && num_write_buff_bytes != 0) { + proxy_write(proxy, write_buff, num_write_buff_bytes); + } } stream_unlock(&out->lock); @@ -491,9 +778,9 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, struct stream_out *out = (struct stream_out *)stream; // discard const qualifier stream_lock(&out->lock); - const alsa_device_proxy *proxy = &out->proxy; - const int ret = proxy_get_presentation_position(proxy, frames, timestamp); - + 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); stream_unlock(&out->lock); return ret; } @@ -551,30 +838,35 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, 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; - profile_init(&out->profile, PCM_OUT); + 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); // build this to hand to the alsa_device_proxy - struct pcm_config proxy_config; - memset(&proxy_config, 0, sizeof(proxy_config)); + struct pcm_config proxy_config = {}; /* Pull out the card/device pair */ - parse_card_device_params(address, &out->profile.card, &out->profile.device); + parse_card_device_params(address, &device_info->profile.card, &device_info->profile.device); - profile_read_device_info(&out->profile); + profile_read_device_info(&device_info->profile); int ret = 0; /* Rate */ if (config->sample_rate == 0) { - 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 = 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; } else { - proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&out->profile); + proxy_config.rate = config->sample_rate = + profile_get_default_sample_rate(&device_info->profile); ret = -EINVAL; } @@ -585,14 +877,14 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, /* Format */ if (config->format == AUDIO_FORMAT_DEFAULT) { - proxy_config.format = profile_get_default_format(&out->profile); + proxy_config.format = profile_get_default_format(&device_info->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(&out->profile, fmt)) { + if (profile_is_format_valid(&device_info->profile, fmt)) { proxy_config.format = fmt; } else { - proxy_config.format = profile_get_default_format(&out->profile); + proxy_config.format = profile_get_default_format(&device_info->profile); config->format = audio_format_from_pcm_format(proxy_config.format); ret = -EINVAL; } @@ -602,7 +894,7 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, bool calc_mask = false; if (config->channel_mask == AUDIO_CHANNEL_NONE) { /* query case */ - out->hal_channel_count = profile_get_default_channel_count(&out->profile); + out->hal_channel_count = profile_get_default_channel_count(&device_info->profile); calc_mask = true; } else { /* explicit case */ @@ -610,19 +902,19 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, } /* The Framework is currently limited to no more than this number of channels */ - if (out->hal_channel_count > FCC_8) { - out->hal_channel_count = FCC_8; + if (out->hal_channel_count > FCC_LIMIT) { + out->hal_channel_count = FCC_LIMIT; 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 then the FW can handle */ + * or the specified mask isn't valid for this device, or is more than 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; @@ -631,8 +923,11 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, // 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(&out->profile, out->hal_channel_count); - proxy_prepare(&out->proxy, &out->profile, &proxy_config); + 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); /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger * So clear any errors that may have occurred above. @@ -656,21 +951,22 @@ static void adev_close_output_stream(struct audio_hw_device *hw_dev, 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 */ - out_standby(&stream->common); + stream_standby_l(&out->alsa_devices, &out->standby); + stream_clear_devices(&out->alsa_devices); 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); } @@ -687,7 +983,13 @@ static size_t adev_get_input_buffer_size(const struct audio_hw_device *hw_dev, */ static uint32_t in_get_sample_rate(const struct audio_stream *stream) { - uint32_t rate = proxy_get_sample_rate(&((const struct stream_in *)stream)->proxy); + 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); ALOGV("in_get_sample_rate() = %d", rate); return rate; } @@ -701,7 +1003,12 @@ static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) static size_t in_get_buffer_size(const struct audio_stream *stream) { const struct stream_in * in = ((const struct stream_in*)stream); - return proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(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)); } static uint32_t in_get_channels(const struct audio_stream *stream) @@ -712,7 +1019,13 @@ static uint32_t in_get_channels(const struct audio_stream *stream) static audio_format_t in_get_format(const struct audio_stream *stream) { - alsa_device_proxy *proxy = &((struct stream_in*)stream)->proxy; + 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; audio_format_t format = audio_format_from_pcm_format(proxy_get_format(proxy)); return format; } @@ -729,12 +1042,10 @@ static int in_standby(struct audio_stream *stream) struct stream_in *in = (struct stream_in *)stream; stream_lock(&in->lock); - if (!in->standby) { - proxy_close(&in->proxy); - in->standby = true; - } + device_lock(in->adev); + stream_standby_l(&in->alsa_devices, &in->standby); + device_unlock(in->adev); stream_unlock(&in->lock); - return 0; } @@ -742,11 +1053,7 @@ static int in_dump(const struct audio_stream *stream, int fd) { const struct stream_in* in_stream = (const struct stream_in*)stream; if (in_stream != NULL) { - dprintf(fd, "Input Profile:\n"); - profile_dump(&in_stream->profile, fd); - - dprintf(fd, "Input Proxy:\n"); - proxy_dump(&in_stream->proxy, fd); + stream_dump_alsa_devices(&in_stream->alsa_devices, fd); } return 0; @@ -756,42 +1063,10 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) { ALOGV("in_set_parameters() keys:%s", kvpairs); - 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; + // 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; } static char * in_get_parameters(const struct audio_stream *stream, const char *keys) @@ -799,7 +1074,11 @@ static char * in_get_parameters(const struct audio_stream *stream, const char *k struct stream_in *in = (struct stream_in *)stream; stream_lock(&in->lock); - char * params_str = device_get_parameters(&in->profile, keys); + 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); + } stream_unlock(&in->lock); return params_str; @@ -823,9 +1102,15 @@ static int in_set_gain(struct audio_stream_in *stream, float gain) /* must be called with hw device and output stream mutexes locked */ static int start_input_stream(struct stream_in *in) { - ALOGV("start_input_stream(card:%d device:%d)", in->profile.card, in->profile.device); + // 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; + } - return proxy_open(&in->proxy); + ALOGV("start_input_stream(card:%d device:%d)", + device_info->profile.card, device_info->profile.device); + return proxy_open(&device_info->proxy); } /* TODO mutex stuff here (see out_write) */ @@ -847,12 +1132,18 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte 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(&in->proxy); /* what we told Alsa */ + int num_device_channels = proxy_get_channel_count(&device_info->proxy); /* what we told Alsa */ int num_req_channels = in->hal_channel_count; /* what we told AudioFlinger */ if (num_device_channels != num_req_channels) { @@ -870,7 +1161,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte read_buff = in->conversion_buffer; } - ret = proxy_read(&in->proxy, read_buff, num_read_buff_bytes); + ret = proxy_read(&device_info->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); @@ -911,8 +1202,10 @@ static int in_get_capture_position(const struct audio_stream_in *stream, struct stream_in *in = (struct stream_in *)stream; // discard const qualifier stream_lock(&in->lock); - const alsa_device_proxy *proxy = &in->proxy; - const int ret = proxy_get_capture_position(proxy, frames, time); + 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); stream_unlock(&in->lock); return ret; @@ -991,14 +1284,18 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, 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; - profile_init(&in->profile, PCM_IN); + 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); - struct pcm_config proxy_config; - memset(&proxy_config, 0, sizeof(proxy_config)); + memset(&in->config, 0, sizeof(in->config)); int ret = 0; device_lock(in->adev); @@ -1007,16 +1304,16 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, /* Check if an input stream is already open */ if (num_open_inputs > 0) { - if (!profile_is_cached_for(&in->profile, card, device)) { + if (!profile_is_cached_for(&device_info->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 */ - in->profile.card = card; - in->profile.device = device; - if (!profile_read_device_info(&in->profile)) { + device_info->profile.card = card; + device_info->profile.device = device; + if (!profile_read_device_info(&device_info->profile)) { ALOGW("%s fail - cannot read profile", __func__); ret = -EINVAL; } @@ -1030,19 +1327,19 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, /* Rate */ int request_config_rate = config->sample_rate; if (config->sample_rate == 0) { - config->sample_rate = profile_get_default_sample_rate(&in->profile); + config->sample_rate = profile_get_default_sample_rate(&device_info->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(&in->profile); + unsigned highest_rate = profile_get_highest_sample_rate(&device_info->profile); if (highest_rate == 0) { ret = -EINVAL; /* error with device */ } else { - proxy_config.rate = config->sample_rate = + in->config.rate = config->sample_rate = min(highest_rate, in->adev->device_sample_rate); - if (request_config_rate != 0 && proxy_config.rate != config->sample_rate) { + if (request_config_rate != 0 && in->config.rate != config->sample_rate) { /* Changing the requested rate */ ret = -EINVAL; } else { @@ -1051,24 +1348,25 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, } } } - } else if (profile_is_sample_rate_valid(&in->profile, config->sample_rate)) { - proxy_config.rate = config->sample_rate; + } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) { + in->config.rate = config->sample_rate; } else { - proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&in->profile); + in->config.rate = config->sample_rate = + profile_get_default_sample_rate(&device_info->profile); ret = -EINVAL; } /* Format */ if (config->format == AUDIO_FORMAT_DEFAULT) { - proxy_config.format = profile_get_default_format(&in->profile); - config->format = audio_format_from_pcm_format(proxy_config.format); + in->config.format = profile_get_default_format(&device_info->profile); + config->format = audio_format_from_pcm_format(in->config.format); } else { enum pcm_format fmt = pcm_format_from_audio_format(config->format); - if (profile_is_format_valid(&in->profile, fmt)) { - proxy_config.format = fmt; + if (profile_is_format_valid(&device_info->profile, fmt)) { + in->config.format = fmt; } else { - proxy_config.format = profile_get_default_format(&in->profile); - config->format = audio_format_from_pcm_format(proxy_config.format); + in->config.format = profile_get_default_format(&device_info->profile); + config->format = audio_format_from_pcm_format(in->config.format); ret = -EINVAL; } } @@ -1077,7 +1375,7 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, bool calc_mask = false; if (config->channel_mask == AUDIO_CHANNEL_NONE) { /* query case */ - in->hal_channel_count = profile_get_default_channel_count(&in->profile); + in->hal_channel_count = profile_get_default_channel_count(&device_info->profile); calc_mask = true; } else { /* explicit case */ @@ -1085,14 +1383,14 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, } /* The Framework is currently limited to no more than this number of channels */ - if (in->hal_channel_count > FCC_8) { - in->hal_channel_count = FCC_8; + if (in->hal_channel_count > FCC_LIMIT) { + in->hal_channel_count = FCC_LIMIT; 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 then the FW can handle */ + * or the specified mask isn't valid for this device, or is more than 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) @@ -1113,9 +1411,9 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, // 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 - proxy_config.channels = - profile_get_closest_channel_count(&in->profile, in->hal_channel_count); - ret = proxy_prepare(&in->proxy, &in->profile, &proxy_config); + 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); if (ret == 0) { in->standby = true; @@ -1128,12 +1426,12 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, 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(&in->proxy); + unsigned channel_count = proxy_get_channel_count(&device_info->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(&in->proxy)); - config->sample_rate = proxy_get_sample_rate(&in->proxy); + config->format = audio_format_from_pcm_format(proxy_get_format(&device_info->proxy)); + config->sample_rate = proxy_get_sample_rate(&device_info->proxy); } } @@ -1145,6 +1443,8 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, return ret; } + list_add_tail(&in->alsa_devices, &device_info->list_node); + device_lock(in->adev); ++in->adev->inputs_open; device_unlock(in->adev); @@ -1156,18 +1456,25 @@ static void adev_close_input_stream(struct audio_hw_device *hw_dev, 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); - - adev_remove_stream_from_list(in->adev, &in->list_node); + stream_lock(&in->lock); 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); - /* Close the pcm device */ - in_standby(&stream->common); + stream_clear_devices(&in->alsa_devices); + stream_unlock(&in->lock); free(in->conversion_buffer); @@ -1221,6 +1528,282 @@ static int adev_get_mic_mute(const struct audio_hw_device *hw_dev, bool *state) 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"); @@ -1290,7 +1873,7 @@ static int adev_open(const hw_module_t* module, const char* name, hw_device_t** list_init(&adev->input_stream_list); adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; - adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; + adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_3_2; adev->hw_device.common.module = (struct hw_module_t *)module; adev->hw_device.common.close = adev_close; @@ -1307,6 +1890,10 @@ static int adev_open(const hw_module_t* module, const char* name, hw_device_t** 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 5e44d3c4..07eb85b2 100644 --- a/modules/usbcamera/Android.bp +++ b/modules/usbcamera/Android.bp @@ -12,6 +12,15 @@ // 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 13ffc835..2412d4d1 100644 --- a/modules/vibrator/Android.bp +++ b/modules/vibrator/Android.bp @@ -12,6 +12,15 @@ // 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 40f4510c..121939be 100644 --- a/modules/vr/Android.bp +++ b/modules/vr/Android.bp @@ -12,6 +12,15 @@ // 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 55486ba0..6d430669 100644 --- a/tests/camera3/Android.bp +++ b/tests/camera3/Android.bp @@ -1,3 +1,12 @@ +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 9524b7ba..9827e893 100644 --- a/tests/fingerprint/Android.bp +++ b/tests/fingerprint/Android.bp @@ -1,3 +1,12 @@ +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 2f5db126..b1376840 100644 --- a/tests/hardware/Android.bp +++ b/tests/hardware/Android.bp @@ -1,3 +1,12 @@ +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 782a314f..82a00e40 100644 --- a/tests/hwc/Android.bp +++ b/tests/hwc/Android.bp @@ -1,3 +1,12 @@ +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 fa03a007..10fa1461 100644 --- a/tests/input/evdev/Android.bp +++ b/tests/input/evdev/Android.bp @@ -1,3 +1,12 @@ +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 deleted file mode 100644 index 8c027e04..00000000 --- a/tests/keymaster/Android.bp +++ /dev/null @@ -1,17 +0,0 @@ -// 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 deleted file mode 100644 index 562c8ed3..00000000 --- a/tests/keymaster/keymaster_test.cpp +++ /dev/null @@ -1,1243 +0,0 @@ -/* - * 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, ¶ms, &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, ¶ms, &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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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 8b267dba..f06cf7a0 100644 --- a/tests/nusensors/Android.bp +++ b/tests/nusensors/Android.bp @@ -1,3 +1,12 @@ +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", |