Merge "Fix VibratorService waveform accumulated delay"

This commit is contained in:
Treehugger Robot
2020-11-02 16:21:57 +00:00
committed by Gerrit Code Review

View File

@@ -1589,13 +1589,11 @@ public class VibratorService extends IVibratorService.Stub
mWakeLock.setWorkSource(mTmpWorkSource); mWakeLock.setWorkSource(mTmpWorkSource);
} }
private long delayLocked(long duration) { private void delayLocked(long wakeUpTime) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked"); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked");
try { try {
long durationRemaining = duration; long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
if (duration > 0) { while (durationRemaining > 0) {
final long bedtime = duration + SystemClock.uptimeMillis();
do {
try { try {
this.wait(durationRemaining); this.wait(durationRemaining);
} }
@@ -1603,11 +1601,8 @@ public class VibratorService extends IVibratorService.Stub
if (mForceStop) { if (mForceStop) {
break; break;
} }
durationRemaining = bedtime - SystemClock.uptimeMillis(); durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
} while (durationRemaining > 0);
return duration - durationRemaining;
} }
return 0;
} finally { } finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
} }
@@ -1641,7 +1636,8 @@ public class VibratorService extends IVibratorService.Stub
final int repeat = mWaveform.getRepeatIndex(); final int repeat = mWaveform.getRepeatIndex();
int index = 0; int index = 0;
long onDuration = 0; long nextStepStartTime = SystemClock.uptimeMillis();
long nextVibratorStopTime = 0;
while (!mForceStop) { while (!mForceStop) {
if (index < len) { if (index < len) {
final int amplitude = amplitudes[index]; final int amplitude = amplitudes[index];
@@ -1650,25 +1646,31 @@ public class VibratorService extends IVibratorService.Stub
continue; continue;
} }
if (amplitude != 0) { if (amplitude != 0) {
if (onDuration <= 0) { long now = SystemClock.uptimeMillis();
if (nextVibratorStopTime <= now) {
// Telling the vibrator to start multiple times usually causes // Telling the vibrator to start multiple times usually causes
// effects to feel "choppy" because the motor resets at every on // effects to feel "choppy" because the motor resets at every on
// command. Instead we figure out how long our next "on" period // command. Instead we figure out how long our next "on" period
// is going to be, tell the motor to stay on for the full // is going to be, tell the motor to stay on for the full
// duration, and then wake up to change the amplitude at the // duration, and then wake up to change the amplitude at the
// appropriate intervals. // appropriate intervals.
onDuration = getTotalOnDuration(timings, amplitudes, index - 1, long onDuration = getTotalOnDuration(
repeat); timings, amplitudes, index - 1, repeat);
doVibratorOn(onDuration, amplitude, mUid, mAttrs); doVibratorOn(onDuration, amplitude, mUid, mAttrs);
nextVibratorStopTime = now + onDuration;
} else { } else {
// Vibrator is already ON, so just change its amplitude.
doVibratorSetAmplitude(amplitude); doVibratorSetAmplitude(amplitude);
} }
} }
long waitTime = delayLocked(duration); // We wait until the time this waveform step was supposed to end,
if (amplitude != 0) { // calculated from the time it was supposed to start. All start times
onDuration -= waitTime; // 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) { } else if (repeat < 0) {
break; break;
} else { } else {