From bf6dfc5fa729f0d3024e257d54e7e6006bbb6de8 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 13 Feb 2018 17:04:55 -0800 Subject: [PATCH] Fixing ANR when using quickscrub from homescreen Change-Id: Id355726f7ec72dc2fd28a3e757355d1143464001 --- .../quickstep/TouchInteractionService.java | 29 ++++---- src/com/android/launcher3/Workspace.java | 71 +++++++++---------- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index d5fa7231ca..080537e5d1 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -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))) { + 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(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); - return; } - 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); } }); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index a4ca68a2fc..0b117075a7 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1163,12 +1163,9 @@ public class Workspace extends PagedView 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 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,39 +1215,6 @@ public class Workspace extends PagedView * @return Whether the callback was deferred. */ public boolean runOnOverlayHidden(Runnable callback) { - View rootView = getRootView(); - if (rootView.hasWindowFocus()) { - if (mOverlayShown) { - chainOverlayHiddenCallback(callback); - return true; - } else { - callback.run(); - return false; - } - } - ViewTreeObserver observer = rootView.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(); - } - observer.removeOnWindowFocusChangeListener(this); - } - } - }); - return true; - } - return false; - } - - private void chainOverlayHiddenCallback(Runnable callback) { if (mOnOverlayHiddenCallback == null) { mOnOverlayHiddenCallback = callback; } else { @@ -1243,6 +1225,21 @@ public class Workspace extends PagedView callback.run(); }; } + if (!tryRunOverlayCallback()) { + ViewTreeObserver observer = getViewTreeObserver(); + if (observer != null && observer.isAlive()) { + observer.addOnWindowFocusChangeListener( + new ViewTreeObserver.OnWindowFocusChangeListener() { + @Override + public void onWindowFocusChanged(boolean hasFocus) { + if (tryRunOverlayCallback() && observer.isAlive()) { + observer.removeOnWindowFocusChangeListener(this); + } + }}); + } + return true; + } + return false; } @Override