From a3c332f5ff9313024ef94f6a1cbedce24f0daba7 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Thu, 20 Jun 2024 10:46:06 +0100 Subject: [PATCH] Introduce IVibrator.performVendorEffect Introduce HAL API to perform vibration effects defined by the vendor. The new API accepts a PersistableBundle representing the effect and some platform-provided parameters, e.g. EffectStrength and scale. The callback support for completion is required for this API, since effect duration is undefined. Fix: 345409060 Test: VtsHalVibratorTargetTest Flag: EXEMPT HAL interface change Change-Id: I26379ede4b64e41e1fc85feae6de5105cb636511 --- .../compatibility_matrix.202504.xml | 4 +- tests/extension/vibrator/aidl/Android.bp | 3 + .../vibrator/aidl/default/Android.bp | 6 +- .../vibrator/aidl/default/Vibrator.cpp | 131 +++++++++++++++++ .../vibrator/aidl/default/Vibrator.h | 56 ++++++++ .../vibrator/aidl/default/service.cpp | 2 +- vibrator/aidl/Android.bp | 19 ++- vibrator/aidl/TEST_MAPPING | 5 + .../android/hardware/vibrator/IVibrator.aidl | 24 ++-- .../hardware/vibrator/IVibratorManager.aidl | 16 +-- .../hardware/vibrator/VendorEffect.aidl | 40 ++++++ .../android/hardware/vibrator/Braking.aidl | 4 +- .../hardware/vibrator/CompositePrimitive.aidl | 18 +-- .../android/hardware/vibrator/Effect.aidl | 44 +++--- .../hardware/vibrator/EffectStrength.aidl | 6 +- .../android/hardware/vibrator/IVibrator.aidl | 32 ++++- .../hardware/vibrator/VendorEffect.aidl | 51 +++++++ vibrator/aidl/default/Android.bp | 6 +- vibrator/aidl/default/Vibrator.cpp | 35 ++++- .../default/android.hardware.vibrator.xml | 4 +- .../default/include/vibrator-impl/Vibrator.h | 3 + vibrator/aidl/vts/Android.bp | 4 +- .../aidl/vts/VtsHalVibratorTargetTest.cpp | 125 ++++++++++++++++ vibrator/aidl/vts/persistable_bundle_utils.h | 134 ++++++++++++++++++ vibrator/bench/Android.bp | 2 +- 25 files changed, 696 insertions(+), 78 deletions(-) create mode 100644 tests/extension/vibrator/aidl/default/Vibrator.cpp create mode 100644 tests/extension/vibrator/aidl/default/Vibrator.h create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl create mode 100644 vibrator/aidl/vts/persistable_bundle_utils.h diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml index ee62163924..d71f79a0ae 100644 --- a/compatibility_matrices/compatibility_matrix.202504.xml +++ b/compatibility_matrices/compatibility_matrix.202504.xml @@ -629,7 +629,7 @@ android.hardware.vibrator - 1-2 + 1-3 IVibrator default @@ -637,7 +637,7 @@ android.hardware.vibrator - 1-2 + 1-3 IVibratorManager default diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp index 9d6fdbcfba..3ef8749caf 100644 --- a/tests/extension/vibrator/aidl/Android.bp +++ b/tests/extension/vibrator/aidl/Android.bp @@ -43,6 +43,9 @@ aidl_interface { cpp: { enabled: false, }, + rust: { + enabled: false, + }, }, frozen: true, versions_with_info: [ diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index 5e156af645..479b4fd8dc 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -10,11 +10,6 @@ package { cc_binary { name: "android.hardware.tests.extension.vibrator-service.example", relative_install_path: "hw", - // normally you implement a service directly, but we are using an implementation - // from a library to attach our extension to. - static_libs: [ - "libvibratorexampleimpl", - ], // need to add this in the manifest and to init as well to use, see // android.hardware.vibrator-service.example. This binary is being tested @@ -23,6 +18,7 @@ cc_binary { vendor: true, srcs: [ "service.cpp", + "Vibrator.cpp", "CustomVibrator.cpp", ], shared_libs: [ diff --git a/tests/extension/vibrator/aidl/default/Vibrator.cpp b/tests/extension/vibrator/aidl/default/Vibrator.cpp new file mode 100644 index 0000000000..50840960d3 --- /dev/null +++ b/tests/extension/vibrator/aidl/default/Vibrator.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2024 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 "Vibrator.h" + +#include + +namespace aidl::android::hardware::vibrator { + +ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { + // basic example with only amplitude control capability + *_aidl_return = IVibrator::CAP_AMPLITUDE_CONTROL; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::off() { + LOG(INFO) << "Vibrator off"; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr&) { + LOG(INFO) << "Vibrator on for timeoutMs: " << timeoutMs; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) { + LOG(INFO) << "Vibrator set amplitude: " << amplitude; + if (amplitude <= 0.0f || amplitude > 1.0f) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT)); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::perform(Effect, EffectStrength, + const std::shared_ptr&, int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector* _aidl_return) { + *_aidl_return = {}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::setExternalControl(bool) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive, int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::compose(const std::vector&, + const std::shared_ptr&) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t, Effect, EffectStrength) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getResonantFrequency(float*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getQFactor(float*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getFrequencyResolution(float*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector*) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +ndk::ScopedAStatus Vibrator::composePwle(const std::vector&, + const std::shared_ptr&) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); +} + +} // namespace aidl::android::hardware::vibrator diff --git a/tests/extension/vibrator/aidl/default/Vibrator.h b/tests/extension/vibrator/aidl/default/Vibrator.h new file mode 100644 index 0000000000..80916ae8e2 --- /dev/null +++ b/tests/extension/vibrator/aidl/default/Vibrator.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::vibrator { + +class Vibrator : public BnVibrator { + ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override; + ndk::ScopedAStatus off() override; + ndk::ScopedAStatus on(int32_t timeoutMs, + const std::shared_ptr& callback) override; + ndk::ScopedAStatus perform(Effect effect, EffectStrength strength, + const std::shared_ptr& callback, + int32_t* _aidl_return) override; + ndk::ScopedAStatus getSupportedEffects(std::vector* _aidl_return) override; + ndk::ScopedAStatus setAmplitude(float amplitude) override; + ndk::ScopedAStatus setExternalControl(bool enabled) override; + ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs); + ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize); + ndk::ScopedAStatus getSupportedPrimitives(std::vector* supported) override; + ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive, + int32_t* durationMs) override; + ndk::ScopedAStatus compose(const std::vector& composite, + const std::shared_ptr& callback) override; + ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector* _aidl_return) override; + ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override; + ndk::ScopedAStatus alwaysOnDisable(int32_t id) override; + ndk::ScopedAStatus getResonantFrequency(float* resonantFreqHz) override; + ndk::ScopedAStatus getQFactor(float* qFactor) override; + ndk::ScopedAStatus getFrequencyResolution(float* freqResolutionHz) override; + ndk::ScopedAStatus getFrequencyMinimum(float* freqMinimumHz) override; + ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector* _aidl_return) override; + ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t* durationMs) override; + ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t* maxSize) override; + ndk::ScopedAStatus getSupportedBraking(std::vector* supported) override; + ndk::ScopedAStatus composePwle(const std::vector& composite, + const std::shared_ptr& callback) override; +}; + +} // namespace aidl::android::hardware::vibrator diff --git a/tests/extension/vibrator/aidl/default/service.cpp b/tests/extension/vibrator/aidl/default/service.cpp index 16290df826..5917d0fb6f 100644 --- a/tests/extension/vibrator/aidl/default/service.cpp +++ b/tests/extension/vibrator/aidl/default/service.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include #include "CustomVibrator.h" +#include "Vibrator.h" #include #include diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp index fe7645067b..b2d98f5b2f 100644 --- a/vibrator/aidl/Android.bp +++ b/vibrator/aidl/Android.bp @@ -15,6 +15,9 @@ aidl_interface { srcs: [ "android/hardware/vibrator/*.aidl", ], + headers: [ + "PersistableBundle_aidl", + ], stability: "vintf", backend: { java: { @@ -26,9 +29,19 @@ aidl_interface { cpp: { enabled: false, }, + rust: { + enabled: false, + }, }, - versions: [ - "1", - "2", + versions_with_info: [ + { + version: "1", + imports: [], + }, + { + version: "2", + imports: [], + }, ], + frozen: false, } diff --git a/vibrator/aidl/TEST_MAPPING b/vibrator/aidl/TEST_MAPPING index 2414b8464f..e00b3e9775 100644 --- a/vibrator/aidl/TEST_MAPPING +++ b/vibrator/aidl/TEST_MAPPING @@ -6,5 +6,10 @@ { "name": "VtsHalVibratorManagerTargetTest" } + ], + "postsubmit": [ + { + "name": "VtsHalVibratorPerformVendorEffectFuzzer" + } ] } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl index b7afb663cf..af619c6a98 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl @@ -58,15 +58,17 @@ interface IVibrator { int getPwleCompositionSizeMax(); android.hardware.vibrator.Braking[] getSupportedBraking(); void composePwle(in android.hardware.vibrator.PrimitivePwle[] composite, in android.hardware.vibrator.IVibratorCallback callback); - const int CAP_ON_CALLBACK = 1; - const int CAP_PERFORM_CALLBACK = 2; - const int CAP_AMPLITUDE_CONTROL = 4; - const int CAP_EXTERNAL_CONTROL = 8; - const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 16; - const int CAP_COMPOSE_EFFECTS = 32; - const int CAP_ALWAYS_ON_CONTROL = 64; - const int CAP_GET_RESONANT_FREQUENCY = 128; - const int CAP_GET_Q_FACTOR = 256; - const int CAP_FREQUENCY_CONTROL = 512; - const int CAP_COMPOSE_PWLE_EFFECTS = 1024; + void performVendorEffect(in android.hardware.vibrator.VendorEffect vendorEffect, in android.hardware.vibrator.IVibratorCallback callback); + const int CAP_ON_CALLBACK = (1 << 0) /* 1 */; + const int CAP_PERFORM_CALLBACK = (1 << 1) /* 2 */; + const int CAP_AMPLITUDE_CONTROL = (1 << 2) /* 4 */; + const int CAP_EXTERNAL_CONTROL = (1 << 3) /* 8 */; + const int CAP_EXTERNAL_AMPLITUDE_CONTROL = (1 << 4) /* 16 */; + const int CAP_COMPOSE_EFFECTS = (1 << 5) /* 32 */; + const int CAP_ALWAYS_ON_CONTROL = (1 << 6) /* 64 */; + const int CAP_GET_RESONANT_FREQUENCY = (1 << 7) /* 128 */; + const int CAP_GET_Q_FACTOR = (1 << 8) /* 256 */; + const int CAP_FREQUENCY_CONTROL = (1 << 9) /* 512 */; + const int CAP_COMPOSE_PWLE_EFFECTS = (1 << 10) /* 1024 */; + const int CAP_PERFORM_VENDOR_EFFECTS = (1 << 11) /* 2048 */; } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl index 290c68d877..ef5794c644 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl @@ -40,12 +40,12 @@ interface IVibratorManager { void prepareSynced(in int[] vibratorIds); void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback); void cancelSynced(); - const int CAP_SYNC = 1; - const int CAP_PREPARE_ON = 2; - const int CAP_PREPARE_PERFORM = 4; - const int CAP_PREPARE_COMPOSE = 8; - const int CAP_MIXED_TRIGGER_ON = 16; - const int CAP_MIXED_TRIGGER_PERFORM = 32; - const int CAP_MIXED_TRIGGER_COMPOSE = 64; - const int CAP_TRIGGER_CALLBACK = 128; + const int CAP_SYNC = (1 << 0) /* 1 */; + const int CAP_PREPARE_ON = (1 << 1) /* 2 */; + const int CAP_PREPARE_PERFORM = (1 << 2) /* 4 */; + const int CAP_PREPARE_COMPOSE = (1 << 3) /* 8 */; + const int CAP_MIXED_TRIGGER_ON = (1 << 4) /* 16 */; + const int CAP_MIXED_TRIGGER_PERFORM = (1 << 5) /* 32 */; + const int CAP_MIXED_TRIGGER_COMPOSE = (1 << 6) /* 64 */; + const int CAP_TRIGGER_CALLBACK = (1 << 7) /* 128 */; } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl new file mode 100644 index 0000000000..190008440d --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.vibrator; +@VintfStability +parcelable VendorEffect { + android.os.PersistableBundle vendorData; + android.hardware.vibrator.EffectStrength strength = android.hardware.vibrator.EffectStrength.MEDIUM; + float scale; +} diff --git a/vibrator/aidl/android/hardware/vibrator/Braking.aidl b/vibrator/aidl/android/hardware/vibrator/Braking.aidl index 2bc51db3f6..f934ff2474 100644 --- a/vibrator/aidl/android/hardware/vibrator/Braking.aidl +++ b/vibrator/aidl/android/hardware/vibrator/Braking.aidl @@ -23,12 +23,12 @@ enum Braking { * No braking mechanism used. * This is the default if the hardware does not support any braking mechanism. */ - NONE, + NONE = 0, /** * Closed-loop active braking. * * This effect should produce a sharp, crisp end to the waveform * Support is optional. */ - CLAB, + CLAB = 1, } diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl index 531489824b..5f8ee8dacc 100644 --- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl +++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl @@ -24,13 +24,13 @@ enum CompositePrimitive { * * Support is required. */ - NOOP, + NOOP = 0, /** * This effect should produce a sharp, crisp click sensation. * * Support is required. */ - CLICK, + CLICK = 1, /** * A haptic effect that simulates downwards movement with gravity. Often * followed by extra energy of hitting and reverberation to augment @@ -38,43 +38,43 @@ enum CompositePrimitive { * * Support is optional. */ - THUD, + THUD = 2, /** * A haptic effect that simulates spinning momentum. * * Support is optional. */ - SPIN, + SPIN = 3, /** * A haptic effect that simulates quick upward movement against gravity. * * Support is required. */ - QUICK_RISE, + QUICK_RISE = 4, /** * A haptic effect that simulates slow upward movement against gravity. * * Support is required. */ - SLOW_RISE, + SLOW_RISE = 5, /** * A haptic effect that simulates quick downwards movement with gravity. * * Support is required. */ - QUICK_FALL, + QUICK_FALL = 6, /** * This very short effect should produce a light crisp sensation intended * to be used repetitively for dynamic feedback. * * Support is required. */ - LIGHT_TICK, + LIGHT_TICK = 7, /** * This very short low frequency effect should produce a light crisp sensation intended * to be used repetitively for dynamic feedback. * * Support is required. */ - LOW_TICK, + LOW_TICK = 8, } diff --git a/vibrator/aidl/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/android/hardware/vibrator/Effect.aidl index c60bfe98dc..f5cf9e392c 100644 --- a/vibrator/aidl/android/hardware/vibrator/Effect.aidl +++ b/vibrator/aidl/android/hardware/vibrator/Effect.aidl @@ -24,57 +24,57 @@ enum Effect { * * This effect should produce a sharp, crisp click sensation. */ - CLICK, + CLICK = 0, /** * A double click effect. * * This effect should produce two sequential sharp, crisp click sensations with a minimal * amount of time between them. */ - DOUBLE_CLICK, + DOUBLE_CLICK = 1, /** * A tick effect. * * This effect should produce a soft, short sensation, like the tick of a clock. */ - TICK, + TICK = 2, /** * A thud effect. * * This effect should solid feeling bump, like the depression of a heavy mechanical button. */ - THUD, + THUD = 3, /** * A pop effect. * * A short, quick burst effect. */ - POP, + POP = 4, /** * A heavy click effect. * * This should produce a sharp striking sensation, like a click but stronger. */ - HEAVY_CLICK, + HEAVY_CLICK = 5, /** * Ringtone patterns. They may correspond with the device's ringtone audio, or may just be a * pattern that can be played as a ringtone with any audio, depending on the device. */ - RINGTONE_1, - RINGTONE_2, - RINGTONE_3, - RINGTONE_4, - RINGTONE_5, - RINGTONE_6, - RINGTONE_7, - RINGTONE_8, - RINGTONE_9, - RINGTONE_10, - RINGTONE_11, - RINGTONE_12, - RINGTONE_13, - RINGTONE_14, - RINGTONE_15, + RINGTONE_1 = 6, + RINGTONE_2 = 7, + RINGTONE_3 = 8, + RINGTONE_4 = 9, + RINGTONE_5 = 10, + RINGTONE_6 = 11, + RINGTONE_7 = 12, + RINGTONE_8 = 13, + RINGTONE_9 = 14, + RINGTONE_10 = 15, + RINGTONE_11 = 16, + RINGTONE_12 = 17, + RINGTONE_13 = 18, + RINGTONE_14 = 19, + RINGTONE_15 = 20, /** * A soft tick effect meant to be played as a texture. * @@ -82,5 +82,5 @@ enum Effect { * are expected to be played multiple times in quick succession, replicating a specific * texture to the user as a form of haptic feedback. */ - TEXTURE_TICK, + TEXTURE_TICK = 21, } diff --git a/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl index 66f70e57f3..c6a78d407c 100644 --- a/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl +++ b/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl @@ -19,7 +19,7 @@ package android.hardware.vibrator; @VintfStability @Backing(type="byte") enum EffectStrength { - LIGHT, - MEDIUM, - STRONG, + LIGHT = 0, + MEDIUM = 1, + STRONG = 2, } diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl index b4e7e44fe0..768ec4f658 100644 --- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl @@ -16,13 +16,14 @@ package android.hardware.vibrator; -import android.hardware.vibrator.IVibratorCallback; import android.hardware.vibrator.Braking; -import android.hardware.vibrator.Effect; -import android.hardware.vibrator.EffectStrength; import android.hardware.vibrator.CompositeEffect; import android.hardware.vibrator.CompositePrimitive; +import android.hardware.vibrator.Effect; +import android.hardware.vibrator.EffectStrength; +import android.hardware.vibrator.IVibratorCallback; import android.hardware.vibrator.PrimitivePwle; +import android.hardware.vibrator.VendorEffect; @VintfStability interface IVibrator { @@ -70,6 +71,10 @@ interface IVibrator { * Whether composePwle is supported. */ const int CAP_COMPOSE_PWLE_EFFECTS = 1 << 10; + /** + * Whether perform w/ vendor effect is supported. + */ + const int CAP_PERFORM_VENDOR_EFFECTS = 1 << 11; /** * Determine capabilities of the vibrator HAL (CAP_* mask) @@ -359,4 +364,25 @@ interface IVibrator { * @param composite Array of PWLEs. */ void composePwle(in PrimitivePwle[] composite, in IVibratorCallback callback); + + /** + * Fire off a vendor-defined haptic event. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_PERFORM_VENDOR_EFFECTS). + * + * The duration of the effect is unknown and can be undefined for looping effects. + * IVibratorCallback.onComplete() support is required for this API. + * + * Doing this operation while the vibrator is already on is undefined behavior. Clients should + * explicitly call off. + * + * @param effect The vendor data representing the effect to be performed. + * @param callback A callback used to inform Frameworks of state change. + * @throws : + * - EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities. + * - EX_ILLEGAL_ARGUMENT for bad framework parameters, e.g. scale or effect strength. + * - EX_SERVICE_SPECIFIC for bad vendor data, vibration is not triggered. + */ + void performVendorEffect(in VendorEffect vendorEffect, in IVibratorCallback callback); } diff --git a/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl new file mode 100644 index 0000000000..2155aca276 --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.hardware.vibrator; + +import android.hardware.vibrator.EffectStrength; +import android.os.PersistableBundle; + +@VintfStability +parcelable VendorEffect { + /** + * Vendor data describing the haptic effect. Expected fields should be defined by the vendor. + * + * Vendors can use this as a platform extension point for experimental hardware capabilities, + * but they are strongly discouraged from using it as an alternative to the AOSP support for + * stable vibrator APIs. Implemenitng vendor-specific custom effects outside the platform APIs + * will hinder portability for the code and overall user experience. + * + * Vendors are encouraged to upstream new capabilities to the IVibrator surface once it has + * matured into a stable interface. + */ + PersistableBundle vendorData; + + /** + * The intensity of the haptic effect. + */ + EffectStrength strength = EffectStrength.MEDIUM; + + /** + * A scale to be applied to the haptic effect intensity. + * + * This value represents a linear scale that should be applied on top of the effect strength to + * dynamically adapt to the device state. + * + * Values in [0,1) should scale down. Values > 1 should scale up within hardware bounds. + */ + float scale; +} diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index 0f342db10e..4b266409f4 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -15,7 +15,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", ], export_include_dirs: ["include"], srcs: [ @@ -49,7 +49,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", ], static_libs: [ "libvibratorexampleimpl", @@ -62,7 +62,7 @@ cc_fuzz { host_supported: true, defaults: ["service_fuzzer_defaults"], static_libs: [ - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", "liblog", "libvibratorexampleimpl", ], diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp index 01602abffb..acf7d34266 100644 --- a/vibrator/aidl/default/Vibrator.cpp +++ b/vibrator/aidl/default/Vibrator.cpp @@ -39,6 +39,9 @@ static constexpr float PWLE_FREQUENCY_MAX_HZ = 160.0; static constexpr float PWLE_BW_MAP_SIZE = 1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ); +// Service specific error code used for vendor vibration effects. +static constexpr int32_t ERROR_CODE_INVALID_DURATION = 1; + ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { LOG(VERBOSE) << "Vibrator reporting capabilities"; *_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK | @@ -46,7 +49,7 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS | IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY | IVibrator::CAP_GET_Q_FACTOR | IVibrator::CAP_FREQUENCY_CONTROL | - IVibrator::CAP_COMPOSE_PWLE_EFFECTS; + IVibrator::CAP_COMPOSE_PWLE_EFFECTS | IVibrator::CAP_PERFORM_VENDOR_EFFECTS; return ndk::ScopedAStatus::ok(); } @@ -102,6 +105,36 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Vibrator::performVendorEffect( + const VendorEffect& effect, const std::shared_ptr& callback) { + LOG(VERBOSE) << "Vibrator perform vendor effect"; + EffectStrength strength = effect.strength; + if (strength != EffectStrength::LIGHT && strength != EffectStrength::MEDIUM && + strength != EffectStrength::STRONG) { + return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT)); + } + float scale = effect.scale; + if (scale <= 0) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + int32_t durationMs = 0; + if (!effect.vendorData.getInt("DURATION_MS", &durationMs) || durationMs <= 0) { + return ndk::ScopedAStatus::fromServiceSpecificError(ERROR_CODE_INVALID_DURATION); + } + + if (callback != nullptr) { + std::thread([callback, durationMs] { + LOG(VERBOSE) << "Starting perform on another thread for durationMs:" << durationMs; + usleep(durationMs * 1000); + LOG(VERBOSE) << "Notifying perform vendor effect complete"; + callback->onComplete(); + }).detach(); + } + + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector* _aidl_return) { *_aidl_return = {Effect::CLICK, Effect::TICK}; return ndk::ScopedAStatus::ok(); diff --git a/vibrator/aidl/default/android.hardware.vibrator.xml b/vibrator/aidl/default/android.hardware.vibrator.xml index b5bd3ddd1e..b7300460c2 100644 --- a/vibrator/aidl/default/android.hardware.vibrator.xml +++ b/vibrator/aidl/default/android.hardware.vibrator.xml @@ -1,12 +1,12 @@ android.hardware.vibrator - 2 + 3 IVibrator/default android.hardware.vibrator - 2 + 3 IVibratorManager/default diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h index 4203bf212c..e8f64cafe4 100644 --- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h +++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h @@ -31,6 +31,9 @@ class Vibrator : public BnVibrator { ndk::ScopedAStatus perform(Effect effect, EffectStrength strength, const std::shared_ptr& callback, int32_t* _aidl_return) override; + ndk::ScopedAStatus performVendorEffect( + const VendorEffect& effect, + const std::shared_ptr& callback) override; ndk::ScopedAStatus getSupportedEffects(std::vector* _aidl_return) override; ndk::ScopedAStatus setAmplitude(float amplitude) override; ndk::ScopedAStatus setExternalControl(bool enabled) override; diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index 166b30ba6a..a48bb2e89f 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -20,7 +20,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", ], test_suites: [ "general-tests", @@ -39,7 +39,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", ], test_suites: [ "general-tests", diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 65a1e84177..706ab416b3 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -21,10 +21,14 @@ #include #include +#include #include +#include +#include #include +#include "persistable_bundle_utils.h" #include "test_utils.h" using aidl::android::hardware::vibrator::ActivePwle; @@ -38,6 +42,8 @@ using aidl::android::hardware::vibrator::EffectStrength; using aidl::android::hardware::vibrator::IVibrator; using aidl::android::hardware::vibrator::IVibratorManager; using aidl::android::hardware::vibrator::PrimitivePwle; +using aidl::android::hardware::vibrator::VendorEffect; +using aidl::android::os::PersistableBundle; using std::chrono::high_resolution_clock; using namespace ::std::chrono_literals; @@ -357,6 +363,122 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) { } } +TEST_P(VibratorAidl, PerformVendorEffectSupported) { + if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return; + + float scale = 0.5f; + for (EffectStrength strength : kEffectStrengths) { + PersistableBundle vendorData; + ::aidl::android::hardware::vibrator::testing::fillBasicData(&vendorData); + + PersistableBundle nestedData; + ::aidl::android::hardware::vibrator::testing::fillBasicData(&nestedData); + vendorData.putPersistableBundle("test_nested_bundle", nestedData); + + VendorEffect effect; + effect.vendorData = vendorData; + effect.strength = strength; + effect.scale = scale; + scale *= 1.5f; + + auto callback = ndk::SharedRefBase::make([] {}); + ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback); + + // No expectations on the actual status, the effect might be refused with illegal argument + // or the vendor might return a service-specific error code. + EXPECT_TRUE(status.getExceptionCode() != EX_UNSUPPORTED_OPERATION && + status.getStatus() != STATUS_UNKNOWN_TRANSACTION) + << status << "\n For vendor effect with strength" << toString(strength) + << " and scale " << effect.scale; + + if (status.isOk()) { + // Generic vendor data should not trigger vibrations, but if it does trigger one + // then we make sure the vibrator is reset by triggering off(). + EXPECT_OK(vibrator->off()); + } + } +} + +TEST_P(VibratorAidl, PerformVendorEffectStability) { + if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return; + + // Run some iterations of performVendorEffect with randomized vendor data to check basic + // stability of the implementation. + uint8_t iterations = 200; + + for (EffectStrength strength : kEffectStrengths) { + float scale = 0.5f; + for (uint8_t i = 0; i < iterations; i++) { + PersistableBundle vendorData; + ::aidl::android::hardware::vibrator::testing::fillRandomData(&vendorData); + + VendorEffect effect; + effect.vendorData = vendorData; + effect.strength = strength; + effect.scale = scale; + scale *= 2; + + auto callback = ndk::SharedRefBase::make([] {}); + ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback); + + // No expectations on the actual status, the effect might be refused with illegal + // argument or the vendor might return a service-specific error code. + EXPECT_TRUE(status.getExceptionCode() != EX_UNSUPPORTED_OPERATION && + status.getStatus() != STATUS_UNKNOWN_TRANSACTION) + << status << "\n For random vendor effect with strength " << toString(strength) + << " and scale " << effect.scale; + + if (status.isOk()) { + // Random vendor data should not trigger vibrations, but if it does trigger one + // then we make sure the vibrator is reset by triggering off(). + EXPECT_OK(vibrator->off()); + } + } + } +} + +TEST_P(VibratorAidl, PerformVendorEffectEmptyVendorData) { + if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return; + + for (EffectStrength strength : kEffectStrengths) { + VendorEffect effect; + effect.strength = strength; + effect.scale = 1.0f; + + ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, nullptr /*callback*/); + + EXPECT_TRUE(status.getExceptionCode() == EX_SERVICE_SPECIFIC) + << status << "\n For vendor effect with strength " << toString(strength) + << " and scale " << effect.scale; + } +} + +TEST_P(VibratorAidl, PerformVendorEffectInvalidScale) { + if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return; + + VendorEffect effect; + effect.strength = EffectStrength::MEDIUM; + + effect.scale = 0.0f; + EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/)); + + effect.scale = -1.0f; + EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/)); +} + +TEST_P(VibratorAidl, PerformVendorEffectUnsupported) { + if (capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) return; + + for (EffectStrength strength : kEffectStrengths) { + VendorEffect effect; + effect.strength = strength; + effect.scale = 1.0f; + + EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->performVendorEffect(effect, nullptr /*callback*/)) + << "\n For vendor effect with strength " << toString(strength); + } +} + TEST_P(VibratorAidl, ChangeVibrationAmplitude) { if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) { EXPECT_OK(vibrator->setAmplitude(0.1f)); @@ -940,6 +1062,9 @@ INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibra PrintGeneratedTest); int main(int argc, char **argv) { + // Random values are used in the implementation. + std::srand(std::time(nullptr)); + ::testing::InitGoogleTest(&argc, argv); ABinderProcess_setThreadPoolMaxThreadCount(1); ABinderProcess_startThreadPool(); diff --git a/vibrator/aidl/vts/persistable_bundle_utils.h b/vibrator/aidl/vts/persistable_bundle_utils.h new file mode 100644 index 0000000000..a765a4992e --- /dev/null +++ b/vibrator/aidl/vts/persistable_bundle_utils.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2024 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 VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H +#define VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H + +#include + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace vibrator { +namespace testing { + +using aidl::android::os::PersistableBundle; + +namespace { + +template +T nextValue() { + return static_cast(std::rand()); +} + +template <> +std::string nextValue() { + std::string str; + uint8_t entryCount = nextValue(); + for (uint8_t i = 0; i < entryCount; i++) { + str.push_back(nextValue()); + } + return str; +} + +template +T nextValue(T limit) { + assert(limit > 0); + return static_cast(std::rand()) / (static_cast(RAND_MAX / limit)); +} + +template +void fillVector(std::vector* values) { + uint8_t entryCount = nextValue(); + for (uint8_t i = 0; i < entryCount; i++) { + values->push_back(nextValue()); + } +} + +const std::vector> + sPersistableBundleSetters = {[](PersistableBundle* bundle, const std::string& key) -> void { + bundle->putBoolean(key, nextValue()); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + bundle->putInt(key, nextValue()); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + bundle->putLong(key, nextValue()); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + bundle->putDouble(key, nextValue()); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + bundle->putString(key, nextValue()); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + std::vector value; + fillVector(&value); + bundle->putBooleanVector(key, value); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + std::vector value; + fillVector(&value); + bundle->putIntVector(key, value); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + std::vector value; + fillVector(&value); + bundle->putLongVector(key, value); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + std::vector value; + fillVector(&value); + bundle->putDoubleVector(key, value); + }, + [](PersistableBundle* bundle, const std::string& key) -> void { + std::vector value; + fillVector(&value); + bundle->putStringVector(key, value); + }}; + +} // namespace + +void fillBasicData(PersistableBundle* bundle) { + bundle->putBoolean("test_bool", true); + bundle->putInt("test_int", 2147483647); + bundle->putLong("test_long", 2147483647L); + bundle->putDouble("test_double", 1.23); + bundle->putString("test_string", "test data"); + bundle->putBooleanVector("test_bool_vector", {true, false, false}); + bundle->putIntVector("test_int_vector", {1, 2, 3, 4}); + bundle->putLongVector("test_long_vector", {100L, 200L, 300L}); + bundle->putDoubleVector("test_double_vector", {1.1, 2.2}); + bundle->putStringVector("test_string_vector", {"test", "val"}); +} + +void fillRandomData(PersistableBundle* bundle) { + uint8_t entryCount = nextValue(); + for (uint8_t i = 0; i < entryCount; i++) { + std::string key(nextValue()); + uint8_t setterIdx = nextValue(sPersistableBundleSetters.size() - 1); + sPersistableBundleSetters[setterIdx](bundle, key); + } +} + +} // namespace testing +} // namespace vibrator +} // namespace hardware +} // namespace android +} // namespace aidl + +#endif // VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp index b31c71955a..cd56516eed 100644 --- a/vibrator/bench/Android.bp +++ b/vibrator/bench/Android.bp @@ -30,7 +30,7 @@ cc_benchmark { "benchmark.cpp", ], shared_libs: [ - "android.hardware.vibrator-V2-ndk", + "android.hardware.vibrator-V3-ndk", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2",