mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Vibrator: Stable AIDL interface."
This commit is contained in:
@@ -465,6 +465,13 @@
|
|||||||
<instance>default</instance>
|
<instance>default</instance>
|
||||||
</interface>
|
</interface>
|
||||||
</hal>
|
</hal>
|
||||||
|
<hal format="aidl" optional="true">
|
||||||
|
<name>android.hardware.vibrator</name>
|
||||||
|
<interface>
|
||||||
|
<name>IVibrator</name>
|
||||||
|
<instance>default</instance>
|
||||||
|
</interface>
|
||||||
|
</hal>
|
||||||
<hal format="hidl" optional="true">
|
<hal format="hidl" optional="true">
|
||||||
<name>android.hardware.vibrator</name>
|
<name>android.hardware.vibrator</name>
|
||||||
<version>1.0-4</version>
|
<version>1.0-4</version>
|
||||||
|
|||||||
14
vibrator/staidl/Android.bp
Normal file
14
vibrator/staidl/Android.bp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
aidl_interface {
|
||||||
|
name: "vintf-vibrator",
|
||||||
|
vendor_available: true,
|
||||||
|
srcs: [
|
||||||
|
"android/hardware/vibrator/*.aidl",
|
||||||
|
],
|
||||||
|
stability: "vintf",
|
||||||
|
backend: {
|
||||||
|
java: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
86
vibrator/staidl/android/hardware/vibrator/Effect.aidl
Normal file
86
vibrator/staidl/android/hardware/vibrator/Effect.aidl
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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;
|
||||||
|
|
||||||
|
@VintfStability
|
||||||
|
@Backing(type="int")
|
||||||
|
enum Effect {
|
||||||
|
/**
|
||||||
|
* A single click effect.
|
||||||
|
*
|
||||||
|
* This effect should produce a sharp, crisp click sensation.
|
||||||
|
*/
|
||||||
|
CLICK,
|
||||||
|
/**
|
||||||
|
* A double click effect.
|
||||||
|
*
|
||||||
|
* This effect should produce two sequential sharp, crisp click sensations with a minimal
|
||||||
|
* amount of time between them.
|
||||||
|
*/
|
||||||
|
DOUBLE_CLICK,
|
||||||
|
/**
|
||||||
|
* A tick effect.
|
||||||
|
*
|
||||||
|
* This effect should produce a soft, short sensation, like the tick of a clock.
|
||||||
|
*/
|
||||||
|
TICK,
|
||||||
|
/**
|
||||||
|
* A thud effect.
|
||||||
|
*
|
||||||
|
* This effect should solid feeling bump, like the depression of a heavy mechanical button.
|
||||||
|
*/
|
||||||
|
THUD,
|
||||||
|
/**
|
||||||
|
* A pop effect.
|
||||||
|
*
|
||||||
|
* A short, quick burst effect.
|
||||||
|
*/
|
||||||
|
POP,
|
||||||
|
/**
|
||||||
|
* A heavy click effect.
|
||||||
|
*
|
||||||
|
* This should produce a sharp striking sensation, like a click but stronger.
|
||||||
|
*/
|
||||||
|
HEAVY_CLICK,
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
/**
|
||||||
|
* A soft tick effect meant to be played as a texture.
|
||||||
|
*
|
||||||
|
* A soft, short sensation like the tick of a clock. Unlike regular effects, texture effects
|
||||||
|
* 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,
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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;
|
||||||
|
|
||||||
|
@VintfStability
|
||||||
|
@Backing(type="byte")
|
||||||
|
enum EffectStrength {
|
||||||
|
LIGHT,
|
||||||
|
MEDIUM,
|
||||||
|
STRONG,
|
||||||
|
}
|
||||||
101
vibrator/staidl/android/hardware/vibrator/IVibrator.aidl
Normal file
101
vibrator/staidl/android/hardware/vibrator/IVibrator.aidl
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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.IVibratorCallback;
|
||||||
|
import android.hardware.vibrator.Effect;
|
||||||
|
import android.hardware.vibrator.EffectStrength;
|
||||||
|
|
||||||
|
@VintfStability
|
||||||
|
interface IVibrator {
|
||||||
|
/**
|
||||||
|
* Whether on w/ IVibratorCallback can be used w/ 'on' function
|
||||||
|
*/
|
||||||
|
const int CAP_ON_CALLBACK = 1 << 0;
|
||||||
|
/**
|
||||||
|
* Whether on w/ IVibratorCallback can be used w/ 'perform' function
|
||||||
|
*/
|
||||||
|
const int CAP_PERFORM_CALLBACK = 1 << 1;
|
||||||
|
/**
|
||||||
|
* Whether setAmplitude is supported.
|
||||||
|
*/
|
||||||
|
const int CAP_AMPLITUDE_CONTROL = 1 << 2;
|
||||||
|
/**
|
||||||
|
* Whether setExternalControl is supported.
|
||||||
|
*/
|
||||||
|
const int CAP_EXTERNAL_CONTROL = 1 << 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine capabilities of the vibrator HAL (CAP_* values)
|
||||||
|
*/
|
||||||
|
int getCapabilities();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn off vibrator
|
||||||
|
*
|
||||||
|
* Cancel a previously-started vibration, if any.
|
||||||
|
*/
|
||||||
|
void off();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn on vibrator
|
||||||
|
*
|
||||||
|
* This function must only be called after the previous timeout has expired or
|
||||||
|
* was canceled (through off()).
|
||||||
|
* @param timeoutMs number of milliseconds to vibrate.
|
||||||
|
* @param callback A callback used to inform Frameworks of state change, if supported.
|
||||||
|
*/
|
||||||
|
void on(in int timeoutMs, in IVibratorCallback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire off a predefined haptic event.
|
||||||
|
*
|
||||||
|
* @param effect The type of haptic event to trigger.
|
||||||
|
* @param strength The intensity of haptic event to trigger.
|
||||||
|
* @param callback A callback used to inform Frameworks of state change, if supported.
|
||||||
|
* @return The length of time the event is expected to take in
|
||||||
|
* milliseconds. This doesn't need to be perfectly accurate, but should be a reasonable
|
||||||
|
* approximation.
|
||||||
|
*/
|
||||||
|
int perform(in Effect effect, in EffectStrength strength, in IVibratorCallback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the motor's vibrational amplitude.
|
||||||
|
*
|
||||||
|
* Changes the force being produced by the underlying motor.
|
||||||
|
*
|
||||||
|
* @param amplitude The unitless force setting. Note that this number must
|
||||||
|
* be between 1 and 255, inclusive. If the motor does not
|
||||||
|
* have exactly 255 steps, it must do it's best to map it
|
||||||
|
* onto the number of steps it does have.
|
||||||
|
*/
|
||||||
|
void setAmplitude(in int amplitude);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables/disables control override of vibrator to audio.
|
||||||
|
*
|
||||||
|
* When this API is set, the vibrator control should be ceded to audio system
|
||||||
|
* for haptic audio. While this is enabled, issuing of other commands to control
|
||||||
|
* the vibrator is unsupported and the resulting behavior is undefined. Amplitude
|
||||||
|
* control may or may not be supported and is reflected in the return value of
|
||||||
|
* supportsAmplitudeControl() while this is enabled. When this is disabled, the
|
||||||
|
* vibrator should resume to an off state.
|
||||||
|
*
|
||||||
|
* @param enabled Whether external control should be enabled or disabled.
|
||||||
|
*/
|
||||||
|
void setExternalControl(in boolean enabled);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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;
|
||||||
|
|
||||||
|
@VintfStability
|
||||||
|
interface IVibratorCallback {
|
||||||
|
oneway void onComplete();
|
||||||
|
}
|
||||||
13
vibrator/staidl/default/Android.bp
Normal file
13
vibrator/staidl/default/Android.bp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
cc_binary {
|
||||||
|
name: "android.hardware.vibrator-service.example",
|
||||||
|
relative_install_path: "hw",
|
||||||
|
init_rc: ["vibrator-default.rc"],
|
||||||
|
vintf_fragments: ["vibrator-default.xml"],
|
||||||
|
vendor: true,
|
||||||
|
shared_libs: [
|
||||||
|
"libbase",
|
||||||
|
"libbinder_ndk",
|
||||||
|
"vintf-vibrator-ndk_platform",
|
||||||
|
],
|
||||||
|
srcs: ["main.cpp", "Vibrator.cpp"],
|
||||||
|
}
|
||||||
97
vibrator/staidl/default/Vibrator.cpp
Normal file
97
vibrator/staidl/default/Vibrator.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace aidl {
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace vibrator {
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
|
||||||
|
LOG(INFO) << "Vibrator reporting capabilities";
|
||||||
|
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
||||||
|
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_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>& callback) {
|
||||||
|
LOG(INFO) << "Vibrator on for timeoutMs: " << timeoutMs;
|
||||||
|
if (callback != nullptr) {
|
||||||
|
std::thread([=] {
|
||||||
|
LOG(INFO) << "Starting on on another thread";
|
||||||
|
usleep(timeoutMs * 1000);
|
||||||
|
LOG(INFO) << "Notifying on complete";
|
||||||
|
callback->onComplete();
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
|
||||||
|
const std::shared_ptr<IVibratorCallback>& callback,
|
||||||
|
int32_t* _aidl_return) {
|
||||||
|
LOG(INFO) << "Vibrator perform";
|
||||||
|
|
||||||
|
if (effect != Effect::CLICK && effect != Effect::TICK) {
|
||||||
|
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||||
|
}
|
||||||
|
if (strength != EffectStrength::LIGHT && strength != EffectStrength::MEDIUM &&
|
||||||
|
strength != EffectStrength::STRONG) {
|
||||||
|
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t kEffectMillis = 100;
|
||||||
|
|
||||||
|
if (callback != nullptr) {
|
||||||
|
std::thread([=] {
|
||||||
|
LOG(INFO) << "Starting perform on another thread";
|
||||||
|
usleep(kEffectMillis * 1000);
|
||||||
|
LOG(INFO) << "Notifying perform complete";
|
||||||
|
callback->onComplete();
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
*_aidl_return = kEffectMillis;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
|
||||||
|
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
|
||||||
|
if (amplitude <= 0 || amplitude > 255) {
|
||||||
|
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
|
||||||
|
}
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
||||||
|
LOG(INFO) << "Vibrator set external control: " << enabled;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace vibrator
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
} // namespace aidl
|
||||||
41
vibrator/staidl/default/Vibrator.h
Normal file
41
vibrator/staidl/default/Vibrator.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 {
|
||||||
|
namespace android {
|
||||||
|
namespace hardware {
|
||||||
|
namespace 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 setAmplitude(int32_t amplitude) override;
|
||||||
|
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vibrator
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
} // namespace aidl
|
||||||
35
vibrator/staidl/default/main.cpp
Normal file
35
vibrator/staidl/default/main.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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>
|
||||||
|
#include <android/binder_manager.h>
|
||||||
|
#include <android/binder_process.h>
|
||||||
|
|
||||||
|
using aidl::android::hardware::vibrator::Vibrator;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||||
|
std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>();
|
||||||
|
|
||||||
|
const std::string instance = std::string() + Vibrator::descriptor + "/default";
|
||||||
|
binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
|
||||||
|
CHECK(status == STATUS_OK);
|
||||||
|
|
||||||
|
ABinderProcess_joinThreadPool();
|
||||||
|
return EXIT_FAILURE; // should not reach
|
||||||
|
}
|
||||||
4
vibrator/staidl/default/vibrator-default.rc
Normal file
4
vibrator/staidl/default/vibrator-default.rc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
service vendor.vibrator-default /vendor/bin/hw/android.hardware.vibrator-service.example
|
||||||
|
class hal
|
||||||
|
user system
|
||||||
|
group system
|
||||||
6
vibrator/staidl/default/vibrator-default.xml
Normal file
6
vibrator/staidl/default/vibrator-default.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<manifest version="1.0" type="device">
|
||||||
|
<hal format="aidl">
|
||||||
|
<name>android.hardware.vibrator</name>
|
||||||
|
<fqname>IVibrator/default</fqname>
|
||||||
|
</hal>
|
||||||
|
</manifest>
|
||||||
17
vibrator/staidl/vts/Android.bp
Normal file
17
vibrator/staidl/vts/Android.bp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
cc_test {
|
||||||
|
name: "VtsHalVibratorTargetTest",
|
||||||
|
defaults: [
|
||||||
|
"VtsHalTargetTestDefaults",
|
||||||
|
"use_libaidlvintf_gtest_helper_static",
|
||||||
|
],
|
||||||
|
srcs: ["VtsHalVibratorTargetTest.cpp"],
|
||||||
|
shared_libs: [
|
||||||
|
"libbinder",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"vintf-vibrator-cpp",
|
||||||
|
],
|
||||||
|
test_suites: [
|
||||||
|
"vts-core",
|
||||||
|
],
|
||||||
|
}
|
||||||
218
vibrator/staidl/vts/VtsHalVibratorTargetTest.cpp
Normal file
218
vibrator/staidl/vts/VtsHalVibratorTargetTest.cpp
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <aidl/Gtest.h>
|
||||||
|
#include <aidl/Vintf.h>
|
||||||
|
|
||||||
|
#include <android/hardware/vibrator/BnVibratorCallback.h>
|
||||||
|
#include <android/hardware/vibrator/IVibrator.h>
|
||||||
|
#include <binder/IServiceManager.h>
|
||||||
|
#include <binder/ProcessState.h>
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
|
||||||
|
using android::ProcessState;
|
||||||
|
using android::sp;
|
||||||
|
using android::String16;
|
||||||
|
using android::binder::Status;
|
||||||
|
using android::hardware::vibrator::BnVibratorCallback;
|
||||||
|
using android::hardware::vibrator::Effect;
|
||||||
|
using android::hardware::vibrator::EffectStrength;
|
||||||
|
using android::hardware::vibrator::IVibrator;
|
||||||
|
|
||||||
|
const std::vector<Effect> kEffects = {
|
||||||
|
Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::THUD,
|
||||||
|
Effect::POP, Effect::HEAVY_CLICK, Effect::RINGTONE_1, Effect::RINGTONE_2,
|
||||||
|
Effect::RINGTONE_3, Effect::RINGTONE_4, Effect::RINGTONE_5, Effect::RINGTONE_6,
|
||||||
|
Effect::RINGTONE_7, Effect::RINGTONE_8, Effect::RINGTONE_9, Effect::RINGTONE_10,
|
||||||
|
Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13, Effect::RINGTONE_14,
|
||||||
|
Effect::RINGTONE_15, Effect::TEXTURE_TICK};
|
||||||
|
|
||||||
|
const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
|
||||||
|
EffectStrength::STRONG};
|
||||||
|
|
||||||
|
const std::vector<Effect> kInvalidEffects = {
|
||||||
|
static_cast<Effect>(static_cast<int32_t>(*kEffects.begin()) - 1),
|
||||||
|
static_cast<Effect>(static_cast<int32_t>(*kEffects.end()) + 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<EffectStrength> kInvalidEffectStrengths = {
|
||||||
|
static_cast<EffectStrength>(static_cast<int8_t>(*kEffectStrengths.begin()) - 1),
|
||||||
|
static_cast<EffectStrength>(static_cast<int8_t>(*kEffectStrengths.end()) + 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompletionCallback : public BnVibratorCallback {
|
||||||
|
public:
|
||||||
|
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
|
||||||
|
Status onComplete() override {
|
||||||
|
mCallback();
|
||||||
|
return Status::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> mCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VibratorAidl : public testing::TestWithParam<std::string> {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() override {
|
||||||
|
vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
|
||||||
|
ASSERT_NE(vibrator, nullptr);
|
||||||
|
ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<IVibrator> vibrator;
|
||||||
|
int32_t capabilities;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
|
||||||
|
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
||||||
|
sleep(1);
|
||||||
|
EXPECT_TRUE(vibrator->off().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, OnWithCallback) {
|
||||||
|
if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
|
||||||
|
|
||||||
|
std::promise<void> completionPromise;
|
||||||
|
std::future<void> completionFuture{completionPromise.get_future()};
|
||||||
|
sp<CompletionCallback> callback =
|
||||||
|
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||||
|
uint32_t durationMs = 250;
|
||||||
|
std::chrono::milliseconds timeout{durationMs * 2};
|
||||||
|
EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
|
||||||
|
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||||
|
EXPECT_TRUE(vibrator->off().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, OnCallbackNotSupported) {
|
||||||
|
if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) {
|
||||||
|
sp<CompletionCallback> callback = new CompletionCallback([] {});
|
||||||
|
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ValidateEffect) {
|
||||||
|
for (Effect effect : kEffects) {
|
||||||
|
for (EffectStrength strength : kEffectStrengths) {
|
||||||
|
int32_t lengthMs = 0;
|
||||||
|
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||||
|
EXPECT_TRUE(status.isOk() ||
|
||||||
|
status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
|
||||||
|
if (status.isOk()) {
|
||||||
|
EXPECT_GT(lengthMs, 0);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(lengthMs, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ValidateEffectWithCallback) {
|
||||||
|
if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
|
||||||
|
|
||||||
|
for (Effect effect : kEffects) {
|
||||||
|
for (EffectStrength strength : kEffectStrengths) {
|
||||||
|
std::promise<void> completionPromise;
|
||||||
|
std::future<void> completionFuture{completionPromise.get_future()};
|
||||||
|
sp<CompletionCallback> callback =
|
||||||
|
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||||
|
int lengthMs;
|
||||||
|
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
|
||||||
|
EXPECT_TRUE(status.isOk() ||
|
||||||
|
status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
|
||||||
|
if (!status.isOk()) continue;
|
||||||
|
|
||||||
|
std::chrono::milliseconds timeout{lengthMs * 2};
|
||||||
|
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
|
||||||
|
if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return;
|
||||||
|
|
||||||
|
for (Effect effect : kEffects) {
|
||||||
|
for (EffectStrength strength : kEffectStrengths) {
|
||||||
|
sp<CompletionCallback> callback = new CompletionCallback([] {});
|
||||||
|
int lengthMs;
|
||||||
|
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
|
||||||
|
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
|
||||||
|
EXPECT_EQ(lengthMs, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
|
||||||
|
for (Effect effect : kInvalidEffects) {
|
||||||
|
for (EffectStrength strength : kInvalidEffectStrengths) {
|
||||||
|
int32_t lengthMs;
|
||||||
|
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||||
|
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
|
||||||
|
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
||||||
|
EXPECT_TRUE(vibrator->setAmplitude(1).isOk());
|
||||||
|
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
||||||
|
EXPECT_TRUE(vibrator->setAmplitude(128).isOk());
|
||||||
|
sleep(1);
|
||||||
|
EXPECT_TRUE(vibrator->setAmplitude(255).isOk());
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
|
||||||
|
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
||||||
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
|
||||||
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
|
||||||
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(256).exceptionCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
|
||||||
|
if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
|
||||||
|
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
|
||||||
|
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
|
||||||
|
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
|
||||||
|
sleep(1);
|
||||||
|
EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
|
||||||
|
if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
|
||||||
|
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
|
||||||
|
vibrator->setExternalControl(true).exceptionCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(, VibratorAidl,
|
||||||
|
testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
|
||||||
|
android::PrintInstanceNameToString);
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||||
|
ProcessState::self()->startThreadPool();
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user