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

Commit 6b10cbd0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add tracing tags to vibrator"

parents 6e24ac89 e59145a1
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,8 @@ public final class Trace {
    public static final long TRACE_TAG_NETWORK = 1L << 21;
    public static final long TRACE_TAG_NETWORK = 1L << 21;
    /** @hide */
    /** @hide */
    public static final long TRACE_TAG_ADB = 1L << 22;
    public static final long TRACE_TAG_ADB = 1L << 22;
    /** @hide */
    public static final long TRACE_TAG_VIBRATOR = 1L << 23;


    private static final long TRACE_TAG_NOT_READY = 1L << 63;
    private static final long TRACE_TAG_NOT_READY = 1L << 63;
    private static final int MAX_SECTION_NAME_LEN = 127;
    private static final int MAX_SECTION_NAME_LEN = 127;
+331 −264
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.Vibrator;
import android.os.Vibrator;
import android.os.VibrationEffect;
import android.os.VibrationEffect;
@@ -294,7 +295,6 @@ public class VibratorService extends IVibratorService.Stub
        VibrationEffect tickEffect = createEffect(tickEffectTimings);
        VibrationEffect tickEffect = createEffect(tickEffectTimings);


        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect };
        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect };

    }
    }


    private static VibrationEffect createEffect(long[] timings) {
    private static VibrationEffect createEffect(long[] timings) {
@@ -308,6 +308,8 @@ public class VibratorService extends IVibratorService.Stub
    }
    }


    public void systemReady() {
    public void systemReady() {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady");
        try {
            mIm = mContext.getSystemService(InputManager.class);
            mIm = mContext.getSystemService(InputManager.class);
            mVibrator = mContext.getSystemService(Vibrator.class);
            mVibrator = mContext.getSystemService(Vibrator.class);
            mSettingObserver = new SettingsObserver(mH);
            mSettingObserver = new SettingsObserver(mH);
@@ -346,6 +348,9 @@ public class VibratorService extends IVibratorService.Stub
            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mH);
            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mH);


            updateVibrators();
            updateVibrators();
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private final class SettingsObserver extends ContentObserver {
    private final class SettingsObserver extends ContentObserver {
@@ -422,6 +427,8 @@ public class VibratorService extends IVibratorService.Stub
    @Override // Binder call
    @Override // Binder call
    public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint,
    public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint,
            IBinder token) {
            IBinder token) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate");
        try {
            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                    != PackageManager.PERMISSION_GRANTED) {
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires VIBRATE permission");
                throw new SecurityException("Requires VIBRATE permission");
@@ -447,16 +454,17 @@ public class VibratorService extends IVibratorService.Stub
                    if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration())
                    if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration())
                            && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) {
                            && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) {
                        if (DEBUG) {
                        if (DEBUG) {
                        Slog.d(TAG, "Ignoring incoming vibration in favor of current vibration");
                            Slog.d(TAG,
                                    "Ignoring incoming vibration in favor of current vibration");
                        }
                        }
                        return;
                        return;
                    }
                    }
                }
                }


            // If the current vibration is repeating and the incoming one is non-repeating, then
                // If the current vibration is repeating and the incoming one is non-repeating,
            // ignore the non-repeating vibration. This is so that we don't cancel vibrations that
                // then ignore the non-repeating vibration. This is so that we don't cancel
            // are meant to grab the attention of the user, like ringtones and alarms, in favor of
                // vibrations that are meant to grab the attention of the user, like ringtones and
            // one-shot vibrations that are likely quite short.
                // alarms, in favor of one-shot vibrations that are likely quite short.
                if (!isRepeatingVibration(effect)
                if (!isRepeatingVibration(effect)
                        && mCurrentVibration != null
                        && mCurrentVibration != null
                        && isRepeatingVibration(mCurrentVibration.effect)) {
                        && isRepeatingVibration(mCurrentVibration.effect)) {
@@ -477,6 +485,9 @@ public class VibratorService extends IVibratorService.Stub
                    Binder.restoreCallingIdentity(ident);
                    Binder.restoreCallingIdentity(ident);
                }
                }
            }
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private static boolean isRepeatingVibration(VibrationEffect effect) {
    private static boolean isRepeatingVibration(VibrationEffect effect) {
@@ -520,6 +531,9 @@ public class VibratorService extends IVibratorService.Stub


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void doCancelVibrateLocked() {
    private void doCancelVibrateLocked() {
        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked");
        try {
            mH.removeCallbacks(mVibrationEndRunnable);
            mH.removeCallbacks(mVibrationEndRunnable);
            if (mThread != null) {
            if (mThread != null) {
                mThread.cancel();
                mThread.cancel();
@@ -527,6 +541,9 @@ public class VibratorService extends IVibratorService.Stub
            }
            }
            doVibratorOff();
            doVibratorOff();
            reportFinishVibrationLocked();
            reportFinishVibrationLocked();
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    // Callback for whenever the current vibration has finished played out
    // Callback for whenever the current vibration has finished played out
@@ -543,6 +560,8 @@ public class VibratorService extends IVibratorService.Stub


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void startVibrationLocked(final Vibration vib) {
    private void startVibrationLocked(final Vibration vib) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");
        try {
            if (!isAllowedToVibrateLocked(vib)) {
            if (!isAllowedToVibrateLocked(vib)) {
                return;
                return;
            }
            }
@@ -562,30 +581,38 @@ public class VibratorService extends IVibratorService.Stub
            final int mode = getAppOpMode(vib);
            final int mode = getAppOpMode(vib);
            if (mode != AppOpsManager.MODE_ALLOWED) {
            if (mode != AppOpsManager.MODE_ALLOWED) {
                if (mode == AppOpsManager.MODE_ERRORED) {
                if (mode == AppOpsManager.MODE_ERRORED) {
                // We might be getting calls from within system_server, so we don't actually want
                    // We might be getting calls from within system_server, so we don't actually
                // to throw a SecurityException here.
                    // want to throw a SecurityException here.
                    Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid);
                    Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid);
                }
                }
                return;
                return;
            }
            }
            applyVibrationIntensityScalingLocked(vib, intensity);
            applyVibrationIntensityScalingLocked(vib, intensity);
            startVibrationInnerLocked(vib);
            startVibrationInnerLocked(vib);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void startVibrationInnerLocked(Vibration vib) {
    private void startVibrationInnerLocked(Vibration vib) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationInnerLocked");
        try {
            mCurrentVibration = vib;
            mCurrentVibration = vib;
            if (vib.effect instanceof VibrationEffect.OneShot) {
            if (vib.effect instanceof VibrationEffect.OneShot) {
                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
                doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint);
                doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint);
                mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration());
                mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration());
            } else if (vib.effect instanceof VibrationEffect.Waveform) {
            } else if (vib.effect instanceof VibrationEffect.Waveform) {
                // mThread better be null here. doCancelVibrate should always be
                // mThread better be null here. doCancelVibrate should always be
                // called before startNextVibrationLocked or startVibrationLocked.
                // called before startNextVibrationLocked or startVibrationLocked.
                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
                mThread = new VibrateThread(waveform, vib.uid, vib.usageHint);
                mThread = new VibrateThread(waveform, vib.uid, vib.usageHint);
                mThread.start();
                mThread.start();
            } else if (vib.effect instanceof VibrationEffect.Prebaked) {
            } else if (vib.effect instanceof VibrationEffect.Prebaked) {
                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
                long timeout = doVibratorPrebakedEffectLocked(vib);
                long timeout = doVibratorPrebakedEffectLocked(vib);
                if (timeout > 0) {
                if (timeout > 0) {
                    mH.postDelayed(mVibrationEndRunnable, timeout);
                    mH.postDelayed(mVibrationEndRunnable, timeout);
@@ -593,6 +620,9 @@ public class VibratorService extends IVibratorService.Stub
            } else {
            } else {
                Slog.e(TAG, "Unknown vibration type, ignoring");
                Slog.e(TAG, "Unknown vibration type, ignoring");
            }
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private boolean isAllowedToVibrateLocked(Vibration vib) {
    private boolean isAllowedToVibrateLocked(Vibration vib) {
@@ -708,6 +738,8 @@ public class VibratorService extends IVibratorService.Stub


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void reportFinishVibrationLocked() {
    private void reportFinishVibrationLocked() {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
        try {
            if (mCurrentVibration != null) {
            if (mCurrentVibration != null) {
                try {
                try {
                    mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
                    mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
@@ -717,6 +749,9 @@ public class VibratorService extends IVibratorService.Stub
                unlinkVibration(mCurrentVibration);
                unlinkVibration(mCurrentVibration);
                mCurrentVibration = null;
                mCurrentVibration = null;
            }
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private void linkVibration(Vibration vib) {
    private void linkVibration(Vibration vib) {
@@ -838,6 +873,8 @@ public class VibratorService extends IVibratorService.Stub
    }
    }


    private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) {
    private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
        try {
            synchronized (mInputDeviceVibrators) {
            synchronized (mInputDeviceVibrators) {
                if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) {
                if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) {
                    amplitude = mDefaultVibrationAmplitude;
                    amplitude = mDefaultVibrationAmplitude;
@@ -855,12 +892,16 @@ public class VibratorService extends IVibratorService.Stub
                        mInputDeviceVibrators.get(i).vibrate(millis, attributes);
                        mInputDeviceVibrators.get(i).vibrate(millis, attributes);
                    }
                    }
                } else {
                } else {
                // Note: ordering is important here! Many haptic drivers will reset their amplitude
                    // Note: ordering is important here! Many haptic drivers will reset their
                // when enabled, so we always have to enable frst, then set the amplitude.
                    // amplitude when enabled, so we always have to enable frst, then set the
                    // amplitude.
                    vibratorOn(millis);
                    vibratorOn(millis);
                    doVibratorSetAmplitude(amplitude);
                    doVibratorSetAmplitude(amplitude);
                }
                }
            }
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private void doVibratorSetAmplitude(int amplitude) {
    private void doVibratorSetAmplitude(int amplitude) {
@@ -870,6 +911,8 @@ public class VibratorService extends IVibratorService.Stub
    }
    }


    private void doVibratorOff() {
    private void doVibratorOff() {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff");
        try {
            synchronized (mInputDeviceVibrators) {
            synchronized (mInputDeviceVibrators) {
                if (DEBUG) {
                if (DEBUG) {
                    Slog.d(TAG, "Turning vibrator off.");
                    Slog.d(TAG, "Turning vibrator off.");
@@ -884,10 +927,15 @@ public class VibratorService extends IVibratorService.Stub
                    vibratorOff();
                    vibratorOff();
                }
                }
            }
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private long doVibratorPrebakedEffectLocked(Vibration vib) {
    private long doVibratorPrebakedEffectLocked(Vibration vib) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked");
        try {
            final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect;
            final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect;
            final boolean usingInputDeviceVibrators;
            final boolean usingInputDeviceVibrators;
            synchronized (mInputDeviceVibrators) {
            synchronized (mInputDeviceVibrators) {
@@ -895,7 +943,8 @@ public class VibratorService extends IVibratorService.Stub
            }
            }
            // Input devices don't support prebaked effect, so skip trying it with them.
            // Input devices don't support prebaked effect, so skip trying it with them.
            if (!usingInputDeviceVibrators) {
            if (!usingInputDeviceVibrators) {
            long timeout = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength());
                long timeout = vibratorPerformEffect(prebaked.getId(),
                        prebaked.getEffectStrength());
                if (timeout > 0) {
                if (timeout > 0) {
                    noteVibratorOnLocked(vib.uid, timeout);
                    noteVibratorOnLocked(vib.uid, timeout);
                    return timeout;
                    return timeout;
@@ -916,6 +965,9 @@ public class VibratorService extends IVibratorService.Stub
            applyVibrationIntensityScalingLocked(fallbackVib, intensity);
            applyVibrationIntensityScalingLocked(fallbackVib, intensity);
            startVibrationInnerLocked(fallbackVib);
            startVibrationInnerLocked(fallbackVib);
            return 0;
            return 0;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
    }
    }


    private VibrationEffect getFallbackEffect(int effectId) {
    private VibrationEffect getFallbackEffect(int effectId) {
@@ -977,6 +1029,8 @@ public class VibratorService extends IVibratorService.Stub
        }
        }


        private long delayLocked(long duration) {
        private long delayLocked(long duration) {
            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked");
            try {
                long durationRemaining = duration;
                long durationRemaining = duration;
                if (duration > 0) {
                if (duration > 0) {
                    final long bedtime = duration + SystemClock.uptimeMillis();
                    final long bedtime = duration + SystemClock.uptimeMillis();
@@ -993,6 +1047,9 @@ public class VibratorService extends IVibratorService.Stub
                    return duration - durationRemaining;
                    return duration - durationRemaining;
                }
                }
                return 0;
                return 0;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
            }
        }
        }


        public void run() {
        public void run() {
@@ -1014,6 +1071,8 @@ public class VibratorService extends IVibratorService.Stub
         * @return true if it finished naturally, false otherwise (e.g. it was canceled).
         * @return true if it finished naturally, false otherwise (e.g. it was canceled).
         */
         */
        public boolean playWaveform() {
        public boolean playWaveform() {
            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playWaveform");
            try {
                synchronized (this) {
                synchronized (this) {
                    final long[] timings = mWaveform.getTimings();
                    final long[] timings = mWaveform.getTimings();
                    final int[] amplitudes = mWaveform.getAmplitudes();
                    final int[] amplitudes = mWaveform.getAmplitudes();
@@ -1033,12 +1092,12 @@ public class VibratorService extends IVibratorService.Stub
                                if (onDuration <= 0) {
                                if (onDuration <= 0) {
                                    // 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 is
                                    // command.  Instead we figure out how long our next "on" period
                                // going to be, tell the motor to stay on for the full duration,
                                    // is going to be, tell the motor to stay on for the full
                                // and then wake up to change the amplitude at the appropriate
                                    // duration, and then wake up to change the amplitude at the
                                // intervals.
                                    // appropriate intervals.
                                onDuration =
                                    onDuration = getTotalOnDuration(timings, amplitudes, index - 1,
                                        getTotalOnDuration(timings, amplitudes, index - 1, repeat);
                                            repeat);
                                    doVibratorOn(onDuration, amplitude, mUid, mUsageHint);
                                    doVibratorOn(onDuration, amplitude, mUid, mUsageHint);
                                } else {
                                } else {
                                    doVibratorSetAmplitude(amplitude);
                                    doVibratorSetAmplitude(amplitude);
@@ -1057,6 +1116,9 @@ public class VibratorService extends IVibratorService.Stub
                    }
                    }
                    return !mForceStop;
                    return !mForceStop;
                }
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
            }
        }
        }


        public void cancel() {
        public void cancel() {
@@ -1161,6 +1223,8 @@ public class VibratorService extends IVibratorService.Stub
        }
        }


        private int runVibrate() {
        private int runVibrate() {
            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrate");
            try {
                try {
                try {
                    final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
                    final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
                            Settings.Global.ZEN_MODE);
                            Settings.Global.ZEN_MODE);
@@ -1190,6 +1254,9 @@ public class VibratorService extends IVibratorService.Stub
                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
                        mToken);
                        mToken);
                return 0;
                return 0;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
            }
        }
        }


        @Override
        @Override