mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Introduce IVibrator.performVendorEffect" into main
This commit is contained in:
@@ -629,7 +629,7 @@
|
||||
</hal>
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>1-2</version>
|
||||
<version>1-3</version>
|
||||
<interface>
|
||||
<name>IVibrator</name>
|
||||
<instance>default</instance>
|
||||
@@ -637,7 +637,7 @@
|
||||
</hal>
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>1-2</version>
|
||||
<version>1-3</version>
|
||||
<interface>
|
||||
<name>IVibratorManager</name>
|
||||
<instance>default</instance>
|
||||
|
||||
@@ -43,6 +43,9 @@ aidl_interface {
|
||||
cpp: {
|
||||
enabled: false,
|
||||
},
|
||||
rust: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
frozen: true,
|
||||
versions_with_info: [
|
||||
|
||||
@@ -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: [
|
||||
|
||||
131
tests/extension/vibrator/aidl/default/Vibrator.cpp
Normal file
131
tests/extension/vibrator/aidl/default/Vibrator.cpp
Normal file
@@ -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 <android-base/logging.h>
|
||||
|
||||
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<IVibratorCallback>&) {
|
||||
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<IVibratorCallback>&, int32_t*) {
|
||||
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _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<CompositePrimitive>*) {
|
||||
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<CompositeEffect>&,
|
||||
const std::shared_ptr<IVibratorCallback>&) {
|
||||
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect>*) {
|
||||
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<float>*) {
|
||||
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<Braking>*) {
|
||||
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle>&,
|
||||
const std::shared_ptr<IVibratorCallback>&) {
|
||||
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::vibrator
|
||||
56
tests/extension/vibrator/aidl/default/Vibrator.h
Normal file
56
tests/extension/vibrator/aidl/default/Vibrator.h
Normal file
@@ -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 <aidl/android/hardware/vibrator/BnVibrator.h>
|
||||
|
||||
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<IVibratorCallback>& callback) override;
|
||||
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback>& callback,
|
||||
int32_t* _aidl_return) override;
|
||||
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _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<CompositePrimitive>* supported) override;
|
||||
ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
|
||||
int32_t* durationMs) override;
|
||||
ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
|
||||
const std::shared_ptr<IVibratorCallback>& callback) override;
|
||||
ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _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<float>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t* durationMs) override;
|
||||
ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t* maxSize) override;
|
||||
ndk::ScopedAStatus getSupportedBraking(std::vector<Braking>* supported) override;
|
||||
ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle>& composite,
|
||||
const std::shared_ptr<IVibratorCallback>& callback) override;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::vibrator
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <vibrator-impl/Vibrator.h>
|
||||
#include "CustomVibrator.h"
|
||||
#include "Vibrator.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -6,5 +6,10 @@
|
||||
{
|
||||
"name": "VtsHalVibratorManagerTargetTest"
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"name": "VtsHalVibratorPerformVendorEffectFuzzer"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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 */;
|
||||
}
|
||||
|
||||
@@ -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 */;
|
||||
}
|
||||
|
||||
@@ -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 <name>-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;
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package android.hardware.vibrator;
|
||||
@VintfStability
|
||||
@Backing(type="byte")
|
||||
enum EffectStrength {
|
||||
LIGHT,
|
||||
MEDIUM,
|
||||
STRONG,
|
||||
LIGHT = 0,
|
||||
MEDIUM = 1,
|
||||
STRONG = 2,
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
51
vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
Normal file
51
vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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",
|
||||
],
|
||||
|
||||
@@ -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<IVibratorCallback>& 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<Effect>* _aidl_return) {
|
||||
*_aidl_return = {Effect::CLICK, Effect::TICK};
|
||||
return ndk::ScopedAStatus::ok();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>2</version>
|
||||
<version>3</version>
|
||||
<fqname>IVibrator/default</fqname>
|
||||
</hal>
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>2</version>
|
||||
<version>3</version>
|
||||
<fqname>IVibratorManager/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
||||
@@ -31,6 +31,9 @@ class Vibrator : public BnVibrator {
|
||||
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback>& callback,
|
||||
int32_t* _aidl_return) override;
|
||||
ndk::ScopedAStatus performVendorEffect(
|
||||
const VendorEffect& effect,
|
||||
const std::shared_ptr<IVibratorCallback>& callback) override;
|
||||
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
|
||||
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
||||
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -21,10 +21,14 @@
|
||||
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <android/persistable_bundle_aidl.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <future>
|
||||
|
||||
#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<CompletionCallback>([] {});
|
||||
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<CompletionCallback>([] {});
|
||||
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();
|
||||
|
||||
134
vibrator/aidl/vts/persistable_bundle_utils.h
Normal file
134
vibrator/aidl/vts/persistable_bundle_utils.h
Normal file
@@ -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 <android/persistable_bundle_aidl.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
namespace testing {
|
||||
|
||||
using aidl::android::os::PersistableBundle;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
T nextValue() {
|
||||
return static_cast<T>(std::rand());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string nextValue() {
|
||||
std::string str;
|
||||
uint8_t entryCount = nextValue<uint8_t>();
|
||||
for (uint8_t i = 0; i < entryCount; i++) {
|
||||
str.push_back(nextValue<char>());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T nextValue(T limit) {
|
||||
assert(limit > 0);
|
||||
return static_cast<T>(std::rand()) / (static_cast<T>(RAND_MAX / limit));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fillVector(std::vector<T>* values) {
|
||||
uint8_t entryCount = nextValue<uint8_t>();
|
||||
for (uint8_t i = 0; i < entryCount; i++) {
|
||||
values->push_back(nextValue<T>());
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::function<void(PersistableBundle*, const std::string&)>>
|
||||
sPersistableBundleSetters = {[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
bundle->putBoolean(key, nextValue<bool>());
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
bundle->putInt(key, nextValue<int32_t>());
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
bundle->putLong(key, nextValue<int64_t>());
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
bundle->putDouble(key, nextValue<double>());
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
bundle->putString(key, nextValue<std::string>());
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
std::vector<bool> value;
|
||||
fillVector<bool>(&value);
|
||||
bundle->putBooleanVector(key, value);
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
std::vector<int32_t> value;
|
||||
fillVector<int32_t>(&value);
|
||||
bundle->putIntVector(key, value);
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
std::vector<int64_t> value;
|
||||
fillVector<int64_t>(&value);
|
||||
bundle->putLongVector(key, value);
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
std::vector<double> value;
|
||||
fillVector<double>(&value);
|
||||
bundle->putDoubleVector(key, value);
|
||||
},
|
||||
[](PersistableBundle* bundle, const std::string& key) -> void {
|
||||
std::vector<std::string> value;
|
||||
fillVector<std::string>(&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<uint8_t>();
|
||||
for (uint8_t i = 0; i < entryCount; i++) {
|
||||
std::string key(nextValue<std::string>());
|
||||
uint8_t setterIdx = nextValue<uint8_t>(sPersistableBundleSetters.size() - 1);
|
||||
sPersistableBundleSetters[setterIdx](bundle, key);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user