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

Commit bf6dfc5f authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fixing ANR when using quickscrub from homescreen

Change-Id: Id355726f7ec72dc2fd28a3e757355d1143464001
parent 84e71bf9
Loading
Loading
Loading
Loading
+15 −14
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;

import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;

@@ -40,14 +43,11 @@ import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.model.ModelPreload;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -295,20 +295,21 @@ public class TouchInteractionService extends Service {
        public void updateTouchTracking(int interactionType) {
            mMainThreadExecutor.execute(() -> {
                if (TouchConsumer.isInteractionQuick(interactionType)) {
                    if (mLauncher.getWorkspace().runOnOverlayHidden(
                            () -> updateTouchTracking(interactionType))) {
                        // Hide the minus one overlay so launcher can get window focus.
                        mLauncher.onQuickstepGestureStarted(true);
                        return;
                    }
                    Runnable action = () -> {
                        Runnable onComplete = null;
                        if (interactionType == INTERACTION_QUICK_SCRUB) {
                            mQuickScrubController.onQuickScrubStart(true);
                        } else if (interactionType == INTERACTION_QUICK_SWITCH) {
                            onComplete = mQuickScrubController::onQuickSwitch;
                        }
                    mLauncher.getStateManager().goToState(LauncherState.OVERVIEW, true, 0,
                            QuickScrubController.QUICK_SWITCH_START_DURATION, onComplete);
                        mLauncher.getStateManager().goToState(OVERVIEW, true, 0,
                                QUICK_SWITCH_START_DURATION, onComplete);
                    };

                    if (mLauncher.getWorkspace().runOnOverlayHidden(action)) {
                        // Hide the minus one overlay so launcher can get window focus.
                        mLauncher.onQuickstepGestureStarted(true);
                    }
                }
            });
        }
+34 −37
Original line number Diff line number Diff line
@@ -1163,12 +1163,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
            if (mOverlayShown) {
                mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
                        Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
                if (mOnOverlayHiddenCallback != null) {
                    mOnOverlayHiddenCallback.run();
                    mOnOverlayHiddenCallback = null;
                }
            }
            mOverlayShown = false;
            tryRunOverlayCallback();
        }
        float offset = 0f;
        float slip = 0f;
@@ -1192,6 +1189,24 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
        mLauncher.getDragLayer().setAlpha(alpha);
    }

    /**
     * @return false if the callback is still pending
     */
    private boolean tryRunOverlayCallback() {
        if (mOnOverlayHiddenCallback == null) {
            // Return true as no callback is pending. This is used by OnWindowFocusChangeListener
            // to remove itself if multiple focus handles were added.
            return true;
        }
        if (mOverlayShown || !hasWindowFocus()) {
            return false;
        }

        mOnOverlayHiddenCallback.run();
        mOnOverlayHiddenCallback = null;
        return true;
    }

    /**
     * Runs the given callback when the minus one overlay is hidden. Specifically, it is run
     * when launcher's window has focus and the overlay is no longer being shown. If a callback
@@ -1200,51 +1215,33 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
     * @return Whether the callback was deferred.
     */
    public boolean runOnOverlayHidden(Runnable callback) {
        View rootView = getRootView();
        if (rootView.hasWindowFocus()) {
            if (mOverlayShown) {
                chainOverlayHiddenCallback(callback);
                return true;
        if (mOnOverlayHiddenCallback == null) {
            mOnOverlayHiddenCallback = callback;
        } else {
            // Chain the new callback onto the previous callback(s).
            Runnable oldCallback = mOnOverlayHiddenCallback;
            mOnOverlayHiddenCallback = () -> {
                oldCallback.run();
                callback.run();
                return false;
            }
            };
        }
        ViewTreeObserver observer = rootView.getViewTreeObserver();
        if (!tryRunOverlayCallback()) {
            ViewTreeObserver observer = getViewTreeObserver();
            if (observer != null && observer.isAlive()) {
                observer.addOnWindowFocusChangeListener(
                        new ViewTreeObserver.OnWindowFocusChangeListener() {
                            @Override
                            public void onWindowFocusChanged(boolean hasFocus) {
                            if (hasFocus) {
                                // Defer further if the minus one overlay is still showing.
                                if (mOverlayShown) {
                                    chainOverlayHiddenCallback(callback);
                                } else {
                                    callback.run();
                                }
                                if (tryRunOverlayCallback() && observer.isAlive()) {
                                    observer.removeOnWindowFocusChangeListener(this);
                                }
                            }});
            }
                    });
            return true;
        }
        return false;
    }

    private void chainOverlayHiddenCallback(Runnable callback) {
        if (mOnOverlayHiddenCallback == null) {
            mOnOverlayHiddenCallback = callback;
        } else {
            // Chain the new callback onto the previous callback(s).
            Runnable oldCallback = mOnOverlayHiddenCallback;
            mOnOverlayHiddenCallback = () -> {
                oldCallback.run();
                callback.run();
            };
        }
    }

    @Override
    protected void notifyPageSwitchListener(int prevPage) {
        super.notifyPageSwitchListener(prevPage);