From 4bc5f25296fe3cf12461636be127a0fc3fdbea3e Mon Sep 17 00:00:00 2001 From: jiabin Date: Wed, 2 Jun 2021 18:31:13 +0000 Subject: No need to update devices when they are the same as original ones. The audio framework will call create_audio_patch to update the new input/output devices. When the new devices are the same as the original ones, there is no need to update. Bug: 188843084 Test: play audio via USB Change-Id: I4bf2a51a0e88797f2d78513962e18009c59f46c3 --- modules/usbaudio/audio_hal.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index c847ae0f..9ab28593 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -432,6 +432,41 @@ 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 */ @@ -1620,6 +1655,13 @@ 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); -- cgit v1.2.3 From 0269a9d1dfc8b027a02826d2c19f43f027bc5008 Mon Sep 17 00:00:00 2001 From: jiabin Date: Wed, 2 Jun 2021 20:27:38 +0000 Subject: Distinguish input and output profile/proxy when dumpping. Bug: 188843084 Test: adb shell dumpsys media.audio_flinger Change-Id: I1883905c2edeb0208be129aca79396106f5ea6d3 --- modules/usbaudio/audio_hal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index c847ae0f..3073041a 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -520,10 +520,11 @@ 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); - dprintf(fd, "Output Profile %zu:\n", i); + const char* direction = device_info->profile.direction == PCM_OUT ? "Output" : "Input"; + dprintf(fd, "%s Profile %zu:\n", direction, i); profile_dump(&device_info->profile, fd); - dprintf(fd, "Output Proxy %zu:\n", i); + dprintf(fd, "%s Proxy %zu:\n", direction, i); proxy_dump(&device_info->proxy, fd); } } -- cgit v1.2.3 From 44e1aaab15e72450bdbfcd8a16aa75e0de416fd7 Mon Sep 17 00:00:00 2001 From: Martin Brabham Date: Tue, 15 Jun 2021 20:43:01 -0700 Subject: add is_valid to oob data Bug: 178007935 Test: manual, test app Tag: #feature Change-Id: I9ba3639904471a4c34d8f5df753c416e149749c7 --- include/hardware/bluetooth.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h index afa0eef7..95a0b6e3 100644 --- a/include/hardware/bluetooth.h +++ b/include/hardware/bluetooth.h @@ -261,6 +261,7 @@ 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) */ -- cgit v1.2.3 From 61583424ff6f0135ebffda9507b085dc6839d430 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Fri, 2 Jul 2021 16:13:11 -0700 Subject: USB Audio Hal: Fix CTS timestamp handling Bug: 192702566 Test: atest AudioRecordTest#testTimestamp Change-Id: I3f045b309c8a95ecbe042fd9222e627cac2cb1c9 --- modules/usbaudio/audio_hal.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index cc9e4f7c..39c0fb5c 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -1652,6 +1652,15 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, stream_standby_l(alsa_devices, out == NULL ? &in->standby : &out->standby); device_unlock(adev); + // Timestamps: + // Audio timestamps assume continuous PCM frame counts which are maintained + // with the device proxy.transferred variable. Technically it would be better + // associated with in or out stream, not the device; here we save and restore + // using the first alsa device as a simplification. + uint64_t saved_transferred_frames = 0; + 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); if (ret != 0) { @@ -1661,6 +1670,13 @@ static int adev_create_audio_patch(struct audio_hw_device *dev, } else { *patch_handle = *handle; } + + // Timestamps: Restore transferred frames. + if (saved_transferred_frames != 0) { + device_info = stream_get_first_alsa_device(alsa_devices); + if (device_info != NULL) device_info->proxy.transferred = saved_transferred_frames; + } + if (!wasStandby) { device_lock(adev); if (in != NULL) { -- cgit v1.2.3 From 2ac7393bd8223e3b708fedb6c2b58753c0f7cb35 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Fri, 10 Sep 2021 13:25:25 -0700 Subject: dynamic_sensor: Add stubbed sensor multi-HAL 2.1 support. Bug: 195964858 Test: Verified the dynamic sensor sub-HAL initializes and non-dynamic sensors can sample. Test: See details in testing done comment in https://googleplex-android-review.git.corp.google.com/15806307 . Change-Id: I59934814cc61c7319731eb840ff2132a8c5ce241 --- modules/sensors/dynamic_sensor/Android.bp | 13 ++- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 117 +++++++++++++++++++++ .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 69 ++++++++++++ 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp create mode 100644 modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp index 1ebc04d2..3f424b51 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -108,7 +108,18 @@ cc_library_shared { cflags: ["-DLOG_TAG=\"DynamicSensorHal\""], - srcs: ["sensors.cpp"], + srcs: [ + "DynamicSensorsSubHal.cpp", + "sensors.cpp", + ], + shared_libs: [ + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "libhidlbase", + ], + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + ], } // diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp new file mode 100644 index 00000000..df636a3b --- /dev/null +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -0,0 +1,117 @@ +/* + * 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 "DynamicSensorsSubHal.h" + +#include +#include + +using ::android::hardware::sensors::V1_0::Result; +template using Return = ::android::hardware::Return; +using ::android::hardware::Void; + +namespace android { +namespace SensorHalExt { + +// ISensors. +Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { + return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? + Result::OK : Result::BAD_VALUE); +} + +Return DynamicSensorsSubHal::activate(int32_t sensor_handle __unused, + bool enabled __unused) { + ALOGE("DynamicSensorsSubHal::activate not supported."); + + return Result::INVALID_OPERATION; +} + +Return DynamicSensorsSubHal::batch( + int32_t sensor_handle __unused, int64_t sampling_period_ns __unused, + int64_t max_report_latency_ns __unused) { + ALOGE("DynamicSensorsSubHal::batch not supported."); + + return Result::INVALID_OPERATION; +} + +Return DynamicSensorsSubHal::flush(int32_t sensor_handle __unused) { + ALOGE("DynamicSensorsSubHal::flush not supported."); + + return Result::INVALID_OPERATION; +} + +Return DynamicSensorsSubHal::registerDirectChannel( + const SharedMemInfo& mem __unused, + registerDirectChannel_cb callback __unused) { + ALOGE("DynamicSensorsSubHal::registerDirectChannel not supported."); + + return Void(); +} + +Return DynamicSensorsSubHal::unregisterDirectChannel( + int32_t channel_handle __unused) { + ALOGE("DynamicSensorsSubHal::unregisterDirectChannel not supported."); + + return Result::INVALID_OPERATION; +} + +Return 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 DynamicSensorsSubHal::getSensorsList_2_1( + getSensorsList_2_1_cb callback __unused) { + ALOGD("DynamicSensorsSubHal::getSensorsList_2_1 invoked."); + + return Void(); +} + +Return DynamicSensorsSubHal::injectSensorData_2_1( + const Event& event __unused) { + ALOGE("DynamicSensorsSubHal::injectSensorData_2_1 not supported."); + + return Result::INVALID_OPERATION; +} + +Return DynamicSensorsSubHal::debug( + const hidl_handle& handle __unused, + const hidl_vec& args __unused) { + return Void(); +} + +// ISensorsSubHal. +Return DynamicSensorsSubHal::initialize( + const sp& hal_proxy_callback __unused) { + ALOGD("DynamicSensorsSubHal::initialize invoked."); + + return Result::OK; +} + +} // 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 new file mode 100644 index 00000000..36ed9f5a --- /dev/null +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -0,0 +1,69 @@ +/* + * 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 + +namespace android { +namespace SensorHalExt { + +class DynamicSensorsSubHal : + 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 using hidl_vec = ::android::hardware::hidl_vec; + 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 using Return = ::android::hardware::Return; + using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; + +public: + // ISensors. + Return setOperationMode(OperationMode mode) override; + Return activate(int32_t sensor_handle, bool enabled) override; + Return batch(int32_t sensor_handle, int64_t sampling_period_ns, + int64_t max_report_latency_ns) override; + Return flush(int32_t sensor_handle) override; + Return registerDirectChannel( + const SharedMemInfo& mem, + registerDirectChannel_cb callback) override; + Return unregisterDirectChannel(int32_t channel_handle) override; + Return configDirectReport( + int32_t sensor_handle, int32_t channel_handle, RateLevel rate, + configDirectReport_cb callback) override; + Return getSensorsList_2_1(getSensorsList_2_1_cb callback) override; + Return injectSensorData_2_1(const Event& event) override; + Return debug( + const hidl_handle& handle, + const hidl_vec& args) override; + + // ISensorsSubHal. + const std::string getName() override { return "Dynamic-SubHAL"; } + Return initialize( + const sp& hal_proxy_callback) override; +}; + +} // namespace SensorHalExt +} // namespace android + +#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H + -- cgit v1.2.3 From 28b58c62b5db41da83366e4b4fe3e0ef9ed32a22 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Tue, 14 Sep 2021 15:58:22 -0700 Subject: dynamic_sensor: Add sensor manager init to sub-HAL 2.1. Bug: 195964858 Test: Verified dynamic sensor manager is present in sensor list. Test: Test: See details in testing done comment in https://googleplex-android-review.git.corp.google.com/15831086 . Change-Id: Ia34596d79f8a6c6985b35dcae75126e456f6009e --- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 39 +++++++++++++++++++++- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 12 +++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index df636a3b..2db58842 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -16,16 +16,30 @@ #include "DynamicSensorsSubHal.h" +#include #include #include using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V2_1::SensorInfo; +using ::android::hardware::sensors::V2_1::SensorType; template using Return = ::android::hardware::Return; using ::android::hardware::Void; namespace android { namespace SensorHalExt { +DynamicSensorsSubHal::DynamicSensorsSubHal() { + // initialize dynamic sensor manager + int32_t base = property_get_int32("sensor.dynamic_sensor_hal.handle_base", + kDynamicHandleBase); + int32_t count = property_get_int32("sensor.dynamic_sensor_hal.handle_count", + kMaxDynamicHandleCount); + mDynamicSensorManager.reset( + DynamicSensorManager::createInstance(base, count, + nullptr /* callback */)); +} + // ISensors. Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? @@ -77,9 +91,32 @@ Return DynamicSensorsSubHal::configDirectReport( } Return DynamicSensorsSubHal::getSensorsList_2_1( - getSensorsList_2_1_cb callback __unused) { + getSensorsList_2_1_cb callback) { + const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor(); + std::vector 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(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(); } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index 36ed9f5a..ab5d2999 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -17,6 +17,8 @@ #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H +#include "DynamicSensorManager.h" + #include namespace android { @@ -37,6 +39,8 @@ class DynamicSensorsSubHal : using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: + DynamicSensorsSubHal(); + // ISensors. Return setOperationMode(OperationMode mode) override; Return activate(int32_t sensor_handle, bool enabled) override; @@ -60,6 +64,14 @@ public: const std::string getName() override { return "Dynamic-SubHAL"; } Return initialize( const sp& hal_proxy_callback) override; + +private: + static constexpr int32_t kDynamicHandleBase = 0; + static constexpr int32_t kDynamicHandleEnd = 0x1000000; + static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - + kDynamicHandleBase; + + std::unique_ptr mDynamicSensorManager; }; } // namespace SensorHalExt -- cgit v1.2.3 From 3482ca5bf73ca6afd10eb49dfc7cfb49609b3eae Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Thu, 16 Sep 2021 22:58:51 +0000 Subject: Revert "dynamic_sensor: Add sensor manager init to sub-HAL 2.1." This reverts commit 28b58c62b5db41da83366e4b4fe3e0ef9ed32a22. Reason for revert: 200210164 Change-Id: I6be2c972a29ec7943dbdf450ef3e491065b011a6 --- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 39 +--------------------- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 12 ------- 2 files changed, 1 insertion(+), 50 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index 2db58842..df636a3b 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -16,30 +16,16 @@ #include "DynamicSensorsSubHal.h" -#include #include #include using ::android::hardware::sensors::V1_0::Result; -using ::android::hardware::sensors::V2_1::SensorInfo; -using ::android::hardware::sensors::V2_1::SensorType; template using Return = ::android::hardware::Return; using ::android::hardware::Void; namespace android { namespace SensorHalExt { -DynamicSensorsSubHal::DynamicSensorsSubHal() { - // initialize dynamic sensor manager - int32_t base = property_get_int32("sensor.dynamic_sensor_hal.handle_base", - kDynamicHandleBase); - int32_t count = property_get_int32("sensor.dynamic_sensor_hal.handle_count", - kMaxDynamicHandleCount); - mDynamicSensorManager.reset( - DynamicSensorManager::createInstance(base, count, - nullptr /* callback */)); -} - // ISensors. Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? @@ -91,32 +77,9 @@ Return DynamicSensorsSubHal::configDirectReport( } Return DynamicSensorsSubHal::getSensorsList_2_1( - getSensorsList_2_1_cb callback) { - const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor(); - std::vector sensors; - + getSensorsList_2_1_cb callback __unused) { 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(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(); } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index ab5d2999..36ed9f5a 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -17,8 +17,6 @@ #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H -#include "DynamicSensorManager.h" - #include namespace android { @@ -39,8 +37,6 @@ class DynamicSensorsSubHal : using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: - DynamicSensorsSubHal(); - // ISensors. Return setOperationMode(OperationMode mode) override; Return activate(int32_t sensor_handle, bool enabled) override; @@ -64,14 +60,6 @@ public: const std::string getName() override { return "Dynamic-SubHAL"; } Return initialize( const sp& hal_proxy_callback) override; - -private: - static constexpr int32_t kDynamicHandleBase = 0; - static constexpr int32_t kDynamicHandleEnd = 0x1000000; - static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - - kDynamicHandleBase; - - std::unique_ptr mDynamicSensorManager; }; } // namespace SensorHalExt -- cgit v1.2.3 From c7038f8a783edfbcc199402a1e3b870a092fbdc7 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Mon, 20 Sep 2021 16:54:59 -0700 Subject: dynamic_sensor: Add sensor manager init to sub-HAL 2.1. Bug: 195964858 Test: Verified dynamic sensor manager is present in sensor list and that no SELinux violations occur. Test: See details in testing done comment in https://googleplex-android-review.git.corp.google.com/15874906 . Change-Id: I5d587dc46bdec66c3162bf222d36b285b8d2ca3d --- .../dynamic_sensor/DummyDynamicAccelDaemon.cpp | 2 +- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 35 +++++++++++++++++++++- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 12 ++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp index a1a47e81..0cc8a393 100644 --- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp +++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp @@ -28,7 +28,7 @@ #include #include //std::max -#define SYSPROP_PREFIX "dynamic_sensor.dummy" +#define SYSPROP_PREFIX "vendor.dynamic_sensor.mock" #define FILE_NAME_BASE "dummy_accel_file" #define FILE_NAME_REGEX ("^" FILE_NAME_BASE "[0-9]$") diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index df636a3b..9f9a9fef 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -20,12 +20,22 @@ #include using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V2_1::SensorInfo; +using ::android::hardware::sensors::V2_1::SensorType; template using Return = ::android::hardware::Return; using ::android::hardware::Void; namespace android { namespace SensorHalExt { +DynamicSensorsSubHal::DynamicSensorsSubHal() { + // initialize dynamic sensor manager + mDynamicSensorManager.reset( + DynamicSensorManager::createInstance(kDynamicHandleBase, + kMaxDynamicHandleCount, + nullptr /* callback */)); +} + // ISensors. Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? @@ -77,9 +87,32 @@ Return DynamicSensorsSubHal::configDirectReport( } Return DynamicSensorsSubHal::getSensorsList_2_1( - getSensorsList_2_1_cb callback __unused) { + getSensorsList_2_1_cb callback) { + const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor(); + std::vector 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(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(); } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index 36ed9f5a..ab5d2999 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -17,6 +17,8 @@ #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H +#include "DynamicSensorManager.h" + #include namespace android { @@ -37,6 +39,8 @@ class DynamicSensorsSubHal : using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: + DynamicSensorsSubHal(); + // ISensors. Return setOperationMode(OperationMode mode) override; Return activate(int32_t sensor_handle, bool enabled) override; @@ -60,6 +64,14 @@ public: const std::string getName() override { return "Dynamic-SubHAL"; } Return initialize( const sp& hal_proxy_callback) override; + +private: + static constexpr int32_t kDynamicHandleBase = 0; + static constexpr int32_t kDynamicHandleEnd = 0x1000000; + static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - + kDynamicHandleBase; + + std::unique_ptr mDynamicSensorManager; }; } // namespace SensorHalExt -- cgit v1.2.3 From 1d509cf815c5e3319ce4303eabe863b6b8dcf3a1 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Wed, 22 Sep 2021 17:53:58 +0000 Subject: Revert "dynamic_sensor: Add sensor manager init to sub-HAL 2.1." Revert submission 15874906-bug_195964858.2 Reason for revert: b/200815351 Reverted Changes: I76a60f7fb:Allow the sensor HAL to access dynamic sensor prop... I5d587dc46:dynamic_sensor: Add sensor manager init to sub-HAL... Change-Id: I26b95614bb276e5c2a686de78d73ab48767176a3 --- .../dynamic_sensor/DummyDynamicAccelDaemon.cpp | 2 +- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 35 +--------------------- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 12 -------- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp index 0cc8a393..a1a47e81 100644 --- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp +++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp @@ -28,7 +28,7 @@ #include #include //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]$") diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index 9f9a9fef..df636a3b 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -20,22 +20,12 @@ #include using ::android::hardware::sensors::V1_0::Result; -using ::android::hardware::sensors::V2_1::SensorInfo; -using ::android::hardware::sensors::V2_1::SensorType; template using Return = ::android::hardware::Return; using ::android::hardware::Void; namespace android { namespace SensorHalExt { -DynamicSensorsSubHal::DynamicSensorsSubHal() { - // initialize dynamic sensor manager - mDynamicSensorManager.reset( - DynamicSensorManager::createInstance(kDynamicHandleBase, - kMaxDynamicHandleCount, - nullptr /* callback */)); -} - // ISensors. Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? @@ -87,32 +77,9 @@ Return DynamicSensorsSubHal::configDirectReport( } Return DynamicSensorsSubHal::getSensorsList_2_1( - getSensorsList_2_1_cb callback) { - const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor(); - std::vector sensors; - + getSensorsList_2_1_cb callback __unused) { 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(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(); } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index ab5d2999..36ed9f5a 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -17,8 +17,6 @@ #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H -#include "DynamicSensorManager.h" - #include namespace android { @@ -39,8 +37,6 @@ class DynamicSensorsSubHal : using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: - DynamicSensorsSubHal(); - // ISensors. Return setOperationMode(OperationMode mode) override; Return activate(int32_t sensor_handle, bool enabled) override; @@ -64,14 +60,6 @@ public: const std::string getName() override { return "Dynamic-SubHAL"; } Return initialize( const sp& hal_proxy_callback) override; - -private: - static constexpr int32_t kDynamicHandleBase = 0; - static constexpr int32_t kDynamicHandleEnd = 0x1000000; - static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - - kDynamicHandleBase; - - std::unique_ptr mDynamicSensorManager; }; } // namespace SensorHalExt -- cgit v1.2.3 From 3c7a12d8f1764df734f74b486e57acf1f629dd5e Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Fri, 24 Sep 2021 05:48:24 -0700 Subject: dynamic_sensor: Add sensor manager init to sub-HAL 2.1. Bug: 195964858 Test: Verified dynamic sensor manager is present in sensor list and that no SELinux violations occur on sc-v2-dev and master. $ make -j28 && \ vendor/google/tools/flashall -w -s 14281FDEE000A5 --disable_verity && \ sleep 90 && adb root . . . $ adb shell sensor_test list | grep "sensor_test\|Type\|Dynamic" sensor_test version 74 Type Subtype Name 32 0 Dynamic Sensor Manager $ adb logcat -d | grep avc | grep sensor $ Change-Id: Ib3da287e4f4118ad6b19498248e263f8c1662b3a --- .../sensors/dynamic_sensor/ConnectionDetector.cpp | 18 +++++++---- .../sensors/dynamic_sensor/ConnectionDetector.h | 3 ++ .../dynamic_sensor/DummyDynamicAccelDaemon.cpp | 4 ++- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 35 +++++++++++++++++++++- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 12 ++++++++ .../sensors/dynamic_sensor/HidRawSensorDaemon.cpp | 1 + 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp index c51e9125..c009a707 100644 --- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp +++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp @@ -57,8 +57,6 @@ SocketConnectionDetector::SocketConnectionDetector(BaseDynamicSensorDaemon *d, i std::ostringstream s; s << "socket:" << port; mDevice = s.str(); - - run("ddad_socket"); } SocketConnectionDetector::~SocketConnectionDetector() { @@ -67,6 +65,12 @@ 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); } @@ -124,9 +128,6 @@ FileConnectionDetector::FileConnectionDetector ( ALOGE("Cannot setup watch on dir %s", path.c_str()); return; } - - // mLooper != null && mInotifyFd added to looper - run("ddad_file"); } FileConnectionDetector::~FileConnectionDetector() { @@ -138,6 +139,13 @@ 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); } diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.h b/modules/sensors/dynamic_sensor/ConnectionDetector.h index 0ee1df29..75fbb0bc 100644 --- a/modules/sensors/dynamic_sensor/ConnectionDetector.h +++ b/modules/sensors/dynamic_sensor/ConnectionDetector.h @@ -34,6 +34,7 @@ class ConnectionDetector : virtual public RefBase { public: ConnectionDetector(BaseDynamicSensorDaemon *d) : mDaemon(d) { } virtual ~ConnectionDetector() = default; + virtual void Init() {} protected: BaseDynamicSensorDaemon* mDaemon; }; @@ -45,6 +46,7 @@ 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(); @@ -62,6 +64,7 @@ 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 a1a47e81..10771e32 100644 --- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp +++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp @@ -28,7 +28,7 @@ #include #include //std::max -#define SYSPROP_PREFIX "dynamic_sensor.dummy" +#define SYSPROP_PREFIX "vendor.dynamic_sensor.mock" #define FILE_NAME_BASE "dummy_accel_file" #define FILE_NAME_REGEX ("^" FILE_NAME_BASE "[0-9]$") @@ -43,11 +43,13 @@ 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/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index df636a3b..9f9a9fef 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -20,12 +20,22 @@ #include using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V2_1::SensorInfo; +using ::android::hardware::sensors::V2_1::SensorType; template using Return = ::android::hardware::Return; using ::android::hardware::Void; namespace android { namespace SensorHalExt { +DynamicSensorsSubHal::DynamicSensorsSubHal() { + // initialize dynamic sensor manager + mDynamicSensorManager.reset( + DynamicSensorManager::createInstance(kDynamicHandleBase, + kMaxDynamicHandleCount, + nullptr /* callback */)); +} + // ISensors. Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { return (mode == static_cast(SENSOR_HAL_NORMAL_MODE) ? @@ -77,9 +87,32 @@ Return DynamicSensorsSubHal::configDirectReport( } Return DynamicSensorsSubHal::getSensorsList_2_1( - getSensorsList_2_1_cb callback __unused) { + getSensorsList_2_1_cb callback) { + const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor(); + std::vector 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(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(); } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index 36ed9f5a..ab5d2999 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -17,6 +17,8 @@ #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSORS_SUB_HAL_H +#include "DynamicSensorManager.h" + #include namespace android { @@ -37,6 +39,8 @@ class DynamicSensorsSubHal : using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: + DynamicSensorsSubHal(); + // ISensors. Return setOperationMode(OperationMode mode) override; Return activate(int32_t sensor_handle, bool enabled) override; @@ -60,6 +64,14 @@ public: const std::string getName() override { return "Dynamic-SubHAL"; } Return initialize( const sp& hal_proxy_callback) override; + +private: + static constexpr int32_t kDynamicHandleBase = 0; + static constexpr int32_t kDynamicHandleEnd = 0x1000000; + static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - + kDynamicHandleBase; + + std::unique_ptr mDynamicSensorManager; }; } // namespace SensorHalExt diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp index 6bf34bc8..4b447ac1 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp @@ -39,6 +39,7 @@ 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) { -- cgit v1.2.3 From 7b29add5f73449e3fdcb462f030b7f44c985815e Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Tue, 28 Sep 2021 05:50:43 -0700 Subject: dynamic_sensor: Notify multi-HAL 2.1 of connected sensors. Bug: 195964858 Test: Paired a Sony PS4 controller and verified it is present in sensor list as an accelerometer. It can't be sampled, but the LSM6DSR accelerometer may still be sampled. Change-Id: I182291cebdf84e5f6cd44d16debd6a07c4bc5281 --- modules/sensors/dynamic_sensor/Android.bp | 5 ++ .../dynamic_sensor/DynamicSensorsSubHal.cpp | 80 +++++++++++++++++++++- .../sensors/dynamic_sensor/DynamicSensorsSubHal.h | 8 +++ 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp index 3f424b51..bad60481 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -114,11 +114,16 @@ cc_library_shared { ], 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", ], } diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index 9f9a9fef..4f0cc481 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -14,12 +14,19 @@ * limitations under the License. */ +#include "BaseSensorObject.h" #include "DynamicSensorsSubHal.h" +#include #include #include +#include +#include + 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 using Return = ::android::hardware::Return; @@ -33,7 +40,7 @@ DynamicSensorsSubHal::DynamicSensorsSubHal() { mDynamicSensorManager.reset( DynamicSensorManager::createInstance(kDynamicHandleBase, kMaxDynamicHandleCount, - nullptr /* callback */)); + this /* callback */)); } // ISensors. @@ -131,12 +138,81 @@ Return DynamicSensorsSubHal::debug( // ISensorsSubHal. Return DynamicSensorsSubHal::initialize( - const sp& hal_proxy_callback __unused) { + const sp& 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 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( + &(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 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(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 diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index ab5d2999..e9a46d68 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -25,6 +25,7 @@ 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; @@ -65,13 +66,20 @@ public: Return initialize( const sp& hal_proxy_callback) override; + // SensorEventCallback. + int submitEvent(SP(BaseSensorObject) sensor, + const sensors_event_t& e) override; + private: static constexpr int32_t kDynamicHandleBase = 0; 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 mDynamicSensorManager; + sp mHalProxyCallback; }; } // namespace SensorHalExt -- cgit v1.2.3 From 43bc7bccdc3e4ee224d5c22ef8f18b0f2fbeb1e0 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Thu, 30 Sep 2021 06:50:43 -0700 Subject: dynamic_sensor: Add multi-HAL 2.1 sampling support. Bug: 195964858 Test: Paired a Sony PS4 controller and verified it can be sampled as an accelerometer. The first subscription always returns all 0's, but subsequent subscriptions return proper accel samples. Change-Id: I4bbc4695c988f600a62502f9fccabaa68f42c72b --- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index 4f0cc481..d9e31824 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -35,6 +35,21 @@ 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( @@ -49,19 +64,18 @@ Return DynamicSensorsSubHal::setOperationMode(OperationMode mode) { Result::OK : Result::BAD_VALUE); } -Return DynamicSensorsSubHal::activate(int32_t sensor_handle __unused, - bool enabled __unused) { - ALOGE("DynamicSensorsSubHal::activate not supported."); - - return Result::INVALID_OPERATION; +Return DynamicSensorsSubHal::activate(int32_t sensor_handle, + bool enabled) { + int rc = mDynamicSensorManager->activate(sensor_handle, enabled); + return ResultFromStatus(rc); } Return DynamicSensorsSubHal::batch( - int32_t sensor_handle __unused, int64_t sampling_period_ns __unused, - int64_t max_report_latency_ns __unused) { - ALOGE("DynamicSensorsSubHal::batch not supported."); - - return Result::INVALID_OPERATION; + 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 DynamicSensorsSubHal::flush(int32_t sensor_handle __unused) { -- cgit v1.2.3 From 35964ba0768558fe61fd225a51015c1b56656ddc Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Mon, 4 Oct 2021 15:17:32 -0700 Subject: dynamic_sensor: Add multi-HAL 2.1 flush support. Bug: 201730055 Test: Verified that flush, batch, and activate sensor VTS tests pass. Change-Id: I6721d9f8976b3ef9f6af02b2320833025b479ee6 --- modules/sensors/dynamic_sensor/BaseSensorObject.cpp | 1 + .../sensors/dynamic_sensor/DynamicSensorManager.cpp | 20 ++++++++++++-------- .../sensors/dynamic_sensor/DynamicSensorManager.h | 1 + .../sensors/dynamic_sensor/DynamicSensorsSubHal.cpp | 7 +++---- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp index 4ec76b27..69fc7d86 100644 --- a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp +++ b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp @@ -42,6 +42,7 @@ 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/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp index 37b43132..be1a0044 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) { - // ignored + mMetaSensorActive = enable; return 0; } @@ -109,13 +109,17 @@ int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) { int DynamicSensorManager::flush(int handle) { if (handle == mHandleRange.first) { - // 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); + 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; + } return 0; } return operateSensor(handle, [] (sp s)->int {return s->flush();}); diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h index b6f39da6..634c5234 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h @@ -111,6 +111,7 @@ private: // available sensor handle space const std::pair mHandleRange; sensor_t mMetaSensor; + bool mMetaSensorActive = false; // immutable pointer to event callback, used in extention mode. SensorEventCallback * const mCallback; diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp index d9e31824..d5a9b3c0 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -78,10 +78,9 @@ Return DynamicSensorsSubHal::batch( return ResultFromStatus(rc); } -Return DynamicSensorsSubHal::flush(int32_t sensor_handle __unused) { - ALOGE("DynamicSensorsSubHal::flush not supported."); - - return Result::INVALID_OPERATION; +Return DynamicSensorsSubHal::flush(int32_t sensor_handle) { + int rc = mDynamicSensorManager->flush(sensor_handle); + return ResultFromStatus(rc); } Return DynamicSensorsSubHal::registerDirectChannel( -- cgit v1.2.3 From 9bba1110141ee23c5a6195bf18d7ebe8198ea93b Mon Sep 17 00:00:00 2001 From: Shawn Willden Date: Wed, 6 Oct 2021 13:08:40 -0600 Subject: Delete KM1 Test: Build Change-Id: I8abb9c570db05599e3d062810427859ea784d47f --- include/hardware/keymaster1.h | 548 ------------------------------------------ 1 file changed, 548 deletions(-) delete mode 100644 include/hardware/keymaster1.h diff --git a/include/hardware/keymaster1.h b/include/hardware/keymaster1.h deleted file mode 100644 index 99693806..00000000 --- a/include/hardware/keymaster1.h +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2015 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_HARDWARE_KEYMASTER1_H -#define ANDROID_HARDWARE_KEYMASTER1_H - -#include -#include - -__BEGIN_DECLS - -/** - * Keymaster1 device definition - */ -struct keymaster1_device { - /** - * Common methods of the keymaster device. This *must* be the first member of - * keymaster_device as users of this structure will cast a hw_device_t to - * keymaster_device pointer in contexts where it's known the hw_device_t references a - * keymaster_device. - */ - struct hw_device_t common; - - /** - * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version" - * fields in the keymaster_module initialization instead. - */ - uint32_t client_version; - - /** - * See flags defined for keymaster0_devices::flags in keymaster_common.h - */ - uint32_t flags; - - void* context; - - /** - * \deprecated Generates a public and private key. The key-blob returned is opaque and must - * subsequently provided for signing and verification. - * - * Returns: 0 on success or an error code less than 0. - */ - int (*generate_keypair)(const struct keymaster1_device* dev, const keymaster_keypair_t key_type, - const void* key_params, uint8_t** key_blob, size_t* key_blob_length); - - /** - * \deprecated Imports a public and private key pair. The imported keys will be in PKCS#8 format - * with DER encoding (Java standard). The key-blob returned is opaque and will be subsequently - * provided for signing and verification. - * - * Returns: 0 on success or an error code less than 0. - */ - int (*import_keypair)(const struct keymaster1_device* dev, const uint8_t* key, - const size_t key_length, uint8_t** key_blob, size_t* key_blob_length); - - /** - * \deprecated Gets the public key part of a key pair. The public key must be in X.509 format - * (Java standard) encoded byte array. - * - * Returns: 0 on success or an error code less than 0. On error, x509_data - * should not be allocated. - */ - int (*get_keypair_public)(const struct keymaster1_device* dev, const uint8_t* key_blob, - const size_t key_blob_length, uint8_t** x509_data, - size_t* x509_data_length); - - /** - * \deprecated Deletes the key pair associated with the key blob. - * - * This function is optional and should be set to NULL if it is not - * implemented. - * - * Returns 0 on success or an error code less than 0. - */ - int (*delete_keypair)(const struct keymaster1_device* dev, const uint8_t* key_blob, - const size_t key_blob_length); - - /** - * \deprecated Deletes all keys in the hardware keystore. Used when keystore is reset - * completely. - * - * This function is optional and should be set to NULL if it is not - * implemented. - * - * Returns 0 on success or an error code less than 0. - */ - int (*delete_all)(const struct keymaster1_device* dev); - - /** - * \deprecated Signs data using a key-blob generated before. This can use either an asymmetric - * key or a secret key. - * - * Returns: 0 on success or an error code less than 0. - */ - int (*sign_data)(const struct keymaster1_device* dev, const void* signing_params, - const uint8_t* key_blob, const size_t key_blob_length, const uint8_t* data, - const size_t data_length, uint8_t** signed_data, size_t* signed_data_length); - - /** - * \deprecated Verifies data signed with a key-blob. This can use either an asymmetric key or a - * secret key. - * - * Returns: 0 on successful verification or an error code less than 0. - */ - int (*verify_data)(const struct keymaster1_device* dev, const void* signing_params, - const uint8_t* key_blob, const size_t key_blob_length, - const uint8_t* signed_data, const size_t signed_data_length, - const uint8_t* signature, const size_t signature_length); - - /** - * Gets algorithms supported. - * - * \param[in] dev The keymaster device structure. - * - * \param[out] algorithms Array of algorithms supported. The caller takes ownership of the - * array and must free() it. - * - * \param[out] algorithms_length Length of \p algorithms. - */ - keymaster_error_t (*get_supported_algorithms)(const struct keymaster1_device* dev, - keymaster_algorithm_t** algorithms, - size_t* algorithms_length); - - /** - * Gets the block modes supported for the specified algorithm. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] algorithm The algorithm for which supported modes will be returned. - * - * \param[out] modes Array of modes supported. The caller takes ownership of the array and must - * free() it. - * - * \param[out] modes_length Length of \p modes. - */ - keymaster_error_t (*get_supported_block_modes)(const struct keymaster1_device* dev, - keymaster_algorithm_t algorithm, - keymaster_purpose_t purpose, - keymaster_block_mode_t** modes, - size_t* modes_length); - - /** - * Gets the padding modes supported for the specified algorithm. Caller assumes ownership of - * the allocated array. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] algorithm The algorithm for which supported padding modes will be returned. - * - * \param[out] modes Array of padding modes supported. The caller takes ownership of the array - * and must free() it. - * - * \param[out] modes_length Length of \p modes. - */ - keymaster_error_t (*get_supported_padding_modes)(const struct keymaster1_device* dev, - keymaster_algorithm_t algorithm, - keymaster_purpose_t purpose, - keymaster_padding_t** modes, - size_t* modes_length); - - /** - * Gets the digests supported for the specified algorithm. Caller assumes ownership of the - * allocated array. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] algorithm The algorithm for which supported digests will be returned. - * - * \param[out] digests Array of digests supported. The caller takes ownership of the array and - * must free() it. - * - * \param[out] digests_length Length of \p digests. - */ - keymaster_error_t (*get_supported_digests)(const struct keymaster1_device* dev, - keymaster_algorithm_t algorithm, - keymaster_purpose_t purpose, - keymaster_digest_t** digests, - size_t* digests_length); - - /** - * Gets the key import formats supported for keys of the specified algorithm. Caller assumes - * ownership of the allocated array. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] algorithm The algorithm for which supported formats will be returned. - * - * \param[out] formats Array of formats supported. The caller takes ownership of the array and - * must free() it. - * - * \param[out] formats_length Length of \p formats. - */ - keymaster_error_t (*get_supported_import_formats)(const struct keymaster1_device* dev, - keymaster_algorithm_t algorithm, - keymaster_key_format_t** formats, - size_t* formats_length); - - /** - * Gets the key export formats supported for keys of the specified algorithm. Caller assumes - * ownership of the allocated array. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] algorithm The algorithm for which supported formats will be returned. - * - * \param[out] formats Array of formats supported. The caller takes ownership of the array and - * must free() it. - * - * \param[out] formats_length Length of \p formats. - */ - keymaster_error_t (*get_supported_export_formats)(const struct keymaster1_device* dev, - keymaster_algorithm_t algorithm, - keymaster_key_format_t** formats, - size_t* formats_length); - - /** - * Adds entropy to the RNG used by keymaster. Entropy added through this method is guaranteed - * not to be the only source of entropy used, and the mixing function is required to be secure, - * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot - * predict (or control), then the RNG output is indistinguishable from random. Thus, if the - * entropy from any source is good, the output will be good. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] data Random data to be mixed in. - * - * \param[in] data_length Length of \p data. - */ - keymaster_error_t (*add_rng_entropy)(const struct keymaster1_device* dev, const uint8_t* data, - size_t data_length); - - /** - * Generates a key, or key pair, returning a key blob and/or a description of the key. - * - * Key generation parameters are defined as keymaster tag/value pairs, provided in \p params. - * See keymaster_tag_t for the full list. Some values that are always required for generation - * of useful keys are: - * - * - KM_TAG_ALGORITHM; - * - KM_TAG_PURPOSE; and - * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. - * - * KM_TAG_AUTH_TIMEOUT should generally be specified unless KM_TAG_NO_AUTH_REQUIRED is present, - * or the user will have to authenticate for every use. - * - * KM_TAG_BLOCK_MODE, KM_TAG_PADDING, KM_TAG_MAC_LENGTH and KM_TAG_DIGEST must be specified for - * algorithms that require them. - * - * The following tags may not be specified; their values will be provided by the implementation. - * - * - KM_TAG_ORIGIN, - * - KM_TAG_ROLLBACK_RESISTANT, - * - KM_TAG_CREATION_DATETIME - * - * \param[in] dev The keymaster device structure. - * - * \param[in] params Array of key generation parameters. - * - * \param[in] params_count Length of \p params. - * - * \param[out] key_blob returns the generated key. \p key_blob must not be NULL. The caller - * assumes ownership key_blob->key_material and must free() it. - * - * \param[out] characteristics returns the characteristics of the key that was, generated, if - * non-NULL. If non-NULL, the caller assumes ownership and must deallocate with - * keymaster_free_characteristics(). Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and - * KM_TAG_APPLICATION_DATA are never returned. - */ - keymaster_error_t (*generate_key)(const struct keymaster1_device* dev, - const keymaster_key_param_set_t* params, - keymaster_key_blob_t* key_blob, - keymaster_key_characteristics_t** characteristics); - - /** - * Returns the characteristics of the specified key, or KM_ERROR_INVALID_KEY_BLOB if the - * key_blob is invalid (implementations must fully validate the integrity of the key). - * client_id and app_data must be the ID and data provided when the key was generated or - * imported, or empty if KM_TAG_APPLICATION_ID and/or KM_TAG_APPLICATION_DATA were not provided - * during generation. Those values are not included in the returned characteristics. The - * caller assumes ownership of the allocated characteristics object, which must be deallocated - * with keymaster_free_characteristics(). - * - * Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and KM_TAG_APPLICATION_DATA are never - * returned. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] key_blob The key to retreive characteristics from. - * - * \param[in] client_id The client ID data, or NULL if none associated. - * - * \param[in] app_id The app data, or NULL if none associated. - * - * \param[out] characteristics The key characteristics. - */ - keymaster_error_t (*get_key_characteristics)(const struct keymaster1_device* dev, - const keymaster_key_blob_t* key_blob, - const keymaster_blob_t* client_id, - const keymaster_blob_t* app_data, - keymaster_key_characteristics_t** characteristics); - - /** - * Imports a key, or key pair, returning a key blob and/or a description of the key. - * - * Most key import parameters are defined as keymaster tag/value pairs, provided in "params". - * See keymaster_tag_t for the full list. Values that are always required for import of useful - * keys are: - * - * - KM_TAG_ALGORITHM; - * - KM_TAG_PURPOSE; and - * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. - * - * KM_TAG_AUTH_TIMEOUT should generally be specified. If unspecified, the user will have to - * authenticate for every use. - * - * The following tags will take default values if unspecified: - * - * - KM_TAG_KEY_SIZE will default to the size of the key provided. - * - KM_TAG_RSA_PUBLIC_EXPONENT will default to the value in the key provided (for RSA keys) - * - * The following tags may not be specified; their values will be provided by the implementation. - * - * - KM_TAG_ORIGIN, - * - KM_TAG_ROLLBACK_RESISTANT, - * - KM_TAG_CREATION_DATETIME - * - * \param[in] dev The keymaster device structure. - * - * \param[in] params Parameters defining the imported key. - * - * \param[in] params_count The number of entries in \p params. - * - * \param[in] key_format specifies the format of the key data in key_data. - * - * \param[out] key_blob Used to return the opaque key blob. Must be non-NULL. The caller - * assumes ownership of the contained key_material. - * - * \param[out] characteristics Used to return the characteristics of the imported key. May be - * NULL, in which case no characteristics will be returned. If non-NULL, the caller assumes - * ownership and must deallocate with keymaster_free_characteristics(). Note that - * KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and - * KM_TAG_APPLICATION_DATA are never returned. - */ - keymaster_error_t (*import_key)(const struct keymaster1_device* dev, - const keymaster_key_param_set_t* params, - keymaster_key_format_t key_format, - const keymaster_blob_t* key_data, - keymaster_key_blob_t* key_blob, - keymaster_key_characteristics_t** characteristics); - - /** - * Exports a public key, returning a byte array in the specified format. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] export_format The format to be used for exporting the key. - * - * \param[in] key_to_export The key to export. - * - * \param[out] export_data The exported key material. The caller assumes ownership. - * - * \param[out] export_data_length The length of \p export_data. - */ - keymaster_error_t (*export_key)(const struct keymaster1_device* dev, - keymaster_key_format_t export_format, - const keymaster_key_blob_t* key_to_export, - const keymaster_blob_t* client_id, - const keymaster_blob_t* app_data, - keymaster_blob_t* export_data); - - /** - * Deletes the key, or key pair, associated with the key blob. After calling this function it - * will be impossible to use the key for any other operations. May be applied to keys from - * foreign roots of trust (keys not usable under the current root of trust). - * - * This function is optional and should be set to NULL if it is not implemented. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] key The key to be deleted. - */ - keymaster_error_t (*delete_key)(const struct keymaster1_device* dev, - const keymaster_key_blob_t* key); - - /** - * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After - * calling this function it will be impossible to use any previously generated or imported key - * blobs for any operations. - * - * This function is optional and should be set to NULL if it is not implemented. - * - * \param[in] dev The keymaster device structure. - */ - keymaster_error_t (*delete_all_keys)(const struct keymaster1_device* dev); - - /** - * Begins a cryptographic operation using the specified key. If all is well, begin() will - * return KM_ERROR_OK and create an operation handle which must be passed to subsequent calls to - * update(), finish() or abort(). - * - * It is critical that each call to begin() be paired with a subsequent call to finish() or - * abort(), to allow the keymaster implementation to clean up any internal operation state. - * Failure to do this may leak internal state space or other internal resources and may - * eventually cause begin() to return KM_ERROR_TOO_MANY_OPERATIONS when it runs out of space for - * operations. Any result other than KM_ERROR_OK from begin(), update() or finish() implicitly - * aborts the operation, in which case abort() need not be called (and will return - * KM_ERROR_INVALID_OPERATION_HANDLE if called). - * - * \param[in] dev The keymaster device structure. - * - * \param[in] purpose The purpose of the operation, one of KM_PURPOSE_ENCRYPT, - * KM_PURPOSE_DECRYPT, KM_PURPOSE_SIGN or KM_PURPOSE_VERIFY. Note that for AEAD modes, - * encryption and decryption imply signing and verification, respectively, but should be - * specified as KM_PURPOSE_ENCRYPT and KM_PURPOSE_DECRYPT. - * - * \param[in] key The key to be used for the operation. \p key must have a purpose compatible - * with \p purpose and all of its usage requirements must be satisfied, or begin() will return - * an appropriate error code. - * - * \param[in] in_params Additional parameters for the operation. This is typically used to - * provide authentication data, with KM_TAG_AUTH_TOKEN. If KM_TAG_APPLICATION_ID or - * KM_TAG_APPLICATION_DATA were provided during generation, they must be provided here, or the - * operation will fail with KM_ERROR_INVALID_KEY_BLOB. For operations that require a nonce or - * IV, on keys that were generated with KM_TAG_CALLER_NONCE, in_params may contain a tag - * KM_TAG_NONCE. For AEAD operations KM_TAG_CHUNK_SIZE is specified here. - * - * \param[out] out_params Output parameters. Used to return additional data from the operation - * initialization, notably to return the IV or nonce from operations that generate an IV or - * nonce. The caller takes ownership of the output parameters array and must free it with - * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are - * expected. If out_params is NULL, and output paramaters are generated, begin() will return - * KM_ERROR_OUTPUT_PARAMETER_NULL. - * - * \param[out] operation_handle The newly-created operation handle which must be passed to - * update(), finish() or abort(). If operation_handle is NULL, begin() will return - * KM_ERROR_OUTPUT_PARAMETER_NULL. - */ - keymaster_error_t (*begin)(const struct keymaster1_device* dev, keymaster_purpose_t purpose, - const keymaster_key_blob_t* key, - const keymaster_key_param_set_t* in_params, - keymaster_key_param_set_t* out_params, - keymaster_operation_handle_t* operation_handle); - - /** - * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun - * with begin(). - * - * If operation_handle is invalid, update() will return KM_ERROR_INVALID_OPERATION_HANDLE. - * - * update() may not consume all of the data provided in the data buffer. update() will return - * the amount consumed in *data_consumed. The caller should provide the unconsumed data in a - * subsequent call. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] operation_handle The operation handle returned by begin(). - * - * \param[in] in_params Additional parameters for the operation. For AEAD modes, this is used - * to specify KM_TAG_ADDITIONAL_DATA. Note that additional data may be provided in multiple - * calls to update(), but only until input data has been provided. - * - * \param[in] input Data to be processed, per the parameters established in the call to begin(). - * Note that update() may or may not consume all of the data provided. See \p input_consumed. - * - * \param[out] input_consumed Amount of data that was consumed by update(). If this is less - * than the amount provided, the caller should provide the remainder in a subsequent call to - * update(). - * - * \param[out] out_params Output parameters. Used to return additional data from the operation - * The caller takes ownership of the output parameters array and must free it with - * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are - * expected. If out_params is NULL, and output paramaters are generated, begin() will return - * KM_ERROR_OUTPUT_PARAMETER_NULL. - * - * \param[out] output The output data, if any. The caller assumes ownership of the allocated - * buffer. output must not be NULL. - * - * Note that update() may not provide any output, in which case output->data_length will be - * zero, and output->data may be either NULL or zero-length (so the caller should always free() - * it). - */ - keymaster_error_t (*update)(const struct keymaster1_device* dev, - keymaster_operation_handle_t operation_handle, - const keymaster_key_param_set_t* in_params, - const keymaster_blob_t* input, size_t* input_consumed, - keymaster_key_param_set_t* out_params, keymaster_blob_t* output); - - /** - * Finalizes a cryptographic operation begun with begin() and invalidates \p operation_handle. - * - * \param[in] dev The keymaster device structure. - * - * \param[in] operation_handle The operation handle returned by begin(). This handle will be - * invalidated. - * - * \param[in] params Additional parameters for the operation. For AEAD modes, this is used to - * specify KM_TAG_ADDITIONAL_DATA, but only if no input data was provided to update(). - * - * \param[in] signature The signature to be verified if the purpose specified in the begin() - * call was KM_PURPOSE_VERIFY. - * - * \param[out] output The output data, if any. The caller assumes ownership of the allocated - * buffer. - * - * If the operation being finished is a signature verification or an AEAD-mode decryption and - * verification fails then finish() will return KM_ERROR_VERIFICATION_FAILED. - */ - keymaster_error_t (*finish)(const struct keymaster1_device* dev, - keymaster_operation_handle_t operation_handle, - const keymaster_key_param_set_t* in_params, - const keymaster_blob_t* signature, - keymaster_key_param_set_t* out_params, keymaster_blob_t* output); - - /** - * Aborts a cryptographic operation begun with begin(), freeing all internal resources and - * invalidating \p operation_handle. - */ - keymaster_error_t (*abort)(const struct keymaster1_device* dev, - keymaster_operation_handle_t operation_handle); -}; -typedef struct keymaster1_device keymaster1_device_t; - -/* Convenience API for opening and closing keymaster devices */ - -static inline int keymaster1_open(const struct hw_module_t* module, keymaster1_device_t** device) { - return module->methods->open(module, KEYSTORE_KEYMASTER, TO_HW_DEVICE_T_OPEN(device)); -} - -static inline int keymaster1_close(keymaster1_device_t* device) { - return device->common.close(&device->common); -} - -__END_DECLS - -#endif // ANDROID_HARDWARE_KEYMASTER1_H -- cgit v1.2.3 From 6b834a3b75f9653bea921a17510faee52c3070dc Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Mon, 11 Oct 2021 13:38:59 +0000 Subject: Revert "Delete KM1" Revert submission 1844016-delkm1 Reason for revert: b/202675261 Reverted Changes: Iba996962b:Delete KM1 Ia4c5359cd:Delete KM1 Iee6ec9816:Delete KM1 I6058e4d86:Delete KM1 I8abb9c570:Delete KM1 I9c4dc5c9e:Delete KM1 Change-Id: If89a96dab30e85c9e9c3b4bf67d8aab20a273a54 --- include/hardware/keymaster1.h | 548 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 include/hardware/keymaster1.h diff --git a/include/hardware/keymaster1.h b/include/hardware/keymaster1.h new file mode 100644 index 00000000..99693806 --- /dev/null +++ b/include/hardware/keymaster1.h @@ -0,0 +1,548 @@ +/* + * Copyright (C) 2015 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_HARDWARE_KEYMASTER1_H +#define ANDROID_HARDWARE_KEYMASTER1_H + +#include +#include + +__BEGIN_DECLS + +/** + * Keymaster1 device definition + */ +struct keymaster1_device { + /** + * Common methods of the keymaster device. This *must* be the first member of + * keymaster_device as users of this structure will cast a hw_device_t to + * keymaster_device pointer in contexts where it's known the hw_device_t references a + * keymaster_device. + */ + struct hw_device_t common; + + /** + * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version" + * fields in the keymaster_module initialization instead. + */ + uint32_t client_version; + + /** + * See flags defined for keymaster0_devices::flags in keymaster_common.h + */ + uint32_t flags; + + void* context; + + /** + * \deprecated Generates a public and private key. The key-blob returned is opaque and must + * subsequently provided for signing and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*generate_keypair)(const struct keymaster1_device* dev, const keymaster_keypair_t key_type, + const void* key_params, uint8_t** key_blob, size_t* key_blob_length); + + /** + * \deprecated Imports a public and private key pair. The imported keys will be in PKCS#8 format + * with DER encoding (Java standard). The key-blob returned is opaque and will be subsequently + * provided for signing and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*import_keypair)(const struct keymaster1_device* dev, const uint8_t* key, + const size_t key_length, uint8_t** key_blob, size_t* key_blob_length); + + /** + * \deprecated Gets the public key part of a key pair. The public key must be in X.509 format + * (Java standard) encoded byte array. + * + * Returns: 0 on success or an error code less than 0. On error, x509_data + * should not be allocated. + */ + int (*get_keypair_public)(const struct keymaster1_device* dev, const uint8_t* key_blob, + const size_t key_blob_length, uint8_t** x509_data, + size_t* x509_data_length); + + /** + * \deprecated Deletes the key pair associated with the key blob. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_keypair)(const struct keymaster1_device* dev, const uint8_t* key_blob, + const size_t key_blob_length); + + /** + * \deprecated Deletes all keys in the hardware keystore. Used when keystore is reset + * completely. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_all)(const struct keymaster1_device* dev); + + /** + * \deprecated Signs data using a key-blob generated before. This can use either an asymmetric + * key or a secret key. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*sign_data)(const struct keymaster1_device* dev, const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, const uint8_t* data, + const size_t data_length, uint8_t** signed_data, size_t* signed_data_length); + + /** + * \deprecated Verifies data signed with a key-blob. This can use either an asymmetric key or a + * secret key. + * + * Returns: 0 on successful verification or an error code less than 0. + */ + int (*verify_data)(const struct keymaster1_device* dev, const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, + const uint8_t* signed_data, const size_t signed_data_length, + const uint8_t* signature, const size_t signature_length); + + /** + * Gets algorithms supported. + * + * \param[in] dev The keymaster device structure. + * + * \param[out] algorithms Array of algorithms supported. The caller takes ownership of the + * array and must free() it. + * + * \param[out] algorithms_length Length of \p algorithms. + */ + keymaster_error_t (*get_supported_algorithms)(const struct keymaster1_device* dev, + keymaster_algorithm_t** algorithms, + size_t* algorithms_length); + + /** + * Gets the block modes supported for the specified algorithm. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported modes will be returned. + * + * \param[out] modes Array of modes supported. The caller takes ownership of the array and must + * free() it. + * + * \param[out] modes_length Length of \p modes. + */ + keymaster_error_t (*get_supported_block_modes)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_block_mode_t** modes, + size_t* modes_length); + + /** + * Gets the padding modes supported for the specified algorithm. Caller assumes ownership of + * the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported padding modes will be returned. + * + * \param[out] modes Array of padding modes supported. The caller takes ownership of the array + * and must free() it. + * + * \param[out] modes_length Length of \p modes. + */ + keymaster_error_t (*get_supported_padding_modes)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_padding_t** modes, + size_t* modes_length); + + /** + * Gets the digests supported for the specified algorithm. Caller assumes ownership of the + * allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported digests will be returned. + * + * \param[out] digests Array of digests supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] digests_length Length of \p digests. + */ + keymaster_error_t (*get_supported_digests)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_digest_t** digests, + size_t* digests_length); + + /** + * Gets the key import formats supported for keys of the specified algorithm. Caller assumes + * ownership of the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported formats will be returned. + * + * \param[out] formats Array of formats supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] formats_length Length of \p formats. + */ + keymaster_error_t (*get_supported_import_formats)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_key_format_t** formats, + size_t* formats_length); + + /** + * Gets the key export formats supported for keys of the specified algorithm. Caller assumes + * ownership of the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported formats will be returned. + * + * \param[out] formats Array of formats supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] formats_length Length of \p formats. + */ + keymaster_error_t (*get_supported_export_formats)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_key_format_t** formats, + size_t* formats_length); + + /** + * Adds entropy to the RNG used by keymaster. Entropy added through this method is guaranteed + * not to be the only source of entropy used, and the mixing function is required to be secure, + * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot + * predict (or control), then the RNG output is indistinguishable from random. Thus, if the + * entropy from any source is good, the output will be good. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] data Random data to be mixed in. + * + * \param[in] data_length Length of \p data. + */ + keymaster_error_t (*add_rng_entropy)(const struct keymaster1_device* dev, const uint8_t* data, + size_t data_length); + + /** + * Generates a key, or key pair, returning a key blob and/or a description of the key. + * + * Key generation parameters are defined as keymaster tag/value pairs, provided in \p params. + * See keymaster_tag_t for the full list. Some values that are always required for generation + * of useful keys are: + * + * - KM_TAG_ALGORITHM; + * - KM_TAG_PURPOSE; and + * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. + * + * KM_TAG_AUTH_TIMEOUT should generally be specified unless KM_TAG_NO_AUTH_REQUIRED is present, + * or the user will have to authenticate for every use. + * + * KM_TAG_BLOCK_MODE, KM_TAG_PADDING, KM_TAG_MAC_LENGTH and KM_TAG_DIGEST must be specified for + * algorithms that require them. + * + * The following tags may not be specified; their values will be provided by the implementation. + * + * - KM_TAG_ORIGIN, + * - KM_TAG_ROLLBACK_RESISTANT, + * - KM_TAG_CREATION_DATETIME + * + * \param[in] dev The keymaster device structure. + * + * \param[in] params Array of key generation parameters. + * + * \param[in] params_count Length of \p params. + * + * \param[out] key_blob returns the generated key. \p key_blob must not be NULL. The caller + * assumes ownership key_blob->key_material and must free() it. + * + * \param[out] characteristics returns the characteristics of the key that was, generated, if + * non-NULL. If non-NULL, the caller assumes ownership and must deallocate with + * keymaster_free_characteristics(). Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and + * KM_TAG_APPLICATION_DATA are never returned. + */ + keymaster_error_t (*generate_key)(const struct keymaster1_device* dev, + const keymaster_key_param_set_t* params, + keymaster_key_blob_t* key_blob, + keymaster_key_characteristics_t** characteristics); + + /** + * Returns the characteristics of the specified key, or KM_ERROR_INVALID_KEY_BLOB if the + * key_blob is invalid (implementations must fully validate the integrity of the key). + * client_id and app_data must be the ID and data provided when the key was generated or + * imported, or empty if KM_TAG_APPLICATION_ID and/or KM_TAG_APPLICATION_DATA were not provided + * during generation. Those values are not included in the returned characteristics. The + * caller assumes ownership of the allocated characteristics object, which must be deallocated + * with keymaster_free_characteristics(). + * + * Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and KM_TAG_APPLICATION_DATA are never + * returned. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] key_blob The key to retreive characteristics from. + * + * \param[in] client_id The client ID data, or NULL if none associated. + * + * \param[in] app_id The app data, or NULL if none associated. + * + * \param[out] characteristics The key characteristics. + */ + keymaster_error_t (*get_key_characteristics)(const struct keymaster1_device* dev, + const keymaster_key_blob_t* key_blob, + const keymaster_blob_t* client_id, + const keymaster_blob_t* app_data, + keymaster_key_characteristics_t** characteristics); + + /** + * Imports a key, or key pair, returning a key blob and/or a description of the key. + * + * Most key import parameters are defined as keymaster tag/value pairs, provided in "params". + * See keymaster_tag_t for the full list. Values that are always required for import of useful + * keys are: + * + * - KM_TAG_ALGORITHM; + * - KM_TAG_PURPOSE; and + * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. + * + * KM_TAG_AUTH_TIMEOUT should generally be specified. If unspecified, the user will have to + * authenticate for every use. + * + * The following tags will take default values if unspecified: + * + * - KM_TAG_KEY_SIZE will default to the size of the key provided. + * - KM_TAG_RSA_PUBLIC_EXPONENT will default to the value in the key provided (for RSA keys) + * + * The following tags may not be specified; their values will be provided by the implementation. + * + * - KM_TAG_ORIGIN, + * - KM_TAG_ROLLBACK_RESISTANT, + * - KM_TAG_CREATION_DATETIME + * + * \param[in] dev The keymaster device structure. + * + * \param[in] params Parameters defining the imported key. + * + * \param[in] params_count The number of entries in \p params. + * + * \param[in] key_format specifies the format of the key data in key_data. + * + * \param[out] key_blob Used to return the opaque key blob. Must be non-NULL. The caller + * assumes ownership of the contained key_material. + * + * \param[out] characteristics Used to return the characteristics of the imported key. May be + * NULL, in which case no characteristics will be returned. If non-NULL, the caller assumes + * ownership and must deallocate with keymaster_free_characteristics(). Note that + * KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and + * KM_TAG_APPLICATION_DATA are never returned. + */ + keymaster_error_t (*import_key)(const struct keymaster1_device* dev, + const keymaster_key_param_set_t* params, + keymaster_key_format_t key_format, + const keymaster_blob_t* key_data, + keymaster_key_blob_t* key_blob, + keymaster_key_characteristics_t** characteristics); + + /** + * Exports a public key, returning a byte array in the specified format. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] export_format The format to be used for exporting the key. + * + * \param[in] key_to_export The key to export. + * + * \param[out] export_data The exported key material. The caller assumes ownership. + * + * \param[out] export_data_length The length of \p export_data. + */ + keymaster_error_t (*export_key)(const struct keymaster1_device* dev, + keymaster_key_format_t export_format, + const keymaster_key_blob_t* key_to_export, + const keymaster_blob_t* client_id, + const keymaster_blob_t* app_data, + keymaster_blob_t* export_data); + + /** + * Deletes the key, or key pair, associated with the key blob. After calling this function it + * will be impossible to use the key for any other operations. May be applied to keys from + * foreign roots of trust (keys not usable under the current root of trust). + * + * This function is optional and should be set to NULL if it is not implemented. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] key The key to be deleted. + */ + keymaster_error_t (*delete_key)(const struct keymaster1_device* dev, + const keymaster_key_blob_t* key); + + /** + * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After + * calling this function it will be impossible to use any previously generated or imported key + * blobs for any operations. + * + * This function is optional and should be set to NULL if it is not implemented. + * + * \param[in] dev The keymaster device structure. + */ + keymaster_error_t (*delete_all_keys)(const struct keymaster1_device* dev); + + /** + * Begins a cryptographic operation using the specified key. If all is well, begin() will + * return KM_ERROR_OK and create an operation handle which must be passed to subsequent calls to + * update(), finish() or abort(). + * + * It is critical that each call to begin() be paired with a subsequent call to finish() or + * abort(), to allow the keymaster implementation to clean up any internal operation state. + * Failure to do this may leak internal state space or other internal resources and may + * eventually cause begin() to return KM_ERROR_TOO_MANY_OPERATIONS when it runs out of space for + * operations. Any result other than KM_ERROR_OK from begin(), update() or finish() implicitly + * aborts the operation, in which case abort() need not be called (and will return + * KM_ERROR_INVALID_OPERATION_HANDLE if called). + * + * \param[in] dev The keymaster device structure. + * + * \param[in] purpose The purpose of the operation, one of KM_PURPOSE_ENCRYPT, + * KM_PURPOSE_DECRYPT, KM_PURPOSE_SIGN or KM_PURPOSE_VERIFY. Note that for AEAD modes, + * encryption and decryption imply signing and verification, respectively, but should be + * specified as KM_PURPOSE_ENCRYPT and KM_PURPOSE_DECRYPT. + * + * \param[in] key The key to be used for the operation. \p key must have a purpose compatible + * with \p purpose and all of its usage requirements must be satisfied, or begin() will return + * an appropriate error code. + * + * \param[in] in_params Additional parameters for the operation. This is typically used to + * provide authentication data, with KM_TAG_AUTH_TOKEN. If KM_TAG_APPLICATION_ID or + * KM_TAG_APPLICATION_DATA were provided during generation, they must be provided here, or the + * operation will fail with KM_ERROR_INVALID_KEY_BLOB. For operations that require a nonce or + * IV, on keys that were generated with KM_TAG_CALLER_NONCE, in_params may contain a tag + * KM_TAG_NONCE. For AEAD operations KM_TAG_CHUNK_SIZE is specified here. + * + * \param[out] out_params Output parameters. Used to return additional data from the operation + * initialization, notably to return the IV or nonce from operations that generate an IV or + * nonce. The caller takes ownership of the output parameters array and must free it with + * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are + * expected. If out_params is NULL, and output paramaters are generated, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + * + * \param[out] operation_handle The newly-created operation handle which must be passed to + * update(), finish() or abort(). If operation_handle is NULL, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + */ + keymaster_error_t (*begin)(const struct keymaster1_device* dev, keymaster_purpose_t purpose, + const keymaster_key_blob_t* key, + const keymaster_key_param_set_t* in_params, + keymaster_key_param_set_t* out_params, + keymaster_operation_handle_t* operation_handle); + + /** + * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun + * with begin(). + * + * If operation_handle is invalid, update() will return KM_ERROR_INVALID_OPERATION_HANDLE. + * + * update() may not consume all of the data provided in the data buffer. update() will return + * the amount consumed in *data_consumed. The caller should provide the unconsumed data in a + * subsequent call. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] operation_handle The operation handle returned by begin(). + * + * \param[in] in_params Additional parameters for the operation. For AEAD modes, this is used + * to specify KM_TAG_ADDITIONAL_DATA. Note that additional data may be provided in multiple + * calls to update(), but only until input data has been provided. + * + * \param[in] input Data to be processed, per the parameters established in the call to begin(). + * Note that update() may or may not consume all of the data provided. See \p input_consumed. + * + * \param[out] input_consumed Amount of data that was consumed by update(). If this is less + * than the amount provided, the caller should provide the remainder in a subsequent call to + * update(). + * + * \param[out] out_params Output parameters. Used to return additional data from the operation + * The caller takes ownership of the output parameters array and must free it with + * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are + * expected. If out_params is NULL, and output paramaters are generated, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + * + * \param[out] output The output data, if any. The caller assumes ownership of the allocated + * buffer. output must not be NULL. + * + * Note that update() may not provide any output, in which case output->data_length will be + * zero, and output->data may be either NULL or zero-length (so the caller should always free() + * it). + */ + keymaster_error_t (*update)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle, + const keymaster_key_param_set_t* in_params, + const keymaster_blob_t* input, size_t* input_consumed, + keymaster_key_param_set_t* out_params, keymaster_blob_t* output); + + /** + * Finalizes a cryptographic operation begun with begin() and invalidates \p operation_handle. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] operation_handle The operation handle returned by begin(). This handle will be + * invalidated. + * + * \param[in] params Additional parameters for the operation. For AEAD modes, this is used to + * specify KM_TAG_ADDITIONAL_DATA, but only if no input data was provided to update(). + * + * \param[in] signature The signature to be verified if the purpose specified in the begin() + * call was KM_PURPOSE_VERIFY. + * + * \param[out] output The output data, if any. The caller assumes ownership of the allocated + * buffer. + * + * If the operation being finished is a signature verification or an AEAD-mode decryption and + * verification fails then finish() will return KM_ERROR_VERIFICATION_FAILED. + */ + keymaster_error_t (*finish)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle, + const keymaster_key_param_set_t* in_params, + const keymaster_blob_t* signature, + keymaster_key_param_set_t* out_params, keymaster_blob_t* output); + + /** + * Aborts a cryptographic operation begun with begin(), freeing all internal resources and + * invalidating \p operation_handle. + */ + keymaster_error_t (*abort)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle); +}; +typedef struct keymaster1_device keymaster1_device_t; + +/* Convenience API for opening and closing keymaster devices */ + +static inline int keymaster1_open(const struct hw_module_t* module, keymaster1_device_t** device) { + return module->methods->open(module, KEYSTORE_KEYMASTER, TO_HW_DEVICE_T_OPEN(device)); +} + +static inline int keymaster1_close(keymaster1_device_t* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_HARDWARE_KEYMASTER1_H -- cgit v1.2.3 From 24ead9d84a9d9ef077f4d44995e2add9a79a206d Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Wed, 3 Nov 2021 15:32:49 -0700 Subject: dynamic_sensor: Don't hold mgr lock when operating sensor. Bug: 205041452 Test: Verified that multiple subscriptions can be made with sensor_test to a dynamic sensor without hanging. Change-Id: Ie7671df8294bee04a0ebe1940242c2a83105f897 --- .../sensors/dynamic_sensor/DynamicSensorManager.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h index 634c5234..264582ec 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h @@ -95,15 +95,18 @@ private: // TF: int foo(sp obj); template int operateSensor(int handle, TF f) const { - std::lock_guard lk(mLock); - const auto i = mMap.find(handle); - if (i == mMap.end()) { - return BAD_VALUE; - } - sp s = i->second.promote(); - if (s == nullptr) { - // sensor object is already gone - return BAD_VALUE; + sp s; + { + std::lock_guard lk(mLock); + const auto i = mMap.find(handle); + if (i == mMap.end()) { + return BAD_VALUE; + } + s = i->second.promote(); + if (s == nullptr) { + // sensor object is already gone + return BAD_VALUE; + } } return f(s); } -- cgit v1.2.3 From f99f73ceebb4a0cfe7b8554194b9dc54f05a902f Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Mon, 22 Nov 2021 10:56:57 -0800 Subject: dynamic_sensor: Support report and power usage collections. Bug: 207008609 Test: Verified dynamic sensor sampling. Change-Id: If0bef3647d5c52f9bf1d92a2a0ead72e98c70b8c --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 68 ++++++++++++++++++---- modules/sensors/dynamic_sensor/HidRawSensor.h | 4 ++ modules/sensors/dynamic_sensor/HidSensorDef.h | 30 +++++----- .../sensors/dynamic_sensor/HidUtils/HidParser.cpp | 1 + .../sensors/dynamic_sensor/HidUtils/HidParser.h | 1 + 5 files changed, 79 insertions(+), 25 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index f3c8a27b..91aed0a5 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -784,8 +784,9 @@ bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) { } bool HidRawSensor::findSensorControlUsage(const std::vector &packets) { + using namespace Hid::Sensor::PowerStateUsage; using namespace Hid::Sensor::PropertyUsage; - using namespace Hid::Sensor::RawMinMax; + using namespace Hid::Sensor::ReportingStateUsage; //REPORTING_STATE const HidParser::ReportItem *reportingState @@ -793,13 +794,31 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorisByteAligned() - || reportingState->bitSize != 8 - || reportingState->minRaw != REPORTING_STATE_MIN - || reportingState->maxRaw != REPORTING_STATE_MAX) { + || reportingState->bitSize != 8) { LOG_W << "Cannot find valid reporting state feature" << LOG_ENDL; } else { mReportingStateId = reportingState->id; mReportingStateOffset = reportingState->bitOffset / 8; + + 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; + } } //POWER_STATE @@ -807,13 +826,31 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorisByteAligned() - || powerState->bitSize != 8 - || powerState->minRaw != POWER_STATE_MIN - || powerState->maxRaw != POWER_STATE_MAX) { + || powerState->bitSize != 8) { LOG_W << "Cannot find valid power state feature" << LOG_ENDL; } else { mPowerStateId = powerState->id; mPowerStateOffset = powerState->bitOffset / 8; + + 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; + } } //REPORT_INTERVAL @@ -846,7 +883,6 @@ 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) { @@ -864,7 +900,8 @@ int HidRawSensor::enable(bool enable) { uint8_t id = static_cast(mPowerStateId); if (device->getFeature(id, &buffer) && buffer.size() > mPowerStateOffset) { - buffer[mPowerStateOffset] = enable ? POWER_STATE_FULL_POWER : POWER_STATE_POWER_OFF; + buffer[mPowerStateOffset] = + enable ? mPowerStateOnIndex : mPowerStateOffIndex; setPowerOk = device->setFeature(id, buffer); } else { LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL; @@ -878,7 +915,8 @@ int HidRawSensor::enable(bool enable) { if (device->getFeature(id, &buffer) && buffer.size() > mReportingStateOffset) { buffer[mReportingStateOffset] - = enable ? REPORTING_STATE_ALL_EVENT : REPORTING_STATE_NO_EVENT; + = enable ? mReportingStateEnableIndex : + mReportingStateDisableIndex; setReportingOk = device->setFeature(id, buffer); } else { LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL; @@ -1019,7 +1057,10 @@ std::string HidRawSensor::dump() const { ss << " Power state "; if (mPowerStateId >= 0) { ss << "found, id: " << mPowerStateId - << " offset: " << mPowerStateOffset << LOG_ENDL; + << " offset: " << mPowerStateOffset + << " power off index: " << mPowerStateOffIndex + << " power on index: " << mPowerStateOnIndex + << LOG_ENDL; } else { ss << "not found" << LOG_ENDL; } @@ -1027,7 +1068,10 @@ std::string HidRawSensor::dump() const { ss << " Reporting state "; if (mReportingStateId >= 0) { ss << "found, id: " << mReportingStateId - << " offset: " << mReportingStateOffset << LOG_ENDL; + << " offset: " << mReportingStateOffset + << " disable index: " << mReportingStateDisableIndex + << " enable index: " << mReportingStateEnableIndex + << 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 2dd32b61..201e72e9 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -138,9 +138,13 @@ private: // Features for control sensor int mReportingStateId; unsigned int mReportingStateOffset; + int mReportingStateDisableIndex; + int mReportingStateEnableIndex; int mPowerStateId; unsigned int mPowerStateOffset; + int mPowerStateOffIndex; + int mPowerStateOnIndex; int mReportIntervalId; unsigned int mReportIntervalOffset; diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h index 2728b28a..8f47a850 100644 --- a/modules/sensors/dynamic_sensor/HidSensorDef.h +++ b/modules/sensors/dynamic_sensor/HidSensorDef.h @@ -77,24 +77,28 @@ enum { }; } // namespace ReportUsage -namespace RawMinMax { +namespace ReportingStateUsage { enum { - REPORTING_STATE_MIN = 0, - REPORTING_STATE_MAX = 5, - POWER_STATE_MIN = 0, - POWER_STATE_MAX = 5, + 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, }; -} // namespace RawMinMax +} // namespace ReportingStateUsage -namespace StateValue { +namespace PowerStateUsage { enum { - POWER_STATE_FULL_POWER = 1, - POWER_STATE_POWER_OFF = 5, - - REPORTING_STATE_ALL_EVENT = 1, - REPORTING_STATE_NO_EVENT = 0, + 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, }; -} // StateValue +} // namespace PowerStateUsage + } // namespace Sensor } // namespace Hid #endif // HID_SENSOR_DEF_H_ diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp index 264f13c2..704a1b39 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp @@ -248,6 +248,7 @@ std::vector HidParser::convertGroupToPacket( ReportItem digest = { .usage = r.getFullUsage(), .id = id, + .usageVector = r.getUsageVector(), .minRaw = logical.first, .maxRaw = logical.second, .a = scale, diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h index 4ef5ec6c..20dcf637 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h @@ -89,6 +89,7 @@ struct HidParser::ReportItem { unsigned int usage; unsigned int id; int type; // feature, input or output + std::vector usageVector; int64_t minRaw; int64_t maxRaw; -- cgit v1.2.3 From 4cb45aba7f1bab4465e61b517b6784de4e98529e Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Mon, 29 Nov 2021 15:39:47 -0800 Subject: dynamic_sensor: Support non-8-bit sized HID report items. Bug: 207008609 Test: Verified dynamic sensor sampling. Test: Verified unit tests pass. Change-Id: I797ccabadefa0dde59fd0f3e8541f9853d657f3f --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 75 +++++++++++----------- modules/sensors/dynamic_sensor/HidRawSensor.h | 10 +-- modules/sensors/dynamic_sensor/HidUtils/Android.bp | 18 ++++++ .../sensors/dynamic_sensor/HidUtils/HidParser.cpp | 1 + .../sensors/dynamic_sensor/HidUtils/HidParser.h | 1 + .../sensors/dynamic_sensor/HidUtils/HidUtils.cpp | 72 +++++++++++++++++++++ modules/sensors/dynamic_sensor/HidUtils/HidUtils.h | 29 +++++++++ .../dynamic_sensor/HidUtils/test/CopyBitsTest.cpp | 73 +++++++++++++++++++++ 8 files changed, 236 insertions(+), 43 deletions(-) create mode 100644 modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp create mode 100644 modules/sensors/dynamic_sensor/HidUtils/HidUtils.h create mode 100644 modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 91aed0a5..531ab9d5 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -19,6 +19,8 @@ #include #include "HidLog.h" +#include + #include #include #include @@ -792,13 +794,12 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorisByteAligned() - || reportingState->bitSize != 8) { + if (reportingState == nullptr) { LOG_W << "Cannot find valid reporting state feature" << LOG_ENDL; } else { mReportingStateId = reportingState->id; - mReportingStateOffset = reportingState->bitOffset / 8; + mReportingStateBitOffset = reportingState->bitOffset; + mReportingStateBitSize = reportingState->bitSize; mReportingStateDisableIndex = -1; mReportingStateEnableIndex = -1; @@ -824,13 +825,12 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorisByteAligned() - || powerState->bitSize != 8) { + if (powerState == nullptr) { LOG_W << "Cannot find valid power state feature" << LOG_ENDL; } else { mPowerStateId = powerState->id; - mPowerStateOffset = powerState->bitOffset / 8; + mPowerStateBitOffset = powerState->bitOffset; + mPowerStateBitSize = powerState->bitSize; mPowerStateOffIndex = -1; mPowerStateOnIndex = -1; @@ -857,14 +857,12 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorisByteAligned() - || reportInterval->minRaw < 0 - || (reportInterval->bitSize != 16 && reportInterval->bitSize != 32)) { + || reportInterval->minRaw < 0) { LOG_W << "Cannot find valid report interval feature" << LOG_ENDL; } else { mReportIntervalId = reportInterval->id; - mReportIntervalOffset = reportInterval->bitOffset / 8; - mReportIntervalSize = reportInterval->bitSize / 8; + mReportIntervalBitOffset = reportInterval->bitOffset; + mReportIntervalBitSize = reportInterval->bitSize; mFeatureInfo.minDelay = std::max(static_cast(1), reportInterval->minRaw) * 1000; mFeatureInfo.maxDelay = std::min(static_cast(1000000), @@ -899,9 +897,11 @@ int HidRawSensor::enable(bool enable) { setPowerOk = false; uint8_t id = static_cast(mPowerStateId); if (device->getFeature(id, &buffer) - && buffer.size() > mPowerStateOffset) { - buffer[mPowerStateOffset] = - enable ? mPowerStateOnIndex : mPowerStateOffIndex; + && (8 * buffer.size()) >= + (mPowerStateBitOffset + mPowerStateBitSize)) { + uint8_t index = enable ? mPowerStateOnIndex : mPowerStateOffIndex; + HidUtil::copyBits(&index, &(buffer[0]), buffer.size(), + 0, mPowerStateBitOffset, mPowerStateBitSize); setPowerOk = device->setFeature(id, buffer); } else { LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL; @@ -913,10 +913,12 @@ int HidRawSensor::enable(bool enable) { setReportingOk = false; uint8_t id = static_cast(mReportingStateId); if (device->getFeature(id, &buffer) - && buffer.size() > mReportingStateOffset) { - buffer[mReportingStateOffset] - = enable ? mReportingStateEnableIndex : - mReportingStateDisableIndex; + && (8 * buffer.size()) > + (mReportingStateBitOffset + mReportingStateBitSize)) { + uint8_t index = enable ? mReportingStateEnableIndex : + mReportingStateDisableIndex; + HidUtil::copyBits(&index, &(buffer[0]), buffer.size(),0, + mReportingStateBitOffset, mReportingStateBitSize); setReportingOk = device->setFeature(id, buffer); } else { LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL; @@ -949,22 +951,15 @@ int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) { ok = false; uint8_t id = static_cast(mReportIntervalId); if (device->getFeature(id, &buffer) - && buffer.size() >= mReportIntervalOffset + mReportIntervalSize) { + && (8 * buffer.size()) >= + (mReportIntervalBitOffset + mReportIntervalBitSize)) { int64_t periodMs = samplingPeriod / 1000000; //ns -> ms - switch (mReportIntervalSize) { - case sizeof(uint16_t): - periodMs = std::min(periodMs, static_cast(UINT16_MAX)); - buffer[mReportIntervalOffset] = periodMs & 0xFF; - buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF; - break; - case sizeof(uint32_t): - periodMs = std::min(periodMs, static_cast(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; - } + int64_t maxPeriodMs = + (1LL << std::min(mReportIntervalBitSize, 63U)) - 1; + periodMs = std::min(periodMs, maxPeriodMs); + HidUtil::copyBits(&periodMs, &(buffer[0]), buffer.size(), + 0, mReportIntervalBitOffset, + mReportIntervalBitSize); ok = device->setFeature(id, buffer); } } @@ -1057,7 +1052,8 @@ std::string HidRawSensor::dump() const { ss << " Power state "; if (mPowerStateId >= 0) { ss << "found, id: " << mPowerStateId - << " offset: " << mPowerStateOffset + << " bit offset: " << mPowerStateBitOffset + << " bit size: " << mPowerStateBitSize << " power off index: " << mPowerStateOffIndex << " power on index: " << mPowerStateOnIndex << LOG_ENDL; @@ -1068,7 +1064,8 @@ std::string HidRawSensor::dump() const { ss << " Reporting state "; if (mReportingStateId >= 0) { ss << "found, id: " << mReportingStateId - << " offset: " << mReportingStateOffset + << " bit offset: " << mReportingStateBitOffset + << " bit size: " << mReportingStateBitSize << " disable index: " << mReportingStateDisableIndex << " enable index: " << mReportingStateEnableIndex << LOG_ENDL; @@ -1079,8 +1076,8 @@ std::string HidRawSensor::dump() const { ss << " Report interval "; if (mReportIntervalId >= 0) { ss << "found, id: " << mReportIntervalId - << " offset: " << mReportIntervalOffset - << " size: " << mReportIntervalSize << LOG_ENDL; + << " bit offset: " << mReportIntervalBitOffset + << " bit size: " << mReportIntervalBitSize << 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 201e72e9..99ddfe30 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -137,18 +137,20 @@ private: // Features for control sensor int mReportingStateId; - unsigned int mReportingStateOffset; + unsigned int mReportingStateBitOffset; + unsigned int mReportingStateBitSize; int mReportingStateDisableIndex; int mReportingStateEnableIndex; int mPowerStateId; - unsigned int mPowerStateOffset; + unsigned int mPowerStateBitOffset; + unsigned int mPowerStateBitSize; int mPowerStateOffIndex; int mPowerStateOnIndex; int mReportIntervalId; - unsigned int mReportIntervalOffset; - unsigned int mReportIntervalSize; + unsigned int mReportIntervalBitOffset; + unsigned int mReportIntervalBitSize; // Input report translate table std::vector mTranslateTable; diff --git a/modules/sensors/dynamic_sensor/HidUtils/Android.bp b/modules/sensors/dynamic_sensor/HidUtils/Android.bp index bbed0327..5823c794 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/Android.bp +++ b/modules/sensors/dynamic_sensor/HidUtils/Android.bp @@ -45,6 +45,7 @@ cc_library { "HidParser.cpp", "HidReport.cpp", "HidTree.cpp", + "HidUtils.cpp", ], export_include_dirs: ["."], @@ -99,3 +100,20 @@ 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 704a1b39..28d87d97 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp @@ -317,4 +317,5 @@ 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 20dcf637..cb4a92a8 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h @@ -174,6 +174,7 @@ 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 new file mode 100644 index 00000000..0cce2a39 --- /dev/null +++ b/modules/sensors/dynamic_sensor/HidUtils/HidUtils.cpp @@ -0,0 +1,72 @@ +/* + * 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 +#include + +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(dst_bit_offset) > (8 * dst_size)) || + (static_cast(bit_count) > (8 * dst_size)) || + (static_cast(dst_bit_offset + bit_count) > (8 * dst_size))) { + return; + } + + // Copy bits from source to destination buffer. + p_src = static_cast(src) + (src_bit_offset / 8); + src_bit_offset = src_bit_offset % 8; + p_dst = static_cast(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 new file mode 100644 index 00000000..54aa31e9 --- /dev/null +++ b/modules/sensors/dynamic_sensor/HidUtils/HidUtils.h @@ -0,0 +1,29 @@ +/* + * 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 + +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 new file mode 100644 index 00000000..1b1ca709 --- /dev/null +++ b/modules/sensors/dynamic_sensor/HidUtils/test/CopyBitsTest.cpp @@ -0,0 +1,73 @@ +/* + * 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 + +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); + } +} + -- cgit v1.2.3 From dbf2545214d16eaed5901bd41c8c8e8871ef0168 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Thu, 2 Dec 2021 14:41:55 -0800 Subject: dynamic_sensor: Support recognizing head tracker sensor. Bug: 207008609 Test: Verified dynamic sensor sampling with proposed standard Android head tracker. Test: Verified dynamic sensor sampling with custom Android sensor. Change-Id: Ia9b991d4a8f7de132cb8509bcc84c51f62e56b31 --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 59 ++++++++++++++++++------- modules/sensors/dynamic_sensor/HidRawSensor.h | 8 ++++ 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 531ab9d5..8aaf2d4f 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -492,13 +492,8 @@ bool HidRawSensor::populateFeatureValueFromFeatureReport( } 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)) { - mFeatureInfo.isAndroidCustom = detectAndroidCustomSensor(str); + detectSensorFromDescription(str); } break; default: @@ -583,26 +578,34 @@ bool HidRawSensor::validateFeatureValueAndBuildSensor() { bool HidRawSensor::decodeString( const HidParser::ReportItem &report, const std::vector &buffer, std::string *d) { - if (!report.isByteAligned() || report.bitSize != 16 || report.count < 1) { + if (!report.isByteAligned() || + (report.bitSize != 8 && report.bitSize != 16) || report.count < 1) { return false; } + size_t charSize = report.bitSize / 8; size_t offset = report.bitOffset / 8; - if (offset + report.count * 2 > buffer.size()) { + if (offset + report.count * charSize > buffer.size()) { return false; } - std::vector 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); + if (charSize == 1) { + *d = std::string(buffer.begin() + offset, + buffer.begin() + offset + report.count); + } else { + std::vector 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, wchar_t> converter; + *d = converter.to_bytes(wstr); } - std::wstring wstr(data.begin(), data.end()); - std::wstring_convert, wchar_t> converter; - *d = converter.to_bytes(wstr); return true; } @@ -621,6 +624,28 @@ std::vector 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_DEVICE_PRIVATE_BASE; + mFeatureInfo.typeString = CUSTOM_TYPE_PREFIX + "headtracker"; + mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE; + mFeatureInfo.permission = ""; + mFeatureInfo.isWakeUp = false; + + return true; +} + bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) { size_t nullPosition = description.find('\0'); if (nullPosition == std::string::npos) { diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index 99ddfe30..0989651f 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -121,6 +121,14 @@ private: // helper function to find sensor control feature usage from packets bool findSensorControlUsage(const std::vector &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); -- cgit v1.2.3 From 0b5ab223e110f3a34b30e7b61e4ea68c03dba98b Mon Sep 17 00:00:00 2001 From: YiMing Tseng Date: Thu, 11 Nov 2021 14:05:30 +0800 Subject: Add GRALLOC_FRAMEBUFFER_NUM configuration Add config to set the NUM_BUFFERS. Set NUM_BUFFERS to 1 can prevent page flipping and set it to a larger number can allow userspace to fill up the following frame earlier. Bug: 205917753 Change-Id: Ibf4a52a1e35f4a2404008a48b637cb82c4b46365 --- modules/gralloc/Android.mk | 3 +++ modules/gralloc/framebuffer.cpp | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk index 439c95dd..4c4899ea 100644 --- a/modules/gralloc/Android.mk +++ b/modules/gralloc/Android.mk @@ -38,5 +38,8 @@ 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 b2ec3e44..fc220dbc 100644 --- a/modules/gralloc/framebuffer.cpp +++ b/modules/gralloc/framebuffer.cpp @@ -45,8 +45,10 @@ #define USE_PAN_DISPLAY 0 #endif -// numbers of buffers for page flipping +// Enabling page flipping by default +#ifndef NUM_BUFFERS #define NUM_BUFFERS 2 +#endif enum { @@ -157,7 +159,8 @@ int mapFrameBufferLocked(struct private_module_t* module, int format) info.activate = FB_ACTIVATE_NOW; /* - * Request NUM_BUFFERS screens (at lest 2 for page flipping) + * Request NUM_BUFFERS screens + * To enable page flipping, NUM_BUFFERS should be at least 2. */ info.yres_virtual = info.yres * NUM_BUFFERS; -- cgit v1.2.3 From 4b4cb8dab3ae8d0cc01af25984473799bbf939c9 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Fri, 10 Dec 2021 12:20:22 -0800 Subject: dynamic_sensor: Fix report item offset calculation. Bug: 207008609 Test: Verified dynamic sensor sampling with proposed standard Android head tracker. Change-Id: I163b79c2c99f02961adebcb5dcb7e39603944e24 --- modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp index 28d87d97..19aa4291 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp @@ -240,10 +240,12 @@ std::vector HidParser::convertGroupToPacket( auto logical = r.getLogicalRange(); auto physical = r.getPhysicalRange(); - int64_t offset = physical.first - logical.first; double scale = static_cast((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(), -- cgit v1.2.3 From 635b7068891a393f793c1d4d2f76672945270d08 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 17 Nov 2021 10:12:17 +0000 Subject: Add new KeyMint curve enum Bug: 194358913 Test: VtsAidlKeyMintTargetTest Change-Id: I6fb21c0662f2c810a086c5146fa3caa51be9464e --- include/hardware/keymaster_defs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index c0b3800e..930aceb0 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -304,6 +304,7 @@ 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; /** -- cgit v1.2.3 From 75fb5d739efcc61ba296a477493aa774ff99c239 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Wed, 15 Dec 2021 11:41:41 -0800 Subject: Add dynamic sensor README.md. Bug: 207008609 Test: Verified in gitiles. Change-Id: I7bb8575aef0a8764390a6dc8f4ca785f49a1eb61 --- modules/sensors/dynamic_sensor/README.md | 152 +++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 modules/sensors/dynamic_sensor/README.md diff --git a/modules/sensors/dynamic_sensor/README.md b/modules/sensors/dynamic_sensor/README.md new file mode 100644 index 00000000..49e541e3 --- /dev/null +++ b/modules/sensors/dynamic_sensor/README.md @@ -0,0 +1,152 @@ +# 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 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$ +``` + -- cgit v1.2.3 From a33c1654fb5086670767296ba52c8e86549867b7 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Thu, 8 Jul 2021 11:21:33 -0700 Subject: r_submix HAL: remove legacy code for in-pipe conversions Old hacky uses of this HAL required channel and sample rate conversion, which were never expected when this HAL is used for its real application as the backend for dynamic audio policies. In that context conversions are performed in audio_flinger in the mixer. Bug: 141604269 Test: atest AudioHostTest#testTwoChannelCapturing Change-Id: I333e981fb3db403ab2da6f77debe49bc7d132ebc --- modules/audio_remote_submix/audio_hw.cpp | 214 ++----------------------------- 1 file changed, 8 insertions(+), 206 deletions(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index b43a44dc..a944caad 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -83,10 +83,7 @@ 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" @@ -130,11 +127,6 @@ 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. @@ -159,11 +151,6 @@ 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 { @@ -325,7 +312,6 @@ 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) { @@ -333,13 +319,8 @@ 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; @@ -376,24 +357,11 @@ 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); @@ -403,18 +371,14 @@ 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}; @@ -444,11 +408,7 @@ 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); @@ -473,10 +433,6 @@ 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 @@ -624,11 +580,7 @@ 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(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; @@ -637,17 +589,6 @@ 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; @@ -994,11 +935,7 @@ 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(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; } @@ -1006,15 +943,6 @@ 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; @@ -1033,13 +961,6 @@ 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); @@ -1168,65 +1089,10 @@ 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()); @@ -1234,56 +1100,6 @@ 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); @@ -1464,13 +1280,6 @@ 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 @@ -1779,16 +1588,9 @@ 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; -- cgit v1.2.3 From 16699d13ec2ba0a068ac9c8d808c429e29f8c9c0 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Thu, 30 Dec 2021 16:29:03 -0800 Subject: r_submix: add owners file Bug: 141604269 Test: see gerrit Change-Id: I975390f8f495267ef0cd24dc8e73db859e541146 --- modules/audio_remote_submix/OWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 modules/audio_remote_submix/OWNERS diff --git a/modules/audio_remote_submix/OWNERS b/modules/audio_remote_submix/OWNERS new file mode 100644 index 00000000..67da0f90 --- /dev/null +++ b/modules/audio_remote_submix/OWNERS @@ -0,0 +1,3 @@ +elaurent@google.com +mnaganov@google.com +jmtrivi@google.com -- cgit v1.2.3 From 3f7bbbb4f15fb9ffb3eba0877d950f67f0e9fb21 Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Wed, 5 Jan 2022 07:00:42 -0800 Subject: r_submix HAL: Remove unused variable We no longer set force_pipe_creation after the removal of legacy code for in-pipe conversions, so we remove it. Test: TreeHugger Bug: 141604269 Change-Id: I82393ba0ad3142aa75d482cc6b0edbaeebbd8116 --- modules/audio_remote_submix/audio_hw.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index a944caad..42d3b98d 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -1227,7 +1227,6 @@ 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; @@ -1283,7 +1282,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, // 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()) || force_pipe_creation) { + && rsxadev->routes[route_idx].rsxSink->isShutdown())) { submix_audio_device_release_pipe_l(rsxadev, route_idx); } -- cgit v1.2.3 From 8262a62fb22ced829cc2613a2c911eda50994b00 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Thu, 6 Jan 2022 12:28:06 -0800 Subject: dynamic_sensor: Use HID unique ID for head tracker UUID. Also, don't require 16-bit strings for HID name, manufacturer, and unique ID. Also change dump of HID unique ID to be in hex. Bug: 213483369 Test: Verified that the standard Android head tracker sensor uses the HID unique ID for the sensor UUID. Test: Verified that custom Android sensors use a fabricated UUID. Change-Id: I125f84187868543dccab758e22dce744c013578e --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 47 ++++++++++++++----------- modules/sensors/dynamic_sensor/HidRawSensor.h | 1 + 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 8aaf2d4f..66542280 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -439,6 +439,7 @@ 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; } @@ -465,28 +466,16 @@ 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; } @@ -541,10 +530,19 @@ bool HidRawSensor::validateFeatureValueAndBuildSensor() { } // initialize uuid field, use name, vendor and uniqueId - if (mFeatureInfo.name.size() >= 4 - && mFeatureInfo.vendor.size() >= 4 - && mFeatureInfo.typeString.size() >= 4 - && mFeatureInfo.uniqueId.size() >= 4) { + // 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) { uint32_t tmp[4], h; std::hash stringHash; h = stringHash(mFeatureInfo.uniqueId); @@ -643,6 +641,11 @@ bool HidRawSensor::detectAndroidHeadTrackerSensor( 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; } @@ -1055,11 +1058,15 @@ 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 - << " uniqueId: " << mFeatureInfo.uniqueId << LOG_ENDL - << " uuid: "; + << " 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(d) << " "; + } + ss << std::dec << std::setfill(' ') << LOG_ENDL; - ss << std::hex << std::setfill('0'); + ss << " uuid: " << std::hex << std::setfill('0'); for (auto d : mFeatureInfo.uuid) { ss << std::setw(2) << static_cast(d) << " "; } diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index 0989651f..f6d13b59 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -86,6 +86,7 @@ private: size_t fifoMaxSize; uint32_t reportModeFlag; bool isWakeUp; + bool useUniqueIdForUuid; // dynamic sensor specific std::string uniqueId; -- cgit v1.2.3 From d3e67d55acd051c3fe1877bc0ce3081e39a15c8d Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Mon, 20 Dec 2021 18:03:27 -0800 Subject: Add definitions for new head tracker sensor type Bug: 210156629 Test: n/a Change-Id: If267401f059fe1377e495a91776b2eb4448fd1ef --- include/hardware/sensors-base.h | 1 + include/hardware/sensors.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h index ef7eead4..b88a8c2c 100644 --- a/include/hardware/sensors-base.h +++ b/include/hardware/sensors-base.h @@ -52,6 +52,7 @@ 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_DEVICE_PRIVATE_BASE = 65536 /* 0x10000 */, }; diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index a03a4095..cef5dd61 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -186,6 +186,7 @@ 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" /** * Values returned by the accelerometer in various locations in the universe. -- cgit v1.2.3 From c76c1d579965d967ff99264a16342ee33ae870c6 Mon Sep 17 00:00:00 2001 From: Zhaoming Yin Date: Sun, 16 Jan 2022 08:12:51 -0800 Subject: Fix opendir NULL dirp return issue Bug: 206035991 Test: use forrest to run boottest Change-Id: I9e77b7d6184a0ee132b8f058f7f83302c54bcb4a --- modules/sensors/dynamic_sensor/ConnectionDetector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp index c009a707..85b99017 100644 --- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp +++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp @@ -156,6 +156,10 @@ 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); -- cgit v1.2.3 From 2588d7555499a663473ef7df3d8081459e262c2b Mon Sep 17 00:00:00 2001 From: Eva Chen Date: Fri, 9 Apr 2021 15:42:31 -0700 Subject: Add limited axes imu sensor type definitions. Included sensors: - SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES - SENSOR_TYPE_GYROSCOPE_LIMITED_AXES - SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED - SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED These changes will enable support for automotive style IMUs that have more limited axes for accelerometers (x-axis and y-axis) and gyroscopes (z-axis). Bug: 187342209 Test: N/A Change-Id: Iff0553c88f62e4b5693a72116173063f35b914e9 --- include/hardware/sensors-base.h | 4 ++++ include/hardware/sensors.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h index b88a8c2c..7dc42a0a 100644 --- a/include/hardware/sensors-base.h +++ b/include/hardware/sensors-base.h @@ -53,6 +53,10 @@ enum { 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_DEVICE_PRIVATE_BASE = 65536 /* 0x10000 */, }; diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index cef5dd61..3101fdc9 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -187,6 +187,10 @@ enum { #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" /** * Values returned by the accelerometer in various locations in the universe. -- cgit v1.2.3 From 373a1b9fe96bd489c0a4d2f90a40176dbf3db318 Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Wed, 19 Jan 2022 16:06:13 -0800 Subject: Add head tracker to sensors_event_t Bug: 210156629 Test: compile (definitions only) Change-Id: Ic76e8b957a4e1660dd975fd3195b7b2aa31035b4 --- include/hardware/sensors.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index cef5dd61..56865162 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -292,6 +292,16 @@ 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; + /** * Union of the various types of sensor data * that can be returned. @@ -369,6 +379,9 @@ 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; }; union { -- cgit v1.2.3 From 78e7f9c0f161e0bfbeabd51dca0ac0d2796fb665 Mon Sep 17 00:00:00 2001 From: Zhaoming Yin Date: Sun, 16 Jan 2022 08:12:51 -0800 Subject: Fix opendir NULL dirp return issue Bug: 206035991 Test: use forrest to run boottest Change-Id: I9e77b7d6184a0ee132b8f058f7f83302c54bcb4a (cherry picked from commit c76c1d579965d967ff99264a16342ee33ae870c6) --- modules/sensors/dynamic_sensor/ConnectionDetector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp index c009a707..85b99017 100644 --- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp +++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp @@ -156,6 +156,10 @@ 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); -- cgit v1.2.3 From 3cbc4a02cee59da505e8a3981e9128ea3554446e Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Fri, 21 Jan 2022 10:52:17 -0800 Subject: Update OWNERS for legacy sensors definitions Bug: None Test: n/a Change-Id: Ic67b5721372ab357faef37b64d89f9bf973182d2 --- OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS b/OWNERS index b6b18dac..53e5f73f 100644 --- a/OWNERS +++ b/OWNERS @@ -5,3 +5,4 @@ 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 -- cgit v1.2.3 From 6515145f9c77acc3194b85c2325413a0384439d3 Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Thu, 20 Jan 2022 23:52:29 +0000 Subject: Add limited axes imu types to sensors_event_t Bug: 187342209 Test: compile (definitions only) Change-Id: Ifa89e45f24a4b4647b4c36b72b5d033397252ee1 --- include/hardware/sensors.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index 56865162..9ee1354b 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -302,6 +302,58 @@ typedef struct { 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; + /** * Union of the various types of sensor data * that can be returned. @@ -382,6 +434,20 @@ typedef struct sensors_event_t { /* 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; }; union { -- cgit v1.2.3 From 544076be9c0e775ef6a3afba43173efe588c545d Mon Sep 17 00:00:00 2001 From: Eva Chen Date: Mon, 10 Jan 2022 21:17:02 -0800 Subject: Add TYPE_HEADING sensor type definitions. Bug: 189983308 Test: Presubmits Change-Id: I74186ac6685a376158101f65d2687f1905c09814 --- include/hardware/sensors-base.h | 1 + include/hardware/sensors.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h index 7dc42a0a..dbf99f57 100644 --- a/include/hardware/sensors-base.h +++ b/include/hardware/sensors-base.h @@ -57,6 +57,7 @@ enum { 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 589aba02..a5ae0860 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -191,6 +191,7 @@ enum { #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. -- cgit v1.2.3 From 3d9af7ccfda5b3e74a2728f397e339543053a407 Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Fri, 21 Jan 2022 00:04:35 +0000 Subject: Add heading to sensors_event_t Bug: 189983308 Test: compile (definitions only) Change-Id: I01b75ecae37755bf43321d99e465a9dc42e2e318 --- include/hardware/sensors.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h index 589aba02..a8bc4ec6 100644 --- a/include/hardware/sensors.h +++ b/include/hardware/sensors.h @@ -358,6 +358,14 @@ typedef struct { }; } 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. @@ -452,6 +460,9 @@ typedef struct sensors_event_t { * 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 { -- cgit v1.2.3 From e689139808905178a06ede28142f8966146ce4a6 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 27 Jan 2022 15:55:40 +0100 Subject: Audio HAL: Add latency mode APIs Add APis for controlling the latency mode on an output stream. Latency mode control is optional but mandated if spatial audio with head tracking is supported over Bluetooth classic audio link. Bug: 187446271 Test: make Change-Id: I30a7f34a265ddac69b283c803b5729770426ebf1 --- include/hardware/audio.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index adec3da8..a3b52146 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -247,6 +247,10 @@ 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. * @@ -533,7 +537,68 @@ 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 { -- cgit v1.2.3 From cbcdc02ef4b8ab8e070f71e9a72e58e1fde40b27 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Mon, 24 Jan 2022 13:07:54 -0800 Subject: dynamic_sensor: Support Android head tracker sensor type. Bug: 189507742 Test: Verified head tracker sensor type and sampling. Test: Verified custom Android sensor sampling. Change-Id: Id403de916111ed737b9cebebe9850d5e5845cf56 --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 65 ++++++++++++++++++++----- modules/sensors/dynamic_sensor/HidRawSensor.h | 35 +++++++++++++ 2 files changed, 88 insertions(+), 12 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 66542280..4520ddaa 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -635,8 +635,8 @@ bool HidRawSensor::detectAndroidHeadTrackerSensor( return false; } - mFeatureInfo.type = SENSOR_TYPE_DEVICE_PRIVATE_BASE; - mFeatureInfo.typeString = CUSTOM_TYPE_PREFIX + "headtracker"; + mFeatureInfo.type = SENSOR_TYPE_HEAD_TRACKER; + mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEAD_TRACKER; mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE; mFeatureInfo.permission = ""; mFeatureInfo.isWakeUp = false; @@ -1011,6 +1011,50 @@ void HidRawSensor::handleInput(uint8_t id, const std::vector &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 &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 &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(rec.byteSize) - 1; i >= 0; --i) { @@ -1020,26 +1064,23 @@ void HidRawSensor::handleInput(uint8_t id, const std::vector &message) switch (rec.type) { case TYPE_FLOAT: if (v > rec.maxValue || v < rec.minValue) { - valid = false; + return 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) { - valid = false; + return 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; } } - if (!valid) { - LOG_V << "Range error observed in decoding, discard" << LOG_ENDL; - } - event.timestamp = -1; - generateEvent(event); + + return true; } std::string HidRawSensor::dump() const { diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index f6d13b59..66843fcd 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -46,6 +46,14 @@ public: // handle input report received void handleInput(uint8_t id, const std::vector &message); + // get head tracker sensor event data + bool getHeadTrackerEventData(const std::vector &message, + sensors_event_t *event); + + // get generic sensor event data + bool getSensorEventData(const std::vector &message, + sensors_event_t *event); + // indicate if the HidRawSensor is a valid one bool isValid() const { return mValid; }; @@ -141,6 +149,33 @@ private: // process HID snesor spec defined orientation(quaternion) sensor usages. bool processQuaternionUsage(const std::vector &packets); + // get the value of a report field + template + bool getReportFieldValue(const std::vector &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(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; -- cgit v1.2.3 From 521310bc2607ed550b89efb638207420de23f85f Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 31 Jan 2022 22:41:55 +0000 Subject: Add audio_hw_device.set_device_connected_state_v7 method Add an interface method for providing extra information about the connected device. Bug: 211601178 Test: m Change-Id: I0868cdfdbe46d1399071967653372b55713843e4 --- include/hardware/audio.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index adec3da8..6c883f28 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -982,6 +982,24 @@ 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; -- cgit v1.2.3 From da4e70bc33e9fc3a258f0b09305b6b0f2ef8fbee Mon Sep 17 00:00:00 2001 From: Roopa Sattiraju Date: Wed, 22 Dec 2021 18:05:30 -0800 Subject: Adding bluetooth apex Bug: 206121418 Test: Compile Change-Id: Ib7dcc33843a2173e353ba6e52f7f423cbf445915 --- Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Android.bp b/Android.bp index ebdd2544..acaeb25d 100644 --- a/Android.bp +++ b/Android.bp @@ -58,6 +58,10 @@ cc_library_headers { ], }, }, + apex_available: [ + "//apex_available:platform", + "com.android.bluetooth", + ], min_sdk_version: "29", host_supported: true, -- cgit v1.2.3 From 71834f37757318e6cabce5d7627846f356435ed7 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 1 Feb 2022 15:31:47 -0800 Subject: r_submix module: pipe size changes with sample rate Adapt the pipe size based on the sample rate. Behavior is unchanged for the default sample rate (48kHz), size is adjusted by the ratio relative to the default rate. Bug: 141604269 Test: atest AudioHostTest#testTwoChannelCapturingMediaConversion Change-Id: I0ba45af18ef02dc0ef77d480e1203d2cd1db9864 --- modules/audio_remote_submix/audio_hw.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index 42d3b98d..f96854b5 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) +#define DEFAULT_PIPE_SIZE_IN_FRAMES (1024*4) // size at default sample rate // 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. @@ -208,6 +208,11 @@ 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) @@ -1289,8 +1294,10 @@ static int adev_open_output_stream(struct audio_hw_device *dev, // Store a pointer to the device from the output stream. out->dev = rsxadev; // Initialize the pipe. - 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, + 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, 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, @@ -1419,7 +1426,8 @@ 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 = DEFAULT_PIPE_SIZE_IN_FRAMES; + max_buffer_period_size_frames = + pipe_size_in_frames(get_supported_sample_rate(config->sample_rate));; } 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", @@ -1532,8 +1540,10 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->read_error_count = 0; // Initialize the pipe. - ALOGV("adev_open_input_stream(): about to create pipe"); - submix_audio_device_create_pipe_l(rsxadev, config, DEFAULT_PIPE_SIZE_IN_FRAMES, + 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, DEFAULT_PIPE_PERIOD_COUNT, in, NULL, address, route_idx); sp sink = rsxadev->routes[route_idx].rsxSink; -- cgit v1.2.3 From 3a14e049230d81df3967a218b756add8dd812cfc Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 27 Jan 2022 15:55:40 +0100 Subject: Audio HAL: Add latency mode APIs Add APis for controlling the latency mode on an output stream. Latency mode control is optional but mandated if spatial audio with head tracking is supported over Bluetooth classic audio link. Bug: 187446271 Test: make Change-Id: I30a7f34a265ddac69b283c803b5729770426ebf1 (cherry picked from commit e689139808905178a06ede28142f8966146ce4a6) Merged-In: I30a7f34a265ddac69b283c803b5729770426ebf1 --- include/hardware/audio.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index adec3da8..a3b52146 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -247,6 +247,10 @@ 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. * @@ -533,7 +537,68 @@ 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 { -- cgit v1.2.3 From 0a0dd5f489fa53e279beb6e4ccc53019ba61649f Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Wed, 9 Feb 2022 10:14:29 -0800 Subject: Make apex_available explicit Move the implicit allowing by modules from a list in the build tools to explicit lines in the relevant module's Android.bp Bug: 215589022 Test: build Change-Id: I17f93210f027cb8189e92b19a46b6d64faef7ed8 --- Android.bp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Android.bp b/Android.bp index acaeb25d..a8f4fe4c 100644 --- a/Android.bp +++ b/Android.bp @@ -61,6 +61,7 @@ cc_library_headers { apex_available: [ "//apex_available:platform", "com.android.bluetooth", + "com.android.media.swcodec", ], min_sdk_version: "29", host_supported: true, @@ -98,4 +99,9 @@ cc_library_shared { }, }, min_sdk_version: "29", + apex_available: [ + "//apex_available:platform", + "com.android.media.swcodec", + "test_com.android.media.swcodec", + ], } -- cgit v1.2.3 From f9121419563862eb21b08fb5a342aca47c8d6b62 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 31 Jan 2022 22:41:55 +0000 Subject: Add audio_hw_device.set_device_connected_state_v7 method Add an interface method for providing extra information about the connected device. Bug: 211601178 Test: m Change-Id: I0868cdfdbe46d1399071967653372b55713843e4 (cherry picked from commit 521310bc2607ed550b89efb638207420de23f85f) Merged-In: I0868cdfdbe46d1399071967653372b55713843e4 --- include/hardware/audio.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index a3b52146..daaa16f1 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -1047,6 +1047,24 @@ 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; -- cgit v1.2.3 From dd45428ffa7f487039df573f6d443484381f9f61 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Tue, 1 Mar 2022 15:45:33 -0800 Subject: drop no-longer-needed apex_available clause on libhardware codec2/vndk referenced, but did not use, libhardware. Now that the reference is cleaned, we don't need to to export to apex's. Bug: 221444002 Test: build, boot Change-Id: I43bff5cab71d53d8c7422c13265f129b26ca0430 --- Android.bp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Android.bp b/Android.bp index a8f4fe4c..92c77faa 100644 --- a/Android.bp +++ b/Android.bp @@ -99,9 +99,4 @@ cc_library_shared { }, }, min_sdk_version: "29", - apex_available: [ - "//apex_available:platform", - "com.android.media.swcodec", - "test_com.android.media.swcodec", - ], } -- cgit v1.2.3 From b9769d799cc69a5d7ecc2dfaa47f7a8dd37264a1 Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Fri, 1 Apr 2022 09:41:41 -0700 Subject: Change dynamic sensors handle base to 1 Fixes: 227766975 Test: load on device, confirm handle number changed Change-Id: I0466784d7e468bd785f2525f1ab7cd02cc5436e8 --- modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h index e9a46d68..f59b00ae 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.h @@ -71,7 +71,7 @@ public: const sensors_event_t& e) override; private: - static constexpr int32_t kDynamicHandleBase = 0; + static constexpr int32_t kDynamicHandleBase = 1; static constexpr int32_t kDynamicHandleEnd = 0x1000000; static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - kDynamicHandleBase; -- cgit v1.2.3 From 9b8bc0f7c1fd4565572a894d4f5380e9ae0905b9 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Fri, 1 Apr 2022 11:04:54 -0700 Subject: dynamic_sensor: Support timing out sensor operations. Bug: 226012902 Test: Used uhid-sample to add a dynamic sensor and verified it can be sampled. Test: Simulated start sampling ioctl timeout and verified operation completes with a timeout and eventually cleans up. Test: Simulated start sampling ioctl timeout with device removal before completion and verified operation completes with a timeout and eventually cleans up. Change-Id: I9a957bc1e4000b2c587278146ecbe6e903010616 --- .../dynamic_sensor/DynamicSensorManager.cpp | 85 +++++++++++++++++++++- .../sensors/dynamic_sensor/DynamicSensorManager.h | 35 +++++---- 2 files changed, 100 insertions(+), 20 deletions(-) diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp index be1a0044..efac5e95 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp @@ -87,7 +87,7 @@ int DynamicSensorManager::activate(int handle, bool enable) { } return operateSensor(handle, - [&enable] (sp s)->int { + [=] (sp 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, - [&sample_period, &batch_period] (sp s)->int { + [=] (sp s)->int { return s->batch(sample_period, batch_period); }); } @@ -239,6 +239,87 @@ const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const { return mMetaSensor; } +int DynamicSensorManager::operateSensor( + int handle, OperateSensorFunc sensorFunc) { + std::shared_future sensorOp; + { + std::lock_guard 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 headSensorOp; + + { + std::lock_guard lock(mSensorOpQueueLock); + + if (mSensorOpQueue.front().first == sensorOpIndex) { + break; + } + headSensorOp = mSensorOpQueue.front().second; + } + headSensorOp.wait(); + } + + // Perform sensor operation. + sp sensor; + { + std::lock_guard 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 sensorOp; + { + std::lock_guard lock(mSensorOpQueueLock); + sensorOp = mSensorOpQueue.front().second; + mSensorOpQueue.pop(); + } + + return rv; +} + DynamicSensorManager::ConnectionReport::ConnectionReport( int handle, sp sensor) : mSensor(*(sensor->getSensor())), diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h index 264582ec..b8a73203 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h +++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include #include #include @@ -92,24 +94,13 @@ private: // returns next available handle to use upon a new sensor connection, or -1 if we run out. int getNextAvailableHandle(); - // TF: int foo(sp obj); - template - int operateSensor(int handle, TF f) const { - sp s; - { - std::lock_guard lk(mLock); - const auto i = mMap.find(handle); - if (i == mMap.end()) { - return BAD_VALUE; - } - s = i->second.promote(); - if (s == nullptr) { - // sensor object is already gone - return BAD_VALUE; - } - } - return f(s); - } + // 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 operateSensor(int handle, OperateSensorFunc sensorFunc); + int operateSensor(int handle, OperateSensorFunc sensorFunc, + uint64_t sensorOpIndex); // available sensor handle space const std::pair mHandleRange; @@ -133,6 +124,14 @@ private: // daemons std::vector> 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>> mSensorOpQueue; + uint64_t mNextSensorOpIndex = 0; }; } // namespace SensorHalExt -- cgit v1.2.3 From fdb42f78cdce22e13353f3e3b529ac13ebf0f18f Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Wed, 6 Apr 2022 15:24:28 -0700 Subject: dynamic_sensor: Fix HID min/max sample rate computation. Bug: 228369656 Test: Used uhid-sample to add a dynamic sensor and verified correct min/max sample rate. Change-Id: I88a1bec26a03a97ee7a3c590d2601151b89ee545 --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 20 +++++++++++++++----- modules/sensors/dynamic_sensor/HidRawSensor.h | 2 ++ .../sensors/dynamic_sensor/HidUtils/HidParser.cpp | 10 ++++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 4520ddaa..3759e7e9 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -891,10 +891,18 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorid; mReportIntervalBitOffset = reportInterval->bitOffset; mReportIntervalBitSize = reportInterval->bitSize; - - mFeatureInfo.minDelay = std::max(static_cast(1), reportInterval->minRaw) * 1000; - mFeatureInfo.maxDelay = std::min(static_cast(1000000), - reportInterval->maxRaw) * 1000; // maximum 1000 second + 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(1000000000), + mFeatureInfo.maxDelay); } return true; return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0; @@ -981,7 +989,9 @@ int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) { if (device->getFeature(id, &buffer) && (8 * buffer.size()) >= (mReportIntervalBitOffset + mReportIntervalBitSize)) { - int64_t periodMs = samplingPeriod / 1000000; //ns -> ms + int64_t periodMs = + (((static_cast(samplingPeriod)) / 1000000000.0) + / mReportIntervalScale) - mReportIntervalOffset; int64_t maxPeriodMs = (1LL << std::min(mReportIntervalBitSize, 63U)) - 1; periodMs = std::min(periodMs, maxPeriodMs); diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index 66843fcd..074482a8 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -195,6 +195,8 @@ private: int mReportIntervalId; unsigned int mReportIntervalBitOffset; unsigned int mReportIntervalBitSize; + double mReportIntervalScale; + int64_t mReportIntervalOffset; // Input report translate table std::vector mTranslateTable; diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp index 19aa4291..63210200 100644 --- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp +++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp @@ -240,8 +240,14 @@ std::vector HidParser::convertGroupToPacket( auto logical = r.getLogicalRange(); auto physical = r.getPhysicalRange(); - double scale = static_cast((physical.second - physical.first)) - / (logical.second - logical.first); + double scale; + if ((physical.first != physical.second) && + (logical.first != logical.second)) { + scale = static_cast(physical.second - physical.first) + / (logical.second - logical.first); + } else { + scale = (physical.first != 0) ? physical.first : 1.0; + } scale *= r.getExponentValue(); int64_t offset = (physical.first * r.getExponentValue() / scale) - -- cgit v1.2.3 From 349356570894ce56eaf3145c4f0f01183ca63358 Mon Sep 17 00:00:00 2001 From: Erik Staats Date: Wed, 20 Apr 2022 11:16:52 -0700 Subject: Add /dev permissions to dynamic sensor README.md . Bug: 228879057 Test: Verified in gitiles. Change-Id: If82a5bf302cb68a2c5b486006e4679fbfc8ee545 --- modules/sensors/dynamic_sensor/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/sensors/dynamic_sensor/README.md b/modules/sensors/dynamic_sensor/README.md index 49e541e3..5d5bd6d3 100644 --- a/modules/sensors/dynamic_sensor/README.md +++ b/modules/sensors/dynamic_sensor/README.md @@ -62,6 +62,7 @@ index 0797253..22a4208 100644 +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; + # -- cgit v1.2.3