diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-15 21:48:15 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-15 21:48:15 +0000 |
commit | 7b65b4bfe2b72e5b873065e0e399375d2e31a530 (patch) | |
tree | b69723eebf023f54d0e71be94f0d74a98cbcf77e | |
parent | e820815d1e20a4bb877a23b3fac11b0735d110e4 (diff) | |
parent | 07c80fdaa0340d60e5be2ceff31037712859412b (diff) | |
download | libhardware-android12-mainline-tzdata3-release.tar.gz |
Snap for 8730993 from 07c80fdaa0340d60e5be2ceff31037712859412b to mainline-tzdata3-releaseaml_tz3_314012070aml_tz3_314012050aml_tz3_314012010aml_tz3_313110000aml_tz3_312511020aml_tz3_312511010aml_tz3_312410020aml_tz3_312410010android12-mainline-tzdata3-releaseaml_tz3_314012010
Change-Id: I1b36d8124dd00566a7175f4d6a33da350556bb70
32 files changed, 365 insertions, 1409 deletions
@@ -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, @@ -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 ®ex); 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); |