mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Disable cpp backend for android.hardware.vibrator
Disable CPP backend for vibrator HAL. Dependencies should use the stable NDK instead. This is also the recommended choice: https://source.android.com/docs/core/architecture/aidl/aidl-hals#choosing-runtime The HAL will be allowed to use ndk-stable types like PersistableBundle after disabling the legacy CPP backend. Fix: 349595412 Test: VtsHalVibratorTargetTest & VtsHalVibratorManagerTargetTest Flag: EXEMPT NDK Change-Id: Id5736e092afd36e786ecf3978ff6ad81c7a4df56
This commit is contained in:
@@ -37,6 +37,12 @@ aidl_interface {
|
||||
java: {
|
||||
enabled: false,
|
||||
},
|
||||
ndk: {
|
||||
enabled: true,
|
||||
},
|
||||
cpp: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
frozen: true,
|
||||
versions_with_info: [
|
||||
|
||||
@@ -16,16 +16,10 @@ cc_test {
|
||||
srcs: [
|
||||
// system code has the option to use the unstable C++ libbinder API
|
||||
// or the NDK one. For maximum code portability, using the ndk client
|
||||
// makes the most sense, but both are provided here as an example.
|
||||
"test-cpp-client.cpp",
|
||||
// makes the most sense.
|
||||
"test-ndk-client.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libutils",
|
||||
"android.hardware.vibrator-V2-cpp",
|
||||
"android.hardware.tests.extension.vibrator-V1-cpp",
|
||||
|
||||
"libbinder_ndk",
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
"android.hardware.tests.extension.vibrator-V1-ndk",
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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 <android/hardware/tests/extension/vibrator/ICustomVibrator.h>
|
||||
#include <android/hardware/vibrator/IVibrator.h>
|
||||
#include <binder/IInterface.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using android::checked_interface_cast;
|
||||
using android::IBinder;
|
||||
using android::IInterface;
|
||||
using android::OK;
|
||||
using android::sp;
|
||||
using android::waitForVintfService;
|
||||
using android::hardware::tests::extension::vibrator::Directionality;
|
||||
using android::hardware::tests::extension::vibrator::ICustomVibrator;
|
||||
using android::hardware::vibrator::IVibrator;
|
||||
|
||||
TEST(Cpp, CallRootMethod) {
|
||||
sp<IVibrator> vib = waitForVintfService<IVibrator>();
|
||||
ASSERT_NE(nullptr, vib.get());
|
||||
ASSERT_TRUE(vib->off().isOk());
|
||||
}
|
||||
|
||||
TEST(Cpp, CallExtMethod) {
|
||||
// normally you would want to cache this
|
||||
sp<IVibrator> vib = waitForVintfService<IVibrator>();
|
||||
ASSERT_NE(nullptr, vib.get());
|
||||
|
||||
// getting the extension
|
||||
sp<IBinder> ext;
|
||||
ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext));
|
||||
sp<ICustomVibrator> cvib = checked_interface_cast<ICustomVibrator>(ext);
|
||||
ASSERT_NE(nullptr, cvib.get());
|
||||
|
||||
// calling extension method
|
||||
ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
|
||||
}
|
||||
@@ -28,7 +28,7 @@ using ndk::SpAIBinder;
|
||||
static const std::string kInstance = std::string() + IVibrator::descriptor + "/default";
|
||||
|
||||
TEST(Ndk, CallRootMethod) {
|
||||
SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
|
||||
SpAIBinder vibBinder = SpAIBinder(AServiceManager_waitForService(kInstance.c_str()));
|
||||
ASSERT_NE(nullptr, vibBinder.get());
|
||||
std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
|
||||
ASSERT_NE(nullptr, vib.get());
|
||||
@@ -38,7 +38,7 @@ TEST(Ndk, CallRootMethod) {
|
||||
TEST(Ndk, CallExtMethod) {
|
||||
// normally you would want to cache this
|
||||
//
|
||||
SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
|
||||
SpAIBinder vibBinder = SpAIBinder(AServiceManager_waitForService(kInstance.c_str()));
|
||||
ASSERT_NE(nullptr, vibBinder.get());
|
||||
std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
|
||||
ASSERT_NE(nullptr, vib.get());
|
||||
|
||||
@@ -20,6 +20,12 @@ aidl_interface {
|
||||
java: {
|
||||
sdk_version: "system_current",
|
||||
},
|
||||
ndk: {
|
||||
enabled: true,
|
||||
},
|
||||
cpp: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
versions: [
|
||||
"1",
|
||||
|
||||
@@ -17,10 +17,10 @@ cc_test {
|
||||
tidy_timeout_srcs: ["VtsHalVibratorTargetTest.cpp"],
|
||||
srcs: ["VtsHalVibratorTargetTest.cpp"],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.vibrator-V2-cpp",
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
@@ -36,10 +36,10 @@ cc_test {
|
||||
],
|
||||
srcs: ["VtsHalVibratorManagerTargetTest.cpp"],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.vibrator-V2-cpp",
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
|
||||
@@ -15,42 +15,40 @@
|
||||
*/
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <aidl/android/hardware/vibrator/IVibrator.h>
|
||||
#include <aidl/android/hardware/vibrator/IVibratorManager.h>
|
||||
|
||||
#include <android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <android/hardware/vibrator/IVibrator.h>
|
||||
#include <android/hardware/vibrator/IVibratorManager.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <future>
|
||||
|
||||
using android::ProcessState;
|
||||
using android::sp;
|
||||
using android::String16;
|
||||
using android::binder::Status;
|
||||
using android::hardware::vibrator::BnVibratorCallback;
|
||||
using android::hardware::vibrator::CompositeEffect;
|
||||
using android::hardware::vibrator::CompositePrimitive;
|
||||
using android::hardware::vibrator::Effect;
|
||||
using android::hardware::vibrator::EffectStrength;
|
||||
using android::hardware::vibrator::IVibrator;
|
||||
using android::hardware::vibrator::IVibratorManager;
|
||||
#include "test_utils.h"
|
||||
|
||||
using aidl::android::hardware::vibrator::BnVibratorCallback;
|
||||
using aidl::android::hardware::vibrator::CompositeEffect;
|
||||
using aidl::android::hardware::vibrator::CompositePrimitive;
|
||||
using aidl::android::hardware::vibrator::Effect;
|
||||
using aidl::android::hardware::vibrator::EffectStrength;
|
||||
using aidl::android::hardware::vibrator::IVibrator;
|
||||
using aidl::android::hardware::vibrator::IVibratorManager;
|
||||
using std::chrono::high_resolution_clock;
|
||||
|
||||
const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
|
||||
android::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
|
||||
android::enum_range<EffectStrength>().end()};
|
||||
const std::vector<CompositePrimitive> kPrimitives{android::enum_range<CompositePrimitive>().begin(),
|
||||
android::enum_range<CompositePrimitive>().end()};
|
||||
const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
|
||||
ndk::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
|
||||
ndk::enum_range<EffectStrength>().end()};
|
||||
const std::vector<CompositePrimitive> kPrimitives{ndk::enum_range<CompositePrimitive>().begin(),
|
||||
ndk::enum_range<CompositePrimitive>().end()};
|
||||
|
||||
class CompletionCallback : public BnVibratorCallback {
|
||||
public:
|
||||
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
|
||||
Status onComplete() override {
|
||||
ndk::ScopedAStatus onComplete() override {
|
||||
mCallback();
|
||||
return Status::ok();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -60,55 +58,50 @@ class CompletionCallback : public BnVibratorCallback {
|
||||
class VibratorAidl : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
manager = android::waitForDeclaredService<IVibratorManager>(String16(GetParam().c_str()));
|
||||
auto serviceName = GetParam().c_str();
|
||||
manager = IVibratorManager::fromBinder(
|
||||
ndk::SpAIBinder(AServiceManager_waitForService(serviceName)));
|
||||
ASSERT_NE(manager, nullptr);
|
||||
ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk());
|
||||
EXPECT_OK(manager->getCapabilities(&capabilities));
|
||||
EXPECT_OK(manager->getVibratorIds(&vibratorIds));
|
||||
}
|
||||
|
||||
sp<IVibratorManager> manager;
|
||||
std::shared_ptr<IVibratorManager> manager;
|
||||
int32_t capabilities;
|
||||
std::vector<int32_t> vibratorIds;
|
||||
};
|
||||
|
||||
inline bool isUnknownOrUnsupported(Status status) {
|
||||
return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
|
||||
status.transactionError() == android::UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ValidateExistingVibrators) {
|
||||
sp<IVibrator> vibrator;
|
||||
for (auto& id : vibratorIds) {
|
||||
EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
for (int32_t id : vibratorIds) {
|
||||
EXPECT_OK(manager->getVibrator(id, &vibrator));
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, GetVibratorWithInvalidId) {
|
||||
int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1;
|
||||
sp<IVibrator> vibrator;
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
manager->getVibrator(invalidId, &vibrator).exceptionCode());
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
EXPECT_ILLEGAL_ARGUMENT(manager->getVibrator(invalidId, &vibrator));
|
||||
ASSERT_EQ(vibrator, nullptr);
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
|
||||
if (vibratorIds.empty()) return;
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
|
||||
std::vector<int32_t> emptyIds;
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(manager->prepareSynced(emptyIds));
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, PrepareSyncedNotSupported) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) {
|
||||
Status status = manager->prepareSynced(vibratorIds);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->prepareSynced(vibratorIds));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,15 +110,14 @@ TEST_P(VibratorAidl, PrepareOnNotSupported) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
|
||||
if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
|
||||
uint32_t durationMs = 250;
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
sp<IVibrator> vibrator;
|
||||
for (auto& id : vibratorIds) {
|
||||
EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
for (int32_t id : vibratorIds) {
|
||||
EXPECT_OK(manager->getVibrator(id, &vibrator));
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
Status status = vibrator->on(durationMs, nullptr);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->on(durationMs, nullptr));
|
||||
}
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,16 +125,16 @@ TEST_P(VibratorAidl, PreparePerformNotSupported) {
|
||||
if (vibratorIds.empty()) return;
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
|
||||
if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
sp<IVibrator> vibrator;
|
||||
for (auto& id : vibratorIds) {
|
||||
EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
for (int32_t id : vibratorIds) {
|
||||
EXPECT_OK(manager->getVibrator(id, &vibrator));
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
int32_t lengthMs = 0;
|
||||
Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(
|
||||
vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs));
|
||||
}
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,15 +149,14 @@ TEST_P(VibratorAidl, PrepareComposeNotSupported) {
|
||||
effect.scale = 1.0f;
|
||||
composite.emplace_back(effect);
|
||||
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
sp<IVibrator> vibrator;
|
||||
for (auto& id : vibratorIds) {
|
||||
EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
for (int32_t id : vibratorIds) {
|
||||
EXPECT_OK(manager->getVibrator(id, &vibrator));
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
Status status = vibrator->compose(composite, nullptr);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->compose(composite, nullptr));
|
||||
}
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,51 +168,58 @@ TEST_P(VibratorAidl, TriggerWithCallback) {
|
||||
|
||||
std::promise<void> completionPromise;
|
||||
std::future<void> completionFuture{completionPromise.get_future()};
|
||||
sp<CompletionCallback> callback =
|
||||
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>(
|
||||
[&completionPromise] { completionPromise.set_value(); });
|
||||
uint32_t durationMs = 250;
|
||||
std::chrono::milliseconds timeout{durationMs * 2};
|
||||
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
sp<IVibrator> vibrator;
|
||||
for (auto& id : vibratorIds) {
|
||||
EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
for (int32_t id : vibratorIds) {
|
||||
EXPECT_OK(manager->getVibrator(id, &vibrator));
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk());
|
||||
EXPECT_OK(vibrator->on(durationMs, nullptr));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(manager->triggerSynced(callback).isOk());
|
||||
EXPECT_OK(manager->triggerSynced(callback));
|
||||
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, TriggerSyncNotSupported) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) {
|
||||
Status status = manager->triggerSynced(nullptr);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->triggerSynced(nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
|
||||
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
|
||||
if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) {
|
||||
sp<CompletionCallback> callback = new CompletionCallback([] {});
|
||||
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
|
||||
Status status = manager->triggerSynced(callback);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_TRUE(manager->cancelSynced().isOk());
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
|
||||
EXPECT_OK(manager->prepareSynced(vibratorIds));
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->triggerSynced(callback));
|
||||
EXPECT_OK(manager->cancelSynced());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> FindVibratorManagerNames() {
|
||||
std::vector<std::string> names;
|
||||
constexpr auto callback = [](const char* instance, void* context) {
|
||||
std::string fullName = std::string(IVibratorManager::descriptor) + "/" + instance;
|
||||
static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
|
||||
};
|
||||
AServiceManager_forEachDeclaredInstance(IVibratorManager::descriptor,
|
||||
static_cast<void*>(&names), callback);
|
||||
return names;
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Vibrator, VibratorAidl,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(FindVibratorManagerNames()),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
ProcessState::self()->startThreadPool();
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
@@ -15,38 +15,37 @@
|
||||
*/
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <android/hardware/vibrator/IVibrator.h>
|
||||
#include <android/hardware/vibrator/IVibratorManager.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <aidl/android/hardware/vibrator/IVibrator.h>
|
||||
#include <aidl/android/hardware/vibrator/IVibratorManager.h>
|
||||
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <future>
|
||||
|
||||
using android::ProcessState;
|
||||
using android::sp;
|
||||
using android::String16;
|
||||
using android::binder::Status;
|
||||
using android::hardware::vibrator::ActivePwle;
|
||||
using android::hardware::vibrator::BnVibratorCallback;
|
||||
using android::hardware::vibrator::Braking;
|
||||
using android::hardware::vibrator::BrakingPwle;
|
||||
using android::hardware::vibrator::CompositeEffect;
|
||||
using android::hardware::vibrator::CompositePrimitive;
|
||||
using android::hardware::vibrator::Effect;
|
||||
using android::hardware::vibrator::EffectStrength;
|
||||
using android::hardware::vibrator::IVibrator;
|
||||
using android::hardware::vibrator::IVibratorManager;
|
||||
using android::hardware::vibrator::PrimitivePwle;
|
||||
#include "test_utils.h"
|
||||
|
||||
using aidl::android::hardware::vibrator::ActivePwle;
|
||||
using aidl::android::hardware::vibrator::BnVibratorCallback;
|
||||
using aidl::android::hardware::vibrator::Braking;
|
||||
using aidl::android::hardware::vibrator::BrakingPwle;
|
||||
using aidl::android::hardware::vibrator::CompositeEffect;
|
||||
using aidl::android::hardware::vibrator::CompositePrimitive;
|
||||
using aidl::android::hardware::vibrator::Effect;
|
||||
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 std::chrono::high_resolution_clock;
|
||||
|
||||
using namespace ::std::chrono_literals;
|
||||
|
||||
const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
|
||||
android::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
|
||||
android::enum_range<EffectStrength>().end()};
|
||||
const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
|
||||
ndk::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
|
||||
ndk::enum_range<EffectStrength>().end()};
|
||||
|
||||
const std::vector<Effect> kInvalidEffects = {
|
||||
static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
|
||||
@@ -59,8 +58,7 @@ const std::vector<EffectStrength> kInvalidEffectStrengths = {
|
||||
};
|
||||
|
||||
const std::vector<CompositePrimitive> kCompositePrimitives{
|
||||
android::enum_range<CompositePrimitive>().begin(),
|
||||
android::enum_range<CompositePrimitive>().end()};
|
||||
ndk::enum_range<CompositePrimitive>().begin(), ndk::enum_range<CompositePrimitive>().end()};
|
||||
|
||||
const std::vector<CompositePrimitive> kRequiredPrimitives = {
|
||||
CompositePrimitive::CLICK, CompositePrimitive::LIGHT_TICK,
|
||||
@@ -74,14 +72,36 @@ const std::vector<CompositePrimitive> kInvalidPrimitives = {
|
||||
};
|
||||
|
||||
// Timeout to wait for vibration callback completion.
|
||||
static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
|
||||
static constexpr std::chrono::milliseconds VIBRATION_CALLBACK_TIMEOUT = 100ms;
|
||||
|
||||
static std::vector<std::string> findVibratorManagerNames() {
|
||||
std::vector<std::string> names;
|
||||
constexpr auto callback = [](const char* instance, void* context) {
|
||||
auto fullName = std::string(IVibratorManager::descriptor) + "/" + instance;
|
||||
static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
|
||||
};
|
||||
AServiceManager_forEachDeclaredInstance(IVibratorManager::descriptor,
|
||||
static_cast<void*>(&names), callback);
|
||||
return names;
|
||||
}
|
||||
|
||||
static std::vector<std::string> findUnmanagedVibratorNames() {
|
||||
std::vector<std::string> names;
|
||||
constexpr auto callback = [](const char* instance, void* context) {
|
||||
auto fullName = std::string(IVibrator::descriptor) + "/" + instance;
|
||||
static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
|
||||
};
|
||||
AServiceManager_forEachDeclaredInstance(IVibrator::descriptor, static_cast<void*>(&names),
|
||||
callback);
|
||||
return names;
|
||||
}
|
||||
|
||||
class CompletionCallback : public BnVibratorCallback {
|
||||
public:
|
||||
CompletionCallback(const std::function<void()> &callback) : mCallback(callback) {}
|
||||
Status onComplete() override {
|
||||
ndk::ScopedAStatus onComplete() override {
|
||||
mCallback();
|
||||
return Status::ok();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -93,88 +113,87 @@ class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>>
|
||||
virtual void SetUp() override {
|
||||
int32_t managerIdx = std::get<0>(GetParam());
|
||||
int32_t vibratorId = std::get<1>(GetParam());
|
||||
auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
|
||||
|
||||
if (managerIdx < 0) {
|
||||
// Testing a unmanaged vibrator, using vibratorId as index from registered HALs
|
||||
auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
|
||||
ASSERT_LT(vibratorId, vibratorAidlNames.size());
|
||||
auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
|
||||
vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
|
||||
std::vector<std::string> vibratorNames = findUnmanagedVibratorNames();
|
||||
ASSERT_LT(vibratorId, vibratorNames.size());
|
||||
vibrator = IVibrator::fromBinder(ndk::SpAIBinder(
|
||||
AServiceManager_waitForService(vibratorNames[vibratorId].c_str())));
|
||||
} else {
|
||||
// Testing a managed vibrator, using vibratorId to retrieve it from the manager
|
||||
ASSERT_LT(managerIdx, managerAidlNames.size());
|
||||
auto managerName = String16(managerAidlNames[managerIdx].c_str());
|
||||
auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
|
||||
auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
|
||||
ASSERT_TRUE(vibratorResult.isOk());
|
||||
std::vector<std::string> managerNames = findVibratorManagerNames();
|
||||
ASSERT_LT(managerIdx, managerNames.size());
|
||||
auto vibratorManager = IVibratorManager::fromBinder(ndk::SpAIBinder(
|
||||
AServiceManager_waitForService(managerNames[managerIdx].c_str())));
|
||||
EXPECT_OK(vibratorManager->getVibrator(vibratorId, &vibrator))
|
||||
<< "\n For vibrator id: " << vibratorId;
|
||||
}
|
||||
|
||||
ASSERT_NE(vibrator, nullptr);
|
||||
ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_OK(vibrator->getCapabilities(&capabilities));
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
// Reset vibrator state between tests.
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
|
||||
sp<IVibrator> vibrator;
|
||||
std::shared_ptr<IVibrator> vibrator;
|
||||
int32_t capabilities;
|
||||
};
|
||||
|
||||
inline bool isUnknownOrUnsupported(Status status) {
|
||||
return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
|
||||
status.transactionError() == android::UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
static float getResonantFrequencyHz(sp<IVibrator> vibrator, int32_t capabilities) {
|
||||
static float getResonantFrequencyHz(const std::shared_ptr<IVibrator>& vibrator,
|
||||
int32_t capabilities) {
|
||||
float resonantFrequencyHz;
|
||||
Status status = vibrator->getResonantFrequency(&resonantFrequencyHz);
|
||||
ndk::ScopedAStatus status = vibrator->getResonantFrequency(&resonantFrequencyHz);
|
||||
if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
|
||||
EXPECT_OK(std::move(status));
|
||||
EXPECT_GT(resonantFrequencyHz, 0);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
return resonantFrequencyHz;
|
||||
}
|
||||
|
||||
static float getFrequencyResolutionHz(sp<IVibrator> vibrator, int32_t capabilities) {
|
||||
static float getFrequencyResolutionHz(const std::shared_ptr<IVibrator>& vibrator,
|
||||
int32_t capabilities) {
|
||||
float freqResolutionHz;
|
||||
Status status = vibrator->getFrequencyResolution(&freqResolutionHz);
|
||||
ndk::ScopedAStatus status = vibrator->getFrequencyResolution(&freqResolutionHz);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
EXPECT_OK(std::move(status));
|
||||
EXPECT_GT(freqResolutionHz, 0);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
return freqResolutionHz;
|
||||
}
|
||||
|
||||
static float getFrequencyMinimumHz(sp<IVibrator> vibrator, int32_t capabilities) {
|
||||
static float getFrequencyMinimumHz(const std::shared_ptr<IVibrator>& vibrator,
|
||||
int32_t capabilities) {
|
||||
float freqMinimumHz;
|
||||
Status status = vibrator->getFrequencyMinimum(&freqMinimumHz);
|
||||
ndk::ScopedAStatus status = vibrator->getFrequencyMinimum(&freqMinimumHz);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
EXPECT_OK(std::move(status));
|
||||
|
||||
float resonantFrequencyHz = getResonantFrequencyHz(vibrator, capabilities);
|
||||
|
||||
EXPECT_GT(freqMinimumHz, 0);
|
||||
EXPECT_LE(freqMinimumHz, resonantFrequencyHz);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
return freqMinimumHz;
|
||||
}
|
||||
|
||||
static float getFrequencyMaximumHz(sp<IVibrator> vibrator, int32_t capabilities) {
|
||||
static float getFrequencyMaximumHz(const std::shared_ptr<IVibrator>& vibrator,
|
||||
int32_t capabilities) {
|
||||
std::vector<float> bandwidthAmplitudeMap;
|
||||
Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
|
||||
ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
EXPECT_OK(std::move(status));
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
|
||||
float freqMaximumHz = ((bandwidthAmplitudeMap.size() - 1) *
|
||||
@@ -191,7 +210,8 @@ static float getAmplitudeMax() {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
static ActivePwle composeValidActivePwle(sp<IVibrator> vibrator, int32_t capabilities) {
|
||||
static ActivePwle composeValidActivePwle(const std::shared_ptr<IVibrator>& vibrator,
|
||||
int32_t capabilities) {
|
||||
float frequencyHz;
|
||||
if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
|
||||
frequencyHz = getResonantFrequencyHz(vibrator, capabilities);
|
||||
@@ -212,9 +232,9 @@ static ActivePwle composeValidActivePwle(sp<IVibrator> vibrator, int32_t capabil
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
|
||||
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
||||
EXPECT_OK(vibrator->on(2000, nullptr /*callback*/));
|
||||
sleep(1);
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, OnWithCallback) {
|
||||
@@ -223,26 +243,25 @@ TEST_P(VibratorAidl, OnWithCallback) {
|
||||
|
||||
std::promise<void> completionPromise;
|
||||
std::future<void> completionFuture{completionPromise.get_future()};
|
||||
sp<CompletionCallback> callback =
|
||||
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>(
|
||||
[&completionPromise] { completionPromise.set_value(); });
|
||||
uint32_t durationMs = 250;
|
||||
auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
|
||||
EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
|
||||
EXPECT_OK(vibrator->on(durationMs, callback));
|
||||
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, OnCallbackNotSupported) {
|
||||
if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) {
|
||||
sp<CompletionCallback> callback = new CompletionCallback([] {});
|
||||
Status status = vibrator->on(250, callback);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->on(250, callback));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ValidateEffect) {
|
||||
std::vector<Effect> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedEffects(&supported));
|
||||
|
||||
for (Effect effect : kEffects) {
|
||||
bool isEffectSupported =
|
||||
@@ -250,15 +269,18 @@ TEST_P(VibratorAidl, ValidateEffect) {
|
||||
|
||||
for (EffectStrength strength : kEffectStrengths) {
|
||||
int32_t lengthMs = 0;
|
||||
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||
ndk::ScopedAStatus status =
|
||||
vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||
|
||||
if (isEffectSupported) {
|
||||
EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
|
||||
EXPECT_OK(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
EXPECT_GT(lengthMs, 0);
|
||||
usleep(lengthMs * 1000);
|
||||
EXPECT_OK(vibrator->off());
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status))
|
||||
<< status << " " << toString(effect) << " " << toString(strength);
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,7 +291,7 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) {
|
||||
return;
|
||||
|
||||
std::vector<Effect> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedEffects(&supported));
|
||||
|
||||
for (Effect effect : kEffects) {
|
||||
bool isEffectSupported =
|
||||
@@ -278,25 +300,26 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) {
|
||||
for (EffectStrength strength : kEffectStrengths) {
|
||||
std::promise<void> completionPromise;
|
||||
std::future<void> completionFuture{completionPromise.get_future()};
|
||||
sp<CompletionCallback> callback =
|
||||
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>(
|
||||
[&completionPromise] { completionPromise.set_value(); });
|
||||
int lengthMs = 0;
|
||||
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
|
||||
ndk::ScopedAStatus status = vibrator->perform(effect, strength, callback, &lengthMs);
|
||||
|
||||
if (isEffectSupported) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
EXPECT_OK(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
EXPECT_GT(lengthMs, 0);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
|
||||
if (!status.isOk())
|
||||
continue;
|
||||
if (lengthMs <= 0) continue;
|
||||
|
||||
auto timeout = std::chrono::milliseconds(lengthMs) + VIBRATION_CALLBACK_TIMEOUT;
|
||||
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,10 +330,10 @@ TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
|
||||
|
||||
for (Effect effect : kEffects) {
|
||||
for (EffectStrength strength : kEffectStrengths) {
|
||||
sp<CompletionCallback> callback = new CompletionCallback([] {});
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
|
||||
int lengthMs;
|
||||
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->perform(effect, strength, callback, &lengthMs))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,53 +342,52 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
|
||||
for (Effect effect : kInvalidEffects) {
|
||||
for (EffectStrength strength : kEffectStrengths) {
|
||||
int32_t lengthMs;
|
||||
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status))
|
||||
<< status << toString(effect) << " " << toString(strength);
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(
|
||||
vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
}
|
||||
for (Effect effect : kEffects) {
|
||||
for (EffectStrength strength : kInvalidEffectStrengths) {
|
||||
int32_t lengthMs;
|
||||
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status))
|
||||
<< status << " " << toString(effect) << " " << toString(strength);
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(
|
||||
vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
|
||||
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
|
||||
EXPECT_OK(vibrator->setAmplitude(0.1f));
|
||||
EXPECT_OK(vibrator->on(2000, nullptr /*callback*/));
|
||||
EXPECT_OK(vibrator->setAmplitude(0.5f));
|
||||
sleep(1);
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
|
||||
EXPECT_OK(vibrator->setAmplitude(1.0f));
|
||||
sleep(1);
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
}
|
||||
|
||||
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(1.1).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(-1));
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(0));
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(1.1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
|
||||
if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
|
||||
Status status = vibrator->setAmplitude(1);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setAmplitude(1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
|
||||
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
|
||||
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
|
||||
EXPECT_OK(vibrator->setExternalControl(true));
|
||||
sleep(1);
|
||||
EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
|
||||
EXPECT_OK(vibrator->setExternalControl(false));
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
@@ -375,15 +397,15 @@ TEST_P(VibratorAidl, ExternalAmplitudeControl) {
|
||||
(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
|
||||
|
||||
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
|
||||
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
|
||||
EXPECT_OK(vibrator->setExternalControl(true));
|
||||
|
||||
Status amplitudeStatus = vibrator->setAmplitude(0.5);
|
||||
if (supportsExternalAmplitudeControl) {
|
||||
EXPECT_TRUE(amplitudeStatus.isOk());
|
||||
EXPECT_OK(vibrator->setAmplitude(0.5));
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(amplitudeStatus)) << amplitudeStatus;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setAmplitude(0.5));
|
||||
}
|
||||
EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
|
||||
|
||||
EXPECT_OK(vibrator->setExternalControl(false));
|
||||
} else {
|
||||
EXPECT_FALSE(supportsExternalAmplitudeControl);
|
||||
}
|
||||
@@ -391,18 +413,16 @@ TEST_P(VibratorAidl, ExternalAmplitudeControl) {
|
||||
|
||||
TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
|
||||
if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
|
||||
Status status = vibrator->setExternalControl(true);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setExternalControl(true));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, GetSupportedPrimitives) {
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||
std::vector<CompositePrimitive> supported;
|
||||
EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
|
||||
|
||||
for (auto primitive : kCompositePrimitives) {
|
||||
for (CompositePrimitive primitive : kCompositePrimitives) {
|
||||
bool isPrimitiveSupported =
|
||||
std::find(supported.begin(), supported.end(), primitive) != supported.end();
|
||||
bool isPrimitiveRequired =
|
||||
@@ -417,22 +437,23 @@ TEST_P(VibratorAidl, GetSupportedPrimitives) {
|
||||
TEST_P(VibratorAidl, GetPrimitiveDuration) {
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||
std::vector<CompositePrimitive> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
|
||||
|
||||
for (auto primitive : kCompositePrimitives) {
|
||||
for (CompositePrimitive primitive : kCompositePrimitives) {
|
||||
bool isPrimitiveSupported =
|
||||
std::find(supported.begin(), supported.end(), primitive) != supported.end();
|
||||
int32_t duration;
|
||||
|
||||
Status status = vibrator->getPrimitiveDuration(primitive, &duration);
|
||||
|
||||
if (isPrimitiveSupported) {
|
||||
EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
|
||||
EXPECT_OK(vibrator->getPrimitiveDuration(primitive, &duration))
|
||||
<< "\n For primitive: " << toString(primitive) << " " << duration;
|
||||
if (primitive != CompositePrimitive::NOOP) {
|
||||
ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
|
||||
ASSERT_GT(duration, 0)
|
||||
<< "\n For primitive: " << toString(primitive) << " " << duration;
|
||||
}
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->getPrimitiveDuration(primitive, &duration))
|
||||
<< "\n For primitive: " << toString(primitive);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,14 +467,14 @@ TEST_P(VibratorAidl, ComposeValidPrimitives) {
|
||||
std::vector<CompositePrimitive> supported;
|
||||
int32_t maxDelay, maxSize;
|
||||
|
||||
ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
|
||||
EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
|
||||
EXPECT_OK(vibrator->getCompositionDelayMax(&maxDelay));
|
||||
EXPECT_OK(vibrator->getCompositionSizeMax(&maxSize));
|
||||
|
||||
std::vector<CompositeEffect> composite;
|
||||
|
||||
for (int i = 0; i < supported.size(); i++) {
|
||||
auto primitive = supported[i];
|
||||
CompositePrimitive primitive = supported[i];
|
||||
float t = static_cast<float>(i + 1) / supported.size();
|
||||
CompositeEffect effect;
|
||||
|
||||
@@ -467,8 +488,8 @@ TEST_P(VibratorAidl, ComposeValidPrimitives) {
|
||||
}
|
||||
|
||||
if (composite.size() != 0) {
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,12 +498,12 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
|
||||
GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
|
||||
}
|
||||
|
||||
auto unsupported = kInvalidPrimitives;
|
||||
std::vector<CompositePrimitive> unsupported(kInvalidPrimitives);
|
||||
std::vector<CompositePrimitive> supported;
|
||||
|
||||
ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
|
||||
|
||||
for (auto primitive : kCompositePrimitives) {
|
||||
for (CompositePrimitive primitive : kCompositePrimitives) {
|
||||
bool isPrimitiveSupported =
|
||||
std::find(supported.begin(), supported.end(), primitive) != supported.end();
|
||||
|
||||
@@ -491,16 +512,15 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto primitive : unsupported) {
|
||||
for (CompositePrimitive primitive : unsupported) {
|
||||
std::vector<CompositeEffect> composite(1);
|
||||
|
||||
for (auto& effect : composite) {
|
||||
for (CompositeEffect& effect : composite) {
|
||||
effect.delayMs = 0;
|
||||
effect.primitive = primitive;
|
||||
effect.scale = 1.0f;
|
||||
}
|
||||
Status status = vibrator->compose(composite, nullptr);
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->compose(composite, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,18 +536,18 @@ TEST_P(VibratorAidl, ComposeScaleBoundary) {
|
||||
effect.primitive = CompositePrimitive::CLICK;
|
||||
|
||||
effect.scale = std::nextafter(0.0f, -1.0f);
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
|
||||
|
||||
effect.scale = 0.0f;
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
effect.scale = 1.0f;
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
effect.scale = std::nextafter(1.0f, 2.0f);
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ComposeDelayBoundary) {
|
||||
@@ -537,7 +557,7 @@ TEST_P(VibratorAidl, ComposeDelayBoundary) {
|
||||
|
||||
int32_t maxDelay;
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
|
||||
EXPECT_OK(vibrator->getCompositionDelayMax(&maxDelay));
|
||||
|
||||
std::vector<CompositeEffect> composite(1);
|
||||
CompositeEffect& effect = composite[0];
|
||||
@@ -546,19 +566,19 @@ TEST_P(VibratorAidl, ComposeDelayBoundary) {
|
||||
effect.scale = 1.0f;
|
||||
|
||||
effect.delayMs = 0;
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
effect.delayMs = 1;
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
effect.delayMs = maxDelay;
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
effect.delayMs = maxDelay + 1;
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ComposeSizeBoundary) {
|
||||
@@ -568,7 +588,7 @@ TEST_P(VibratorAidl, ComposeSizeBoundary) {
|
||||
|
||||
int32_t maxSize;
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
|
||||
EXPECT_OK(vibrator->getCompositionSizeMax(&maxSize));
|
||||
|
||||
std::vector<CompositeEffect> composite(maxSize);
|
||||
CompositeEffect effect;
|
||||
@@ -578,11 +598,11 @@ TEST_P(VibratorAidl, ComposeSizeBoundary) {
|
||||
effect.scale = 1.0f;
|
||||
|
||||
std::fill(composite.begin(), composite.end(), effect);
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->compose(composite, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
|
||||
composite.emplace_back(effect);
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ComposeCallback) {
|
||||
@@ -591,18 +611,17 @@ TEST_P(VibratorAidl, ComposeCallback) {
|
||||
}
|
||||
|
||||
std::vector<CompositePrimitive> supported;
|
||||
EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
|
||||
|
||||
ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
|
||||
|
||||
for (auto primitive : supported) {
|
||||
for (CompositePrimitive primitive : supported) {
|
||||
if (primitive == CompositePrimitive::NOOP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::promise<void> completionPromise;
|
||||
std::future<void> completionFuture{completionPromise.get_future()};
|
||||
sp<CompletionCallback> callback =
|
||||
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>(
|
||||
[&completionPromise] { completionPromise.set_value(); });
|
||||
CompositeEffect effect;
|
||||
std::vector<CompositeEffect> composite;
|
||||
int32_t durationMs;
|
||||
@@ -615,50 +634,50 @@ TEST_P(VibratorAidl, ComposeCallback) {
|
||||
effect.scale = 1.0f;
|
||||
composite.emplace_back(effect);
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE,
|
||||
vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
|
||||
<< toString(primitive);
|
||||
EXPECT_OK(vibrator->getPrimitiveDuration(primitive, &durationMs))
|
||||
<< "\n For primitive: " << toString(primitive);
|
||||
duration = std::chrono::milliseconds(durationMs);
|
||||
|
||||
start = high_resolution_clock::now();
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
|
||||
<< toString(primitive);
|
||||
EXPECT_OK(vibrator->compose(composite, callback))
|
||||
<< "\n For primitive: " << toString(primitive);
|
||||
|
||||
EXPECT_EQ(completionFuture.wait_for(duration + VIBRATION_CALLBACK_TIMEOUT),
|
||||
std::future_status::ready)
|
||||
<< toString(primitive);
|
||||
<< "\n For primitive: " << toString(primitive);
|
||||
end = high_resolution_clock::now();
|
||||
|
||||
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
|
||||
EXPECT_GE(elapsed.count(), duration.count())
|
||||
<< "\n For primitive: " << toString(primitive);
|
||||
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off()) << "\n For primitive: " << toString(primitive);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, AlwaysOn) {
|
||||
if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
|
||||
std::vector<Effect> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedAlwaysOnEffects(&supported));
|
||||
|
||||
for (Effect effect : kEffects) {
|
||||
bool isEffectSupported =
|
||||
std::find(supported.begin(), supported.end(), effect) != supported.end();
|
||||
|
||||
for (EffectStrength strength : kEffectStrengths) {
|
||||
Status status = vibrator->alwaysOnEnable(0, effect, strength);
|
||||
ndk::ScopedAStatus status = vibrator->alwaysOnEnable(0, effect, strength);
|
||||
|
||||
if (isEffectSupported) {
|
||||
EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
|
||||
<< toString(effect) << " " << toString(strength);
|
||||
EXPECT_OK(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status))
|
||||
<< status << " " << toString(effect) << " " << toString(strength);
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
|
||||
<< "\n For effect: " << toString(effect) << " " << toString(strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
|
||||
EXPECT_OK(vibrator->alwaysOnDisable(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,12 +687,12 @@ TEST_P(VibratorAidl, GetResonantFrequency) {
|
||||
|
||||
TEST_P(VibratorAidl, GetQFactor) {
|
||||
float qFactor;
|
||||
Status status = vibrator->getQFactor(&qFactor);
|
||||
ndk::ScopedAStatus status = vibrator->getQFactor(&qFactor);
|
||||
if (capabilities & IVibrator::CAP_GET_Q_FACTOR) {
|
||||
EXPECT_OK(std::move(status));
|
||||
ASSERT_GT(qFactor, 0);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,9 +706,9 @@ TEST_P(VibratorAidl, GetFrequencyMinimum) {
|
||||
|
||||
TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) {
|
||||
std::vector<float> bandwidthAmplitudeMap;
|
||||
Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
|
||||
ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
EXPECT_OK(std::move(status));
|
||||
ASSERT_FALSE(bandwidthAmplitudeMap.empty());
|
||||
|
||||
int minMapSize = (getResonantFrequencyHz(vibrator, capabilities) -
|
||||
@@ -702,42 +721,42 @@ TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) {
|
||||
ASSERT_LE(e, 1.0);
|
||||
}
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, GetPwlePrimitiveDurationMax) {
|
||||
int32_t durationMs;
|
||||
Status status = vibrator->getPwlePrimitiveDurationMax(&durationMs);
|
||||
ndk::ScopedAStatus status = vibrator->getPwlePrimitiveDurationMax(&durationMs);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
EXPECT_OK(std::move(status));
|
||||
ASSERT_NE(durationMs, 0);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, GetPwleCompositionSizeMax) {
|
||||
int32_t maxSize;
|
||||
Status status = vibrator->getPwleCompositionSizeMax(&maxSize);
|
||||
ndk::ScopedAStatus status = vibrator->getPwleCompositionSizeMax(&maxSize);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
EXPECT_OK(std::move(status));
|
||||
ASSERT_NE(maxSize, 0);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, GetSupportedBraking) {
|
||||
std::vector<Braking> supported;
|
||||
Status status = vibrator->getSupportedBraking(&supported);
|
||||
ndk::ScopedAStatus status = vibrator->getSupportedBraking(&supported);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
bool isDefaultNoneSupported =
|
||||
std::find(supported.begin(), supported.end(), Braking::NONE) != supported.end();
|
||||
EXPECT_OK(std::move(status));
|
||||
ASSERT_TRUE(isDefaultNoneSupported);
|
||||
EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
|
||||
} else {
|
||||
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
|
||||
EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,7 +765,7 @@ TEST_P(VibratorAidl, ComposeValidPwle) {
|
||||
ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities);
|
||||
|
||||
std::vector<Braking> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedBraking(&supported));
|
||||
bool isClabSupported =
|
||||
std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
|
||||
BrakingPwle firstBraking;
|
||||
@@ -765,11 +784,11 @@ TEST_P(VibratorAidl, ComposeValidPwle) {
|
||||
secondBraking.braking = Braking::NONE;
|
||||
secondBraking.duration = 10;
|
||||
|
||||
auto pwleQueue =
|
||||
std::vector<PrimitivePwle>{firstActive, firstBraking, secondActive, secondBraking};
|
||||
std::vector<PrimitivePwle> pwleQueue = {firstActive, firstBraking, secondActive,
|
||||
secondBraking};
|
||||
|
||||
EXPECT_EQ(Status::EX_NONE, vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->composePwle(pwleQueue, nullptr));
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,8 +799,8 @@ TEST_P(VibratorAidl, ComposeValidPwleWithCallback) {
|
||||
|
||||
std::promise<void> completionPromise;
|
||||
std::future<void> completionFuture{completionPromise.get_future()};
|
||||
sp<CompletionCallback> callback =
|
||||
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
|
||||
auto callback = ndk::SharedRefBase::make<CompletionCallback>(
|
||||
[&completionPromise] { completionPromise.set_value(); });
|
||||
int32_t segmentDurationMaxMs;
|
||||
vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
|
||||
uint32_t durationMs = segmentDurationMaxMs * 2 + 100; // Sum of 2 active and 1 braking below
|
||||
@@ -790,27 +809,25 @@ TEST_P(VibratorAidl, ComposeValidPwleWithCallback) {
|
||||
ActivePwle active = composeValidActivePwle(vibrator, capabilities);
|
||||
|
||||
std::vector<Braking> supported;
|
||||
ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
|
||||
EXPECT_OK(vibrator->getSupportedBraking(&supported));
|
||||
bool isClabSupported =
|
||||
std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
|
||||
BrakingPwle braking;
|
||||
braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE;
|
||||
braking.duration = 100;
|
||||
|
||||
auto pwleQueue = std::vector<PrimitivePwle>{active, braking, active};
|
||||
std::vector<PrimitivePwle> pwleQueue = {active, braking, active};
|
||||
|
||||
EXPECT_TRUE(vibrator->composePwle(pwleQueue, callback).isOk());
|
||||
EXPECT_OK(vibrator->composePwle(pwleQueue, callback));
|
||||
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_OK(vibrator->off());
|
||||
}
|
||||
|
||||
TEST_P(VibratorAidl, ComposePwleSegmentBoundary) {
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
std::vector<PrimitivePwle> pwleQueue;
|
||||
// test empty queue
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
|
||||
|
||||
ActivePwle active = composeValidActivePwle(vibrator, capabilities);
|
||||
|
||||
@@ -824,9 +841,7 @@ TEST_P(VibratorAidl, ComposePwleSegmentBoundary) {
|
||||
pwleQueue.emplace_back(std::move(pwle));
|
||||
}
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,20 +851,16 @@ TEST_P(VibratorAidl, ComposePwleAmplitudeParameterBoundary) {
|
||||
active.startAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
|
||||
active.endAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
|
||||
|
||||
auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
|
||||
std::vector<PrimitivePwle> pwleQueueGreater = {active};
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueGreater, nullptr));
|
||||
|
||||
active.startAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
|
||||
active.endAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
|
||||
|
||||
auto pwleQueueLess = std::vector<PrimitivePwle>{active};
|
||||
std::vector<PrimitivePwle> pwleQueueLess = {active};
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueLess, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,20 +876,16 @@ TEST_P(VibratorAidl, ComposePwleFrequencyParameterBoundary) {
|
||||
freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
|
||||
active.endFrequency = freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
|
||||
|
||||
auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
|
||||
std::vector<PrimitivePwle> pwleQueueGreater = {active};
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueGreater, nullptr));
|
||||
|
||||
active.startFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
|
||||
active.endFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
|
||||
|
||||
auto pwleQueueLess = std::vector<PrimitivePwle>{active};
|
||||
std::vector<PrimitivePwle> pwleQueueLess = {active};
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueLess, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -890,32 +897,30 @@ TEST_P(VibratorAidl, ComposePwleSegmentDurationBoundary) {
|
||||
vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
|
||||
active.duration = segmentDurationMaxMs + 10; // Segment duration greater than allowed
|
||||
|
||||
auto pwleQueue = std::vector<PrimitivePwle>{active};
|
||||
std::vector<PrimitivePwle> pwleQueue = {active};
|
||||
|
||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||
vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
|
||||
EXPECT_TRUE(vibrator->off().isOk());
|
||||
EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
|
||||
std::vector<std::tuple<int32_t, int32_t>> tuples;
|
||||
auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
|
||||
std::vector<int32_t> vibratorIds;
|
||||
|
||||
for (int i = 0; i < managerAidlNames.size(); i++) {
|
||||
auto managerName = String16(managerAidlNames[i].c_str());
|
||||
auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
|
||||
std::vector<std::string> managerNames = findVibratorManagerNames();
|
||||
std::vector<int32_t> vibratorIds;
|
||||
for (int i = 0; i < managerNames.size(); i++) {
|
||||
auto vibratorManager = IVibratorManager::fromBinder(
|
||||
ndk::SpAIBinder(AServiceManager_waitForService(managerNames[i].c_str())));
|
||||
if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
|
||||
for (auto &vibratorId : vibratorIds) {
|
||||
tuples.push_back(std::make_tuple(i, vibratorId));
|
||||
for (int32_t vibratorId : vibratorIds) {
|
||||
tuples.emplace_back(i, vibratorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
|
||||
for (int i = 0; i < vibratorAidlNames.size(); i++) {
|
||||
tuples.push_back(std::make_tuple(-1, i));
|
||||
std::vector<std::string> vibratorNames = findUnmanagedVibratorNames();
|
||||
for (int i = 0; i < vibratorNames.size(); i++) {
|
||||
tuples.emplace_back(-1, i);
|
||||
}
|
||||
|
||||
return tuples;
|
||||
@@ -936,7 +941,7 @@ INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibra
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
ProcessState::self()->startThreadPool();
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
60
vibrator/aidl/vts/test_utils.h
Normal file
60
vibrator/aidl/vts/test_utils.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_TEST_UTILS_H
|
||||
#define VIBRATOR_HAL_TEST_UTILS_H
|
||||
|
||||
#include <android/binder_auto_utils.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#if !defined(EXPECT_OK)
|
||||
#define EXPECT_OK(expression) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::ndk::ScopedAStatus&& _status = (expression); _status.isOk()) \
|
||||
; \
|
||||
else \
|
||||
ADD_FAILURE() << "Expected STATUS_OK for: " << #expression << "\n Actual: " << _status
|
||||
#else
|
||||
#error Macro EXPECT_OK already defined unexpectedly
|
||||
#endif
|
||||
|
||||
#if !defined(EXPECT_UNKNOWN_OR_UNSUPPORTED)
|
||||
#define EXPECT_UNKNOWN_OR_UNSUPPORTED(expression) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::ndk::ScopedAStatus&& _status = (expression); \
|
||||
_status.getExceptionCode() == EX_UNSUPPORTED_OPERATION || \
|
||||
_status.getStatus() == STATUS_UNKNOWN_TRANSACTION) \
|
||||
; \
|
||||
else \
|
||||
ADD_FAILURE() << "Expected STATUS_UNKNOWN_TRANSACTION or EX_UNSUPPORTED_OPERATION for: " \
|
||||
<< #expression << "\n Actual: " << _status
|
||||
#else
|
||||
#error Macro EXPECT_UNKNOWN_OR_UNSUPPORTED already defined unexpectedly
|
||||
#endif
|
||||
|
||||
#if !defined(EXPECT_ILLEGAL_ARGUMENT)
|
||||
#define EXPECT_ILLEGAL_ARGUMENT(expression) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::ndk::ScopedAStatus&& _status = (expression); \
|
||||
_status.getExceptionCode() == EX_ILLEGAL_ARGUMENT) \
|
||||
; \
|
||||
else \
|
||||
ADD_FAILURE() << "Expected EX_ILLEGAL_ARGUMENT for: " << #expression \
|
||||
<< "\n Actual: " << _status
|
||||
#else
|
||||
#error Macro EXPECT_ILLEGAL_ARGUMENT already defined unexpectedly
|
||||
#endif
|
||||
|
||||
#endif // VIBRATOR_HAL_TEST_UTILS_H
|
||||
@@ -30,12 +30,12 @@ cc_benchmark {
|
||||
"benchmark.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.vibrator-V2-cpp",
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
"android.hardware.vibrator@1.0",
|
||||
"android.hardware.vibrator@1.1",
|
||||
"android.hardware.vibrator@1.2",
|
||||
"android.hardware.vibrator@1.3",
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libhardware",
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <aidl/android/hardware/vibrator/IVibrator.h>
|
||||
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <android/hardware/vibrator/1.3/IVibrator.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::enum_range;
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_enum_range;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::details::hidl_enum_values;
|
||||
@@ -33,10 +32,11 @@ using ::benchmark::Fixture;
|
||||
using ::benchmark::kMicrosecond;
|
||||
using ::benchmark::State;
|
||||
using ::benchmark::internal::Benchmark;
|
||||
using ::ndk::enum_range;
|
||||
|
||||
using namespace ::std::chrono_literals;
|
||||
|
||||
namespace Aidl = ::android::hardware::vibrator;
|
||||
namespace Aidl = ::aidl::android::hardware::vibrator;
|
||||
namespace V1_0 = ::android::hardware::vibrator::V1_0;
|
||||
namespace V1_1 = ::android::hardware::vibrator::V1_1;
|
||||
namespace V1_2 = ::android::hardware::vibrator::V1_2;
|
||||
@@ -56,8 +56,8 @@ template <typename I>
|
||||
class BaseBench : public Fixture {
|
||||
public:
|
||||
void SetUp(State& /*state*/) override {
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
}
|
||||
|
||||
void TearDown(State& /*state*/) override {
|
||||
@@ -75,7 +75,7 @@ class BaseBench : public Fixture {
|
||||
auto getOtherArg(const State& state, std::size_t index) const { return state.range(index + 0); }
|
||||
|
||||
protected:
|
||||
sp<I> mVibrator;
|
||||
std::shared_ptr<I> mVibrator;
|
||||
};
|
||||
|
||||
template <typename I>
|
||||
@@ -83,7 +83,12 @@ class VibratorBench : public BaseBench<I> {
|
||||
public:
|
||||
void SetUp(State& state) override {
|
||||
BaseBench<I>::SetUp(state);
|
||||
this->mVibrator = I::getService();
|
||||
auto service = I::getService();
|
||||
if (service) {
|
||||
this->mVibrator = std::shared_ptr<I>(service.release());
|
||||
} else {
|
||||
this->mVibrator = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -356,7 +361,9 @@ class VibratorBench_Aidl : public BaseBench<Aidl::IVibrator> {
|
||||
public:
|
||||
void SetUp(State& state) override {
|
||||
BaseBench::SetUp(state);
|
||||
this->mVibrator = android::waitForVintfService<Aidl::IVibrator>();
|
||||
auto serviceName = std::string(Aidl::IVibrator::descriptor) + "/default";
|
||||
this->mVibrator = Aidl::IVibrator::fromBinder(
|
||||
ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
|
||||
}
|
||||
|
||||
void TearDown(State& state) override {
|
||||
@@ -373,9 +380,9 @@ class VibratorBench_Aidl : public BaseBench<Aidl::IVibrator> {
|
||||
return (deviceCapabilities & capabilities) == capabilities;
|
||||
}
|
||||
|
||||
bool shouldSkipWithError(State& state, const android::binder::Status&& status) {
|
||||
bool shouldSkipWithError(State& state, const ndk::ScopedAStatus&& status) {
|
||||
if (!status.isOk()) {
|
||||
state.SkipWithError(status.toString8().c_str());
|
||||
state.SkipWithError(status.getMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -407,9 +414,9 @@ class HalCallback : public Aidl::BnVibratorCallback {
|
||||
HalCallback() = default;
|
||||
~HalCallback() = default;
|
||||
|
||||
android::binder::Status onComplete() override {
|
||||
ndk::ScopedAStatus onComplete() override {
|
||||
mPromise.set_value();
|
||||
return android::binder::Status::ok();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::future<void> getFuture() { return mPromise.get_future(); }
|
||||
@@ -422,7 +429,9 @@ BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, on, {
|
||||
auto ms = MAX_ON_DURATION_MS;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
|
||||
? ndk::SharedRefBase::make<HalCallback>()
|
||||
: nullptr;
|
||||
// Grab the future before callback promise is destroyed by the HAL.
|
||||
auto cbFuture = cb ? cb->getFuture() : std::future<void>();
|
||||
|
||||
@@ -445,7 +454,9 @@ BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, off, {
|
||||
auto ms = MAX_ON_DURATION_MS;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
|
||||
? ndk::SharedRefBase::make<HalCallback>()
|
||||
: nullptr;
|
||||
// Grab the future before callback promise is destroyed by the HAL.
|
||||
auto cbFuture = cb ? cb->getFuture() : std::future<void>();
|
||||
|
||||
@@ -487,7 +498,9 @@ BENCHMARK_WRAPPER(VibratorBench_Aidl, setAmplitude, {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
|
||||
? ndk::SharedRefBase::make<HalCallback>()
|
||||
: nullptr;
|
||||
if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
|
||||
return;
|
||||
}
|
||||
@@ -689,8 +702,9 @@ BENCHMARK_WRAPPER(SlowVibratorEffectsBench_Aidl, perform, {
|
||||
int32_t lengthMs = 0;
|
||||
|
||||
for (auto _ : state) {
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback()
|
||||
: nullptr;
|
||||
auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK)
|
||||
? ndk::SharedRefBase::make<HalCallback>()
|
||||
: nullptr;
|
||||
// Grab the future before callback promise is destroyed by the HAL.
|
||||
auto cbFuture = cb ? cb->getFuture() : std::future<void>();
|
||||
|
||||
@@ -803,7 +817,7 @@ BENCHMARK_WRAPPER(SlowVibratorPrimitivesBench_Aidl, compose, {
|
||||
effects.push_back(effect);
|
||||
|
||||
for (auto _ : state) {
|
||||
auto cb = new HalCallback();
|
||||
auto cb = ndk::SharedRefBase::make<HalCallback>();
|
||||
// Grab the future before callback promise is moved and destroyed by the HAL.
|
||||
auto cbFuture = cb->getFuture();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user