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

Commit 0088997d authored by Simon Bowden's avatar Simon Bowden
Browse files

Small VibrationThread fixes.

Use the correct clock, and allow the "notify" calls to be run on
VibrationThread or not (in case the HAL callback happens directly
on the thread calling into HAL), and expand commentary on this.

Bug: 193792066
Test: presubmit
Change-Id: I5039ca6e43c9220b01530fe52ea41a1ddb08f14c
parent d319a179
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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")
@@ -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);
@@ -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");
@@ -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) {
@@ -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();
            }
+3 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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();
            }
        }
    }