Loading core/java/android/os/Trace.java +2 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ public final class Trace { public static final long TRACE_TAG_NETWORK = 1L << 21; /** @hide */ 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 int MAX_SECTION_NAME_LEN = 127; Loading services/core/java/com/android/server/VibratorService.java +331 −264 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.Vibrator; import android.os.VibrationEffect; Loading Loading @@ -294,7 +295,6 @@ public class VibratorService extends IVibratorService.Stub VibrationEffect tickEffect = createEffect(tickEffectTimings); mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect }; } private static VibrationEffect createEffect(long[] timings) { Loading @@ -308,6 +308,8 @@ public class VibratorService extends IVibratorService.Stub } public void systemReady() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady"); try { mIm = mContext.getSystemService(InputManager.class); mVibrator = mContext.getSystemService(Vibrator.class); mSettingObserver = new SettingsObserver(mH); Loading Loading @@ -346,6 +348,9 @@ public class VibratorService extends IVibratorService.Stub }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mH); updateVibrators(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private final class SettingsObserver extends ContentObserver { Loading Loading @@ -422,6 +427,8 @@ public class VibratorService extends IVibratorService.Stub @Override // Binder call public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint, IBinder token) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate"); try { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires VIBRATE permission"); Loading @@ -447,16 +454,17 @@ public class VibratorService extends IVibratorService.Stub if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration()) && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) { 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; } } // If the current vibration is repeating and the incoming one is non-repeating, then // ignore the non-repeating vibration. This is so that we don't cancel vibrations that // are meant to grab the attention of the user, like ringtones and alarms, in favor of // one-shot vibrations that are likely quite short. // If the current vibration is repeating and the incoming one is non-repeating, // then ignore the non-repeating vibration. This is so that we don't cancel // vibrations that are meant to grab the attention of the user, like ringtones and // alarms, in favor of one-shot vibrations that are likely quite short. if (!isRepeatingVibration(effect) && mCurrentVibration != null && isRepeatingVibration(mCurrentVibration.effect)) { Loading @@ -477,6 +485,9 @@ public class VibratorService extends IVibratorService.Stub Binder.restoreCallingIdentity(ident); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private static boolean isRepeatingVibration(VibrationEffect effect) { Loading Loading @@ -520,6 +531,9 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void doCancelVibrateLocked() { Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked"); try { mH.removeCallbacks(mVibrationEndRunnable); if (mThread != null) { mThread.cancel(); Loading @@ -527,6 +541,9 @@ public class VibratorService extends IVibratorService.Stub } doVibratorOff(); reportFinishVibrationLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } // Callback for whenever the current vibration has finished played out Loading @@ -543,6 +560,8 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void startVibrationLocked(final Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked"); try { if (!isAllowedToVibrateLocked(vib)) { return; } Loading @@ -562,30 +581,38 @@ public class VibratorService extends IVibratorService.Stub final int mode = getAppOpMode(vib); if (mode != AppOpsManager.MODE_ALLOWED) { if (mode == AppOpsManager.MODE_ERRORED) { // We might be getting calls from within system_server, so we don't actually want // to throw a SecurityException here. // We might be getting calls from within system_server, so we don't actually // want to throw a SecurityException here. Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); } return; } applyVibrationIntensityScalingLocked(vib, intensity); startVibrationInnerLocked(vib); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") private void startVibrationInnerLocked(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationInnerLocked"); try { mCurrentVibration = vib; if (vib.effect instanceof VibrationEffect.OneShot) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect; doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint); mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration()); } else if (vib.effect instanceof VibrationEffect.Waveform) { // mThread better be null here. doCancelVibrate should always be // called before startNextVibrationLocked or startVibrationLocked. Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect; mThread = new VibrateThread(waveform, vib.uid, vib.usageHint); mThread.start(); } else if (vib.effect instanceof VibrationEffect.Prebaked) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); long timeout = doVibratorPrebakedEffectLocked(vib); if (timeout > 0) { mH.postDelayed(mVibrationEndRunnable, timeout); Loading @@ -593,6 +620,9 @@ public class VibratorService extends IVibratorService.Stub } else { Slog.e(TAG, "Unknown vibration type, ignoring"); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private boolean isAllowedToVibrateLocked(Vibration vib) { Loading Loading @@ -708,6 +738,8 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void reportFinishVibrationLocked() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); try { if (mCurrentVibration != null) { try { mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService), Loading @@ -717,6 +749,9 @@ public class VibratorService extends IVibratorService.Stub unlinkVibration(mCurrentVibration); mCurrentVibration = null; } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void linkVibration(Vibration vib) { Loading Loading @@ -838,6 +873,8 @@ public class VibratorService extends IVibratorService.Stub } private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn"); try { synchronized (mInputDeviceVibrators) { if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) { amplitude = mDefaultVibrationAmplitude; Loading @@ -855,12 +892,16 @@ public class VibratorService extends IVibratorService.Stub mInputDeviceVibrators.get(i).vibrate(millis, attributes); } } else { // Note: ordering is important here! Many haptic drivers will reset their amplitude // when enabled, so we always have to enable frst, then set the amplitude. // Note: ordering is important here! Many haptic drivers will reset their // amplitude when enabled, so we always have to enable frst, then set the // amplitude. vibratorOn(millis); doVibratorSetAmplitude(amplitude); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void doVibratorSetAmplitude(int amplitude) { Loading @@ -870,6 +911,8 @@ public class VibratorService extends IVibratorService.Stub } private void doVibratorOff() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff"); try { synchronized (mInputDeviceVibrators) { if (DEBUG) { Slog.d(TAG, "Turning vibrator off."); Loading @@ -884,10 +927,15 @@ public class VibratorService extends IVibratorService.Stub vibratorOff(); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") private long doVibratorPrebakedEffectLocked(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked"); try { final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect; final boolean usingInputDeviceVibrators; synchronized (mInputDeviceVibrators) { Loading @@ -895,7 +943,8 @@ public class VibratorService extends IVibratorService.Stub } // Input devices don't support prebaked effect, so skip trying it with them. if (!usingInputDeviceVibrators) { long timeout = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength()); long timeout = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength()); if (timeout > 0) { noteVibratorOnLocked(vib.uid, timeout); return timeout; Loading @@ -916,6 +965,9 @@ public class VibratorService extends IVibratorService.Stub applyVibrationIntensityScalingLocked(fallbackVib, intensity); startVibrationInnerLocked(fallbackVib); return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private VibrationEffect getFallbackEffect(int effectId) { Loading Loading @@ -977,6 +1029,8 @@ public class VibratorService extends IVibratorService.Stub } private long delayLocked(long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked"); try { long durationRemaining = duration; if (duration > 0) { final long bedtime = duration + SystemClock.uptimeMillis(); Loading @@ -993,6 +1047,9 @@ public class VibratorService extends IVibratorService.Stub return duration - durationRemaining; } return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } public void run() { Loading @@ -1014,6 +1071,8 @@ public class VibratorService extends IVibratorService.Stub * @return true if it finished naturally, false otherwise (e.g. it was canceled). */ public boolean playWaveform() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playWaveform"); try { synchronized (this) { final long[] timings = mWaveform.getTimings(); final int[] amplitudes = mWaveform.getAmplitudes(); Loading @@ -1033,12 +1092,12 @@ public class VibratorService extends IVibratorService.Stub if (onDuration <= 0) { // 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); // 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); doVibratorOn(onDuration, amplitude, mUid, mUsageHint); } else { doVibratorSetAmplitude(amplitude); Loading @@ -1057,6 +1116,9 @@ public class VibratorService extends IVibratorService.Stub } return !mForceStop; } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } public void cancel() { Loading Loading @@ -1161,6 +1223,8 @@ public class VibratorService extends IVibratorService.Stub } private int runVibrate() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrate"); try { try { final int zenMode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE); Loading Loading @@ -1190,6 +1254,9 @@ public class VibratorService extends IVibratorService.Stub vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN, mToken); return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading Loading
core/java/android/os/Trace.java +2 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ public final class Trace { public static final long TRACE_TAG_NETWORK = 1L << 21; /** @hide */ 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 int MAX_SECTION_NAME_LEN = 127; Loading
services/core/java/com/android/server/VibratorService.java +331 −264 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.Vibrator; import android.os.VibrationEffect; Loading Loading @@ -294,7 +295,6 @@ public class VibratorService extends IVibratorService.Stub VibrationEffect tickEffect = createEffect(tickEffectTimings); mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect }; } private static VibrationEffect createEffect(long[] timings) { Loading @@ -308,6 +308,8 @@ public class VibratorService extends IVibratorService.Stub } public void systemReady() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady"); try { mIm = mContext.getSystemService(InputManager.class); mVibrator = mContext.getSystemService(Vibrator.class); mSettingObserver = new SettingsObserver(mH); Loading Loading @@ -346,6 +348,9 @@ public class VibratorService extends IVibratorService.Stub }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mH); updateVibrators(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private final class SettingsObserver extends ContentObserver { Loading Loading @@ -422,6 +427,8 @@ public class VibratorService extends IVibratorService.Stub @Override // Binder call public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint, IBinder token) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate"); try { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires VIBRATE permission"); Loading @@ -447,16 +454,17 @@ public class VibratorService extends IVibratorService.Stub if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration()) && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) { 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; } } // If the current vibration is repeating and the incoming one is non-repeating, then // ignore the non-repeating vibration. This is so that we don't cancel vibrations that // are meant to grab the attention of the user, like ringtones and alarms, in favor of // one-shot vibrations that are likely quite short. // If the current vibration is repeating and the incoming one is non-repeating, // then ignore the non-repeating vibration. This is so that we don't cancel // vibrations that are meant to grab the attention of the user, like ringtones and // alarms, in favor of one-shot vibrations that are likely quite short. if (!isRepeatingVibration(effect) && mCurrentVibration != null && isRepeatingVibration(mCurrentVibration.effect)) { Loading @@ -477,6 +485,9 @@ public class VibratorService extends IVibratorService.Stub Binder.restoreCallingIdentity(ident); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private static boolean isRepeatingVibration(VibrationEffect effect) { Loading Loading @@ -520,6 +531,9 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void doCancelVibrateLocked() { Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked"); try { mH.removeCallbacks(mVibrationEndRunnable); if (mThread != null) { mThread.cancel(); Loading @@ -527,6 +541,9 @@ public class VibratorService extends IVibratorService.Stub } doVibratorOff(); reportFinishVibrationLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } // Callback for whenever the current vibration has finished played out Loading @@ -543,6 +560,8 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void startVibrationLocked(final Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked"); try { if (!isAllowedToVibrateLocked(vib)) { return; } Loading @@ -562,30 +581,38 @@ public class VibratorService extends IVibratorService.Stub final int mode = getAppOpMode(vib); if (mode != AppOpsManager.MODE_ALLOWED) { if (mode == AppOpsManager.MODE_ERRORED) { // We might be getting calls from within system_server, so we don't actually want // to throw a SecurityException here. // We might be getting calls from within system_server, so we don't actually // want to throw a SecurityException here. Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); } return; } applyVibrationIntensityScalingLocked(vib, intensity); startVibrationInnerLocked(vib); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") private void startVibrationInnerLocked(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationInnerLocked"); try { mCurrentVibration = vib; if (vib.effect instanceof VibrationEffect.OneShot) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect; doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint); mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration()); } else if (vib.effect instanceof VibrationEffect.Waveform) { // mThread better be null here. doCancelVibrate should always be // called before startNextVibrationLocked or startVibrationLocked. Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect; mThread = new VibrateThread(waveform, vib.uid, vib.usageHint); mThread.start(); } else if (vib.effect instanceof VibrationEffect.Prebaked) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); long timeout = doVibratorPrebakedEffectLocked(vib); if (timeout > 0) { mH.postDelayed(mVibrationEndRunnable, timeout); Loading @@ -593,6 +620,9 @@ public class VibratorService extends IVibratorService.Stub } else { Slog.e(TAG, "Unknown vibration type, ignoring"); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private boolean isAllowedToVibrateLocked(Vibration vib) { Loading Loading @@ -708,6 +738,8 @@ public class VibratorService extends IVibratorService.Stub @GuardedBy("mLock") private void reportFinishVibrationLocked() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); try { if (mCurrentVibration != null) { try { mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService), Loading @@ -717,6 +749,9 @@ public class VibratorService extends IVibratorService.Stub unlinkVibration(mCurrentVibration); mCurrentVibration = null; } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void linkVibration(Vibration vib) { Loading Loading @@ -838,6 +873,8 @@ public class VibratorService extends IVibratorService.Stub } private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn"); try { synchronized (mInputDeviceVibrators) { if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) { amplitude = mDefaultVibrationAmplitude; Loading @@ -855,12 +892,16 @@ public class VibratorService extends IVibratorService.Stub mInputDeviceVibrators.get(i).vibrate(millis, attributes); } } else { // Note: ordering is important here! Many haptic drivers will reset their amplitude // when enabled, so we always have to enable frst, then set the amplitude. // Note: ordering is important here! Many haptic drivers will reset their // amplitude when enabled, so we always have to enable frst, then set the // amplitude. vibratorOn(millis); doVibratorSetAmplitude(amplitude); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void doVibratorSetAmplitude(int amplitude) { Loading @@ -870,6 +911,8 @@ public class VibratorService extends IVibratorService.Stub } private void doVibratorOff() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff"); try { synchronized (mInputDeviceVibrators) { if (DEBUG) { Slog.d(TAG, "Turning vibrator off."); Loading @@ -884,10 +927,15 @@ public class VibratorService extends IVibratorService.Stub vibratorOff(); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") private long doVibratorPrebakedEffectLocked(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked"); try { final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect; final boolean usingInputDeviceVibrators; synchronized (mInputDeviceVibrators) { Loading @@ -895,7 +943,8 @@ public class VibratorService extends IVibratorService.Stub } // Input devices don't support prebaked effect, so skip trying it with them. if (!usingInputDeviceVibrators) { long timeout = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength()); long timeout = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength()); if (timeout > 0) { noteVibratorOnLocked(vib.uid, timeout); return timeout; Loading @@ -916,6 +965,9 @@ public class VibratorService extends IVibratorService.Stub applyVibrationIntensityScalingLocked(fallbackVib, intensity); startVibrationInnerLocked(fallbackVib); return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private VibrationEffect getFallbackEffect(int effectId) { Loading Loading @@ -977,6 +1029,8 @@ public class VibratorService extends IVibratorService.Stub } private long delayLocked(long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked"); try { long durationRemaining = duration; if (duration > 0) { final long bedtime = duration + SystemClock.uptimeMillis(); Loading @@ -993,6 +1047,9 @@ public class VibratorService extends IVibratorService.Stub return duration - durationRemaining; } return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } public void run() { Loading @@ -1014,6 +1071,8 @@ public class VibratorService extends IVibratorService.Stub * @return true if it finished naturally, false otherwise (e.g. it was canceled). */ public boolean playWaveform() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playWaveform"); try { synchronized (this) { final long[] timings = mWaveform.getTimings(); final int[] amplitudes = mWaveform.getAmplitudes(); Loading @@ -1033,12 +1092,12 @@ public class VibratorService extends IVibratorService.Stub if (onDuration <= 0) { // 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); // 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); doVibratorOn(onDuration, amplitude, mUid, mUsageHint); } else { doVibratorSetAmplitude(amplitude); Loading @@ -1057,6 +1116,9 @@ public class VibratorService extends IVibratorService.Stub } return !mForceStop; } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } public void cancel() { Loading Loading @@ -1161,6 +1223,8 @@ public class VibratorService extends IVibratorService.Stub } private int runVibrate() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrate"); try { try { final int zenMode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE); Loading Loading @@ -1190,6 +1254,9 @@ public class VibratorService extends IVibratorService.Stub vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN, mToken); return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading