mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 05:49:27 +00:00
Merge "Vibrator: Stable AIDL interface." am: ad51fe22b7
am: dfbaa68529
Change-Id: I998072b6e529c40d65b2ee7d2efba8277dd68c45
This commit is contained in:
@@ -465,6 +465,13 @@
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</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">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<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