vibrator: Add Composition APIs
Bug: 139762802 Test: Manual Invocation via 'idlcli' Change-Id: Ibc938d08f186039681d523784b90f4172a52af51 Signed-off-by: Harpreet \"Eli\" Sangha <eliptus@google.com>
This commit is contained in:
parent
43286a882b
commit
7eab6201a9
6 changed files with 275 additions and 13 deletions
28
vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
Normal file
28
vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.CompositePrimitive;
|
||||||
|
|
||||||
|
@VintfStability
|
||||||
|
parcelable CompositeEffect {
|
||||||
|
/* Period of silence preceding primitive. */
|
||||||
|
int delayMs;
|
||||||
|
CompositePrimitive primitive;
|
||||||
|
/* 0.0 (exclusive) - 1.0 (inclusive) */
|
||||||
|
float scale;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 CompositePrimitive {
|
||||||
|
NOOP,
|
||||||
|
CLICK,
|
||||||
|
THUD,
|
||||||
|
SPIN,
|
||||||
|
QUICK_RISE,
|
||||||
|
SLOW_RISE,
|
||||||
|
QUICK_FALL,
|
||||||
|
}
|
|
@ -19,6 +19,8 @@ package android.hardware.vibrator;
|
||||||
import android.hardware.vibrator.IVibratorCallback;
|
import android.hardware.vibrator.IVibratorCallback;
|
||||||
import android.hardware.vibrator.Effect;
|
import android.hardware.vibrator.Effect;
|
||||||
import android.hardware.vibrator.EffectStrength;
|
import android.hardware.vibrator.EffectStrength;
|
||||||
|
import android.hardware.vibrator.CompositeEffect;
|
||||||
|
import android.hardware.vibrator.CompositePrimitive;
|
||||||
|
|
||||||
@VintfStability
|
@VintfStability
|
||||||
interface IVibrator {
|
interface IVibrator {
|
||||||
|
@ -42,6 +44,10 @@ interface IVibrator {
|
||||||
* Whether setAmplitude is supported (when external control is enabled)
|
* Whether setAmplitude is supported (when external control is enabled)
|
||||||
*/
|
*/
|
||||||
const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 1 << 4;
|
const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 1 << 4;
|
||||||
|
/**
|
||||||
|
* Whether compose is supported.
|
||||||
|
*/
|
||||||
|
const int CAP_COMPOSE_EFFECTS = 1 << 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine capabilities of the vibrator HAL (CAP_* mask)
|
* Determine capabilities of the vibrator HAL (CAP_* mask)
|
||||||
|
@ -107,11 +113,10 @@ interface IVibrator {
|
||||||
* CAP_EXTERNAL_AMPLITUDE_CONTROL.
|
* CAP_EXTERNAL_AMPLITUDE_CONTROL.
|
||||||
*
|
*
|
||||||
* @param amplitude The unitless force setting. Note that this number must
|
* @param amplitude The unitless force setting. Note that this number must
|
||||||
* be between 1 and 255, inclusive. If the motor does not
|
* be between 0.0 (exclusive) and 1.0 (inclusive). It must
|
||||||
* have exactly 255 steps, it must do it's best to map it
|
* do it's best to map it onto the number of steps it does have.
|
||||||
* onto the number of steps it does have.
|
|
||||||
*/
|
*/
|
||||||
void setAmplitude(in int amplitude);
|
void setAmplitude(in float amplitude);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables/disables control override of vibrator to audio.
|
* Enables/disables control override of vibrator to audio.
|
||||||
|
@ -128,4 +133,36 @@ interface IVibrator {
|
||||||
* @param enabled Whether external control should be enabled or disabled.
|
* @param enabled Whether external control should be enabled or disabled.
|
||||||
*/
|
*/
|
||||||
void setExternalControl(in boolean enabled);
|
void setExternalControl(in boolean enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve composition delay limit.
|
||||||
|
*
|
||||||
|
* Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
|
||||||
|
*
|
||||||
|
* @return Maximum delay for a single CompositeEffect[] entry.
|
||||||
|
*/
|
||||||
|
int getCompositionDelayMax();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve composition size limit.
|
||||||
|
*
|
||||||
|
* Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
|
||||||
|
*
|
||||||
|
* @return Maximum number of entries in CompositeEffect[].
|
||||||
|
* @param maxDelayMs Maximum delay for a single CompositeEffect[] entry.
|
||||||
|
*/
|
||||||
|
int getCompositionSizeMax();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire off a string of effect primitives, combined to perform richer effects.
|
||||||
|
*
|
||||||
|
* Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
|
||||||
|
*
|
||||||
|
* Doing this operation while the vibrator is already on is undefined behavior. Clients should
|
||||||
|
* explicitly call off.
|
||||||
|
*
|
||||||
|
* @param composite Array of composition parameters.
|
||||||
|
*/
|
||||||
|
void compose(in CompositeEffect[] composite, in IVibratorCallback callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,14 @@ namespace android {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
namespace vibrator {
|
namespace vibrator {
|
||||||
|
|
||||||
|
static constexpr int32_t kComposeDelayMaxMs = 1000;
|
||||||
|
static constexpr int32_t kComposeSizeMax = 256;
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
|
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
|
||||||
LOG(INFO) << "Vibrator reporting capabilities";
|
LOG(INFO) << "Vibrator reporting capabilities";
|
||||||
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
||||||
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
|
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
|
||||||
IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
|
IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS;
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +87,9 @@ ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_retu
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
|
ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
||||||
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
|
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
|
||||||
if (amplitude <= 0 || amplitude > 255) {
|
if (amplitude <= 0.0f || amplitude > 1.0f) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
|
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
|
||||||
}
|
}
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
|
@ -97,6 +100,55 @@ ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* maxDelayMs) {
|
||||||
|
*maxDelayMs = kComposeDelayMaxMs;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
|
||||||
|
*maxSize = kComposeSizeMax;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
|
||||||
|
const std::shared_ptr<IVibratorCallback>& callback) {
|
||||||
|
if (composite.size() > kComposeSizeMax) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& e : composite) {
|
||||||
|
if (e.delayMs > kComposeDelayMaxMs) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||||
|
}
|
||||||
|
if (e.scale <= 0.0f || e.scale > 1.0f) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||||
|
}
|
||||||
|
if (e.primitive < CompositePrimitive::NOOP ||
|
||||||
|
e.primitive > CompositePrimitive::QUICK_FALL) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread([=] {
|
||||||
|
LOG(INFO) << "Starting compose on another thread";
|
||||||
|
|
||||||
|
for (auto& e : composite) {
|
||||||
|
if (e.delayMs) {
|
||||||
|
usleep(e.delayMs * 1000);
|
||||||
|
}
|
||||||
|
LOG(INFO) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
|
||||||
|
<< e.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback != nullptr) {
|
||||||
|
LOG(INFO) << "Notifying perform complete";
|
||||||
|
callback->onComplete();
|
||||||
|
}
|
||||||
|
}).detach();
|
||||||
|
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace vibrator
|
} // namespace vibrator
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
@ -32,8 +32,12 @@ class Vibrator : public BnVibrator {
|
||||||
const std::shared_ptr<IVibratorCallback>& callback,
|
const std::shared_ptr<IVibratorCallback>& callback,
|
||||||
int32_t* _aidl_return) override;
|
int32_t* _aidl_return) override;
|
||||||
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
|
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
|
||||||
ndk::ScopedAStatus setAmplitude(int32_t amplitude) override;
|
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
||||||
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||||
|
ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
|
||||||
|
ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize);
|
||||||
|
ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
|
||||||
|
const std::shared_ptr<IVibratorCallback>& callback) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vibrator
|
} // namespace vibrator
|
||||||
|
|
|
@ -28,6 +28,8 @@ using android::sp;
|
||||||
using android::String16;
|
using android::String16;
|
||||||
using android::binder::Status;
|
using android::binder::Status;
|
||||||
using android::hardware::vibrator::BnVibratorCallback;
|
using android::hardware::vibrator::BnVibratorCallback;
|
||||||
|
using android::hardware::vibrator::CompositeEffect;
|
||||||
|
using android::hardware::vibrator::CompositePrimitive;
|
||||||
using android::hardware::vibrator::Effect;
|
using android::hardware::vibrator::Effect;
|
||||||
using android::hardware::vibrator::EffectStrength;
|
using android::hardware::vibrator::EffectStrength;
|
||||||
using android::hardware::vibrator::IVibrator;
|
using android::hardware::vibrator::IVibrator;
|
||||||
|
@ -55,6 +57,20 @@ const std::vector<EffectStrength> kInvalidEffectStrengths = {
|
||||||
static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
|
static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO(b/143992652): autogenerate
|
||||||
|
const std::vector<CompositePrimitive> kCompositePrimitives = {
|
||||||
|
CompositePrimitive::NOOP, CompositePrimitive::CLICK,
|
||||||
|
CompositePrimitive::THUD, CompositePrimitive::SPIN,
|
||||||
|
CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
|
||||||
|
CompositePrimitive::QUICK_FALL,
|
||||||
|
};
|
||||||
|
// TODO(b/143992652): autogenerate
|
||||||
|
|
||||||
|
const std::vector<CompositePrimitive> kInvalidPrimitives = {
|
||||||
|
static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
|
||||||
|
static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
|
||||||
|
};
|
||||||
|
|
||||||
class CompletionCallback : public BnVibratorCallback {
|
class CompletionCallback : public BnVibratorCallback {
|
||||||
public:
|
public:
|
||||||
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
|
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
|
||||||
|
@ -201,11 +217,11 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
|
||||||
|
|
||||||
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
|
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
|
||||||
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
||||||
EXPECT_TRUE(vibrator->setAmplitude(1).isOk());
|
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
|
||||||
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
|
||||||
EXPECT_TRUE(vibrator->setAmplitude(128).isOk());
|
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
|
||||||
sleep(1);
|
sleep(1);
|
||||||
EXPECT_TRUE(vibrator->setAmplitude(255).isOk());
|
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +230,7 @@ TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
|
||||||
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
|
||||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
|
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(0).exceptionCode());
|
||||||
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(256).exceptionCode());
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +256,7 @@ TEST_P(VibratorAidl, ExternalAmplitudeControl) {
|
||||||
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
|
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
|
||||||
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
|
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
|
||||||
|
|
||||||
Status amplitudeStatus = vibrator->setAmplitude(128);
|
Status amplitudeStatus = vibrator->setAmplitude(0.5);
|
||||||
if (supportsExternalAmplitudeControl) {
|
if (supportsExternalAmplitudeControl) {
|
||||||
EXPECT_TRUE(amplitudeStatus.isOk());
|
EXPECT_TRUE(amplitudeStatus.isOk());
|
||||||
} else {
|
} else {
|
||||||
|
@ -259,6 +275,102 @@ TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ComposeValidPrimitives) {
|
||||||
|
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||||
|
int32_t maxDelay, maxSize;
|
||||||
|
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
|
||||||
|
|
||||||
|
std::vector<CompositeEffect> composite;
|
||||||
|
|
||||||
|
for (auto primitive : kCompositePrimitives) {
|
||||||
|
CompositeEffect effect;
|
||||||
|
|
||||||
|
effect.delayMs = std::rand() % (maxDelay + 1);
|
||||||
|
effect.primitive = primitive;
|
||||||
|
effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
|
||||||
|
composite.emplace_back(effect);
|
||||||
|
|
||||||
|
if (composite.size() == maxSize) {
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
composite.clear();
|
||||||
|
vibrator->off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (composite.size() != 0) {
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
vibrator->off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
|
||||||
|
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||||
|
for (auto primitive : kInvalidPrimitives) {
|
||||||
|
std::vector<CompositeEffect> composite(1);
|
||||||
|
|
||||||
|
for (auto& effect : composite) {
|
||||||
|
effect.delayMs = 0;
|
||||||
|
effect.primitive = primitive;
|
||||||
|
effect.scale = 1.0f;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
|
||||||
|
vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
vibrator->off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, CompseDelayBoundary) {
|
||||||
|
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||||
|
int32_t maxDelay;
|
||||||
|
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
|
||||||
|
|
||||||
|
std::vector<CompositeEffect> composite(1);
|
||||||
|
CompositeEffect effect;
|
||||||
|
|
||||||
|
effect.delayMs = 1;
|
||||||
|
effect.primitive = CompositePrimitive::CLICK;
|
||||||
|
effect.scale = 1.0f;
|
||||||
|
|
||||||
|
std::fill(composite.begin(), composite.end(), effect);
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
|
||||||
|
effect.delayMs = maxDelay + 1;
|
||||||
|
|
||||||
|
std::fill(composite.begin(), composite.end(), effect);
|
||||||
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||||
|
vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
vibrator->off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VibratorAidl, CompseSizeBoundary) {
|
||||||
|
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
|
||||||
|
int32_t maxSize;
|
||||||
|
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
|
||||||
|
|
||||||
|
std::vector<CompositeEffect> composite(maxSize);
|
||||||
|
CompositeEffect effect;
|
||||||
|
|
||||||
|
effect.delayMs = 1;
|
||||||
|
effect.primitive = CompositePrimitive::CLICK;
|
||||||
|
effect.scale = 1.0f;
|
||||||
|
|
||||||
|
std::fill(composite.begin(), composite.end(), effect);
|
||||||
|
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
|
||||||
|
composite.emplace_back(effect);
|
||||||
|
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
|
||||||
|
vibrator->compose(composite, nullptr).exceptionCode());
|
||||||
|
vibrator->off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
|
INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
|
||||||
testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
|
testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
|
||||||
android::PrintInstanceNameToString);
|
android::PrintInstanceNameToString);
|
||||||
|
|
Loading…
Reference in a new issue