summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:48:15 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:48:15 +0000
commit7b65b4bfe2b72e5b873065e0e399375d2e31a530 (patch)
treeb69723eebf023f54d0e71be94f0d74a98cbcf77e
parente820815d1e20a4bb877a23b3fac11b0735d110e4 (diff)
parent07c80fdaa0340d60e5be2ceff31037712859412b (diff)
downloadlibhardware-android12-mainline-tzdata3-release.tar.gz
Change-Id: I1b36d8124dd00566a7175f4d6a33da350556bb70
-rw-r--r--Android.bp5
-rw-r--r--OWNERS1
-rw-r--r--include/hardware/audio.h83
-rw-r--r--include/hardware/bluetooth.h1
-rw-r--r--include/hardware/keymaster_defs.h1
-rw-r--r--include/hardware/sensors-base.h6
-rw-r--r--include/hardware/sensors.h96
-rw-r--r--modules/audio_remote_submix/OWNERS3
-rw-r--r--modules/audio_remote_submix/audio_hw.cpp239
-rw-r--r--modules/gralloc/Android.mk3
-rw-r--r--modules/gralloc/framebuffer.cpp7
-rw-r--r--modules/sensors/dynamic_sensor/Android.bp18
-rw-r--r--modules/sensors/dynamic_sensor/BaseSensorObject.cpp1
-rw-r--r--modules/sensors/dynamic_sensor/ConnectionDetector.cpp22
-rw-r--r--modules/sensors/dynamic_sensor/ConnectionDetector.h3
-rw-r--r--modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp4
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.cpp105
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.h33
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp239
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h89
-rw-r--r--modules/sensors/dynamic_sensor/HidRawSensor.cpp314
-rw-r--r--modules/sensors/dynamic_sensor/HidRawSensor.h60
-rw-r--r--modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp1
-rw-r--r--modules/sensors/dynamic_sensor/HidSensorDef.h30
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/Android.bp18
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp16
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/HidParser.h2
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp72
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/HidUtils.h29
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp73
-rw-r--r--modules/sensors/dynamic_sensor/README.md153
-rw-r--r--modules/usbaudio/audio_hal.c47
32 files changed, 365 insertions, 1409 deletions
diff --git a/Android.bp b/Android.bp
index 92c77faa..ebdd2544 100644
--- a/Android.bp
+++ b/Android.bp
@@ -58,11 +58,6 @@ cc_library_headers {
],
},
},
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth",
- "com.android.media.swcodec",
- ],
min_sdk_version: "29",
host_supported: true,
diff --git a/OWNERS b/OWNERS
index 53e5f73f..b6b18dac 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,4 +5,3 @@ malchev@google.com
smoreland@google.com
swillden@google.com
per-file include/hardware/camera*=etalvala@google.com
-per-file include/hardware/sensors*=bduddie@google.com
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index daaa16f1..adec3da8 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -247,10 +247,6 @@ typedef struct sink_metadata_v7 {
struct record_track_metadata_v7* tracks;
} sink_metadata_v7_t;
-/** output stream callback method to indicate changes in supported latency modes */
-typedef void (*stream_latency_mode_callback_t)(
- audio_latency_mode_t *modes, size_t num_modes, void *cookie);
-
/**
* audio_stream_out is the abstraction interface for the audio output hardware.
*
@@ -537,68 +533,7 @@ struct audio_stream_out {
*/
int (*set_playback_rate_parameters)(struct audio_stream_out *stream,
const audio_playback_rate_t *playbackRate);
-
- /**
- * Indicates the requested latency mode for this output stream.
- *
- * The requested mode can be one of the modes returned by
- * get_recommended_latency_modes().
- *
- * Support for this method is optional but mandated on specific spatial audio
- * streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed
- * to a BT classic sink.
- *
- * \param[in] stream the stream object.
- * \param[in] mode the requested latency mode.
- * \return 0 in case of success.
- * -EINVAL if the arguments are invalid
- * -ENOSYS if the function is not available
- */
- int (*set_latency_mode)(struct audio_stream_out *stream, audio_latency_mode_t mode);
-
- /**
- * Indicates which latency modes are currently supported on this output stream.
- * If the transport protocol (e.g Bluetooth A2DP) used by this output stream to reach
- * the output device supports variable latency modes, the HAL indicates which
- * modes are currently supported.
- * The framework can then call setLatencyMode() with one of the supported modes to select
- * the desired operation mode.
- *
- * Support for this method is optional but mandated on specific spatial audio
- * streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed
- * to a BT classic sink.
- *
- * \return 0 in case of success.
- * -EINVAL if the arguments are invalid
- * -ENOSYS if the function is not available
- * \param[in] stream the stream object.
- * \param[out] modes the supported latency modes.
- * \param[in/out] num_modes as input the maximum number of modes to return,
- * as output the actual number of modes returned.
- */
- int (*get_recommended_latency_modes)(struct audio_stream_out *stream,
- audio_latency_mode_t *modes, size_t *num_modes);
-
- /**
- * Set the callback interface for notifying changes in supported latency modes.
- *
- * Calling this method with a null pointer will result in clearing a previously set callback.
- *
- * Support for this method is optional but mandated on specific spatial audio
- * streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can be routed
- * to a BT classic sink.
- *
- * \param[in] stream the stream object.
- * \param[in] callback the registered callback or null to unregister.
- * \param[in] cookie the context to pass when calling the callback.
- * \return 0 in case of success.
- * -EINVAL if the arguments are invalid
- * -ENOSYS if the function is not available
- */
- int (*set_latency_mode_callback)(struct audio_stream_out *stream,
- stream_latency_mode_callback_t callback, void *cookie);
};
-
typedef struct audio_stream_out audio_stream_out_t;
struct audio_stream_in {
@@ -1047,24 +982,6 @@ struct audio_hw_device {
*/
int (*get_audio_port_v7)(struct audio_hw_device *dev,
struct audio_port_v7 *port);
-
- /**
- * Called when the state of the connection of an external device has been changed.
- * The "port" parameter is only used as input and besides identifying the device
- * port, also may contain additional information such as extra audio descriptors.
- *
- * HAL version 3.2 and higher only. If the HAL does not implement this method,
- * it must leave the function entry as null, or return -ENOSYS. In this case
- * the framework will use 'set_parameters', which can only pass the device address.
- *
- * @param dev the audio HAL device context.
- * @param port device port identification and extra information.
- * @param connected whether the external device is connected.
- * @return retval operation completion status.
- */
- int (*set_device_connected_state_v7)(struct audio_hw_device *dev,
- struct audio_port_v7 *port,
- bool connected);
};
typedef struct audio_hw_device audio_hw_device_t;
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 95a0b6e3..afa0eef7 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -261,7 +261,6 @@ typedef struct
/** Represents the actual Out of Band data itself */
typedef struct {
// Both
- bool is_valid = false; /* Default to invalid data; force caller to verify */
uint8_t address[7]; /* Bluetooth Device Address (6) plus Address Type (1) */
uint8_t c[16]; /* Simple Pairing Hash C-192/256 (Classic or LE) */
uint8_t r[16]; /* Simple Pairing Randomizer R-192/256 (Classic or LE) */
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index 930aceb0..c0b3800e 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -304,7 +304,6 @@ typedef enum {
KM_EC_CURVE_P_256 = 1,
KM_EC_CURVE_P_384 = 2,
KM_EC_CURVE_P_521 = 3,
- KM_EC_CURVE_CURVE_25519 = 4,
} keymaster_ec_curve_t;
/**
diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h
index dbf99f57..ef7eead4 100644
--- a/include/hardware/sensors-base.h
+++ b/include/hardware/sensors-base.h
@@ -52,12 +52,6 @@ enum {
SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT = 34,
SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 35,
SENSOR_TYPE_HINGE_ANGLE = 36,
- SENSOR_TYPE_HEAD_TRACKER = 37,
- SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES = 38,
- SENSOR_TYPE_GYROSCOPE_LIMITED_AXES = 39,
- SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40,
- SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41,
- SENSOR_TYPE_HEADING = 42,
SENSOR_TYPE_DEVICE_PRIVATE_BASE = 65536 /* 0x10000 */,
};
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index 6f4baf8f..a03a4095 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -186,12 +186,6 @@ enum {
#define SENSOR_STRING_TYPE_LOW_LATENCY_OFFBODY_DETECT "android.sensor.low_latency_offbody_detect"
#define SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED "android.sensor.accelerometer_uncalibrated"
#define SENSOR_STRING_TYPE_HINGE_ANGLE "android.sensor.hinge_angle"
-#define SENSOR_STRING_TYPE_HEAD_TRACKER "android.sensor.head_tracker"
-#define SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES "android.sensor.accelerometer_limited_axes"
-#define SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES "android.sensor.gyroscope_limited_axes"
-#define SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED "android.sensor.accelerometer_limited_axes_uncalibrated"
-#define SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED "android.sensor.gyroscope_limited_axes_uncalibrated"
-#define SENSOR_STRING_TYPE_HEADING "android.sensor.heading"
/**
* Values returned by the accelerometer in various locations in the universe.
@@ -297,76 +291,6 @@ typedef struct {
};
} additional_info_event_t;
-typedef struct {
- float rx;
- float ry;
- float rz;
- float vx;
- float vy;
- float vz;
- int32_t discontinuity_count;
-} head_tracker_event_t;
-
-/**
- * limited axes imu event data
- */
-typedef struct {
- union {
- float calib[3];
- struct {
- float x;
- float y;
- float z;
- };
- };
- union {
- float supported[3];
- struct {
- float x_supported;
- float y_supported;
- float z_supported;
- };
- };
-} limited_axes_imu_event_t;
-
-/**
- * limited axes uncalibrated imu event data
- */
-typedef struct {
- union {
- float uncalib[3];
- struct {
- float x_uncalib;
- float y_uncalib;
- float z_uncalib;
- };
- };
- union {
- float bias[3];
- struct {
- float x_bias;
- float y_bias;
- float z_bias;
- };
- };
- union {
- float supported[3];
- struct {
- float x_supported;
- float y_supported;
- float z_supported;
- };
- };
-} limited_axes_imu_uncalibrated_event_t;
-
-/**
- * Heading event data
- */
-typedef struct {
- float heading;
- float accuracy;
-} heading_event_t;
-
/**
* Union of the various types of sensor data
* that can be returned.
@@ -444,26 +368,6 @@ typedef struct sensors_event_t {
* SENSOR_TYPE_ADDITIONAL_INFO for details.
*/
additional_info_event_t additional_info;
-
- /* vector describing head orientation (added for legacy code support only) */
- head_tracker_event_t head_tracker;
-
- /*
- * limited axes imu event, See
- * SENSOR_TYPE_GYROSCOPE_LIMITED_AXES and
- * SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES for details.
- */
- limited_axes_imu_event_t limited_axes_imu;
-
- /*
- * limited axes imu uncalibrated event, See
- * SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED and
- * SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED for details.
- */
- limited_axes_imu_uncalibrated_event_t limited_axes_imu_uncalibrated;
-
- /* heading data containing value in degrees and its accuracy */
- heading_event_t heading;
};
union {
diff --git a/modules/audio_remote_submix/OWNERS b/modules/audio_remote_submix/OWNERS
deleted file mode 100644
index 67da0f90..00000000
--- a/modules/audio_remote_submix/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
-jmtrivi@google.com
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index f96854b5..b43a44dc 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -63,7 +63,7 @@ namespace android {
#endif // SUBMIX_VERBOSE_LOGGING
// NOTE: This value will be rounded up to the nearest power of 2 by MonoPipe().
-#define DEFAULT_PIPE_SIZE_IN_FRAMES (1024*4) // size at default sample rate
+#define DEFAULT_PIPE_SIZE_IN_FRAMES (1024*4)
// Value used to divide the MonoPipe() buffer into segments that are written to the source and
// read from the sink. The maximum latency of the device is the size of the MonoPipe's buffer
// the minimum latency is the MonoPipe buffer size divided by this value.
@@ -83,7 +83,10 @@ namespace android {
// multiple input streams from this device. If this option is enabled, each input stream returned
// is *the same stream* which means that readers will race to read data from these streams.
#define ENABLE_LEGACY_INPUT_OPEN 1
-
+// Whether channel conversion (16-bit signed PCM mono->stereo, stereo->mono) is enabled.
+#define ENABLE_CHANNEL_CONVERSION 1
+// Whether resampling is enabled.
+#define ENABLE_RESAMPLING 1
#if LOG_STREAMS_TO_FILES
// Folder to save stream log files to.
#define LOG_STREAM_FOLDER "/data/misc/audioserver"
@@ -127,6 +130,11 @@ struct submix_config {
// channel bitfields are not equivalent.
audio_channel_mask_t input_channel_mask;
audio_channel_mask_t output_channel_mask;
+#if ENABLE_RESAMPLING
+ // Input stream and output stream sample rates.
+ uint32_t input_sample_rate;
+ uint32_t output_sample_rate;
+#endif // ENABLE_RESAMPLING
size_t pipe_frame_size; // Number of bytes in each audio frame in the pipe.
size_t buffer_size_frames; // Size of the audio pipe in frames.
// Maximum number of frames buffered by the input and output streams.
@@ -151,6 +159,11 @@ typedef struct route_config {
// destroyed if both and input and output streams are destroyed.
struct submix_stream_out *output;
struct submix_stream_in *input;
+#if ENABLE_RESAMPLING
+ // Buffer used as temporary storage for resampled data prior to returning data to the output
+ // stream.
+ int16_t resampler_buffer[DEFAULT_PIPE_SIZE_IN_FRAMES];
+#endif // ENABLE_RESAMPLING
} route_config_t;
struct submix_audio_device {
@@ -208,11 +221,6 @@ static bool sample_rate_supported(const uint32_t sample_rate)
return return_value;
}
-static size_t pipe_size_in_frames(const uint32_t sample_rate)
-{
- return DEFAULT_PIPE_SIZE_IN_FRAMES * ((float) sample_rate / DEFAULT_SAMPLE_RATE_HZ);
-}
-
// Determine whether the specified sample rate is supported, if it is return the specified sample
// rate, otherwise return the default sample rate for the submix module.
static uint32_t get_supported_sample_rate(uint32_t sample_rate)
@@ -317,6 +325,7 @@ static struct submix_audio_device * audio_hw_device_get_submix_audio_device(
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 = 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) {
@@ -324,8 +333,13 @@ static bool audio_config_compare(const audio_config * const input_config,
input_channels, output_channels);
return false;
}
-
+#endif // !ENABLE_CHANNEL_CONVERSION
+#if ENABLE_RESAMPLING
+ if (input_config->sample_rate != output_config->sample_rate &&
+ audio_channel_count_from_in_mask(input_config->channel_mask) != 1) {
+#else
if (input_config->sample_rate != output_config->sample_rate) {
+#endif // ENABLE_RESAMPLING
ALOGE("audio_config_compare() sample rate mismatch %ul vs. %ul",
input_config->sample_rate, output_config->sample_rate);
return false;
@@ -362,11 +376,24 @@ static void submix_audio_device_create_pipe_l(struct submix_audio_device * const
in->route_handle = route_idx;
rsxadev->routes[route_idx].input = in;
rsxadev->routes[route_idx].config.input_channel_mask = config->channel_mask;
+#if ENABLE_RESAMPLING
+ rsxadev->routes[route_idx].config.input_sample_rate = config->sample_rate;
+ // If the output isn't configured yet, set the output sample rate to the maximum supported
+ // sample rate such that the smallest possible input buffer is created, and put a default
+ // value for channel count
+ if (!rsxadev->routes[route_idx].output) {
+ rsxadev->routes[route_idx].config.output_sample_rate = 48000;
+ rsxadev->routes[route_idx].config.output_channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ }
+#endif // ENABLE_RESAMPLING
}
if (out) {
out->route_handle = route_idx;
rsxadev->routes[route_idx].output = out;
rsxadev->routes[route_idx].config.output_channel_mask = config->channel_mask;
+#if ENABLE_RESAMPLING
+ rsxadev->routes[route_idx].config.output_sample_rate = config->sample_rate;
+#endif // ENABLE_RESAMPLING
}
// Save the address
strncpy(rsxadev->routes[route_idx].address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
@@ -376,14 +403,18 @@ static void submix_audio_device_create_pipe_l(struct submix_audio_device * const
{
struct submix_config * const device_config = &rsxadev->routes[route_idx].config;
uint32_t channel_count;
- if (out) {
+ if (out)
channel_count = audio_channel_count_from_out_mask(config->channel_mask);
- } else {
+ 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
+ // the output stream don't match the number in the input stream.
+ const uint32_t pipe_channel_count = max(channel_count, 2);
+#else
const uint32_t pipe_channel_count = channel_count;
-
+#endif // ENABLE_CHANNEL_CONVERSION
const NBAIO_Format format = Format_from_SR_C(config->sample_rate, pipe_channel_count,
config->format);
const NBAIO_Format offers[1] = {format};
@@ -413,7 +444,11 @@ static void submix_audio_device_create_pipe_l(struct submix_audio_device * const
buffer_period_count;
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) /
+ channel_count;
+#endif // ENABLE_CHANNEL_CONVERSION
SUBMIX_ALOGV("submix_audio_device_create_pipe_l(): pipe frame size %zd, pipe size %zd, "
"period size %zd", device_config->pipe_frame_size,
device_config->buffer_size_frames, device_config->buffer_period_size_frames);
@@ -438,6 +473,10 @@ static void submix_audio_device_release_pipe_l(struct submix_audio_device * cons
rsxadev->routes[route_idx].rsxSource.clear();
}
memset(rsxadev->routes[route_idx].address, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+#if ENABLE_RESAMPLING
+ memset(rsxadev->routes[route_idx].resampler_buffer, 0,
+ sizeof(int16_t) * DEFAULT_PIPE_SIZE_IN_FRAMES);
+#endif
}
// Remove references to the specified input and output streams. When the device no longer
@@ -585,7 +624,11 @@ static uint32_t out_get_sample_rate(const struct audio_stream *stream)
{
const struct submix_stream_out * const out = audio_stream_get_submix_stream_out(
const_cast<struct audio_stream *>(stream));
+#if ENABLE_RESAMPLING
+ const uint32_t out_rate = out->dev->routes[out->route_handle].config.output_sample_rate;
+#else
const uint32_t out_rate = out->dev->routes[out->route_handle].config.common.sample_rate;
+#endif // ENABLE_RESAMPLING
SUBMIX_ALOGV("out_get_sample_rate() returns %u for addr %s",
out_rate, out->dev->routes[out->route_handle].address);
return out_rate;
@@ -594,6 +637,17 @@ static uint32_t out_get_sample_rate(const struct audio_stream *stream)
static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
struct submix_stream_out * const out = audio_stream_get_submix_stream_out(stream);
+#if ENABLE_RESAMPLING
+ // 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->routes[out->route_handle].config.output_sample_rate) {
+ ALOGE("out_set_sample_rate() resampling enabled can't change sample rate from "
+ "%u to %u for addr %s",
+ out->dev->routes[out->route_handle].config.output_sample_rate, rate,
+ out->dev->routes[out->route_handle].address);
+ return -ENOSYS;
+ }
+#endif // ENABLE_RESAMPLING
if (!sample_rate_supported(rate)) {
ALOGE("out_set_sample_rate(rate=%u) rate unsupported", rate);
return -ENOSYS;
@@ -940,7 +994,11 @@ static uint32_t in_get_sample_rate(const struct audio_stream *stream)
{
const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(
const_cast<struct audio_stream*>(stream));
+#if ENABLE_RESAMPLING
+ const uint32_t rate = in->dev->routes[in->route_handle].config.input_sample_rate;
+#else
const uint32_t rate = in->dev->routes[in->route_handle].config.common.sample_rate;
+#endif // ENABLE_RESAMPLING
SUBMIX_ALOGV("in_get_sample_rate() returns %u", rate);
return rate;
}
@@ -948,6 +1006,15 @@ static uint32_t in_get_sample_rate(const struct audio_stream *stream)
static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
const struct submix_stream_in * const in = audio_stream_get_submix_stream_in(stream);
+#if ENABLE_RESAMPLING
+ // 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->routes[in->route_handle].config.input_sample_rate) {
+ ALOGE("in_set_sample_rate() resampling enabled can't change sample rate from "
+ "%u to %u", in->dev->routes[in->route_handle].config.input_sample_rate, rate);
+ return -ENOSYS;
+ }
+#endif // ENABLE_RESAMPLING
if (!sample_rate_supported(rate)) {
ALOGE("in_set_sample_rate(rate=%u) rate unsupported", rate);
return -ENOSYS;
@@ -966,6 +1033,13 @@ static size_t in_get_buffer_size(const struct audio_stream *stream)
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_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.
+ buffer_size_frames = (size_t)(((float)buffer_size_frames *
+ (float)config->input_sample_rate) /
+ (float)config->output_sample_rate);
+#endif // ENABLE_RESAMPLING
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);
@@ -1094,10 +1168,65 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
// read the data from the pipe (it's non blocking)
int attempts = 0;
char* buff = (char*)buffer;
+#if ENABLE_CHANNEL_CONVERSION
+ // Determine whether channel conversion is required.
+ const uint32_t input_channels = audio_channel_count_from_in_mask(
+ rsxadev->routes[in->route_handle].config.input_channel_mask);
+ const uint32_t output_channels = audio_channel_count_from_out_mask(
+ rsxadev->routes[in->route_handle].config.output_channel_mask);
+ if (input_channels != output_channels) {
+ SUBMIX_ALOGV("in_read(): %d output channels will be converted to %d "
+ "input channels", output_channels, input_channels);
+ // Only support 16-bit PCM channel conversion from mono to stereo or stereo to mono.
+ ALOG_ASSERT(rsxadev->routes[in->route_handle].config.common.format ==
+ AUDIO_FORMAT_PCM_16_BIT);
+ ALOG_ASSERT((input_channels == 1 && output_channels == 2) ||
+ (input_channels == 2 && output_channels == 1));
+ }
+#endif // ENABLE_CHANNEL_CONVERSION
+
+#if ENABLE_RESAMPLING
+ const uint32_t input_sample_rate = in_get_sample_rate(&stream->common);
+ const uint32_t output_sample_rate =
+ rsxadev->routes[in->route_handle].config.output_sample_rate;
+ const size_t resampler_buffer_size_frames =
+ sizeof(rsxadev->routes[in->route_handle].resampler_buffer) /
+ sizeof(rsxadev->routes[in->route_handle].resampler_buffer[0]);
+ float resampler_ratio = 1.0f;
+ // Determine whether resampling is required.
+ if (input_sample_rate != output_sample_rate) {
+ resampler_ratio = (float)output_sample_rate / (float)input_sample_rate;
+ // Only support 16-bit PCM mono resampling.
+ // NOTE: Resampling is performed after the channel conversion step.
+ ALOG_ASSERT(rsxadev->routes[in->route_handle].config.common.format ==
+ AUDIO_FORMAT_PCM_16_BIT);
+ ALOG_ASSERT(audio_channel_count_from_in_mask(
+ rsxadev->routes[in->route_handle].config.input_channel_mask) == 1);
+ }
+#endif // ENABLE_RESAMPLING
while ((remaining_frames > 0) && (attempts < MAX_READ_ATTEMPTS)) {
ssize_t frames_read = -1977;
size_t read_frames = remaining_frames;
+#if ENABLE_RESAMPLING
+ char* const saved_buff = buff;
+ if (resampler_ratio != 1.0f) {
+ // Calculate the number of frames from the pipe that need to be read to generate
+ // the data for the input stream read.
+ const size_t frames_required_for_resampler = (size_t)(
+ (float)read_frames * (float)resampler_ratio);
+ read_frames = min(frames_required_for_resampler, resampler_buffer_size_frames);
+ // Read into the resampler buffer.
+ buff = (char*)rsxadev->routes[in->route_handle].resampler_buffer;
+ }
+#endif // ENABLE_RESAMPLING
+#if ENABLE_CHANNEL_CONVERSION
+ if (output_channels == 1 && input_channels == 2) {
+ // Need to read half the requested frames since the converted output
+ // data will take twice the space (mono->stereo).
+ read_frames /= 2;
+ }
+#endif // ENABLE_CHANNEL_CONVERSION
SUBMIX_ALOGV("in_read(): frames available to read %zd", source->availableToRead());
@@ -1105,6 +1234,56 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
SUBMIX_ALOGV("in_read(): frames read %zd", frames_read);
+#if ENABLE_CHANNEL_CONVERSION
+ // Perform in-place channel conversion.
+ // NOTE: In the following "input stream" refers to the data returned by this function
+ // and "output stream" refers to the data read from the pipe.
+ if (input_channels != output_channels && frames_read > 0) {
+ int16_t *data = (int16_t*)buff;
+ if (output_channels == 2 && input_channels == 1) {
+ // Offset into the output stream data in samples.
+ ssize_t output_stream_offset = 0;
+ for (ssize_t input_stream_frame = 0; input_stream_frame < frames_read;
+ input_stream_frame++, output_stream_offset += 2) {
+ // Average the content from both channels.
+ data[input_stream_frame] = ((int32_t)data[output_stream_offset] +
+ (int32_t)data[output_stream_offset + 1]) / 2;
+ }
+ } else if (output_channels == 1 && input_channels == 2) {
+ // Offset into the input stream data in samples.
+ ssize_t input_stream_offset = (frames_read - 1) * 2;
+ for (ssize_t output_stream_frame = frames_read - 1; output_stream_frame >= 0;
+ output_stream_frame--, input_stream_offset -= 2) {
+ const short sample = data[output_stream_frame];
+ data[input_stream_offset] = sample;
+ data[input_stream_offset + 1] = sample;
+ }
+ }
+ }
+#endif // ENABLE_CHANNEL_CONVERSION
+
+#if ENABLE_RESAMPLING
+ if (resampler_ratio != 1.0f) {
+ SUBMIX_ALOGV("in_read(): resampling %zd frames", frames_read);
+ const int16_t * const data = (int16_t*)buff;
+ int16_t * const resampled_buffer = (int16_t*)saved_buff;
+ // Resample with *no* filtering - if the data from the ouptut stream was really
+ // sampled at a different rate this will result in very nasty aliasing.
+ const float output_stream_frames = (float)frames_read;
+ size_t input_stream_frame = 0;
+ for (float output_stream_frame = 0.0f;
+ output_stream_frame < output_stream_frames &&
+ input_stream_frame < remaining_frames;
+ output_stream_frame += resampler_ratio, input_stream_frame++) {
+ resampled_buffer[input_stream_frame] = data[(size_t)output_stream_frame];
+ }
+ ALOG_ASSERT(input_stream_frame <= (ssize_t)resampler_buffer_size_frames);
+ SUBMIX_ALOGV("in_read(): resampler produced %zd frames", input_stream_frame);
+ frames_read = input_stream_frame;
+ buff = saved_buff;
+ }
+#endif // ENABLE_RESAMPLING
+
if (frames_read > 0) {
#if LOG_STREAMS_TO_FILES
if (in->log_fd >= 0) write(in->log_fd, buff, frames_read * frame_size);
@@ -1232,6 +1411,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
struct submix_audio_device * const rsxadev = audio_hw_device_get_submix_audio_device(dev);
ALOGD("adev_open_output_stream(address=%s)", address);
struct submix_stream_out *out;
+ bool force_pipe_creation = false;
(void)handle;
(void)devices;
(void)flags;
@@ -1284,20 +1464,25 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
out->stream.get_presentation_position = out_get_presentation_position;
+#if ENABLE_RESAMPLING
+ // Recreate the pipe with the correct sample rate so that MonoPipe.write() rate limits
+ // writes correctly.
+ force_pipe_creation = rsxadev->routes[route_idx].config.common.sample_rate
+ != config->sample_rate;
+#endif // ENABLE_RESAMPLING
+
// If the sink has been shutdown or pipe recreation is forced (see above), delete the pipe so
// that it's recreated.
if ((rsxadev->routes[route_idx].rsxSink != NULL
- && rsxadev->routes[route_idx].rsxSink->isShutdown())) {
+ && rsxadev->routes[route_idx].rsxSink->isShutdown()) || force_pipe_creation) {
submix_audio_device_release_pipe_l(rsxadev, route_idx);
}
// Store a pointer to the device from the output stream.
out->dev = rsxadev;
// Initialize the pipe.
- const size_t pipeSizeInFrames = pipe_size_in_frames(config->sample_rate);
- ALOGI("adev_open_output_stream(): about to create pipe at index %d, rate %u, pipe size %zu",
- route_idx, config->sample_rate, pipeSizeInFrames);
- submix_audio_device_create_pipe_l(rsxadev, config, pipeSizeInFrames,
+ ALOGV("adev_open_output_stream(): about to create pipe at index %d", route_idx);
+ submix_audio_device_create_pipe_l(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
DEFAULT_PIPE_PERIOD_COUNT, NULL, out, address, route_idx);
#if LOG_STREAMS_TO_FILES
out->log_fd = open(LOG_STREAM_OUT_FILENAME, O_CREAT | O_TRUNC | O_WRONLY,
@@ -1426,8 +1611,7 @@ static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
const size_t frame_size_in_bytes = audio_channel_count_from_in_mask(config->channel_mask) *
audio_bytes_per_sample(config->format);
if (max_buffer_period_size_frames == 0) {
- max_buffer_period_size_frames =
- pipe_size_in_frames(get_supported_sample_rate(config->sample_rate));;
+ max_buffer_period_size_frames = DEFAULT_PIPE_SIZE_IN_FRAMES;
}
const size_t buffer_size = max_buffer_period_size_frames * frame_size_in_bytes;
SUBMIX_ALOGV("adev_get_input_buffer_size() returns %zu bytes, %zu frames",
@@ -1540,10 +1724,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->read_error_count = 0;
// Initialize the pipe.
- const size_t pipeSizeInFrames = pipe_size_in_frames(config->sample_rate);
- ALOGI("adev_open_input_stream(): about to create pipe at index %d, rate %u, pipe size %zu",
- route_idx, config->sample_rate, pipeSizeInFrames);
- submix_audio_device_create_pipe_l(rsxadev, config, pipeSizeInFrames,
+ ALOGV("adev_open_input_stream(): about to create pipe");
+ submix_audio_device_create_pipe_l(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES,
DEFAULT_PIPE_PERIOD_COUNT, in, NULL, address, route_idx);
sp <MonoPipe> sink = rsxadev->routes[route_idx].rsxSink;
@@ -1597,9 +1779,16 @@ static int adev_dump(const audio_hw_device_t *device, int fd)
int n = snprintf(msg, sizeof(msg), "\nReroute submix audio module:\n");
write(fd, &msg, n);
for (int i=0 ; i < MAX_ROUTES ; i++) {
+#if ENABLE_RESAMPLING
+ n = snprintf(msg, sizeof(msg), " route[%d] rate in=%d out=%d, addr=[%s]\n", i,
+ rsxadev->routes[i].config.input_sample_rate,
+ rsxadev->routes[i].config.output_sample_rate,
+ rsxadev->routes[i].address);
+#else
n = snprintf(msg, sizeof(msg), " route[%d], rate=%d addr=[%s]\n", i,
rsxadev->routes[i].config.common.sample_rate,
rsxadev->routes[i].address);
+#endif
write(fd, &msg, n);
}
return 0;
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index 4c4899ea..439c95dd 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -38,8 +38,5 @@ LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
ifeq ($(TARGET_USE_PAN_DISPLAY),true)
LOCAL_CFLAGS += -DUSE_PAN_DISPLAY=1
endif
-ifneq ($(GRALLOC_FRAMEBUFFER_NUM),)
-LOCAL_CFLAGS += -DNUM_BUFFERS=$(GRALLOC_FRAMEBUFFER_NUM)
-endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp
index fc220dbc..b2ec3e44 100644
--- a/modules/gralloc/framebuffer.cpp
+++ b/modules/gralloc/framebuffer.cpp
@@ -45,10 +45,8 @@
#define USE_PAN_DISPLAY 0
#endif
-// Enabling page flipping by default
-#ifndef NUM_BUFFERS
+// numbers of buffers for page flipping
#define NUM_BUFFERS 2
-#endif
enum {
@@ -159,8 +157,7 @@ int mapFrameBufferLocked(struct private_module_t* module, int format)
info.activate = FB_ACTIVATE_NOW;
/*
- * Request NUM_BUFFERS screens
- * To enable page flipping, NUM_BUFFERS should be at least 2.
+ * Request NUM_BUFFERS screens (at lest 2 for page flipping)
*/
info.yres_virtual = info.yres * NUM_BUFFERS;
diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp
index bad60481..1ebc04d2 100644
--- a/modules/sensors/dynamic_sensor/Android.bp
+++ b/modules/sensors/dynamic_sensor/Android.bp
@@ -108,23 +108,7 @@ cc_library_shared {
cflags: ["-DLOG_TAG=\"DynamicSensorHal\""],
- srcs: [
- "DynamicSensorsSubHal.cpp",
- "sensors.cpp",
- ],
- shared_libs: [
- "android.hardware.sensors@2.0",
- "android.hardware.sensors@2.0-ScopedWakelock",
- "android.hardware.sensors@2.1",
- "libhidlbase",
- ],
- static_libs: [
- "android.hardware.sensors@1.0-convert",
- ],
- header_libs: [
- "android.hardware.sensors@2.X-multihal.header",
- "android.hardware.sensors@2.X-shared-utils",
- ],
+ srcs: ["sensors.cpp"],
}
//
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
index 69fc7d86..4ec76b27 100644
--- a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
@@ -42,7 +42,6 @@ void BaseSensorObject::getUuid(uint8_t* uuid) const {
int BaseSensorObject::flush() {
static const sensors_event_t event = {
.type = SENSOR_TYPE_META_DATA,
- .meta_data.what = META_DATA_FLUSH_COMPLETE,
.timestamp = TIMESTAMP_AUTO_FILL // timestamp will be filled at dispatcher
};
generateEvent(event);
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
index 85b99017..c51e9125 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -57,6 +57,8 @@ SocketConnectionDetector::SocketConnectionDetector(BaseDynamicSensorDaemon *d, i
std::ostringstream s;
s << "socket:" << port;
mDevice = s.str();
+
+ run("ddad_socket");
}
SocketConnectionDetector::~SocketConnectionDetector() {
@@ -65,12 +67,6 @@ SocketConnectionDetector::~SocketConnectionDetector() {
}
}
-void SocketConnectionDetector::Init() {
- // run adds a strong reference to this object, so it can't be invoked from
- // the constructor.
- run("ddad_socket");
-}
-
int SocketConnectionDetector::waitForConnection() {
return ::accept(mListenFd, nullptr, nullptr);
}
@@ -128,6 +124,9 @@ FileConnectionDetector::FileConnectionDetector (
ALOGE("Cannot setup watch on dir %s", path.c_str());
return;
}
+
+ // mLooper != null && mInotifyFd added to looper
+ run("ddad_file");
}
FileConnectionDetector::~FileConnectionDetector() {
@@ -139,13 +138,6 @@ FileConnectionDetector::~FileConnectionDetector() {
}
}
-void FileConnectionDetector::Init() {
- // mLooper != null && mInotifyFd added to looper
- // run adds a strong reference to this object, so it can't be invoked from
- // the constructor.
- run("ddad_file");
-}
-
bool FileConnectionDetector::matches(const std::string &name) const {
return std::regex_match(name, mRegex);
}
@@ -156,10 +148,6 @@ std::string FileConnectionDetector::getFullName(const std::string name) const {
void FileConnectionDetector::processExistingFiles() const {
auto dirp = ::opendir(mPath.c_str());
- if(dirp == NULL) {
- ALOGE("Problem open dir %s, errno: %s", mPath.c_str(), ::strerror(errno));
- return;
- }
struct dirent *dp;
while ((dp = ::readdir(dirp)) != NULL) {
const std::string name(dp->d_name);
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.h b/modules/sensors/dynamic_sensor/ConnectionDetector.h
index 75fbb0bc..0ee1df29 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.h
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.h
@@ -34,7 +34,6 @@ class ConnectionDetector : virtual public RefBase {
public:
ConnectionDetector(BaseDynamicSensorDaemon *d) : mDaemon(d) { }
virtual ~ConnectionDetector() = default;
- virtual void Init() {}
protected:
BaseDynamicSensorDaemon* mDaemon;
};
@@ -46,7 +45,6 @@ class SocketConnectionDetector : public ConnectionDetector, public Thread {
public:
SocketConnectionDetector(BaseDynamicSensorDaemon *d, int port);
virtual ~SocketConnectionDetector();
- void Init() override;
private:
// implement virtual of Thread
virtual bool threadLoop();
@@ -64,7 +62,6 @@ public:
FileConnectionDetector(
BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex);
virtual ~FileConnectionDetector();
- void Init() override;
private:
static constexpr int POLL_IDENT = 1;
// implement virtual of Thread
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
index 10771e32..a1a47e81 100644
--- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
+++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
@@ -28,7 +28,7 @@
#include <netinet/in.h>
#include <algorithm> //std::max
-#define SYSPROP_PREFIX "vendor.dynamic_sensor.mock"
+#define SYSPROP_PREFIX "dynamic_sensor.dummy"
#define FILE_NAME_BASE "dummy_accel_file"
#define FILE_NAME_REGEX ("^" FILE_NAME_BASE "[0-9]$")
@@ -43,13 +43,11 @@ DummyDynamicAccelDaemon::DummyDynamicAccelDaemon(DynamicSensorManager& manager)
if (strcmp(property, "") != 0) {
mFileDetector = new FileConnectionDetector(
this, std::string(property), std::string(FILE_NAME_REGEX));
- mFileDetector->Init();
}
property_get(SYSPROP_PREFIX ".socket", property, "");
if (strcmp(property, "") != 0) {
mSocketDetector = new SocketConnectionDetector(this, atoi(property));
- mSocketDetector->Init();
}
}
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
index efac5e95..37b43132 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -76,7 +76,7 @@ bool DynamicSensorManager::owns(int handle) const {
int DynamicSensorManager::activate(int handle, bool enable) {
if (handle == mHandleRange.first) {
- mMetaSensorActive = enable;
+ // ignored
return 0;
}
@@ -87,7 +87,7 @@ int DynamicSensorManager::activate(int handle, bool enable) {
}
return operateSensor(handle,
- [=] (sp<BaseSensorObject> s)->int {
+ [&enable] (sp<BaseSensorObject> s)->int {
return s->enable(enable);
});
}
@@ -98,7 +98,7 @@ int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch
return 0;
}
return operateSensor(handle,
- [=] (sp<BaseSensorObject> s)->int {
+ [&sample_period, &batch_period] (sp<BaseSensorObject> s)->int {
return s->batch(sample_period, batch_period);
});
}
@@ -109,17 +109,13 @@ int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) {
int DynamicSensorManager::flush(int handle) {
if (handle == mHandleRange.first) {
- if (mMetaSensorActive) {
- static const sensors_event_t event = {
- .sensor = mHandleRange.first,
- .type = SENSOR_TYPE_META_DATA,
- .meta_data.what = META_DATA_FLUSH_COMPLETE,
- .timestamp = TIMESTAMP_AUTO_FILL, // timestamp will be filled at dispatcher
- };
- submitEvent(nullptr, event);
- } else {
- return -EINVAL;
- }
+ // submit a flush complete here
+ static const sensors_event_t event = {
+ .sensor = mHandleRange.first,
+ .type = SENSOR_TYPE_META_DATA,
+ .timestamp = TIMESTAMP_AUTO_FILL, // timestamp will be filled at dispatcher
+ };
+ submitEvent(nullptr, event);
return 0;
}
return operateSensor(handle, [] (sp<BaseSensorObject> s)->int {return s->flush();});
@@ -239,87 +235,6 @@ const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
return mMetaSensor;
}
-int DynamicSensorManager::operateSensor(
- int handle, OperateSensorFunc sensorFunc) {
- std::shared_future<int> sensorOp;
- {
- std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
-
- // Invoke the function asynchronously.
- sensorOp = std::async(
- [this, handle = handle, sensorFunc = sensorFunc,
- sensorOpIndex = mNextSensorOpIndex] ()->int {
- return operateSensor(handle, sensorFunc, sensorOpIndex);
- }).share();
-
- // Add sensor operation to the queue.
- mSensorOpQueue.push({mNextSensorOpIndex, sensorOp});
- mNextSensorOpIndex++;
- }
-
- // Wait for the sensor operation to complete.
- if (sensorOp.wait_for(kSensorOpTimeout) != std::future_status::ready) {
- ALOGE("sensor operation timed out");
- return TIMED_OUT;
- }
-
- return sensorOp.get();
-}
-
-int DynamicSensorManager::operateSensor(
- int handle, OperateSensorFunc sensorFunc, uint64_t sensorOpIndex) {
- int rv = 0;
-
- // Wait until this sensor operation is at the head of the queue.
- while (1) {
- std::shared_future<int> headSensorOp;
-
- {
- std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
-
- if (mSensorOpQueue.front().first == sensorOpIndex) {
- break;
- }
- headSensorOp = mSensorOpQueue.front().second;
- }
- headSensorOp.wait();
- }
-
- // Perform sensor operation.
- sp<BaseSensorObject> sensor;
- {
- std::lock_guard<std::mutex> lk(mLock);
- const auto i = mMap.find(handle);
- if (i == mMap.end()) {
- rv = BAD_VALUE;
- }
- if (rv == 0) {
- sensor = i->second.promote();
- if (sensor == nullptr) {
- // sensor object is already gone
- rv = BAD_VALUE;
- }
- }
- }
- if (rv == 0) {
- rv = sensorFunc(sensor);
- }
-
- // Remove sensor operation from queue. When the operation's shared state is
- // destroyed, execution of this function ceases. Thus, if the state is
- // destroyed when the operation is removed from the queue, the lock will
- // never be released. To prevent that, the state is shared locally, so it
- // isn't destroyed until this function completes.
- std::shared_future<int> sensorOp;
- {
- std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
- sensorOp = mSensorOpQueue.front().second;
- mSensorOpQueue.pop();
- }
-
- return rv;
-}
-
DynamicSensorManager::ConnectionReport::ConnectionReport(
int handle, sp<BaseSensorObject> sensor) :
mSensor(*(sensor->getSensor())),
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
index b8a73203..b6f39da6 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -22,9 +22,7 @@
#include <hardware/sensors.h>
#include <utils/RefBase.h>
-#include <future>
#include <mutex>
-#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
@@ -94,18 +92,25 @@ private:
// returns next available handle to use upon a new sensor connection, or -1 if we run out.
int getNextAvailableHandle();
- // Runs a sensor function with a timeout. On timeout, function could still
- // be running, so any function parameter or closure lifetimes should match
- // the function's lifetime.
- using OperateSensorFunc = std::function<int(sp<BaseSensorObject>)>;
- int operateSensor(int handle, OperateSensorFunc sensorFunc);
- int operateSensor(int handle, OperateSensorFunc sensorFunc,
- uint64_t sensorOpIndex);
+ // TF: int foo(sp<BaseSensorObject> obj);
+ template <typename TF>
+ int operateSensor(int handle, TF f) const {
+ std::lock_guard<std::mutex> lk(mLock);
+ const auto i = mMap.find(handle);
+ if (i == mMap.end()) {
+ return BAD_VALUE;
+ }
+ sp<BaseSensorObject> s = i->second.promote();
+ if (s == nullptr) {
+ // sensor object is already gone
+ return BAD_VALUE;
+ }
+ return f(s);
+ }
// available sensor handle space
const std::pair<int, int> mHandleRange;
sensor_t mMetaSensor;
- bool mMetaSensorActive = false;
// immutable pointer to event callback, used in extention mode.
SensorEventCallback * const mCallback;
@@ -124,14 +129,6 @@ private:
// daemons
std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector;
-
- // Sensor operation queue. Calls to the sensor HAL must complete within 1
- // second.
- static constexpr std::chrono::milliseconds
- kSensorOpTimeout = std::chrono::milliseconds(900);
- std::mutex mSensorOpQueueLock;
- std::queue<std::pair<uint64_t, std::shared_future<int>>> mSensorOpQueue;
- uint64_t mNextSensorOpIndex = 0;
};
} // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
deleted file mode 100644
index d5a9b3c0..00000000
--- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "BaseSensorObject.h"
-#include "DynamicSensorsSubHal.h"
-
-#include <convertV2_1.h>
-#include <hardware/sensors-base.h>
-#include <log/log.h>
-
-#include <chrono>
-#include <thread>
-
-using ::android::hardware::sensors::V1_0::Result;
-using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;
-using ::android::hardware::sensors::V2_1::implementation::convertFromSensorEvent;
-using ::android::hardware::sensors::V2_1::SensorInfo;
-using ::android::hardware::sensors::V2_1::SensorType;
-template<class T> using Return = ::android::hardware::Return<T>;
-using ::android::hardware::Void;
-
-namespace android {
-namespace SensorHalExt {
-
-static Result ResultFromStatus(status_t err) {
- switch (err) {
- case ::android::OK:
- return Result::OK;
- case ::android::PERMISSION_DENIED:
- return Result::PERMISSION_DENIED;
- case ::android::NO_MEMORY:
- return Result::NO_MEMORY;
- case ::android::BAD_VALUE:
- return Result::BAD_VALUE;
- default:
- return Result::INVALID_OPERATION;
- }
-}
-
-DynamicSensorsSubHal::DynamicSensorsSubHal() {
- // initialize dynamic sensor manager
- mDynamicSensorManager.reset(
- DynamicSensorManager::createInstance(kDynamicHandleBase,
- kMaxDynamicHandleCount,
- this /* callback */));
-}
-
-// ISensors.
-Return<Result> DynamicSensorsSubHal::setOperationMode(OperationMode mode) {
- return (mode == static_cast<OperationMode>(SENSOR_HAL_NORMAL_MODE) ?
- Result::OK : Result::BAD_VALUE);
-}
-
-Return<Result> DynamicSensorsSubHal::activate(int32_t sensor_handle,
- bool enabled) {
- int rc = mDynamicSensorManager->activate(sensor_handle, enabled);
- return ResultFromStatus(rc);
-}
-
-Return<Result> DynamicSensorsSubHal::batch(
- int32_t sensor_handle, int64_t sampling_period_ns,
- int64_t max_report_latency_ns) {
- int rc = mDynamicSensorManager->batch(sensor_handle, sampling_period_ns,
- max_report_latency_ns);
- return ResultFromStatus(rc);
-}
-
-Return<Result> DynamicSensorsSubHal::flush(int32_t sensor_handle) {
- int rc = mDynamicSensorManager->flush(sensor_handle);
- return ResultFromStatus(rc);
-}
-
-Return<void> DynamicSensorsSubHal::registerDirectChannel(
- const SharedMemInfo& mem __unused,
- registerDirectChannel_cb callback __unused) {
- ALOGE("DynamicSensorsSubHal::registerDirectChannel not supported.");
-
- return Void();
-}
-
-Return<Result> DynamicSensorsSubHal::unregisterDirectChannel(
- int32_t channel_handle __unused) {
- ALOGE("DynamicSensorsSubHal::unregisterDirectChannel not supported.");
-
- return Result::INVALID_OPERATION;
-}
-
-Return<void> DynamicSensorsSubHal::configDirectReport(
- int32_t sensor_handle __unused, int32_t channel_handle __unused,
- RateLevel rate __unused, configDirectReport_cb callback __unused) {
- ALOGE("DynamicSensorsSubHal::configDirectReport not supported.");
-
- return Void();
-}
-
-Return<void> DynamicSensorsSubHal::getSensorsList_2_1(
- getSensorsList_2_1_cb callback) {
- const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor();
- std::vector<SensorInfo> sensors;
-
- ALOGD("DynamicSensorsSubHal::getSensorsList_2_1 invoked.");
-
- // get the dynamic sensor info
- sensors.resize(1);
- sensors[0].sensorHandle = sensor_info.handle;
- sensors[0].name = sensor_info.name;
- sensors[0].vendor = sensor_info.vendor;
- sensors[0].version = 1;
- sensors[0].type = static_cast<SensorType>(sensor_info.type);
- sensors[0].typeAsString = sensor_info.stringType;
- sensors[0].maxRange = sensor_info.maxRange;
- sensors[0].resolution = sensor_info.resolution;
- sensors[0].power = sensor_info.power;
- sensors[0].minDelay = sensor_info.minDelay;
- sensors[0].fifoReservedEventCount = sensor_info.fifoReservedEventCount;
- sensors[0].fifoMaxEventCount = sensor_info.fifoMaxEventCount;
- sensors[0].requiredPermission = sensor_info.requiredPermission;
- sensors[0].maxDelay = sensor_info.maxDelay;
- sensors[0].flags = sensor_info.flags;
-
- callback(sensors);
-
- return Void();
-}
-
-Return<Result> DynamicSensorsSubHal::injectSensorData_2_1(
- const Event& event __unused) {
- ALOGE("DynamicSensorsSubHal::injectSensorData_2_1 not supported.");
-
- return Result::INVALID_OPERATION;
-}
-
-Return<void> DynamicSensorsSubHal::debug(
- const hidl_handle& handle __unused,
- const hidl_vec<hidl_string>& args __unused) {
- return Void();
-}
-
-// ISensorsSubHal.
-Return<Result> DynamicSensorsSubHal::initialize(
- const sp<IHalProxyCallback>& hal_proxy_callback) {
- ALOGD("DynamicSensorsSubHal::initialize invoked.");
-
- mHalProxyCallback = hal_proxy_callback;
-
- return Result::OK;
-}
-
-// SensorEventCallback.
-int DynamicSensorsSubHal::submitEvent(SP(BaseSensorObject) sensor,
- const sensors_event_t& e) {
- std::vector<Event> events;
- Event hal_event;
- bool wakeup;
-
- if (e.type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
- const dynamic_sensor_meta_event_t* sensor_meta;
-
- sensor_meta = static_cast<const dynamic_sensor_meta_event_t*>(
- &(e.dynamic_sensor_meta));
- if (sensor_meta->connected != 0) {
- // The sensor framework must be notified of the connected sensor
- // through the callback before handling the sensor added event. If
- // it isn't, it will assert when looking up the sensor handle when
- // processing the sensor added event.
- //
- // TODO (b/201529167): Fix dynamic sensors addition / removal when
- // converting to AIDL.
- // The sensor framework runs in a separate process from the sensor
- // HAL, and it processes events in a dedicated thread, so it's
- // possible the event handling can be done before the callback is
- // run. Thus, a delay is added after sending notification of the
- // connected sensor.
- onSensorConnected(sensor_meta->handle, sensor_meta->sensor);
- std::this_thread::sleep_for(std::chrono::milliseconds(1000));
- }
- }
-
- convertFromSensorEvent(e, &hal_event);
- events.push_back(hal_event);
- if (sensor && sensor->getSensor()) {
- wakeup = sensor->getSensor()->flags & SENSOR_FLAG_WAKE_UP;
- } else {
- wakeup = false;
- }
- ScopedWakelock wakelock = mHalProxyCallback->createScopedWakelock(wakeup);
- mHalProxyCallback->postEvents(events, std::move(wakelock));
-
- return 0;
-}
-
-void DynamicSensorsSubHal::onSensorConnected(
- int handle, const sensor_t* sensor_info) {
- hidl_vec<SensorInfo> sensor_list;
-
- sensor_list.resize(1);
- sensor_list[0].sensorHandle = handle;
- sensor_list[0].name = sensor_info->name;
- sensor_list[0].vendor = sensor_info->vendor;
- sensor_list[0].version = 1;
- sensor_list[0].type = static_cast<SensorType>(sensor_info->type);
- sensor_list[0].typeAsString = sensor_info->stringType;
- sensor_list[0].maxRange = sensor_info->maxRange;
- sensor_list[0].resolution = sensor_info->resolution;
- sensor_list[0].power = sensor_info->power;
- sensor_list[0].minDelay = sensor_info->minDelay;
- sensor_list[0].fifoReservedEventCount = sensor_info->fifoReservedEventCount;
- sensor_list[0].fifoMaxEventCount = sensor_info->fifoMaxEventCount;
- sensor_list[0].requiredPermission = sensor_info->requiredPermission;
- sensor_list[0].maxDelay = sensor_info->maxDelay;
- sensor_list[0].flags = sensor_info->flags;
-
- mHalProxyCallback->onDynamicSensorsConnected_2_1(sensor_list);
-}
-
-} // namespace SensorHalExt
-} // namespace android
-
-using ::android::hardware::sensors::V2_1::implementation::ISensorsSubHal;
-ISensorsSubHal* sensorsHalGetSubHal_2_1(uint32_t* version) {
- static android::SensorHalExt::DynamicSensorsSubHal subHal;
-
- *version = SUB_HAL_2_1_VERSION;
- return &subHal;
-}
-
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h
deleted file mode 100644
index f59b00ae..00000000
--- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2021 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_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H
-#define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H
-
-#include "DynamicSensorManager.h"
-
-#include <V2_1/SubHal.h>
-
-namespace android {
-namespace SensorHalExt {
-
-class DynamicSensorsSubHal :
- public SensorEventCallback,
- public ::android::hardware::sensors::V2_1::implementation::ISensorsSubHal {
- using Event = ::android::hardware::sensors::V2_1::Event;
- using hidl_handle = ::android::hardware::hidl_handle;
- using hidl_string = ::android::hardware::hidl_string;
- template<class T> using hidl_vec = ::android::hardware::hidl_vec<T>;
- using IHalProxyCallback =
- ::android::hardware::sensors::V2_1::implementation::IHalProxyCallback;
- using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
- using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
- using Result = ::android::hardware::sensors::V1_0::Result;
- template<class T> using Return = ::android::hardware::Return<T>;
- using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
-
-public:
- DynamicSensorsSubHal();
-
- // ISensors.
- Return<Result> setOperationMode(OperationMode mode) override;
- Return<Result> activate(int32_t sensor_handle, bool enabled) override;
- Return<Result> batch(int32_t sensor_handle, int64_t sampling_period_ns,
- int64_t max_report_latency_ns) override;
- Return<Result> flush(int32_t sensor_handle) override;
- Return<void> registerDirectChannel(
- const SharedMemInfo& mem,
- registerDirectChannel_cb callback) override;
- Return<Result> unregisterDirectChannel(int32_t channel_handle) override;
- Return<void> configDirectReport(
- int32_t sensor_handle, int32_t channel_handle, RateLevel rate,
- configDirectReport_cb callback) override;
- Return<void> getSensorsList_2_1(getSensorsList_2_1_cb callback) override;
- Return<Result> injectSensorData_2_1(const Event& event) override;
- Return<void> debug(
- const hidl_handle& handle,
- const hidl_vec<hidl_string>& args) override;
-
- // ISensorsSubHal.
- const std::string getName() override { return "Dynamic-SubHAL"; }
- Return<Result> initialize(
- const sp<IHalProxyCallback>& hal_proxy_callback) override;
-
- // SensorEventCallback.
- int submitEvent(SP(BaseSensorObject) sensor,
- const sensors_event_t& e) override;
-
-private:
- static constexpr int32_t kDynamicHandleBase = 1;
- static constexpr int32_t kDynamicHandleEnd = 0x1000000;
- static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd -
- kDynamicHandleBase;
-
- void onSensorConnected(int handle, const sensor_t* sensor_info);
-
- std::unique_ptr<DynamicSensorManager> mDynamicSensorManager;
- sp<IHalProxyCallback> mHalProxyCallback;
-};
-
-} // namespace SensorHalExt
-} // namespace android
-
-#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H
-
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
index 3759e7e9..f3c8a27b 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -19,8 +19,6 @@
#include <utils/Errors.h>
#include "HidLog.h"
-#include <HidUtils.h>
-
#include <algorithm>
#include <cfloat>
#include <codecvt>
@@ -439,7 +437,6 @@ void HidRawSensor::initFeatureValueFromHidDeviceInfo(
featureValue->reportModeFlag = SENSOR_FLAG_SPECIAL_REPORTING_MODE;
featureValue->isWakeUp = false;
- featureValue->useUniqueIdForUuid = false;
memset(featureValue->uuid, 0, sizeof(featureValue->uuid));
featureValue->isAndroidCustom = false;
}
@@ -466,23 +463,40 @@ bool HidRawSensor::populateFeatureValueFromFeatureReport(
for (const auto & r : packet.reports) {
switch (r.usage) {
case FRIENDLY_NAME:
+ if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+ // invalid friendly name
+ break;
+ }
if (decodeString(r, buffer, &str) && !str.empty()) {
featureValue->name = str;
}
break;
case SENSOR_MANUFACTURER:
+ if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+ // invalid manufacturer
+ break;
+ }
if (decodeString(r, buffer, &str) && !str.empty()) {
featureValue->vendor = str;
}
break;
case PERSISTENT_UNIQUE_ID:
+ if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+ // invalid unique id string
+ break;
+ }
if (decodeString(r, buffer, &str) && !str.empty()) {
featureValue->uniqueId = str;
}
break;
case SENSOR_DESCRIPTION:
+ if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1
+ || (r.bitOffset / 8 + r.count * 2) > buffer.size() ) {
+ // invalid description
+ break;
+ }
if (decodeString(r, buffer, &str)) {
- detectSensorFromDescription(str);
+ mFeatureInfo.isAndroidCustom = detectAndroidCustomSensor(str);
}
break;
default:
@@ -530,19 +544,10 @@ bool HidRawSensor::validateFeatureValueAndBuildSensor() {
}
// initialize uuid field, use name, vendor and uniqueId
- // initialize uuid field using one of the following methods:
- //
- // 1. use uniqueId
- // 2. use name, vendor and uniqueId
- if (mFeatureInfo.useUniqueIdForUuid) {
- if (mFeatureInfo.uniqueId.size() == sizeof(mFeatureInfo.uuid)) {
- memcpy(mFeatureInfo.uuid, mFeatureInfo.uniqueId.c_str(),
- sizeof(mFeatureInfo.uuid));
- }
- } else if (mFeatureInfo.name.size() >= 4
- && mFeatureInfo.vendor.size() >= 4
- && mFeatureInfo.typeString.size() >= 4
- && mFeatureInfo.uniqueId.size() >= 4) {
+ if (mFeatureInfo.name.size() >= 4
+ && mFeatureInfo.vendor.size() >= 4
+ && mFeatureInfo.typeString.size() >= 4
+ && mFeatureInfo.uniqueId.size() >= 4) {
uint32_t tmp[4], h;
std::hash<std::string> stringHash;
h = stringHash(mFeatureInfo.uniqueId);
@@ -576,34 +581,26 @@ bool HidRawSensor::validateFeatureValueAndBuildSensor() {
bool HidRawSensor::decodeString(
const HidParser::ReportItem &report, const std::vector<uint8_t> &buffer, std::string *d) {
- if (!report.isByteAligned() ||
- (report.bitSize != 8 && report.bitSize != 16) || report.count < 1) {
+ if (!report.isByteAligned() || report.bitSize != 16 || report.count < 1) {
return false;
}
- size_t charSize = report.bitSize / 8;
size_t offset = report.bitOffset / 8;
- if (offset + report.count * charSize > buffer.size()) {
+ if (offset + report.count * 2 > buffer.size()) {
return false;
}
- if (charSize == 1) {
- *d = std::string(buffer.begin() + offset,
- buffer.begin() + offset + report.count);
- } else {
- std::vector<uint16_t> data(report.count);
- auto i = data.begin();
- auto j = buffer.begin() + offset;
- for ( ; i != data.end(); ++i, j += sizeof(uint16_t)) {
- // hid specified little endian
- *i = *j + (*(j + 1) << 8);
- }
- std::wstring wstr(data.begin(), data.end());
-
- std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
- *d = converter.to_bytes(wstr);
+ std::vector<uint16_t> data(report.count);
+ auto i = data.begin();
+ auto j = buffer.begin() + offset;
+ for ( ; i != data.end(); ++i, j += sizeof(uint16_t)) {
+ // hid specified little endian
+ *i = *j + (*(j + 1) << 8);
}
+ std::wstring wstr(data.begin(), data.end());
+ std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
+ *d = converter.to_bytes(wstr);
return true;
}
@@ -622,33 +619,6 @@ std::vector<std::string> split(const std::string &text, char sep) {
return tokens;
}
-void HidRawSensor::detectSensorFromDescription(const std::string &description) {
- if (detectAndroidHeadTrackerSensor(description) ||
- detectAndroidCustomSensor(description)) {
- mFeatureInfo.isAndroidCustom = true;
- }
-}
-
-bool HidRawSensor::detectAndroidHeadTrackerSensor(
- const std::string &description) {
- if (description.find("#AndroidHeadTracker#1.") != 0) {
- return false;
- }
-
- mFeatureInfo.type = SENSOR_TYPE_HEAD_TRACKER;
- mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEAD_TRACKER;
- mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
- mFeatureInfo.permission = "";
- mFeatureInfo.isWakeUp = false;
-
- // HID head tracker sensors must use the HID unique ID for the sensor UUID
- // to permit association between the sensor and audio device (see
- // specification for HEAD_TRACKER in SensorType).
- mFeatureInfo.useUniqueIdForUuid = true;
-
- return true;
-}
-
bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) {
size_t nullPosition = description.find('\0');
if (nullPosition == std::string::npos) {
@@ -814,95 +784,54 @@ bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) {
}
bool HidRawSensor::findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets) {
- using namespace Hid::Sensor::PowerStateUsage;
using namespace Hid::Sensor::PropertyUsage;
- using namespace Hid::Sensor::ReportingStateUsage;
+ using namespace Hid::Sensor::RawMinMax;
//REPORTING_STATE
const HidParser::ReportItem *reportingState
= find(packets, REPORTING_STATE, HidParser::REPORT_TYPE_FEATURE);
- if (reportingState == nullptr) {
+ if (reportingState == nullptr
+ || !reportingState->isByteAligned()
+ || reportingState->bitSize != 8
+ || reportingState->minRaw != REPORTING_STATE_MIN
+ || reportingState->maxRaw != REPORTING_STATE_MAX) {
LOG_W << "Cannot find valid reporting state feature" << LOG_ENDL;
} else {
mReportingStateId = reportingState->id;
- mReportingStateBitOffset = reportingState->bitOffset;
- mReportingStateBitSize = reportingState->bitSize;
-
- mReportingStateDisableIndex = -1;
- mReportingStateEnableIndex = -1;
- for (unsigned i = 0; i < reportingState->usageVector.size(); ++i) {
- if (reportingState->usageVector[i] == REPORTING_STATE_NO_EVENTS) {
- mReportingStateDisableIndex = i;
- }
- if (reportingState->usageVector[i] == REPORTING_STATE_ALL_EVENTS) {
- mReportingStateEnableIndex = i;
- }
- }
- if (mReportingStateDisableIndex < 0) {
- LOG_W << "Cannot find reporting state to disable sensor"
- << LOG_ENDL;
- mReportingStateId = -1;
- }
- if (mReportingStateEnableIndex < 0) {
- LOG_W << "Cannot find reporting state to enable sensor" << LOG_ENDL;
- mReportingStateId = -1;
- }
+ mReportingStateOffset = reportingState->bitOffset / 8;
}
//POWER_STATE
const HidParser::ReportItem *powerState
= find(packets, POWER_STATE, HidParser::REPORT_TYPE_FEATURE);
- if (powerState == nullptr) {
+ if (powerState == nullptr
+ || !powerState->isByteAligned()
+ || powerState->bitSize != 8
+ || powerState->minRaw != POWER_STATE_MIN
+ || powerState->maxRaw != POWER_STATE_MAX) {
LOG_W << "Cannot find valid power state feature" << LOG_ENDL;
} else {
mPowerStateId = powerState->id;
- mPowerStateBitOffset = powerState->bitOffset;
- mPowerStateBitSize = powerState->bitSize;
-
- mPowerStateOffIndex = -1;
- mPowerStateOnIndex = -1;
- for (unsigned i = 0; i < powerState->usageVector.size(); ++i) {
- if (powerState->usageVector[i] == POWER_STATE_D4_POWER_OFF) {
- mPowerStateOffIndex = i;
- }
- if (powerState->usageVector[i] == POWER_STATE_D0_FULL_POWER) {
- mPowerStateOnIndex = i;
- }
- }
- if (mPowerStateOffIndex < 0) {
- LOG_W << "Cannot find power state to power off sensor"
- << LOG_ENDL;
- mPowerStateId = -1;
- }
- if (mPowerStateOnIndex < 0) {
- LOG_W << "Cannot find power state to power on sensor" << LOG_ENDL;
- mPowerStateId = -1;
- }
+ mPowerStateOffset = powerState->bitOffset / 8;
}
//REPORT_INTERVAL
const HidParser::ReportItem *reportInterval
= find(packets, REPORT_INTERVAL, HidParser::REPORT_TYPE_FEATURE);
if (reportInterval == nullptr
- || reportInterval->minRaw < 0) {
+ || !reportInterval->isByteAligned()
+ || reportInterval->minRaw < 0
+ || (reportInterval->bitSize != 16 && reportInterval->bitSize != 32)) {
LOG_W << "Cannot find valid report interval feature" << LOG_ENDL;
} else {
mReportIntervalId = reportInterval->id;
- mReportIntervalBitOffset = reportInterval->bitOffset;
- mReportIntervalBitSize = reportInterval->bitSize;
- mReportIntervalScale = reportInterval->a;
- mReportIntervalOffset = reportInterval->b;
-
- mFeatureInfo.minDelay = 1000000.0
- * (reportInterval->minRaw + reportInterval->b)
- * reportInterval->a;
- mFeatureInfo.minDelay = std::max(1000, mFeatureInfo.minDelay);
- mFeatureInfo.maxDelay = 1000000.0
- * (reportInterval->maxRaw + reportInterval->b)
- * reportInterval->a;
- mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000000),
- mFeatureInfo.maxDelay);
+ mReportIntervalOffset = reportInterval->bitOffset / 8;
+ mReportIntervalSize = reportInterval->bitSize / 8;
+
+ mFeatureInfo.minDelay = std::max(static_cast<int64_t>(1), reportInterval->minRaw) * 1000;
+ mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000),
+ reportInterval->maxRaw) * 1000; // maximum 1000 second
}
return true;
return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0;
@@ -917,6 +846,7 @@ void HidRawSensor::getUuid(uint8_t* uuid) const {
}
int HidRawSensor::enable(bool enable) {
+ using namespace Hid::Sensor::StateValue;
SP(HidDevice) device = PROMOTE(mDevice);
if (device == nullptr) {
@@ -933,11 +863,8 @@ int HidRawSensor::enable(bool enable) {
setPowerOk = false;
uint8_t id = static_cast<uint8_t>(mPowerStateId);
if (device->getFeature(id, &buffer)
- && (8 * buffer.size()) >=
- (mPowerStateBitOffset + mPowerStateBitSize)) {
- uint8_t index = enable ? mPowerStateOnIndex : mPowerStateOffIndex;
- HidUtil::copyBits(&index, &(buffer[0]), buffer.size(),
- 0, mPowerStateBitOffset, mPowerStateBitSize);
+ && buffer.size() > mPowerStateOffset) {
+ buffer[mPowerStateOffset] = enable ? POWER_STATE_FULL_POWER : POWER_STATE_POWER_OFF;
setPowerOk = device->setFeature(id, buffer);
} else {
LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL;
@@ -949,12 +876,9 @@ int HidRawSensor::enable(bool enable) {
setReportingOk = false;
uint8_t id = static_cast<uint8_t>(mReportingStateId);
if (device->getFeature(id, &buffer)
- && (8 * buffer.size()) >
- (mReportingStateBitOffset + mReportingStateBitSize)) {
- uint8_t index = enable ? mReportingStateEnableIndex :
- mReportingStateDisableIndex;
- HidUtil::copyBits(&index, &(buffer[0]), buffer.size(),0,
- mReportingStateBitOffset, mReportingStateBitSize);
+ && buffer.size() > mReportingStateOffset) {
+ buffer[mReportingStateOffset]
+ = enable ? REPORTING_STATE_ALL_EVENT : REPORTING_STATE_NO_EVENT;
setReportingOk = device->setFeature(id, buffer);
} else {
LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL;
@@ -987,17 +911,22 @@ int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) {
ok = false;
uint8_t id = static_cast<uint8_t>(mReportIntervalId);
if (device->getFeature(id, &buffer)
- && (8 * buffer.size()) >=
- (mReportIntervalBitOffset + mReportIntervalBitSize)) {
- int64_t periodMs =
- (((static_cast<double>(samplingPeriod)) / 1000000000.0)
- / mReportIntervalScale) - mReportIntervalOffset;
- int64_t maxPeriodMs =
- (1LL << std::min(mReportIntervalBitSize, 63U)) - 1;
- periodMs = std::min(periodMs, maxPeriodMs);
- HidUtil::copyBits(&periodMs, &(buffer[0]), buffer.size(),
- 0, mReportIntervalBitOffset,
- mReportIntervalBitSize);
+ && buffer.size() >= mReportIntervalOffset + mReportIntervalSize) {
+ int64_t periodMs = samplingPeriod / 1000000; //ns -> ms
+ switch (mReportIntervalSize) {
+ case sizeof(uint16_t):
+ periodMs = std::min(periodMs, static_cast<int64_t>(UINT16_MAX));
+ buffer[mReportIntervalOffset] = periodMs & 0xFF;
+ buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+ break;
+ case sizeof(uint32_t):
+ periodMs = std::min(periodMs, static_cast<int64_t>(UINT32_MAX));
+ buffer[mReportIntervalOffset] = periodMs & 0xFF;
+ buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+ buffer[mReportIntervalOffset + 2] = (periodMs >> 16) & 0xFF;
+ buffer[mReportIntervalOffset + 3] = (periodMs >> 24) & 0xFF;
+ break;
+ }
ok = device->setFeature(id, buffer);
}
}
@@ -1021,50 +950,6 @@ void HidRawSensor::handleInput(uint8_t id, const std::vector<uint8_t> &message)
.type = mSensor.type
};
bool valid = true;
-
- switch (mFeatureInfo.type) {
- case SENSOR_TYPE_HEAD_TRACKER:
- valid = getHeadTrackerEventData(message, &event);
- break;
- default:
- valid = getSensorEventData(message, &event);
- break;
- }
- if (!valid) {
- LOG_E << "Invalid data observed in decoding, discard" << LOG_ENDL;
- return;
- }
- event.timestamp = -1;
- generateEvent(event);
-}
-
-bool HidRawSensor::getHeadTrackerEventData(const std::vector<uint8_t> &message,
- sensors_event_t *event) {
- head_tracker_event_t *head_tracker;
-
- head_tracker = &(event->head_tracker);
- if (!getReportFieldValue(message, &(mTranslateTable[0]),
- &(head_tracker->rx))
- || !getReportFieldValue(message, &(mTranslateTable[1]),
- &(head_tracker->ry))
- || !getReportFieldValue(message, &(mTranslateTable[2]),
- &(head_tracker->rz))
- || !getReportFieldValue(message, &(mTranslateTable[3]),
- &(head_tracker->vx))
- || !getReportFieldValue(message, &(mTranslateTable[4]),
- &(head_tracker->vy))
- || !getReportFieldValue(message, &(mTranslateTable[5]),
- &(head_tracker->vz))
- || !getReportFieldValue(message, &(mTranslateTable[6]),
- &(head_tracker->discontinuity_count))) {
- return false;
- }
-
- return true;
-}
-
-bool HidRawSensor::getSensorEventData(const std::vector<uint8_t> &message,
- sensors_event_t *event) {
for (const auto &rec : mTranslateTable) {
int64_t v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0;
for (int i = static_cast<int>(rec.byteSize) - 1; i >= 0; --i) {
@@ -1074,23 +959,26 @@ bool HidRawSensor::getSensorEventData(const std::vector<uint8_t> &message,
switch (rec.type) {
case TYPE_FLOAT:
if (v > rec.maxValue || v < rec.minValue) {
- return false;
+ valid = false;
}
- event->data[rec.index] = rec.a * (v + rec.b);
+ event.data[rec.index] = rec.a * (v + rec.b);
break;
case TYPE_INT64:
if (v > rec.maxValue || v < rec.minValue) {
- return false;
+ valid = false;
}
- event->u64.data[rec.index] = v + rec.b;
+ event.u64.data[rec.index] = v + rec.b;
break;
case TYPE_ACCURACY:
- event->magnetic.status = (v & 0xFF) + rec.b;
+ event.magnetic.status = (v & 0xFF) + rec.b;
break;
}
}
-
- return true;
+ if (!valid) {
+ LOG_V << "Range error observed in decoding, discard" << LOG_ENDL;
+ }
+ event.timestamp = -1;
+ generateEvent(event);
}
std::string HidRawSensor::dump() const {
@@ -1109,15 +997,11 @@ std::string HidRawSensor::dump() const {
<< " fifoSize: " << mFeatureInfo.fifoSize << LOG_ENDL
<< " fifoMaxSize: " << mFeatureInfo.fifoMaxSize << LOG_ENDL
<< " reportModeFlag: " << mFeatureInfo.reportModeFlag << LOG_ENDL
- << " isWakeUp: " << (mFeatureInfo.isWakeUp ? "true" : "false") << LOG_ENDL;
-
- ss << " uniqueId: " << std::hex << std::setfill('0');
- for (auto d : mFeatureInfo.uniqueId) {
- ss << std::setw(2) << static_cast<int>(d) << " ";
- }
- ss << std::dec << std::setfill(' ') << LOG_ENDL;
+ << " isWakeUp: " << (mFeatureInfo.isWakeUp ? "true" : "false") << LOG_ENDL
+ << " uniqueId: " << mFeatureInfo.uniqueId << LOG_ENDL
+ << " uuid: ";
- ss << " uuid: " << std::hex << std::setfill('0');
+ ss << std::hex << std::setfill('0');
for (auto d : mFeatureInfo.uuid) {
ss << std::setw(2) << static_cast<int>(d) << " ";
}
@@ -1135,11 +1019,7 @@ std::string HidRawSensor::dump() const {
ss << " Power state ";
if (mPowerStateId >= 0) {
ss << "found, id: " << mPowerStateId
- << " bit offset: " << mPowerStateBitOffset
- << " bit size: " << mPowerStateBitSize
- << " power off index: " << mPowerStateOffIndex
- << " power on index: " << mPowerStateOnIndex
- << LOG_ENDL;
+ << " offset: " << mPowerStateOffset << LOG_ENDL;
} else {
ss << "not found" << LOG_ENDL;
}
@@ -1147,11 +1027,7 @@ std::string HidRawSensor::dump() const {
ss << " Reporting state ";
if (mReportingStateId >= 0) {
ss << "found, id: " << mReportingStateId
- << " bit offset: " << mReportingStateBitOffset
- << " bit size: " << mReportingStateBitSize
- << " disable index: " << mReportingStateDisableIndex
- << " enable index: " << mReportingStateEnableIndex
- << LOG_ENDL;
+ << " offset: " << mReportingStateOffset << LOG_ENDL;
} else {
ss << "not found" << LOG_ENDL;
}
@@ -1159,8 +1035,8 @@ std::string HidRawSensor::dump() const {
ss << " Report interval ";
if (mReportIntervalId >= 0) {
ss << "found, id: " << mReportIntervalId
- << " bit offset: " << mReportIntervalBitOffset
- << " bit size: " << mReportIntervalBitSize << LOG_ENDL;
+ << " offset: " << mReportIntervalOffset
+ << " size: " << mReportIntervalSize << LOG_ENDL;
} else {
ss << "not found" << LOG_ENDL;
}
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
index 074482a8..2dd32b61 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.h
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -46,14 +46,6 @@ public:
// handle input report received
void handleInput(uint8_t id, const std::vector<uint8_t> &message);
- // get head tracker sensor event data
- bool getHeadTrackerEventData(const std::vector<uint8_t> &message,
- sensors_event_t *event);
-
- // get generic sensor event data
- bool getSensorEventData(const std::vector<uint8_t> &message,
- sensors_event_t *event);
-
// indicate if the HidRawSensor is a valid one
bool isValid() const { return mValid; };
@@ -94,7 +86,6 @@ private:
size_t fifoMaxSize;
uint32_t reportModeFlag;
bool isWakeUp;
- bool useUniqueIdForUuid;
// dynamic sensor specific
std::string uniqueId;
@@ -130,14 +121,6 @@ private:
// helper function to find sensor control feature usage from packets
bool findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets);
- // try to parse sensor description feature value to see if it matches any
- // known sensors
- void detectSensorFromDescription(const std::string &description);
-
- // try to parse sensor description feature value to see if it matches the
- // Android header tracker sensor
- bool detectAndroidHeadTrackerSensor(const std::string &description);
-
// try to parse sensor description feature value to see if it matches
// android specified custom sensor definition.
bool detectAndroidCustomSensor(const std::string &description);
@@ -149,54 +132,19 @@ private:
// process HID snesor spec defined orientation(quaternion) sensor usages.
bool processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets);
- // get the value of a report field
- template<typename ValueType>
- bool getReportFieldValue(const std::vector<uint8_t> &message,
- ReportTranslateRecord* rec, ValueType* value) {
- bool valid = true;
- int64_t v;
-
- v = (message[rec->byteOffset + rec->byteSize - 1] & 0x80) ? -1 : 0;
- for (int i = static_cast<int>(rec->byteSize) - 1; i >= 0; --i) {
- v = (v << 8) | message[rec->byteOffset + i]; // HID is little endian
- }
- if (v > rec->maxValue || v < rec->minValue) {
- valid = false;
- }
-
- switch (rec->type) {
- case TYPE_FLOAT:
- *value = rec->a * (v + rec->b);
- break;
- case TYPE_INT64:
- *value = v + rec->b;
- break;
- }
-
- return valid;
- }
-
// dump data for test/debug purpose
std::string dump() const;
// Features for control sensor
int mReportingStateId;
- unsigned int mReportingStateBitOffset;
- unsigned int mReportingStateBitSize;
- int mReportingStateDisableIndex;
- int mReportingStateEnableIndex;
+ unsigned int mReportingStateOffset;
int mPowerStateId;
- unsigned int mPowerStateBitOffset;
- unsigned int mPowerStateBitSize;
- int mPowerStateOffIndex;
- int mPowerStateOnIndex;
+ unsigned int mPowerStateOffset;
int mReportIntervalId;
- unsigned int mReportIntervalBitOffset;
- unsigned int mReportIntervalBitSize;
- double mReportIntervalScale;
- int64_t mReportIntervalOffset;
+ unsigned int mReportIntervalOffset;
+ unsigned int mReportIntervalSize;
// Input report translate table
std::vector<ReportTranslateRecord> mTranslateTable;
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
index 4b447ac1..6bf34bc8 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
@@ -39,7 +39,6 @@ HidRawSensorDaemon::HidRawSensorDaemon(DynamicSensorManager& manager)
: BaseDynamicSensorDaemon(manager) {
mDetector = new FileConnectionDetector(
this, std::string(DEV_PATH), std::string(DEV_NAME_REGEX));
- mDetector->Init();
}
BaseSensorVector HidRawSensorDaemon::createSensor(const std::string &deviceKey) {
diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h
index 8f47a850..2728b28a 100644
--- a/modules/sensors/dynamic_sensor/HidSensorDef.h
+++ b/modules/sensors/dynamic_sensor/HidSensorDef.h
@@ -77,28 +77,24 @@ enum {
};
} // namespace ReportUsage
-namespace ReportingStateUsage {
+namespace RawMinMax {
enum {
- REPORTING_STATE_NO_EVENTS = 0x0840,
- REPORTING_STATE_ALL_EVENTS = 0x0841,
- REPORTING_STATE_REPORT_THRESHOLD_EVENTS = 0x0842,
- REPORTING_STATE_REPORT_WAKE_ON_NO_EVENTS = 0x0843,
- REPORTING_STATE_REPORT_WAKE_ON_ALL_EVENTS = 0x0844,
- REPORTING_STATE_REPORT_WAKE_ON_THRESHOLD_EVENTS = 0x0845,
+ REPORTING_STATE_MIN = 0,
+ REPORTING_STATE_MAX = 5,
+ POWER_STATE_MIN = 0,
+ POWER_STATE_MAX = 5,
};
-} // namespace ReportingStateUsage
+} // namespace RawMinMax
-namespace PowerStateUsage {
+namespace StateValue {
enum {
- POWER_STATE_UNDEFINED = 0x0850,
- POWER_STATE_D0_FULL_POWER = 0x0851,
- POWER_STATE_D1_LOW_POWER = 0x0852,
- POWER_STATE_D2_STANDBY_POWER_WITH_WAKEUP = 0x0853,
- POWER_STATE_D3_SLEEP_WITH_WAKEUP = 0x0854,
- POWER_STATE_D4_POWER_OFF = 0x0855,
-};
-} // namespace PowerStateUsage
+ POWER_STATE_FULL_POWER = 1,
+ POWER_STATE_POWER_OFF = 5,
+ REPORTING_STATE_ALL_EVENT = 1,
+ REPORTING_STATE_NO_EVENT = 0,
+};
+} // StateValue
} // namespace Sensor
} // namespace Hid
#endif // HID_SENSOR_DEF_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/Android.bp b/modules/sensors/dynamic_sensor/HidUtils/Android.bp
index 5823c794..bbed0327 100644
--- a/modules/sensors/dynamic_sensor/HidUtils/Android.bp
+++ b/modules/sensors/dynamic_sensor/HidUtils/Android.bp
@@ -45,7 +45,6 @@ cc_library {
"HidParser.cpp",
"HidReport.cpp",
"HidTree.cpp",
- "HidUtils.cpp",
],
export_include_dirs: ["."],
@@ -100,20 +99,3 @@ cc_test_host {
local_include_dirs: ["test"],
}
-
-//
-// Test for HidUtils
-//
-cc_test_host {
- name: "hid_utils_test",
- defaults: ["hid_defaults"],
-
- srcs: ["test/CopyBitsTest.cpp"],
-
- shared_libs: [
- "libhidparser",
- ],
-
- local_include_dirs: ["test"],
-}
-
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
index 63210200..264f13c2 100644
--- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
@@ -240,23 +240,14 @@ std::vector<HidParser::ReportPacket> HidParser::convertGroupToPacket(
auto logical = r.getLogicalRange();
auto physical = r.getPhysicalRange();
- double scale;
- if ((physical.first != physical.second) &&
- (logical.first != logical.second)) {
- scale = static_cast<double>(physical.second - physical.first)
- / (logical.second - logical.first);
- } else {
- scale = (physical.first != 0) ? physical.first : 1.0;
- }
+ int64_t offset = physical.first - logical.first;
+ double scale = static_cast<double>((physical.second - physical.first))
+ / (logical.second - logical.first);
scale *= r.getExponentValue();
- int64_t offset =
- (physical.first * r.getExponentValue() / scale) -
- logical.first;
ReportItem digest = {
.usage = r.getFullUsage(),
.id = id,
- .usageVector = r.getUsageVector(),
.minRaw = logical.first,
.maxRaw = logical.second,
.a = scale,
@@ -325,5 +316,4 @@ std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digest
os << LOG_ENDL;
return os;
}
-
} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
index cb4a92a8..4ef5ec6c 100644
--- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
@@ -89,7 +89,6 @@ struct HidParser::ReportItem {
unsigned int usage;
unsigned int id;
int type; // feature, input or output
- std::vector<unsigned int> usageVector;
int64_t minRaw;
int64_t maxRaw;
@@ -174,7 +173,6 @@ struct HidParser::ReportPacket {
};
std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digest2);
-
} // namespace HidUtil
#endif // HIDUTIL_HIDPARSER_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp
deleted file mode 100644
index 0cce2a39..00000000
--- a/modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "HidUtils.h"
-#include <stdint.h>
-#include <algorithm>
-
-namespace HidUtil {
-
-void copyBits(const void *src, void *dst, size_t dst_size,
- unsigned int src_bit_offset, unsigned int dst_bit_offset,
- unsigned int bit_count) {
- const uint8_t *p_src;
- uint8_t *p_dst;
- uint8_t dst_mask;
- unsigned int bits_rem;
- unsigned int bit_block_count;
-
- // Do nothing if copying past the end of the destination buffer.
- if ((static_cast<size_t>(dst_bit_offset) > (8 * dst_size)) ||
- (static_cast<size_t>(bit_count) > (8 * dst_size)) ||
- (static_cast<size_t>(dst_bit_offset + bit_count) > (8 * dst_size))) {
- return;
- }
-
- // Copy bits from source to destination buffer.
- p_src = static_cast<const uint8_t*>(src) + (src_bit_offset / 8);
- src_bit_offset = src_bit_offset % 8;
- p_dst = static_cast<uint8_t*>(dst) + (dst_bit_offset / 8);
- dst_bit_offset = dst_bit_offset % 8;
- bits_rem = bit_count;
- while (bits_rem > 0) {
- // Determine the size of the next block of bits to copy. The block must
- // not cross a source or desintation byte boundary.
- bit_block_count = std::min(bits_rem, 8 - src_bit_offset);
- bit_block_count = std::min(bit_block_count, 8 - dst_bit_offset);
-
- // Determine the destination bit block mask.
- dst_mask = ((1 << bit_block_count) - 1) << dst_bit_offset;
-
- // Copy the block of bits.
- *p_dst = (*p_dst & ~dst_mask) |
- (((*p_src >> src_bit_offset) << dst_bit_offset) & dst_mask);
-
- // Advance past the block of copied bits in the source.
- src_bit_offset += bit_block_count;
- p_src += src_bit_offset / 8;
- src_bit_offset = src_bit_offset % 8;
-
- // Advance past the block of copied bits in the destination.
- dst_bit_offset += bit_block_count;
- p_dst += dst_bit_offset / 8;
- dst_bit_offset = dst_bit_offset % 8;
-
- // Decrement the number of bits remaining.
- bits_rem -= bit_block_count;
- }
-}
-
-} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidUtils.h b/modules/sensors/dynamic_sensor/HidUtils/HidUtils.h
deleted file mode 100644
index 54aa31e9..00000000
--- a/modules/sensors/dynamic_sensor/HidUtils/HidUtils.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 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 HIDUTIL_HIDUTILS_H_
-#define HIDUTIL_HIDUTILS_H_
-
-#include <stddef.h>
-
-namespace HidUtil {
-
-void copyBits(const void *src, void *dst, size_t dst_size,
- unsigned int src_bit_offset, unsigned int dst_bit_offset,
- unsigned int bit_count);
-
-} // namespace HidUtil
-
-#endif // HIDUTIL_HIDUTILS_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp
deleted file mode 100644
index 1b1ca709..00000000
--- a/modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "HidUtils.h"
-#include <gtest/gtest.h>
-
-using HidUtil::copyBits;
-
-TEST(CopyBitsTest, CopyBits) {
- const struct {
- uint32_t src;
- uint32_t dst;
- int src_bit_offset;
- int dst_bit_offset;
- int bit_count;
- uint32_t expected_dst;
- } kTestVectorList[] = {
- { 0x00000005, 0x00000000, 0, 0, 8, 0x00000005 },
- { 0x00000005, 0x00000000, 0, 4, 8, 0x00000050 },
- { 0x0000000C, 0x00000020, 0, 4, 8, 0x000000C0 },
- { 0x00000005, 0x0000F02F, 0, 4, 8, 0x0000F05F },
- { 0x12345678, 0x87654321, 5, 11, 17, 0x8D159B21 },
- { 0x12345678, 0x87654321, 11, 5, 17, 0x8748D141 },
- };
-
- for (auto test_vector : kTestVectorList) {
- uint32_t dst = test_vector.dst;
- copyBits(&(test_vector.src), &dst, sizeof(dst),
- test_vector.src_bit_offset, test_vector.dst_bit_offset,
- test_vector.bit_count);
- EXPECT_EQ(test_vector.expected_dst, dst);
- }
-}
-
-TEST(CopyBitsTest, Overflow) {
- const struct {
- uint32_t src;
- uint32_t dst;
- unsigned int src_bit_offset;
- unsigned int dst_bit_offset;
- unsigned int bit_count;
- uint32_t expected_dst;
- } kTestVectorList[] = {
- { 0x000000FF, 0x00000000, 0, 0, 8, 0x000000FF },
- { 0x000000FF, 0x00000000, 0, 24, 8, 0xFF000000 },
- { 0x000000FF, 0x00000000, 0, 25, 8, 0x00000000 },
- { 0x000000FF, 0x00000000, 0, 32, 8, 0x00000000 },
- { 0x000000FF, 0x00000000, 0, UINT_MAX, 8, 0x00000000 },
- { 0x000000FF, 0x00000000, 0, 8, UINT_MAX, 0x00000000 },
- };
-
- for (auto test_vector : kTestVectorList) {
- uint32_t dst = test_vector.dst;
- copyBits(&(test_vector.src), &dst, sizeof(dst),
- test_vector.src_bit_offset, test_vector.dst_bit_offset,
- test_vector.bit_count);
- EXPECT_EQ(test_vector.expected_dst, dst);
- }
-}
-
diff --git a/modules/sensors/dynamic_sensor/README.md b/modules/sensors/dynamic_sensor/README.md
deleted file mode 100644
index 5d5bd6d3..00000000
--- a/modules/sensors/dynamic_sensor/README.md
+++ /dev/null
@@ -1,153 +0,0 @@
-# Dynamic Sensors
-
-[TOC]
-
-## Links
-
-* [Sensor HAL dynamic sensor support](https://source.android.com/devices/sensors/sensors-hal2#dynamic-sensors)
-* [Sensors Multi-HAL](https://source.android.com/devices/sensors/sensors-multihal)
-
-## Adding dynamic sensor support to a device
-
-A few files need to be modified to add dynamic sensor support to a device. The
-dynamic sensor HAL must be enabled in the device product makefile and in the
-sensor sub-HAL configuration file, raw HID devices must be configured, and raw
-HID device and dynamic sensor property permissions must be set up in the SELinux
-policy files.
-
-```shell
-acme-co$ git -C device/acme/rocket-phone diff
-diff --git a/sensor_hal/hals.conf b/sensor_hal/hals.conf
-index a1f4b8b..d112546 100644
---- a/sensor_hal/hals.conf
-+++ b/sensor_hal/hals.conf
-@@ -1 +1,2 @@
-+sensors.dynamic_sensor_hal.so
- sensors.rocket-phone.so
-diff --git a/rocket-phone.mk b/rocket-phone.mk
-index 3fc8538..b1bd8a1 100644
---- a/rocket-phone.mk
-+++ b/rocket-phone.mk
-@@ -73,6 +73,9 @@
- PRODUCT_PACKAGES += sensors.rocket-phone
- PRODUCT_PACKAGES += thruster_stats
-
-+# Add the dynamic sensor HAL.
-+PRODUCT_PACKAGES += sensors.dynamic_sensor_hal
-+
- # Only install test tools in debug build or eng build.
- ifneq ($(filter userdebug eng,$(TARGET_BUILD_VARIANT)),)
- PRODUCT_PACKAGES += thruster_test
-diff --git a/conf/ueventd.rc b/conf/ueventd.rc
-index 88ee00b..2f03009 100644
---- a/conf/ueventd.rc
-+++ b/conf/ueventd.rc
-@@ -209,3 +209,7 @@
-
- # Thrusters
- /dev/thruster* 0600 system system
-+
-+# Raw HID devices
-+/dev/hidraw* 0660 system system
-+
-diff --git a/sepolicy/sensor_hal.te b/sepolicy/sensor_hal.te
-index 0797253..22a4208 100644
---- a/sepolicy/sensor_hal.te
-+++ b/sepolicy/sensor_hal.te
-@@ -52,6 +52,9 @@
- # Allow sensor HAL to read thruster state.
- allow hal_sensors_default thruster_state:file r_file_perms;
-
-+# Allow access for dynamic sensor properties.
-+get_prop(hal_sensors_default, vendor_dynamic_sensor_prop)
-+
-+# Allow access to raw HID devices for dynamic sensors.
-+allow hal_sensors_default device:dir r_dir_perms;
-+allow hal_sensors_default hidraw_device:chr_file rw_file_perms;
-+
- #
- # Thruster sensor enforcements.
- #
-diff --git a/sepolicy/device.te b/sepolicy/device.te
-index bc3c947..bad0be0 100644
---- a/sepolicy/device.te
-+++ b/sepolicy/device.te
-@@ -55,3 +55,7 @@
-
- # Thruster
- type thruster_device, dev_type;
-+
-+# Raw HID device
-+type hidraw_device, dev_type;
-+
-diff --git a/sepolicy/property.te b/sepolicy/property.te
-index 4b671a4..bb0894f 100644
---- a/sepolicy/property.te
-+++ b/sepolicy/property.te
-@@ -49,3 +49,7 @@
-
- # Thruster
- vendor_internal_prop(vendor_thruster_debug_prop)
-+
-+# Dynamic sensor
-+vendor_internal_prop(vendor_dynamic_sensor_prop)
-+
-diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
-index bc03a78..ff401dc 100644
---- a/sepolicy/file_contexts
-+++ b/sepolicy/file_contexts
-@@ -441,3 +441,7 @@
- /dev/thruster-fuel u:object_r:thruster_device:s0
- /dev/thruster-output u:object_r:thruster_device:s0
- /dev/thruster-telemetry u:object_r:thruster_device:s0
-+
-+# Raw HID device
-+/dev/hidraw[0-9]* u:object_r:hidraw_device:s0
-+
-diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
-index 5d2f018..18a6059 100644
---- a/sepolicy/property_contexts
-+++ b/sepolicy/property_contexts
-@@ -104,3 +104,7 @@
-
- # Thruster
- vendor.thruster.debug u:object_r:vendor_thruster_debug_prop:s0
-+
-+# Dynamic sensor
-+vendor.dynamic_sensor. u:object_r:vendor_dynamic_sensor_prop:s0
-+
-acme-co$
-```
-
-Once the file modifications are made, rebuild and flash. The dynamic sensor HAL
-should be initialized and appear in the sensor service.
-
-```shell
-acme-co$ make -j28 && fastboot flashall
-.
-.
-.
-acme-co$ adb logcat -d | grep DynamicSensorHal
-12-15 18:18:45.735 791 791 D DynamicSensorHal: DynamicSensorsSubHal::getSensorsList_2_1 invoked.
-12-15 18:18:47.474 791 791 D DynamicSensorHal: DynamicSensorsSubHal::initialize invoked.
-acme-co$ adb shell dumpsys sensorservice | grep Dynamic
-0000000000) Dynamic Sensor Manager | Google | ver: 1 | type: android.sensor.dynamic_sensor_meta(32) | perm: n/a | flags: 0x00000007
-Dynamic Sensor Manager (handle=0x00000000, connections=1)
- Dynamic Sensor Manager 0x00000000 | status: active | pending flush events 0
-acme-co$ adb logcat -c
-acme-co$
-```
-
-When a dynamic sensor is paired with the device (e.g., Bluetooth rocket buds),
-it will appear in the sensor service.
-
-```shell
-acme-co$ adb logcat -d | grep "DynamicSensorHal\|hidraw\|Rocket"
-12-15 18:19:55.268 157 157 I hid-generic 0003: 1234:5678.0001: hidraw0: BLUETOOTH HID v0.00 Device [RocketBuds] on
-12-15 18:19:55.235 791 809 E DynamicSensorHal: return 1 sensors
-12-15 18:19:56.239 1629 1787 I SensorService: Dynamic sensor handle 0x1 connected, type 65536, name RocketBuds
-acme-co$ adb shell dumpsys sensorservice | grep Rocket
-0x00000001) RocketBuds | BLUETOOTH 1234:1234 | ver: 1 | type: com.google.hardware.sensor.hid_dynamic.headtracker(65536) | perm: n/a | flags: 0x00000020
-acme-co$
-```
-
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index fe921d69..39c0fb5c 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -460,41 +460,6 @@ static unsigned int populate_sample_rates_from_profile(const alsa_device_profile
return num_sample_rates;
}
-static bool are_all_devices_found(unsigned int num_devices_to_find,
- const int cards_to_find[],
- const int devices_to_find[],
- unsigned int num_devices,
- const int cards[],
- const int devices[]) {
- for (unsigned int i = 0; i < num_devices_to_find; ++i) {
- unsigned int j = 0;
- for (; j < num_devices; ++j) {
- if (cards_to_find[i] == cards[j] && devices_to_find[i] == devices[j]) {
- break;
- }
- }
- if (j >= num_devices) {
- return false;
- }
- }
- return true;
-}
-
-static bool are_devices_the_same(unsigned int left_num_devices,
- const int left_cards[],
- const int left_devices[],
- unsigned int right_num_devices,
- const int right_cards[],
- const int right_devices[]) {
- if (left_num_devices != right_num_devices) {
- return false;
- }
- return are_all_devices_found(left_num_devices, left_cards, left_devices,
- right_num_devices, right_cards, right_devices) &&
- are_all_devices_found(right_num_devices, right_cards, right_devices,
- left_num_devices, left_cards, left_devices);
-}
-
/*
* HAl Functions
*/
@@ -583,11 +548,10 @@ static void stream_dump_alsa_devices(const struct listnode *alsa_devices, int fd
list_for_each(node, alsa_devices) {
struct alsa_device_info *device_info =
node_to_item(node, struct alsa_device_info, list_node);
- const char* direction = device_info->profile.direction == PCM_OUT ? "Output" : "Input";
- dprintf(fd, "%s Profile %zu:\n", direction, i);
+ dprintf(fd, "Output Profile %zu:\n", i);
profile_dump(&device_info->profile, fd);
- dprintf(fd, "%s Proxy %zu:\n", direction, i);
+ dprintf(fd, "Output Proxy %zu:\n", i);
proxy_dump(&device_info->proxy, fd);
}
}
@@ -1684,13 +1648,6 @@ static int adev_create_audio_patch(struct audio_hw_device *dev,
saved_devices[num_saved_devices++] = device_info->profile.device;
}
- if (are_devices_the_same(
- num_configs, cards, devices, num_saved_devices, saved_cards, saved_devices)) {
- // The new devices are the same as original ones. No need to update.
- stream_unlock(lock);
- return 0;
- }
-
device_lock(adev);
stream_standby_l(alsa_devices, out == NULL ? &in->standby : &out->standby);
device_unlock(adev);