summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/hardware/fingerprint.h82
-rw-r--r--include/hardware/gatekeeper.h29
-rw-r--r--include/hardware/keymaster_defs.h73
-rw-r--r--include/hardware/sensors.h31
-rw-r--r--modules/usbaudio/audio_hal.c77
5 files changed, 185 insertions, 107 deletions
diff --git a/include/hardware/fingerprint.h b/include/hardware/fingerprint.h
index fd0d8f3..075e18b 100644
--- a/include/hardware/fingerprint.h
+++ b/include/hardware/fingerprint.h
@@ -102,6 +102,35 @@ typedef struct fingerprint_device {
struct hw_device_t common;
/*
+ * Client provided callback function to receive notifications.
+ * Do not set by hand, use the function above instead.
+ */
+ fingerprint_notify_t notify;
+
+ /*
+ * Set notification callback:
+ * Registers a user function that would receive notifications from the HAL
+ * The call will block if the HAL state machine is in busy state until HAL
+ * leaves the busy state.
+ *
+ * Function return: 0 if callback function is successfuly registered
+ * or a negative number in case of error, generally from the errno.h set.
+ */
+ int (*set_notify)(struct fingerprint_device *dev, fingerprint_notify_t notify);
+
+ /*
+ * Fingerprint pre-enroll enroll request:
+ * Generates a unique token to upper layers to indicate the start of an enrollment transaction.
+ * This token will be wrapped by security for verification and passed to enroll() for
+ * verification before enrollment will be allowed. This is to ensure adding a new fingerprint
+ * template was preceded by some kind of credential confirmation (e.g. device password).
+ *
+ * Function return: 0 if function failed
+ * otherwise, a uint64_t of token
+ */
+ uint64_t (*pre_enroll)(struct fingerprint_device *dev);
+
+ /*
* Fingerprint enroll request:
* Switches the HAL state machine to collect and store a new fingerprint
* template. Switches back as soon as enroll is complete
@@ -112,23 +141,21 @@ typedef struct fingerprint_device {
* to supply the gid or set it to 0 in which case a unique group id will be generated.
*
* Function return: 0 if enrollment process can be successfully started
- * -1 otherwise. A notify() function may be called
- * indicating the error condition.
+ * or a negative number in case of error, generally from the errno.h set.
+ * A notify() function may be called indicating the error condition.
*/
int (*enroll)(struct fingerprint_device *dev, const hw_auth_token_t *hat,
uint32_t gid, uint32_t timeout_sec);
/*
- * Fingerprint pre-enroll enroll request:
- * Generates a unique token to upper layers to indicate the start of an enrollment transaction.
- * This token will be wrapped by security for verification and passed to enroll() for
- * verification before enrollment will be allowed. This is to ensure adding a new fingerprint
- * template was preceded by some kind of credential confirmation (e.g. device password).
+ * Finishes the enroll operation and invalidates the pre_enroll() generated challenge.
+ * This will be called at the end of a multi-finger enrollment session to indicate
+ * that no more fingers will be added.
*
- * Function return: 0 if function failed
- * otherwise, a uint64_t of token
+ * Function return: 0 if the request is accepted
+ * or a negative number in case of error, generally from the errno.h set.
*/
- uint64_t (*pre_enroll)(struct fingerprint_device *dev);
+ int (*post_enroll)(struct fingerprint_device *dev);
/*
* get_authenticator_id:
@@ -136,17 +163,17 @@ typedef struct fingerprint_device {
* change whenever a new fingerprint is enrolled, thus creating a new fingerprint
* set.
*
- * Function return: current authenticator id.
+ * Function return: current authenticator id or 0 if function failed.
*/
uint64_t (*get_authenticator_id)(struct fingerprint_device *dev);
/*
* Cancel pending enroll or authenticate, sending FINGERPRINT_ERROR_CANCELED
* to all running clients. Switches the HAL state machine back to the idle state.
- * will indicate switch back to the scan mode.
+ * Unlike enroll_done() doesn't invalidate the pre_enroll() challenge.
*
* Function return: 0 if cancel request is accepted
- * -1 otherwise.
+ * or a negative number in case of error, generally from the errno.h set.
*/
int (*cancel)(struct fingerprint_device *dev);
@@ -165,9 +192,8 @@ typedef struct fingerprint_device {
* The caller of this function has a complete list of the templates when *max_size
* is the same as the function return.
*
- * Function return: Total number of fingerprint templates in the current
- storage directory.
- * -1 on error.
+ * Function return: Total number of fingerprint templates in the current storage directory.
+ * or a negative number in case of error, generally from the errno.h set.
*/
int (*enumerate)(struct fingerprint_device *dev, fingerprint_finger_id_t *results,
uint32_t *max_size);
@@ -181,7 +207,7 @@ typedef struct fingerprint_device {
* fingerprint_msg.data.removed.id indicating the template id removed.
*
* Function return: 0 if fingerprint template(s) can be successfully deleted
- * -1 otherwise.
+ * or a negative number in case of error, generally from the errno.h set.
*/
int (*remove)(struct fingerprint_device *dev, uint32_t gid, uint32_t fid);
@@ -192,7 +218,7 @@ typedef struct fingerprint_device {
* data directory.
*
* Function return: 0 on success
- * -1 if the group does not exist.
+ * or a negative number in case of error, generally from the errno.h set.
*/
int (*set_active_group)(struct fingerprint_device *dev, uint32_t gid,
const char *store_path);
@@ -201,26 +227,12 @@ typedef struct fingerprint_device {
* Authenticates an operation identifed by operation_id
*
* Function return: 0 on success
- * -1 if the operation cannot be completed
+ * or a negative number in case of error, generally from the errno.h set.
*/
int (*authenticate)(struct fingerprint_device *dev, uint64_t operation_id, uint32_t gid);
- /*
- * Set notification callback:
- * Registers a user function that would receive notifications from the HAL
- * The call will block if the HAL state machine is in busy state until HAL
- * leaves the busy state.
- *
- * Function return: 0 if callback function is successfuly registered
- * -1 otherwise.
- */
- int (*set_notify)(struct fingerprint_device *dev, fingerprint_notify_t notify);
-
- /*
- * Client provided callback function to receive notifications.
- * Do not set by hand, use the function above instead.
- */
- fingerprint_notify_t notify;
+ /* Reserved for backward binary compatibility */
+ void *reserved[4];
} fingerprint_device_t;
typedef struct fingerprint_module {
diff --git a/include/hardware/gatekeeper.h b/include/hardware/gatekeeper.h
index 6d2fb0b..2bb2b08 100644
--- a/include/hardware/gatekeeper.h
+++ b/include/hardware/gatekeeper.h
@@ -143,7 +143,36 @@ struct gatekeeper_device {
const uint8_t *provided_password, uint32_t provided_password_length,
uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
+ /*
+ * Deletes the enrolled_password_handle associated wth the uid. Once deleted
+ * the user cannot be verified anymore.
+ * This function is optional and should be set to NULL if it is not implemented.
+ *
+ * Parameters
+ * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open
+ * - uid: the Android user identifier
+ *
+ * Returns:
+ * - 0 on success
+ * - An error code < 0 on failure
+ */
+ int (*delete_user)(const struct gatekeeper_device *dev, uint32_t uid);
+
+ /*
+ * Deletes all the enrolled_password_handles for all uid's. Once called,
+ * no users will be enrolled on the device.
+ * This function is optional and should be set to NULL if it is not implemented.
+ *
+ * Parameters
+ * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open
+ *
+ * Returns:
+ * - 0 on success
+ * - An error code < 0 on failure
+ */
+ int (*delete_all_users)(const struct gatekeeper_device *dev);
};
+
typedef struct gatekeeper_device gatekeeper_device_t;
static inline int gatekeeper_open(const struct hw_module_t *module,
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index 77067d5..32374f1 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -34,14 +34,14 @@ typedef enum {
KM_INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
KM_ENUM = 1 << 28,
KM_ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
- KM_INT = 3 << 28,
- KM_INT_REP = 4 << 28, /* Repeatable integer value */
- KM_LONG = 5 << 28,
+ KM_UINT = 3 << 28,
+ KM_UINT_REP = 4 << 28, /* Repeatable integer value */
+ KM_ULONG = 5 << 28,
KM_DATE = 6 << 28,
KM_BOOL = 7 << 28,
KM_BIGNUM = 8 << 28,
KM_BYTES = 9 << 28,
- KM_LONG_REP = 10 << 28, /* Repeatable long value */
+ KM_ULONG_REP = 10 << 28, /* Repeatable long value */
} keymaster_tag_type_t;
typedef enum {
@@ -54,14 +54,14 @@ typedef enum {
/* Crypto parameters */
KM_TAG_PURPOSE = KM_ENUM_REP | 1, /* keymaster_purpose_t. */
KM_TAG_ALGORITHM = KM_ENUM | 2, /* keymaster_algorithm_t. */
- KM_TAG_KEY_SIZE = KM_INT | 3, /* Key size in bits. */
+ KM_TAG_KEY_SIZE = KM_UINT | 3, /* Key size in bits. */
KM_TAG_BLOCK_MODE = KM_ENUM_REP | 4, /* keymaster_block_mode_t. */
KM_TAG_DIGEST = KM_ENUM_REP | 5, /* keymaster_digest_t. */
KM_TAG_PADDING = KM_ENUM_REP | 6, /* keymaster_padding_t. */
KM_TAG_CALLER_NONCE = KM_BOOL | 7, /* Allow caller to specify nonce or IV. */
/* Algorithm-specific. */
- KM_TAG_RSA_PUBLIC_EXPONENT = KM_LONG | 200, /* Defaults to 2^16+1 */
+ KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200,
/* Other hardware-enforced. */
KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 301, /* keymaster_key_blob_usage_requirements_t */
@@ -78,34 +78,32 @@ typedef enum {
longer be created. */
KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402, /* Date when existing "messages" should no
longer be trusted. */
- KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_INT | 403, /* Minimum elapsed time between
+ KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_UINT | 403, /* Minimum elapsed time between
cryptographic operations with the key. */
- KM_TAG_MAX_USES_PER_BOOT = KM_INT | 404, /* Number of times the key can be used per
+ KM_TAG_MAX_USES_PER_BOOT = KM_UINT | 404, /* Number of times the key can be used per
boot. */
/* User authentication */
- KM_TAG_ALL_USERS = KM_BOOL | 500, /* If key is usable by all users. */
- KM_TAG_USER_ID = KM_INT | 501, /* ID of authorized user. Disallowed if
- KM_TAG_ALL_USERS is present. */
- KM_TAG_USER_SECURE_ID = KM_LONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
- Disallowed if KM_TAG_ALL_USERS or
- KM_TAG_NO_AUTH_REQUIRED is present. */
- KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503, /* If key is usable without authentication. */
- KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504, /* Bitmask of authenticator types allowed when
- * KM_TAG_USER_SECURE_ID contains a secure user ID,
- * rather than a secure authenticator ID. Defined in
- * hw_authenticator_type_t in hw_auth_token.h. */
- KM_TAG_AUTH_TIMEOUT = KM_INT | 505, /* Required freshness of user authentication for
- private/secret key operations, in seconds.
- Public key operations require no authentication.
- If absent, authentication is required for every
- use. Authentication state is lost when the
- device is powered off. */
+ KM_TAG_ALL_USERS = KM_BOOL | 500, /* Reserved for future use -- ignore */
+ KM_TAG_USER_ID = KM_UINT | 501, /* Reserved for future use -- ignore */
+ KM_TAG_USER_SECURE_ID = KM_ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
+ Disallowed if KM_TAG_ALL_USERS or
+ KM_TAG_NO_AUTH_REQUIRED is present. */
+ KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503, /* If key is usable without authentication. */
+ KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504, /* Bitmask of authenticator types allowed when
+ * KM_TAG_USER_SECURE_ID contains a secure user ID,
+ * rather than a secure authenticator ID. Defined in
+ * hw_authenticator_type_t in hw_auth_token.h. */
+ KM_TAG_AUTH_TIMEOUT = KM_UINT | 505, /* Required freshness of user authentication for
+ private/secret key operations, in seconds.
+ Public key operations require no authentication.
+ If absent, authentication is required for every
+ use. Authentication state is lost when the
+ device is powered off. */
/* Application access control */
- KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* If key is usable by all applications. */
- KM_TAG_APPLICATION_ID = KM_BYTES | 601, /* ID of authorized application. Disallowed if
- KM_TAG_ALL_APPLICATIONS is present. */
+ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Reserved for future use -- ignore */
+ KM_TAG_APPLICATION_ID = KM_BYTES | 601, /* Reserved for fugure use -- ignore */
/*
* Semantically unenforceable tags, either because they have no specific meaning or because
@@ -121,13 +119,10 @@ typedef enum {
/* 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. */
KM_TAG_NONCE = KM_BYTES | 1001, /* Nonce or Initialization Vector */
- KM_TAG_AEAD_TAG = KM_BYTES | 1002, /* AEAD tag data. Returned from finish() during AEAD
- * encryption and provided to begin() during AEAD
- * decryption.*/
- KM_TAG_AUTH_TOKEN = KM_BYTES | 1003, /* Authentication token that proves secure user
+ KM_TAG_AUTH_TOKEN = KM_BYTES | 1002, /* Authentication token that proves secure user
authentication has been performed. Structure
defined in hw_auth_token_t in hw_auth_token.h. */
- KM_TAG_MAC_LENGTH = KM_INT | 1004, /* MAC or AEAD authentication tag length in bits. */
+ KM_TAG_MAC_LENGTH = KM_UINT | 1003, /* MAC or AEAD authentication tag length in bits. */
} keymaster_tag_t;
/**
@@ -338,7 +333,9 @@ typedef enum {
KM_ERROR_MISSING_NONCE = -51,
KM_ERROR_INVALID_NONCE = -52,
KM_ERROR_MISSING_MAC_LENGTH = -53,
+ KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54,
KM_ERROR_CALLER_NONCE_PROHIBITED = -55,
+ KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56,
KM_ERROR_UNIMPLEMENTED = -100,
KM_ERROR_VERSION_MISMATCH = -101,
@@ -360,7 +357,7 @@ static inline uint32_t keymaster_tag_mask_type(keymaster_tag_t tag) {
static inline bool keymaster_tag_type_repeatable(keymaster_tag_type_t type) {
switch (type) {
- case KM_INT_REP:
+ case KM_UINT_REP:
case KM_ENUM_REP:
return true;
default:
@@ -443,11 +440,11 @@ inline int keymaster_param_compare(const keymaster_key_param_t* a, const keymast
case KM_ENUM:
case KM_ENUM_REP:
return KEYMASTER_SIMPLE_COMPARE(a->enumerated, b->enumerated);
- case KM_INT:
- case KM_INT_REP:
+ case KM_UINT:
+ case KM_UINT_REP:
return KEYMASTER_SIMPLE_COMPARE(a->integer, b->integer);
- case KM_LONG:
- case KM_LONG_REP:
+ case KM_ULONG:
+ case KM_ULONG_REP:
return KEYMASTER_SIMPLE_COMPARE(a->long_integer, b->long_integer);
case KM_DATE:
return KEYMASTER_SIMPLE_COMPARE(a->date_time, b->date_time);
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index b8b550f..b368ee6 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -108,12 +108,12 @@ enum {
*/
SENSOR_HAL_NORMAL_MODE = 0,
- /*
- * Loopback mode. In this mode, the device shall not source data from the
+ /*
+ * Data Injection mode. In this mode, the device shall not source data from the
* physical sensors as it would in normal mode. Instead sensor data is
* injected by the sensor service.
*/
- SENSOR_HAL_LOOPBACK_MODE = 0x1
+ SENSOR_HAL_DATA_INJECTION_MODE = 0x1
};
/*
@@ -138,7 +138,16 @@ enum {
SENSOR_FLAG_CONTINUOUS_MODE = 0, // 0000
SENSOR_FLAG_ON_CHANGE_MODE = 0x2, // 0010
SENSOR_FLAG_ONE_SHOT_MODE = 0x4, // 0100
- SENSOR_FLAG_SPECIAL_REPORTING_MODE = 0x6 // 0110
+ SENSOR_FLAG_SPECIAL_REPORTING_MODE = 0x6, // 0110
+
+ /*
+ * Set this flag if the sensor supports data_injection mode and allows data to be injected
+ * from the SensorService. When in data_injection ONLY sensors with this flag set are injected
+ * sensor data and only sensors with this flag set are activated. Eg: Accelerometer and Step
+ * Counter sensors can be set with this flag and SensorService will inject accelerometer data
+ * and read the corresponding step counts.
+ */
+ SENSOR_FLAG_SUPPORTS_DATA_INJECTION = 0x8 // 1000
};
/*
@@ -148,6 +157,12 @@ enum {
#define REPORTING_MODE_SHIFT (1)
/*
+ * Mask and shift for data_injection mode sensor flags defined above.
+ */
+#define DATA_INJECTION_MASK (0x10)
+#define DATA_INJECTION_SHIFT (4)
+
+/*
* Sensor type
*
* Each sensor has a type which defines what this sensor measures and how
@@ -838,9 +853,9 @@ struct sensors_module_t {
* 0 - Normal operation. Default state of the module.
* 1 - Loopback mode. Data is injected for the the supported
* sensors by the sensor service in this mode.
- * @return 0 on success
+ * @return 0 on success
* -EINVAL if requested mode is not supported
- * -EPERM if operation is not allowed
+ * -EPERM if operation is not allowed
*/
int (*set_operation_mode)(unsigned int mode);
};
@@ -1043,8 +1058,8 @@ typedef struct sensors_poll_device_1 {
/*
* Inject a single sensor sample to be to this device.
* data points to the sensor event to be injected
- * @return 0 on success
- * -EPERM if operation is not allowed
+ * @return 0 on success
+ * -EPERM if operation is not allowed
* -EINVAL if sensor event cannot be injected
*/
int (*inject_sensor_data)(struct sensors_poll_device_1 *dev, const sensors_event_t *data);
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index 872fa93..bbea5f5 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -80,6 +80,7 @@ struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
bool standby;
struct audio_device *dev; /* hardware information - only using this for the lock */
@@ -103,7 +104,8 @@ struct stream_out {
struct stream_in {
struct audio_stream_in stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by capture thread */
bool standby;
struct audio_device *dev; /* hardware information - only using this for the lock */
@@ -126,6 +128,13 @@ struct stream_in {
};
/*
+ * NOTE: when multiple mutexes have to be acquired, always take the
+ * stream_in or stream_out mutex first, followed by the audio_device mutex.
+ * stream pre_lock is always acquired before stream lock to prevent starvation of control thread by
+ * higher priority playback or capture thread.
+ */
+
+/*
* Extract the card and device numbers from the supplied key/value pairs.
* kvpairs A null-terminated string containing the key/value pairs or card and device.
* i.e. "card=1;device=42"
@@ -203,6 +212,20 @@ static char * device_get_parameters(alsa_device_profile * profile, const char *
return result_str;
}
+void lock_input_stream(struct stream_in *in)
+{
+ pthread_mutex_lock(&in->pre_lock);
+ pthread_mutex_lock(&in->lock);
+ pthread_mutex_unlock(&in->pre_lock);
+}
+
+void lock_output_stream(struct stream_out *out)
+{
+ pthread_mutex_lock(&out->pre_lock);
+ pthread_mutex_lock(&out->lock);
+ pthread_mutex_unlock(&out->pre_lock);
+}
+
/*
* HAl Functions
*/
@@ -260,16 +283,14 @@ static int out_standby(struct audio_stream *stream)
{
struct stream_out *out = (struct stream_out *)stream;
- pthread_mutex_lock(&out->dev->lock);
- pthread_mutex_lock(&out->lock);
-
+ lock_output_stream(out);
if (!out->standby) {
+ pthread_mutex_lock(&out->dev->lock);
proxy_close(&out->proxy);
+ pthread_mutex_unlock(&out->dev->lock);
out->standby = true;
}
-
pthread_mutex_unlock(&out->lock);
- pthread_mutex_unlock(&out->dev->lock);
return 0;
}
@@ -295,9 +316,9 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
return ret_value;
}
+ lock_output_stream(out);
/* Lock the device because that is where the profile lives */
pthread_mutex_lock(&out->dev->lock);
- pthread_mutex_lock(&out->lock);
if (!profile_is_cached_for(out->profile, card, device)) {
/* cannot read pcm device info if playback is active */
@@ -316,8 +337,8 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
}
- pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&out->dev->lock);
+ pthread_mutex_unlock(&out->lock);
return ret_value;
}
@@ -325,8 +346,8 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
{
struct stream_out *out = (struct stream_out *)stream;
+ lock_output_stream(out);
pthread_mutex_lock(&out->dev->lock);
- pthread_mutex_lock(&out->lock);
char * params_str = device_get_parameters(out->profile, keys);
@@ -360,17 +381,16 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si
int ret;
struct stream_out *out = (struct stream_out *)stream;
- pthread_mutex_lock(&out->dev->lock);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->standby) {
+ pthread_mutex_lock(&out->dev->lock);
ret = start_output_stream(out);
+ pthread_mutex_unlock(&out->dev->lock);
if (ret != 0) {
- pthread_mutex_unlock(&out->dev->lock);
goto err;
}
out->standby = false;
}
- pthread_mutex_unlock(&out->dev->lock);
alsa_device_proxy* proxy = &out->proxy;
const void * write_buff = buffer;
@@ -480,6 +500,9 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.get_presentation_position = out_get_presentation_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
+ pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
+
out->dev = adev;
pthread_mutex_lock(&adev->lock);
out->profile = &adev->out_profile;
@@ -639,16 +662,15 @@ static int in_standby(struct audio_stream *stream)
{
struct stream_in *in = (struct stream_in *)stream;
- pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
-
+ lock_input_stream(in);
if (!in->standby) {
+ pthread_mutex_lock(&in->dev->lock);
proxy_close(&in->proxy);
+ pthread_mutex_unlock(&in->dev->lock);
in->standby = true;
}
pthread_mutex_unlock(&in->lock);
- pthread_mutex_unlock(&in->dev->lock);
return 0;
}
@@ -676,8 +698,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
return ret_value;
}
+ lock_input_stream(in);
pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) {
/* cannot read pcm device info if playback is active */
@@ -696,8 +718,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
}
- pthread_mutex_unlock(&in->lock);
pthread_mutex_unlock(&in->dev->lock);
+ pthread_mutex_unlock(&in->lock);
return ret_value;
}
@@ -706,13 +728,13 @@ static char * in_get_parameters(const struct audio_stream *stream, const char *k
{
struct stream_in *in = (struct stream_in *)stream;
+ lock_input_stream(in);
pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
char * params_str = device_get_parameters(in->profile, keys);
- pthread_mutex_unlock(&in->lock);
pthread_mutex_unlock(&in->dev->lock);
+ pthread_mutex_unlock(&in->lock);
return params_str;
}
@@ -750,16 +772,16 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
struct stream_in * in = (struct stream_in *)stream;
- pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (in->standby) {
- if (start_input_stream(in) != 0) {
- pthread_mutex_unlock(&in->dev->lock);
+ pthread_mutex_lock(&in->dev->lock);
+ ret = start_input_stream(in);
+ pthread_mutex_unlock(&in->dev->lock);
+ if (ret != 0) {
goto err;
}
in->standby = false;
}
- pthread_mutex_unlock(&in->dev->lock);
alsa_device_profile * profile = in->profile;
@@ -858,6 +880,9 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
+ pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
+
in->dev = (struct audio_device *)dev;
pthread_mutex_lock(&in->dev->lock);