Loading core/java/android/os/SystemVibratorManager.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -138,11 +138,14 @@ public class SystemVibratorManager extends VibratorManager { Log.w(TAG, "Failed to vibrate; no vibrator manager service."); Log.w(TAG, "Failed to vibrate; no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason=" + reason); try { try { mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mToken); mToken); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to vibrate.", e); Log.w(TAG, "Failed to vibrate.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -152,11 +155,14 @@ public class SystemVibratorManager extends VibratorManager { Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback, reason=" + reason); try { try { mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, reason, flags, privFlags); reason, flags, privFlags); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to perform haptic feedback.", e); Log.w(TAG, "Failed to perform haptic feedback.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -168,11 +174,15 @@ public class SystemVibratorManager extends VibratorManager { + " no vibrator manager service."); + " no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice, reason=" + reason); try { try { mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, constant, inputDeviceId, inputSource, reason, flags, privFlags); constant, inputDeviceId, inputSource, reason, flags, privFlags); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to perform haptic feedback for input device.", e); Log.w(TAG, "Failed to perform haptic feedback for input device.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading services/core/java/com/android/server/vibrator/VibrationThread.java +12 −7 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,8 @@ final class VibrationThread extends Thread { * before the release callback. * before the release callback. */ */ boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrationOnVibrationThread"); try { synchronized (mLock) { synchronized (mLock) { if (mRequestedActiveConductor != null) { if (mRequestedActiveConductor != null) { Slog.wtf(TAG, "Attempt to start vibration when one already running"); Slog.wtf(TAG, "Attempt to start vibration when one already running"); Loading @@ -137,6 +139,9 @@ final class VibrationThread extends Thread { mLock.notifyAll(); mLock.notifyAll(); } } return true; return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override Loading services/core/java/com/android/server/vibrator/VibratorController.java +123 −70 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.IVibratorStateListener; import android.os.Parcel; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibrationEffect; import android.os.VibratorInfo; import android.os.VibratorInfo; import android.os.vibrator.PrebakedSegment; import android.os.vibrator.PrebakedSegment; Loading Loading @@ -123,6 +124,8 @@ final class VibratorController { /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ public void reloadVibratorInfoIfNeeded() { public void reloadVibratorInfoIfNeeded() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#reloadVibratorInfoIfNeeded"); try { // Early check outside lock, for quick return. // Early check outside lock, for quick return. if (mVibratorInfoLoadSuccessful) { if (mVibratorInfoLoadSuccessful) { return; return; Loading @@ -139,6 +142,9 @@ final class VibratorController { Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ Loading Loading @@ -193,9 +199,14 @@ final class VibratorController { /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { public boolean isAvailable() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#isAvailable"); try { synchronized (mLock) { synchronized (mLock) { return mNativeWrapper.isAvailable(); return mNativeWrapper.isAvailable(); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -204,6 +215,8 @@ final class VibratorController { * <p>This will affect the state of {@link #isUnderExternalControl()}. * <p>This will affect the state of {@link #isUnderExternalControl()}. */ */ public void setExternalControl(boolean externalControl) { public void setExternalControl(boolean externalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "setExternalControl(" + externalControl + ")"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; return; } } Loading @@ -211,6 +224,9 @@ final class VibratorController { mIsUnderExternalControl = externalControl; mIsUnderExternalControl = externalControl; mNativeWrapper.setExternalControl(externalControl); mNativeWrapper.setExternalControl(externalControl); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -218,6 +234,8 @@ final class VibratorController { * if given {@code effect} is {@code null}. * if given {@code effect} is {@code null}. */ */ public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#updateAlwaysOn"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { return; return; } } Loading @@ -229,10 +247,15 @@ final class VibratorController { prebaked.getEffectStrength()); prebaked.getEffectStrength()); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ public void setAmplitude(float amplitude) { public void setAmplitude(float amplitude) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#setAmplitude"); try { synchronized (mLock) { synchronized (mLock) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.setAmplitude(amplitude); mNativeWrapper.setAmplitude(amplitude); Loading @@ -241,6 +264,9 @@ final class VibratorController { mCurrentAmplitude = amplitude; mCurrentAmplitude = amplitude; } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -253,6 +279,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(long milliseconds, long vibrationId) { public long on(long milliseconds, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on"); try { synchronized (mLock) { synchronized (mLock) { long duration = mNativeWrapper.on(milliseconds, vibrationId); long duration = mNativeWrapper.on(milliseconds, vibrationId); if (duration > 0) { if (duration > 0) { Loading @@ -261,6 +289,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -273,6 +304,7 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (vendor)"); synchronized (mLock) { synchronized (mLock) { Parcel vendorData = Parcel.obtain(); Parcel vendorData = Parcel.obtain(); try { try { Loading @@ -288,6 +320,7 @@ final class VibratorController { return duration; return duration; } finally { } finally { vendorData.recycle(); vendorData.recycle(); Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } } } Loading @@ -302,6 +335,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(PrebakedSegment prebaked, long vibrationId) { public long on(PrebakedSegment prebaked, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Prebaked)"); try { synchronized (mLock) { synchronized (mLock) { long duration = mNativeWrapper.perform(prebaked.getEffectId(), long duration = mNativeWrapper.perform(prebaked.getEffectId(), prebaked.getEffectStrength(), vibrationId); prebaked.getEffectStrength(), vibrationId); Loading @@ -311,6 +346,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -323,6 +361,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(PrimitiveSegment[] primitives, long vibrationId) { public long on(PrimitiveSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Primitive)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; return 0; } } Loading @@ -334,6 +374,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -345,6 +388,8 @@ final class VibratorController { * @return The duration of the effect playing, or 0 if unsupported. * @return The duration of the effect playing, or 0 if unsupported. */ */ public long on(RampSegment[] primitives, long vibrationId) { public long on(RampSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (PWLE)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { return 0; return 0; } } Loading @@ -357,6 +402,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -365,11 +413,16 @@ final class VibratorController { * <p>This will affect the state of {@link #isVibrating()}. * <p>This will affect the state of {@link #isVibrating()}. */ */ public void off() { public void off() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#off"); try { synchronized (mLock) { synchronized (mLock) { mNativeWrapper.off(); mNativeWrapper.off(); mCurrentAmplitude = 0; mCurrentAmplitude = 0; notifyListenerOnVibrating(false); notifyListenerOnVibrating(false); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +275 −235 Original line number Original line Diff line number Diff line Loading @@ -462,20 +462,31 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call @Override // Binder call public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, String reason, int flags, int privFlags) { String reason, int flags, int privFlags) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback"); // Note that the `performHapticFeedback` method does not take a token argument from the // Note that the `performHapticFeedback` method does not take a token argument from the // caller, and instead, uses this service as the token. This is to mitigate performance // caller, and instead, uses this service as the token. This is to mitigate performance // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are // short-lived, so we don't need to cancel when the process dies. // short-lived, so we don't need to cancel when the process dies. try { performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ this, flags, privFlags); this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override // Binder call @Override // Binder call public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, int constant, int inputDeviceId, int inputSource, String reason, int flags, int constant, int inputDeviceId, int inputSource, String reason, int flags, int privFlags) { int privFlags) { performHapticFeedbackForInputDeviceInternal(uid, deviceId, opPkg, constant, inputDeviceId, Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice"); try { performHapticFeedbackForInputDeviceInternal(uid, deviceId, opPkg, constant, inputDeviceId, inputSource, reason, /* token= */ this, flags, privFlags); inputSource, reason, /* token= */ this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading Loading @@ -919,8 +930,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") @Nullable @Nullable private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked"); try { HalVibration vib = conductor.getVibration(); HalVibration vib = conductor.getVibration(); int mode = startAppOpModeLocked(vib.callerInfo); int mode = startAppOpModeLocked(vib.callerInfo); switch (mode) { switch (mode) { Loading @@ -941,9 +950,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { default: default: return new Vibration.EndInfo(Status.IGNORED_APP_OPS); return new Vibration.EndInfo(Status.IGNORED_APP_OPS); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -1050,9 +1056,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); try { HalVibration vib = mCurrentVibration.getVibration(); HalVibration vib = mCurrentVibration.getVibration(); if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " Loading @@ -1062,9 +1066,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // vibration was released, after all cleanup. The metrics will be reported then. // vibration was released, after all cleanup. The metrics will be reported then. endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); finishAppOpModeLocked(vib.callerInfo); finishAppOpModeLocked(vib.callerInfo); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private void onSyncedVibrationComplete(long vibrationId) { private void onSyncedVibrationComplete(long vibrationId) { Loading Loading @@ -1418,10 +1419,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") @Nullable @Nullable private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked( private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(CombinedVibration effect) { CombinedVibration effect) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked"); try { SparseArray<VibrationEffect> effects; SparseArray<VibrationEffect> effects; if (effect instanceof CombinedVibration.Mono) { if (effect instanceof CombinedVibration.Mono) { VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); Loading Loading @@ -1449,9 +1447,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return null; return null; } } return result; return result; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Nullable @Nullable Loading Loading @@ -1580,25 +1575,42 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override @Override public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "prepareSyncedVibration"); try { if ((mCapabilities & requiredCapabilities) != requiredCapabilities) { if ((mCapabilities & requiredCapabilities) != requiredCapabilities) { // This sync step requires capabilities this device doesn't have, skipping sync... // This sync step requires capabilities this device doesn't have, skipping // sync... return false; return false; } } return mNativeWrapper.prepareSynced(vibratorIds); return mNativeWrapper.prepareSynced(vibratorIds); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public boolean triggerSyncedVibration(long vibrationId) { public boolean triggerSyncedVibration(long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "triggerSyncedVibration"); try { return mNativeWrapper.triggerSynced(vibrationId); return mNativeWrapper.triggerSynced(vibrationId); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void cancelSyncedVibration() { public void cancelSyncedVibration() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "cancelSyncedVibration"); try { mNativeWrapper.cancelSynced(); mNativeWrapper.cancelSynced(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void noteVibratorOn(int uid, long duration) { public void noteVibratorOn(int uid, long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOn"); try { try { if (duration <= 0) { if (duration <= 0) { // Tried to turn vibrator ON and got: // Tried to turn vibrator ON and got: Loading @@ -1616,16 +1628,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } @Override @Override public void noteVibratorOff(int uid) { public void noteVibratorOff(int uid) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOff"); try { try { mBatteryStatsService.noteVibratorOff(uid); mBatteryStatsService.noteVibratorOff(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to OFF", e); Slog.e(TAG, "Error logging VibratorStateChanged to OFF", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -1634,12 +1651,17 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationCompleted"); try { synchronized (mLock) { synchronized (mLock) { if (mCurrentVibration != null if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) { && mCurrentVibration.getVibration().id == vibrationId) { reportFinishedVibrationLocked(vibrationEndInfo); reportFinishedVibrationLocked(vibrationEndInfo); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override Loading @@ -1647,6 +1669,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "VibrationThread released after finished vibration"); Slog.d(TAG, "VibrationThread released after finished vibration"); } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationThreadReleased: " + vibrationId); try { synchronized (mLock) { synchronized (mLock) { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Processing VibrationThread released callback"); Slog.d(TAG, "Processing VibrationThread released callback"); Loading @@ -1658,7 +1682,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentVibration.getVibration().id, vibrationId)); mCurrentVibration.getVibration().id, vibrationId)); } } if (mCurrentVibration != null) { if (mCurrentVibration != null) { // This is when we consider the current vibration complete, so report metrics. // This is when we consider the current vibration complete, so report // metrics. mFrameworkStatsLogger.writeVibrationReportedAsync( mFrameworkStatsLogger.writeVibrationReportedAsync( mCurrentVibration.getVibration().getStatsInfo( mCurrentVibration.getVibration().getStatsInfo( /* completionUptimeMillis= */ SystemClock.uptimeMillis())); /* completionUptimeMillis= */ SystemClock.uptimeMillis())); Loading @@ -1676,6 +1701,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } } Loading Loading @@ -1917,8 +1945,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, boolean continueExternalControl) { boolean continueExternalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked"); try { if (mCurrentExternalVibration == null) { if (mCurrentExternalVibration == null) { return; return; } } Loading @@ -1930,9 +1956,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, /* shouldWriteStats= */ true); /* shouldWriteStats= */ true); mCurrentExternalVibration = null; mCurrentExternalVibration = null; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private HapticFeedbackVibrationProvider getHapticVibrationProvider() { private HapticFeedbackVibrationProvider getHapticVibrationProvider() { Loading Loading @@ -1987,7 +2010,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override @Override public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { // Create Vibration.Stats as close to the received request as possible, for tracking. Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStart"); try { // Create Vibration.Stats as close to the received request as possible, for // tracking. ExternalVibrationSession externalVibration = new ExternalVibrationSession(vib); ExternalVibrationSession externalVibration = new ExternalVibrationSession(vib); // Mute the request until we run all the checks and accept the vibration. // Mute the request until we run all the checks and accept the vibration. externalVibration.muteScale(); externalVibration.muteScale(); Loading @@ -2002,7 +2028,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return externalVibration.getScale(); return externalVibration.getScale(); } } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission( android.Manifest.permission.VIBRATE, vib.getUid(), -1 /*owningUid*/, true /*exported*/) vib.getUid(), -1 /*owningUid*/, true /*exported*/) != PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) { Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() Loading Loading @@ -2038,7 +2065,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (mCurrentExternalVibration == null) { if (mCurrentExternalVibration == null) { // If we're not under external control right now, then cancel any normal // If we're not under external control right now, then cancel any normal // vibration that may be playing and ready the vibrator for external control. // vibration that may be playing and ready the vibrator for external // control. if (mCurrentVibration != null) { if (mCurrentVibration != null) { externalVibration.stats.reportInterruptedAnotherVibration( externalVibration.stats.reportInterruptedAnotherVibration( mCurrentVibration.getVibration().callerInfo); mCurrentVibration.getVibration().callerInfo); Loading @@ -2053,13 +2081,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } } else { } else { // At this point we have an externally controlled vibration playing already. // At this point we have an externally controlled vibration playing already. // Since the interface defines that only one externally controlled vibration can // Since the interface defines that only one externally controlled // play at a time, we need to first mute the ongoing vibration and then return // vibration can // play at a time, we need to first mute the ongoing vibration and then // return // a scale from this function for the new one, so we can be assured that the // a scale from this function for the new one, so we can be assured that the // ongoing will be muted in favor of the new vibration. // ongoing will be muted in favor of the new vibration. // // // Note that this doesn't support multiple concurrent external controls, as we // Note that this doesn't support multiple concurrent external controls, // would need to mute the old one still if it came from a different controller. // as we would need to mute the old one still if it came from a different // controller. alreadyUnderExternalControl = true; alreadyUnderExternalControl = true; mCurrentExternalVibration.notifyEnded(); mCurrentExternalVibration.notifyEnded(); externalVibration.stats.reportInterruptedAnotherVibration( externalVibration.stats.reportInterruptedAnotherVibration( Loading @@ -2070,11 +2101,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ true); /* continueExternalControl= */ true); } } VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), VibrationAttributes attrs = fixupVibrationAttributes( vib.getVibrationAttributes(), /* effect= */ null); /* effect= */ null); if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { // Force update of user settings before checking if this vibration effect should // Force update of user settings before checking if this vibration effect // be ignored or scaled. // should be ignored or scaled. mVibrationSettings.update(); mVibrationSettings.update(); } } Loading Loading @@ -2110,10 +2142,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Report current time as the vibration start time, for debugging. // Report current time as the vibration start time, for debugging. externalVibration.stats.reportStarted(); externalVibration.stats.reportStarted(); return externalVibration.getScale(); return externalVibration.getScale(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void onExternalVibrationStop(ExternalVibration vib) { public void onExternalVibrationStop(ExternalVibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStop"); try { synchronized (mLock) { synchronized (mLock) { if (mCurrentExternalVibration != null if (mCurrentExternalVibration != null && mCurrentExternalVibration.isHoldingSameVibration(vib)) { && mCurrentExternalVibration.isHoldingSameVibration(vib)) { Loading @@ -2125,6 +2162,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ false); /* continueExternalControl= */ false); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private boolean hasExternalControlCapability() { private boolean hasExternalControlCapability() { Loading Loading
core/java/android/os/SystemVibratorManager.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -138,11 +138,14 @@ public class SystemVibratorManager extends VibratorManager { Log.w(TAG, "Failed to vibrate; no vibrator manager service."); Log.w(TAG, "Failed to vibrate; no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason=" + reason); try { try { mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mToken); mToken); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to vibrate.", e); Log.w(TAG, "Failed to vibrate.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -152,11 +155,14 @@ public class SystemVibratorManager extends VibratorManager { Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback, reason=" + reason); try { try { mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, reason, flags, privFlags); reason, flags, privFlags); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to perform haptic feedback.", e); Log.w(TAG, "Failed to perform haptic feedback.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -168,11 +174,15 @@ public class SystemVibratorManager extends VibratorManager { + " no vibrator manager service."); + " no vibrator manager service."); return; return; } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice, reason=" + reason); try { try { mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, constant, inputDeviceId, inputSource, reason, flags, privFlags); constant, inputDeviceId, inputSource, reason, flags, privFlags); } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "Failed to perform haptic feedback for input device.", e); Log.w(TAG, "Failed to perform haptic feedback for input device.", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading
services/core/java/com/android/server/vibrator/VibrationThread.java +12 −7 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,8 @@ final class VibrationThread extends Thread { * before the release callback. * before the release callback. */ */ boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrationOnVibrationThread"); try { synchronized (mLock) { synchronized (mLock) { if (mRequestedActiveConductor != null) { if (mRequestedActiveConductor != null) { Slog.wtf(TAG, "Attempt to start vibration when one already running"); Slog.wtf(TAG, "Attempt to start vibration when one already running"); Loading @@ -137,6 +139,9 @@ final class VibrationThread extends Thread { mLock.notifyAll(); mLock.notifyAll(); } } return true; return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override Loading
services/core/java/com/android/server/vibrator/VibratorController.java +123 −70 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.IVibratorStateListener; import android.os.Parcel; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibrationEffect; import android.os.VibratorInfo; import android.os.VibratorInfo; import android.os.vibrator.PrebakedSegment; import android.os.vibrator.PrebakedSegment; Loading Loading @@ -123,6 +124,8 @@ final class VibratorController { /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ public void reloadVibratorInfoIfNeeded() { public void reloadVibratorInfoIfNeeded() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#reloadVibratorInfoIfNeeded"); try { // Early check outside lock, for quick return. // Early check outside lock, for quick return. if (mVibratorInfoLoadSuccessful) { if (mVibratorInfoLoadSuccessful) { return; return; Loading @@ -139,6 +142,9 @@ final class VibratorController { Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ Loading Loading @@ -193,9 +199,14 @@ final class VibratorController { /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { public boolean isAvailable() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#isAvailable"); try { synchronized (mLock) { synchronized (mLock) { return mNativeWrapper.isAvailable(); return mNativeWrapper.isAvailable(); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -204,6 +215,8 @@ final class VibratorController { * <p>This will affect the state of {@link #isUnderExternalControl()}. * <p>This will affect the state of {@link #isUnderExternalControl()}. */ */ public void setExternalControl(boolean externalControl) { public void setExternalControl(boolean externalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "setExternalControl(" + externalControl + ")"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; return; } } Loading @@ -211,6 +224,9 @@ final class VibratorController { mIsUnderExternalControl = externalControl; mIsUnderExternalControl = externalControl; mNativeWrapper.setExternalControl(externalControl); mNativeWrapper.setExternalControl(externalControl); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -218,6 +234,8 @@ final class VibratorController { * if given {@code effect} is {@code null}. * if given {@code effect} is {@code null}. */ */ public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#updateAlwaysOn"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { return; return; } } Loading @@ -229,10 +247,15 @@ final class VibratorController { prebaked.getEffectStrength()); prebaked.getEffectStrength()); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ public void setAmplitude(float amplitude) { public void setAmplitude(float amplitude) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#setAmplitude"); try { synchronized (mLock) { synchronized (mLock) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.setAmplitude(amplitude); mNativeWrapper.setAmplitude(amplitude); Loading @@ -241,6 +264,9 @@ final class VibratorController { mCurrentAmplitude = amplitude; mCurrentAmplitude = amplitude; } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -253,6 +279,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(long milliseconds, long vibrationId) { public long on(long milliseconds, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on"); try { synchronized (mLock) { synchronized (mLock) { long duration = mNativeWrapper.on(milliseconds, vibrationId); long duration = mNativeWrapper.on(milliseconds, vibrationId); if (duration > 0) { if (duration > 0) { Loading @@ -261,6 +289,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -273,6 +304,7 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (vendor)"); synchronized (mLock) { synchronized (mLock) { Parcel vendorData = Parcel.obtain(); Parcel vendorData = Parcel.obtain(); try { try { Loading @@ -288,6 +320,7 @@ final class VibratorController { return duration; return duration; } finally { } finally { vendorData.recycle(); vendorData.recycle(); Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } } } Loading @@ -302,6 +335,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(PrebakedSegment prebaked, long vibrationId) { public long on(PrebakedSegment prebaked, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Prebaked)"); try { synchronized (mLock) { synchronized (mLock) { long duration = mNativeWrapper.perform(prebaked.getEffectId(), long duration = mNativeWrapper.perform(prebaked.getEffectId(), prebaked.getEffectStrength(), vibrationId); prebaked.getEffectStrength(), vibrationId); Loading @@ -311,6 +346,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -323,6 +361,8 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. * do not support the input or a negative number if the operation failed. */ */ public long on(PrimitiveSegment[] primitives, long vibrationId) { public long on(PrimitiveSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Primitive)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; return 0; } } Loading @@ -334,6 +374,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -345,6 +388,8 @@ final class VibratorController { * @return The duration of the effect playing, or 0 if unsupported. * @return The duration of the effect playing, or 0 if unsupported. */ */ public long on(RampSegment[] primitives, long vibrationId) { public long on(RampSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (PWLE)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { return 0; return 0; } } Loading @@ -357,6 +402,9 @@ final class VibratorController { } } return duration; return duration; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading @@ -365,11 +413,16 @@ final class VibratorController { * <p>This will affect the state of {@link #isVibrating()}. * <p>This will affect the state of {@link #isVibrating()}. */ */ public void off() { public void off() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#off"); try { synchronized (mLock) { synchronized (mLock) { mNativeWrapper.off(); mNativeWrapper.off(); mCurrentAmplitude = 0; mCurrentAmplitude = 0; notifyListenerOnVibrating(false); notifyListenerOnVibrating(false); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +275 −235 Original line number Original line Diff line number Diff line Loading @@ -462,20 +462,31 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call @Override // Binder call public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, String reason, int flags, int privFlags) { String reason, int flags, int privFlags) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback"); // Note that the `performHapticFeedback` method does not take a token argument from the // Note that the `performHapticFeedback` method does not take a token argument from the // caller, and instead, uses this service as the token. This is to mitigate performance // caller, and instead, uses this service as the token. This is to mitigate performance // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are // short-lived, so we don't need to cancel when the process dies. // short-lived, so we don't need to cancel when the process dies. try { performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ this, flags, privFlags); this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override // Binder call @Override // Binder call public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, int constant, int inputDeviceId, int inputSource, String reason, int flags, int constant, int inputDeviceId, int inputSource, String reason, int flags, int privFlags) { int privFlags) { performHapticFeedbackForInputDeviceInternal(uid, deviceId, opPkg, constant, inputDeviceId, Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice"); try { performHapticFeedbackForInputDeviceInternal(uid, deviceId, opPkg, constant, inputDeviceId, inputSource, reason, /* token= */ this, flags, privFlags); inputSource, reason, /* token= */ this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } /** /** Loading Loading @@ -919,8 +930,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") @Nullable @Nullable private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked"); try { HalVibration vib = conductor.getVibration(); HalVibration vib = conductor.getVibration(); int mode = startAppOpModeLocked(vib.callerInfo); int mode = startAppOpModeLocked(vib.callerInfo); switch (mode) { switch (mode) { Loading @@ -941,9 +950,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { default: default: return new Vibration.EndInfo(Status.IGNORED_APP_OPS); return new Vibration.EndInfo(Status.IGNORED_APP_OPS); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @GuardedBy("mLock") @GuardedBy("mLock") Loading Loading @@ -1050,9 +1056,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); try { HalVibration vib = mCurrentVibration.getVibration(); HalVibration vib = mCurrentVibration.getVibration(); if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " Loading @@ -1062,9 +1066,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // vibration was released, after all cleanup. The metrics will be reported then. // vibration was released, after all cleanup. The metrics will be reported then. endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); finishAppOpModeLocked(vib.callerInfo); finishAppOpModeLocked(vib.callerInfo); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private void onSyncedVibrationComplete(long vibrationId) { private void onSyncedVibrationComplete(long vibrationId) { Loading Loading @@ -1418,10 +1419,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") @Nullable @Nullable private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked( private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(CombinedVibration effect) { CombinedVibration effect) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked"); try { SparseArray<VibrationEffect> effects; SparseArray<VibrationEffect> effects; if (effect instanceof CombinedVibration.Mono) { if (effect instanceof CombinedVibration.Mono) { VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); Loading Loading @@ -1449,9 +1447,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return null; return null; } } return result; return result; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Nullable @Nullable Loading Loading @@ -1580,25 +1575,42 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override @Override public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "prepareSyncedVibration"); try { if ((mCapabilities & requiredCapabilities) != requiredCapabilities) { if ((mCapabilities & requiredCapabilities) != requiredCapabilities) { // This sync step requires capabilities this device doesn't have, skipping sync... // This sync step requires capabilities this device doesn't have, skipping // sync... return false; return false; } } return mNativeWrapper.prepareSynced(vibratorIds); return mNativeWrapper.prepareSynced(vibratorIds); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public boolean triggerSyncedVibration(long vibrationId) { public boolean triggerSyncedVibration(long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "triggerSyncedVibration"); try { return mNativeWrapper.triggerSynced(vibrationId); return mNativeWrapper.triggerSynced(vibrationId); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void cancelSyncedVibration() { public void cancelSyncedVibration() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "cancelSyncedVibration"); try { mNativeWrapper.cancelSynced(); mNativeWrapper.cancelSynced(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void noteVibratorOn(int uid, long duration) { public void noteVibratorOn(int uid, long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOn"); try { try { if (duration <= 0) { if (duration <= 0) { // Tried to turn vibrator ON and got: // Tried to turn vibrator ON and got: Loading @@ -1616,16 +1628,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } @Override @Override public void noteVibratorOff(int uid) { public void noteVibratorOff(int uid) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOff"); try { try { mBatteryStatsService.noteVibratorOff(uid); mBatteryStatsService.noteVibratorOff(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); } catch (RemoteException e) { } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to OFF", e); Slog.e(TAG, "Error logging VibratorStateChanged to OFF", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } Loading @@ -1634,12 +1651,17 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationCompleted"); try { synchronized (mLock) { synchronized (mLock) { if (mCurrentVibration != null if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) { && mCurrentVibration.getVibration().id == vibrationId) { reportFinishedVibrationLocked(vibrationEndInfo); reportFinishedVibrationLocked(vibrationEndInfo); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override Loading @@ -1647,6 +1669,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "VibrationThread released after finished vibration"); Slog.d(TAG, "VibrationThread released after finished vibration"); } } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationThreadReleased: " + vibrationId); try { synchronized (mLock) { synchronized (mLock) { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Processing VibrationThread released callback"); Slog.d(TAG, "Processing VibrationThread released callback"); Loading @@ -1658,7 +1682,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentVibration.getVibration().id, vibrationId)); mCurrentVibration.getVibration().id, vibrationId)); } } if (mCurrentVibration != null) { if (mCurrentVibration != null) { // This is when we consider the current vibration complete, so report metrics. // This is when we consider the current vibration complete, so report // metrics. mFrameworkStatsLogger.writeVibrationReportedAsync( mFrameworkStatsLogger.writeVibrationReportedAsync( mCurrentVibration.getVibration().getStatsInfo( mCurrentVibration.getVibration().getStatsInfo( /* completionUptimeMillis= */ SystemClock.uptimeMillis())); /* completionUptimeMillis= */ SystemClock.uptimeMillis())); Loading @@ -1676,6 +1701,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } } } Loading Loading @@ -1917,8 +1945,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, boolean continueExternalControl) { boolean continueExternalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked"); try { if (mCurrentExternalVibration == null) { if (mCurrentExternalVibration == null) { return; return; } } Loading @@ -1930,9 +1956,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, /* shouldWriteStats= */ true); /* shouldWriteStats= */ true); mCurrentExternalVibration = null; mCurrentExternalVibration = null; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private HapticFeedbackVibrationProvider getHapticVibrationProvider() { private HapticFeedbackVibrationProvider getHapticVibrationProvider() { Loading Loading @@ -1987,7 +2010,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override @Override public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { // Create Vibration.Stats as close to the received request as possible, for tracking. Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStart"); try { // Create Vibration.Stats as close to the received request as possible, for // tracking. ExternalVibrationSession externalVibration = new ExternalVibrationSession(vib); ExternalVibrationSession externalVibration = new ExternalVibrationSession(vib); // Mute the request until we run all the checks and accept the vibration. // Mute the request until we run all the checks and accept the vibration. externalVibration.muteScale(); externalVibration.muteScale(); Loading @@ -2002,7 +2028,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return externalVibration.getScale(); return externalVibration.getScale(); } } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission( android.Manifest.permission.VIBRATE, vib.getUid(), -1 /*owningUid*/, true /*exported*/) vib.getUid(), -1 /*owningUid*/, true /*exported*/) != PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) { Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() Loading Loading @@ -2038,7 +2065,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (mCurrentExternalVibration == null) { if (mCurrentExternalVibration == null) { // If we're not under external control right now, then cancel any normal // If we're not under external control right now, then cancel any normal // vibration that may be playing and ready the vibrator for external control. // vibration that may be playing and ready the vibrator for external // control. if (mCurrentVibration != null) { if (mCurrentVibration != null) { externalVibration.stats.reportInterruptedAnotherVibration( externalVibration.stats.reportInterruptedAnotherVibration( mCurrentVibration.getVibration().callerInfo); mCurrentVibration.getVibration().callerInfo); Loading @@ -2053,13 +2081,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } } else { } else { // At this point we have an externally controlled vibration playing already. // At this point we have an externally controlled vibration playing already. // Since the interface defines that only one externally controlled vibration can // Since the interface defines that only one externally controlled // play at a time, we need to first mute the ongoing vibration and then return // vibration can // play at a time, we need to first mute the ongoing vibration and then // return // a scale from this function for the new one, so we can be assured that the // a scale from this function for the new one, so we can be assured that the // ongoing will be muted in favor of the new vibration. // ongoing will be muted in favor of the new vibration. // // // Note that this doesn't support multiple concurrent external controls, as we // Note that this doesn't support multiple concurrent external controls, // would need to mute the old one still if it came from a different controller. // as we would need to mute the old one still if it came from a different // controller. alreadyUnderExternalControl = true; alreadyUnderExternalControl = true; mCurrentExternalVibration.notifyEnded(); mCurrentExternalVibration.notifyEnded(); externalVibration.stats.reportInterruptedAnotherVibration( externalVibration.stats.reportInterruptedAnotherVibration( Loading @@ -2070,11 +2101,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ true); /* continueExternalControl= */ true); } } VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), VibrationAttributes attrs = fixupVibrationAttributes( vib.getVibrationAttributes(), /* effect= */ null); /* effect= */ null); if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { // Force update of user settings before checking if this vibration effect should // Force update of user settings before checking if this vibration effect // be ignored or scaled. // should be ignored or scaled. mVibrationSettings.update(); mVibrationSettings.update(); } } Loading Loading @@ -2110,10 +2142,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Report current time as the vibration start time, for debugging. // Report current time as the vibration start time, for debugging. externalVibration.stats.reportStarted(); externalVibration.stats.reportStarted(); return externalVibration.getScale(); return externalVibration.getScale(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } @Override @Override public void onExternalVibrationStop(ExternalVibration vib) { public void onExternalVibrationStop(ExternalVibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStop"); try { synchronized (mLock) { synchronized (mLock) { if (mCurrentExternalVibration != null if (mCurrentExternalVibration != null && mCurrentExternalVibration.isHoldingSameVibration(vib)) { && mCurrentExternalVibration.isHoldingSameVibration(vib)) { Loading @@ -2125,6 +2162,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ false); /* continueExternalControl= */ false); } } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } } private boolean hasExternalControlCapability() { private boolean hasExternalControlCapability() { Loading