Loading quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +12 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHE import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.LAUNCHER_DESTROYED; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; Loading Loading @@ -182,6 +183,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, if (mActivity != activity) { return; } handleActivityDestroyed(); mRecentsView = null; mActivity = null; } Loading Loading @@ -462,6 +464,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return false; } mStateCallback.resumeCallbacks(); T createdActivity = mActivityInterface.getCreatedActivity(); if (createdActivity != null) { Loading Loading @@ -531,6 +534,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, return true; } private void handleActivityDestroyed() { ActiveGestureLog.INSTANCE.addLog("Launcher activity destroyed", LAUNCHER_DESTROYED); if (mActivityInterface.shouldCancelGestureOnDestroy()) { onGestureCancelled(); } else { mStateCallback.pauseCallbacks(); } } /** * Return true if the window should be translated horizontally if the recents view scrolls */ Loading quickstep/src/com/android/quickstep/BaseActivityInterface.java +8 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,14 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState, boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback); /** * Returns {@code true} iff an ongoing navigational gesture should be cancelled on activity * destroy. Otherwise, the MultiStateCallbacks will be paused until the activity is recreated. */ public boolean shouldCancelGestureOnDestroy() { return true; } public abstract ActivityInitListener createActivityInitListener( Predicate<Boolean> onInitListener); Loading quickstep/src/com/android/quickstep/FallbackActivityInterface.java +5 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,11 @@ public final class FallbackActivityInterface extends return factory; } @Override public boolean shouldCancelGestureOnDestroy() { return false; } @Override public ActivityInitListener createActivityInitListener( Predicate<Boolean> onInitListener) { Loading quickstep/src/com/android/quickstep/MultiStateCallback.java +33 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.quickstep.util.ActiveGestureLog; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.StringJoiner; import java.util.function.Consumer; Loading @@ -52,6 +53,9 @@ public class MultiStateCallback { private int mState = 0; private boolean mCallbacksPaused = false; private final List<Runnable> mPendingCallbacks = new ArrayList<>(); public MultiStateCallback(String[] stateNames) { this(stateNames, stateFlag -> null); } Loading @@ -78,6 +82,24 @@ public class MultiStateCallback { } } /** Pauses callbacks. */ public void pauseCallbacks() { mCallbacksPaused = true; } /** Immediately queues any callbacks that were pending paused. */ public void resumeCallbacks() { if (!mCallbacksPaused) { return; } mCallbacksPaused = false; List<Runnable> queuedCallbacks = new ArrayList<>(mPendingCallbacks); mPendingCallbacks.clear(); for (Runnable runnable : queuedCallbacks) { runnable.run(); } } /** * Adds the provided state flags to the global state and executes any callbacks as a result. */ Loading @@ -99,7 +121,12 @@ public class MultiStateCallback { if ((mState & state) == state) { LinkedList<Runnable> callbacks = mCallbacks.valueAt(i); while (!callbacks.isEmpty()) { callbacks.pollFirst().run(); Runnable cb = callbacks.pollFirst(); if (mCallbacksPaused) { mPendingCallbacks.add(cb); } else { cb.run(); } } } } Loading Loading @@ -151,11 +178,15 @@ public class MultiStateCallback { if (wasOn != isOn) { ArrayList<Consumer<Boolean>> listeners = mStateChangeListeners.valueAt(i); for (Consumer<Boolean> listener : listeners) { if (mCallbacksPaused) { mPendingCallbacks.add(() -> listener.accept(isOn)); } else { listener.accept(isOn); } } } } } /** * Sets a callback to be run when the provided states in the given {@param stateMask} is Loading quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java +8 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ public class ActiveGestureErrorDetector { ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED, /** * These GestureEvents are specifically associated to state flags that get set in Loading Loading @@ -162,6 +162,13 @@ public class ActiveGestureErrorDetector { + "before/without setting end target to new task", writer); break; case LAUNCHER_DESTROYED: errorDetected |= printErrorIfTrue( true, prefix, /* errorMessage= */ "Launcher destroyed mid-gesture", writer); break; case STATE_GESTURE_COMPLETED: errorDetected |= printErrorIfTrue( !encounteredEvents.contains(GestureEvent.MOTION_UP), Loading Loading
quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +12 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHE import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.LAUNCHER_DESTROYED; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; Loading Loading @@ -182,6 +183,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, if (mActivity != activity) { return; } handleActivityDestroyed(); mRecentsView = null; mActivity = null; } Loading Loading @@ -462,6 +464,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return false; } mStateCallback.resumeCallbacks(); T createdActivity = mActivityInterface.getCreatedActivity(); if (createdActivity != null) { Loading Loading @@ -531,6 +534,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, return true; } private void handleActivityDestroyed() { ActiveGestureLog.INSTANCE.addLog("Launcher activity destroyed", LAUNCHER_DESTROYED); if (mActivityInterface.shouldCancelGestureOnDestroy()) { onGestureCancelled(); } else { mStateCallback.pauseCallbacks(); } } /** * Return true if the window should be translated horizontally if the recents view scrolls */ Loading
quickstep/src/com/android/quickstep/BaseActivityInterface.java +8 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,14 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState, boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback); /** * Returns {@code true} iff an ongoing navigational gesture should be cancelled on activity * destroy. Otherwise, the MultiStateCallbacks will be paused until the activity is recreated. */ public boolean shouldCancelGestureOnDestroy() { return true; } public abstract ActivityInitListener createActivityInitListener( Predicate<Boolean> onInitListener); Loading
quickstep/src/com/android/quickstep/FallbackActivityInterface.java +5 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,11 @@ public final class FallbackActivityInterface extends return factory; } @Override public boolean shouldCancelGestureOnDestroy() { return false; } @Override public ActivityInitListener createActivityInitListener( Predicate<Boolean> onInitListener) { Loading
quickstep/src/com/android/quickstep/MultiStateCallback.java +33 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.quickstep.util.ActiveGestureLog; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.StringJoiner; import java.util.function.Consumer; Loading @@ -52,6 +53,9 @@ public class MultiStateCallback { private int mState = 0; private boolean mCallbacksPaused = false; private final List<Runnable> mPendingCallbacks = new ArrayList<>(); public MultiStateCallback(String[] stateNames) { this(stateNames, stateFlag -> null); } Loading @@ -78,6 +82,24 @@ public class MultiStateCallback { } } /** Pauses callbacks. */ public void pauseCallbacks() { mCallbacksPaused = true; } /** Immediately queues any callbacks that were pending paused. */ public void resumeCallbacks() { if (!mCallbacksPaused) { return; } mCallbacksPaused = false; List<Runnable> queuedCallbacks = new ArrayList<>(mPendingCallbacks); mPendingCallbacks.clear(); for (Runnable runnable : queuedCallbacks) { runnable.run(); } } /** * Adds the provided state flags to the global state and executes any callbacks as a result. */ Loading @@ -99,7 +121,12 @@ public class MultiStateCallback { if ((mState & state) == state) { LinkedList<Runnable> callbacks = mCallbacks.valueAt(i); while (!callbacks.isEmpty()) { callbacks.pollFirst().run(); Runnable cb = callbacks.pollFirst(); if (mCallbacksPaused) { mPendingCallbacks.add(cb); } else { cb.run(); } } } } Loading Loading @@ -151,11 +178,15 @@ public class MultiStateCallback { if (wasOn != isOn) { ArrayList<Consumer<Boolean>> listeners = mStateChangeListeners.valueAt(i); for (Consumer<Boolean> listener : listeners) { if (mCallbacksPaused) { mPendingCallbacks.add(() -> listener.accept(isOn)); } else { listener.accept(isOn); } } } } } /** * Sets a callback to be run when the provided states in the given {@param stateMask} is Loading
quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java +8 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ public class ActiveGestureErrorDetector { ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED, /** * These GestureEvents are specifically associated to state flags that get set in Loading Loading @@ -162,6 +162,13 @@ public class ActiveGestureErrorDetector { + "before/without setting end target to new task", writer); break; case LAUNCHER_DESTROYED: errorDetected |= printErrorIfTrue( true, prefix, /* errorMessage= */ "Launcher destroyed mid-gesture", writer); break; case STATE_GESTURE_COMPLETED: errorDetected |= printErrorIfTrue( !encounteredEvents.contains(GestureEvent.MOTION_UP), Loading