Log vibrations in realtime, not the monotonic clock base.
Also, keep more vibration logs around for debugging by default and do a
bit of clean up in VibratorService.
Bug: 70283106
Test: flash, run dumpsys vibrator
Change-Id: Ib541be0ed97cdc6e2fda278fa59896d2fde20228
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 0e51fda..c1cda98 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -26,6 +26,7 @@
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.hardware.vibrator.V1_0.Constants.EffectStrength;
+import android.icu.text.DateFormat;
import android.media.AudioManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerSaveState;
@@ -62,6 +63,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.Date;
public class VibratorService extends IVibratorService.Stub
implements InputManager.InputDeviceListener {
@@ -69,6 +71,8 @@
private static final boolean DEBUG = false;
private static final String SYSTEM_UI_PACKAGE = "com.android.systemui";
+ private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = { 0, 30, 100, 30 };
+
private final LinkedList<VibrationInfo> mPreviousVibrations;
private final int mPreviousVibrationsLimit;
private final boolean mAllowPriorityVibrationsInLowPowerMode;
@@ -110,7 +114,12 @@
private class Vibration implements IBinder.DeathRecipient {
private final IBinder mToken;
private final VibrationEffect mEffect;
+ // Start time in CLOCK_BOOTTIME base.
private final long mStartTime;
+ // Start time in unix epoch time. Only to be used for debugging purposes and to correlate
+ // with other system events, any duration calculations should be done use mStartTime so as
+ // not to be affected by discontinuities created by RTC adjustments.
+ private final long mStartTimeDebug;
private final int mUsageHint;
private final int mUid;
private final String mOpPkg;
@@ -119,7 +128,8 @@
int usageHint, int uid, String opPkg) {
mToken = token;
mEffect = effect;
- mStartTime = SystemClock.uptimeMillis();
+ mStartTime = SystemClock.elapsedRealtime();
+ mStartTimeDebug = System.currentTimeMillis();
mUsageHint = usageHint;
mUid = uid;
mOpPkg = opPkg;
@@ -153,18 +163,22 @@
return (mUid == Process.SYSTEM_UID || mUid == 0 || SYSTEM_UI_PACKAGE.equals(mOpPkg))
&& !repeating;
}
+
+ public VibrationInfo toInfo() {
+ return new VibrationInfo(mStartTimeDebug, mEffect, mUsageHint, mUid, mOpPkg);
+ }
}
private static class VibrationInfo {
- private final long mStartTime;
+ private final long mStartTimeDebug;
private final VibrationEffect mEffect;
private final int mUsageHint;
private final int mUid;
private final String mOpPkg;
- public VibrationInfo(long startTime, VibrationEffect effect,
+ public VibrationInfo(long startTimeDebug, VibrationEffect effect,
int usageHint, int uid, String opPkg) {
- mStartTime = startTime;
+ mStartTimeDebug = startTimeDebug;
mEffect = effect;
mUsageHint = usageHint;
mUid = uid;
@@ -174,8 +188,8 @@
@Override
public String toString() {
return new StringBuilder()
- .append(", startTime: ")
- .append(mStartTime)
+ .append("startTime: ")
+ .append(DateFormat.getDateTimeInstance().format(new Date(mStartTimeDebug)))
.append(", effect: ")
.append(mEffect)
.append(", usageHint: ")
@@ -225,7 +239,7 @@
com.android.internal.R.array.config_virtualKeyVibePattern);
VibrationEffect clickEffect = createEffect(clickEffectTimings);
VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
- new long[] {0, 30, 100, 30} /*timings*/, -1);
+ DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS, -1 /*repeatIndex*/);
long[] tickEffectTimings = getLongIntArray(context.getResources(),
com.android.internal.R.array.config_clockTickVibePattern);
VibrationEffect tickEffect = createEffect(tickEffectTimings);
@@ -392,17 +406,7 @@
}
Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg);
-
- // Only link against waveforms since they potentially don't have a finish if
- // they're repeating. Let other effects just play out until they're done.
- if (effect instanceof VibrationEffect.Waveform) {
- try {
- token.linkToDeath(vib, 0);
- } catch (RemoteException e) {
- return;
- }
- }
-
+ linkVibration(vib);
long ident = Binder.clearCallingIdentity();
try {
@@ -430,8 +434,7 @@
if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
mPreviousVibrations.removeFirst();
}
- mPreviousVibrations.addLast(new VibrationInfo(
- vib.mStartTime, vib.mEffect, vib.mUsageHint, vib.mUid, vib.mOpPkg));
+ mPreviousVibrations.addLast(vib.toInfo());
}
@Override // Binder call
@@ -589,10 +592,23 @@
AppOpsManager.OP_VIBRATE, mCurrentVibration.mUid,
mCurrentVibration.mOpPkg);
} catch (RemoteException e) { }
+ unlinkVibration(mCurrentVibration);
mCurrentVibration = null;
}
}
+ private void linkVibration(Vibration vib) {
+ // Only link against waveforms since they potentially don't have a finish if
+ // they're repeating. Let other effects just play out until they're done.
+ if (vib.mEffect instanceof VibrationEffect.Waveform) {
+ try {
+ vib.mToken.linkToDeath(vib, 0);
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+ }
+
private void unlinkVibration(Vibration vib) {
if (vib.mEffect instanceof VibrationEffect.Waveform) {
vib.mToken.unlinkToDeath(vib, 0);
@@ -742,8 +758,7 @@
synchronized (mInputDeviceVibrators) {
VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.mEffect;
// Input devices don't support prebaked effect, so skip trying it with them.
- final int vibratorCount = mInputDeviceVibrators.size();
- if (vibratorCount == 0) {
+ if (mInputDeviceVibrators.isEmpty()) {
long timeout = vibratorPerformEffect(prebaked.getId(), EffectStrength.MEDIUM);
if (timeout > 0) {
noteVibratorOnLocked(vib.mUid, timeout);
@@ -753,12 +768,11 @@
if (!prebaked.shouldFallback()) {
return 0;
}
- final int id = prebaked.getId();
- if (id < 0 || id >= mFallbackEffects.length || mFallbackEffects[id] == null) {
+ VibrationEffect effect = getFallbackEffect(prebaked.getId());
+ if (effect == null) {
Slog.w(TAG, "Failed to play prebaked effect, no fallback");
return 0;
}
- VibrationEffect effect = mFallbackEffects[id];
Vibration fallbackVib =
new Vibration(vib.mToken, effect, vib.mUsageHint, vib.mUid, vib.mOpPkg);
startVibrationInnerLocked(fallbackVib);
@@ -766,6 +780,13 @@
return 0;
}
+ private VibrationEffect getFallbackEffect(int effectId) {
+ if (effectId < 0 || effectId >= mFallbackEffects.length) {
+ return null;
+ }
+ return mFallbackEffects[effectId];
+ }
+
private void noteVibratorOnLocked(int uid, long millis) {
try {
mBatteryStatsService.noteVibratorOn(uid, millis);