Loading services/core/java/com/android/server/vibrator/VibrationStepConductor.java +13 −9 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f; static final List<Step> EMPTY_STEP_LIST = new ArrayList<>(); private final Object mLock = new Object(); // Used within steps. public final VibrationSettings vibrationSettings; public final DeviceVibrationEffectAdapter deviceEffectAdapter; Loading @@ -74,6 +72,11 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>(); // Signalling fields. // Note that vibrator callback signals may happen inside vibrator HAL calls made by the // VibrationThread, or on an external executor, so this lock should not be held for anything // other than updating signalling state - particularly not during HAL calls or when invoking // other callbacks that may trigger calls into the thread. private final Object mLock = new Object(); @GuardedBy("mLock") private final IntArray mSignalVibratorsComplete; @GuardedBy("mLock") Loading Loading @@ -334,9 +337,9 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { * The state update is recorded for processing on the main execution thread (VibrationThread). */ public void notifyVibratorComplete(int vibratorId) { if (Build.IS_DEBUGGABLE) { expectIsVibrationThread(false); } // HAL callbacks may be triggered directly within HAL calls, so these notifications // could be on the VibrationThread as it calls the HAL, or some other executor later. // Therefore no thread assertion is made here. if (DEBUG) { Slog.d(TAG, "Vibration complete reported by vibrator " + vibratorId); Loading @@ -356,9 +359,9 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { * (VibrationThread). */ public void notifySyncedVibrationComplete() { if (Build.IS_DEBUGGABLE) { expectIsVibrationThread(false); } // HAL callbacks may be triggered directly within HAL calls, so these notifications // could be on the VibrationThread as it calls the HAL, or some other executor later. // Therefore no thread assertion is made here. if (DEBUG) { Slog.d(TAG, "Synced vibration complete reported by vibrator manager"); Loading Loading @@ -394,7 +397,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { int[] vibratorsToProcess = null; boolean doCancel = false; boolean doCancelImmediate = false; // Swap out the queue of completions to process. // Collect signals to process, but don't keep the lock while processing them. synchronized (mLock) { if (mSignalCancelImmediate) { if (mCancelledImmediately) { Loading @@ -407,6 +410,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { doCancel = true; } if (!doCancelImmediate && mSignalVibratorsComplete.size() > 0) { // Swap out the queue of completions to process. vibratorsToProcess = mSignalVibratorsComplete.toArray(); // makes a copy mSignalVibratorsComplete.clear(); } Loading services/core/java/com/android/server/vibrator/VibrationThread.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.IBinder; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.os.WorkSource; import android.util.Slog; Loading Loading @@ -176,7 +177,7 @@ final class VibrationThread extends Thread { * @return true if the vibration completed, or false if waiting timed out. */ public boolean waitForThreadIdle(long maxWaitMillis) { long now = System.currentTimeMillis(); long now = SystemClock.elapsedRealtime(); long deadline = now + maxWaitMillis; synchronized (mLock) { while (true) { Loading @@ -191,7 +192,7 @@ final class VibrationThread extends Thread { } catch (InterruptedException e) { Slog.w(TAG, "VibrationThread interrupted waiting to stop, continuing"); } now = System.currentTimeMillis(); now = SystemClock.elapsedRealtime(); } } } Loading Loading
services/core/java/com/android/server/vibrator/VibrationStepConductor.java +13 −9 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f; static final List<Step> EMPTY_STEP_LIST = new ArrayList<>(); private final Object mLock = new Object(); // Used within steps. public final VibrationSettings vibrationSettings; public final DeviceVibrationEffectAdapter deviceEffectAdapter; Loading @@ -74,6 +72,11 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>(); // Signalling fields. // Note that vibrator callback signals may happen inside vibrator HAL calls made by the // VibrationThread, or on an external executor, so this lock should not be held for anything // other than updating signalling state - particularly not during HAL calls or when invoking // other callbacks that may trigger calls into the thread. private final Object mLock = new Object(); @GuardedBy("mLock") private final IntArray mSignalVibratorsComplete; @GuardedBy("mLock") Loading Loading @@ -334,9 +337,9 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { * The state update is recorded for processing on the main execution thread (VibrationThread). */ public void notifyVibratorComplete(int vibratorId) { if (Build.IS_DEBUGGABLE) { expectIsVibrationThread(false); } // HAL callbacks may be triggered directly within HAL calls, so these notifications // could be on the VibrationThread as it calls the HAL, or some other executor later. // Therefore no thread assertion is made here. if (DEBUG) { Slog.d(TAG, "Vibration complete reported by vibrator " + vibratorId); Loading @@ -356,9 +359,9 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { * (VibrationThread). */ public void notifySyncedVibrationComplete() { if (Build.IS_DEBUGGABLE) { expectIsVibrationThread(false); } // HAL callbacks may be triggered directly within HAL calls, so these notifications // could be on the VibrationThread as it calls the HAL, or some other executor later. // Therefore no thread assertion is made here. if (DEBUG) { Slog.d(TAG, "Synced vibration complete reported by vibrator manager"); Loading Loading @@ -394,7 +397,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { int[] vibratorsToProcess = null; boolean doCancel = false; boolean doCancelImmediate = false; // Swap out the queue of completions to process. // Collect signals to process, but don't keep the lock while processing them. synchronized (mLock) { if (mSignalCancelImmediate) { if (mCancelledImmediately) { Loading @@ -407,6 +410,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { doCancel = true; } if (!doCancelImmediate && mSignalVibratorsComplete.size() > 0) { // Swap out the queue of completions to process. vibratorsToProcess = mSignalVibratorsComplete.toArray(); // makes a copy mSignalVibratorsComplete.clear(); } Loading
services/core/java/com/android/server/vibrator/VibrationThread.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.IBinder; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.os.WorkSource; import android.util.Slog; Loading Loading @@ -176,7 +177,7 @@ final class VibrationThread extends Thread { * @return true if the vibration completed, or false if waiting timed out. */ public boolean waitForThreadIdle(long maxWaitMillis) { long now = System.currentTimeMillis(); long now = SystemClock.elapsedRealtime(); long deadline = now + maxWaitMillis; synchronized (mLock) { while (true) { Loading @@ -191,7 +192,7 @@ final class VibrationThread extends Thread { } catch (InterruptedException e) { Slog.w(TAG, "VibrationThread interrupted waiting to stop, continuing"); } now = System.currentTimeMillis(); now = SystemClock.elapsedRealtime(); } } } Loading