Loading quickstep/src/com/android/quickstep/util/MotionPauseDetector.java +19 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.quickstep.util; import android.content.Context; import android.content.res.Resources; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; Loading @@ -31,6 +32,8 @@ import com.android.launcher3.testing.TestProtocol; */ public class MotionPauseDetector { private static final String TAG = "MotionPauseDetector"; // The percentage of the previous speed that determines whether this is a rapid deceleration. // The bigger this number, the easier it is to trigger the first pause. private static final float RAPID_DECELERATION_FACTOR = 0.6f; Loading Loading @@ -85,7 +88,8 @@ public class MotionPauseDetector { mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast); mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast); mForcePauseTimeout = new Alarm(); mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */)); mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */, "Force pause timeout after " + alarm.getLastSetTimeout() + "ms" /* reason */)); mMakePauseHarderToTrigger = makePauseHarderToTrigger; mVelocityProvider = new SystemVelocityProvider(axis); } Loading @@ -102,7 +106,7 @@ public class MotionPauseDetector { */ public void setDisallowPause(boolean disallowPause) { mDisallowPause = disallowPause; updatePaused(mIsPaused); updatePaused(mIsPaused, "Set disallowPause=" + disallowPause); } /** Loading Loading @@ -134,21 +138,27 @@ public class MotionPauseDetector { float speed = Math.abs(velocity); float previousSpeed = Math.abs(prevVelocity); boolean isPaused; String isPausedReason = ""; if (mIsPaused) { // Continue to be paused until moving at a fast speed. isPaused = speed < mSpeedFast || previousSpeed < mSpeedFast; isPausedReason = "Was paused, but started moving at a fast speed"; } else { if (velocity < 0 != prevVelocity < 0) { // We're just changing directions, not necessarily stopping. isPaused = false; isPausedReason = "Velocity changed directions"; } else { isPaused = speed < mSpeedVerySlow && previousSpeed < mSpeedVerySlow; isPausedReason = "Pause requires back to back slow speeds"; if (!isPaused && !mHasEverBeenPaused) { // We want to be more aggressive about detecting the first pause to ensure it // feels as responsive as possible; getting two very slow speeds back to back // takes too long, so also check for a rapid deceleration. boolean isRapidDeceleration = speed < previousSpeed * RAPID_DECELERATION_FACTOR; isPaused = isRapidDeceleration && speed < mSpeedSomewhatFast; isPausedReason = "Didn't have back to back slow speeds, checking for rapid" + " deceleration on first pause only"; } if (mMakePauseHarderToTrigger) { if (speed < mSpeedSlow) { Loading @@ -156,22 +166,27 @@ public class MotionPauseDetector { mSlowStartTime = time; } isPaused = time - mSlowStartTime >= HARDER_TRIGGER_TIMEOUT; isPausedReason = "Maintained slow speed for sufficient duration when making" + " pause harder to trigger"; } else { mSlowStartTime = 0; isPaused = false; isPausedReason = "Intentionally making pause harder to trigger"; } } } } updatePaused(isPaused); updatePaused(isPaused, isPausedReason); } private void updatePaused(boolean isPaused) { private void updatePaused(boolean isPaused, String reason) { if (mDisallowPause) { reason = "Disallow pause; otherwise, would have been " + isPaused + " due to " + reason; isPaused = false; } if (mIsPaused != isPaused) { mIsPaused = isPaused; Log.d(TAG, "onMotionPauseChanged, paused=" + mIsPaused + " reason=" + reason); boolean isFirstDetectedPause = !mHasEverBeenPaused && mIsPaused; if (mIsPaused) { AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext); Loading src/com/android/launcher3/Alarm.java +7 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public class Alarm implements Runnable{ private Handler mHandler; private OnAlarmListener mAlarmListener; private boolean mAlarmPending = false; private long mLastSetTimeout; public Alarm() { mHandler = new Handler(); Loading @@ -46,6 +47,7 @@ public class Alarm implements Runnable{ mAlarmPending = true; long oldTriggerTime = mAlarmTriggerTime; mAlarmTriggerTime = currentTime + millisecondsInFuture; mLastSetTimeout = millisecondsInFuture; // If the previous alarm was set for a longer duration, cancel it. if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) { Loading Loading @@ -84,4 +86,9 @@ public class Alarm implements Runnable{ public boolean alarmPending() { return mAlarmPending; } /** Returns the last value passed to {@link #setAlarm(long)} */ public long getLastSetTimeout() { return mLastSetTimeout; } } Loading
quickstep/src/com/android/quickstep/util/MotionPauseDetector.java +19 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.quickstep.util; import android.content.Context; import android.content.res.Resources; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; Loading @@ -31,6 +32,8 @@ import com.android.launcher3.testing.TestProtocol; */ public class MotionPauseDetector { private static final String TAG = "MotionPauseDetector"; // The percentage of the previous speed that determines whether this is a rapid deceleration. // The bigger this number, the easier it is to trigger the first pause. private static final float RAPID_DECELERATION_FACTOR = 0.6f; Loading Loading @@ -85,7 +88,8 @@ public class MotionPauseDetector { mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast); mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast); mForcePauseTimeout = new Alarm(); mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */)); mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */, "Force pause timeout after " + alarm.getLastSetTimeout() + "ms" /* reason */)); mMakePauseHarderToTrigger = makePauseHarderToTrigger; mVelocityProvider = new SystemVelocityProvider(axis); } Loading @@ -102,7 +106,7 @@ public class MotionPauseDetector { */ public void setDisallowPause(boolean disallowPause) { mDisallowPause = disallowPause; updatePaused(mIsPaused); updatePaused(mIsPaused, "Set disallowPause=" + disallowPause); } /** Loading Loading @@ -134,21 +138,27 @@ public class MotionPauseDetector { float speed = Math.abs(velocity); float previousSpeed = Math.abs(prevVelocity); boolean isPaused; String isPausedReason = ""; if (mIsPaused) { // Continue to be paused until moving at a fast speed. isPaused = speed < mSpeedFast || previousSpeed < mSpeedFast; isPausedReason = "Was paused, but started moving at a fast speed"; } else { if (velocity < 0 != prevVelocity < 0) { // We're just changing directions, not necessarily stopping. isPaused = false; isPausedReason = "Velocity changed directions"; } else { isPaused = speed < mSpeedVerySlow && previousSpeed < mSpeedVerySlow; isPausedReason = "Pause requires back to back slow speeds"; if (!isPaused && !mHasEverBeenPaused) { // We want to be more aggressive about detecting the first pause to ensure it // feels as responsive as possible; getting two very slow speeds back to back // takes too long, so also check for a rapid deceleration. boolean isRapidDeceleration = speed < previousSpeed * RAPID_DECELERATION_FACTOR; isPaused = isRapidDeceleration && speed < mSpeedSomewhatFast; isPausedReason = "Didn't have back to back slow speeds, checking for rapid" + " deceleration on first pause only"; } if (mMakePauseHarderToTrigger) { if (speed < mSpeedSlow) { Loading @@ -156,22 +166,27 @@ public class MotionPauseDetector { mSlowStartTime = time; } isPaused = time - mSlowStartTime >= HARDER_TRIGGER_TIMEOUT; isPausedReason = "Maintained slow speed for sufficient duration when making" + " pause harder to trigger"; } else { mSlowStartTime = 0; isPaused = false; isPausedReason = "Intentionally making pause harder to trigger"; } } } } updatePaused(isPaused); updatePaused(isPaused, isPausedReason); } private void updatePaused(boolean isPaused) { private void updatePaused(boolean isPaused, String reason) { if (mDisallowPause) { reason = "Disallow pause; otherwise, would have been " + isPaused + " due to " + reason; isPaused = false; } if (mIsPaused != isPaused) { mIsPaused = isPaused; Log.d(TAG, "onMotionPauseChanged, paused=" + mIsPaused + " reason=" + reason); boolean isFirstDetectedPause = !mHasEverBeenPaused && mIsPaused; if (mIsPaused) { AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext); Loading
src/com/android/launcher3/Alarm.java +7 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public class Alarm implements Runnable{ private Handler mHandler; private OnAlarmListener mAlarmListener; private boolean mAlarmPending = false; private long mLastSetTimeout; public Alarm() { mHandler = new Handler(); Loading @@ -46,6 +47,7 @@ public class Alarm implements Runnable{ mAlarmPending = true; long oldTriggerTime = mAlarmTriggerTime; mAlarmTriggerTime = currentTime + millisecondsInFuture; mLastSetTimeout = millisecondsInFuture; // If the previous alarm was set for a longer duration, cancel it. if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) { Loading Loading @@ -84,4 +86,9 @@ public class Alarm implements Runnable{ public boolean alarmPending() { return mAlarmPending; } /** Returns the last value passed to {@link #setAlarm(long)} */ public long getLastSetTimeout() { return mLastSetTimeout; } }