Merge "Add defroster fan positions" into nyc-dev
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 29b695c..36bfa86 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -431,6 +431,23 @@
* Unit: the number of input audio frames
*/
uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream);
+
+ /**
+ * Return a recent count of the number of audio frames received and
+ * the clock time associated with that frame count.
+ *
+ * frames is the total frame count received. This should be as early in
+ * the capture pipeline as possible. In general,
+ * frames should be non-negative and should not go "backwards".
+ *
+ * time is the clock MONOTONIC time when frames was measured. In general,
+ * time should be a positive quantity and should not go "backwards".
+ *
+ * The status returned is 0 on success, -ENOSYS if the device is not
+ * ready/available, or -EINVAL if the arguments are null or otherwise invalid.
+ */
+ int (*get_capture_position)(const struct audio_stream_in *stream,
+ int64_t *frames, int64_t *time);
};
typedef struct audio_stream_in audio_stream_in_t;
@@ -445,7 +462,7 @@
size_t chan_samp_sz;
audio_format_t format = s->get_format(s);
- if (audio_is_linear_pcm(format)) {
+ if (audio_has_proportional_frames(format)) {
chan_samp_sz = audio_bytes_per_sample(format);
return popcount(s->get_channels(s)) * chan_samp_sz;
}
@@ -461,7 +478,7 @@
size_t chan_samp_sz;
audio_format_t format = s->common.get_format(&s->common);
- if (audio_is_linear_pcm(format)) {
+ if (audio_has_proportional_frames(format)) {
chan_samp_sz = audio_bytes_per_sample(format);
return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz;
}
@@ -477,7 +494,7 @@
size_t chan_samp_sz;
audio_format_t format = s->common.get_format(&s->common);
- if (audio_is_linear_pcm(format)) {
+ if (audio_has_proportional_frames(format)) {
chan_samp_sz = audio_bytes_per_sample(format);
return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz;
}
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index 6fd47a9..68e3052 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -39,10 +39,15 @@
/** Maximum number of SVs for gps_sv_status_callback(). */
#define GPS_MAX_SVS 32
+/** Maximum number of SVs for gps_sv_status_callback(). */
+#define GNSS_MAX_SVS 64
/** Maximum number of Measurements in gps_measurement_callback(). */
#define GPS_MAX_MEASUREMENT 32
+/** Maximum number of Measurements in gnss_measurement_callback(). */
+#define GNSS_MAX_MEASUREMENT 64
+
/** Requested operational mode for GPS operation. */
typedef uint32_t GpsPositionMode;
// IMPORTANT: Note that the following values must match
@@ -524,7 +529,7 @@
* - Galileo: 1-25
* - Beidou: 1-35
*/
- int prn;
+ int16_t svid;
/** Signal to noise ratio. */
float snr;
@@ -550,63 +555,36 @@
} GnssSvInfo;
/**
- * Represents SV status.
- *
- * When switching from pre-N to N version of GpsSvStatus:
- *
- * 1) Fill in the fields from num_svs through used_in_fix_mask the same way as
- * was done before, e.g. using the range of 65-88 to report Glonass info,
- * 201-235 for Beidou, etc. (but with no used_in_fix_mask info - those are
- * index by prn, and thus for GPS only). This will help ensure compatibility
- * when a newer GPS HAL is used with an older version of Android.
- *
- * 2) Fill in the gnss_sv_list with information about SVs from all
- * constellations (GPS & other GNSS's) - when this is filled in, this will be
- * the only source of information about satellite status (e.g. for working with
- * GpsStatus facing applications), the earlier fields will be ignored.
+ * Legacy struct to represents SV status.
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssSvStatus instead.
*/
typedef struct {
/** set to sizeof(GpsSvStatus) */
size_t size;
+ int num_svs;
+ GpsSvInfo sv_list[GPS_MAX_SVS];
+ uint32_t ephemeris_mask;
+ uint32_t almanac_mask;
+ uint32_t used_in_fix_mask;
+} GpsSvStatus;
+
+/**
+ * Represents SV status.
+ */
+typedef struct {
+ /** set to sizeof(GnssSvStatus) */
+ size_t size;
/** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
int num_svs;
-
- /** Contains an array of GPS SV information in legacy GPS format. */
- GpsSvInfo sv_list[GPS_MAX_SVS];
-
- /**
- * Represents a bit mask indicating which GPS SVs have ephemeris data,
- * refers to sv_list.
- */
- uint32_t ephemeris_mask;
-
- /**
- * Represents a bit mask indicating which GPS SVs have almanac data, refers
- * to sv_list.
- */
- uint32_t almanac_mask;
-
- /**
- * Represents a bit mask indicating which GPS SVs
- * were used for computing the most recent position fix,
- * refers to sv_list.
- */
- uint32_t used_in_fix_mask;
-
- /**
- * Size of the array which contains SV info for all GNSS constellation
- * except for GPS.
- */
- size_t gnss_sv_list_size;
-
/**
* Pointer to an array of SVs information for all GNSS constellations,
* except GPS, which is reported using sv_list
*/
- GnssSvInfo* gnss_sv_list;
+ GnssSvInfo gnss_sv_list[GNSS_MAX_SVS];
-} GpsSvStatus;
+} GnssSvStatus;
/* CellID for 2G, 3G and LTE, used in AGPS. */
typedef struct {
@@ -660,6 +638,12 @@
typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gnss_sv_status_callback)(GnssSvStatus* sv_info);
+
+/**
* Callback for reporting NMEA sentences. Can only be called from a thread
* created by create_thread_cb.
*/
@@ -715,24 +699,6 @@
*/
typedef void (*gps_set_system_info)(const GpsSystemInfo* info);
-/**
- * Legacy GPS callback structure.
- * See GpsCallbacks for more information.
- */
-typedef struct {
- /** set to sizeof(GpsCallbacks_v1) */
- size_t size;
- gps_location_callback location_cb;
- gps_status_callback status_cb;
- gps_sv_status_callback sv_status_cb;
- gps_nmea_callback nmea_cb;
- gps_set_capabilities set_capabilities_cb;
- gps_acquire_wakelock acquire_wakelock_cb;
- gps_release_wakelock release_wakelock_cb;
- gps_create_thread create_thread_cb;
- gps_request_utc_time request_utc_time_cb;
-} GpsCallbacks_v1;
-
/** New GPS callback structure. */
typedef struct {
/** set to sizeof(GpsCallbacks) */
@@ -747,15 +713,8 @@
gps_create_thread create_thread_cb;
gps_request_utc_time request_utc_time_cb;
- /**
- * Callback for the chipset to report system information.
- *
- * This field is newly introduced since N. The driver implementation must
- * check 'size' field against 'sizeof(GpsCallbacks)' and
- * 'sizeof(GpsCallbacks_v1)' to decide whether the new field is valid before
- * calling it.
- */
gps_set_system_info set_system_info_cb;
+ gnss_sv_status_callback gnss_sv_status_cb;
} GpsCallbacks;
/** Represents the standard GPS interface. */
@@ -1402,11 +1361,31 @@
} GpsGeofencingInterface;
/**
- * Represents an estimate of the GPS clock time.
+ * Legacy struct to represent an estimate of the GPS clock time.
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssClock instead.
*/
typedef struct {
/** set to sizeof(GpsClock) */
size_t size;
+ GpsClockFlags flags;
+ int16_t leap_second;
+ GpsClockType type;
+ int64_t time_ns;
+ double time_uncertainty_ns;
+ int64_t full_bias_ns;
+ double bias_ns;
+ double bias_uncertainty_ns;
+ double drift_nsps;
+ double drift_uncertainty_nsps;
+} GpsClock;
+
+/**
+ * Represents an estimate of the GPS clock time.
+ */
+typedef struct {
+ /** set to sizeof(GnssClock) */
+ size_t size;
/** A set of flags indicating the validity of the fields in this data structure. */
GpsClockFlags flags;
@@ -1538,10 +1517,53 @@
* re-solve for the clock bias and drift.
*/
int64_t time_of_last_hw_clock_discontinuity_ns;
-} GpsClock;
+} GnssClock;
/**
- * Represents a GPS Measurement, it contains raw and computed information.
+ * Legacy struct to represent a GPS Measurement, it contains raw and computed
+ * information.
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssMeasurement instead.
+ */
+typedef struct {
+ /** set to sizeof(GpsMeasurement) */
+ size_t size;
+ GpsMeasurementFlags flags;
+ int8_t prn;
+ double time_offset_ns;
+ GpsMeasurementState state;
+ int64_t received_gps_tow_ns;
+ int64_t received_gps_tow_uncertainty_ns;
+ double c_n0_dbhz;
+ double pseudorange_rate_mps;
+ double pseudorange_rate_uncertainty_mps;
+ GpsAccumulatedDeltaRangeState accumulated_delta_range_state;
+ double accumulated_delta_range_m;
+ double accumulated_delta_range_uncertainty_m;
+ double pseudorange_m;
+ double pseudorange_uncertainty_m;
+ double code_phase_chips;
+ double code_phase_uncertainty_chips;
+ float carrier_frequency_hz;
+ int64_t carrier_cycles;
+ double carrier_phase;
+ double carrier_phase_uncertainty;
+ GpsLossOfLock loss_of_lock;
+ int32_t bit_number;
+ int16_t time_from_last_bit_ms;
+ double doppler_shift_hz;
+ double doppler_shift_uncertainty_hz;
+ GpsMultipathIndicator multipath_indicator;
+ double snr_db;
+ double elevation_deg;
+ double elevation_uncertainty_deg;
+ double azimuth_deg;
+ double azimuth_uncertainty_deg;
+ bool used_in_fix;
+} GpsMeasurement;
+
+/**
+ * Represents a GNSS Measurement, it contains raw and computed information.
*/
typedef struct {
/** set to sizeof(GpsMeasurement) */
@@ -1551,10 +1573,10 @@
GpsMeasurementFlags flags;
/**
- * Pseudo-random number in the range of [1, 32]
+ * Satellite vehicle ID number, as defined in GnssSvInfo::svid
* This is a mandatory value.
*/
- int8_t prn;
+ int16_t svid;
/**
* Time offset at which the measurement was taken in nanoseconds.
@@ -1858,22 +1880,37 @@
*/
double pseudorange_rate_carrier_uncertainty_mps;
-} GpsMeasurement;
+} GnssMeasurement;
+
+/**
+ * Legacy struct to represents a reading of GPS measurements.
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssData instead.
+ */
+typedef struct {
+ /** set to sizeof(GpsData) */
+ size_t size;
+ size_t measurement_count;
+ GpsMeasurement measurements[GPS_MAX_MEASUREMENT];
+
+ /** The GPS clock time reading. */
+ GpsClock clock;
+} GpsData;
/** Represents a reading of GPS measurements. */
typedef struct {
- /** set to sizeof(GpsData) */
+ /** set to sizeof(GnssData) */
size_t size;
/** Number of measurements. */
size_t measurement_count;
/** The array of measurements. */
- GpsMeasurement measurements[GPS_MAX_MEASUREMENT];
+ GnssMeasurement measurements[GNSS_MAX_MEASUREMENT];
/** The GPS clock time reading. */
- GpsClock clock;
-} GpsData;
+ GnssClock clock;
+} GnssData;
/**
* The callback for to report measurements from the HAL.
@@ -1883,10 +1920,19 @@
*/
typedef void (*gps_measurement_callback) (GpsData* data);
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ * data - A data structure containing the measurements.
+ */
+typedef void (*gnss_measurement_callback) (GnssData* data);
+
typedef struct {
/** set to sizeof(GpsMeasurementCallbacks) */
size_t size;
gps_measurement_callback measurement_callback;
+ gnss_measurement_callback gnss_measurement_callback;
} GpsMeasurementCallbacks;
#define GPS_MEASUREMENT_OPERATION_SUCCESS 0
@@ -1923,17 +1969,32 @@
} GpsMeasurementInterface;
-
-/** Represents a GPS navigation message (or a fragment of it). */
+/**
+ * Legacy struct to represents a GPS navigation message (or a fragment of it).
+ * Deprecated, to be removed in the next Android release.
+ * Use GnssNavigationMessage instead.
+ */
typedef struct {
/** set to sizeof(GpsNavigationMessage) */
size_t size;
+ int8_t prn;
+ GpsNavigationMessageType type;
+ NavigationMessageStatus status;
+ int16_t message_id;
+ int16_t submessage_id;
+ size_t data_length;
+ uint8_t* data;
+} GpsNavigationMessage;
+
+/** Represents a GPS navigation message (or a fragment of it). */
+typedef struct {
+ /** set to sizeof(GnssNavigationMessage) */
+ size_t size;
/**
- * Pseudo-random number in the range of [1, 32]
* This is a mandatory value.
*/
- int8_t prn;
+ int16_t svid;
/**
* The type of message contained in the structure.
@@ -1982,7 +2043,7 @@
*/
uint8_t* data;
-} GpsNavigationMessage;
+} GnssNavigationMessage;
/**
* The callback to report an available fragment of a GPS navigation messages from the HAL.
@@ -1992,10 +2053,19 @@
*/
typedef void (*gps_navigation_message_callback) (GpsNavigationMessage* message);
+/**
+ * The callback to report an available fragment of a GPS navigation messages from the HAL.
+ *
+ * Parameters:
+ * message - The GPS navigation submessage/subframe representation.
+ */
+typedef void (*gnss_navigation_message_callback) (GnssNavigationMessage* message);
+
typedef struct {
/** set to sizeof(GpsNavigationMessageCallbacks) */
size_t size;
gps_navigation_message_callback navigation_message_callback;
+ gnss_navigation_message_callback gnss_navigation_message_callback;
} GpsNavigationMessageCallbacks;
#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS 0
diff --git a/include/hardware/gps_internal.h b/include/hardware/gps_internal.h
index cd83636..6a3833b 100644
--- a/include/hardware/gps_internal.h
+++ b/include/hardware/gps_internal.h
@@ -26,18 +26,23 @@
__BEGIN_DECLS
/**
- * Legacy struct to represent SV status.
- * See GpsSvStatus_v2 for more information.
+ * Legacy GPS callback structure.
+ * Deprecated, to be removed in the next Android release.
+ * Use GpsCallbacks instead.
*/
typedef struct {
- /** set to sizeof(GpsSvStatus_v1) */
- size_t size;
- int num_svs;
- GpsSvInfo sv_list[GPS_MAX_SVS];
- uint32_t ephemeris_mask;
- uint32_t almanac_mask;
- uint32_t used_in_fix_mask;
-} GpsSvStatus_v1;
+ /** set to sizeof(GpsCallbacks_v1) */
+ size_t size;
+ gps_location_callback location_cb;
+ gps_status_callback status_cb;
+ gps_sv_status_callback sv_status_cb;
+ gps_nmea_callback nmea_cb;
+ gps_set_capabilities set_capabilities_cb;
+ gps_acquire_wakelock acquire_wakelock_cb;
+ gps_release_wakelock release_wakelock_cb;
+ gps_create_thread create_thread_cb;
+ gps_request_utc_time request_utc_time_cb;
+} GpsCallbacks_v1;
#pragma pack(push,4)
// We need to keep the alignment of this data structure to 4-bytes, to ensure that in 64-bit
@@ -86,82 +91,6 @@
int (*set_server)( AGpsType type, const char* hostname, int port );
} AGpsInterface_v1;
-/**
- * Legacy struct to represent an estimate of the GPS clock time.
- * See GpsClock_v2 for more details.
- */
-typedef struct {
- /** set to sizeof(GpsClock_v1) */
- size_t size;
- GpsClockFlags flags;
- int16_t leap_second;
- GpsClockType type;
- int64_t time_ns;
- double time_uncertainty_ns;
- int64_t full_bias_ns;
- double bias_ns;
- double bias_uncertainty_ns;
- double drift_nsps;
- double drift_uncertainty_nsps;
-} GpsClock_v1;
-
-/**
- * Legacy struct to represent a GPS Measurement, it contains raw and computed
- * information.
- * See GpsMeasurement_v2 for more details.
- */
-typedef struct {
- /** set to sizeof(GpsMeasurement_v1) */
- size_t size;
- GpsMeasurementFlags flags;
- int8_t prn;
- double time_offset_ns;
- GpsMeasurementState state;
- int64_t received_gps_tow_ns;
- int64_t received_gps_tow_uncertainty_ns;
- double c_n0_dbhz;
- double pseudorange_rate_mps;
- double pseudorange_rate_uncertainty_mps;
- GpsAccumulatedDeltaRangeState accumulated_delta_range_state;
- double accumulated_delta_range_m;
- double accumulated_delta_range_uncertainty_m;
- double pseudorange_m;
- double pseudorange_uncertainty_m;
- double code_phase_chips;
- double code_phase_uncertainty_chips;
- float carrier_frequency_hz;
- int64_t carrier_cycles;
- double carrier_phase;
- double carrier_phase_uncertainty;
- GpsLossOfLock loss_of_lock;
- int32_t bit_number;
- int16_t time_from_last_bit_ms;
- double doppler_shift_hz;
- double doppler_shift_uncertainty_hz;
- GpsMultipathIndicator multipath_indicator;
- double snr_db;
- double elevation_deg;
- double elevation_uncertainty_deg;
- double azimuth_deg;
- double azimuth_uncertainty_deg;
- bool used_in_fix;
-} GpsMeasurement_v1;
-
-/** Represents a reading of GPS measurements. */
-typedef struct {
- /** set to sizeof(GpsData_v1) */
- size_t size;
-
- /** Number of measurements. */
- size_t measurement_count;
-
- /** The array of measurements. */
- GpsMeasurement_v1 measurements[GPS_MAX_MEASUREMENT];
-
- /** The GPS clock time reading. */
- GpsClock_v1 clock;
-} GpsData_v1;
-
__END_DECLS
#endif /* ANDROID_INCLUDE_HARDWARE_GPS_INTERNAL_H */
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index 80b2318..d59f3cb 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -126,14 +126,15 @@
* Semantically unenforceable tags, either because they have no specific meaning or because
* they're informational only.
*/
- KM_TAG_APPLICATION_DATA = KM_BYTES | 700, /* Data provided by authorized application. */
- KM_TAG_CREATION_DATETIME = KM_DATE | 701, /* Key creation time */
- KM_TAG_ORIGIN = KM_ENUM | 702, /* keymaster_key_origin_t. */
- KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703, /* Whether key is rollback-resistant. */
- KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704, /* Root of trust ID. */
- KM_TAG_OS_VERSION = KM_UINT | 705, /* Version of system (keymaster2) */
- KM_TAG_OS_PATCHLEVEL = KM_UINT | 706, /* Patch level of system (keymaster2) */
- KM_TAG_UNIQUE_ID = KM_BYTES | 707, /* Used to provide unique ID in attestation */
+ KM_TAG_APPLICATION_DATA = KM_BYTES | 700, /* Data provided by authorized application. */
+ KM_TAG_CREATION_DATETIME = KM_DATE | 701, /* Key creation time */
+ KM_TAG_ORIGIN = KM_ENUM | 702, /* keymaster_key_origin_t. */
+ KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703, /* Whether key is rollback-resistant. */
+ KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704, /* Root of trust ID. */
+ KM_TAG_OS_VERSION = KM_UINT | 705, /* Version of system (keymaster2) */
+ KM_TAG_OS_PATCHLEVEL = KM_UINT | 706, /* Patch level of system (keymaster2) */
+ KM_TAG_UNIQUE_ID = KM_BYTES | 707, /* Used to provide unique ID in attestation */
+ KM_TAG_ATTESTATION_CHALLENGE = KM_BYTES | 708, /* Used to provide challenge in attestation */
/* 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. */
@@ -400,6 +401,7 @@
KM_ERROR_UNSUPPORTED_KDF = -60,
KM_ERROR_UNSUPPORTED_EC_CURVE = -61,
KM_ERROR_KEY_REQUIRES_UPGRADE = -62,
+ KM_ERROR_ATTESTATION_CHALLENGE_MISSING = -63,
KM_ERROR_UNIMPLEMENTED = -100,
KM_ERROR_VERSION_MISMATCH = -101,
diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h
index a0bc1fe..161322a 100644
--- a/include/hardware/vehicle.h
+++ b/include/hardware/vehicle.h
@@ -731,6 +731,8 @@
VEHICLE_AUDIO_CONTEXT_CD_ROM = 0x100,
/** Aux audio input is played */
VEHICLE_AUDIO_CONTEXT_AUX_AUDIO = 0x200,
+ /** system sound like UI feedback */
+ VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND = 0x400,
};
/**
@@ -1160,17 +1162,17 @@
* Various Seats in the car.
*/
enum vehicle_seat {
- VEHICLE_SEAT_DRIVER_LHD = 0x0001,
- VEHICLE_SEAT_DRIVER_RHD = 0x0002,
- VEHICLE_SEAT_ROW_1_PASSENGER_1 = 0x0010,
- VEHICLE_SEAT_ROW_1_PASSENGER_2 = 0x0020,
- VEHICLE_SEAT_ROW_1_PASSENGER_3 = 0x0040,
- VEHICLE_SEAT_ROW_2_PASSENGER_1 = 0x0100,
- VEHICLE_SEAT_ROW_2_PASSENGER_2 = 0x0200,
- VEHICLE_SEAT_ROW_2_PASSENGER_3 = 0x0400,
- VEHICLE_SEAT_ROW_3_PASSENGER_1 = 0x1000,
- VEHICLE_SEAT_ROW_3_PASSENGER_2 = 0x2000,
- VEHICLE_SEAT_ROW_3_PASSENGER_3 = 0x4000
+ VEHICLE_SEAT_DRIVER_LHD = 0x0001,
+ VEHICLE_SEAT_DRIVER_RHD = 0x0002,
+ VEHICLE_SEAT_ROW_1_PASSENGER_LEFT = 0x0010,
+ VEHICLE_SEAT_ROW_1_PASSENGER_CENTER = 0x0020,
+ VEHICLE_SEAT_ROW_1_PASSENGER_RIGHT = 0x0040,
+ VEHICLE_SEAT_ROW_2_PASSENGER_LEFT = 0x0100,
+ VEHICLE_SEAT_ROW_2_PASSENGER_CENTER = 0x0200,
+ VEHICLE_SEAT_ROW_2_PASSENGER_RIGHT = 0x0400,
+ VEHICLE_SEAT_ROW_3_PASSENGER_LEFT = 0x1000,
+ VEHICLE_SEAT_ROW_3_PASSENGER_CENTER = 0x2000,
+ VEHICLE_SEAT_ROW_3_PASSENGER_RIGHT = 0x4000
};
/**
diff --git a/include/hardware/vr.h b/include/hardware/vr.h
index 494f016..17a0606 100644
--- a/include/hardware/vr.h
+++ b/include/hardware/vr.h
@@ -23,7 +23,7 @@
__BEGIN_DECLS
-#define VR_HARDWARE_MODULE_ID "vr_module"
+#define VR_HARDWARE_MODULE_ID "vr"
#define VR_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index 2c1cc9c..8083b1f 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -30,7 +30,7 @@
*/
#define LOG_TAG "sound_trigger_hw_default"
-/*#define LOG_NDEBUG 0*/
+#define LOG_NDEBUG 1
#include <errno.h>
#include <stdio.h>
@@ -51,10 +51,6 @@
#include <system/sound_trigger.h>
#include <hardware/sound_trigger.h>
-/* Although max_sound_models is specified in sound_trigger_properties, having a maximum maximum
-allows a dramatic simplification of data structures in this file */
-#define MAX_MAX_SOUND_MODELS 5
-
static const struct sound_trigger_properties hw_properties = {
"The Android Open Source Project", // implementor
"Sound Trigger stub HAL", // description
@@ -72,15 +68,19 @@
};
struct recognition_context {
- /* Sound Model Information Modified On Load */
- sound_model_handle_t loaded_sound_model;
- sound_model_callback_t sound_model_callback;
- void *sound_model_cookie;
+ // Sound Model information, added in method load_sound_model
+ sound_model_handle_t model_handle;
+ sound_trigger_sound_model_type_t model_type;
+ sound_model_callback_t model_callback;
+ void *model_cookie;
- /* Sound Model Information Modified On Recognition Start */
+ // Sound Model information, added in start_recognition
struct sound_trigger_recognition_config *config;
recognition_callback_t recognition_callback;
void *recognition_cookie;
+
+ // Next recognition_context in the linked list
+ struct recognition_context *next;
};
struct stub_sound_trigger_device {
@@ -88,7 +88,8 @@
pthread_mutex_t lock;
pthread_t callback_thread;
- struct recognition_context model_context[MAX_MAX_SOUND_MODELS];
+ // Recognition contexts are stored as a linked list
+ struct recognition_context *root_model_context;
int next_sound_model_id;
};
@@ -104,57 +105,94 @@
return new_id;
}
-static char *sound_trigger_event_alloc(struct stub_sound_trigger_device *stdev,
- sound_model_handle_t handle) {
- struct sound_trigger_phrase_recognition_event *event;
+static char *sound_trigger_event_alloc(sound_model_handle_t handle,
+ sound_trigger_sound_model_type_t model_type,
+ struct sound_trigger_recognition_config *config) {
char *data;
- data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event));
- if (!data)
- return NULL;
+ if (model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ struct sound_trigger_phrase_recognition_event *event;
+ data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event));
+ if (!data)
+ return NULL;
+ event = (struct sound_trigger_phrase_recognition_event *)data;
+ event->common.status = RECOGNITION_STATUS_SUCCESS;
+ event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
+ event->common.model = handle;
- unsigned int model_index;
- bool found = false;
- for(model_index = 0; model_index < hw_properties.max_sound_models; model_index++) {
- if (stdev->model_context[model_index].loaded_sound_model == handle) {
- found = true;
- break;
+ if (config) {
+ unsigned int i;
+
+ event->num_phrases = config->num_phrases;
+ if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
+ event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
+ for (i=0; i < event->num_phrases; i++)
+ memcpy(&event->phrase_extras[i],
+ &config->phrases[i],
+ sizeof(struct sound_trigger_phrase_recognition_extra));
}
- }
- if (found == false) {
- ALOGW("Can't find model");
+
+ event->num_phrases = 1;
+ event->phrase_extras[0].confidence_level = 100;
+ event->phrase_extras[0].num_levels = 1;
+ event->phrase_extras[0].levels[0].level = 100;
+ event->phrase_extras[0].levels[0].user_id = 0;
+ // Signify that all the data is comming through streaming, not through the buffer.
+ event->common.capture_available = true;
+ event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
+ event->common.audio_config.sample_rate = 16000;
+ event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
+ event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
+ } else if (model_type == SOUND_MODEL_TYPE_GENERIC) {
+ struct sound_trigger_generic_recognition_event *event;
+ data = (char *)calloc(1, sizeof(struct sound_trigger_generic_recognition_event));
+ if (!data)
+ return NULL;
+ event = (struct sound_trigger_generic_recognition_event *)data;
+ event->common.status = RECOGNITION_STATUS_SUCCESS;
+ event->common.type = SOUND_MODEL_TYPE_GENERIC;
+ event->common.model = handle;
+
+ // Signify that all the data is comming through streaming, not through the buffer.
+ event->common.capture_available = true;
+ event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
+ event->common.audio_config.sample_rate = 16000;
+ event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
+ event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
+ } else {
+ ALOGW("No Valid Event Type Known");
return NULL;
}
+ return data;
+}
- event = (struct sound_trigger_phrase_recognition_event *)data;
- event->common.status = RECOGNITION_STATUS_SUCCESS;
- event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
- event->common.model = handle;
-
- if (stdev->model_context[model_index].config) {
- unsigned int i;
-
- event->num_phrases = stdev->model_context[model_index].config->num_phrases;
- if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
- event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
- for (i=0; i < event->num_phrases; i++)
- memcpy(&event->phrase_extras[i], &stdev->model_context[model_index].config->phrases[i],
- sizeof(struct sound_trigger_phrase_recognition_extra));
+static void send_recognition_event(sound_model_handle_t model_handle,
+ sound_trigger_sound_model_type_t model_type,
+ recognition_callback_t recognition_callback, void *recognition_cookie,
+ struct sound_trigger_recognition_config *config) {
+ if (recognition_callback == NULL) {
+ ALOGI("%s No matching callback for handle %d", __func__, model_handle);
+ return;
}
- event->num_phrases = 1;
- event->phrase_extras[0].confidence_level = 100;
- event->phrase_extras[0].num_levels = 1;
- event->phrase_extras[0].levels[0].level = 100;
- event->phrase_extras[0].levels[0].user_id = 0;
- // Signify that all the data is comming through streaming, not through the buffer.
- event->common.capture_available = true;
-
- event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
- event->common.audio_config.sample_rate = 16000;
- event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
- event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
-
- return data;
+ if (model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ struct sound_trigger_phrase_recognition_event *event;
+ event = (struct sound_trigger_phrase_recognition_event *)
+ sound_trigger_event_alloc(model_handle, model_type, config);
+ if (event) {
+ recognition_callback(&event->common, recognition_cookie);
+ free(event);
+ }
+ } else if (model_type == SOUND_MODEL_TYPE_GENERIC) {
+ struct sound_trigger_generic_recognition_event *event;
+ event = (struct sound_trigger_generic_recognition_event *)
+ sound_trigger_event_alloc(model_handle, model_type, config);
+ if (event) {
+ recognition_callback(&event->common, recognition_cookie);
+ free(event);
+ }
+ } else {
+ ALOGI("Unknown Sound Model Type, No Event to Send");
+ }
}
static void *callback_thread_loop(void *context) {
@@ -215,26 +253,26 @@
ALOGI("Received kill signal: stop listening to incoming server messages");
exit = true;
} else if (index < hw_properties.max_sound_models) {
- ALOGI("Going to send trigger for model #%d", index );
- if (stdev->model_context[index].recognition_callback != NULL) {
- sound_model_handle_t handle = stdev->model_context[index].loaded_sound_model;
- if (handle == 0) {
- ALOGW("This trigger is not loaded");
- } else {
- struct sound_trigger_phrase_recognition_event *event;
- event = (struct sound_trigger_phrase_recognition_event *)
- sound_trigger_event_alloc(stdev, handle);
- if (event) {
- ALOGI("%s send callback model %d", __func__, index);
- stdev->model_context[index].recognition_callback(&event->common,
- stdev->model_context[index].recognition_cookie);
- free(event);
- stdev->model_context[index].recognition_callback = NULL;
- }
- exit = true;
+ ALOGI("Going to send trigger for model index #%d", index );
+ struct recognition_context *model_context = NULL;
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ int model_index = 0;
+ while(last_model_context) {
+ if (model_index == index) {
+ model_context = last_model_context;
+ break;
}
+ last_model_context = last_model_context->next;
+ model_index++;
+ }
+ if (model_context) {
+ send_recognition_event(model_context->model_handle,
+ model_context->model_type,
+ model_context->recognition_callback,
+ model_context->recognition_cookie,
+ model_context->config);
} else {
- ALOGI("%s No matching callback for %d", __func__, index);
+ ALOGI("Sound Model Does Not Exist at this Index: %d", index);
}
} else {
ALOGI("Data is not recognized: %d", index);
@@ -302,29 +340,46 @@
return -EINVAL;
}
- /* Find if there is space for this sound model */
- unsigned int model_index;
- bool found = false;
- for(model_index = 0; model_index < hw_properties.max_sound_models; model_index++) {
- if (stdev->model_context[model_index].loaded_sound_model == 0) {
- found = true;
- break;
- }
- }
- if (found == false) {
- ALOGW("Can't load model: reached max sound model limit");
+ struct recognition_context *model_context;
+ model_context = malloc(sizeof(struct recognition_context));
+ if(!model_context) {
+ ALOGW("Could not allocate recognition_context");
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- stdev->model_context[model_index].loaded_sound_model = generate_sound_model_id(dev);
- *handle = stdev->model_context[model_index].loaded_sound_model;
+ // Add the new model context to the recognition_context linked list
+ if (stdev->root_model_context) {
+ // Find the tail
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ int model_count = 0;
+ while(last_model_context->next) {
+ last_model_context = last_model_context->next;
+ model_count++;
+ if (model_count >= hw_properties.max_sound_models) {
+ ALOGW("Can't load model: reached max sound model limit");
+ free(model_context);
+ pthread_mutex_unlock(&stdev->lock);
+ return -ENOSYS;
+ }
+ }
+ last_model_context->next = model_context;
+ } else {
+ stdev->root_model_context = model_context;
+ }
+
+ model_context->model_handle = generate_sound_model_id(dev);
+ *handle = model_context->model_handle;
+ model_context->model_type = sound_model->type;
char *data = (char *)sound_model + sound_model->data_offset;
ALOGI("%s data size %d data %d - %d", __func__,
sound_model->data_size, data[0], data[sound_model->data_size - 1]);
- stdev->model_context[model_index].sound_model_callback = callback;
- stdev->model_context[model_index].sound_model_cookie = cookie;
+ model_context->model_callback = callback;
+ model_context->model_cookie = cookie;
+ model_context->config = NULL;
+ model_context->recognition_callback = NULL;
+ model_context->recognition_cookie = NULL;
pthread_mutex_unlock(&stdev->lock);
return status;
@@ -337,35 +392,46 @@
ALOGI("unload_sound_model");
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- unsigned int model_index;
- bool found = false;
- bool other_callbacks_found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- model_index = i;
- break;
- } else if (stdev->model_context[i].recognition_callback != NULL) {
- other_callbacks_found = true;
+
+ struct recognition_context *model_context = NULL;
+ struct recognition_context *previous_model_context = NULL;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ break;
+ }
+ previous_model_context = last_model_context;
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- stdev->model_context[i].loaded_sound_model = 0;
- stdev->model_context[i].sound_model_callback = NULL;
- stdev->model_context[i].sound_model_cookie = NULL;
-
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
+ if(previous_model_context) {
+ previous_model_context->next = model_context->next;
+ } else {
+ stdev->root_model_context = model_context->next;
+ }
+ free(model_context->config);
+ free(model_context);
/* If no more models running with callbacks, stop trigger thread */
+ bool other_callbacks_found = false;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->recognition_callback != NULL) {
+ other_callbacks_found = true;
+ break;
+ }
+ last_model_context = last_model_context->next;
+ }
+ }
if (!other_callbacks_found) {
send_loop_kill_signal();
pthread_mutex_unlock(&stdev->lock);
@@ -385,32 +451,36 @@
ALOGI("%s", __func__);
struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- bool found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- break;
+
+ struct recognition_context *model_context = NULL;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ break;
+ }
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
+ free(model_context->config);
+ model_context->config = NULL;
if (config) {
- stdev->model_context[i].config = malloc(sizeof(*config));
- if (!stdev->model_context[i].config) {
+ model_context->config = malloc(sizeof(*config));
+ if (!model_context->config) {
pthread_mutex_unlock(&stdev->lock);
return -ENOMEM;
}
- memcpy(stdev->model_context[i].config, config, sizeof(*config));
+ memcpy(model_context->config, config, sizeof(*config));
}
- stdev->model_context[i].recognition_callback = callback;
- stdev->model_context[i].recognition_cookie = cookie;
+ model_context->recognition_callback = callback;
+ model_context->recognition_cookie = cookie;
pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
callback_thread_loop, stdev);
@@ -424,48 +494,56 @@
ALOGI("%s", __func__);
pthread_mutex_lock(&stdev->lock);
- unsigned int i;
- bool found = false;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- if (stdev->model_context[i].loaded_sound_model == handle) {
- found = true;
- break;
+ struct recognition_context *model_context = NULL;
+ bool other_callbacks_found = false;
+ if (stdev->root_model_context) {
+ struct recognition_context *last_model_context = stdev->root_model_context;
+ while(last_model_context) {
+ if (last_model_context->model_handle == handle) {
+ model_context = last_model_context;
+ } else if (last_model_context->recognition_callback != NULL) {
+ other_callbacks_found = true;
+ }
+ last_model_context = last_model_context->next;
}
}
- if (found == false) {
- ALOGW("Can't sound model %d in registered list", handle);
+ if (!model_context) {
+ ALOGW("Can't find sound model handle %d in registered list", handle);
pthread_mutex_unlock(&stdev->lock);
return -ENOSYS;
}
- free(stdev->model_context[i].config);
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
+ free(model_context->config);
+ model_context->config = NULL;
+ model_context->recognition_callback = NULL;
+ model_context->recognition_cookie = NULL;
- send_loop_kill_signal();
- pthread_mutex_unlock(&stdev->lock);
- pthread_join(stdev->callback_thread, (void **) NULL);
+ /* If no more models running with callbacks, stop trigger thread */
+ if (!other_callbacks_found) {
+ send_loop_kill_signal();
+ pthread_mutex_unlock(&stdev->lock);
+ pthread_join(stdev->callback_thread, (void **)NULL);
+ } else {
+ pthread_mutex_unlock(&stdev->lock);
+ }
+
return 0;
}
__attribute__ ((visibility ("default")))
-int sound_trigger_open_for_streaming()
-{
+int sound_trigger_open_for_streaming() {
int ret = 0;
return ret;
}
__attribute__ ((visibility ("default")))
-size_t sound_trigger_read_samples(int audio_handle, void *buffer, size_t buffer_len)
-{
+size_t sound_trigger_read_samples(int audio_handle, void *buffer, size_t buffer_len) {
size_t ret = 0;
return ret;
}
__attribute__ ((visibility ("default")))
-int sound_trigger_close_for_streaming(int audio_handle __unused)
-{
+int sound_trigger_close_for_streaming(int audio_handle __unused) {
return 0;
}
@@ -486,21 +564,7 @@
if (!stdev)
return -ENOMEM;
- if (MAX_MAX_SOUND_MODELS < hw_properties.max_sound_models) {
- ALOGW("max_sound_models is greater than the allowed %d", MAX_MAX_SOUND_MODELS);
- return -EINVAL;
- }
-
stdev->next_sound_model_id = 1;
- unsigned int i;
- for(i = 0; i < hw_properties.max_sound_models; i++) {
- stdev->model_context[i].loaded_sound_model = 0;
- stdev->model_context[i].sound_model_callback = NULL;
- stdev->model_context[i].sound_model_cookie = NULL;
- stdev->model_context[i].config = NULL;
- stdev->model_context[i].recognition_callback = NULL;
- stdev->model_context[i].recognition_cookie = NULL;
- }
stdev->device.common.tag = HARDWARE_DEVICE_TAG;
stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_0;
@@ -534,3 +598,4 @@
.methods = &hal_module_methods,
},
};
+