Skip to content
Snippets Groups Projects
Commit 6569dc0d authored by Lais Andrade's avatar Lais Andrade
Browse files

Fix VibratorService waveform accumulated delay

Change VibrateWaveformThread logic around delays while playing a
waveform to amortize processing/scheduling delays into the sleep part of
the thread. This should make the actual waveform duration closer to the
requested one.

Bug: 171133221
Test: manually check waveform vibration durations with dumpsys
Change-Id: I0ac88baf4127e9aebe56041a3a334ef8a2f8d43d
Merged-In: Iafe7f031444f68cd2cdc16883812874f385cba8e
parent 3a14c6bd
No related branches found
No related tags found
No related merge requests found
......@@ -1589,25 +1589,20 @@ public class VibratorService extends IVibratorService.Stub
mWakeLock.setWorkSource(mTmpWorkSource);
}
private long delayLocked(long duration) {
private void delayLocked(long wakeUpTime) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked");
try {
long durationRemaining = duration;
if (duration > 0) {
final long bedtime = duration + SystemClock.uptimeMillis();
do {
try {
this.wait(durationRemaining);
}
catch (InterruptedException e) { }
if (mForceStop) {
break;
}
durationRemaining = bedtime - SystemClock.uptimeMillis();
} while (durationRemaining > 0);
return duration - durationRemaining;
long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
while (durationRemaining > 0) {
try {
this.wait(durationRemaining);
}
catch (InterruptedException e) { }
if (mForceStop) {
break;
}
durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
}
return 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
......@@ -1641,7 +1636,8 @@ public class VibratorService extends IVibratorService.Stub
final int repeat = mWaveform.getRepeatIndex();
int index = 0;
long onDuration = 0;
long nextStepStartTime = SystemClock.uptimeMillis();
long nextVibratorStopTime = 0;
while (!mForceStop) {
if (index < len) {
final int amplitude = amplitudes[index];
......@@ -1650,25 +1646,31 @@ public class VibratorService extends IVibratorService.Stub
continue;
}
if (amplitude != 0) {
if (onDuration <= 0) {
long now = SystemClock.uptimeMillis();
if (nextVibratorStopTime <= now) {
// Telling the vibrator to start multiple times usually causes
// effects to feel "choppy" because the motor resets at every on
// command. Instead we figure out how long our next "on" period
// is going to be, tell the motor to stay on for the full
// duration, and then wake up to change the amplitude at the
// appropriate intervals.
onDuration = getTotalOnDuration(timings, amplitudes, index - 1,
repeat);
long onDuration = getTotalOnDuration(
timings, amplitudes, index - 1, repeat);
doVibratorOn(onDuration, amplitude, mUid, mAttrs);
nextVibratorStopTime = now + onDuration;
} else {
// Vibrator is already ON, so just change its amplitude.
doVibratorSetAmplitude(amplitude);
}
}
long waitTime = delayLocked(duration);
if (amplitude != 0) {
onDuration -= waitTime;
}
// We wait until the time this waveform step was supposed to end,
// calculated from the time it was supposed to start. All start times
// are calculated from the waveform original start time by adding the
// input durations. Any scheduling or processing delay should not affect
// this step's perceived total duration. They will be amortized here.
nextStepStartTime += duration;
delayLocked(nextStepStartTime);
} else if (repeat < 0) {
break;
} else {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment