From 74a845f8c4885a37593299c54043ef061c280ec0 Mon Sep 17 00:00:00 2001 From: jiabin Date: Wed, 5 Jan 2022 19:06:30 +0000 Subject: Set standby as false when the stream is started successfully. When the audio patch is created and the stream is started, set the standby as false. In that case, if there is a simultaneous request for read or write data, it is no need to start the stream again. Bug: 212509560 Test: repo steps in the bug Change-Id: Ic3dbab3134bc761271b6b2ac8619135ef08075bc --- modules/usbaudio/audio_hal.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index fe921d69..616c4a62 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -1723,10 +1723,16 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, if (!wasStandby) { device_lock(adev); if (in != NULL) { - start_input_stream(in); + ret = start_input_stream(in); + if (!ret) { + in->standby = false; + } } if (out != NULL) { - start_output_stream(out); + ret = start_output_stream(out); + if (!ret) { + out->standby = false; + } } device_unlock(adev); } -- cgit v1.2.3 From 3e805478fb3dbde609c38750d4beeeabd4a36d51 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Mon, 13 Jun 2022 17:52:48 +0000 Subject: Remove explicit dependency on libdl A dependency to libdl is added by default by the build system based on system_dynamic_libs property. Test: m libhardware Change-Id: I4bc1a7cb4af2c49d6f1343843cf86c436294bed7 --- Android.bp | 1 - 1 file changed, 1 deletion(-) diff --git a/Android.bp b/Android.bp index acaeb25d..d11615bd 100644 --- a/Android.bp +++ b/Android.bp @@ -74,7 +74,6 @@ cc_library_shared { shared_libs: [ "libcutils", "liblog", - "libdl", "libvndksupport", ], cflags: [ -- cgit v1.2.3 From 4db625386f29aa48fd9fd8a08582a60deb1c5580 Mon Sep 17 00:00:00 2001 From: William Escande Date: Mon, 22 Aug 2022 11:27:59 -0700 Subject: [Bluetooth apex] Use new apex name The Bluetooth apex name is now called com.android.btservices Bug: 243054261 Test: Build Change-Id: Ie016fa354f5c9516b2f9a671f2235787f92da37d --- Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android.bp b/Android.bp index a34c7901..e567ccae 100644 --- a/Android.bp +++ b/Android.bp @@ -60,7 +60,7 @@ cc_library_headers { }, apex_available: [ "//apex_available:platform", - "com.android.bluetooth", + "com.android.btservices", "com.android.media.swcodec", ], min_sdk_version: "29", -- cgit v1.2.3 From f4def6edb59d19c4d277f7f5b5d8a2ef897e29b5 Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Wed, 24 Aug 2022 23:21:27 +0000 Subject: Clarify and clean up dynamic_sensor documentation Test: n/a Change-Id: I0b0226b1fce940bd37b8d8a1f72123948ff1fe0a --- modules/sensors/dynamic_sensor/README.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/modules/sensors/dynamic_sensor/README.md b/modules/sensors/dynamic_sensor/README.md index 5d5bd6d3..8af15a90 100644 --- a/modules/sensors/dynamic_sensor/README.md +++ b/modules/sensors/dynamic_sensor/README.md @@ -11,9 +11,9 @@ 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. +sensor sub-HAL configuration file, support for raw HID devices must be configured +in the Linux kernel (`CONFIG_HIDRAW=y`), and SELinux policy files must be updated +to provide the necessary permissions. Example changes are provided below. ```shell acme-co$ git -C device/acme/rocket-phone diff @@ -123,10 +123,8 @@ 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$ build_and_flash_android +... 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. @@ -134,8 +132,6 @@ 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), @@ -145,9 +141,9 @@ it will appear in the sensor service. 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 +12-15 18:19:56.239 1629 1787 I SensorService: Dynamic sensor handle 0x1 connected, type 37, name RocketBuds +acme-co$ adb shell dumpsys sensorservice | grep head_tracker +0x00000001) RocketBuds | BLUETOOTH 1234:5678 | ver: 1 | type: android.sensor.head_tracker(37) | perm: n/a | flags: 0x00000020 acme-co$ ``` -- cgit v1.2.3 From 7aad531bc9b0b4b52d353ddf9a172dcff1ab4c20 Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Wed, 7 Sep 2022 19:34:47 +0000 Subject: dynamic_sensor: Improve error logging Correctly pass errno to strerror() rather than the return value, which will always be -1 on error. Fixes: 245585769 Test: build only Change-Id: Iae1170949f3b2a0286ef8b9ddf26c74a6cee6783 --- modules/sensors/dynamic_sensor/HidRawDevice.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawDevice.cpp b/modules/sensors/dynamic_sensor/HidRawDevice.cpp index 2588483a..6032ed95 100644 --- a/modules/sensors/dynamic_sensor/HidRawDevice.cpp +++ b/modules/sensors/dynamic_sensor/HidRawDevice.cpp @@ -204,7 +204,7 @@ bool HidRawDevice::getFeature(uint8_t id, std::vector *out) { int res = ::ioctl(mDevFd, HIDIOCGFEATURE(size), mIoBuffer.data()); if (res < 0) { LOG_E << "HidRawDevice::getFeature: feature " << static_cast(id) - << " ioctl returns " << res << " (" << ::strerror(res) << ")" << LOG_ENDL; + << " ioctl returned " << res << ", errno: " << ::strerror(errno) << LOG_ENDL; return false; } @@ -249,8 +249,8 @@ bool HidRawDevice::setFeature(uint8_t id, const std::vector &in) { std::copy(in.begin(), in.end(), &mIoBuffer[1]); int res = ::ioctl(mDevFd, HIDIOCSFEATURE(size), mIoBuffer.data()); if (res < 0) { - LOG_E << "HidRawDevice::setFeature: feature " << id << " ioctl returns " << res - << " (" << ::strerror(res) << ")" << LOG_ENDL; + LOG_E << "HidRawDevice::setFeature: feature " << id << " ioctl returned " << res + << ", errno: " << ::strerror(errno) << LOG_ENDL; return false; } return true; @@ -287,8 +287,8 @@ bool HidRawDevice::sendReport(uint8_t id, std::vector &data) { res = ::write(mDevFd, data.data(), size); } if (res < 0) { - LOG_E << "HidRawDevice::sendReport: output " << id << " write returns " << res - << " (" << ::strerror(res) << ")" << LOG_ENDL; + LOG_E << "HidRawDevice::sendReport: output " << id << " write returned " + << res << ", errno: " << ::strerror(errno) << LOG_ENDL; return false; } return true; @@ -302,8 +302,8 @@ bool HidRawDevice::receiveReport(uint8_t *id, std::vector *data) { uint8_t buffer[256]; int res = ::read(mDevFd, buffer, 256); if (res < 0) { - LOG_E << "HidRawDevice::receiveReport: read returns " << res - << " (" << ::strerror(res) << ")" << LOG_ENDL; + LOG_E << "HidRawDevice::receiveReport: read returned " << res + << ", errno: " << ::strerror(errno) << LOG_ENDL; return false; } -- cgit v1.2.3 From d4085b7193e2489954b6c0aa5620837c795a505c Mon Sep 17 00:00:00 2001 From: Manish Kushwaha Date: Fri, 9 Sep 2022 16:36:13 +0000 Subject: [dynamic_sensor] correctly interpret HID data specifically, interpret HID data value as unsigned if minValue is positive Fix: 238391386 Test: See "Testing Done" in comments in ag/19889364 Change-Id: I715c2189ad90ee71e022ae131354354157694556 --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 5 ++++- modules/sensors/dynamic_sensor/HidRawSensor.h | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 3759e7e9..c90f4f1a 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -1066,7 +1066,10 @@ bool HidRawSensor::getHeadTrackerEventData(const std::vector &message, bool HidRawSensor::getSensorEventData(const std::vector &message, sensors_event_t *event) { for (const auto &rec : mTranslateTable) { - int64_t v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0; + int64_t v = 0; + if (rec.minValue < 0) { + v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0; + } for (int i = static_cast(rec.byteSize) - 1; i >= 0; --i) { v = (v << 8) | message[rec.byteOffset + i]; // HID is little endian } diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index 074482a8..e4564a0f 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -154,9 +154,11 @@ private: bool getReportFieldValue(const std::vector &message, ReportTranslateRecord* rec, ValueType* value) { bool valid = true; - int64_t v; + int64_t v = 0; + if (rec->minValue < 0) { + v = (message[rec->byteOffset + rec->byteSize - 1] & 0x80) ? -1 : 0; + } - v = (message[rec->byteOffset + rec->byteSize - 1] & 0x80) ? -1 : 0; for (int i = static_cast(rec->byteSize) - 1; i >= 0; --i) { v = (v << 8) | message[rec->byteOffset + i]; // HID is little endian } -- cgit v1.2.3 From 8b0619b47dcfb49e2269691439cb4c6a33bbb00b Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Fri, 7 Oct 2022 11:28:47 -0700 Subject: Modify a data structure into a union. The new 6.0 kernel headers changed all variable length structures from [0] to []. This causes a clang warning to trigger, so rewrite the affected data structure using a union to avoid having a variable sized array in the middle of the structure. Test: Builds. Change-Id: I60c6d31a93566c4aa9f7501f39f88543ee76ce91 --- modules/sensors/dynamic_sensor/ConnectionDetector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp index 85b99017..99dab5b0 100644 --- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp +++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp @@ -194,9 +194,9 @@ void FileConnectionDetector::handleInotifyData(ssize_t len, const char *data) { } bool FileConnectionDetector::readInotifyData() { - struct { + union { struct inotify_event ev; - char padding[NAME_MAX + 1]; + char raw[sizeof(inotify_event) + NAME_MAX + 1]; } buffer; bool ret = true; -- cgit v1.2.3 From 9a056455f2218695f8fce5f25f8374916229656e Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Mon, 31 Oct 2022 23:09:50 +0000 Subject: Increase dynamic sensor op timeout to 1.6 sec Minimizes intermittent failures when a device is in sniff mode. Fixes: 245881714 Test: enable/disable with spatial audio feature enabled Change-Id: I5fb5b9ff37a6f8a245678c87ee82e2032dc845f2 --- modules/sensors/dynamic_sensor/DynamicSensorManager.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h index b8a73203..2cae1208 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h @@ -125,10 +125,11 @@ private: // daemons std::vector> mDaemonVector; - // Sensor operation queue. Calls to the sensor HAL must complete within 1 - // second. + // Sensor operation queue. Calls to the sensor HAL should complete within ~1 + // second, but to permit delayed replies due to sniff mode, etc., we use a + // slightly longer timeout here. static constexpr std::chrono::milliseconds - kSensorOpTimeout = std::chrono::milliseconds(900); + kSensorOpTimeout = std::chrono::milliseconds(1600); std::mutex mSensorOpQueueLock; std::queue>> mSensorOpQueue; uint64_t mNextSensorOpIndex = 0; -- cgit v1.2.3 From 690e02aa2c89d6bb79b4127de960c72595983fb8 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Mon, 14 Nov 2022 19:13:56 +0000 Subject: Make libhardware host_supported This requires dropping a header file and avoiding a missing strlcpy API. Required for host_supported fuzzers that include this lib. Test: libsensorserviceaidl_fuzzer Bug: 205764765 Change-Id: Ib1d2851e915ed87ef2936a044e7a72bab3077f40 --- Android.bp | 4 ++++ hardware.c | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Android.bp b/Android.bp index e567ccae..7aa3a23c 100644 --- a/Android.bp +++ b/Android.bp @@ -86,6 +86,7 @@ cc_library_shared { header_libs: ["libhardware_headers"], export_header_lib_headers: ["libhardware_headers"], + host_supported: true, recovery_available: true, vendor_available: true, vndk: { @@ -93,6 +94,9 @@ cc_library_shared { support_system_process: true, }, target: { + host: { + exclude_shared_libs: ["libvndksupport"], + }, recovery: { exclude_shared_libs: ["libvndksupport"], }, diff --git a/hardware.c b/hardware.c index 6e72ce9f..d0e91e97 100644 --- a/hardware.c +++ b/hardware.c @@ -30,7 +30,7 @@ #define LOG_TAG "HAL" #include -#if !defined(__ANDROID_RECOVERY__) +#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__) #include #endif @@ -97,7 +97,7 @@ static int load(const char *id, */ handle = dlopen(path, RTLD_NOW); } else { -#if defined(__ANDROID_RECOVERY__) +#if defined(__ANDROID_RECOVERY__) || !defined(__ANDROID__) handle = dlopen(path, RTLD_NOW); #else handle = android_load_sphal_library(path, RTLD_NOW); @@ -206,8 +206,13 @@ int hw_get_module_by_class(const char *class_id, const char *inst, if (inst) snprintf(name, PATH_MAX, "%s.%s", class_id, inst); +#if defined(__ANDROID__) else strlcpy(name, class_id, PATH_MAX); +#else + else + snprintf(name, PATH_MAX, "%s", class_id); +#endif /* * Here we rely on the fact that calling dlopen multiple times on -- cgit v1.2.3 From bd9dcfcf4f3b7f148da3432761947e5be8fc5de8 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Wed, 9 Nov 2022 13:59:13 +0000 Subject: Add the second IMEI tag This CL keeps keymaster_defs.h in sync with the changes to KeymasterDefs.java. Bug: 244732345 Test: n/a Change-Id: I3dbed2c077d74ffd276ea007c165309a61f90992 --- include/hardware/keymaster_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 930aceb0..dd286d6d 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -175,6 +175,8 @@ typedef enum { attestation is requested. */ KM_TAG_IDENTITY_CREDENTIAL_KEY = KM_BOOL | 721, /* This is an identity credential key */ KM_TAG_STORAGE_KEY = KM_BOOL | 722, /* storage encryption key */ + KM_TAG_ATTESTATION_ID_SECOND_IMEI = KM_BYTES | 723, /* Used to provide the device's second + IMEI to be included in attestation */ /* Tags used only to provide data to or receive data from operations */ KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000, /* Used to provide associated data for AEAD modes. */ -- cgit v1.2.3 From 894dd49d68d960537c894a2a972f255853a45e90 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Tue, 29 Nov 2022 19:13:56 +0000 Subject: Add a LINT.IfChange to sensors_event_t If that is changed, ASensorEvent also needs to be changed. Test: na Bug: 259711109 Change-Id: If1fdedba6a73d46b64f47490a7946954c47a3b79 --- include/hardware/sensors.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index 6f4baf8f..7b844b8a 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -367,9 +367,11 @@ typedef struct { float accuracy; } heading_event_t; +// LINT.IfChange /** * Union of the various types of sensor data * that can be returned. + * This type needs to remain identical to ASensorEvent. */ typedef struct sensors_event_t { /* must be sizeof(struct sensors_event_t) */ @@ -479,6 +481,7 @@ typedef struct sensors_event_t { uint32_t reserved1[3]; } sensors_event_t; +// LINT.ThenChange (frameworks/native/include/android/sensor.h) /* see SENSOR_TYPE_META_DATA */ -- cgit v1.2.3 From 69e91793276fe00434e2d7931c8d4e7f1e36ad94 Mon Sep 17 00:00:00 2001 From: Chih-Hung Hsieh Date: Thu, 8 Dec 2022 20:13:20 -0800 Subject: Fix sizeof warnings on unusual calloc Test: make tidy-hardware-libhardware-modules-soundtrigger_subset Change-Id: If1afcd4834461a2d1f855832dc89b8ae54bd8e2f --- modules/soundtrigger/sound_trigger_hw.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c index 38212c45..cae91cab 100644 --- a/modules/soundtrigger/sound_trigger_hw.c +++ b/modules/soundtrigger/sound_trigger_hw.c @@ -246,12 +246,10 @@ static void unload_all_sound_models(struct stub_sound_trigger_device *stdev); static char *sound_trigger_keyphrase_event_alloc(sound_model_handle_t handle, struct sound_trigger_recognition_config *config, int recognition_status) { - char *data; - struct sound_trigger_phrase_recognition_event *event; - data = (char *)calloc(1, sizeof(struct sound_trigger_phrase_recognition_event)); - if (!data) + struct sound_trigger_phrase_recognition_event *event = + calloc(1, sizeof(struct sound_trigger_phrase_recognition_event)); + if (!event) return NULL; - event = (struct sound_trigger_phrase_recognition_event *)data; event->common.status = recognition_status; event->common.type = SOUND_MODEL_TYPE_KEYPHRASE; event->common.model = handle; @@ -279,18 +277,16 @@ static char *sound_trigger_keyphrase_event_alloc(sound_model_handle_t handle, event->common.audio_config.sample_rate = 16000; event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO; event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT; - return data; + return (char*) event; } static char *sound_trigger_generic_event_alloc(sound_model_handle_t handle, struct sound_trigger_recognition_config *config, int recognition_status) { - char *data; - struct sound_trigger_generic_recognition_event *event; - data = (char *)calloc(1, sizeof(struct sound_trigger_generic_recognition_event)); - if (!data) + struct sound_trigger_generic_recognition_event *event = + calloc(1, sizeof(struct sound_trigger_generic_recognition_event)); + if (!event) return NULL; - event = (struct sound_trigger_generic_recognition_event *)data; event->common.status = recognition_status; event->common.type = SOUND_MODEL_TYPE_GENERIC; event->common.model = handle; @@ -301,7 +297,7 @@ static char *sound_trigger_generic_event_alloc(sound_model_handle_t handle, event->common.audio_config.sample_rate = 16000; event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO; event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT; - return data; + return (char*) event; } void send_event_with_handle(sound_model_handle_t* model_handle_str, @@ -338,15 +334,13 @@ void send_event_with_handle(sound_model_handle_t* model_handle_str, ALOGI("Unknown Sound Model Type, No Event to Send"); } } else if (event_type == EVENT_SOUND_MODEL) { - char *data; - data = (char *)calloc(1, sizeof(struct sound_trigger_model_event)); - if (!data) { + struct sound_trigger_model_event *event = + calloc(1, sizeof(struct sound_trigger_model_event)); + if (!event) { ALOGW("%s Could not allocate event", __func__); return; } - struct sound_trigger_model_event *event; - event = (struct sound_trigger_model_event *)data; event->status = SOUND_MODEL_STATUS_UPDATED; event->model = model_context->model_handle; if (event) { -- cgit v1.2.3 From 46fd7e6077c4380ee65d136bd312782a306e1314 Mon Sep 17 00:00:00 2001 From: Theodore Dubois Date: Mon, 12 Dec 2022 10:49:08 -0800 Subject: Support HAL_PIXEL_FORMAT_BLOB in default gralloc Test: manual, ran scrcpy with codec2's blob allocator Change-Id: I647ed5b0e9df4920e4a02686185956aa71ee806e --- modules/gralloc/gralloc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp index 87bda975..f7ea01cf 100644 --- a/modules/gralloc/gralloc.cpp +++ b/modules/gralloc/gralloc.cpp @@ -224,7 +224,11 @@ static int gralloc_alloc(alloc_device_t* dev, case HAL_PIXEL_FORMAT_RAW16: bytesPerPixel = 2; break; + case HAL_PIXEL_FORMAT_BLOB: + bytesPerPixel = 1; + break; default: + ALOGE("gralloc_alloc bad format %d", format); return -EINVAL; } -- cgit v1.2.3 From c5782cba4a6af3b85c7e7f1af2bbbe06d7e9b13d Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 15 Dec 2022 21:54:59 +0000 Subject: Add volume control for AOSP USB audio HAL. When the stream is open with bit-perfect output flag, the volume command may be sent to the HAL. Use volume control from the mixer when it is present. Bug: 262581771 Test: adjust volume Change-Id: I11e76450a2c3dbcad0ddbd56bd3db1ea83f10f2b --- modules/usbaudio/audio_hal.c | 96 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 616c4a62..6bf6b0d8 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -118,6 +119,13 @@ struct stream_out { audio_io_handle_t handle; // Unique constant for a stream audio_patch_handle_t patch_handle; // Patch handle for this stream + + // Mixer information used for volume handling + struct mixer* mixer; + struct mixer_ctl* volume_ctl; + int volume_ctl_num_values; + int max_volume_level; + int min_volume_level; }; struct stream_in { @@ -223,6 +231,14 @@ static const audio_channel_mask_t CHANNEL_INDEX_MASKS_MAP[FCC_24 + 1] = { }; static const int CHANNEL_INDEX_MASKS_SIZE = AUDIO_ARRAY_SIZE(CHANNEL_INDEX_MASKS_MAP); +static const char* ALL_VOLUME_CONTROL_NAMES[] = { + "PCM Playback Volume", + "Headset Playback Volume", + "Headphone Playback Volume", + "Master Playback Volume", +}; +static const int VOLUME_CONTROL_NAMES_NUM = AUDIO_ARRAY_SIZE(ALL_VOLUME_CONTROL_NAMES); + /* * Locking Helpers */ @@ -495,6 +511,45 @@ static bool are_devices_the_same(unsigned int left_num_devices, left_num_devices, left_cards, left_devices); } +static void out_stream_find_mixer_volume_control(struct stream_out* out, int card) { + out->mixer = mixer_open(card); + if (out->mixer == NULL) { + ALOGI("%s, no mixer found for card=%d", __func__, card); + return; + } + unsigned int num_ctls = mixer_get_num_ctls(out->mixer); + for (int i = 0; i < VOLUME_CONTROL_NAMES_NUM; ++i) { + for (unsigned int j = 0; j < num_ctls; ++j) { + struct mixer_ctl *ctl = mixer_get_ctl(out->mixer, j); + enum mixer_ctl_type ctl_type = mixer_ctl_get_type(ctl); + if (strcasestr(mixer_ctl_get_name(ctl), ALL_VOLUME_CONTROL_NAMES[i]) == NULL || + ctl_type != MIXER_CTL_TYPE_INT) { + continue; + } + ALOGD("%s, mixer volume control(%s) found", __func__, ALL_VOLUME_CONTROL_NAMES[i]); + out->volume_ctl_num_values = mixer_ctl_get_num_values(ctl); + if (out->volume_ctl_num_values <= 0) { + ALOGE("%s the num(%d) of volume ctl values is wrong", + __func__, out->volume_ctl_num_values); + out->volume_ctl_num_values = 0; + continue; + } + out->max_volume_level = mixer_ctl_get_range_max(ctl); + out->min_volume_level = mixer_ctl_get_range_min(ctl); + if (out->max_volume_level < out->min_volume_level) { + ALOGE("%s the max volume level(%d) is less than min volume level(%d)", + __func__, out->max_volume_level, out->min_volume_level); + out->max_volume_level = 0; + out->min_volume_level = 0; + continue; + } + out->volume_ctl = ctl; + return; + } + } + ALOGI("%s, no volume control found", __func__); +} + /* * HAl Functions */ @@ -709,7 +764,31 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream) static int out_set_volume(struct audio_stream_out *stream, float left, float right) { - return -ENOSYS; + struct stream_out *out = (struct stream_out *)stream; + int result = -ENOSYS; + stream_lock(&out->lock); + if (out->volume_ctl != NULL) { + int left_volume = + out->min_volume_level + ceil((out->max_volume_level - out->min_volume_level) * left); + int right_volume = + out->min_volume_level + ceil((out->max_volume_level - out->min_volume_level) * right); + int volumes[out->volume_ctl_num_values]; + if (out->volume_ctl_num_values == 1) { + volumes[0] = left_volume; + } else { + volumes[0] = left_volume; + volumes[1] = right_volume; + for (int i = 2; i < out->volume_ctl_num_values; ++i) { + volumes[i] = left_volume; + } + } + result = mixer_ctl_set_array(out->volume_ctl, volumes, out->volume_ctl_num_values); + if (result != 0) { + ALOGE("%s error=%d left=%f right=%f", __func__, result, left, right); + } + } + stream_unlock(&out->lock); + return result; } /* must be called with hw device and output stream mutexes locked */ @@ -965,6 +1044,10 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, list_add_tail(&out->alsa_devices, &device_info->list_node); + if ((flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE) { + out_stream_find_mixer_volume_control(out, device_info->profile.card); + } + /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger * So clear any errors that may have occurred above. */ @@ -998,6 +1081,17 @@ static void adev_close_output_stream(struct audio_hw_device *hw_dev, out->conversion_buffer = NULL; out->conversion_buffer_size = 0; + if (out->volume_ctl != NULL) { + for (int i = 0; i < out->volume_ctl_num_values; ++i) { + mixer_ctl_set_value(out->volume_ctl, i, out->max_volume_level); + } + out->volume_ctl = NULL; + } + if (out->mixer != NULL) { + mixer_close(out->mixer); + out->mixer = NULL; + } + device_lock(out->adev); list_remove(&out->list_node); out->adev->device_sample_rate = 0; -- cgit v1.2.3 From 662fe4aedae8ef10b3e8e48ab3f734ca101aa34d Mon Sep 17 00:00:00 2001 From: jiabin Date: Mon, 19 Dec 2022 19:31:36 +0000 Subject: Support opening bit-perfect output stream. When opening bit-perfect output stream, the HAL should require the HAL configuration match the request exactly. Bug: 262581771 Test: manually Change-Id: I2f79d41ad42b0c662d28667bde6ae115575d41e1 --- modules/usbaudio/audio_hal.c | 54 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 6bf6b0d8..43f8d240 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -120,6 +120,8 @@ struct stream_out { audio_patch_handle_t patch_handle; // Patch handle for this stream + bool is_bit_perfect; // True if the stream is open with bit-perfect output flag + // Mixer information used for volume handling struct mixer* mixer; struct mixer_ctl* volume_ctl; @@ -599,7 +601,8 @@ static int stream_set_new_devices(struct pcm_config *config, unsigned int num_devices, const int cards[], const int devices[], - int direction) + int direction, + bool is_bit_perfect) { int status = 0; stream_clear_devices(alsa_devices); @@ -616,7 +619,7 @@ static int stream_set_new_devices(struct pcm_config *config, __func__, cards[i], devices[i]); goto exit; } - status = proxy_prepare(&device_info->proxy, &device_info->profile, config); + status = proxy_prepare(&device_info->proxy, &device_info->profile, config, is_bit_perfect); if (status != 0) { ALOGE("%s failed to prepare device card=%d;device=%d", __func__, cards[i], devices[i]); @@ -926,6 +929,16 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, ALOGV("adev_open_output_stream() handle:0x%X, devicesSpec:0x%X, flags:0x%X, addr:%s", handle, devicesSpec, flags, address); + const bool is_bit_perfect = ((flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE); + if (is_bit_perfect && (config->format == AUDIO_FORMAT_DEFAULT || + config->sample_rate == 0 || + config->channel_mask == AUDIO_CHANNEL_NONE)) { + ALOGE("%s request bit perfect playback, config(format=%#x, sample_rate=%u, " + "channel_mask=%#x) must be specified", __func__, config->format, + config->sample_rate, config->channel_mask); + return -EINVAL; + } + struct stream_out *out; out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); @@ -980,9 +993,14 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) { proxy_config.rate = config->sample_rate; } else { + ret = -EINVAL; + if (is_bit_perfect) { + ALOGE("%s requesting bit-perfect but the sample rate(%u) is not valid", + __func__, config->sample_rate); + return ret; + } proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&device_info->profile); - ret = -EINVAL; } /* TODO: This is a problem if the input does not support this rate */ @@ -999,9 +1017,14 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, if (profile_is_format_valid(&device_info->profile, fmt)) { proxy_config.format = fmt; } else { + ret = -EINVAL; + if (is_bit_perfect) { + ALOGE("%s request bit-perfect but the format(%#x) is not valid", + __func__, config->format); + return ret; + } proxy_config.format = profile_get_default_format(&device_info->profile); config->format = audio_format_from_pcm_format(proxy_config.format); - ret = -EINVAL; } } @@ -1039,7 +1062,17 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, // and store THAT in proxy_config.channels proxy_config.channels = profile_get_closest_channel_count(&device_info->profile, out->hal_channel_count); - proxy_prepare(&device_info->proxy, &device_info->profile, &proxy_config); + if (is_bit_perfect && proxy_config.channels != out->hal_channel_count) { + ALOGE("%s request bit-perfect, but channel mask(%#x) cannot find exact match", + __func__, config->channel_mask); + return -EINVAL; + } + + ret = proxy_prepare(&device_info->proxy, &device_info->profile, &proxy_config, is_bit_perfect); + if (is_bit_perfect && ret != 0) { + ALOGE("%s failed to prepare proxy for bit-perfect playback, err=%d", __func__, ret); + return ret; + } out->config = proxy_config; list_add_tail(&out->alsa_devices, &device_info->list_node); @@ -1543,7 +1576,8 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, // and store THAT in proxy_config.channels in->config.channels = profile_get_closest_channel_count(&device_info->profile, in->hal_channel_count); - ret = proxy_prepare(&device_info->proxy, &device_info->profile, &in->config); + ret = proxy_prepare(&device_info->proxy, &device_info->profile, &in->config, + false /*require_exact_match*/); if (ret == 0) { in->standby = true; @@ -1710,6 +1744,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, struct pcm_config *config = NULL; struct stream_in *in = NULL; struct stream_out *out = NULL; + bool is_bit_perfect = false; unsigned int num_saved_devices = 0; int saved_cards[AUDIO_PATCH_PORTS_MAX]; @@ -1750,6 +1785,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, alsa_devices = &out->alsa_devices; lock = &out->lock; config = &out->config; + is_bit_perfect = out->is_bit_perfect; } // Check if the patch handle match the recorded one if a valid patch handle is passed. @@ -1798,12 +1834,14 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, struct alsa_device_info *device_info = stream_get_first_alsa_device(alsa_devices); if (device_info != NULL) saved_transferred_frames = device_info->proxy.transferred; - int ret = stream_set_new_devices(config, alsa_devices, num_configs, cards, devices, direction); + int ret = stream_set_new_devices( + config, alsa_devices, num_configs, cards, devices, direction, is_bit_perfect); if (ret != 0) { *handle = generatedPatchHandle ? AUDIO_PATCH_HANDLE_NONE : *handle; stream_set_new_devices( - config, alsa_devices, num_saved_devices, saved_cards, saved_devices, direction); + config, alsa_devices, num_saved_devices, saved_cards, saved_devices, direction, + is_bit_perfect); } else { *patch_handle = *handle; } -- cgit v1.2.3 From b264eb4bd3e9a8344e5ee59141aef5989da4d87b Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Fri, 27 Jan 2023 11:42:20 -0800 Subject: HidRawDeviceTest: Enable for device build Test: $ adb shell hidrawdevice_test /dev/hidraw0 Bug: 265754293 Change-Id: I103ebc030f012d11e977fc155fc68f884f71f518 --- modules/sensors/dynamic_sensor/Android.bp | 25 ++++++++++++++++++++++ .../dynamic_sensor/test/HidRawDeviceTest.cpp | 7 +++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp index bad60481..890da82d 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -157,3 +157,28 @@ cc_binary_host { "test/HidRawDeviceTest.cpp", ], } + +// +// Android device test for HidRawDevice and HidRawSensor +// +// Assuming lunch target 1 +// $ cd test +// $ mma -j . +// $ adb push $ANDROID_BUILD_TOP/out/target/product/generic/vendor/bin/hidrawdevice_test /vendor/bin +// $ adb shell hidrawdevice_test /dev/hidraw0 +// +cc_binary { + name: "hidrawdevice_test", + defaults: ["dynamic_sensor_defaults"], + + srcs: [ + "test/HidRawDeviceTest.cpp", + ], + + cflags: ["-DLOG_TO_CONSOLE=1"], + + local_include_dirs: [ + "test", + "HidUtils/test", + ], +} diff --git a/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp b/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp index 2a68e39a..7522ca75 100644 --- a/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp +++ b/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp @@ -38,8 +38,7 @@ public: std::unordered_set interestedUsage{ ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM}; - SP(HidRawDevice) device = - std::make_shared(std::string(devicePath), interestedUsage); + SP(HidRawDevice) device{new HidRawDevice(std::string(devicePath), interestedUsage)}; const HidDevice::HidDeviceInfo &info = device->getDeviceInfo(); LOG_V << "Sizeof descriptor: " << info.descriptor.size() << LOG_ENDL; @@ -69,8 +68,8 @@ public: // use HidRawSensor to operate the device, pick first digest // auto &reportDigest = device->mDigestVector[0]; - SP(HidRawSensor) sensor = std::make_shared( - device, reportDigest.fullUsage, reportDigest.packets); + SP(HidRawSensor) sensor{ + new HidRawSensor(device, reportDigest.fullUsage, reportDigest.packets)}; if (!sensor->isValid()) { LOG_E << "Sensor is not valid " << LOG_ENDL; -- cgit v1.2.3 From 016fa2107cebf075e15a472535691cb6fad1563b Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 15 Dec 2022 21:54:59 +0000 Subject: Add volume control for AOSP USB audio HAL. When the stream is open with bit-perfect output flag, the volume command may be sent to the HAL. Use volume control from the mixer when it is present. Bug: 262581771 Test: adjust volume Change-Id: I11e76450a2c3dbcad0ddbd56bd3db1ea83f10f2b Merged-In: I11e76450a2c3dbcad0ddbd56bd3db1ea83f10f2b --- modules/usbaudio/audio_hal.c | 96 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index fe921d69..aa4167d7 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -118,6 +119,13 @@ struct stream_out { audio_io_handle_t handle; // Unique constant for a stream audio_patch_handle_t patch_handle; // Patch handle for this stream + + // Mixer information used for volume handling + struct mixer* mixer; + struct mixer_ctl* volume_ctl; + int volume_ctl_num_values; + int max_volume_level; + int min_volume_level; }; struct stream_in { @@ -223,6 +231,14 @@ static const audio_channel_mask_t CHANNEL_INDEX_MASKS_MAP[FCC_24 + 1] = { }; static const int CHANNEL_INDEX_MASKS_SIZE = AUDIO_ARRAY_SIZE(CHANNEL_INDEX_MASKS_MAP); +static const char* ALL_VOLUME_CONTROL_NAMES[] = { + "PCM Playback Volume", + "Headset Playback Volume", + "Headphone Playback Volume", + "Master Playback Volume", +}; +static const int VOLUME_CONTROL_NAMES_NUM = AUDIO_ARRAY_SIZE(ALL_VOLUME_CONTROL_NAMES); + /* * Locking Helpers */ @@ -495,6 +511,45 @@ static bool are_devices_the_same(unsigned int left_num_devices, left_num_devices, left_cards, left_devices); } +static void out_stream_find_mixer_volume_control(struct stream_out* out, int card) { + out->mixer = mixer_open(card); + if (out->mixer == NULL) { + ALOGI("%s, no mixer found for card=%d", __func__, card); + return; + } + unsigned int num_ctls = mixer_get_num_ctls(out->mixer); + for (int i = 0; i < VOLUME_CONTROL_NAMES_NUM; ++i) { + for (unsigned int j = 0; j < num_ctls; ++j) { + struct mixer_ctl *ctl = mixer_get_ctl(out->mixer, j); + enum mixer_ctl_type ctl_type = mixer_ctl_get_type(ctl); + if (strcasestr(mixer_ctl_get_name(ctl), ALL_VOLUME_CONTROL_NAMES[i]) == NULL || + ctl_type != MIXER_CTL_TYPE_INT) { + continue; + } + ALOGD("%s, mixer volume control(%s) found", __func__, ALL_VOLUME_CONTROL_NAMES[i]); + out->volume_ctl_num_values = mixer_ctl_get_num_values(ctl); + if (out->volume_ctl_num_values <= 0) { + ALOGE("%s the num(%d) of volume ctl values is wrong", + __func__, out->volume_ctl_num_values); + out->volume_ctl_num_values = 0; + continue; + } + out->max_volume_level = mixer_ctl_get_range_max(ctl); + out->min_volume_level = mixer_ctl_get_range_min(ctl); + if (out->max_volume_level < out->min_volume_level) { + ALOGE("%s the max volume level(%d) is less than min volume level(%d)", + __func__, out->max_volume_level, out->min_volume_level); + out->max_volume_level = 0; + out->min_volume_level = 0; + continue; + } + out->volume_ctl = ctl; + return; + } + } + ALOGI("%s, no volume control found", __func__); +} + /* * HAl Functions */ @@ -709,7 +764,31 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream) static int out_set_volume(struct audio_stream_out *stream, float left, float right) { - return -ENOSYS; + struct stream_out *out = (struct stream_out *)stream; + int result = -ENOSYS; + stream_lock(&out->lock); + if (out->volume_ctl != NULL) { + int left_volume = + out->min_volume_level + ceil((out->max_volume_level - out->min_volume_level) * left); + int right_volume = + out->min_volume_level + ceil((out->max_volume_level - out->min_volume_level) * right); + int volumes[out->volume_ctl_num_values]; + if (out->volume_ctl_num_values == 1) { + volumes[0] = left_volume; + } else { + volumes[0] = left_volume; + volumes[1] = right_volume; + for (int i = 2; i < out->volume_ctl_num_values; ++i) { + volumes[i] = left_volume; + } + } + result = mixer_ctl_set_array(out->volume_ctl, volumes, out->volume_ctl_num_values); + if (result != 0) { + ALOGE("%s error=%d left=%f right=%f", __func__, result, left, right); + } + } + stream_unlock(&out->lock); + return result; } /* must be called with hw device and output stream mutexes locked */ @@ -965,6 +1044,10 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, list_add_tail(&out->alsa_devices, &device_info->list_node); + if ((flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE) { + out_stream_find_mixer_volume_control(out, device_info->profile.card); + } + /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger * So clear any errors that may have occurred above. */ @@ -998,6 +1081,17 @@ static void adev_close_output_stream(struct audio_hw_device *hw_dev, out->conversion_buffer = NULL; out->conversion_buffer_size = 0; + if (out->volume_ctl != NULL) { + for (int i = 0; i < out->volume_ctl_num_values; ++i) { + mixer_ctl_set_value(out->volume_ctl, i, out->max_volume_level); + } + out->volume_ctl = NULL; + } + if (out->mixer != NULL) { + mixer_close(out->mixer); + out->mixer = NULL; + } + device_lock(out->adev); list_remove(&out->list_node); out->adev->device_sample_rate = 0; -- cgit v1.2.3 From fea9e1be0a6c1d34c860e0b19198a85e6c234b3d Mon Sep 17 00:00:00 2001 From: jiabin Date: Mon, 19 Dec 2022 19:31:36 +0000 Subject: Support opening bit-perfect output stream. When opening bit-perfect output stream, the HAL should require the HAL configuration match the request exactly. Bug: 262581771 Test: manually Change-Id: I2f79d41ad42b0c662d28667bde6ae115575d41e1 Merged-In: I2f79d41ad42b0c662d28667bde6ae115575d41e1 --- modules/usbaudio/audio_hal.c | 54 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index aa4167d7..1bd53c27 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -120,6 +120,8 @@ struct stream_out { audio_patch_handle_t patch_handle; // Patch handle for this stream + bool is_bit_perfect; // True if the stream is open with bit-perfect output flag + // Mixer information used for volume handling struct mixer* mixer; struct mixer_ctl* volume_ctl; @@ -599,7 +601,8 @@ static int stream_set_new_devices(struct pcm_config *config, unsigned int num_devices, const int cards[], const int devices[], - int direction) + int direction, + bool is_bit_perfect) { int status = 0; stream_clear_devices(alsa_devices); @@ -616,7 +619,7 @@ static int stream_set_new_devices(struct pcm_config *config, __func__, cards[i], devices[i]); goto exit; } - status = proxy_prepare(&device_info->proxy, &device_info->profile, config); + status = proxy_prepare(&device_info->proxy, &device_info->profile, config, is_bit_perfect); if (status != 0) { ALOGE("%s failed to prepare device card=%d;device=%d", __func__, cards[i], devices[i]); @@ -926,6 +929,16 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, ALOGV("adev_open_output_stream() handle:0x%X, devicesSpec:0x%X, flags:0x%X, addr:%s", handle, devicesSpec, flags, address); + const bool is_bit_perfect = ((flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE); + if (is_bit_perfect && (config->format == AUDIO_FORMAT_DEFAULT || + config->sample_rate == 0 || + config->channel_mask == AUDIO_CHANNEL_NONE)) { + ALOGE("%s request bit perfect playback, config(format=%#x, sample_rate=%u, " + "channel_mask=%#x) must be specified", __func__, config->format, + config->sample_rate, config->channel_mask); + return -EINVAL; + } + struct stream_out *out; out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); @@ -980,9 +993,14 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) { proxy_config.rate = config->sample_rate; } else { + ret = -EINVAL; + if (is_bit_perfect) { + ALOGE("%s requesting bit-perfect but the sample rate(%u) is not valid", + __func__, config->sample_rate); + return ret; + } proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(&device_info->profile); - ret = -EINVAL; } /* TODO: This is a problem if the input does not support this rate */ @@ -999,9 +1017,14 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, if (profile_is_format_valid(&device_info->profile, fmt)) { proxy_config.format = fmt; } else { + ret = -EINVAL; + if (is_bit_perfect) { + ALOGE("%s request bit-perfect but the format(%#x) is not valid", + __func__, config->format); + return ret; + } proxy_config.format = profile_get_default_format(&device_info->profile); config->format = audio_format_from_pcm_format(proxy_config.format); - ret = -EINVAL; } } @@ -1039,7 +1062,17 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, // and store THAT in proxy_config.channels proxy_config.channels = profile_get_closest_channel_count(&device_info->profile, out->hal_channel_count); - proxy_prepare(&device_info->proxy, &device_info->profile, &proxy_config); + if (is_bit_perfect && proxy_config.channels != out->hal_channel_count) { + ALOGE("%s request bit-perfect, but channel mask(%#x) cannot find exact match", + __func__, config->channel_mask); + return -EINVAL; + } + + ret = proxy_prepare(&device_info->proxy, &device_info->profile, &proxy_config, is_bit_perfect); + if (is_bit_perfect && ret != 0) { + ALOGE("%s failed to prepare proxy for bit-perfect playback, err=%d", __func__, ret); + return ret; + } out->config = proxy_config; list_add_tail(&out->alsa_devices, &device_info->list_node); @@ -1543,7 +1576,8 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, // and store THAT in proxy_config.channels in->config.channels = profile_get_closest_channel_count(&device_info->profile, in->hal_channel_count); - ret = proxy_prepare(&device_info->proxy, &device_info->profile, &in->config); + ret = proxy_prepare(&device_info->proxy, &device_info->profile, &in->config, + false /*require_exact_match*/); if (ret == 0) { in->standby = true; @@ -1710,6 +1744,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, struct pcm_config *config = NULL; struct stream_in *in = NULL; struct stream_out *out = NULL; + bool is_bit_perfect = false; unsigned int num_saved_devices = 0; int saved_cards[AUDIO_PATCH_PORTS_MAX]; @@ -1750,6 +1785,7 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, alsa_devices = &out->alsa_devices; lock = &out->lock; config = &out->config; + is_bit_perfect = out->is_bit_perfect; } // Check if the patch handle match the recorded one if a valid patch handle is passed. @@ -1798,12 +1834,14 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, struct alsa_device_info *device_info = stream_get_first_alsa_device(alsa_devices); if (device_info != NULL) saved_transferred_frames = device_info->proxy.transferred; - int ret = stream_set_new_devices(config, alsa_devices, num_configs, cards, devices, direction); + int ret = stream_set_new_devices( + config, alsa_devices, num_configs, cards, devices, direction, is_bit_perfect); if (ret != 0) { *handle = generatedPatchHandle ? AUDIO_PATCH_HANDLE_NONE : *handle; stream_set_new_devices( - config, alsa_devices, num_saved_devices, saved_cards, saved_devices, direction); + config, alsa_devices, num_saved_devices, saved_cards, saved_devices, direction, + is_bit_perfect); } else { *patch_handle = *handle; } -- cgit v1.2.3 From 2007fd1ee67c00de57e8cd56dbe18f68b481ef60 Mon Sep 17 00:00:00 2001 From: Oystein Eftevaag Date: Wed, 1 Feb 2023 23:53:41 +0000 Subject: Enable Windows host compilation of libhardware-headers Bug: 261908998 Test: scrypt builds using MinGW Change-Id: Ica552fe1fb89c94f6ea2210a4c50d1b504929d11 --- Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Android.bp b/Android.bp index 7aa3a23c..88e0d44f 100644 --- a/Android.bp +++ b/Android.bp @@ -57,6 +57,9 @@ cc_library_headers { "libbluetooth-types-header", ], }, + windows: { + enabled: true, + }, }, apex_available: [ "//apex_available:platform", -- cgit v1.2.3 From 4e7ab5d87798889a0db6b0f0b5084648fc468b7c Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Mon, 27 Mar 2023 16:39:31 -0700 Subject: AudioParameter: Use for RemoteSubmix exiting Test: compiles Bug: 279106598 Change-Id: I50263a48584bac120c65123cd5bed09f60582089 --- modules/audio_remote_submix/audio_hw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index f96854b5..5019ae5b 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -679,7 +679,8 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) // FIXME this is using hard-coded strings but in the future, this functionality will be // converted to use audio HAL extensions required to support tunneling - if ((parms.getInt(String8("exiting"), exiting) == NO_ERROR) && (exiting > 0)) { + if ((parms.getInt(String8(AUDIO_PARAMETER_KEY_EXITING), exiting) == NO_ERROR) + && (exiting > 0)) { struct submix_audio_device * const rsxadev = audio_stream_get_submix_stream_out(stream)->dev; pthread_mutex_lock(&rsxadev->lock); -- cgit v1.2.3 From c8fbb82f0820e13ba8f22583c27c977a13b0b02b Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 28 Apr 2023 15:47:54 -0700 Subject: Add 'com.android.media' to apex_available of libhardware_headers Due to adding a dependency of libmedia_helper on libhardware_headers Bug: 278976019 Test: m Change-Id: I97df31b209630dc7fb6b46a0b0221c0d496e6375 --- Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.bp b/Android.bp index 88e0d44f..6baab685 100644 --- a/Android.bp +++ b/Android.bp @@ -64,6 +64,7 @@ cc_library_headers { apex_available: [ "//apex_available:platform", "com.android.btservices", + "com.android.media", "com.android.media.swcodec", ], min_sdk_version: "29", -- cgit v1.2.3 From 5b5e0c4552e71ba522b429d5a9e8756b7e72db60 Mon Sep 17 00:00:00 2001 From: jiabin Date: Tue, 16 May 2023 23:20:17 +0000 Subject: Use requested sample rate when it matches device sample rate. For input stream, the sample rate should be set as requested one if it matches the device sample rate and is valid. Bug: 282816698 Test: TH (cherry picked from https://android-review.googlesource.com/q/commit:abf24d3cc770f04b7ece1986fd51ce5db742a811) Merged-In: Iebee2b269062609ff7bcd460f48714ca64980e68 Change-Id: Iebee2b269062609ff7bcd460f48714ca64980e68 --- modules/usbaudio/audio_hal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 43f8d240..d77f7ec6 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -1510,6 +1510,8 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, ret = 0; } } + } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) { + in->config.rate = config->sample_rate; } } else if (profile_is_sample_rate_valid(&device_info->profile, config->sample_rate)) { in->config.rate = config->sample_rate; -- cgit v1.2.3