Loading core/java/android/os/SystemVibratorManager.java +10 −0 Original line number 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason=" + reason); try { mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mToken); } catch (RemoteException 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback, reason=" + reason); try { mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, reason, flags, privFlags); } catch (RemoteException 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice, reason=" + reason); try { mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, constant, inputDeviceId, inputSource, reason, flags, privFlags); } catch (RemoteException 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 Diff line number Diff line Loading @@ -128,6 +128,8 @@ final class VibrationThread extends Thread { * before the release callback. */ boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrationOnVibrationThread"); try { synchronized (mLock) { if (mRequestedActiveConductor != null) { Slog.wtf(TAG, "Attempt to start vibration when one already running"); Loading @@ -137,6 +139,9 @@ final class VibrationThread extends Thread { mLock.notifyAll(); } return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading services/core/java/com/android/server/vibrator/VibratorController.java +123 −70 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.IVibratorStateListener; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibratorInfo; 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. */ public void reloadVibratorInfoIfNeeded() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#reloadVibratorInfoIfNeeded"); try { // Early check outside lock, for quick return. if (mVibratorInfoLoadSuccessful) { return; Loading @@ -139,6 +142,9 @@ final class VibratorController { 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. */ Loading Loading @@ -193,9 +199,14 @@ final class VibratorController { /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#isAvailable"); try { synchronized (mLock) { 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()}. */ public void setExternalControl(boolean externalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "setExternalControl(" + externalControl + ")"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; } Loading @@ -211,6 +224,9 @@ final class VibratorController { mIsUnderExternalControl = 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}. */ 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)) { return; } Loading @@ -229,10 +247,15 @@ final class VibratorController { prebaked.getEffectStrength()); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ public void setAmplitude(float amplitude) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#setAmplitude"); try { synchronized (mLock) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.setAmplitude(amplitude); Loading @@ -241,6 +264,9 @@ final class VibratorController { 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. */ public long on(long milliseconds, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on"); try { synchronized (mLock) { long duration = mNativeWrapper.on(milliseconds, vibrationId); if (duration > 0) { Loading @@ -261,6 +289,9 @@ final class VibratorController { } 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. */ public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (vendor)"); synchronized (mLock) { Parcel vendorData = Parcel.obtain(); try { Loading @@ -288,6 +320,7 @@ final class VibratorController { return duration; } finally { 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. */ public long on(PrebakedSegment prebaked, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Prebaked)"); try { synchronized (mLock) { long duration = mNativeWrapper.perform(prebaked.getEffectId(), prebaked.getEffectStrength(), vibrationId); Loading @@ -311,6 +346,9 @@ final class VibratorController { } 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. */ public long on(PrimitiveSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Primitive)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; } Loading @@ -334,6 +374,9 @@ final class VibratorController { } 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. */ 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)) { return 0; } Loading @@ -357,6 +402,9 @@ final class VibratorController { } 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()}. */ public void off() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#off"); try { synchronized (mLock) { mNativeWrapper.off(); mCurrentAmplitude = 0; notifyListenerOnVibrating(false); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +275 −235 Original line number Diff line number Diff line Loading @@ -462,20 +462,31 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, 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 // 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 // short-lived, so we don't need to cancel when the process dies. try { performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override // Binder call public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, int constant, int inputDeviceId, int inputSource, String reason, int flags, 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); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Loading Loading @@ -919,8 +930,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked"); try { HalVibration vib = conductor.getVibration(); int mode = startAppOpModeLocked(vib.callerInfo); switch (mode) { Loading @@ -941,9 +950,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { default: return new Vibration.EndInfo(Status.IGNORED_APP_OPS); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") Loading Loading @@ -1050,9 +1056,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); try { HalVibration vib = mCurrentVibration.getVibration(); if (DEBUG) { 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. endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); finishAppOpModeLocked(vib.callerInfo); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void onSyncedVibrationComplete(long vibrationId) { Loading Loading @@ -1418,10 +1419,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked( CombinedVibration effect) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked"); try { private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(CombinedVibration effect) { SparseArray<VibrationEffect> effects; if (effect instanceof CombinedVibration.Mono) { VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); Loading Loading @@ -1449,9 +1447,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return null; } return result; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Nullable Loading Loading @@ -1580,25 +1575,42 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "prepareSyncedVibration"); try { 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 mNativeWrapper.prepareSynced(vibratorIds); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public boolean triggerSyncedVibration(long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "triggerSyncedVibration"); try { return mNativeWrapper.triggerSynced(vibrationId); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void cancelSyncedVibration() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "cancelSyncedVibration"); try { mNativeWrapper.cancelSynced(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void noteVibratorOn(int uid, long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOn"); try { if (duration <= 0) { // Tried to turn vibrator ON and got: Loading @@ -1616,16 +1628,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void noteVibratorOff(int uid) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOff"); try { mBatteryStatsService.noteVibratorOff(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); } catch (RemoteException 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) { Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationCompleted"); try { synchronized (mLock) { if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) { reportFinishedVibrationLocked(vibrationEndInfo); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading @@ -1647,6 +1669,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { Slog.d(TAG, "VibrationThread released after finished vibration"); } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationThreadReleased: " + vibrationId); try { synchronized (mLock) { if (DEBUG) { Slog.d(TAG, "Processing VibrationThread released callback"); Loading @@ -1658,7 +1682,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentVibration.getVibration().id, vibrationId)); } 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( mCurrentVibration.getVibration().getStatsInfo( /* 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") private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, boolean continueExternalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked"); try { if (mCurrentExternalVibration == null) { return; } Loading @@ -1930,9 +1956,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, /* shouldWriteStats= */ true); mCurrentExternalVibration = null; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private HapticFeedbackVibrationProvider getHapticVibrationProvider() { Loading Loading @@ -1987,7 +2010,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override 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); // Mute the request until we run all the checks and accept the vibration. externalVibration.muteScale(); Loading @@ -2002,7 +2028,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return externalVibration.getScale(); } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission( android.Manifest.permission.VIBRATE, vib.getUid(), -1 /*owningUid*/, true /*exported*/) != PackageManager.PERMISSION_GRANTED) { 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 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) { externalVibration.stats.reportInterruptedAnotherVibration( mCurrentVibration.getVibration().callerInfo); Loading @@ -2053,13 +2081,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } else { // At this point we have an externally controlled vibration playing already. // Since the interface defines that only one externally controlled vibration can // play at a time, we need to first mute the ongoing vibration and then return // Since the interface defines that only one externally controlled // 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 // ongoing will be muted in favor of the new vibration. // // Note that this doesn't support multiple concurrent external controls, as we // would need to mute the old one still if it came from a different controller. // Note that this doesn't support multiple concurrent external controls, // as we would need to mute the old one still if it came from a different // controller. alreadyUnderExternalControl = true; mCurrentExternalVibration.notifyEnded(); externalVibration.stats.reportInterruptedAnotherVibration( Loading @@ -2070,11 +2101,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ true); } VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), VibrationAttributes attrs = fixupVibrationAttributes( vib.getVibrationAttributes(), /* effect= */ null); if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { // Force update of user settings before checking if this vibration effect should // be ignored or scaled. // Force update of user settings before checking if this vibration effect // should be ignored or scaled. mVibrationSettings.update(); } Loading Loading @@ -2110,10 +2142,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Report current time as the vibration start time, for debugging. externalVibration.stats.reportStarted(); return externalVibration.getScale(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void onExternalVibrationStop(ExternalVibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStop"); try { synchronized (mLock) { if (mCurrentExternalVibration != null && mCurrentExternalVibration.isHoldingSameVibration(vib)) { Loading @@ -2125,6 +2162,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ false); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private boolean hasExternalControlCapability() { Loading Loading
core/java/android/os/SystemVibratorManager.java +10 −0 Original line number 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason=" + reason); try { mService.vibrate(uid, mContext.getDeviceId(), opPkg, effect, attributes, reason, mToken); } catch (RemoteException 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedback, reason=" + reason); try { mService.performHapticFeedback(mUid, mContext.getDeviceId(), mPackageName, constant, reason, flags, privFlags); } catch (RemoteException 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."); return; } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice, reason=" + reason); try { mService.performHapticFeedbackForInputDevice(mUid, mContext.getDeviceId(), mPackageName, constant, inputDeviceId, inputSource, reason, flags, privFlags); } catch (RemoteException 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 Diff line number Diff line Loading @@ -128,6 +128,8 @@ final class VibrationThread extends Thread { * before the release callback. */ boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrationOnVibrationThread"); try { synchronized (mLock) { if (mRequestedActiveConductor != null) { Slog.wtf(TAG, "Attempt to start vibration when one already running"); Loading @@ -137,6 +139,9 @@ final class VibrationThread extends Thread { mLock.notifyAll(); } return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading
services/core/java/com/android/server/vibrator/VibratorController.java +123 −70 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.IVibratorStateListener; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibratorInfo; 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. */ public void reloadVibratorInfoIfNeeded() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#reloadVibratorInfoIfNeeded"); try { // Early check outside lock, for quick return. if (mVibratorInfoLoadSuccessful) { return; Loading @@ -139,6 +142,9 @@ final class VibratorController { 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. */ Loading Loading @@ -193,9 +199,14 @@ final class VibratorController { /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#isAvailable"); try { synchronized (mLock) { 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()}. */ public void setExternalControl(boolean externalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "setExternalControl(" + externalControl + ")"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; } Loading @@ -211,6 +224,9 @@ final class VibratorController { mIsUnderExternalControl = 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}. */ 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)) { return; } Loading @@ -229,10 +247,15 @@ final class VibratorController { prebaked.getEffectStrength()); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ public void setAmplitude(float amplitude) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#setAmplitude"); try { synchronized (mLock) { if (mVibratorInfo.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.setAmplitude(amplitude); Loading @@ -241,6 +264,9 @@ final class VibratorController { 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. */ public long on(long milliseconds, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on"); try { synchronized (mLock) { long duration = mNativeWrapper.on(milliseconds, vibrationId); if (duration > 0) { Loading @@ -261,6 +289,9 @@ final class VibratorController { } 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. */ public long on(VibrationEffect.VendorEffect vendorEffect, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (vendor)"); synchronized (mLock) { Parcel vendorData = Parcel.obtain(); try { Loading @@ -288,6 +320,7 @@ final class VibratorController { return duration; } finally { 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. */ public long on(PrebakedSegment prebaked, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Prebaked)"); try { synchronized (mLock) { long duration = mNativeWrapper.perform(prebaked.getEffectId(), prebaked.getEffectStrength(), vibrationId); Loading @@ -311,6 +346,9 @@ final class VibratorController { } 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. */ public long on(PrimitiveSegment[] primitives, long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#on (Primitive)"); try { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; } Loading @@ -334,6 +374,9 @@ final class VibratorController { } 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. */ 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)) { return 0; } Loading @@ -357,6 +402,9 @@ final class VibratorController { } 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()}. */ public void off() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorController#off"); try { synchronized (mLock) { mNativeWrapper.off(); mCurrentAmplitude = 0; notifyListenerOnVibrating(false); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +275 −235 Original line number Diff line number Diff line Loading @@ -462,20 +462,31 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, 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 // 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 // short-lived, so we don't need to cancel when the process dies. try { performHapticFeedbackInternal(uid, deviceId, opPkg, constant, reason, /* token= */ this, flags, privFlags); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override // Binder call public void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg, int constant, int inputDeviceId, int inputSource, String reason, int flags, 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); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } /** Loading Loading @@ -919,8 +930,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private Vibration.EndInfo startVibrationOnThreadLocked(VibrationStepConductor conductor) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked"); try { HalVibration vib = conductor.getVibration(); int mode = startAppOpModeLocked(vib.callerInfo); switch (mode) { Loading @@ -941,9 +950,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { default: return new Vibration.EndInfo(Status.IGNORED_APP_OPS); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @GuardedBy("mLock") Loading Loading @@ -1050,9 +1056,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); try { HalVibration vib = mCurrentVibration.getVibration(); if (DEBUG) { 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. endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false); finishAppOpModeLocked(vib.callerInfo); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private void onSyncedVibrationComplete(long vibrationId) { Loading Loading @@ -1418,10 +1419,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked( CombinedVibration effect) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked"); try { private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(CombinedVibration effect) { SparseArray<VibrationEffect> effects; if (effect instanceof CombinedVibration.Mono) { VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect(); Loading Loading @@ -1449,9 +1447,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return null; } return result; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Nullable Loading Loading @@ -1580,25 +1575,42 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "prepareSyncedVibration"); try { 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 mNativeWrapper.prepareSynced(vibratorIds); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public boolean triggerSyncedVibration(long vibrationId) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "triggerSyncedVibration"); try { return mNativeWrapper.triggerSynced(vibrationId); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void cancelSyncedVibration() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "cancelSyncedVibration"); try { mNativeWrapper.cancelSynced(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void noteVibratorOn(int uid, long duration) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOn"); try { if (duration <= 0) { // Tried to turn vibrator ON and got: Loading @@ -1616,16 +1628,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mFrameworkStatsLogger.writeVibratorStateOnAsync(uid, duration); } catch (RemoteException e) { Slog.e(TAG, "Error logging VibratorStateChanged to ON", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void noteVibratorOff(int uid) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "noteVibratorOff"); try { mBatteryStatsService.noteVibratorOff(uid); mFrameworkStatsLogger.writeVibratorStateOffAsync(uid); } catch (RemoteException 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) { Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo); } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationCompleted"); try { synchronized (mLock) { if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) { reportFinishedVibrationLocked(vibrationEndInfo); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override Loading @@ -1647,6 +1669,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (DEBUG) { Slog.d(TAG, "VibrationThread released after finished vibration"); } Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationThreadReleased: " + vibrationId); try { synchronized (mLock) { if (DEBUG) { Slog.d(TAG, "Processing VibrationThread released callback"); Loading @@ -1658,7 +1682,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentVibration.getVibration().id, vibrationId)); } 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( mCurrentVibration.getVibration().getStatsInfo( /* 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") private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo, boolean continueExternalControl) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked"); try { if (mCurrentExternalVibration == null) { return; } Loading @@ -1930,9 +1956,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo, /* shouldWriteStats= */ true); mCurrentExternalVibration = null; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private HapticFeedbackVibrationProvider getHapticVibrationProvider() { Loading Loading @@ -1987,7 +2010,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override 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); // Mute the request until we run all the checks and accept the vibration. externalVibration.muteScale(); Loading @@ -2002,7 +2028,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return externalVibration.getScale(); } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission( android.Manifest.permission.VIBRATE, vib.getUid(), -1 /*owningUid*/, true /*exported*/) != PackageManager.PERMISSION_GRANTED) { 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 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) { externalVibration.stats.reportInterruptedAnotherVibration( mCurrentVibration.getVibration().callerInfo); Loading @@ -2053,13 +2081,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } else { // At this point we have an externally controlled vibration playing already. // Since the interface defines that only one externally controlled vibration can // play at a time, we need to first mute the ongoing vibration and then return // Since the interface defines that only one externally controlled // 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 // ongoing will be muted in favor of the new vibration. // // Note that this doesn't support multiple concurrent external controls, as we // would need to mute the old one still if it came from a different controller. // Note that this doesn't support multiple concurrent external controls, // as we would need to mute the old one still if it came from a different // controller. alreadyUnderExternalControl = true; mCurrentExternalVibration.notifyEnded(); externalVibration.stats.reportInterruptedAnotherVibration( Loading @@ -2070,11 +2101,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ true); } VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), VibrationAttributes attrs = fixupVibrationAttributes( vib.getVibrationAttributes(), /* effect= */ null); if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { // Force update of user settings before checking if this vibration effect should // be ignored or scaled. // Force update of user settings before checking if this vibration effect // should be ignored or scaled. mVibrationSettings.update(); } Loading Loading @@ -2110,10 +2142,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Report current time as the vibration start time, for debugging. externalVibration.stats.reportStarted(); return externalVibration.getScale(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } @Override public void onExternalVibrationStop(ExternalVibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onExternalVibrationStop"); try { synchronized (mLock) { if (mCurrentExternalVibration != null && mCurrentExternalVibration.isHoldingSameVibration(vib)) { Loading @@ -2125,6 +2162,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* continueExternalControl= */ false); } } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } private boolean hasExternalControlCapability() { Loading