Merge "hwcomposer: Allow display configuration selection"
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 6558dda..7ff5b78 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -428,7 +428,10 @@
/**
* return the frame size (number of bytes per sample).
+ *
+ * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead.
*/
+__attribute__((__deprecated__))
static inline size_t audio_stream_frame_size(const struct audio_stream *s)
{
size_t chan_samp_sz;
@@ -442,6 +445,37 @@
return sizeof(int8_t);
}
+/**
+ * return the frame size (number of bytes per sample) of an output stream.
+ */
+static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s)
+{
+ size_t chan_samp_sz;
+ audio_format_t format = s->common.get_format(&s->common);
+
+ if (audio_is_linear_pcm(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;
+ }
+
+ return sizeof(int8_t);
+}
+
+/**
+ * return the frame size (number of bytes per sample) of an input stream.
+ */
+static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s)
+{
+ size_t chan_samp_sz;
+ audio_format_t format = s->common.get_format(&s->common);
+
+ if (audio_is_linear_pcm(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;
+ }
+
+ return sizeof(int8_t);
+}
/**********************************************************************/
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index a074f4f..4d38ff7 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -45,6 +45,7 @@
#define BT_PROFILE_SOCKETS_ID "socket"
#define BT_PROFILE_HIDHOST_ID "hidhost"
#define BT_PROFILE_PAN_ID "pan"
+#define BT_PROFILE_MAP_CLIENT_ID "map_client"
#define BT_PROFILE_GATT_ID "gatt"
#define BT_PROFILE_AV_RC_ID "avrcp"
diff --git a/include/hardware/bt_mce.h b/include/hardware/bt_mce.h
new file mode 100644
index 0000000..5d159b3
--- /dev/null
+++ b/include/hardware/bt_mce.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 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_INCLUDE_BT_MCE_H
+#define ANDROID_INCLUDE_BT_MCE_H
+
+__BEGIN_DECLS
+
+/** MAS instance description */
+typedef struct
+{
+ int id;
+ int scn;
+ int msg_types;
+ char *p_name;
+} btmce_mas_instance_t;
+
+/** callback for get_remote_mas_instances */
+typedef void (*btmce_remote_mas_instances_callback)(bt_status_t status, bt_bdaddr_t *bd_addr,
+ int num_instances, btmce_mas_instance_t *instances);
+
+typedef struct {
+ /** set to sizeof(btmce_callbacks_t) */
+ size_t size;
+ btmce_remote_mas_instances_callback remote_mas_instances_cb;
+} btmce_callbacks_t;
+
+typedef struct {
+ /** set to size of this struct */
+ size_t size;
+
+ /** register BT MCE callbacks */
+ bt_status_t (*init)(btmce_callbacks_t *callbacks);
+
+ /** search for MAS instances on remote device */
+ bt_status_t (*get_remote_mas_instances)(bt_bdaddr_t *bd_addr);
+} btmce_interface_t;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_BT_MCE_H */
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index 07d19a6..b024090 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -1123,11 +1123,13 @@
* a request at some future point.
*
* For ZSL use case, the pixel format for bidirectional stream will be
- * HAL_PIXEL_FORMAT_RAW_OPAQUE if it is listed in
- * android.scaler.availableInputOutputFormatsMap. A configuration stream list
- * that has BIDIRECTIONAL stream used as input, will usually also have a
- * distinct OUTPUT stream to get the reprocessing data. For example, for the
- * ZSL use case, the stream list might be configured with the following:
+ * HAL_PIXEL_FORMAT_RAW_OPAQUE or HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED if it
+ * is listed in android.scaler.availableInputOutputFormatsMap. When
+ * HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, the gralloc
+ * usage flags for the consumer endpoint will be set to GRALLOC_USAGE_HW_CAMERA_ZSL.
+ * A configuration stream list that has BIDIRECTIONAL stream used as input, will
+ * usually also have a distinct OUTPUT stream to get the reprocessing data. For example,
+ * for the ZSL use case, the stream list might be configured with the following:
*
* - A HAL_PIXEL_FORMAT_RAW_OPAQUE bidirectional stream is used
* as input.
@@ -1950,7 +1952,8 @@
* less than the buffer count in the capture request, at least one more call
* to process_capture_result with the same frame_number must be made, to
* return the remaining output buffers to the framework. This may only be
- * zero if the structure includes valid result metadata.
+ * zero if the structure includes valid result metadata or an input buffer
+ * is returned in this result.
*/
uint32_t num_output_buffers;
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index 7244738..3cb006b 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <pthread.h>
#include <sys/socket.h>
+#include <stdbool.h>
#include <hardware/hardware.h>
@@ -39,6 +40,9 @@
/** Maximum number of SVs for gps_sv_status_callback(). */
#define GPS_MAX_SVS 32
+/** Maximum number of Measurements in gps_measurement_callback(). */
+#define GPS_MAX_MEASUREMENT 32
+
/** Requested operational mode for GPS operation. */
typedef uint32_t GpsPositionMode;
// IMPORTANT: Note that the following values must match
@@ -213,6 +217,102 @@
#define AGPS_RIL_NETWORK_TTYPE_WIMAX 6
/**
+ * Flags to indicate what fields in GpsClock are valid.
+ */
+typedef uint16_t GpsClockFlags;
+/** A valid 'leap second' is stored in the data structure. */
+#define GPS_CLOCK_HAS_LEAP_SECOND (1<<0)
+/** A valid 'time uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_TIME_UNCERTAINTY (1<<1)
+/** A valid 'bias' is stored in the data structure. */
+#define GPS_CLOCK_HAS_BIAS (1<<2)
+/** A valid 'bias uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_BIAS_UNCERTAINTY (1<<3)
+/** A valid 'drift' is stored in the data structure. */
+#define GPS_CLOCK_HAS_DRIFT (1<<4)
+/** A valid 'drift uncertainty' is stored in the data structure. */
+#define GPS_CLOCK_HAS_DRIFT_UNCERTAINTY (1<<5)
+
+/**
+ * Flags to indicate what fields in GpsMeasurement are valid.
+ */
+typedef uint32_t GpsMeasurementFlags;
+/** A valid 'snr' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_SNR (1<<0)
+/** A valid 'elevation' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_ELEVATION (1<<1)
+/** A valid 'elevation uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY (1<<2)
+/** A valid 'azimuth' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_AZIMUTH (1<<3)
+/** A valid 'azimuth uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY (1<<4)
+/** A valid 'pseudorange' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_PSEUDORANGE (1<<5)
+/** A valid 'pseudorange uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY (1<<6)
+/** A valid 'code phase' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CODE_PHASE (1<<7)
+/** A valid 'code phase uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY (1<<8)
+/** A valid 'carrier frequency' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY (1<<9)
+/** A valid 'carrier cycles' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_CYCLES (1<<10)
+/** A valid 'carrier phase' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_PHASE (1<<11)
+/** A valid 'carrier phase uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY (1<<12)
+/** A valid 'bit number' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_BIT_NUMBER (1<<13)
+/** A valid 'time from last bit' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT (1<<14)
+/** A valid 'doppler shift' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT (1<<15)
+/** A valid 'doppler shift uncertainty' is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY (1<<16)
+/** A valid 'used in fix' flag is stored in the data structure. */
+#define GPS_MEASUREMENT_HAS_USED_IN_FIX (1<<17)
+
+/**
+ * Flags that indicate the available values for the GPS Measurement's loss of lock.
+ */
+typedef uint8_t GpsLossOfLock;
+/** The indicator is not available or it is unknown. */
+#define GPS_LOSS_OF_LOCK_UNKNOWN 0
+/** The measurement does not present any indication of loss of lock. */
+#define GPS_LOSS_OF_LOCK_OK 1
+/** Loss of lock between previous and current observation: cycle slip possible. */
+#define GPS_LOSS_OF_LOCK_CYCLE_SLIP 2
+
+/**
+ * Flags that indicate the available values for the GPS Measurement's multipath indicator.
+ */
+typedef uint8_t GpsMultipathIndicator;
+/** The indicator is not available or unknown. */
+#define GPS_MULTIPATH_INDICATOR_UNKNOWN 0
+/** The measurement has been indicated to use multipath. */
+#define GPS_MULTIPATH_INDICATOR_DETECTED 1
+/** The measurement has been indicated Not to use multipath. */
+#define GPS_MULTIPATH_INDICATOR_NOT_USED 2
+
+/**
+ * Flags to indicate the available GPS Natigation message types.
+ */
+typedef uint8_t GpsNavigationMessageType;
+/** The message type is unknown. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_UNKNOWN 0
+/** L1 C/A message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L1CA 1
+/** L2-CNAV message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L2CNAV 2
+/** L5-CNAV message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_L5CNAV 3
+/** CNAV-2 message contained in the structure. */
+#define GPS_NAVIGATION_MESSAGE_TYPE_CNAV2 4
+
+
+/**
* Name for the GPS XTRA interface.
*/
#define GPS_XTRA_INTERFACE "gps-xtra"
@@ -247,6 +347,16 @@
*/
#define GPS_GEOFENCING_INTERFACE "gps_geofencing"
+/**
+ * Name of the GPS Measurements interface.
+ */
+#define GPS_MEASUREMENT_INTERFACE "gps_measurement"
+
+/**
+ * Name of the GPS navigation message interface.
+ */
+ #define GPS_NAVIGATION_MESSAGE_INTERFACE "gps_navigation_message"
+
/** Represents a location. */
typedef struct {
@@ -320,6 +430,7 @@
uint32_t used_in_fix_mask;
} GpsSvStatus;
+
/* 2G and 3G */
/* In 3G lac is discarded */
typedef struct {
@@ -353,8 +464,9 @@
*/
typedef void (* gps_status_callback)(GpsStatus* status);
-/** Callback with SV status information.
- * Can only be called from a thread created by create_thread_cb.
+/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
*/
typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
@@ -406,7 +518,7 @@
size_t size;
/**
* Opens the interface and provides the callback routines
- * to the implemenation of this interface.
+ * to the implementation of this interface.
*/
int (*init)( GpsCallbacks* callbacks );
@@ -467,7 +579,7 @@
size_t size;
/**
* Opens the XTRA interface and provides the callback routines
- * to the implemenation of this interface.
+ * to the implementation of this interface.
*/
int (*init)( GpsXtraCallbacks* callbacks );
/** Injects XTRA data into the GPS. */
@@ -547,7 +659,7 @@
/**
* Opens the AGPS interface and provides the callback routines
- * to the implemenation of this interface.
+ * to the implementation of this interface.
*/
void (*init)( AGpsCallbacks* callbacks );
/**
@@ -631,7 +743,7 @@
u_char data[20];
} Sha1CertificateFingerprint;
-/** AGPS Inteface to handle SUPL certificate operations */
+/** AGPS Interface to handle SUPL certificate operations */
typedef struct {
/** set to sizeof(SuplCertificateInterface) */
size_t size;
@@ -803,7 +915,7 @@
size_t size;
/**
* Opens the AGPS interface and provides the callback routines
- * to the implemenation of this interface.
+ * to the implementation of this interface.
*/
void (*init)( AGpsRilCallbacks* callbacks );
@@ -942,7 +1054,7 @@
int32_t transition, GpsUtcTime timestamp);
/**
- * The callback associated with the availablity of the GPS system for geofencing
+ * The callback associated with the availability of the GPS system for geofencing
* monitoring. If the GPS system determines that it cannot monitor geofences
* because of lack of reliability or unavailability of the GPS signals, it will
* call this callback with GPS_GEOFENCE_UNAVAILABLE parameter.
@@ -1020,7 +1132,7 @@
/**
* Opens the geofence interface and provides the callback routines
- * to the implemenation of this interface.
+ * to the implementation of this interface.
*/
void (*init)( GpsGeofenceCallbacks* callbacks );
@@ -1050,14 +1162,12 @@
* sampling the GPS for power-saving reasons; thus the rate of
* sampling may be faster or slower than this.
* unknown_timer_ms - The time limit after which the UNCERTAIN transition
- * should be triggered. This paramter is defined in milliseconds.
+ * should be triggered. This parameter is defined in milliseconds.
* See above for a detailed explanation.
*/
- void (*add_geofence_area) (int32_t geofence_id, double latitude,
- double longitude, double radius_meters,
- int last_transition, int monitor_transitions,
- int notification_responsiveness_ms,
- int unknown_timer_ms);
+ void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int last_transition, int monitor_transitions,
+ int notification_responsiveness_ms, int unknown_timer_ms);
/**
* Pause monitoring a particular geofence.
@@ -1086,6 +1196,471 @@
*/
void (*remove_geofence_area) (int32_t geofence_id);
} GpsGeofencingInterface;
+
+
+/**
+ * Represents an estimate of the GPS clock time.
+ */
+typedef struct {
+ /** set to sizeof(GpsClock) */
+ size_t size;
+
+ /** A set of flags indicating the validity of the fields in this data structure. */
+ GpsClockFlags flags;
+
+ /**
+ * Leap second data.
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_LEAP_SECOND.
+ */
+ int16_t leap_second;
+
+ /**
+ * The receiver's GPS time since 0000Z, January 6, 1980 in nanoseconds.
+ * It is referenced using the uncorrected receiver's clock ('bias_ns' included).
+ * The current precision allows a range that spans approximately to the end of the year 2272.
+ *
+ * Sub-nanosecond accuracy can be provided for each individual measurement using the field
+ * GpsMeasurement::time_offset_ns.
+ *
+ * The value contains the 'time uncertainty' in it.
+ * This is a Mandatory field.
+ */
+ int64_t time_ns;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's time in nanoseconds.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_TIME_UNCERTAINTY.
+ */
+ double time_uncertainty_ns;
+
+ /**
+ * The clock's bias in nanoseconds.
+ * The sign of the value is defined by the following equation:
+ * true time = time - bias.
+ *
+ * The value contains the 'bias uncertainty' in it.
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS.
+ */
+ double bias_ns;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's bias in nanoseconds.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS_UNCERTAINTY.
+ */
+ double bias_uncertainty_ns;
+
+ /**
+ * The clock's drift in nanoseconds (per second).
+ * A positive value means that the frequency is higher than the nominal frequency.
+ *
+ * The value contains the 'drift uncertainty' in it.
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT.
+ */
+ double drift_nsps;
+
+ /**
+ * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per second).
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT_UNCERTAINTY.
+ */
+ double drift_uncertainty_nsps;
+} GpsClock;
+
+/**
+ * Represents a GPS Measurement, it contains raw and computed information.
+ */
+typedef struct {
+ /** set to sizeof(GpsMeasurement) */
+ size_t size;
+
+ /** A set of flags indicating the validity of the fields in this data structure. */
+ GpsMeasurementFlags flags;
+
+ /**
+ * Pseudo-random number in the range of [1, 32]
+ * This is a Mandatory value.
+ */
+ int8_t prn;
+
+ /**
+ * Local hardware time offset at which the measurement was taken in nanoseconds.
+ * The reference receiver's time is specified by GpsData::clock.
+ * The sign of time_offset_ns is given by the following equation:
+ * measurement time = GpsClock::time_ns + time_offset_ns
+ *
+ * It provides an individual time-stamp for the measurement, and allows sub-nanosecond accuracy.
+ * This is a Mandatory value.
+ */
+ int64_t time_offset_ns;
+
+ /**
+ * Received GPS Time-of-Week in nanoseconds.
+ * The value is relative to the beginning of the current GPS week.
+ *
+ * This is a Mandatory value.
+ */
+ int64_t received_gps_tow_ns;
+
+ /**
+ * Carrier-to-noise density in dB-Hz, in the range [0, 63].
+ * It contains the measured C/N0 value for the signal at the antenna input.
+ *
+ * This is a Mandatory value.
+ */
+ double c_n0_dbhz;
+
+ /**
+ * Pseudorange rate at the timestamp in m/s.
+ * The value also includes the effects of the receiver clock frequency and satellite clock
+ * frequency errors.
+ *
+ * The value includes the 'pseudorange rate uncertainty' in it.
+ * A positive value indicates that the pseudorange is getting larger.
+ *
+ * This is a Mandatory value.
+ */
+ double pseudorange_rate_mpersec;
+
+ /**
+ * 1-Sigma uncertainty of the pseudurange rate in m/s.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * This is a Mandatory value.
+ */
+ double pseudorange_rate_uncertainty_mpersec;
+
+ /**
+ * Accumulated delta range since the last channel reset in meters.
+ *
+ * This is a Mandatory value.
+ */
+ double accumulated_delta_range_m;
+
+ /**
+ * 1-Sigma uncertainty of the accumulated delta range in meters.
+ *
+ * This is a Mandatory value.
+ */
+ double accumulated_delta_range_uncertainty_m;
+
+ /**
+ * Best derived Pseudorange by the chip-set, in meters.
+ * The value contains the 'pseudorange uncertainty' in it.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE.
+ */
+ double pseudorange_m;
+
+ /**
+ * 1-Sigma uncertainty of the pseudorange in meters.
+ * The value contains the 'pseudorange' and 'clock' uncertainty in it.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY.
+ */
+ double pseudorange_uncertainty_m;
+
+ /**
+ * A fraction of the current C/A code cycle, in the range [0.0, 1023.0]
+ * This value contains the time (in Chip units) since the last C/A code cycle (GPS Msec epoch).
+ *
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ * The value contains the 'code-phase uncertainty' in it.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE.
+ */
+ double code_phase_chips;
+
+ /**
+ * 1-Sigma uncertainty of the code-phase, in a fraction of chips.
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY.
+ */
+ double code_phase_uncertainty_chips;
+
+ /**
+ * Carrier frequency at which codes and messages are modulated, it can be L1 or L2.
+ * If the field is not set, the carrier frequency is assumed to be L1.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY.
+ */
+ float carrier_frequency_hz;
+
+ /**
+ * The number of full carrier cycles between the satellite and the receiver.
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_CYCLES.
+ */
+ int64_t carrier_cycles;
+
+ /**
+ * The RF phase detected by the receiver, in the range [0.0, 1.0].
+ * This is usually the fractional part of the complete carrier phase measurement.
+ *
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ * The value contains the 'carrier-phase uncertainty' in it.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE.
+ */
+ double carrier_phase;
+
+ /**
+ * 1-Sigma uncertainty of the carrier-phase.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY.
+ */
+ double carrier_phase_uncertainty;
+
+ /**
+ * An enumeration that indicates the 'loss of lock' state of the event.
+ */
+ GpsLossOfLock loss_of_lock;
+
+ /**
+ * The number of GPS bits transmitted since Sat-Sun midnight (GPS week).
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_BIT_NUMBER.
+ */
+ int16_t bit_number;
+
+ /**
+ * The elapsed time since the last received bit in nanoseconds, in the range [0, 20,000,000]
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT.
+ */
+ int64_t time_from_last_bit_ns;
+
+ /**
+ * Doppler shift in Hz.
+ * A positive value indicates that the SV is moving toward the receiver.
+ *
+ * The reference frequency is given by the field 'carrier_frequency_hz'.
+ * The value contains the 'doppler shift uncertainty' in it.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT.
+ */
+ double doppler_shift_hz;
+
+ /**
+ * 1-Sigma uncertainty of the doppler shift in Hz.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY.
+ */
+ double doppler_shift_uncertainty_hz;
+
+ /**
+ * An enumeration that indicates the 'multipath' state of the event.
+ */
+ GpsMultipathIndicator multipath_indicator;
+
+ /**
+ * Signal-to-noise ratio in dB.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_SNR.
+ */
+ double snr_db;
+
+ /**
+ * Elevation in degrees, the valid range is [-90, 90].
+ * The value contains the 'elevation uncertainty' in it.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION.
+ */
+ double elevation_deg;
+
+ /**
+ * 1-Sigma uncertainty of the elevation in degrees, the valid range is [0, 90].
+ * The uncertainty is represented as the absolute (single sided) value.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY.
+ */
+ double elevation_uncertainty_deg;
+
+ /**
+ * Azimuth in degrees, in the range [0, 360).
+ * The value contains the 'azimuth uncertainty' in it.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH.
+ * */
+ double azimuth_deg;
+
+ /**
+ * 1-Sigma uncertainty of the azimuth in degrees, the valid range is [0, 180].
+ * The uncertainty is represented as an absolute (single sided) value.
+ *
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY.
+ */
+ double azimuth_uncertainty_deg;
+
+ /**
+ * Whether the GPS represented by the measurement was used for computing the most recent fix.
+ * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_USED_IN_FIX.
+ */
+ bool used_in_fix;
+} GpsMeasurement;
+
+/** Represents a reading of GPS measurements. */
+typedef struct {
+ /** set to sizeof(GpsData) */
+ size_t size;
+
+ /** Number of measurements. */
+ size_t measurement_count;
+
+ /** The array of measurements. */
+ GpsMeasurement measurements[GPS_MAX_MEASUREMENT];
+
+ /** The GPS clock time reading. */
+ GpsClock clock;
+} GpsData;
+
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ * data - A data structure containing the measurements.
+ */
+typedef void (*gps_measurement_callback) (GpsData* data);
+
+typedef struct {
+ /** set to sizeof(GpsMeasurementCallbacks) */
+ size_t size;
+ gps_measurement_callback measurement_callback;
+} GpsMeasurementCallbacks;
+
+#define GPS_MEASUREMENT_OPERATION_SUCCESS 0
+#define GPS_MEASUREMENT_ERROR_ALREADY_INIT -100
+#define GPS_MEASUREMENT_ERROR_GENERIC -101
+
+/**
+ * Extended interface for GPS Measurements support.
+ */
+typedef struct {
+ /** Set to sizeof(GpsMeasurementInterface) */
+ size_t size;
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL.
+ * After a successful call to 'init' the HAL must begin to provide updates at its own phase.
+ *
+ * Status:
+ * GPS_MEASUREMENT_OPERATION_SUCCESS
+ * GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a
+ * corresponding call to 'close'
+ * GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL
+ * will not generate any updates upon returning this error code.
+ */
+ int (*init) (GpsMeasurementCallbacks* callbacks);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines.
+ * After a call to stop, the previously registered callbacks must be considered invalid by the
+ * HAL.
+ * If stop is invoked without a previous 'init', this function should perform no work.
+ */
+ void (*close) ();
+
+} GpsMeasurementInterface;
+
+
+/** Represents a GPS navigation message (or a fragment of it). */
+typedef struct {
+ /** set to sizeof(GpsNavigationMessage) */
+ size_t size;
+
+ /**
+ * Pseudo-random number in the range of [1, 32]
+ * This is a Mandatory value.
+ */
+ int8_t prn;
+
+ /**
+ * The type of message contained in the structure.
+ * This is a Mandatory value.
+ */
+ GpsNavigationMessageType type;
+
+ /**
+ * Message identifier.
+ * It provides an index so the complete Navigation Message can be assembled.
+ * i.e. for L1 C/A the message id corresponds to the frame id of the navigation message.
+ */
+ int16_t message_id;
+
+ /**
+ * Sub-message identifier.
+ * If required by the message 'type', this value contains a sub-index within the current
+ * message (or frame) that is being transmitted.
+ * i.e. for L1 C/A the submessage id corresponds to the sub-frame id of the navigation message.
+ */
+ int16_t submessage_id;
+
+ /**
+ * The length of the data (in bytes) contained in the current message.
+ * If this value is different from zero, 'data' must point to an array of the same size.
+ * i.e. for L1 C/A the size of the sub-frame will be 40 bytes (10 words).
+ *
+ * This is a Mandatory value.
+ */
+ size_t data_length;
+
+ /**
+ * The data of the reported GPS message.
+ * The bytes (or words) specified using big endian format (MSB first).
+ */
+ uint8_t* data;
+
+} GpsNavigationMessage;
+
+/**
+ * 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 (*gps_navigation_message_callback) (GpsNavigationMessage* message);
+
+typedef struct {
+ /** set to sizeof(GpsNavigationMessageCallbacks) */
+ size_t size;
+ gps_navigation_message_callback navigation_message_callback;
+} GpsNavigationMessageCallbacks;
+
+#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS 0
+#define GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT -100
+#define GPS_NAVIGATION_MESSAGE_ERROR_GENERIC -101
+
+/**
+ * Extended interface for GPS navigation message reporting support.
+ */
+typedef struct {
+ /** Set to sizeof(GpsNavigationMessageInterface) */
+ size_t size;
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL.
+ * After a successful call to 'init' the HAL must begin to provide updates as they become
+ * available.
+ *
+ * Status:
+ * GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS
+ * GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT - if a callback has already been registered
+ * without a corresponding call to 'close'.
+ * GPS_NAVIGATION_MESSAGE_ERROR_GENERIC - if any other error occurred, it is expected that
+ * the HAL will not generate any updates upon returning this error code.
+ */
+ int (*init) (GpsNavigationMessageCallbacks* callbacks);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines.
+ * After a call to stop, the previously registered callbacks must be considered invalid by the
+ * HAL.
+ * If stop is invoked without a previous 'init', this function should perform no work.
+ */
+ void (*close) ();
+
+} GpsNavigationMessageInterface;
+
__END_DECLS
#endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */
diff --git a/include/hardware/hdmi_cec.h b/include/hardware/hdmi_cec.h
index 46294ae..95c0c4e 100644
--- a/include/hardware/hdmi_cec.h
+++ b/include/hardware/hdmi_cec.h
@@ -156,7 +156,6 @@
enum {
HDMI_EVENT_CEC_MESSAGE = 1,
HDMI_EVENT_HOT_PLUG = 2,
- HDMI_EVENT_TX_STATUS = 3,
};
/*
@@ -169,21 +168,13 @@
};
/*
- * TX result type. Used when the event type is HDMI_EVENT_TX_STATUS.
- */
-enum {
- HDMI_TX_STATUS_SUCCESS = 0,
- HDMI_TX_STATUS_TIMEDOUT = 1, /* failed on wait */
- HDMI_TX_STATUS_NOCONN = 2 /* connection problem */
-};
-
-/*
* error code used for send_message.
*/
enum {
HDMI_RESULT_SUCCESS = 0,
HDMI_RESULT_NACK = 1, /* not acknowledged */
- HDMI_RESULT_BUSY = 2 /* bus is busy */
+ HDMI_RESULT_BUSY = 2, /* bus is busy */
+ HDMI_RESULT_FAIL = 3,
};
/*
@@ -246,7 +237,7 @@
* true if the cable is connected; otherwise false.
*/
int connected;
- int port;
+ int port_id;
} hotplug_event_t;
typedef struct tx_status_event {
@@ -263,7 +254,6 @@
union {
cec_message_t cec;
hotplug_event_t hotplug;
- tx_status_event_t tx_status;
};
} hdmi_event_t;
@@ -272,7 +262,8 @@
*/
typedef struct hdmi_port_info {
hdmi_port_type_t type;
- int port_num;
+ // Port ID should start from 1 which corresponds to HDMI "port 1".
+ int port_id;
int cec_supported;
int arc_supported;
uint16_t physical_address;
@@ -348,8 +339,7 @@
* some reason. HAL implementation should take the situation into account
* so as not to wait forever for the message to get sent out.
*
- * It should try retransmission at least once as specified in the standard,
- * and later should report the transmission result via tx_status_event_t.
+ * It should try retransmission at least once as specified in the standard.
*
* Returns error code. See HDMI_RESULT_SUCCESS, HDMI_RESULT_NACK, and
* HDMI_RESULT_BUSY.
@@ -407,7 +397,7 @@
* Returns HDMI_CONNECTED if a device is connected, otherwise HDMI_NOT_CONNECTED.
* The HAL should watch for +5V power signal to determine the status.
*/
- int (*is_connected)(const struct hdmi_cec_device* dev, int port);
+ int (*is_connected)(const struct hdmi_cec_device* dev, int port_id);
/* Reserved for future use to maximum 16 functions. Must be NULL. */
void* reserved[16 - 11];
diff --git a/include/hardware/sound_trigger.h b/include/hardware/sound_trigger.h
index fc3ac47..2a8db87 100644
--- a/include/hardware/sound_trigger.h
+++ b/include/hardware/sound_trigger.h
@@ -98,12 +98,9 @@
*/
int (*start_recognition)(const struct sound_trigger_hw_device *dev,
sound_model_handle_t sound_model_handle,
- audio_io_handle_t capture_handle,
- audio_devices_t capture_device,
+ const struct sound_trigger_recognition_config *config,
recognition_callback_t callback,
- void *cookie,
- unsigned int data_size,
- char *data);
+ void *cookie);
/* Stop recognition on a given model.
* The implementation does not have to call the callback when stopped via this method.
diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c
index 3051519..2f44d95 100644
--- a/modules/audio/audio_hw.c
+++ b/modules/audio/audio_hw.c
@@ -105,7 +105,7 @@
size_t bytes)
{
/* XXX: fake timing for audio output */
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
out_get_sample_rate(&stream->common));
return bytes;
}
@@ -193,7 +193,7 @@
size_t bytes)
{
/* XXX: fake timing for audio input */
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+ usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
in_get_sample_rate(&stream->common));
return bytes;
}
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index 51a5a29..c7e4305 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -307,26 +307,14 @@
offsetof(struct submix_audio_device, device));
}
-// Get the number of channels referenced by the specified channel_mask. The channel_mask can
-// reference either input or output channels.
-uint32_t get_channel_count_from_mask(const audio_channel_mask_t channel_mask) {
- if (audio_is_input_channel(channel_mask)) {
- return popcount(channel_mask & AUDIO_CHANNEL_IN_ALL);
- } else if (audio_is_output_channel(channel_mask)) {
- return popcount(channel_mask & AUDIO_CHANNEL_OUT_ALL);
- }
- ALOGE("get_channel_count(): No channels specified in channel mask %x", channel_mask);
- return 0;
-}
-
// Compare an audio_config with input channel mask and an audio_config with output channel mask
// returning false if they do *not* match, true otherwise.
static bool audio_config_compare(const audio_config * const input_config,
const audio_config * const output_config)
{
#if !ENABLE_CHANNEL_CONVERSION
- const uint32_t input_channels = get_channel_count_from_mask(input_config->channel_mask);
- const uint32_t output_channels = get_channel_count_from_mask(output_config->channel_mask);
+ const uint32_t input_channels = audio_channel_count_from_in_mask(input_config->channel_mask);
+ const uint32_t output_channels = audio_channel_count_from_out_mask(output_config->channel_mask);
if (input_channels != output_channels) {
ALOGE("audio_config_compare() channel count mismatch input=%d vs. output=%d",
input_channels, output_channels);
@@ -335,7 +323,7 @@
#endif // !ENABLE_CHANNEL_CONVERSION
#if ENABLE_RESAMPLING
if (input_config->sample_rate != output_config->sample_rate &&
- get_channel_count_from_mask(input_config->channel_mask) != 1) {
+ audio_channel_count_from_in_mask(input_config->channel_mask) != 1) {
#else
if (input_config->sample_rate != output_config->sample_rate) {
#endif // ENABLE_RESAMPLING
@@ -388,7 +376,11 @@
// If a pipe isn't associated with the device, create one.
if (rsxadev->rsxSink == NULL || rsxadev->rsxSource == NULL) {
struct submix_config * const device_config = &rsxadev->config;
- const uint32_t channel_count = get_channel_count_from_mask(config->channel_mask);
+ uint32_t channel_count;
+ if (out)
+ channel_count = audio_channel_count_from_out_mask(config->channel_mask);
+ else
+ channel_count = audio_channel_count_from_in_mask(config->channel_mask);
#if ENABLE_CHANNEL_CONVERSION
// If channel conversion is enabled, allocate enough space for the maximum number of
// possible channels stored in the pipe for the situation when the number of channels in
@@ -424,8 +416,8 @@
device_config->buffer_size_frames = sink->maxFrames();
device_config->buffer_period_size_frames = device_config->buffer_size_frames /
buffer_period_count;
- if (in) device_config->pipe_frame_size = audio_stream_frame_size(&in->stream.common);
- if (out) device_config->pipe_frame_size = audio_stream_frame_size(&out->stream.common);
+ if (in) device_config->pipe_frame_size = audio_stream_in_frame_size(&in->stream);
+ if (out) device_config->pipe_frame_size = audio_stream_out_frame_size(&out->stream);
#if ENABLE_CHANNEL_CONVERSION
// Calculate the pipe frame size based upon the number of channels.
device_config->pipe_frame_size = (device_config->pipe_frame_size * pipe_channel_count) /
@@ -535,9 +527,9 @@
// Calculate the maximum size of the pipe buffer in frames for the specified stream.
static size_t calculate_stream_pipe_size_in_frames(const struct audio_stream *stream,
const struct submix_config *config,
- const size_t pipe_frames)
+ const size_t pipe_frames,
+ const size_t stream_frame_size)
{
- const size_t stream_frame_size = audio_stream_frame_size(stream);
const size_t pipe_frame_size = config->pipe_frame_size;
const size_t max_frame_size = max(stream_frame_size, pipe_frame_size);
return (pipe_frames * config->pipe_frame_size) / max_frame_size;
@@ -565,7 +557,7 @@
// The sample rate of the stream can't be changed once it's set since this would change the
// output buffer size and hence break playback to the shared pipe.
if (rate != out->dev->config.output_sample_rate) {
- ALOGE("out_set_sample_rate(rate=%u) resampling enabled can't change sample rate from "
+ ALOGE("out_set_sample_rate() resampling enabled can't change sample rate from "
"%u to %u", out->dev->config.output_sample_rate, rate);
return -ENOSYS;
}
@@ -584,9 +576,11 @@
const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
const_cast<struct audio_stream *>(stream));
const struct submix_config * const config = &out->dev->config;
+ const size_t stream_frame_size =
+ audio_stream_out_frame_size((const struct audio_stream_out *)stream);
const size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
- stream, config, config->buffer_period_size_frames);
- const size_t buffer_size_bytes = buffer_size_frames * audio_stream_frame_size(stream);
+ stream, config, config->buffer_period_size_frames, stream_frame_size);
+ const size_t buffer_size_bytes = buffer_size_frames * stream_frame_size;
SUBMIX_ALOGV("out_get_buffer_size() returns %zu bytes, %zu frames",
buffer_size_bytes, buffer_size_frames);
return buffer_size_bytes;
@@ -681,8 +675,10 @@
const struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(
const_cast<struct audio_stream_out *>(stream));
const struct submix_config * const config = &out->dev->config;
+ const size_t stream_frame_size =
+ audio_stream_out_frame_size(stream);
const size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
- &stream->common, config, config->buffer_size_frames);
+ &stream->common, config, config->buffer_size_frames, stream_frame_size);
const uint32_t sample_rate = out_get_sample_rate(&stream->common);
const uint32_t latency_ms = (buffer_size_frames * 1000) / sample_rate;
SUBMIX_ALOGV("out_get_latency() returns %u ms, size in frames %zu, sample rate %u",
@@ -704,7 +700,7 @@
{
SUBMIX_ALOGV("out_write(bytes=%zd)", bytes);
ssize_t written_frames = 0;
- const size_t frame_size = audio_stream_frame_size(&stream->common);
+ const size_t frame_size = audio_stream_out_frame_size(stream);
struct submix_stream_out * const out = audio_stream_out_get_submix_stream_out(stream);
struct submix_audio_device * const rsxadev = out->dev;
const size_t frames = bytes / frame_size;
@@ -839,7 +835,7 @@
// The sample rate of the stream can't be changed once it's set since this would change the
// input buffer size and hence break recording from the shared pipe.
if (rate != in->dev->config.input_sample_rate) {
- ALOGE("in_set_sample_rate(rate=%u) resampling enabled can't change sample rate from "
+ ALOGE("in_set_sample_rate() resampling enabled can't change sample rate from "
"%u to %u", in->dev->config.input_sample_rate, rate);
return -ENOSYS;
}
@@ -858,8 +854,10 @@
const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
const_cast<struct audio_stream*>(stream));
const struct submix_config * const config = &in->dev->config;
+ const size_t stream_frame_size =
+ audio_stream_in_frame_size((const struct audio_stream_in *)stream);
size_t buffer_size_frames = calculate_stream_pipe_size_in_frames(
- stream, config, config->buffer_period_size_frames);
+ stream, config, config->buffer_period_size_frames, stream_frame_size);
#if ENABLE_RESAMPLING
// Scale the size of the buffer based upon the maximum number of frames that could be returned
// given the ratio of output to input sample rate.
@@ -867,7 +865,7 @@
(float)config->input_sample_rate) /
(float)config->output_sample_rate);
#endif // ENABLE_RESAMPLING
- const size_t buffer_size_bytes = buffer_size_frames * audio_stream_frame_size(stream);
+ const size_t buffer_size_bytes = buffer_size_frames * stream_frame_size;
SUBMIX_ALOGV("in_get_buffer_size() returns %zu bytes, %zu frames", buffer_size_bytes,
buffer_size_frames);
return buffer_size_bytes;
@@ -951,7 +949,7 @@
struct submix_stream_in * const in = audio_stream_in_get_submix_stream_in(stream);
struct submix_audio_device * const rsxadev = in->dev;
struct audio_config *format;
- const size_t frame_size = audio_stream_frame_size(&stream->common);
+ const size_t frame_size = audio_stream_in_frame_size(stream);
const size_t frames_to_read = bytes / frame_size;
SUBMIX_ALOGV("in_read bytes=%zu", bytes);
@@ -991,9 +989,9 @@
char* buff = (char*)buffer;
#if ENABLE_CHANNEL_CONVERSION
// Determine whether channel conversion is required.
- const uint32_t input_channels = get_channel_count_from_mask(
+ const uint32_t input_channels = audio_channel_count_from_in_mask(
rsxadev->config.input_channel_mask);
- const uint32_t output_channels = get_channel_count_from_mask(
+ const uint32_t output_channels = audio_channel_count_from_out_mask(
rsxadev->config.output_channel_mask);
if (input_channels != output_channels) {
SUBMIX_ALOGV("in_read(): %d output channels will be converted to %d "
@@ -1017,7 +1015,7 @@
// Only support 16-bit PCM mono resampling.
// NOTE: Resampling is performed after the channel conversion step.
ALOG_ASSERT(rsxadev->config.common.format == AUDIO_FORMAT_PCM_16_BIT);
- ALOG_ASSERT(get_channel_count_from_mask(rsxadev->config.input_channel_mask) == 1);
+ ALOG_ASSERT(audio_channel_count_from_in_mask(rsxadev->config.input_channel_mask) == 1);
}
#endif // ENABLE_RESAMPLING
@@ -1361,7 +1359,7 @@
const size_t buffer_period_size_frames =
audio_hw_device_get_submix_audio_device(const_cast<struct audio_hw_device*>(dev))->
config.buffer_period_size_frames;
- const size_t frame_size_in_bytes = get_channel_count_from_mask(config->channel_mask) *
+ const size_t frame_size_in_bytes = audio_channel_count_from_in_mask(config->channel_mask) *
audio_bytes_per_sample(config->format);
const size_t buffer_size = buffer_period_size_frames * frame_size_in_bytes;
SUBMIX_ALOGV("adev_get_input_buffer_size() returns %zu bytes, %zu frames",
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index a4ffd20..092e851 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -29,5 +29,8 @@
LOCAL_MODULE := gralloc.default
LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
+ifeq ($(TARGET_USE_PAN_DISPLAY),true)
+LOCAL_CFLAGS += -DUSE_PAN_DISPLAY=1
+endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp
index 9d8513a..486e27a 100644
--- a/modules/gralloc/framebuffer.cpp
+++ b/modules/gralloc/framebuffer.cpp
@@ -42,6 +42,13 @@
/*****************************************************************************/
+// Set TARGET_USE_PAN_DISPLAY to true at compile time if the
+// board uses FBIOPAN_DISPLAY to setup page flipping, otherwise
+// default ioctl to do page-flipping is FBIOPUT_VSCREENINFO.
+#ifndef USE_PAN_DISPLAY
+#define USE_PAN_DISPLAY 0
+#endif
+
// numbers of buffers for page flipping
#define NUM_BUFFERS 2
@@ -178,10 +185,15 @@
uint32_t flags = PAGE_FLIP;
+#if USE_PAN_DISPLAY
+ if (ioctl(fd, FBIOPAN_DISPLAY, &info) == -1) {
+ ALOGW("FBIOPAN_DISPLAY failed, page flipping not supported");
+#else
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+ ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+#endif
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
- ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
}
if (info.yres_virtual < info.yres * 2) {
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index 8347d02..b78a0d1 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -81,8 +81,9 @@
event->key_phrase_in_capture = false;
event->num_phrases = 1;
event->phrase_extras[0].recognition_modes = RECOGNITION_MODE_VOICE_TRIGGER;
- event->phrase_extras[0].num_users = 1;
- event->phrase_extras[0].confidence_levels[0] = 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;
event->common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
event->common.data_size = 1;
data[event->common.data_offset] = 8;
@@ -183,12 +184,9 @@
static int stdev_start_recognition(const struct sound_trigger_hw_device *dev,
sound_model_handle_t sound_model_handle,
- audio_io_handle_t capture_handle __unused,
- audio_devices_t capture_device __unused,
+ const struct sound_trigger_recognition_config *config,
recognition_callback_t callback,
- void *cookie,
- unsigned int data_size,
- char *data)
+ void *cookie)
{
struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
int status = 0;
@@ -202,13 +200,10 @@
status = -ENOSYS;
goto exit;
}
- if (data_size != 0 && data == NULL) {
- status = -EINVAL;
- goto exit;
- }
- if (data_size != 0) {
+ if (config->data_size != 0) {
+ char *data = (char *)config + config->data_offset;
ALOGI("%s data size %d data %d - %d", __func__,
- data_size, data[0], data[data_size - 1]);
+ config->data_size, data[0], data[config->data_size - 1]);
}
stdev->recognition_callback = callback;
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 7b65014..b2005c6 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -16,6 +16,7 @@
#define LOG_TAG "usb_audio_hw"
/*#define LOG_NDEBUG 0*/
+/*#define LOG_PCM_PARAMS 0*/
#include <errno.h>
#include <inttypes.h>
@@ -36,6 +37,8 @@
#include <tinyalsa/asoundlib.h>
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
/* This is the default configuration to hand to The Framework on the initial
* adev_open_output_stream(). Actual device attributes will be used on the subsequent
* adev_open_output_stream() after the card and device number have been set in out_set_parameters()
@@ -69,18 +72,22 @@
.stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
};
+struct audio_device_profile {
+ int card;
+ int device;
+ int direction; /* PCM_OUT or PCM_IN */
+};
+
struct audio_device {
struct audio_hw_device hw_device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
/* output */
- int out_card;
- int out_device;
+ struct audio_device_profile out_profile;
/* input */
- int in_card;
- int in_device;
+ struct audio_device_profile in_profile;
bool standby;
};
@@ -93,6 +100,7 @@
bool standby;
struct audio_device *dev; /* hardware information */
+ struct audio_device_profile * profile;
void * conversion_buffer; /* any conversions are put into here
* they could come from here too if
@@ -102,8 +110,7 @@
/*
* Output Configuration Cache
- * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure
- * but that will involve changes in The Framework.
+ * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure.
*/
static struct pcm_config cached_output_hardware_config;
static bool output_hardware_config_is_cached = false;
@@ -117,8 +124,15 @@
struct audio_device *dev;
+ struct audio_device_profile * profile;
+
struct audio_config hal_pcm_config;
+ /* this is the format the framework thinks it's using. We may need to convert from the actual
+ * (24-bit, 32-bit?) format to this theoretical (framework, probably 16-bit)
+ * format in in_read() */
+ enum pcm_format input_framework_format;
+
// struct resampler_itfe *resampler;
// struct resampler_buffer_provider buf_provider;
@@ -155,7 +169,6 @@
* We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
* support PCM24_3LE (24-bit, packed).
* NOTE:
- * We're just filling the low-order byte of the PCM24LE samples with 0.
* This conversion is safe to do in-place (in_buff == out_buff).
* TODO Move this to a utilities module.
*/
@@ -181,6 +194,37 @@
}
/*
+ * Convert a buffer of packed (3-byte) PCM32 samples to PCM16LE samples.
+ * in_buff points to the buffer of PCM32 samples
+ * num_in_samples size of input buffer in SAMPLES
+ * out_buff points to the buffer to receive converted PCM16LE LE samples.
+ * returns
+ * the number of BYTES of output data.
+ * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
+ * support PCM_FORMAT_S32_LE (32-bit).
+ * NOTE:
+ * This conversion is safe to do in-place (in_buff == out_buff).
+ * TODO Move this to a utilities module.
+ */
+static size_t convert_32_to_16(const int32_t * in_buff, size_t num_in_samples, short * out_buff)
+{
+ /*
+ * Move from front to back so that the conversion can be done in-place
+ * i.e. in_buff == out_buff
+ */
+
+ short * dst_ptr = out_buff;
+ const int32_t* src_ptr = in_buff;
+ size_t src_smpl_index;
+ for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
+ *dst_ptr++ = *src_ptr++ >> 16;
+ }
+
+ /* return number of *bytes* generated: */
+ return num_in_samples * 2;
+}
+
+/*
* Convert a buffer of N-channel, interleaved PCM16 samples to M-channel PCM16 channels
* (where N < M).
* in_buff points to the buffer of PCM16 samples
@@ -373,14 +417,14 @@
/*
* Maps from bit position in pcm_mask to AUDIO_ format constants.
*/
-static int const format_value_map[] = {
+static audio_format_t const format_value_map[] = {
AUDIO_FORMAT_PCM_8_BIT, /* 00 - SNDRV_PCM_FORMAT_S8 */
AUDIO_FORMAT_PCM_8_BIT, /* 01 - SNDRV_PCM_FORMAT_U8 */
AUDIO_FORMAT_PCM_16_BIT, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
AUDIO_FORMAT_INVALID, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
AUDIO_FORMAT_INVALID, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
AUDIO_FORMAT_INVALID, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
- AUDIO_FORMAT_PCM_24_BIT_PACKED, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
+ AUDIO_FORMAT_INVALID, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
AUDIO_FORMAT_INVALID, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
AUDIO_FORMAT_INVALID, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
AUDIO_FORMAT_INVALID, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
@@ -406,7 +450,7 @@
AUDIO_FORMAT_INVALID,
AUDIO_FORMAT_INVALID,
AUDIO_FORMAT_INVALID, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
- AUDIO_FORMAT_PCM_24_BIT_PACKED, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
+ AUDIO_FORMAT_PCM_24_BIT_PACKED, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */
AUDIO_FORMAT_INVALID, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
AUDIO_FORMAT_INVALID, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
AUDIO_FORMAT_INVALID, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
@@ -426,6 +470,13 @@
AUDIO_FORMAT_INVALID /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
};
+/*
+ * Returns true if mask indicates support for PCM_16.
+ */
+static bool mask_has_pcm_16(struct pcm_mask* mask) {
+ return (mask->bits[0] & 0x0004) != 0;
+}
+
static int get_format_for_mask(struct pcm_mask* mask)
{
int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
@@ -525,7 +576,7 @@
/* just return the first one */
return table_index < table_size
? pcm_format_value_map[table_index]
- : AUDIO_FORMAT_INVALID;
+ : (int)AUDIO_FORMAT_INVALID;
}
bit_mask <<= 1;
table_index++;
@@ -535,6 +586,54 @@
return 0; // is this right?
}
+static bool test_out_sample_rate(struct audio_device_profile* dev_profile, unsigned rate) {
+ struct pcm_config local_config = cached_output_hardware_config;
+ local_config.rate = rate;
+
+ bool works = false; /* let's be pessimistic */
+ struct pcm * pcm =
+ pcm_open(dev_profile->card, dev_profile->device, dev_profile->direction, &local_config);
+
+ if (pcm != NULL) {
+ works = pcm_is_ready(pcm);
+ pcm_close(pcm);
+ }
+
+ return works;
+}
+
+/* sort these highest -> lowest */
+static const unsigned std_sample_rates[] =
+ {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
+
+static char* enum_std_sample_rates(struct audio_device_profile* dev_profile,
+ unsigned min, unsigned max)
+{
+ char buffer[128];
+ buffer[0] = '\0';
+ int buffSize = ARRAY_SIZE(buffer);
+
+ char numBuffer[32];
+
+ int numEntries = 0;
+ unsigned index;
+ for(index = 0; index < ARRAY_SIZE(std_sample_rates); index++) {
+ if (std_sample_rates[index] >= min && std_sample_rates[index] <= max &&
+ test_out_sample_rate(dev_profile, std_sample_rates[index])) {
+ if (numEntries++ != 0) {
+ strncat(buffer, "|", buffSize);
+ }
+ snprintf(numBuffer, sizeof(numBuffer), "%u", std_sample_rates[index]);
+ strncat(buffer, numBuffer, buffSize);
+ }
+ }
+
+ return strdup(buffer);
+}
+
+/*
+ * Logging
+ */
static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
char buff[512];
char bit_buff[32];
@@ -624,15 +723,18 @@
/*
* Reads and decodes configuration info from the specified ALSA card/device
*/
-static int read_alsa_device_config(int card, int device, int io_type, struct pcm_config * config)
+static int read_alsa_device_config(struct audio_device_profile * dev_profile,
+ struct pcm_config * config)
{
- ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",card, device, io_type);
+ ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
+ dev_profile->card, dev_profile->device, dev_profile->direction);
- if (card < 0 || device < 0) {
+ if (dev_profile->card < 0 || dev_profile->device < 0) {
return -EINVAL;
}
- struct pcm_params * alsa_hw_params = pcm_params_get(card, device, io_type);
+ struct pcm_params * alsa_hw_params =
+ pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
if (alsa_hw_params == NULL) {
return -EINVAL;
}
@@ -640,7 +742,9 @@
/*
* This Logging will be useful when testing new USB devices.
*/
- /* log_pcm_params(alsa_hw_params); */
+#ifdef LOG_PCM_PARAMS
+ log_pcm_params(alsa_hw_params);
+#endif
config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
@@ -655,6 +759,9 @@
config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
+
+ pcm_params_free(alsa_hw_params);
+
return 0;
}
@@ -679,7 +786,8 @@
static size_t out_get_buffer_size(const struct audio_stream *stream)
{
- return cached_output_hardware_config.period_size * audio_stream_frame_size(stream);
+ return cached_output_hardware_config.period_size *
+ audio_stream_out_frame_size((const struct audio_stream_out *)stream);
}
static uint32_t out_get_channels(const struct audio_stream *stream)
@@ -730,7 +838,6 @@
ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
struct str_parms *parms;
char value[32];
int param_val;
@@ -738,45 +845,41 @@
int ret_value = 0;
parms = str_parms_create_str(kvpairs);
- pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&out->dev->lock);
+ pthread_mutex_lock(&out->lock);
bool recache_device_params = false;
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
if (param_val >= 0) {
- adev->out_card = atoi(value);
+ out->profile->card = atoi(value);
recache_device_params = true;
}
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
if (param_val >= 0) {
- adev->out_device = atoi(value);
+ out->profile->device = atoi(value);
recache_device_params = true;
}
- if (recache_device_params && adev->out_card >= 0 && adev->out_device >= 0) {
- ret_value = read_alsa_device_config(adev->out_card, adev->out_device, PCM_OUT,
- &cached_output_hardware_config);
+ if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
+ ret_value = read_alsa_device_config(out->profile, &cached_output_hardware_config);
output_hardware_config_is_cached = (ret_value == 0);
}
- pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ pthread_mutex_unlock(&out->dev->lock);
str_parms_destroy(parms);
return ret_value;
}
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
- could be written in terms of a get_device_parameters(io_type) */
-
-static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+static char * device_get_parameters(struct audio_device_profile * dev_profile, const char *keys)
{
- ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+ ALOGV("usb:audio_hw::device_get_parameters() keys:%s", keys);
- struct stream_out *out = (struct stream_out *) stream;
- struct audio_device *adev = out->dev;
-
- if (adev->out_card < 0 || adev->out_device < 0)
+ if (dev_profile->card < 0 || dev_profile->device < 0) {
return strdup("");
+ }
unsigned min, max;
@@ -788,58 +891,74 @@
int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
char* result_str = NULL;
- struct pcm_params * alsa_hw_params = pcm_params_get(adev->out_card, adev->out_device, PCM_OUT);
+ struct pcm_params * alsa_hw_params =
+ pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
// These keys are from hardware/libhardware/include/audio.h
// supported sample rates
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
- // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
- // if they are different, return a list containing those two values, otherwise just the one.
min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
- buffer);
+
+ char* rates_list = enum_std_sample_rates(dev_profile, min, max);
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, rates_list);
+ free(rates_list);
} // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
// supported channel counts
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
- // Similarly for output channels count
- /* TODO - This is wrong, we need format strings, not numbers (another CL) */
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, buffer);
+ // TODO remove this hack when it is superceeded by proper multi-channel support
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
+ dev_profile->direction == PCM_OUT
+ ? "AUDIO_CHANNEL_OUT_STEREO"
+ : "AUDIO_CHANNEL_IN_STEREO");
} // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
// supported sample formats
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
- char * format_params =
- get_format_str_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
- free(format_params);
+ // TODO remove this hack when we have support for input in non PCM16 formats
+ if (dev_profile->direction == PCM_IN) {
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, "AUDIO_FORMAT_PCM_16_BIT");
+ } else {
+ struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
+ char * format_params = get_format_str_for_mask(format_mask);
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
+ free(format_params);
+ }
} // AUDIO_PARAMETER_STREAM_SUP_FORMATS
+ pcm_params_free(alsa_hw_params);
+
result_str = str_parms_to_str(result);
// done with these...
str_parms_destroy(query);
str_parms_destroy(result);
- ALOGV("usb:audio_hw::out out_get_parameters() = %s", result_str);
+ ALOGV("usb:audio_hw::device_get_parameters = %s", result_str);
return result_str;
}
+static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+{
+ ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+
+ struct stream_out *out = (struct stream_out *) stream;
+ pthread_mutex_lock(&out->dev->lock);
+ pthread_mutex_lock(&out->lock);
+
+ char * params_str = device_get_parameters(out->profile, keys);
+
+ pthread_mutex_unlock(&out->lock);
+ pthread_mutex_unlock(&out->dev->lock);
+
+ return params_str;
+}
+
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
- struct stream_out *out = (struct stream_out *) stream;
+ // struct stream_out *out = (struct stream_out *) stream;
/*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
uint32_t latency = (cached_output_hardware_config.period_size
@@ -856,13 +975,13 @@
/* must be called with hw device and output stream mutexes locked */
static int start_output_stream(struct stream_out *out)
{
- struct audio_device *adev = out->dev;
int return_val = 0;
ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
- adev->out_card, adev->out_device);
+ out->profile->card, out->profile->device);
- out->pcm = pcm_open(adev->out_card, adev->out_device, PCM_OUT, &cached_output_hardware_config);
+ out->pcm = pcm_open(out->profile->card, out->profile->device, PCM_OUT,
+ &cached_output_hardware_config);
if (out->pcm == NULL) {
return -ENOMEM;
@@ -933,7 +1052,7 @@
pthread_mutex_unlock(&out->lock);
pthread_mutex_unlock(&out->dev->lock);
if (ret != 0) {
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
out_get_sample_rate(&stream->common));
}
@@ -999,6 +1118,9 @@
out->dev = adev;
+ out->profile = &(adev->out_profile);
+ out->profile->direction = PCM_OUT;
+
if (output_hardware_config_is_cached) {
config->sample_rate = cached_output_hardware_config.rate;
@@ -1109,9 +1231,10 @@
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
- ALOGV("usb: in_get_buffer_size() = %zu",
- cached_input_hardware_config.period_size * audio_stream_frame_size(stream));
- return cached_input_hardware_config.period_size * audio_stream_frame_size(stream);
+ size_t buffer_size = cached_input_hardware_config.period_size *
+ audio_stream_in_frame_size((const struct audio_stream_in *)stream);
+ ALOGV("usb: in_get_buffer_size() = %zu", buffer_size);
+ return buffer_size;
}
static uint32_t in_get_channels(const struct audio_stream *stream)
@@ -1122,7 +1245,12 @@
static audio_format_t in_get_format(const struct audio_stream *stream)
{
- return audio_format_from_pcm_format(cached_input_hardware_config.format);
+ const struct stream_in * in_stream = (const struct stream_in *)stream;
+
+ ALOGV("in_get_format() = %d -> %d", in_stream->input_framework_format,
+ audio_format_from_pcm_format(in_stream->input_framework_format));
+ /* return audio_format_from_pcm_format(cached_input_hardware_config.format); */
+ return audio_format_from_pcm_format(in_stream->input_framework_format);
}
static int in_set_format(struct audio_stream *stream, audio_format_t format)
@@ -1159,7 +1287,6 @@
ALOGV("usb: audio_hw::in in_set_parameters() keys:%s", kvpairs);
struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
struct str_parms *parms;
char value[32];
int param_val;
@@ -1167,108 +1294,49 @@
int ret_value = 0;
parms = str_parms_create_str(kvpairs);
- pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&in->dev->lock);
+ pthread_mutex_lock(&in->lock);
bool recache_device_params = false;
// Card/Device
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
if (param_val >= 0) {
- adev->in_card = atoi(value);
+ in->profile->card = atoi(value);
recache_device_params = true;
}
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
if (param_val >= 0) {
- adev->in_device = atoi(value);
+ in->profile->device = atoi(value);
recache_device_params = true;
}
- if (recache_device_params && adev->in_card >= 0 && adev->in_device >= 0) {
- ret_value = read_alsa_device_config(adev->in_card, adev->in_device,
- PCM_IN, &(cached_input_hardware_config));
+ if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
+ ret_value = read_alsa_device_config(in->profile, &cached_input_hardware_config);
input_hardware_config_is_cached = (ret_value == 0);
}
- pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&in->dev->lock);
str_parms_destroy(parms);
return ret_value;
}
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
- could be written in terms of a get_device_parameters(io_type) */
-
static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
+ pthread_mutex_lock(&in->dev->lock);
+ pthread_mutex_lock(&in->lock);
- if (adev->in_card < 0 || adev->in_device < 0)
- return strdup("");
+ char * params_str = device_get_parameters(in->profile, keys);
- struct pcm_params * alsa_hw_params = pcm_params_get(adev->in_card, adev->in_device, PCM_IN);
- if (alsa_hw_params == NULL)
- return strdup("");
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&in->dev->lock);
- struct str_parms *query = str_parms_create_str(keys);
- struct str_parms *result = str_parms_create();
-
- int num_written = 0;
- char buffer[256];
- int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
- char* result_str = NULL;
-
- unsigned min, max;
-
- // These keys are from hardware/libhardware/include/audio.h
- // supported sample rates
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
- // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
- // if they are different, return a list containing those two values, otherwise just the one.
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, buffer);
- } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
-
- // supported channel counts
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
- // Similarly for output channels count
- // TODO This is wrong, we need format strings, not numbers (another CL)
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_CHANNELS, buffer);
- } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
-
- // supported sample formats
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
- /*TODO This is wrong. It needs to return AUDIO_ format constants (as strings)
- as in audio_policy.conf */
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
- } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
-
- result_str = str_parms_to_str(result);
-
- // done with these...
- str_parms_destroy(query);
- str_parms_destroy(result);
-
- return result_str;
+ return params_str;
}
static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
@@ -1288,13 +1356,13 @@
/* must be called with hw device and output stream mutexes locked */
static int start_input_stream(struct stream_in *in) {
- struct audio_device *adev = in->dev;
int return_val = 0;
ALOGV("usb:audio_hw::start_input_stream(card:%d device:%d)",
- adev->in_card, adev->in_device);
+ in->profile->card, in->profile->device);
- in->pcm = pcm_open(adev->in_card, adev->in_device, PCM_IN, &cached_input_hardware_config);
+ in->pcm = pcm_open(in->profile->card, in->profile->device, PCM_IN,
+ &cached_input_hardware_config);
if (in->pcm == NULL) {
ALOGE("usb:audio_hw pcm_open() in->pcm == NULL");
return -ENOMEM;
@@ -1338,8 +1406,13 @@
num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
}
+ /* Assume (for now) that in->input_framework_format == PCM_FORMAT_S16_LE */
if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+ /* 24-bit USB device */
num_read_buff_bytes = (3 * num_read_buff_bytes) / 2;
+ } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
+ /* 32-bit USB device */
+ num_read_buff_bytes = num_read_buff_bytes * 2;
}
// Setup/Realloc the conversion buffer (if necessary).
@@ -1358,14 +1431,22 @@
* Do any conversions necessary to send the data in the format specified to/by the HAL
* (but different from the ALSA format), such as 24bit ->16bit, or 4chan -> 2chan.
*/
- if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+ if (cached_input_hardware_config.format != PCM_FORMAT_S16_LE) {
+ // we need to convert
if (num_device_channels != num_req_channels) {
out_buff = read_buff;
}
- /* Bit Format Conversion */
- num_read_buff_bytes =
- convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
+ if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
+ num_read_buff_bytes =
+ convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
+ } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
+ num_read_buff_bytes =
+ convert_32_to_16(read_buff, num_read_buff_bytes / 4, out_buff);
+ }
+ else {
+ goto err;
+ }
}
if (num_device_channels != num_req_channels) {
@@ -1430,36 +1511,53 @@
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
+ in->input_framework_format = PCM_FORMAT_S16_LE;
+
in->dev = (struct audio_device *)dev;
- if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO)
- ret = -EINVAL;
+ in->profile = &(in->dev->in_profile);
+ in->profile->direction = PCM_IN;
- if (input_hardware_config_is_cached) {
- config->sample_rate = cached_input_hardware_config.rate;
-
- config->format = audio_format_from_pcm_format(cached_input_hardware_config.format);
- if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
- // Always report PCM16 for now. AudioPolicyManagerBase/AudioFlinger dont' understand
- // formats with more other format, so we won't get chosen (say with a 24bit DAC).
- /* TODO Remove this when the above restriction is removed. */
- config->format = AUDIO_FORMAT_PCM_16_BIT;
- }
-
- config->channel_mask = audio_channel_in_mask_from_count(
- cached_input_hardware_config.channels);
- if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
- // Always report STEREO for now. AudioPolicyManagerBase/AudioFlinger dont' understand
- // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
- /* TODO Remove this when the above restriction is removed. */
- config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
- }
- } else {
+ if (!input_hardware_config_is_cached) {
+ // just return defaults until we can actually query the device.
cached_input_hardware_config = default_alsa_in_config;
+ }
- config->format = in_get_format(&in->stream.common);
- config->channel_mask = in_get_channels(&in->stream.common);
- config->sample_rate = in_get_sample_rate(&in->stream.common);
+ /* Rate */
+ /* TODO Check that the requested rate is valid for the connected device */
+ if (config->sample_rate == 0) {
+ config->sample_rate = cached_input_hardware_config.rate;
+ } else {
+ cached_input_hardware_config.rate = config->sample_rate;
+ }
+
+ /* Format */
+ /* until the framework supports format conversion, just take what it asks for
+ * i.e. AUDIO_FORMAT_PCM_16_BIT */
+ /* config->format = audio_format_from_pcm_format(cached_input_hardware_config.format); */
+ if (config->format == AUDIO_FORMAT_DEFAULT) {
+ /* just return AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
+ * formats */
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ } else if (config->format == AUDIO_FORMAT_PCM_16_BIT) {
+ /* Always accept AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
+ * formats */
+ } else {
+ /* When the framework support other formats, validate here */
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ ret = -EINVAL;
+ }
+
+ /* don't change the cached_input_hardware_config, we will open it as what it is and
+ * convert as necessary */
+ if (config->channel_mask == AUDIO_CHANNEL_NONE) {
+ /* just return AUDIO_CHANNEL_IN_STEREO until the framework supports other input
+ * formats */
+ config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+ } else if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
+ /* allow only stereo capture for now */
+ config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+ ret = -EINVAL;
}
in->standby = true;