vibrator hal: add loop mode control and update waveform

This patch updates the click waveform to use 6 ms full amplitude as well
as switching to open-loop mode for any duration that's less than 20 ms.
The medium and strong now shares the same strength to provide a stronger
default feedback.

Bug: 37952639
Test: keyboard and home key taps
Change-Id: I00086e47e41d97ce8363ba4032eeab320ad1b765
Signed-off-by: David Lin <dtwlin@google.com>
This commit is contained in:
David Lin
2017-05-03 11:28:37 -07:00
parent e95c2e5d4f
commit 646e1e592b
3 changed files with 27 additions and 10 deletions

View File

@@ -43,27 +43,39 @@ static constexpr char WAVEFORM_MODE[] = "waveform";
// Use effect #1 in the waveform library
static constexpr char WAVEFORM_CLICK_EFFECT_SEQ[] = "1 0";
static constexpr uint32_t WAVEFORM_CLICK_EFFECT_MS = 45;
static constexpr uint32_t WAVEFORM_CLICK_EFFECT_MS = 6;
// Make double click a single click and loop once
static constexpr char WAVEFORM_DOUBLE_CLICK_EFFECT_SEQ[] = "1 1";
static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_EFFECT_MS = WAVEFORM_CLICK_EFFECT_MS * 2;
// Timeout threshold for selecting open or closed loop mode
static constexpr int8_t LOOP_MODE_THRESHOLD_MS = 20;
Vibrator::Vibrator(std::ofstream&& activate, std::ofstream&& duration,
std::ofstream&& state, std::ofstream&& rtpinput,
std::ofstream&& mode, std::ofstream&& sequencer,
std::ofstream&& scale) :
std::ofstream&& scale, std::ofstream&& ctrlloop) :
mActivate(std::move(activate)),
mDuration(std::move(duration)),
mState(std::move(state)),
mRtpInput(std::move(rtpinput)),
mMode(std::move(mode)),
mSequencer(std::move(sequencer)),
mScale(std::move(scale)) {}
mScale(std::move(scale)),
mCtrlLoop(std::move(ctrlloop)) {}
// Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
Return<Status> Vibrator::on(uint32_t timeout_ms) {
uint32_t loop_mode = 1;
// Open-loop mode is used for short click for over-drive
// Close-loop mode is used for long notification for stability
if (timeout_ms > LOOP_MODE_THRESHOLD_MS) {
loop_mode = 0;
}
mCtrlLoop << loop_mode << std::endl;
mDuration << timeout_ms << std::endl;
if (!mDuration) {
ALOGE("Failed to set duration (%d): %s", errno, strerror(errno));
@@ -109,7 +121,7 @@ Return<Status> Vibrator::setAmplitude(uint8_t amplitude) {
std::round((amplitude - 1) / 254.0 * (MAX_RTP_INPUT - MIN_RTP_INPUT) +
MIN_RTP_INPUT);
mRtpInput << rtp_input;
mRtpInput << rtp_input << std::endl;
if (!mRtpInput) {
ALOGE("Failed to set amplitude (%d): %s", errno, strerror(errno));
return Status::UNKNOWN_ERROR;
@@ -123,12 +135,9 @@ static uint8_t convertEffectStrength(EffectStrength strength) {
switch (strength) {
case EffectStrength::LIGHT:
scale = 2; // 50%
scale = 1; // 50%
break;
case EffectStrength::MEDIUM:
scale = 1; // 75%
break;
default:
case EffectStrength::STRONG:
scale = 0; // 100%
break;

View File

@@ -32,7 +32,7 @@ public:
Vibrator(std::ofstream&& activate, std::ofstream&& duration,
std::ofstream&& state, std::ofstream&& rtpinput,
std::ofstream&& mode, std::ofstream&& sequencer,
std::ofstream&& scale);
std::ofstream&& scale, std::ofstream&& ctrlloop);
// Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
Return<Status> on(uint32_t timeoutMs) override;
@@ -49,6 +49,7 @@ private:
std::ofstream mMode;
std::ofstream mSequencer;
std::ofstream mScale;
std::ofstream mCtrlLoop;
};
} // namespace implementation
} // namespace V1_0

View File

@@ -38,6 +38,7 @@ static const char *RTP_INPUT_PATH = "/sys/class/leds/vibrator/device/rtp_input";
static const char *MODE_PATH = "/sys/class/leds/vibrator/device/mode";
static const char *SEQUENCER_PATH = "/sys/class/leds/vibrator/device/set_sequencer";
static const char *SCALE_PATH = "/sys/class/leds/vibrator/device/scale";
static const char *CTRL_LOOP_PATH = "/sys/class/leds/vibrator/device/ctrl_loop";
status_t registerVibratorService() {
// ostreams below are required
@@ -94,9 +95,15 @@ status_t registerVibratorService() {
ALOGW("Failed to open %s (%d): %s", SCALE_PATH, error, strerror(error));
}
std::ofstream ctrlloop{CTRL_LOOP_PATH};
if (!state) {
int error = errno;
ALOGW("Failed to open %s (%d): %s", CTRL_LOOP_PATH, error, strerror(error));
}
sp<IVibrator> vibrator = new Vibrator(std::move(activate), std::move(duration),
std::move(state), std::move(rtpinput), std::move(mode),
std::move(sequencer), std::move(scale));
std::move(sequencer), std::move(scale), std::move(ctrlloop));
vibrator->registerAsService();