Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36d873fd authored by Michael Wright's avatar Michael Wright
Browse files

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
parent 0ff8dabf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2784,7 +2784,7 @@
    <bool name="config_eap_sim_based_auth_supported">true</bool>

    <!-- How long history of previous vibrations should be kept for the dumpsys. -->
    <integer name="config_previousVibrationsDumpLimit">20</integer>
    <integer name="config_previousVibrationsDumpLimit">50</integer>

    <!-- The default vibration strength, must be between 1 and 255 inclusive. -->
    <integer name="config_defaultVibrationAmplitude">255</integer>
+46 −25
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.res.Resources;
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.FileDescriptor;
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 @@ public class VibratorService extends IVibratorService.Stub
    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 @@ public class VibratorService extends IVibratorService.Stub
    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 @@ public class VibratorService extends IVibratorService.Stub
                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 @@ public class VibratorService extends IVibratorService.Stub
            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 @@ public class VibratorService extends IVibratorService.Stub
        @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 @@ public class VibratorService extends IVibratorService.Stub
                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 @@ public class VibratorService extends IVibratorService.Stub
        }

        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 @@ public class VibratorService extends IVibratorService.Stub
        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 @@ public class VibratorService extends IVibratorService.Stub
                        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 @@ public class VibratorService extends IVibratorService.Stub
        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 @@ public class VibratorService extends IVibratorService.Stub
            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 @@ public class VibratorService extends IVibratorService.Stub
        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);