From 857b3fbb7e1cc7603139d03d46cb1d08c737a338 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 10 Jul 2019 11:04:40 -0700 Subject: [PATCH 01/34] Fix bug where app icons are clipped when transitioning from app to home. Bug: 135636137 Change-Id: Icaba06ed27b3196371730a5a4c5d3382cedc7000 --- .../util/StaggeredWorkspaceAnim.java | 40 +++++++++++++++++-- .../launcher3/anim/SpringObjectAnimator.java | 5 ++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 07e96869ed..45d12fd77e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -16,6 +16,8 @@ package com.android.quickstep.util; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.view.View; import android.view.ViewGroup; @@ -29,6 +31,7 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; +import com.android.launcher3.Workspace; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.SpringObjectAnimator; @@ -79,9 +82,19 @@ public class StaggeredWorkspaceAnim { .getDimensionPixelSize(R.dimen.swipe_up_max_workspace_trans_y); DeviceProfile grid = launcher.getDeviceProfile(); - ShortcutAndWidgetContainer currentPage = ((CellLayout) launcher.getWorkspace() - .getChildAt(launcher.getWorkspace().getCurrentPage())) - .getShortcutsAndWidgets(); + Workspace workspace = launcher.getWorkspace(); + CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage()); + ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets(); + + boolean workspaceClipChildren = workspace.getClipChildren(); + boolean workspaceClipToPadding = workspace.getClipToPadding(); + boolean cellLayoutClipChildren = cellLayout.getClipChildren(); + boolean cellLayoutClipToPadding = cellLayout.getClipToPadding(); + + workspace.setClipChildren(false); + workspace.setClipToPadding(false); + cellLayout.setClipChildren(false); + cellLayout.setClipToPadding(false); // Hotseat and QSB takes up two additional rows. int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2); @@ -111,6 +124,27 @@ public class StaggeredWorkspaceAnim { addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0); addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS); + + AnimatorListener resetClipListener = new AnimatorListenerAdapter() { + int numAnimations = mAnimators.size(); + + @Override + public void onAnimationEnd(Animator animation) { + numAnimations--; + if (numAnimations > 0) { + return; + } + + workspace.setClipChildren(workspaceClipChildren); + workspace.setClipToPadding(workspaceClipToPadding); + cellLayout.setClipChildren(cellLayoutClipChildren); + cellLayout.setClipToPadding(cellLayoutClipToPadding); + } + }; + + for (Animator a : mAnimators) { + a.addListener(resetClipListener); + } } /** diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java index 395fed259a..91a31069c1 100644 --- a/src/com/android/launcher3/anim/SpringObjectAnimator.java +++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java @@ -96,7 +96,10 @@ public class SpringObjectAnimator extends ValueAnimator { } }); - mSpring.addUpdateListener((animation, value, velocity) -> mSpringEnded = false); + mSpring.addUpdateListener((animation, value, velocity) -> { + mSpringEnded = false; + mEnded = false; + }); mSpring.addEndListener((animation, canceled, value, velocity) -> { mSpringEnded = true; tryEnding(); From cabbaf986cacfc7eeb40eaae549658e9e594368e Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 10 Jul 2019 14:14:23 -0700 Subject: [PATCH 02/34] Fix bug where floating icon and workspace icon visible at the same time. - Add a signal for the animation to be "cancelled" - Allow the workspace view to be attached to a spring during the animatoin (but kept hidden) to prevent any jumpy movement Bug: 137215697 Change-Id: Ie6868a7f45fefaee5366c8d30bb323fe042e9156 --- .../WindowTransformSwipeHandler.java | 82 +++++++++++++------ .../quickstep/util/RectFSpringAnim.java | 11 +++ .../util/StaggeredWorkspaceAnim.java | 8 +- .../launcher3/views/FloatingIconView.java | 5 +- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..f8e0c245e9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -871,7 +871,7 @@ public class WindowTransformSwipeHandler @UiThread private InputConsumer createNewInputProxyHandler() { - endRunningWindowAnim(); + endRunningWindowAnim(true /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden @@ -883,9 +883,13 @@ public class WindowTransformSwipeHandler ? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true); } - private void endRunningWindowAnim() { + private void endRunningWindowAnim(boolean cancel) { if (mRunningWindowAnim != null) { - mRunningWindowAnim.end(); + if (cancel) { + mRunningWindowAnim.cancel(); + } else { + mRunningWindowAnim.end(); + } } } @@ -1177,27 +1181,37 @@ public class WindowTransformSwipeHandler // We want the window alpha to be 0 once this threshold is met, so that the // FolderIconView can be seen morphing into the icon shape. final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f; - anim.addOnUpdateListener((currentRect, progress) -> { - homeAnim.setPlayFraction(progress); + anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() { + @Override + public void onUpdate(RectF currentRect, float progress) { + homeAnim.setPlayFraction(progress); - float alphaProgress = ACCEL_1_5.getInterpolation(progress); - float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, - windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); - mTransformParams.setProgress(progress) - .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); - if (isFloatingIconView) { - mTransformParams.setCornerRadius(endRadius * progress + startRadius - * (1f - progress)); - } - mClipAnimationHelper.applyTransform(targetSet, mTransformParams, - false /* launcherOnTop */); + float alphaProgress = ACCEL_1_5.getInterpolation(progress); + float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, + windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); + mTransformParams.setProgress(progress) + .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); + if (isFloatingIconView) { + mTransformParams.setCornerRadius(endRadius * progress + startRadius + * (1f - progress)); + } + mClipAnimationHelper.applyTransform(targetSet, mTransformParams, + false /* launcherOnTop */); - if (isFloatingIconView) { - ((FloatingIconView) floatingView).update(currentRect, 1f, progress, - windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); + if (isFloatingIconView) { + ((FloatingIconView) floatingView).update(currentRect, 1f, progress, + windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); + } + + updateSysUiFlags(Math.max(progress, mCurrentShift.value)); } - updateSysUiFlags(Math.max(progress, mCurrentShift.value)); + @Override + public void onCancel() { + if (isFloatingIconView) { + ((FloatingIconView) floatingView).fastFinish(); + } + } }); anim.addAnimatorListener(new AnimationSuccessListener() { @Override @@ -1306,7 +1320,7 @@ public class WindowTransformSwipeHandler } private void invalidateHandler() { - endRunningWindowAnim(); + endRunningWindowAnim(false /* cancel */); if (mGestureEndCallback != null) { mGestureEndCallback.run(); @@ -1471,12 +1485,34 @@ public class WindowTransformSwipeHandler private interface RunningWindowAnim { void end(); + void cancel(); + static RunningWindowAnim wrap(Animator animator) { - return animator::end; + return new RunningWindowAnim() { + @Override + public void end() { + animator.end(); + } + + @Override + public void cancel() { + animator.cancel(); + } + }; } static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) { - return rectFSpringAnim::end; + return new RunningWindowAnim() { + @Override + public void end() { + rectFSpringAnim.end(); + } + + @Override + public void cancel() { + rectFSpringAnim.cancel(); + } + }; } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 77dc6f32e7..9c5cf2042b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -225,7 +225,18 @@ public class RectFSpringAnim { } } + public void cancel() { + if (mAnimsStarted) { + for (OnUpdateListener onUpdateListener : mOnUpdateListeners) { + onUpdateListener.onCancel(); + } + } + end(); + } + public interface OnUpdateListener { void onUpdate(RectF currentRect, float progress); + + void onCancel(); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 07e96869ed..bb6892ade7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -134,10 +134,6 @@ public class StaggeredWorkspaceAnim { * @param totalRows Total number of rows. */ private void addStaggeredAnimationForView(View v, int row, int totalRows) { - if (v == mViewToIgnore) { - return; - } - // Invert the rows, because we stagger starting from the bottom of the screen. int invertedRow = totalRows - row; // Add 1 to the inverted row so that the bottom most row has a start delay. @@ -149,6 +145,10 @@ public class StaggeredWorkspaceAnim { springTransY.setStartDelay(startDelay); mAnimators.add(springTransY); + if (v == mViewToIgnore) { + return; + } + v.setAlpha(0); ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f); alpha.setInterpolator(LINEAR); diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index ab4b576bf9..4fdd83b657 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -656,8 +656,7 @@ public class FloatingIconView extends View implements canvas.restoreToCount(count); } - public void onListenerViewClosed() { - // Fast finish here. + public void fastFinish() { if (mEndRunnable != null) { mEndRunnable.run(); mEndRunnable = null; @@ -757,7 +756,7 @@ public class FloatingIconView extends View implements view.setVisibility(INVISIBLE); parent.addView(view); dragLayer.addView(view.mListenerView); - view.mListenerView.setListener(view::onListenerViewClosed); + view.mListenerView.setListener(view::fastFinish); view.mEndRunnable = () -> { view.mEndRunnable = null; From 4d93df51a348125f2f85d310bb555e39d35be7b2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 10 Jul 2019 17:32:58 -0700 Subject: [PATCH 03/34] Switching flinging gestures injection to model time This is a right thing to do in any case. Change-Id: I34eeecac6d9eb13130eb1015f9a9a5e2a32974ec --- src/com/android/launcher3/PagedView.java | 2 ++ .../com/android/launcher3/tapl/BaseOverview.java | 12 ++++++------ .../launcher3/tapl/LauncherInstrumentation.java | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index f8e4c9dfc7..bd52ffe4b2 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -47,6 +47,7 @@ import android.view.animation.Interpolator; import android.widget.ScrollView; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.pageindicators.PageIndicator; import com.android.launcher3.touch.OverScroll; @@ -367,6 +368,7 @@ public abstract class PagedView extends ViewGrou */ protected void onPageEndTransition() { mWasInOverscroll = false; + AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext()); } protected int getUnboundedScrollX() { diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index ace49e9cea..ae93867191 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -16,6 +16,8 @@ package com.android.launcher3.tapl; +import android.graphics.Rect; + import androidx.annotation.NonNull; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; @@ -49,9 +51,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling forward in overview")) { LauncherInstrumentation.log("Overview.flingForward before fling"); final UiObject2 overview = verifyActiveContainer(); - overview.setGestureMargins(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0); - overview.fling(Direction.LEFT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); - mLauncher.waitForIdle(); + mLauncher.scroll(overview, Direction.LEFT, 1, + new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0), 20); verifyActiveContainer(); } } @@ -86,9 +87,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling backward in overview")) { LauncherInstrumentation.log("Overview.flingBackward before fling"); final UiObject2 overview = verifyActiveContainer(); - overview.setGestureMargins(0, 0, mLauncher.getEdgeSensitivityWidth(), 0); - overview.fling(Direction.RIGHT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); - mLauncher.waitForIdle(); + mLauncher.scroll(overview, Direction.RIGHT, 1, + new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0), 20); verifyActiveContainer(); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 11b0665d95..72fc31903c 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -820,6 +820,22 @@ public final class LauncherInstrumentation { endY = (int) (vertCenter - halfGestureHeight); } break; + case LEFT: { + startY = endY = rect.centerY(); + final int horizCenter = rect.centerX(); + final float halfGestureWidth = rect.width() * percent / 2.0f; + startX = (int) (horizCenter - halfGestureWidth); + endX = (int) (horizCenter + halfGestureWidth); + } + break; + case RIGHT: { + startY = endY = rect.centerY(); + final int horizCenter = rect.centerX(); + final float halfGestureWidth = rect.width() * percent / 2.0f; + startX = (int) (horizCenter + halfGestureWidth); + endX = (int) (horizCenter - halfGestureWidth); + } + break; default: fail("Unsupported direction"); return; From f11dd8e1077ca229e228afd6a39e7b22d12105f7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 10 Jul 2019 14:05:58 -0700 Subject: [PATCH 04/34] Using a higher priority executor than BackgroundExecutor for various recents tasks BackgroundExecutor is also using thread pool executor where the order is perserved Change-Id: Ieef8825599f35fe22da3e9adb1270c5525449d62 --- .../quickstep/TouchInteractionService.java | 5 +++++ .../quickstep/TouchInteractionService.java | 18 +++++++----------- .../DeviceLockedInputConsumer.java | 7 ++----- .../FallbackNoButtonInputConsumer.java | 6 ++---- .../OtherActivityInputConsumer.java | 6 ++---- .../android/quickstep/views/RecentsView.java | 4 ++-- .../com/android/quickstep/RecentTasksList.java | 9 ++++----- 7 files changed, 24 insertions(+), 31 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 900b94e186..c902826ed8 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -34,6 +34,8 @@ import android.view.MotionEvent; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.util.LooperExecutor; +import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -137,6 +139,9 @@ public class TouchInteractionService extends Service { return sConnected; } + public static final LooperExecutor BACKGROUND_EXECUTOR = + new LooperExecutor(UiThreadHelper.getBackgroundLooper()); + private RecentsModel mRecentsModel; private OverviewComponentObserver mOverviewComponentObserver; private OverviewCommandHelper mOverviewCommandHelper; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index bf9d531061..0ef2f5c5ad 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -43,7 +43,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.RectF; @@ -95,12 +94,12 @@ import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; +import com.android.systemui.shared.system.RecentsAnimationListener; import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; import java.io.FileDescriptor; @@ -124,10 +123,6 @@ class ArgList extends LinkedList { public String nextArg() { return pollFirst().toLowerCase(); } - - public String nextArgExact() { - return pollFirst(); - } } /** @@ -714,11 +709,7 @@ public class TouchInteractionService extends Service implements } // Pass null animation handler to indicate this start is preload. - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), - null /* assistDataReceiver */, null /* animationHandler */, - null /* resultCallback */, null /* resultCallbackHandler */)); + startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), null); } @Override @@ -796,4 +787,9 @@ public class TouchInteractionService extends Service implements break; } } + + public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { + BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() + .startRecentsActivity(intent, null, listener, null, null)); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index db2af59aca..3d763ab52c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -23,6 +23,7 @@ import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import android.content.ComponentName; import android.content.Context; @@ -44,8 +45,6 @@ import com.android.quickstep.SwipeSharedState; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -209,9 +208,7 @@ public class DeviceLockedInputConsumer implements InputConsumer, .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mInputMonitorCompat.pilferPointers(); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - intent, null, newListenerSet, null, null)); + startRecentsActivityAsync(intent, newListenerSet); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index d05ca2a161..d17bba49b5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -27,6 +27,7 @@ import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATI import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_SWIPE_DURATION; import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; @@ -56,7 +57,6 @@ import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -222,9 +222,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mSwipeSharedState.newRecentsAnimationListenerSet(); listenerSet.addListener(this); Intent homeIntent = mOverviewComponentObserver.getHomeIntent(); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - homeIntent, null, listenerSet, null, null)); + startRecentsActivityAsync(homeIntent, listenerSet); ActivityManagerWrapper.getInstance().closeSystemWindows( CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 4c137d3bf9..a4d2f39d29 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -28,6 +28,7 @@ import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.util.RaceConditionTracker.ENTER; import static com.android.launcher3.util.RaceConditionTracker.EXIT; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.annotation.TargetApi; @@ -61,7 +62,6 @@ import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; @@ -352,9 +352,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RecentsAnimationListenerSet newListenerSet = mSwipeSharedState.newRecentsAnimationListenerSet(); newListenerSet.addListener(handler); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - mHomeIntent, null, newListenerSet, null, null)); + startRecentsActivityAsync(mHomeIntent, newListenerSet); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 6a9abd5455..432f8a1355 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -37,6 +37,7 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; +import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.animation.Animator; import android.animation.AnimatorSet; @@ -108,7 +109,6 @@ import com.android.quickstep.util.ClipAnimationHelper; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.LauncherEventUtil; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; @@ -226,7 +226,7 @@ public abstract class RecentsView extends PagedView impl return; } - BackgroundExecutor.get().submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { TaskView taskView = getTaskView(taskId); if (taskView == null) { return; diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index f27ba85388..7a1d0e83f6 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -16,6 +16,8 @@ package com.android.quickstep; +import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; + import android.annotation.TargetApi; import android.app.ActivityManager; import android.content.Context; @@ -25,7 +27,6 @@ import android.util.SparseBooleanArray; import com.android.launcher3.MainThreadExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.KeyguardManagerCompat; import com.android.systemui.shared.system.RecentTaskInfoCompat; import com.android.systemui.shared.system.TaskDescriptionCompat; @@ -43,7 +44,6 @@ public class RecentTasksList extends TaskStackChangeListener { private final KeyguardManagerCompat mKeyguardManager; private final MainThreadExecutor mMainThreadExecutor; - private final BackgroundExecutor mBgThreadExecutor; // The list change id, increments as the task list changes in the system private int mChangeId; @@ -56,7 +56,6 @@ public class RecentTasksList extends TaskStackChangeListener { public RecentTasksList(Context context) { mMainThreadExecutor = new MainThreadExecutor(); - mBgThreadExecutor = BackgroundExecutor.get(); mKeyguardManager = new KeyguardManagerCompat(context); mChangeId = 1; ActivityManagerWrapper.getInstance().registerTaskStackListener(this); @@ -67,7 +66,7 @@ public class RecentTasksList extends TaskStackChangeListener { */ public void getTaskKeys(int numTasks, Consumer> callback) { // Kick off task loading in the background - mBgThreadExecutor.submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */); mMainThreadExecutor.execute(() -> callback.accept(tasks)); }); @@ -93,7 +92,7 @@ public class RecentTasksList extends TaskStackChangeListener { } // Kick off task loading in the background - mBgThreadExecutor.submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly); mMainThreadExecutor.execute(() -> { From 6b0eb38461ac061bd9a3281c205a45d8f3faa9f2 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 9 Jul 2019 17:30:22 -0700 Subject: [PATCH 05/34] Swipe-up support for 3P Launcher On swipe up, we start a rencets transition to the current launcher app. At the end of the transition, if the user is going to recents, we start overview activity. Bug: 137197916 Change-Id: Ie5ed848879ad965dcab2780a05d649e3be066568 --- quickstep/AndroidManifest.xml | 1 + .../android/quickstep/BaseSwipeUpHandler.java | 101 +++++++++ .../android/quickstep/RecentsActivity.java | 21 ++ .../WindowTransformSwipeHandler.java | 69 +----- .../FallbackNoButtonInputConsumer.java | 199 ++++++++++++------ .../quickstep/util/ClipAnimationHelper.java | 28 ++- .../android/quickstep/util/ObjectWrapper.java | 41 ++++ 7 files changed, 325 insertions(+), 135 deletions(-) create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index 332e0fa360..546548036e 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -23,6 +23,7 @@ package="com.android.launcher3" > + mVibrator.vibrate(effect)); + } + + protected float getShiftForDisplacement(float displacement) { + // We are moving in the negative x/y direction + displacement = -displacement; + if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { + return mDragLengthFactor; + } else { + float translation = Math.max(displacement, 0); + float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; + if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { + float pullbackProgress = Utilities.getProgress(shift, + DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); + pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress); + shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress + * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); + } + return shift; + } + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index fc29a5663b..52e8ba26d0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -28,8 +28,10 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.app.ActivityOptions; +import android.content.Intent; import android.content.res.Configuration; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.view.View; @@ -42,7 +44,9 @@ import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsRootView; import com.android.quickstep.util.ClipAnimationHelper; +import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; @@ -54,6 +58,9 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; */ public final class RecentsActivity extends BaseRecentsActivity { + public static final String EXTRA_THUMBNAIL = "thumbnailData"; + public static final String EXTRA_TASK_ID = "taskID"; + private Handler mUiHandler = new Handler(Looper.getMainLooper()); private RecentsRootView mRecentsRootView; private FallbackRecentsView mFallbackRecentsView; @@ -78,6 +85,20 @@ public final class RecentsActivity extends BaseRecentsActivity { } } + @Override + protected void onNewIntent(Intent intent) { + int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); + IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); + if (taskID != 0 && thumbnail instanceof ObjectWrapper) { + ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); + mFallbackRecentsView.showCurrentTask(taskID); + mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + } + intent.removeExtra(EXTRA_TASK_ID); + intent.removeExtra(EXTRA_THUMBNAIL); + super.onNewIntent(intent); + } + @Override protected void onHandleConfigChanged() { super.onHandleConfigChanged(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..da9c6cb5fe 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -43,7 +43,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_O import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.TargetApi; @@ -59,7 +58,6 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; -import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; @@ -97,7 +95,7 @@ import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer; -import com.android.quickstep.util.ClipAnimationHelper; +import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; @@ -112,11 +110,10 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import java.util.function.BiFunction; import java.util.function.Consumer; @TargetApi(Build.VERSION_CODES.O) -public class WindowTransformSwipeHandler +public class WindowTransformSwipeHandler extends BaseSwipeUpHandler implements SwipeAnimationListener, OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); @@ -220,30 +217,17 @@ public class WindowTransformSwipeHandler private static final long SHELF_ANIM_DURATION = 240; public static final long RECENTS_ATTACH_DURATION = 300; - // Start resisting when swiping past this factor of mTransitionDragLength. - private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; - // This is how far down we can scale down, where 0f is full screen and 1f is recents. - private static final float DRAG_LENGTH_FACTOR_MAX_PULLBACK = 1.8f; - private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL; - /** * Used as the page index for logging when we return to the last task at the end of the gesture. */ private static final int LOG_NO_OP_PAGE_INDEX = -1; - private final ClipAnimationHelper mClipAnimationHelper; - private final ClipAnimationHelper.TransformParams mTransformParams; - private Runnable mGestureEndCallback; private GestureEndTarget mGestureEndTarget; // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; - // The distance needed to drag to reach the task size in recents. - private int mTransitionDragLength; - // How much further we can drag past recents, as a factor of mTransitionDragLength. - private float mDragLengthFactor = 1; // Shift in the range of [0, 1]. // 0 => preview snapShot is completely visible, and hotseat is completely translated down @@ -256,7 +240,6 @@ public class WindowTransformSwipeHandler private final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); - private final Context mContext; private final ActivityControlHelper mActivityControlHelper; private final ActivityInitListener mActivityInitListener; @@ -294,7 +277,7 @@ public class WindowTransformSwipeHandler public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, InputConsumerController inputConsumer) { - mContext = context; + super(context); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; mActivityControlHelper = controller; @@ -303,8 +286,6 @@ public class WindowTransformSwipeHandler mContinuingLastGesture = continuingLastGesture; mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, this::createNewInputProxyHandler); - mClipAnimationHelper = new ClipAnimationHelper(context); - mTransformParams = new ClipAnimationHelper.TransformParams(); mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); @@ -394,18 +375,6 @@ public class WindowTransformSwipeHandler } } - private long getFadeInDuration() { - if (mCurrentShift.getCurrentAnimation() != null) { - ObjectAnimator anim = mCurrentShift.getCurrentAnimation(); - long theirDuration = anim.getDuration() - anim.getCurrentPlayTime(); - - // TODO: Find a better heuristic - return Math.min(MAX_SWIPE_DURATION, Math.max(theirDuration, MIN_SWIPE_DURATION)); - } else { - return MAX_SWIPE_DURATION; - } - } - public void initWhenReady() { mActivityInitListener.register(); } @@ -583,22 +552,7 @@ public class WindowTransformSwipeHandler @UiThread public void updateDisplacement(float displacement) { - // We are moving in the negative x/y direction - displacement = -displacement; - if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { - mCurrentShift.updateValue(mDragLengthFactor); - } else { - float translation = Math.max(displacement, 0); - float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; - if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { - float pullbackProgress = Utilities.getProgress(shift, - DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); - pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress); - shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress - * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); - } - mCurrentShift.updateValue(shift); - } + mCurrentShift.updateValue(getShiftForDisplacement(displacement)); } public void onMotionPauseChanged(boolean isPaused) { @@ -666,9 +620,8 @@ public class WindowTransformSwipeHandler if (mIsShelfPeeking != wasShelfPeeking) { maybeUpdateRecentsAttachedState(); } - if (mRecentsView != null && shelfState.shouldPreformHaptic) { - mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + if (shelfState.shouldPreformHaptic) { + performHapticFeedback(); } } @@ -722,9 +675,8 @@ public class WindowTransformSwipeHandler final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW; if (passed != mPassedOverviewThreshold) { mPassedOverviewThreshold = passed; - if (mRecentsView != null && mMode != Mode.NO_BUTTON) { - mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + if (mMode != Mode.NO_BUTTON) { + performHapticFeedback(); } } @@ -1450,13 +1402,12 @@ public class WindowTransformSwipeHandler mGestureEndCallback = gestureEndCallback; } - private void setTargetAlphaProvider( - BiFunction provider) { + private void setTargetAlphaProvider(TargetAlphaProvider provider) { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); } - public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) { + public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, float expectedAlpha) { if (!isNotInRecents(app)) { return 0; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index d17bba49b5..cdd91b78f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -23,22 +23,27 @@ import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.INVALID_POINTER_ID; -import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION; +import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; +import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; -import static com.android.quickstep.WindowTransformSwipeHandler.MIN_SWIPE_DURATION; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; +import android.animation.AnimatorSet; import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; +import android.os.Bundle; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.ViewConfiguration; @@ -48,38 +53,50 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.quickstep.ActivityControlHelper; +import com.android.quickstep.AnimatedFloat; +import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.SwipeSharedState; -import com.android.quickstep.util.ClipAnimationHelper; -import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; +import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; +import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimationListener { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler + implements InputConsumer, SwipeAnimationListener { - private static final int STATE_NOT_FINISHED = 0; - private static final int STATE_FINISHED_TO_HOME = 1; - private static final int STATE_FINISHED_TO_APP = 2; + public enum GestureEndTarget { + HOME(3, 100, 1), + RECENTS(1, 300, 0), + LAST_TASK(0, 150, 1); - private static final float PROGRESS_TO_END_GESTURE = -2; + private final float mEndProgress; + private final long mDurationMultiplier; + private final float mLauncherAlpha; + GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { + mEndProgress = endProgress; + mDurationMultiplier = durationMultiplier; + mLauncherAlpha = launcherAlpha; + } + } private final ActivityControlHelper mActivityControlHelper; private final InputMonitorCompat mInputMonitor; - private final Context mContext; private final NavBarPosition mNavBarPosition; private final SwipeSharedState mSwipeSharedState; private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; - private final ClipAnimationHelper mClipAnimationHelper; - private final TransformParams mTransformParams = new TransformParams(); - private final float mTransitionDragLength; private final DeviceProfile mDP; + private final MotionPauseDetector mMotionPauseDetector; + private final float mMotionPauseMinDisplacement; + private final Rect mTargetRect = new Rect(); private final RectF mSwipeTouchRegion; private final boolean mDisableHorizontalSwipe; @@ -87,6 +104,9 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); + private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); + private final AnimatedFloat mProgress = new AnimatedFloat(this::onProgressChanged); + private int mActivePointerId = -1; // Slop used to determine when we say that the gesture has started. private boolean mPassedPilferInputSlop; @@ -99,21 +119,26 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. private float mStartDisplacement; private SwipeAnimationTargetSet mSwipeAnimationTargetSet; - private float mProgress; - private int mState = STATE_NOT_FINISHED; + private boolean mIsMotionPaused = false; + private GestureEndTarget mEndTarget; public FallbackNoButtonInputConsumer(Context context, ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor, SwipeSharedState swipeSharedState, RectF swipeTouchRegion, OverviewComponentObserver overviewComponentObserver, boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) { - mContext = context; + super(context); mActivityControlHelper = activityControlHelper; mInputMonitor = inputMonitor; mOverviewComponentObserver = overviewComponentObserver; mRunningTaskId = runningTaskInfo.id; + mMotionPauseDetector = new MotionPauseDetector(context); + mMotionPauseMinDisplacement = context.getResources().getDimension( + R.dimen.motion_pause_detector_min_displacement_from_app); + mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged); + mSwipeSharedState = swipeSharedState; mSwipeTouchRegion = swipeTouchRegion; mDisableHorizontalSwipe = disableHorizontalSwipe; @@ -124,13 +149,11 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop(); - mClipAnimationHelper = new ClipAnimationHelper(context); - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); - Rect tempRect = new Rect(); - mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - mDP, context, tempRect); - mClipAnimationHelper.updateTargetRect(tempRect); + mLauncherAlpha.value = 1; + + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + initTransitionTarget(); } @Override @@ -138,6 +161,19 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat return TYPE_FALLBACK_NO_BUTTON; } + private void onLauncherAlphaChanged() { + if (mSwipeAnimationTargetSet != null && mEndTarget == null) { + mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + } + } + + private void onMotionPauseChanged(boolean isPaused) { + mIsMotionPaused = isPaused; + mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) + .setDuration(150).start(); + performHapticFeedback(); + } + @Override public void onMotionEvent(MotionEvent ev) { if (mVelocityTracker == null) { @@ -147,6 +183,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mVelocityTracker.addMovement(ev); if (ev.getActionMasked() == ACTION_POINTER_UP) { mVelocityTracker.clear(); + mMotionPauseDetector.clear(); } switch (ev.getActionMasked()) { @@ -204,6 +241,9 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat } } else { updateDisplacement(displacement - mStartDisplacement); + mMotionPauseDetector.setDisallowPause( + -displacement < mMotionPauseMinDisplacement); + mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); } break; } @@ -230,9 +270,11 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat } private void updateDisplacement(float displacement) { - mProgress = displacement / mTransitionDragLength; - mTransformParams.setProgress(mProgress); + mProgress.updateValue(getShiftForDisplacement(displacement)); + } + private void onProgressChanged() { + mTransformParams.setProgress(mProgress.value); if (mSwipeAnimationTargetSet != null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } @@ -251,7 +293,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat */ private void finishTouchTracking(MotionEvent ev) { if (ev.getAction() == ACTION_CANCEL) { - mState = STATE_FINISHED_TO_APP; + mEndTarget = LAST_TASK; } else { mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity()); @@ -264,53 +306,68 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat .getDimension(R.dimen.quickstep_fling_threshold_velocity); boolean isFling = Math.abs(velocity) > flingThreshold; - boolean goingHome; - if (!isFling) { - goingHome = -mProgress >= MIN_PROGRESS_FOR_OVERVIEW; + if (isFling) { + mEndTarget = velocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; } else { - goingHome = velocity < 0; - } - - if (goingHome) { - mState = STATE_FINISHED_TO_HOME; - } else { - mState = STATE_FINISHED_TO_APP; + mEndTarget = mProgress.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; } } if (mSwipeAnimationTargetSet != null) { finishAnimationTargetSet(); } + mMotionPauseDetector.clear(); + } + + private void finishAnimationTargetSetAnimationComplete() { + switch (mEndTarget) { + case HOME: + mSwipeAnimationTargetSet.finishController(true, null, true); + break; + case LAST_TASK: + mSwipeAnimationTargetSet.finishController(false, null, false); + break; + case RECENTS: { + ThumbnailData thumbnail = + mSwipeAnimationTargetSet.controller.screenshotTask(mRunningTaskId); + mSwipeAnimationTargetSet.controller.setCancelWithDeferredScreenshot(true); + + ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); + Bundle extras = new Bundle(); + extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail)); + extras.putInt(EXTRA_TASK_ID, mRunningTaskId); + + Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent()) + .putExtras(extras); + mContext.startActivity(intent, options.toBundle()); + mSwipeAnimationTargetSet.controller.cleanupScreenshot(); + break; + } + } } private void finishAnimationTargetSet() { - if (mState == STATE_FINISHED_TO_APP) { - mSwipeAnimationTargetSet.finishController(false, null, false); - } else { - if (mProgress < PROGRESS_TO_END_GESTURE) { - mSwipeAnimationTargetSet.finishController(true, null, true); - } else { - long duration = (long) (Math.min(mProgress - PROGRESS_TO_END_GESTURE, 1) - * MAX_SWIPE_DURATION / Math.abs(PROGRESS_TO_END_GESTURE)); - if (duration < 0) { - duration = MIN_SWIPE_DURATION; - } + float endProgress = mEndTarget.mEndProgress; - ValueAnimator anim = ValueAnimator.ofFloat(mProgress, PROGRESS_TO_END_GESTURE); - anim.addUpdateListener(a -> { - float p = (Float) anim.getAnimatedValue(); - mTransformParams.setProgress(p); - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); - }); - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mSwipeAnimationTargetSet.finishController(true, null, true); - } - }); - anim.start(); - } + if (mProgress.value != endProgress) { + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue( + mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); + anim.play(mProgress.animateToValue(mProgress.value, endProgress)); + + anim.setDuration((long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mProgress.value))); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + finishAnimationTargetSetAnimationComplete(); + } + }); + anim.start(); + } else { + finishAnimationTargetSetAnimationComplete(); } } @@ -321,21 +378,29 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); mDP.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + if (targetSet.homeContentInsets != null) { + mDP.updateInsets(targetSet.homeContentInsets); + } + if (runningTaskTarget != null) { mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); } mClipAnimationHelper.prepareAnimation(mDP, false /* isOpening */); - - overviewStackBounds - .inset(-overviewStackBounds.width() / 5, -overviewStackBounds.height() / 5); - mClipAnimationHelper.updateTargetRect(overviewStackBounds); + initTransitionTarget(); mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); - if (mState != STATE_NOT_FINISHED) { + if (mEndTarget != null) { finishAnimationTargetSet(); } } + private void initTransitionTarget() { + mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( + mDP, mContext, mTargetRect); + mDragLengthFactor = (float) mDP.heightPx / mTransitionDragLength; + mClipAnimationHelper.updateTargetRect(mTargetRect); + } + @Override public void onRecentsAnimationCanceled() { } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index de671e04aa..f0a290333c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -99,8 +99,8 @@ public class ClipAnimationHelper { // Whether to boost the opening animation target layers, or the closing private int mBoostModeTargetLayers = -1; - private BiFunction mTaskAlphaCallback = - (t, a1) -> a1; + private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a; + private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1; public ClipAnimationHelper(Context context) { mWindowCornerRadius = getWindowCornerRadius(context.getResources()); @@ -187,12 +187,12 @@ public class ClipAnimationHelper { Rect crop = mTmpRect; crop.set(app.sourceContainerBounds); crop.offsetTo(0, 0); - float alpha = 1f; + float alpha; int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers); float cornerRadius = 0f; float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width(); if (app.mode == targetSet.targetMode) { - alpha = mTaskAlphaCallback.apply(app, params.targetAlpha); + alpha = mTaskAlphaCallback.getAlpha(app, params.targetAlpha); if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL); mTmpMatrix.postTranslate(app.position.x, app.position.y); @@ -214,9 +214,12 @@ public class ClipAnimationHelper { // home target. alpha = 1 - (progress * params.targetAlpha); } - } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { - crop = null; - layer = Integer.MAX_VALUE; + } else { + alpha = mBaseAlphaCallback.getAlpha(app, progress); + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { + crop = null; + layer = Integer.MAX_VALUE; + } } // Since radius is in Surface space, but we draw the rounded corners in screen space, we @@ -247,11 +250,14 @@ public class ClipAnimationHelper { } } - public void setTaskAlphaCallback( - BiFunction callback) { + public void setTaskAlphaCallback(TargetAlphaProvider callback) { mTaskAlphaCallback = callback; } + public void setBaseAlphaCallback(TargetAlphaProvider callback) { + mBaseAlphaCallback = callback; + } + public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) { fromTaskThumbnailView(ttv, rv, null); } @@ -357,6 +363,10 @@ public class ClipAnimationHelper { return mCurrentCornerRadius; } + public interface TargetAlphaProvider { + float getAlpha(RemoteAnimationTargetCompat target, float expectedAlpha); + } + public static class TransformParams { float progress; public float offsetX; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java new file mode 100644 index 0000000000..abfe3adbff --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import android.os.Binder; +import android.os.IBinder; + +/** + * Utility class to pass non-parcealable objects within same process using parcealable payload. + * + * It wraps the object in a binder as binders are singleton within a process + */ +public class ObjectWrapper extends Binder { + + private final T mObject; + + public ObjectWrapper(T object) { + mObject = object; + } + + public T get() { + return mObject; + } + + public static IBinder wrap(Object obj) { + return new ObjectWrapper<>(obj); + } +} From c127dff1812fd5059ba16cf92de608c6f79de196 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 10 Jul 2019 13:16:43 -0700 Subject: [PATCH 06/34] Unifying FallbackNoButton input consumer with OtherActivityInputConsumer using a different handler This will allow us to use common logic for handling horizontal swipe Bug: 137197916 Change-Id: I6f9cba6e8728dd0669482906c4bf34270af2bc82 --- .../android/quickstep/BaseSwipeUpHandler.java | 73 ++++- .../android/quickstep/RecentsActivity.java | 6 + .../quickstep/TouchInteractionService.java | 49 +++- .../WindowTransformSwipeHandler.java | 73 +++-- .../FallbackNoButtonInputConsumer.java | 254 +++--------------- .../inputconsumers/InputConsumer.java | 2 - .../OtherActivityInputConsumer.java | 61 ++--- 7 files changed, 193 insertions(+), 325 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 6e4a40843f..d34b604a76 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -22,22 +22,32 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.annotation.TargetApi; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.graphics.PointF; import android.os.Build; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.view.MotionEvent; import android.view.animation.Interpolator; import com.android.launcher3.Utilities; +import com.android.launcher3.graphics.RotationMode; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; +import com.android.quickstep.views.RecentsView; + +import java.util.function.Consumer; + +import androidx.annotation.UiThread; /** * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler { +public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -57,6 +67,16 @@ public abstract class BaseSwipeUpHandler { private final Vibrator mVibrator; + // Shift in the range of [0, 1]. + // 0 => preview snapShot is completely visible, and hotseat is completely translated down + // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely + // visible. + protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); + + protected RecentsView mRecentsView; + + protected Runnable mGestureEndCallback; + protected BaseSwipeUpHandler(Context context) { mContext = context; mClipAnimationHelper = new ClipAnimationHelper(context); @@ -80,14 +100,20 @@ public abstract class BaseSwipeUpHandler { BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect)); } - protected float getShiftForDisplacement(float displacement) { + public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { + return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; + } + + @UiThread + public void updateDisplacement(float displacement) { // We are moving in the negative x/y direction displacement = -displacement; + float shift; if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { - return mDragLengthFactor; + shift = mDragLengthFactor; } else { float translation = Math.max(displacement, 0); - float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; + shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { float pullbackProgress = Utilities.getProgress(shift, DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); @@ -95,7 +121,44 @@ public abstract class BaseSwipeUpHandler { shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); } - return shift; } + + mCurrentShift.updateValue(shift); + } + + public void setGestureEndCallback(Runnable gestureEndCallback) { + mGestureEndCallback = gestureEndCallback; + } + + /** + * Called when the value of {@link #mCurrentShift} changes + */ + public abstract void updateFinalShift(); + + + /** + * Called when motion pause is detected + */ + public abstract void onMotionPauseChanged(boolean isPaused); + + @UiThread + public void onGestureStarted() { } + + @UiThread + public abstract void onGestureCancelled(); + + @UiThread + public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); + + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { } + + public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } + + public void initWhenReady() { } + + public interface Factory { + + BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 52e8ba26d0..61767e5f74 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -199,6 +199,12 @@ public final class RecentsActivity extends BaseRecentsActivity { mFallbackRecentsView.resetTaskVisuals(); } + @Override + protected void onStop() { + super.onStop(); + mFallbackRecentsView.reset(); + } + public void onTaskLaunched() { mFallbackRecentsView.resetTaskVisuals(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 0ef2f5c5ad..fafa4d34ca 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -239,6 +239,11 @@ public class TouchInteractionService extends Service implements private final InputConsumer mResetGestureInputConsumer = new ResetGestureInputConsumer(sSwipeSharedState); + private final BaseSwipeUpHandler.Factory mWindowTreansformFactory = + this::createWindowTransformSwipeHandler; + private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory = + this::createFallbackNoButtonSwipeHandler; + private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; private ISystemUiProxy mISystemUiProxy; @@ -623,10 +628,6 @@ public class TouchInteractionService extends Service implements } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { return mResetGestureInputConsumer; - } else if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { - return new FallbackNoButtonInputConsumer(this, activityControl, - mInputMonitorCompat, sSwipeSharedState, mSwipeTouchRegion, - mOverviewComponentObserver, disableHorizontalSwipe(event), runningTaskInfo); } else { return createOtherActivityInputConsumer(event, runningTaskInfo); } @@ -639,17 +640,28 @@ public class TouchInteractionService extends Service implements && exclusionRegion.contains((int) event.getX(), (int) event.getY()); } - private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event, + private InputConsumer createOtherActivityInputConsumer(MotionEvent event, RunningTaskInfo runningTaskInfo) { - final ActivityControlHelper activityControl = - mOverviewComponentObserver.getActivityControlHelper(); - boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event); - return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel, - mOverviewComponentObserver.getOverviewIntent(), activityControl, - shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive, + final boolean shouldDefer; + final BaseSwipeUpHandler.Factory factory; + final Intent homeIntent; + + if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { + shouldDefer = true; + factory = mFallbackNoButtonFactory; + homeIntent = mOverviewComponentObserver.getHomeIntent(); + } else { + shouldDefer = mOverviewComponentObserver.getActivityControlHelper() + .deferStartingActivity(mActiveNavBarRegion, event); + factory = mWindowTreansformFactory; + homeIntent = mOverviewComponentObserver.getOverviewIntent(); + } + + return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent, + shouldDefer, mOverviewCallbacks, this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, - disableHorizontalSwipe(event)); + disableHorizontalSwipe(event), factory); } private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) { @@ -788,6 +800,19 @@ public class TouchInteractionService extends Service implements } } + private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new WindowTransformSwipeHandler( + runningTask, this, touchTimeMs, + mOverviewComponentObserver.getActivityControlHelper(), + continuingLastGesture, mInputConsumer, mRecentsModel); + } + + private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask); + } + public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() .startRecentsActivity(intent, null, listener, null, null)); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index da9c6cb5fe..9684eeca2f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -58,7 +58,6 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; @@ -66,10 +65,6 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.animation.Interpolator; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -79,7 +74,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -99,9 +93,7 @@ import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.LiveTileOverlay; -import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; @@ -110,11 +102,12 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import java.util.function.Consumer; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler extends BaseSwipeUpHandler - implements SwipeAnimationListener, OnApplyWindowInsetsListener { + implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); private static final Rect TEMP_RECT = new Rect(); @@ -222,18 +215,12 @@ public class WindowTransformSwipeHandler extends */ private static final int LOG_NO_OP_PAGE_INDEX = -1; - private Runnable mGestureEndCallback; private GestureEndTarget mGestureEndTarget; // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; - // Shift in the range of [0, 1]. - // 0 => preview snapShot is completely visible, and hotseat is completely translated down - // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely - // visible. - private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); private boolean mContinuingLastGesture; // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; @@ -242,6 +229,7 @@ public class WindowTransformSwipeHandler extends private final ActivityControlHelper mActivityControlHelper; private final ActivityInitListener mActivityInitListener; + private final RecentsModel mRecentsModel; private final SysUINavigationMode.Mode mMode; @@ -254,7 +242,6 @@ public class WindowTransformSwipeHandler extends private boolean mHasLauncherTransitionControllerStarted; private T mActivity; - private RecentsView mRecentsView; private AnimationFactory mAnimationFactory = (t) -> { }; private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay(); @@ -276,11 +263,12 @@ public class WindowTransformSwipeHandler extends public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, - InputConsumerController inputConsumer) { + InputConsumerController inputConsumer, RecentsModel recentsModel) { super(context); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; mActivityControlHelper = controller; + mRecentsModel = recentsModel; mActivityInitListener = mActivityControlHelper .createActivityInitListener(this::onActivityInit); mContinuingLastGesture = continuingLastGesture; @@ -375,7 +363,11 @@ public class WindowTransformSwipeHandler extends } } + @Override public void initWhenReady() { + // Preload the plan + mRecentsModel.getTasks(null); + mActivityInitListener.register(); } @@ -546,15 +538,7 @@ public class WindowTransformSwipeHandler extends return TaskView.getCurveScaleForInterpolation(interpolation); } - public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { - return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; - } - - @UiThread - public void updateDisplacement(float displacement) { - mCurrentShift.updateValue(getShiftForDisplacement(displacement)); - } - + @Override public void onMotionPauseChanged(boolean isPaused) { setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); } @@ -605,6 +589,7 @@ public class WindowTransformSwipeHandler extends mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); } + @Override public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; @@ -651,7 +636,8 @@ public class WindowTransformSwipeHandler extends } @UiThread - private void updateFinalShift() { + @Override + public void updateFinalShift() { float shift = mCurrentShift.value; SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); @@ -766,7 +752,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("cancelRecentsAnimation"); } - @UiThread + @Override public void onGestureStarted() { notifyGestureStartedAsync(); mShiftAtGestureStart = mCurrentShift.value; @@ -790,7 +776,7 @@ public class WindowTransformSwipeHandler extends /** * Called as a result on ACTION_CANCEL to return the UI to the start state. */ - @UiThread + @Override public void onGestureCancelled() { updateDisplacement(0); setStateOnUiThread(STATE_GESTURE_COMPLETED); @@ -803,7 +789,7 @@ public class WindowTransformSwipeHandler extends * @param velocity The x and y components of the velocity when the gesture ends. * @param downPos The x and y value of where the gesture started. */ - @UiThread + @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { float flingThreshold = mContext.getResources() .getDimension(R.dimen.quickstep_fling_threshold_velocity); @@ -1174,11 +1160,18 @@ public class WindowTransformSwipeHandler extends return anim; } - /** - * @return The GestureEndTarget if the gesture has ended, else null. - */ - public @Nullable GestureEndTarget getGestureEndTarget() { - return mGestureEndTarget; + @Override + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { + if (mGestureEndTarget != null) { + sharedState.canGestureBeContinued = mGestureEndTarget.canBeContinued; + sharedState.goingToLauncher = mGestureEndTarget.isLauncher; + } + + if (sharedState.canGestureBeContinued) { + cancelCurrentAnimation(sharedState); + } else { + reset(); + } } @UiThread @@ -1227,7 +1220,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); } - public void reset() { + private void reset() { setStateOnUiThread(STATE_HANDLER_INVALIDATED); } @@ -1235,7 +1228,7 @@ public class WindowTransformSwipeHandler extends * Cancels any running animation so that the active target can be overriden by a new swipe * handle (in case of quick switch). */ - public void cancelCurrentAnimation(SwipeSharedState sharedState) { + private void cancelCurrentAnimation(SwipeSharedState sharedState) { mCanceled = true; mCurrentShift.cancelAnimation(); if (mLauncherTransitionController != null && mLauncherTransitionController @@ -1398,10 +1391,6 @@ public class WindowTransformSwipeHandler extends reset(); } - public void setGestureEndCallback(Runnable gestureEndCallback) { - mGestureEndCallback = gestureEndCallback; - } - private void setTargetAlphaProvider(TargetAlphaProvider provider) { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index cdd91b78f4..a5a8f388f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -15,23 +15,12 @@ */ package com.android.quickstep.inputconsumers; -import static android.view.MotionEvent.ACTION_CANCEL; -import static android.view.MotionEvent.ACTION_DOWN; -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 android.view.MotionEvent.INVALID_POINTER_ID; - import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; -import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; -import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; -import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -42,11 +31,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Bundle; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.ViewConfiguration; import android.view.WindowManager; import com.android.launcher3.DeviceProfile; @@ -56,20 +41,12 @@ import com.android.quickstep.ActivityControlHelper; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewComponentObserver; -import com.android.quickstep.SwipeSharedState; -import com.android.quickstep.util.MotionPauseDetector; -import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.ObjectWrapper; -import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler - implements InputConsumer, SwipeAnimationListener { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { public enum GestureEndTarget { HOME(3, 100, 1), @@ -79,6 +56,7 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler private final float mEndProgress; private final long mDurationMultiplier; private final float mLauncherAlpha; + GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { mEndProgress = endProgress; mDurationMultiplier = durationMultiplier; @@ -87,68 +65,26 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } private final ActivityControlHelper mActivityControlHelper; - private final InputMonitorCompat mInputMonitor; - private final NavBarPosition mNavBarPosition; - private final SwipeSharedState mSwipeSharedState; private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; private final DeviceProfile mDP; - private final MotionPauseDetector mMotionPauseDetector; - private final float mMotionPauseMinDisplacement; private final Rect mTargetRect = new Rect(); - private final RectF mSwipeTouchRegion; - private final boolean mDisableHorizontalSwipe; - - private final PointF mDownPos = new PointF(); - private final PointF mLastPos = new PointF(); - private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); - private final AnimatedFloat mProgress = new AnimatedFloat(this::onProgressChanged); - private int mActivePointerId = -1; - // Slop used to determine when we say that the gesture has started. - private boolean mPassedPilferInputSlop; - - private VelocityTracker mVelocityTracker; - - // Distance after which we start dragging the window. - private final float mTouchSlop; - - // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. - private float mStartDisplacement; private SwipeAnimationTargetSet mSwipeAnimationTargetSet; private boolean mIsMotionPaused = false; private GestureEndTarget mEndTarget; public FallbackNoButtonInputConsumer(Context context, - ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor, - SwipeSharedState swipeSharedState, RectF swipeTouchRegion, OverviewComponentObserver overviewComponentObserver, - boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) { + RunningTaskInfo runningTaskInfo) { super(context); - mActivityControlHelper = activityControlHelper; - mInputMonitor = inputMonitor; mOverviewComponentObserver = overviewComponentObserver; + mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); mRunningTaskId = runningTaskInfo.id; - - mMotionPauseDetector = new MotionPauseDetector(context); - mMotionPauseMinDisplacement = context.getResources().getDimension( - R.dimen.motion_pause_detector_min_displacement_from_app); - mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged); - - mSwipeSharedState = swipeSharedState; - mSwipeTouchRegion = swipeTouchRegion; - mDisableHorizontalSwipe = disableHorizontalSwipe; - - mNavBarPosition = new NavBarPosition(context); - mVelocityTracker = VelocityTracker.obtain(); - - mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO - * ViewConfiguration.get(context).getScaledTouchSlop(); - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); mLauncherAlpha.value = 1; @@ -156,18 +92,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler initTransitionTarget(); } - @Override - public int getType() { - return TYPE_FALLBACK_NO_BUTTON; - } - private void onLauncherAlphaChanged() { if (mSwipeAnimationTargetSet != null && mEndTarget == null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void onMotionPauseChanged(boolean isPaused) { + @Override + public void onMotionPauseChanged(boolean isPaused) { mIsMotionPaused = isPaused; mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) .setDuration(150).start(); @@ -175,150 +107,36 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } @Override - public void onMotionEvent(MotionEvent ev) { - if (mVelocityTracker == null) { - return; - } - - mVelocityTracker.addMovement(ev); - if (ev.getActionMasked() == ACTION_POINTER_UP) { - mVelocityTracker.clear(); - mMotionPauseDetector.clear(); - } - - switch (ev.getActionMasked()) { - case ACTION_DOWN: { - mActivePointerId = ev.getPointerId(0); - mDownPos.set(ev.getX(), ev.getY()); - mLastPos.set(mDownPos); - break; - } - case ACTION_POINTER_DOWN: { - if (!mPassedPilferInputSlop) { - // Cancel interaction in case of multi-touch interaction - int ptrIdx = ev.getActionIndex(); - if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) { - forceCancelGesture(ev); - } - } - break; - } - case ACTION_POINTER_UP: { - int ptrIdx = ev.getActionIndex(); - int ptrId = ev.getPointerId(ptrIdx); - if (ptrId == mActivePointerId) { - final int newPointerIdx = ptrIdx == 0 ? 1 : 0; - mDownPos.set( - ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x), - ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y)); - mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx)); - mActivePointerId = ev.getPointerId(newPointerIdx); - } - break; - } - case ACTION_MOVE: { - int pointerIndex = ev.findPointerIndex(mActivePointerId); - if (pointerIndex == INVALID_POINTER_ID) { - break; - } - mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex)); - float displacement = getDisplacement(ev); - - if (!mPassedPilferInputSlop) { - if (mDisableHorizontalSwipe && Math.abs(mLastPos.x - mDownPos.x) - > Math.abs(mLastPos.y - mDownPos.y)) { - // Horizontal gesture is not allowed in this region - forceCancelGesture(ev); - break; - } - - if (Math.abs(displacement) >= mTouchSlop) { - mPassedPilferInputSlop = true; - - // Deferred gesture, start the animation and gesture tracking once - // we pass the actual touch slop - startTouchTrackingForWindowAnimation(displacement); - } - } else { - updateDisplacement(displacement - mStartDisplacement); - mMotionPauseDetector.setDisallowPause( - -displacement < mMotionPauseMinDisplacement); - mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); - } - break; - } - case ACTION_CANCEL: - case ACTION_UP: { - finishTouchTracking(ev); - break; - } - } - } - - private void startTouchTrackingForWindowAnimation(float displacement) { - mStartDisplacement = Math.min(displacement, -mTouchSlop); - - RecentsAnimationListenerSet listenerSet = - mSwipeSharedState.newRecentsAnimationListenerSet(); - listenerSet.addListener(this); - Intent homeIntent = mOverviewComponentObserver.getHomeIntent(); - startRecentsActivityAsync(homeIntent, listenerSet); - - ActivityManagerWrapper.getInstance().closeSystemWindows( - CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); - mInputMonitor.pilferPointers(); - } - - private void updateDisplacement(float displacement) { - mProgress.updateValue(getShiftForDisplacement(displacement)); - } - - private void onProgressChanged() { - mTransformParams.setProgress(mProgress.value); + public void updateFinalShift() { + mTransformParams.setProgress(mCurrentShift.value); if (mSwipeAnimationTargetSet != null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void forceCancelGesture(MotionEvent ev) { - int action = ev.getAction(); - ev.setAction(ACTION_CANCEL); - finishTouchTracking(ev); - ev.setAction(action); + @Override + public void onGestureCancelled() { + updateDisplacement(0); + mEndTarget = LAST_TASK; + finishAnimationTargetSetAnimationComplete(); } - /** - * Called when the gesture has ended. Does not correlate to the completion of the interaction as - * the animation can still be running. - */ - private void finishTouchTracking(MotionEvent ev) { - if (ev.getAction() == ACTION_CANCEL) { - mEndTarget = LAST_TASK; + @Override + public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { + float flingThreshold = mContext.getResources() + .getDimension(R.dimen.quickstep_fling_threshold_velocity); + boolean isFling = Math.abs(endVelocity) > flingThreshold; + + if (isFling) { + mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; } else { - mVelocityTracker.computeCurrentVelocity(1000, - ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity()); - float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); - float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = mNavBarPosition.isRightEdge() ? velocityX - : mNavBarPosition.isLeftEdge() ? -velocityX - : velocityY; - float flingThreshold = mContext.getResources() - .getDimension(R.dimen.quickstep_fling_threshold_velocity); - boolean isFling = Math.abs(velocity) > flingThreshold; - - if (isFling) { - mEndTarget = velocity < 0 ? HOME : LAST_TASK; - } else if (mIsMotionPaused) { - mEndTarget = RECENTS; - } else { - mEndTarget = mProgress.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; - } + mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; } - if (mSwipeAnimationTargetSet != null) { finishAnimationTargetSet(); } - mMotionPauseDetector.clear(); } private void finishAnimationTargetSetAnimationComplete() { @@ -346,19 +164,22 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler break; } } + if (mGestureEndCallback != null) { + mGestureEndCallback.run(); + } } private void finishAnimationTargetSet() { float endProgress = mEndTarget.mEndProgress; - if (mProgress.value != endProgress) { + if (mCurrentShift.value != endProgress) { AnimatorSet anim = new AnimatorSet(); anim.play(mLauncherAlpha.animateToValue( mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); - anim.play(mProgress.animateToValue(mProgress.value, endProgress)); + anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); anim.setDuration((long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mProgress.value))); + Math.abs(endProgress - mCurrentShift.value))); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -403,19 +224,4 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler @Override public void onRecentsAnimationCanceled() { } - - private float getDisplacement(MotionEvent ev) { - if (mNavBarPosition.isRightEdge()) { - return ev.getX() - mDownPos.x; - } else if (mNavBarPosition.isLeftEdge()) { - return mDownPos.x - ev.getX(); - } else { - return ev.getY() - mDownPos.y; - } - } - - @Override - public boolean allowInterceptByParent() { - return !mPassedPilferInputSlop; - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java index f5cf654b15..a1e5d47a53 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java @@ -33,7 +33,6 @@ public interface InputConsumer { int TYPE_SCREEN_PINNED = 1 << 6; int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; int TYPE_RESET_GESTURE = 1 << 8; - int TYPE_FALLBACK_NO_BUTTON = 1 << 9; String[] NAMES = new String[] { "TYPE_NO_OP", // 0 @@ -45,7 +44,6 @@ public interface InputConsumer { "TYPE_SCREEN_PINNED", // 6 "TYPE_OVERVIEW_WITHOUT_FOCUS", // 7 "TYPE_RESET_GESTURE", // 8 - "TYPE_FALLBACK_NO_BUTTON", // 9 }; InputConsumer NO_OP = () -> TYPE_NO_OP; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index a4d2f39d29..9114995cc9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -49,20 +49,16 @@ import com.android.launcher3.R; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.RaceConditionTracker; import com.android.launcher3.util.TraceHelper; -import com.android.quickstep.ActivityControlHelper; +import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewCallbacks; -import com.android.quickstep.RecentsModel; import com.android.quickstep.SwipeSharedState; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; -import com.android.quickstep.WindowTransformSwipeHandler; -import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import java.util.function.Consumer; @@ -83,16 +79,15 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final RunningTaskInfo mRunningTask; - private final RecentsModel mRecentsModel; private final Intent mHomeIntent; - private final ActivityControlHelper mActivityControlHelper; private final OverviewCallbacks mOverviewCallbacks; - private final InputConsumerController mInputConsumer; private final SwipeSharedState mSwipeSharedState; private final InputMonitorCompat mInputMonitorCompat; private final SysUINavigationMode.Mode mMode; private final RectF mSwipeTouchRegion; + private final BaseSwipeUpHandler.Factory mHandlerFactory; + private final NavBarPosition mNavBarPosition; private final Consumer mOnCompleteCallback; @@ -100,7 +95,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final float mMotionPauseMinDisplacement; private VelocityTracker mVelocityTracker; - private WindowTransformSwipeHandler mInteractionHandler; + private BaseSwipeUpHandler mInteractionHandler; private final boolean mIsDeferredDownTarget; private final PointF mDownPos = new PointF(); @@ -114,7 +109,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final boolean mDisableHorizontalSwipe; // Slop used to check when we start moving window. - private boolean mPaddedWindowMoveSlop; + private boolean mPassedWindowMoveSlop; // Slop used to determine when we say that the gesture has started. private boolean mPassedPilferInputSlop; @@ -122,26 +117,24 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private float mStartDisplacement; private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> { + private Runnable mCancelRecentsAnimationRunnable = () -> ActivityManagerWrapper.getInstance().cancelRecentsAnimation( true /* restoreHomeStackPosition */); - }; public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo, - RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl, - boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, - InputConsumerController inputConsumer, + Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, Consumer onCompleteCallback, SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, - RectF swipeTouchRegion, boolean disableHorizontalSwipe) { + RectF swipeTouchRegion, boolean disableHorizontalSwipe, + BaseSwipeUpHandler.Factory handlerFactory) { super(base); mMainThreadHandler = new Handler(Looper.getMainLooper()); mRunningTask = runningTaskInfo; - mRecentsModel = recentsModel; mHomeIntent = homeIntent; mMode = SysUINavigationMode.getMode(base); mSwipeTouchRegion = swipeTouchRegion; + mHandlerFactory = handlerFactory; mMotionPauseDetector = new MotionPauseDetector(base); mMotionPauseMinDisplacement = base.getResources().getDimension( @@ -150,11 +143,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mVelocityTracker = VelocityTracker.obtain(); mInputMonitorCompat = inputMonitorCompat; - mActivityControlHelper = activityControl; boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null; mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; mOverviewCallbacks = overviewCallbacks; - mInputConsumer = inputConsumer; mSwipeSharedState = swipeSharedState; mNavBarPosition = new NavBarPosition(base); @@ -163,7 +154,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float slop = QUICKSTEP_TOUCH_SLOP_RATIO * mTouchSlop; mSquaredTouchSlop = slop * slop; - mPassedPilferInputSlop = mPaddedWindowMoveSlop = continuingPreviousGesture; + mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture; mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe; } @@ -186,7 +177,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } // Proxy events to recents view - if (mPaddedWindowMoveSlop && mInteractionHandler != null + if (mPassedWindowMoveSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( mNavBarPosition.getRotationMode())); @@ -251,12 +242,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float displacement = getDisplacement(ev); float displacementX = mLastPos.x - mDownPos.x; - if (!mPaddedWindowMoveSlop) { + if (!mPassedWindowMoveSlop) { if (!mIsDeferredDownTarget) { // Normal gesture, ensure we pass the drag slop before we start tracking // the gesture if (Math.abs(displacement) > mTouchSlop) { - mPaddedWindowMoveSlop = true; + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } } @@ -279,8 +270,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // we pass the actual touch slop startTouchTrackingForWindowAnimation(ev.getEventTime()); } - if (!mPaddedWindowMoveSlop) { - mPaddedWindowMoveSlop = true; + if (!mPassedWindowMoveSlop) { + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } @@ -289,7 +280,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mInteractionHandler != null) { - if (mPaddedWindowMoveSlop) { + if (mPassedWindowMoveSlop) { // Move mInteractionHandler.updateDisplacement(displacement - mStartDisplacement); } @@ -333,12 +324,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener(); - final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler( - mRunningTask, this, touchTimeMs, mActivityControlHelper, - listenerSet != null, mInputConsumer); + final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs, + listenerSet != null); - // Preload the plan - mRecentsModel.getTasks(null); mInteractionHandler = handler; handler.setGestureEndCallback(this::onInteractionGestureFinished); mMotionPauseDetector.setOnMotionPauseListener(handler::onMotionPauseChanged); @@ -364,7 +352,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RaceConditionTracker.onEvent(UP_EVT, ENTER); TraceHelper.endSection("TouchInt"); - if (mPaddedWindowMoveSlop && mInteractionHandler != null) { + if (mPassedWindowMoveSlop && mInteractionHandler != null) { if (ev.getActionMasked() == ACTION_CANCEL) { mInteractionHandler.onGestureCancelled(); } else { @@ -407,14 +395,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // The consumer is being switched while we are active. Set up the shared state to be // used by the next animation removeListener(); - GestureEndTarget endTarget = mInteractionHandler.getGestureEndTarget(); - mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued; - mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher; - if (mSwipeSharedState.canGestureBeContinued) { - mInteractionHandler.cancelCurrentAnimation(mSwipeSharedState); - } else { - mInteractionHandler.reset(); - } + mInteractionHandler.onConsumerAboutToBeSwitched(mSwipeSharedState); } } From 2af71dd058deb86dd575b0043ad87cf1ba16c596 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 11 Jul 2019 12:52:43 -0700 Subject: [PATCH 07/34] Removing tracing for a fixed bug. Bug: 133867119 Change-Id: I796118f5ff0c27db002bb0e3369e651c95b06bbe --- .../quickstep/TouchInteractionService.java | 3 --- .../inputconsumers/OverviewInputConsumer.java | 3 --- .../launcher3/LauncherStateManager.java | 5 ---- .../allapps/AllAppsTransitionController.java | 4 --- .../compat/AccessibilityManagerCompat.java | 3 --- .../launcher3/testing/TestProtocol.java | 2 -- .../AbstractStateChangeTouchController.java | 26 ------------------- .../launcher3/touch/SwipeDetector.java | 17 ------------ .../launcher3/views/BaseDragLayer.java | 6 ----- 9 files changed, 69 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index fafa4d34ca..62f46ecbfb 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -508,9 +508,6 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onInputEvent " + ev); - } if (!(ev instanceof MotionEvent)) { Log.e(TAG, "Unknown event " + ev); return; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index f2e53bb18c..e55389161c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -82,9 +82,6 @@ public class OverviewInputConsumer @Override public void onMotionEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onMotionEvent " + ev); - } if (!mProxyTouch) { return; } diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 2c8c208456..ccd6efaf55 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -429,11 +429,6 @@ public class LauncherStateManager { // Only change the stable states after the transitions have finished if (state != mCurrentStableState) { mLastStableState = state.getHistoryForState(mCurrentStableState); - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "mCurrentStableState = " + state.getClass().getSimpleName() + " @ " + - android.util.Log.getStackTraceString(new Throwable())); - } mCurrentStableState = state; } diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 4683893ea0..a64374bc37 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -168,10 +168,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil @Override public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder, AnimationConfig config) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "setStateWithAnimation " + toState.getClass().getSimpleName()); - } float targetProgress = toState.getVerticalProgress(mLauncher); if (Float.compare(mProgress, targetProgress) == 0) { setAlphas(toState, config, builder); diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 43ae65175f..81c95cbdd4 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -53,9 +53,6 @@ public class AccessibilityManagerCompat { } public static void sendStateEventToTest(Context context, int stateOrdinal) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "sendStateEventToTest"); - } final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context); if (accessibilityManager == null) return; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 3774042c93..d6d0577c9f 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -73,10 +73,8 @@ public final class TestProtocol { public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; - public static final String NO_ALLAPPS_EVENT_TAG = "b/133867119"; public static final String NO_DRAG_TAG = "b/133009122"; public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; - public static final String EVENTS_TO_OVERVIEW_MISSING_TAG = "b/133867119"; } diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 6f53140eab..7252410e03 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -118,9 +118,6 @@ public abstract class AbstractStateChangeTouchController @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onControllerInterceptTouchEvent 1 " + ev); - } if (ev.getAction() == MotionEvent.ACTION_DOWN) { mNoIntercept = !canInterceptTouch(ev); if (mNoIntercept) { @@ -150,9 +147,6 @@ public abstract class AbstractStateChangeTouchController return false; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onControllerInterceptTouchEvent 2 "); - } onControllerTouchEvent(ev); return mDetector.isDraggingOrSettling(); } @@ -240,9 +234,6 @@ public abstract class AbstractStateChangeTouchController @Override public void onDragStart(boolean start) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragStart 1 " + start); - } mStartState = mLauncher.getStateManager().getState(); if (mStartState == ALL_APPS) { mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS; @@ -252,9 +243,6 @@ public abstract class AbstractStateChangeTouchController mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER; } if (mCurrentAnimation == null) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragStart 2"); - } mFromState = mStartState; mToState = null; cancelAnimationControllers(); @@ -376,9 +364,6 @@ public abstract class AbstractStateChangeTouchController @Override public void onDragEnd(float velocity, boolean fling) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragEnd"); - } final int logAction = fling ? Touch.FLING : Touch.SWIPE; boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); @@ -515,9 +500,6 @@ public abstract class AbstractStateChangeTouchController } protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 1"); - } if (mAtomicComponentsController != null) { mAtomicComponentsController.getAnimationPlayer().end(); mAtomicComponentsController = null; @@ -535,11 +517,6 @@ public abstract class AbstractStateChangeTouchController logReachedState(logAction, targetState); } mLauncher.getStateManager().goToState(targetState, false /* animated */); - - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e( - TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 2"); - } } } @@ -563,9 +540,6 @@ public abstract class AbstractStateChangeTouchController } private void cancelAnimationControllers() { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "cancelAnimationControllers"); - } mCurrentAnimation = null; cancelAtomicComponentsController(); mDetector.finishedScrolling(); diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java index 3d454046a5..3777a41ad8 100644 --- a/src/com/android/launcher3/touch/SwipeDetector.java +++ b/src/com/android/launcher3/touch/SwipeDetector.java @@ -158,9 +158,6 @@ public class SwipeDetector { // SETTLING -> (View settled) -> IDLE private void setState(ScrollState newState) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "setState -- start: " + newState); - } if (DBG) { Log.d(TAG, "setState:" + mState + "->" + newState); } @@ -168,9 +165,6 @@ public class SwipeDetector { if (newState == ScrollState.DRAGGING) { initializeDragging(); if (mState == ScrollState.IDLE) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "setState -- 1: " + newState); - } reportDragStart(false /* recatch */); } else if (mState == ScrollState.SETTLING) { reportDragStart(true /* recatch */); @@ -181,11 +175,6 @@ public class SwipeDetector { } mState = newState; - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "setState: " + newState + " @ " + android.util.Log.getStackTraceString( - new Throwable())); - } } public boolean isDraggingOrSettling() { @@ -324,15 +313,9 @@ public class SwipeDetector { break; } mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos, mIsRtl); - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onTouchEvent 1"); - } // handle state and listener calls. if (mState != ScrollState.DRAGGING && shouldScrollStart(ev, pointerIndex)) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onTouchEvent 2"); - } setState(ScrollState.DRAGGING); } if (mState == ScrollState.DRAGGING) { diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 1e70c7f812..15f2724708 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -152,9 +152,6 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "findControllerToHandleTouch " + ev); - } if (shouldDisableGestures(ev)) return null; AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); @@ -315,9 +312,6 @@ public abstract class BaseDragLayer * Proxies the touch events to the gesture handlers */ public boolean proxyTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "proxyTouchEvent " + ev); - } boolean handled; if (mProxyTouchController != null) { handled = mProxyTouchController.onControllerTouchEvent(ev); From 853852351f3b1bd9fbaa063b0e99cd8067e61c50 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 12:04:36 -0700 Subject: [PATCH 08/34] Correctly restarting Launcher from OOP tests Waiting for touch interaction service; waiting for package-restart events. Bug: 136215685 Change-Id: I0c31c09fe3a58b898168dfdb4e4d23757b94a47c --- .../android/quickstep/TouchInteractionService.java | 4 ++++ .../android/quickstep/TouchInteractionService.java | 7 +++++++ .../quickstep/QuickstepTestInformationHandler.java | 9 ++++++++- .../launcher3/testing/TestInformationHandler.java | 5 +++++ .../android/launcher3/testing/TestProtocol.java | 1 + .../launcher3/tapl/LauncherInstrumentation.java | 14 ++++++++++++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index c902826ed8..917800f2a6 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -185,4 +185,8 @@ public class TouchInteractionService extends Service { } return mMyBinder; } + + public static boolean isInputMonitorInitialized() { + return true; + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 0ef2f5c5ad..dd04024539 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -226,12 +226,17 @@ public class TouchInteractionService extends Service implements }; private static boolean sConnected = false; + private static boolean sInputMonitorInitialized = false; private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState(); public static boolean isConnected() { return sConnected; } + public static boolean isInputMonitorInitialized() { + return sInputMonitorInitialized; + } + public static SwipeSharedState getSwipeSharedState() { return sSwipeSharedState; } @@ -325,6 +330,7 @@ public class TouchInteractionService extends Service implements mInputMonitorCompat.dispose(); mInputMonitorCompat = null; } + sInputMonitorInitialized = false; } private void initInputMonitor() { @@ -342,6 +348,7 @@ public class TouchInteractionService extends Service implements Log.e(TAG, "Unable to create input monitor", e); } initTouchBounds(); + sInputMonitorInitialized = true; } private int getNavbarSize(String resName) { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 89513634fe..b59e13362d 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -10,7 +10,8 @@ import com.android.quickstep.util.LayoutUtils; public class QuickstepTestInformationHandler extends TestInformationHandler { - public QuickstepTestInformationHandler(Context context) { } + public QuickstepTestInformationHandler(Context context) { + } @Override public Bundle call(String method) { @@ -29,6 +30,12 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); return response; } + + case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { + response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, + TouchInteractionService.isInputMonitorInitialized()); + break; + } } return super.call(method); diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index d2e196138c..bab454f070 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -74,6 +74,11 @@ public class TestInformationHandler implements ResourceBasedOverride { break; } + case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { + response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, true); + break; + } + case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING: TestProtocol.sDebugTracing = true; break; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 3774042c93..3a07be0968 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -66,6 +66,7 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized"; public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 11b0665d95..2b0a794ea6 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -444,6 +444,8 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { + waitForTouchInteractionService(); + assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); @@ -514,6 +516,18 @@ public final class LauncherInstrumentation { } } + private void waitForTouchInteractionService() { + for (int i = 0; i < 100; ++i) { + if (getTestInfo( + TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED). + getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD)) { + return; + } + SystemClock.sleep(100); + } + fail("TouchInteractionService didn't connect"); + } + Parcelable executeAndWaitForEvent(Runnable command, UiAutomation.AccessibilityEventFilter eventFilter, String message) { try { From 8874e5f8a7d575341b1ec34d3f16b624e615834b Mon Sep 17 00:00:00 2001 From: Becky Date: Thu, 11 Jul 2019 13:54:03 -0700 Subject: [PATCH 09/34] Fill the logging container in the AllAppsContainerView This would fix the issue that when drag and drop an icon from the all apps page, it doesn't have the right container information logged. Logging after this fix: 07-11 10:57:04.392 12969 12969 D UserEvent: action:DRAGDROP 07-11 10:57:04.392 12969 12969 D UserEvent: Source child:APP_ICON parent:ALLAPPS 07-11 10:57:04.392 12969 12969 D UserEvent: Destination child:APP_ICON parent:WORKSPACE id=0 07-11 10:57:04.392 12969 12969 D UserEvent: Elapsed container 744 ms, session 17440 ms, action 739 ms Test: manual Bug: 111935715 Change-Id: Ifb078e57697b051e3a527c16abaad40663eae687 --- .../android/launcher3/allapps/AllAppsContainerView.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ea9b077c62..b279cfc0be 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -50,6 +50,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusedItemDecorator; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.MultiValueAlpha; @@ -297,7 +298,11 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) { - // This is filled in {@link AllAppsRecyclerView} + if (getApps().hasFilter()) { + targetParent.containerType = ContainerType.SEARCHRESULT; + } else { + targetParent.containerType = ContainerType.ALLAPPS; + } } @Override From 1fd52d9024a6ac3b1dd38f8518903e7c332bc750 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 11 Jul 2019 16:00:12 -0700 Subject: [PATCH 10/34] Remove tracing for a fixed bug Bug: 132900132 Change-Id: Ic4ce3669f88c932e392b7517ec9fda11384dc334 --- .../launcher3/BaseDraggingActivity.java | 8 ------ src/com/android/launcher3/BubbleTextView.java | 3 -- src/com/android/launcher3/Launcher.java | 5 ---- .../allapps/AllAppsContainerView.java | 3 -- .../allapps/AlphabeticalAppsList.java | 5 ---- .../launcher3/testing/TestProtocol.java | 1 - .../launcher3/touch/ItemClickHandler.java | 28 ++----------------- .../launcher3/views/BaseDragLayer.java | 3 -- 8 files changed, 2 insertions(+), 54 deletions(-) diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index f69b172480..50553095d6 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -135,10 +135,6 @@ public abstract class BaseDraggingActivity extends BaseActivity public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely 1"); - } if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) { Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show(); return false; @@ -162,10 +158,6 @@ public abstract class BaseDraggingActivity extends BaseActivity startShortcutIntentSafely(intent, optsBundle, item, sourceContainer); } else if (user == null || user.equals(Process.myUserHandle())) { // Could be launching some bookkeeping activity - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely 2"); - } startActivity(intent, optsBundle); AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), Process.myUserHandle(), sourceContainer); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 1619e3645f..22c69f59a5 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -319,9 +319,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @Override public boolean onTouchEvent(MotionEvent event) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "BubbleTextView.onTouchEvent " + event); - } // Call the superclass onTouchEvent first, because sometimes it changes the state to // isPressed() on an ACTION_UP boolean result = super.onTouchEvent(event); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bc3aa7ef40..9229832687 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1809,11 +1809,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, public boolean startActivitySafely(View v, Intent intent, ItemInfo item, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely outer"); - } - if (!hasBeenResumed()) { // Workaround an issue where the WM launch animation is clobbered when finishing the // recents animation into launcher. Defer launching the activity until Launcher is diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ea9b077c62..12a493013f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -626,9 +626,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public boolean dispatchTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "AllAppsContainerView.dispatchTouchEvent " + ev); - } final boolean result = super.dispatchTouchEvent(ev); switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index 2ad92e16f8..1369441fe1 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -301,11 +301,6 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { } private void refreshRecyclerView() { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "refreshRecyclerView @ " + android.util.Log.getStackTraceString( - new Throwable())); - } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 011ff86e2c..e28eba8094 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -75,7 +75,6 @@ public final class TestProtocol { public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; public static final String NO_DRAG_TAG = "b/133009122"; - public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; } diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 85f763d095..2895a89be3 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -68,28 +68,12 @@ public class ItemClickHandler { } private static void onClick(View v, String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 1"); - } // Make sure that rogue clicks don't get through while allapps is launching, or after the // view has detached (it's possible for this to happen if the view is removed mid touch). - if (v.getWindowToken() == null) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 2"); - } - return; - } + if (v.getWindowToken() == null) return; Launcher launcher = Launcher.getLauncher(v.getContext()); - if (!launcher.getWorkspace().isFinishedSwitchingState()) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 3"); - } - return; - } + if (!launcher.getWorkspace().isFinishedSwitchingState()) return; Object tag = v.getTag(); if (tag instanceof WorkspaceItemInfo) { @@ -99,10 +83,6 @@ public class ItemClickHandler { onClickFolderIcon(v); } } else if (tag instanceof AppInfo) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 4"); - } startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer); } else if (tag instanceof LauncherAppWidgetInfo) { @@ -234,10 +214,6 @@ public class ItemClickHandler { private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startAppShortcutOrInfoActivity"); - } Intent intent; if (item instanceof PromiseAppInfo) { PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item; diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 15f2724708..8bf33bf05c 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -256,9 +256,6 @@ public abstract class BaseDragLayer @Override public boolean dispatchTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "BaseDragLayer.dispatchTouchEvent " + ev); - } switch (ev.getAction()) { case ACTION_DOWN: { float x = ev.getX(); From e1463f5580ed46a37816e586f75eab697d4c3a7b Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 11 Jul 2019 16:55:01 -0700 Subject: [PATCH 11/34] Defer jumping to NORMAL state if overview is still peeking Bug: 137316430 Change-Id: I1ace19bb229d07bd9dfe5ed6f60c63715b9f8cf2 --- .../FlingAndHoldTouchController.java | 15 +++++++++++++++ .../touch/AbstractStateChangeTouchController.java | 14 ++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java index 3fe4bcfd9c..f06b8a910f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java @@ -167,6 +167,21 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController { mMotionPauseDetector.clear(); } + @Override + protected void goToTargetState(LauncherState targetState, int logAction) { + if (mPeekAnim != null && mPeekAnim.isStarted()) { + // Don't jump to the target state until overview is no longer peeking. + mPeekAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + FlingAndHoldTouchController.super.goToTargetState(targetState, logAction); + } + }); + } else { + super.goToTargetState(targetState, logAction); + } + } + @Override protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) { if (handlingOverviewAnim()) { diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 7252410e03..ae69f3b32d 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -31,7 +31,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.os.SystemClock; -import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; @@ -43,7 +42,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; @@ -513,13 +511,17 @@ public abstract class AbstractStateChangeTouchController shouldGoToTargetState = !reachedTarget; } if (shouldGoToTargetState) { - if (targetState != mStartState) { - logReachedState(logAction, targetState); - } - mLauncher.getStateManager().goToState(targetState, false /* animated */); + goToTargetState(targetState, logAction); } } + protected void goToTargetState(LauncherState targetState, int logAction) { + if (targetState != mStartState) { + logReachedState(logAction, targetState); + } + mLauncher.getStateManager().goToState(targetState, false /* animated */); + } + private void logReachedState(int logAction, LauncherState targetState) { // Transition complete. log the action mLauncher.getUserEventDispatcher().logStateChangeAction(logAction, From 7400bb3f725d288766ddf9e9256327fcb90015c5 Mon Sep 17 00:00:00 2001 From: Anna Wasewicz Date: Thu, 11 Jul 2019 18:58:05 -0700 Subject: [PATCH 12/34] Set the chips flag to false in QP1A. This flag should be off by default. Chips should not be running in QP1A. Bug:137290162 Change-Id: I159e1bd00d1f9ff4f6cf63daf93a68e3e8d063c8 --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 54efcb7868..45639e0a43 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", true, + "ENABLE_HINTS_IN_OVERVIEW", false, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( From 39cfa03d11f134b997da3e94bd5d44d4e32fa75a Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 12 Jul 2019 12:02:24 -0700 Subject: [PATCH 13/34] Update the home stack bounds with the transition end points - When the user dismisses splitscreen while launcher is hidden and was previously minimized, getLocationOnScreen() will continue to return the old position until the first view root traversal after the window is shown. As a result, we will end up with home bounds for the minimized state and the wrong target bounds calculated Bug: 135952890 Test: Enter splitscreen, launcher another app, dismiss splitscreen and then swipe up Change-Id: Id19dfa664623b2b855db4209999508c76a9aacdc --- .../WindowTransformSwipeHandler.java | 32 ++++++++++++------- .../quickstep/util/ClipAnimationHelper.java | 6 +++- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..d81bb31e60 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -381,12 +381,31 @@ public class WindowTransformSwipeHandler } } + private Rect getStackBounds(DeviceProfile dp) { + if (mActivity != null) { + int loc[] = new int[2]; + View rootView = mActivity.getRootView(); + rootView.getLocationOnScreen(loc); + return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), + loc[1] + rootView.getHeight()); + } else { + return new Rect(0, 0, dp.widthPx, dp.heightPx); + } + } + private void initTransitionEndpoints(DeviceProfile dp) { mDp = dp; Rect tempRect = new Rect(); mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( dp, mContext, tempRect); + if (!dp.isMultiWindowMode) { + // When updating the target rect, also update the home bounds since the location on + // screen of the launcher window may be stale (position is not updated until first + // traversal after the window is resized). We only do this for non-multiwindow because + // we otherwise use the minimized home bounds provided by the system. + mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); + } mClipAnimationHelper.updateTargetRect(tempRect); if (mMode == Mode.NO_BUTTON) { // We can drag all the way to the top of the screen. @@ -776,21 +795,12 @@ public class WindowTransformSwipeHandler .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); dp = dp.getMultiWindowProfile(mContext, new Point( targetSet.minimizedHomeBounds.width(), targetSet.minimizedHomeBounds.height())); - dp.updateInsets(targetSet.homeContentInsets); } else { - if (mActivity != null) { - int loc[] = new int[2]; - View rootView = mActivity.getRootView(); - rootView.getLocationOnScreen(loc); - overviewStackBounds = new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), - loc[1] + rootView.getHeight()); - } else { - overviewStackBounds = new Rect(0, 0, dp.widthPx, dp.heightPx); - } // If we are not in multi-window mode, home insets should be same as system insets. dp = dp.copy(mContext); - dp.updateInsets(targetSet.homeContentInsets); + overviewStackBounds = getStackBounds(dp); } + dp.updateInsets(targetSet.homeContentInsets); dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); if (runningTaskTarget != null) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index de671e04aa..9809112a0d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -119,8 +119,12 @@ public class ClipAnimationHelper { } public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) { - mHomeStackBounds.set(homeStackBounds); updateSourceStack(target); + updateHomeBounds(homeStackBounds); + } + + public void updateHomeBounds(Rect homeStackBounds) { + mHomeStackBounds.set(homeStackBounds); } public void updateTargetRect(Rect targetRect) { From d91cec72feb435d403192080edc28747889d02fa Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 12 Jul 2019 12:26:08 -0700 Subject: [PATCH 14/34] Simplifying switching to home for some tests Change-Id: I696d0267a2c36a18080396657bed07f7b1654a7d --- .../quickstep/AppPredictionsUITests.java | 6 ++--- .../ui/DefaultLayoutProviderTest.java | 6 ++--- .../com/android/launcher3/ui/WorkTabTest.java | 2 +- .../ui/widget/AddConfigWidgetTest.java | 2 +- .../launcher3/ui/widget/AddWidgetTest.java | 2 +- .../launcher3/ui/widget/BindWidgetTest.java | 2 +- .../ui/widget/RequestPinItemTest.java | 2 +- .../util/rule/LauncherActivityRule.java | 26 ++++--------------- 8 files changed, 16 insertions(+), 32 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java index d9fcf4d97a..d0956d1f6d 100644 --- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java +++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java @@ -88,7 +88,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { */ @Test public void testPredictionExistsInAllApps() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); mLauncher.pressHome().switchToAllApps(); // Dispatch an update @@ -103,7 +103,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { */ @Test public void testPredictionsDeferredUntilHome() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); sendPredictionUpdate(mSampleApp1, mSampleApp2); mLauncher.pressHome().switchToAllApps(); waitForLauncherCondition("Predictions were not updated in loading state", @@ -120,7 +120,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { @Test public void testPredictionsDisabled() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); sendPredictionUpdate(); mLauncher.pressHome().switchToAllApps(); diff --git a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java index 58c74cef16..a76b4a4886 100644 --- a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java +++ b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java @@ -72,7 +72,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { writeLayout(new LauncherLayoutBuilder().atHotseat(0).putApp(SETTINGS_APP, SETTINGS_APP)); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); mLauncher.getWorkspace().getHotseatAppIcon(getSettingsApp().getLabel().toString()); @@ -88,7 +88,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { info.getComponent().getClassName(), 2, 2)); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); // Verify widget present @@ -105,7 +105,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { .build()); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); mLauncher.getWorkspace().getHotseatFolder("Folder: Copy"); diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index c93c20a616..79c2d071d5 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -53,7 +53,7 @@ public class WorkTabTest extends AbstractLauncherUiTest { @Test public void workTabExists() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index dc72bda9a3..3206a69bbf 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -98,7 +98,7 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { lockRotation(true); clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); final Widgets widgets = mLauncher.getWorkspace().openAllWidgets(); diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 4529a80d1d..276c6144a2 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -55,7 +55,7 @@ public class AddWidgetTest extends AbstractLauncherUiTest { private void performTest() throws Throwable { clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); final LauncherAppWidgetProviderInfo widgetInfo = TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */); diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java index d36126bb17..3a7df64e81 100644 --- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java @@ -267,7 +267,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest { resetLoaderState(); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); } diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index 6122daec2c..a9a5090988 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -131,7 +131,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { lockRotation(true); clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); // Open Pin item activity BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver( diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java index 2aba7a56de..204240324e 100644 --- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java +++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java @@ -15,11 +15,6 @@ */ package com.android.launcher3.util.rule; -import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage; - -import static androidx.test.InstrumentationRegistry.getInstrumentation; -import static androidx.test.InstrumentationRegistry.getTargetContext; - import android.app.Activity; import android.app.Application; import android.app.Application.ActivityLifecycleCallbacks; @@ -52,26 +47,15 @@ public class LauncherActivityRule implements TestRule { } public Callable itemExists(final ItemOperator op) { - return new Callable() { - - @Override - public Boolean call() throws Exception { - Launcher launcher = getActivity(); - if (launcher == null) { - return false; - } - return launcher.getWorkspace().getFirstMatch(op) != null; + return () -> { + Launcher launcher = getActivity(); + if (launcher == null) { + return false; } + return launcher.getWorkspace().getFirstMatch(op) != null; }; } - /** - * Starts the launcher activity in the target package. - */ - public void startLauncher() { - getInstrumentation().startActivitySync(getHomeIntentInPackage(getTargetContext())); - } - private class MyStatement extends Statement implements ActivityLifecycleCallbacks { private final Statement mBase; From 5818f9b3c523d41ba0e399a1513e22bb83d38abc Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 12 Jul 2019 18:02:09 -0700 Subject: [PATCH 15/34] Fix overshoot velocity in 2-button landscape mode Now we use the velocity towards the middle of the screen (e.g. x when in landscape) instead of always using y. Test: testBackground with @PortraitLandscape Bug: 135567630 Change-Id: I77ab6bdf0d556475a6c182ae91914a718a81e1c4 --- .../src/com/android/quickstep/WindowTransformSwipeHandler.java | 2 +- .../tests/src/com/android/quickstep/TaplTestsQuickstep.java | 3 +-- src/com/android/launcher3/anim/Interpolators.java | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..4f351bae9d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -976,7 +976,7 @@ public class WindowTransformSwipeHandler if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) { if (endTarget == RECENTS && mMode != Mode.NO_BUTTON) { Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams( - startShift, endShift, endShift, velocityPxPerMs.y, + startShift, endShift, endShift, endVelocity / 1000, mTransitionDragLength); endShift = overshoot.end; interpolator = overshoot.interpolator; diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 9e3bf2f56e..885fdbf423 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -17,7 +17,6 @@ package com.android.quickstep; import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -208,7 +207,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { @Test @NavigationModeSwitch -// @PortraitLandscape + @PortraitLandscape public void testBackground() throws Exception { startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); final Background background = mLauncher.getBackground(); diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index b169cb80be..8443231e8d 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -144,7 +144,8 @@ public class Interpolators { public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound, float upperBound) { if (upperBound <= lowerBound) { - throw new IllegalArgumentException("lowerBound must be less than upperBound"); + throw new IllegalArgumentException(String.format( + "lowerBound (%f) must be less than upperBound (%f)", lowerBound, upperBound)); } return t -> { if (t < lowerBound) { From 69ac3349353242e267512119c0c3077cf2f5a647 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 15 Jul 2019 18:49:06 +0800 Subject: [PATCH 16/34] Don't preload overview if current home isn't gestural overview During first boot, home activity after FallbackHome may be an one-time setup. If the overview is preloaded at this moment, system won't resume the real home after the one-time setup is finished because the activity stack is not empty. Since the navigation mode doesn't support gesture during the first time setup, and in order to keep the ability to preload launcher if it is also the overview, these conditions are combined to guard the case of first boot. Fix: 137281732 Test: Build sdk_gphone_x86-userdebug. Run "emulator -wipe-data" and check the recents activity won't start during booting. Change-Id: I4b20f61f4a412371c19b379410c8a0a188e41276 --- .../src/com/android/quickstep/TouchInteractionService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 22c18d0b00..fd4b3940a5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -708,6 +708,10 @@ public class TouchInteractionService extends Service implements if (!mIsUserUnlocked) { return; } + if (!mMode.hasGestures && !mOverviewComponentObserver.isHomeAndOverviewSame()) { + // Prevent the overview from being started before the real home on first boot. + return; + } final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); From 092b6f8cbf40b0f144fb4d903f92ade6bdbacb0e Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 27 Jun 2019 19:16:38 -0700 Subject: [PATCH 17/34] Adding system health diags for inporoc tests Bug: 133891845 Change-Id: I90161bfc9db5983a45dfb89728a82ec1e3d81f19 --- .../testcomponent/TestCommandReceiver.java | 17 +++- .../launcher3/ui/AbstractLauncherUiTest.java | 7 +- .../tapl/LauncherInstrumentation.java | 84 ++++--------------- .../android/launcher3/tapl/TestHelpers.java | 68 +++++++++++++++ 4 files changed, 102 insertions(+), 74 deletions(-) diff --git a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java index fa23b8d5b9..6a6916eec3 100644 --- a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java +++ b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java @@ -32,13 +32,14 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.util.Base64; +import androidx.test.InstrumentationRegistry; + +import com.android.launcher3.tapl.TestHelpers; + import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import androidx.test.InstrumentationRegistry; - /** * Content provider to receive commands from tests */ @@ -47,6 +48,7 @@ public class TestCommandReceiver extends ContentProvider { public static final String ENABLE_TEST_LAUNCHER = "enable-test-launcher"; public static final String DISABLE_TEST_LAUNCHER = "disable-test-launcher"; public static final String KILL_PROCESS = "kill-process"; + public static final String GET_SYSTEM_HEALTH_MESSAGE = "get-system-health-message"; @Override public boolean onCreate() { @@ -99,6 +101,12 @@ public class TestCommandReceiver extends ContentProvider { killBackgroundProcesses(arg); return null; } + + case GET_SYSTEM_HEALTH_MESSAGE: { + final Bundle response = new Bundle(); + response.putString("result", TestHelpers.getSystemHealthMessage(getContext())); + return response; + } } return super.call(method, arg, extras); } @@ -122,7 +130,8 @@ public class TestCommandReceiver extends ContentProvider { // Create an empty file so that we can pass its descriptor try { file.createNewFile(); - } catch (IOException e) { } + } catch (IOException e) { + } } return ParcelFileDescriptor.open(file, MODE_READ_WRITE); diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index e39fc76a0b..361f2fb533 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -51,6 +51,7 @@ import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; +import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; @@ -98,7 +99,11 @@ public abstract class AbstractLauncherUiTest { } catch (RemoteException e) { throw new RuntimeException(e); } - if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests(); + if (TestHelpers.isInLauncherProcess()) { + Utilities.enableRunningInTestHarnessForTests(); + mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand( + TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result")); + } } protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 5a6c898104..0fed337a04 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -39,7 +39,6 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.DropBoxManager; import android.os.Parcelable; import android.os.SystemClock; import android.text.TextUtils; @@ -73,6 +72,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.function.Supplier; /** * The main tapl object. The only object that can be explicitly constructed by the using code. It @@ -133,6 +133,7 @@ public final class LauncherInstrumentation { private int mExpectedRotation = Surface.ROTATION_0; private final Uri mTestProviderUri; private final Deque mDiagnosticContext = new LinkedList<>(); + private Supplier mSystemHealthSupplier; /** * Constructs the root of TAPL hierarchy. You get all other objects from it. @@ -285,79 +286,24 @@ public final class LauncherInstrumentation { return "Background"; } - private static String truncateCrash(String text, int maxLines) { - String[] lines = text.split("\\r?\\n"); - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < maxLines && i < lines.length; i++) { - ret.append(lines[i]); - ret.append('\n'); - } - if (lines.length > maxLines) { - ret.append("... "); - ret.append(lines.length - maxLines); - ret.append(" more lines truncated ...\n"); - } - return ret.toString(); - } - - private String checkCrash(String label) { - DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( - Context.DROPBOX_SERVICE); - Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); - - long timestamp = 0; - DropBoxManager.Entry entry; - int crashCount = 0; - StringBuilder errorDetails = new StringBuilder(); - while (null != (entry = dropbox.getNextEntry(label, timestamp))) { - String dropboxSnippet; - try { - dropboxSnippet = entry.getText(4096); - } finally { - entry.close(); - } - - crashCount++; - errorDetails.append(label); - errorDetails.append(": "); - errorDetails.append(truncateCrash(dropboxSnippet, 40)); - errorDetails.append(" ...\n"); - - timestamp = entry.getTimeMillis(); - } - Assert.assertEquals(errorDetails.toString(), 0, crashCount); - return crashCount > 0 ? errorDetails.toString() : null; + public void setSystemHealthSupplier(Supplier supplier) { + this.mSystemHealthSupplier = supplier; } private String getSystemHealthMessage() { + final String testPackage = getContext().getPackageName(); try { - StringBuilder errors = new StringBuilder(); - - final String testPackage = getContext().getPackageName(); - try { - mDevice.executeShellCommand("pm grant " + testPackage + - " android.permission.READ_LOGS"); - mDevice.executeShellCommand("pm grant " + testPackage + - " android.permission.PACKAGE_USAGE_STATS"); - } catch (IOException e) { - e.printStackTrace(); - } - - final String[] labels = { - "system_server_crash", - "system_server_native_crash", - "system_server_anr", - }; - - for (String label : labels) { - final String crash = checkCrash(label); - if (crash != null) errors.append(crash); - } - - return errors.length() != 0 ? errors.toString() : null; - } catch (Exception e) { - return null; + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.READ_LOGS"); + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.PACKAGE_USAGE_STATS"); + } catch (IOException e) { + e.printStackTrace(); } + + return mSystemHealthSupplier != null + ? mSystemHealthSupplier.get() + : TestHelpers.getSystemHealthMessage(getContext()); } private void fail(String message) { diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java index 93554d2452..e19f91a20a 100644 --- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java +++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java @@ -26,6 +26,9 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.os.DropBoxManager; + +import org.junit.Assert; import java.util.List; @@ -81,4 +84,69 @@ public class TestHelpers { } return "com.android.systemui"; } + + private static String truncateCrash(String text, int maxLines) { + String[] lines = text.split("\\r?\\n"); + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < maxLines && i < lines.length; i++) { + ret.append(lines[i]); + ret.append('\n'); + } + if (lines.length > maxLines) { + ret.append("... "); + ret.append(lines.length - maxLines); + ret.append(" more lines truncated ...\n"); + } + return ret.toString(); + } + + private static String checkCrash(Context context, String label) { + DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); + Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); + + long timestamp = 0; + DropBoxManager.Entry entry; + int crashCount = 0; + StringBuilder errorDetails = new StringBuilder(); + while (null != (entry = dropbox.getNextEntry(label, timestamp))) { + String dropboxSnippet; + try { + dropboxSnippet = entry.getText(4096); + } finally { + entry.close(); + } + + crashCount++; + errorDetails.append(label); + errorDetails.append(": "); + errorDetails.append(truncateCrash(dropboxSnippet, 40)); + errorDetails.append(" ...\n"); + + timestamp = entry.getTimeMillis(); + } + Assert.assertEquals(errorDetails.toString(), 0, crashCount); + return crashCount > 0 ? errorDetails.toString() : null; + } + + public static String getSystemHealthMessage(Context context) { + try { + StringBuilder errors = new StringBuilder(); + + final String[] labels = { + "system_server_crash", + "system_server_native_crash", + "system_server_anr", + }; + + for (String label : labels) { + final String crash = checkCrash(context, label); + if (crash != null) errors.append(crash); + } + + return errors.length() != 0 ? errors.toString() : null; + } catch (Exception e) { + return "Failed to get system health diags, maybe build your test via .bp instead of " + + ".mk? " + android.util.Log.getStackTraceString(e); + } + } } From 8820399e57c78000c8e25e2c91de706063878a07 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 15 Jul 2019 13:30:32 -0700 Subject: [PATCH 18/34] Waiting for launcher to start in workTabExists() Change-Id: I08c5385b188dda81ee0dfc1bfd639a0892bd6584 --- tests/src/com/android/launcher3/ui/WorkTabTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index 79c2d071d5..d9edc35874 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -54,7 +54,7 @@ public class WorkTabTest extends AbstractLauncherUiTest { @Test public void workTabExists() { mDevice.pressHome(); - + waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); /* From 7dcd09433094e1585a6c454081c15f4878c2ee94 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 15 Jul 2019 15:34:10 -0700 Subject: [PATCH 19/34] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I897d0df49125785a4524fedb8dcdbad50f758337 --- quickstep/res/values-fr/strings.xml | 2 +- quickstep/res/values-hi/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 2 +- res/values-ca/strings.xml | 2 +- res/values-in/strings.xml | 12 ++++++------ res/values-mr/strings.xml | 14 +++++++------- res/values-ru/strings.xml | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 5394f495e9..01dcff202d 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -33,5 +33,5 @@ "Encore %1$s aujourd\'hui" "Suggestions d\'applications" "Toutes les applications" - "Vos applications prévues" + "Applications prévues pour vous" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 0467af4b2d..387d509587 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -27,7 +27,7 @@ "बंद करें" "ऐप्लिकेशन इस्तेमाल की सेटिंग" "सभी ऐप्लिकेशन बंद करें" - "हाल ही में इस्तेमाल किए गए एेप्लिकेशन" + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन" "%1$s, %2$s" "<1 मिनट" "आज %1$s और चलेगा" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 1ca558a240..cccece749c 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -27,7 +27,7 @@ "बंद" "अ‍ॅप वापर सेटिंग्ज" "सर्व साफ करा" - "अलीकडील अॅप्स" + "अलीकडील अ‍ॅप्स" "%1$s, %2$s" "१मिहून कमी" "आज %1$sशिल्लक आहे" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index c0859d3b4d..50f92daf28 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -88,7 +88,7 @@ "Punts de notificació" "Activats" "Desactivats" - "Cal que tingui accés a les notificacions" + "Cal accés a les notificacions" "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 3054214b5e..211f735b49 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -30,10 +30,10 @@ "Layar utama" "Tindakan khusus" "Sentuh lama untuk memilih widget." - "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." + "Ketuk dua kali & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Tap lama untuk menempatkan secara manual" + "Sentuh lama untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -41,8 +41,8 @@ "Telusuri aplikasi lainnya" "Aplikasi" "Notifikasi" - "Tap lama untuk memilih pintasan." - "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." + "Sentuh lama untuk memilih pintasan." + "Ketuk dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." "Tidak ada ruang lagi pada layar Utama ini." "Tidak ada ruang tersisa di baki Favorit" "Daftar aplikasi" @@ -73,8 +73,8 @@ "Layar utama %1$d dari %2$d" "Halaman layar utama baru" "Folder dibuka, %1$d x %2$d" - "Tap untuk menutup folder" - "Tap untuk menyimpan ganti nama" + "Ketuk untuk menutup folder" + "Ketuk untuk menyimpan ganti nama" "Folder ditutup" "Folder diganti namanya menjadi %1$s" "Folder: %1$s" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 19c06976b0..49e38982cd 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -35,18 +35,18 @@ "%1$d रूंद बाय %2$d उंच" "स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा" "आपोआप जोडा" - "अॅप्स शोधा" - "अॅप्स लोड करत आहे…" - "\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत" - "अधिक अॅप्स शोधा" + "अ‍ॅप्स शोधा" + "अ‍ॅप्स लोड करत आहे…" + "\"%1$s\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत" + "अधिक अ‍ॅप्स शोधा" "ॲप" "सूचना" "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा." "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा." "या मुख्य स्क्रीनवर आणखी जागा नाही." "आवडीच्या ट्रे मध्ये आणखी जागा नाही" - "अॅप्स सूची" - "वैयक्तिक अॅप्स सूची" + "अ‍ॅप्स सूची" + "वैयक्तिक अ‍ॅप्स सूची" "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची" "होम" "काढा" @@ -136,7 +136,7 @@ "कामाची अ‍ॅप्स येथे मिळवा" "प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा." "तुमच्या संस्थेकडून व्यवस्थापित" - "सूचना आणि अॅप्स बंद आहेत" + "सूचना आणि अ‍ॅप्स बंद आहेत" "बंद करा" "बंद केले" "हे करता आले नाही: %1$s" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34e267da9b..23b00d0936 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -90,7 +90,7 @@ "Значки уведомлений" "Включены" "Отключены" - "Нет доступа к уведомлениям" + "Нужен доступ к уведомлениям" "Чтобы показывать значки уведомлений, включите уведомления в приложении \"%1$s\"" "Изменить настройки" "Показывать значки уведомлений" From 22065f290cd6d52a7d72e165759bf8b3b536e17c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 15 Jul 2019 15:37:48 -0700 Subject: [PATCH 20/34] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I249348f471abce9332ca65e07ebb9bde8c5b1d7b --- quickstep/res/values-fr/strings.xml | 2 +- quickstep/res/values-hi/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 2 +- res/values-ca/strings.xml | 2 +- res/values-in/strings.xml | 12 ++++++------ res/values-mr/strings.xml | 14 +++++++------- res/values-ru/strings.xml | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 5394f495e9..01dcff202d 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -33,5 +33,5 @@ "Encore %1$s aujourd\'hui" "Suggestions d\'applications" "Toutes les applications" - "Vos applications prévues" + "Applications prévues pour vous" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 0467af4b2d..387d509587 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -27,7 +27,7 @@ "बंद करें" "ऐप्लिकेशन इस्तेमाल की सेटिंग" "सभी ऐप्लिकेशन बंद करें" - "हाल ही में इस्तेमाल किए गए एेप्लिकेशन" + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन" "%1$s, %2$s" "<1 मिनट" "आज %1$s और चलेगा" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 1ca558a240..cccece749c 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -27,7 +27,7 @@ "बंद" "अ‍ॅप वापर सेटिंग्ज" "सर्व साफ करा" - "अलीकडील अॅप्स" + "अलीकडील अ‍ॅप्स" "%1$s, %2$s" "१मिहून कमी" "आज %1$sशिल्लक आहे" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index c0859d3b4d..50f92daf28 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -88,7 +88,7 @@ "Punts de notificació" "Activats" "Desactivats" - "Cal que tingui accés a les notificacions" + "Cal accés a les notificacions" "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 3054214b5e..211f735b49 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -30,10 +30,10 @@ "Layar utama" "Tindakan khusus" "Sentuh lama untuk memilih widget." - "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." + "Ketuk dua kali & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Tap lama untuk menempatkan secara manual" + "Sentuh lama untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -41,8 +41,8 @@ "Telusuri aplikasi lainnya" "Aplikasi" "Notifikasi" - "Tap lama untuk memilih pintasan." - "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." + "Sentuh lama untuk memilih pintasan." + "Ketuk dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." "Tidak ada ruang lagi pada layar Utama ini." "Tidak ada ruang tersisa di baki Favorit" "Daftar aplikasi" @@ -73,8 +73,8 @@ "Layar utama %1$d dari %2$d" "Halaman layar utama baru" "Folder dibuka, %1$d x %2$d" - "Tap untuk menutup folder" - "Tap untuk menyimpan ganti nama" + "Ketuk untuk menutup folder" + "Ketuk untuk menyimpan ganti nama" "Folder ditutup" "Folder diganti namanya menjadi %1$s" "Folder: %1$s" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 19c06976b0..49e38982cd 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -35,18 +35,18 @@ "%1$d रूंद बाय %2$d उंच" "स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा" "आपोआप जोडा" - "अॅप्स शोधा" - "अॅप्स लोड करत आहे…" - "\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत" - "अधिक अॅप्स शोधा" + "अ‍ॅप्स शोधा" + "अ‍ॅप्स लोड करत आहे…" + "\"%1$s\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत" + "अधिक अ‍ॅप्स शोधा" "ॲप" "सूचना" "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा." "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा." "या मुख्य स्क्रीनवर आणखी जागा नाही." "आवडीच्या ट्रे मध्ये आणखी जागा नाही" - "अॅप्स सूची" - "वैयक्तिक अॅप्स सूची" + "अ‍ॅप्स सूची" + "वैयक्तिक अ‍ॅप्स सूची" "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची" "होम" "काढा" @@ -136,7 +136,7 @@ "कामाची अ‍ॅप्स येथे मिळवा" "प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा." "तुमच्या संस्थेकडून व्यवस्थापित" - "सूचना आणि अॅप्स बंद आहेत" + "सूचना आणि अ‍ॅप्स बंद आहेत" "बंद करा" "बंद केले" "हे करता आले नाही: %1$s" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34e267da9b..23b00d0936 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -90,7 +90,7 @@ "Значки уведомлений" "Включены" "Отключены" - "Нет доступа к уведомлениям" + "Нужен доступ к уведомлениям" "Чтобы показывать значки уведомлений, включите уведомления в приложении \"%1$s\"" "Изменить настройки" "Показывать значки уведомлений" From 7a4ed2f258939f8d558bd9264dfa6f1940883db2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 15 Jul 2019 18:48:06 -0700 Subject: [PATCH 21/34] Removing tracing for fixed bugs Bug: 133009122 Bug: 133765434 Bug: 134532571 Change-Id: I37aa1851a1bc0874c0b9acf561bde28966e9b523 --- .../LauncherActivityControllerHelper.java | 3 --- .../WindowTransformSwipeHandler.java | 21 ------------------ .../com/android/quickstep/views/TaskView.java | 9 -------- src/com/android/launcher3/Launcher.java | 3 --- .../launcher3/LauncherStateManager.java | 8 ------- src/com/android/launcher3/Workspace.java | 8 ------- .../dragndrop/BaseItemDragListener.java | 3 --- .../launcher3/dragndrop/DragController.java | 22 ------------------- .../popup/PopupContainerWithArrow.java | 5 ----- .../launcher3/testing/TestProtocol.java | 3 --- .../launcher3/views/BaseDragLayer.java | 8 ------- .../com/android/launcher3/tapl/AllApps.java | 2 -- .../android/launcher3/tapl/Background.java | 2 -- .../android/launcher3/tapl/Launchable.java | 2 -- .../android/launcher3/tapl/OverviewTask.java | 2 -- .../com/android/launcher3/tapl/Workspace.java | 4 ---- 16 files changed, 105 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java index b2a71a4882..894edd46c7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -194,9 +194,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe @Override public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible, boolean animateActivity, Consumer callback) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "prepareRecentsUI"); - } final LauncherState startState = activity.getStateManager().getState(); LauncherState resetState = startState; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index c60b28de3b..6f30a5651c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -439,32 +439,17 @@ public class WindowTransformSwipeHandler extends } private void onLauncherStart(final T activity) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart"); - } if (mActivity != activity) { return; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 1"); - } if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 2"); - } // If we've already ended the gesture and are going home, don't prepare recents UI, // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL. if (mGestureEndTarget != HOME) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 3"); - } Runnable initAnimFactory = () -> { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 4"); - } mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible, true, this::onAnimatorPlaybackControllerCreated); @@ -474,14 +459,8 @@ public class WindowTransformSwipeHandler extends // Launcher is visible, but might be about to stop. Thus, if we prepare recents // now, it might get overridden by moveToRestState() in onStop(). To avoid this, // wait until the next gesture (and possibly launcher) starts. - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 5"); - } mStateCallback.addCallback(STATE_GESTURE_STARTED, initAnimFactory); } else { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 6"); - } initAnimFactory.run(); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index b26fdce92f..2211eb4dd7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -192,9 +192,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { super(context, attrs, defStyleAttr); mActivity = BaseDraggingActivity.fromContext(context); setOnClickListener((view) -> { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "TaskView onClick"); - } if (getTask() == null) { return; } @@ -291,9 +288,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { public void launchTask(boolean animate, boolean freezeTaskList, Consumer resultCallback, Handler resultCallbackHandler) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "launchTask"); - } if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { if (isRunningTask()) { getRecentsView().finishRecentsAnimation(false /* toRecents */, @@ -308,9 +302,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private void launchTaskInternal(boolean animate, boolean freezeTaskList, Consumer resultCallback, Handler resultCallbackHandler) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "launchTaskInternal"); - } if (mTask != null) { final ActivityOptions opts; if (animate) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 9229832687..03fdc971dd 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -890,9 +890,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override protected void onStart() { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart"); - } RaceConditionTracker.onEvent(ON_START_EVT, ENTER); super.onStart(); if (mLauncherCallbacks != null) { diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index ccd6efaf55..d66e5813b9 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -403,10 +403,6 @@ public class LauncherStateManager { } private void onStateTransitionStart(LauncherState state) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onStateTransitionStart"); - } if (mState != state) { mState.onStateDisabled(mLauncher); } @@ -575,10 +571,6 @@ public class LauncherStateManager { private final AnimatorSet mAnim; public StartAnimRunnable(AnimatorSet anim) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "StartAnimRunnable"); - } mAnim = anim; } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 9f846bbc4d..8cd0822991 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -370,10 +370,6 @@ public class Workspace extends PagedView @Override public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onDragStart 1"); - } if (ENFORCE_DRAG_EVENT_ORDER) { enforceDragParity("onDragStart", 0, 0); } @@ -424,10 +420,6 @@ public class Workspace extends PagedView } // Always enter the spring loaded mode - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onDragStart 2"); - } mLauncher.getStateManager().goToState(SPRING_LOADED); } diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index c719c1c986..1b08723f63 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -137,9 +137,6 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen @Override public boolean shouldStartDrag(double distanceDragged) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, "BIDL.shouldStartDrag"); - } // Stay in pre-drag mode, if workspace is locked. return !mLauncher.isWorkspaceLocked(); } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 72a1abb833..d32dd2eb98 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -474,10 +474,6 @@ public class DragController implements DragDriver.EventListener, TouchController } private void handleMoveEvent(int x, int y) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent 1"); - } mDragObject.dragView.move(x, y); // Drop on someone? @@ -492,22 +488,8 @@ public class DragController implements DragDriver.EventListener, TouchController mLastTouch[0] = x; mLastTouch[1] = y; - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent Conditions " + - mIsInPreDrag + ", " + - (mIsInPreDrag && mOptions.preDragCondition != null) + ", " + - (mIsInPreDrag && mOptions.preDragCondition != null - && mOptions.preDragCondition.shouldStartDrag( - mDistanceSinceScroll))); - } - if (mIsInPreDrag && mOptions.preDragCondition != null && mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent 2"); - } callOnDragStart(); } } @@ -545,10 +527,6 @@ public class DragController implements DragDriver.EventListener, TouchController * Call this from a drag source view. */ public boolean onControllerTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onControllerTouchEvent"); - } if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) { return false; } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 9719a1892f..25d9f7976a 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -449,11 +449,6 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, @Override public boolean shouldStartDrag(double distanceDragged) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, - "createPreDragCondition().shouldStartDrag " + distanceDragged + ", " - + mStartDragThreshold); - } return distanceDragged > mStartDragThreshold; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index e28eba8094..6bdc0ab462 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -74,7 +74,4 @@ public final class TestProtocol { public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; - public static final String NO_DRAG_TAG = "b/133009122"; - public static final String NO_START_TASK_TAG = "b/133765434"; - public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 8bf33bf05c..594a24630b 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -230,10 +230,6 @@ public abstract class BaseDragLayer @Override public boolean onTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onTouchEvent " + ev); - } int action = ev.getAction(); if (action == ACTION_UP || action == ACTION_CANCEL) { if (mTouchCompleteListener != null) { @@ -243,10 +239,6 @@ public abstract class BaseDragLayer } if (mActiveController != null) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onTouchEvent 1"); - } return mActiveController.onControllerTouchEvent(ev); } else { // In case no child view handled the touch event, we may not get onIntercept anymore diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index 0ac5e9f887..9ff354a7eb 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -181,7 +181,6 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { * Flings backward (up) and waits the fling's end. */ public void flingBackward() { - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to fling backward in all apps")) { final UiObject2 allAppsContainer = verifyActiveContainer(); @@ -190,7 +189,6 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { allAppsContainer, Direction.UP, 1, new Rect(0, mHeight / 2, 0, 0), 10); verifyActiveContainer(); } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /** diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index c9eaf276d7..060bf30202 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -59,7 +59,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } protected void goToOverviewUnchecked(int expectedState) { - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); switch (mLauncher.getNavigationModel()) { case ZERO_BUTTON: { final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; @@ -112,7 +111,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { mLauncher.waitForSystemUiObject("recent_apps").click(); break; } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } protected String getSwipeHeightRequestName() { diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 04b8019450..82af7b03ac 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -53,11 +53,9 @@ abstract class Launchable { private Background launch(BySelector selector) { LauncherInstrumentation.log("Launchable.launch before click " + mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds()); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); mLauncher.assertTrue( "Launching an app didn't open a new window: " + mObject.getText(), mObject.clickAndWait(Until.newWindow(), WAIT_TIME_MS)); - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); mLauncher.assertTrue( "App didn't start: " + selector, mLauncher.getDevice().wait(Until.hasObject(selector), diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 641c413538..6e3332260b 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -64,14 +64,12 @@ public final class OverviewTask { */ public Background open() { verifyActiveContainer(); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "clicking an overview task")) { mLauncher.assertTrue("Launching task didn't open a new window: " + mTask.getParent().getContentDescription(), mTask.clickAndWait(Until.newWindow(), WAIT_TIME_MS)); } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); return new Background(mLauncher); } } diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index b01b6f363c..07f8b64433 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -67,7 +67,6 @@ public final class Workspace extends Home { "switchToAllApps: swipeHeight = " + swipeHeight + ", slop = " + mLauncher.getTouchSlop()); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); mLauncher.swipeToState( start.x, start.y, @@ -75,7 +74,6 @@ public final class Workspace extends Home { start.y - swipeHeight - mLauncher.getTouchSlop(), 60, ALL_APPS_STATE_ORDINAL); - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( "swiped to all apps")) { @@ -157,7 +155,6 @@ public final class Workspace extends Home { static void dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator) { - launcher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); LauncherInstrumentation.log("dragIconToWorkspace: begin"); final Point launchableCenter = launchable.getObject().getVisibleCenter(); final long downTime = SystemClock.uptimeMillis(); @@ -172,7 +169,6 @@ public final class Workspace extends Home { downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest); LauncherInstrumentation.log("dragIconToWorkspace: end"); launcher.waitUntilGone("drop_target_bar"); - launcher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /** From 2e4b665933b5c67d062b3c09787a8d42c8586d17 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 11 Jul 2019 11:55:22 -0700 Subject: [PATCH 22/34] Adding horizontal swipe support for 3p launcher Bug: 137197916 Change-Id: I0fb5db791b3471d651db43f0e8c30b8d5baf9f27 --- .../android/quickstep/BaseSwipeUpHandler.java | 157 ++++++++- .../quickstep/TouchInteractionService.java | 20 +- .../WindowTransformSwipeHandler.java | 135 ++------ .../fallback/FallbackRecentsView.java | 12 + .../FallbackNoButtonInputConsumer.java | 304 ++++++++++++++---- .../OtherActivityInputConsumer.java | 27 +- .../android/quickstep/views/RecentsView.java | 3 +- 7 files changed, 460 insertions(+), 198 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index d34b604a76..3032ca3079 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -18,26 +18,41 @@ package com.android.quickstep; import static android.os.VibrationEffect.EFFECT_CLICK; import static android.os.VibrationEffect.createPredefined; +import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; +import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.content.Intent; import android.graphics.PointF; import android.os.Build; +import android.os.Handler; +import android.os.Looper; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; import android.view.MotionEvent; import android.view.animation.Interpolator; +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.graphics.RotationMode; +import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.system.InputConsumerController; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import java.util.function.Consumer; @@ -47,7 +62,10 @@ import androidx.annotation.UiThread; * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { +public abstract class BaseSwipeUpHandler + implements SwipeAnimationListener { + + private static final String TAG = "BaseSwipeUpHandler"; // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -61,6 +79,9 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { protected float mDragLengthFactor = 1; protected final Context mContext; + protected final OverviewComponentObserver mOverviewComponentObserver; + protected final ActivityControlHelper mActivityControlHelper; + protected final RecentsModel mRecentsModel; protected final ClipAnimationHelper mClipAnimationHelper; protected final TransformParams mTransformParams = new TransformParams(); @@ -73,18 +94,48 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { // visible. protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); + protected final ActivityInitListener mActivityInitListener; + protected final RecentsAnimationWrapper mRecentsAnimationWrapper; + + protected T mActivity; protected RecentsView mRecentsView; + protected DeviceProfile mDp; + private final int mPageSpacing; protected Runnable mGestureEndCallback; - protected BaseSwipeUpHandler(Context context) { - mContext = context; - mClipAnimationHelper = new ClipAnimationHelper(context); + protected final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); + protected MultiStateCallback mStateCallback; + protected boolean mCanceled; + protected int mFinishingRecentsAnimationForNewTaskId = -1; + + protected BaseSwipeUpHandler(Context context, + OverviewComponentObserver overviewComponentObserver, + RecentsModel recentsModel, InputConsumerController inputConsumer) { + mContext = context; + mOverviewComponentObserver = overviewComponentObserver; + mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); + mRecentsModel = recentsModel; + mActivityInitListener = + mActivityControlHelper.createActivityInitListener(this::onActivityInit); + mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, + this::createNewInputProxyHandler); + + mClipAnimationHelper = new ClipAnimationHelper(context); + mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); mVibrator = context.getSystemService(Vibrator.class); } - public void performHapticFeedback() { + protected void setStateOnUiThread(int stateFlag) { + if (Looper.myLooper() == mMainThreadHandler.getLooper()) { + mStateCallback.setState(stateFlag); + } else { + postAsyncCallback(mMainThreadHandler, () -> mStateCallback.setState(stateFlag)); + } + } + + protected void performHapticFeedback() { if (!mVibrator.hasVibrator()) { return; } @@ -130,12 +181,76 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { mGestureEndCallback = gestureEndCallback; } + public abstract Intent getLaunchIntent(); + + protected void linkRecentsViewScroll() { + SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> { + mTransformParams.setSyncTransactionApplier(applier); + mRecentsAnimationWrapper.runOnInit(() -> + mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier)); + }); + + mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { + if (moveWindowWithRecentsScroll()) { + updateFinalShift(); + } + }); + mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); + mRecentsView.setClipAnimationHelper(mClipAnimationHelper); + } + + protected void startNewTask(int successStateFlag, Consumer resultCallback) { + // Launch the task user scrolled to (mRecentsView.getNextPage()). + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { + // We finish recents animation inside launchTask() when live tile is enabled. + mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */, + true /* freezeTaskList */); + } else { + int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id; + mFinishingRecentsAnimationForNewTaskId = taskId; + mRecentsAnimationWrapper.finish(true /* toRecents */, () -> { + if (!mCanceled) { + TaskView nextTask = mRecentsView.getTaskView(taskId); + if (nextTask != null) { + nextTask.launchTask(false /* animate */, true /* freezeTaskList */, + success -> { + resultCallback.accept(success); + if (!success) { + mActivityControlHelper.onLaunchTaskFailed(mActivity); + nextTask.notifyTaskLaunchFailed(TAG); + } else { + mActivityControlHelper.onLaunchTaskSuccess(mActivity); + } + }, mMainThreadHandler); + } + setStateOnUiThread(successStateFlag); + } + mCanceled = false; + mFinishingRecentsAnimationForNewTaskId = -1; + }); + } + TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); + } + + /** + * Return true if the window should be translated horizontally if the recents view scrolls + */ + protected abstract boolean moveWindowWithRecentsScroll(); + + protected abstract boolean onActivityInit(final T activity, Boolean alreadyOnHome); + + /** + * Called to create a input proxy for the running task + */ + @UiThread + protected abstract InputConsumer createNewInputProxyHandler(); + /** * Called when the value of {@link #mCurrentShift} changes */ + @UiThread public abstract void updateFinalShift(); - /** * Called when motion pause is detected */ @@ -150,15 +265,39 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { @UiThread public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); - public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { } + public abstract void onConsumerAboutToBeSwitched(SwipeSharedState sharedState); public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } - public void initWhenReady() { } + public void initWhenReady() { + // Preload the plan + mRecentsModel.getTasks(null); + + mActivityInitListener.register(); + } + + /** + * Applies the transform on the recents animation without any additional null checks + */ + protected void applyTransformUnchecked() { + float shift = mCurrentShift.value; + float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); + float offsetScale = getTaskCurveScaleForOffsetX(offsetX, + mClipAnimationHelper.getTargetRect().width()); + mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); + mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, + mTransformParams); + } + + private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) { + float distanceToReachEdge = mDp.widthPx / 2 + taskWidth / 2 + mPageSpacing; + float interpolation = Math.min(1, offsetX / distanceToReachEdge); + return TaskView.getCurveScaleForInterpolation(interpolation); + } public interface Factory { BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index fd4b3940a5..4bc4c761b0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -649,20 +649,17 @@ public class TouchInteractionService extends Service implements final boolean shouldDefer; final BaseSwipeUpHandler.Factory factory; - final Intent homeIntent; if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { - shouldDefer = true; + shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted; factory = mFallbackNoButtonFactory; - homeIntent = mOverviewComponentObserver.getHomeIntent(); } else { shouldDefer = mOverviewComponentObserver.getActivityControlHelper() .deferStartingActivity(mActiveNavBarRegion, event); factory = mWindowTreansformFactory; - homeIntent = mOverviewComponentObserver.getOverviewIntent(); } - return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent, + return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer, mOverviewCallbacks, this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe(event), factory); @@ -809,16 +806,15 @@ public class TouchInteractionService extends Service implements } private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture) { - return new WindowTransformSwipeHandler( - runningTask, this, touchTimeMs, - mOverviewComponentObserver.getActivityControlHelper(), - continuingLastGesture, mInputConsumer, mRecentsModel); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) { + return new WindowTransformSwipeHandler(runningTask, this, touchTimeMs, + mOverviewComponentObserver, continuingLastGesture, mInputConsumer, mRecentsModel); } private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture) { - return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) { + return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask, + mRecentsModel, mInputConsumer, isLikelyToStartNewTask, continuingLastGesture); } public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index c60b28de3b..184b8e131c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; -import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -32,7 +31,6 @@ import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATI import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.HIDE; import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.PEEK; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.HOME; import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.LAST_TASK; @@ -48,14 +46,13 @@ import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.content.Intent; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.View; @@ -82,7 +79,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.RaceConditionTracker; import com.android.launcher3.util.TraceHelper; import com.android.launcher3.views.FloatingIconView; -import com.android.quickstep.ActivityControlHelper.ActivityInitListener; import com.android.quickstep.ActivityControlHelper.AnimationFactory; import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState; import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; @@ -99,14 +95,14 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; import androidx.annotation.NonNull; import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) -public class WindowTransformSwipeHandler extends BaseSwipeUpHandler +public class WindowTransformSwipeHandler + extends BaseSwipeUpHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); @@ -219,35 +215,24 @@ public class WindowTransformSwipeHandler extends // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; - private DeviceProfile mDp; private boolean mContinuingLastGesture; // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; - private final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); - - private final ActivityControlHelper mActivityControlHelper; - private final ActivityInitListener mActivityInitListener; - private final RecentsModel mRecentsModel; - - private final SysUINavigationMode.Mode mMode; + private final Mode mMode; private final int mRunningTaskId; private ThumbnailData mTaskSnapshot; - private MultiStateCallback mStateCallback; // Used to control launcher components throughout the swipe gesture. private AnimatorPlaybackController mLauncherTransitionController; private boolean mHasLauncherTransitionControllerStarted; - private T mActivity; private AnimationFactory mAnimationFactory = (t) -> { }; private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay(); - private boolean mCanceled; private boolean mWasLauncherAlreadyVisible; - private int mFinishingRecentsAnimationForNewTaskId = -1; private boolean mPassedOverviewThreshold; private boolean mGestureStarted; @@ -256,24 +241,17 @@ public class WindowTransformSwipeHandler extends private PointF mDownPos; private boolean mIsLikelyToStartNewTask; - private final RecentsAnimationWrapper mRecentsAnimationWrapper; - private final long mTouchTimeMs; private long mLauncherFrameDrawnTime; public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, - long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, + long touchTimeMs, OverviewComponentObserver overviewComponentObserver, + boolean continuingLastGesture, InputConsumerController inputConsumer, RecentsModel recentsModel) { - super(context); + super(context, overviewComponentObserver, recentsModel, inputConsumer); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; - mActivityControlHelper = controller; - mRecentsModel = recentsModel; - mActivityInitListener = mActivityControlHelper - .createActivityInitListener(this::onActivityInit); mContinuingLastGesture = continuingLastGesture; - mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, - this::createNewInputProxyHandler); mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); @@ -342,14 +320,6 @@ public class WindowTransformSwipeHandler extends } } - private void setStateOnUiThread(int stateFlag) { - if (Looper.myLooper() == mMainThreadHandler.getLooper()) { - mStateCallback.setState(stateFlag); - } else { - postAsyncCallback(mMainThreadHandler, () -> mStateCallback.setState(stateFlag)); - } - } - private Rect getStackBounds(DeviceProfile dp) { if (mActivity != null) { int loc[] = new int[2]; @@ -383,14 +353,7 @@ public class WindowTransformSwipeHandler extends } @Override - public void initWhenReady() { - // Preload the plan - mRecentsModel.getTasks(null); - - mActivityInitListener.register(); - } - - private boolean onActivityInit(final T activity, Boolean alreadyOnHome) { + protected boolean onActivityInit(final T activity, Boolean alreadyOnHome) { if (mActivity == activity) { return true; } @@ -411,19 +374,7 @@ public class WindowTransformSwipeHandler extends } mRecentsView = activity.getOverviewPanel(); - SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> { - mTransformParams.setSyncTransactionApplier(applier); - mRecentsAnimationWrapper.runOnInit(() -> - mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier)); - }); - - mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { - if (mGestureEndTarget != HOME) { - updateFinalShift(); - } - }); - mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); - mRecentsView.setClipAnimationHelper(mClipAnimationHelper); + linkRecentsViewScroll(); mRecentsView.setLiveTileOverlay(mLiveTileOverlay); mActivity.getRootView().getOverlay().add(mLiveTileOverlay); @@ -438,6 +389,11 @@ public class WindowTransformSwipeHandler extends return true; } + @Override + protected boolean moveWindowWithRecentsScroll() { + return mGestureEndTarget != HOME; + } + private void onLauncherStart(final T activity) { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart"); @@ -654,20 +610,18 @@ public class WindowTransformSwipeHandler extends updateLauncherTransitionProgress(); } - @UiThread + @Override + public Intent getLaunchIntent() { + return mOverviewComponentObserver.getOverviewIntent(); + } + @Override public void updateFinalShift() { - float shift = mCurrentShift.value; SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); if (controller != null) { - float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); - float offsetScale = getTaskCurveScaleForOffsetX(offsetX, - mClipAnimationHelper.getTargetRect().width()); - mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); - mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, - mTransformParams); - updateSysUiFlags(shift); + applyTransformUnchecked(); + updateSysUiFlags(mCurrentShift.value); } if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { @@ -817,8 +771,8 @@ public class WindowTransformSwipeHandler extends handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */); } - @UiThread - private InputConsumer createNewInputProxyHandler() { + @Override + protected InputConsumer createNewInputProxyHandler() { endRunningWindowAnim(true /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { @@ -1208,40 +1162,15 @@ public class WindowTransformSwipeHandler extends @UiThread private void startNewTask() { - // Launch the task user scrolled to (mRecentsView.getNextPage()). - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - // We finish recents animation inside launchTask() when live tile is enabled. - mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */, - true /* freezeTaskList */); - } else { - int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id; - mFinishingRecentsAnimationForNewTaskId = taskId; - mRecentsAnimationWrapper.finish(true /* toRecents */, () -> { - if (!mCanceled) { - TaskView nextTask = mRecentsView.getTaskView(taskId); - if (nextTask != null) { - nextTask.launchTask(false /* animate */, true /* freezeTaskList */, - success -> { - if (!success) { - // We couldn't launch the task, so take user to overview so they can - // decide what to do instead of staying in this broken state. - endLauncherTransitionController(); - mActivityControlHelper.onLaunchTaskFailed(mActivity); - nextTask.notifyTaskLaunchFailed(TAG); - updateSysUiFlags(1 /* windowProgress == overview */); - } else { - mActivityControlHelper.onLaunchTaskSuccess(mActivity); - } - }, mMainThreadHandler); - doLogGesture(NEW_TASK); - } - reset(); - } - mCanceled = false; - mFinishingRecentsAnimationForNewTaskId = -1; - }); - } - TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); + startNewTask(STATE_HANDLER_INVALIDATED, success -> { + if (!success) { + // We couldn't launch the task, so take user to overview so they can + // decide what to do instead of staying in this broken state. + endLauncherTransitionController(); + updateSysUiFlags(1 /* windowProgress == overview */); + } + doLogGesture(NEW_TASK); + }); } private void reset() { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index c28761804b..eaf6ebac80 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -87,6 +87,12 @@ public class FallbackRecentsView extends RecentsView { super.draw(canvas); } + @Override + public void reset() { + super.reset(); + resetViewUI(); + } + @Override protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateFallbackTaskSize(getContext(), dp, outRect); @@ -114,6 +120,12 @@ public class FallbackRecentsView extends RecentsView { } } + @Override + public void resetTaskVisuals() { + super.resetTaskVisuals(); + setFullscreenProgress(mFullscreenProgress); + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index a5a8f388f4..a0e806eee3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -15,15 +15,16 @@ */ package com.android.quickstep.inputconsumers; +import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityOptions; @@ -34,24 +35,53 @@ import android.graphics.Rect; import android.os.Bundle; import android.view.WindowManager; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; -import com.android.quickstep.ActivityControlHelper; +import com.android.launcher3.anim.AnimationSuccessListener; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; +import com.android.quickstep.MultiStateCallback; import com.android.quickstep.OverviewComponentObserver; +import com.android.quickstep.RecentsActivity; +import com.android.quickstep.RecentsModel; +import com.android.quickstep.SwipeSharedState; +import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.SwipeAnimationTargetSet; +import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.ActivityOptionsCompat; +import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { + + private static final String[] STATE_NAMES = DEBUG_STATES ? new String[5] : null; + + private static int getFlagForIndex(int index, String name) { + if (DEBUG_STATES) { + STATE_NAMES[index] = name; + } + return 1 << index; + } + + private static final int STATE_RECENTS_PRESENT = + getFlagForIndex(0, "STATE_RECENTS_PRESENT"); + private static final int STATE_HANDLER_INVALIDATED = + getFlagForIndex(1, "STATE_HANDLER_INVALIDATED"); + + private static final int STATE_GESTURE_CANCELLED = + getFlagForIndex(2, "STATE_GESTURE_CANCELLED"); + private static final int STATE_GESTURE_COMPLETED = + getFlagForIndex(3, "STATE_GESTURE_COMPLETED"); + private static final int STATE_APP_CONTROLLER_RECEIVED = + getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED"); public enum GestureEndTarget { HOME(3, 100, 1), RECENTS(1, 300, 0), - LAST_TASK(0, 150, 1); + LAST_TASK(0, 150, 1), + NEW_TASK(0, 150, 1); private final float mEndProgress; private final long mDurationMultiplier; @@ -64,53 +94,131 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { } } - private final ActivityControlHelper mActivityControlHelper; - private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; - private final DeviceProfile mDP; private final Rect mTargetRect = new Rect(); private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); - private SwipeAnimationTargetSet mSwipeAnimationTargetSet; - private boolean mIsMotionPaused = false; private GestureEndTarget mEndTarget; + private final boolean mInQuickSwitchMode; + private final boolean mContinuingLastGesture; + + private Animator mFinishAnimation; + public FallbackNoButtonInputConsumer(Context context, OverviewComponentObserver overviewComponentObserver, - RunningTaskInfo runningTaskInfo) { - super(context); - mOverviewComponentObserver = overviewComponentObserver; - mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); + RunningTaskInfo runningTaskInfo, RecentsModel recentsModel, + InputConsumerController inputConsumer, + boolean isLikelyToStartNewTask, boolean continuingLastGesture) { + super(context, overviewComponentObserver, recentsModel, inputConsumer); mRunningTaskId = runningTaskInfo.id; - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); + mDp = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); mLauncherAlpha.value = 1; + mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture; + mContinuingLastGesture = continuingLastGesture; mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + initStateCallbacks(); initTransitionTarget(); } + private void initStateCallbacks() { + mStateCallback = new MultiStateCallback(STATE_NAMES); + + mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, + this::onHandlerInvalidated); + mStateCallback.addCallback(STATE_RECENTS_PRESENT | STATE_HANDLER_INVALIDATED, + this::onHandlerInvalidatedWithRecents); + + mStateCallback.addCallback(STATE_GESTURE_CANCELLED | STATE_APP_CONTROLLER_RECEIVED, + this::finishAnimationTargetSetAnimationComplete); + + if (mInQuickSwitchMode) { + mStateCallback.addCallback(STATE_GESTURE_COMPLETED | STATE_APP_CONTROLLER_RECEIVED + | STATE_RECENTS_PRESENT, + this::finishAnimationTargetSet); + } else { + mStateCallback.addCallback(STATE_GESTURE_COMPLETED | STATE_APP_CONTROLLER_RECEIVED, + this::finishAnimationTargetSet); + } + } + private void onLauncherAlphaChanged() { - if (mSwipeAnimationTargetSet != null && mEndTarget == null) { - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + if (mRecentsAnimationWrapper.targetSet != null && mEndTarget == null) { + applyTransformUnchecked(); } } + @Override + protected boolean onActivityInit(final RecentsActivity activity, Boolean alreadyOnHome) { + mActivity = activity; + mRecentsView = activity.getOverviewPanel(); + linkRecentsViewScroll(); + mRecentsView.setDisallowScrollToClearAll(true); + mRecentsView.getClearAllButton().setVisibilityAlpha(0); + + ((FallbackRecentsView) mRecentsView).setZoomProgress(1); + + if (!mContinuingLastGesture) { + mRecentsView.onGestureAnimationStart(mRunningTaskId); + } + setStateOnUiThread(STATE_RECENTS_PRESENT); + return true; + } + + @Override + protected boolean moveWindowWithRecentsScroll() { + return mInQuickSwitchMode; + } + + @Override + public void initWhenReady() { + if (mInQuickSwitchMode) { + // Only init if we are in quickswitch mode + super.initWhenReady(); + } + } + + @Override + public void updateDisplacement(float displacement) { + if (!mInQuickSwitchMode) { + super.updateDisplacement(displacement); + } + } + + @Override + protected InputConsumer createNewInputProxyHandler() { + // Just consume all input on the active task + return InputConsumer.NO_OP; + } + @Override public void onMotionPauseChanged(boolean isPaused) { - mIsMotionPaused = isPaused; - mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) - .setDuration(150).start(); - performHapticFeedback(); + if (!mInQuickSwitchMode) { + mIsMotionPaused = isPaused; + mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) + .setDuration(150).start(); + performHapticFeedback(); + } + } + + @Override + public Intent getLaunchIntent() { + if (mInQuickSwitchMode) { + return mOverviewComponentObserver.getOverviewIntent(); + } else { + return mOverviewComponentObserver.getHomeIntent(); + } } @Override public void updateFinalShift() { mTransformParams.setProgress(mCurrentShift.value); - if (mSwipeAnimationTargetSet != null) { - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + if (mRecentsAnimationWrapper.targetSet != null) { + applyTransformUnchecked(); } } @@ -118,41 +226,90 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { public void onGestureCancelled() { updateDisplacement(0); mEndTarget = LAST_TASK; - finishAnimationTargetSetAnimationComplete(); + setStateOnUiThread(STATE_GESTURE_CANCELLED); } @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { - float flingThreshold = mContext.getResources() - .getDimension(R.dimen.quickstep_fling_threshold_velocity); - boolean isFling = Math.abs(endVelocity) > flingThreshold; - - if (isFling) { - mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; - } else if (mIsMotionPaused) { - mEndTarget = RECENTS; + if (mInQuickSwitchMode) { + // For now set it to non-null, it will be reset before starting the animation + mEndTarget = LAST_TASK; } else { - mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; + float flingThreshold = mContext.getResources() + .getDimension(R.dimen.quickstep_fling_threshold_velocity); + boolean isFling = Math.abs(endVelocity) > flingThreshold; + + if (isFling) { + mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; + } else { + mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; + } } - if (mSwipeAnimationTargetSet != null) { - finishAnimationTargetSet(); + setStateOnUiThread(STATE_GESTURE_COMPLETED); + } + + @Override + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { + if (mInQuickSwitchMode && mEndTarget != null) { + sharedState.canGestureBeContinued = true; + sharedState.goingToLauncher = false; + + mCanceled = true; + mCurrentShift.cancelAnimation(); + if (mFinishAnimation != null) { + mFinishAnimation.cancel(); + } + + if (mRecentsView != null) { + if (mFinishingRecentsAnimationForNewTaskId != -1) { + TaskView newRunningTaskView = mRecentsView.getTaskView( + mFinishingRecentsAnimationForNewTaskId); + int newRunningTaskId = newRunningTaskView != null + ? newRunningTaskView.getTask().key.id + : -1; + mRecentsView.setCurrentTask(newRunningTaskId); + sharedState.setRecentsAnimationFinishInterrupted(newRunningTaskId); + } + mRecentsView.setOnScrollChangeListener(null); + } + } else { + setStateOnUiThread(STATE_HANDLER_INVALIDATED); } } + + private void onHandlerInvalidated() { + mActivityInitListener.unregister(); + if (mGestureEndCallback != null) { + mGestureEndCallback.run(); + } + } + + private void onHandlerInvalidatedWithRecents() { + mRecentsView.onGestureAnimationEnd(); + mRecentsView.setDisallowScrollToClearAll(false); + mRecentsView.getClearAllButton().setVisibilityAlpha(1); + } + + private void finishAnimationTargetSetAnimationComplete() { switch (mEndTarget) { case HOME: - mSwipeAnimationTargetSet.finishController(true, null, true); + mRecentsAnimationWrapper.finish(true, null, true); break; case LAST_TASK: - mSwipeAnimationTargetSet.finishController(false, null, false); + mRecentsAnimationWrapper.finish(false, null, false); break; case RECENTS: { ThumbnailData thumbnail = - mSwipeAnimationTargetSet.controller.screenshotTask(mRunningTaskId); - mSwipeAnimationTargetSet.controller.setCancelWithDeferredScreenshot(true); + mRecentsAnimationWrapper.targetSet.controller.screenshotTask(mRunningTaskId); + mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true); ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); + ActivityOptionsCompat.setFreezeRecentTasksList(options); + Bundle extras = new Bundle(); extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail)); extras.putInt(EXTRA_TASK_ID, mRunningTaskId); @@ -160,33 +317,58 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent()) .putExtras(extras); mContext.startActivity(intent, options.toBundle()); - mSwipeAnimationTargetSet.controller.cleanupScreenshot(); + mRecentsAnimationWrapper.targetSet.controller.cleanupScreenshot(); + break; + } + case NEW_TASK: { + startNewTask(STATE_HANDLER_INVALIDATED, b -> {}); break; } } - if (mGestureEndCallback != null) { - mGestureEndCallback.run(); - } + + setStateOnUiThread(STATE_HANDLER_INVALIDATED); } private void finishAnimationTargetSet() { + if (mInQuickSwitchMode) { + // Recalculate the end target, some views might have been initialized after + // gesture has ended. + if (mRecentsView == null || !mRecentsAnimationWrapper.hasTargets()) { + mEndTarget = LAST_TASK; + } else { + final int runningTaskIndex = mRecentsView.getRunningTaskIndex(); + final int taskToLaunch = mRecentsView.getNextPage(); + mEndTarget = (runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex) + ? NEW_TASK : LAST_TASK; + } + } + float endProgress = mEndTarget.mEndProgress; - if (mCurrentShift.value != endProgress) { + if (mCurrentShift.value != endProgress || mInQuickSwitchMode) { AnimatorSet anim = new AnimatorSet(); anim.play(mLauncherAlpha.animateToValue( mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); - anim.setDuration((long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mCurrentShift.value))); - anim.addListener(new AnimatorListenerAdapter() { + + long duration = (long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mCurrentShift.value)); + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } + + anim.setDuration(duration); + anim.addListener(new AnimationSuccessListener() { + @Override - public void onAnimationEnd(Animator animation) { + public void onAnimationSuccess(Animator animator) { finishAnimationTargetSetAnimationComplete(); + mFinishAnimation = null; } }); anim.start(); + mFinishAnimation = anim; } else { finishAnimationTargetSetAnimationComplete(); } @@ -194,34 +376,36 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { @Override public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { - mSwipeAnimationTargetSet = targetSet; - Rect overviewStackBounds = new Rect(0, 0, mDP.widthPx, mDP.heightPx); + mRecentsAnimationWrapper.setController(targetSet); + mRecentsAnimationWrapper.enableInputConsumer(); + Rect overviewStackBounds = new Rect(0, 0, mDp.widthPx, mDp.heightPx); RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); - mDP.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + mDp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); if (targetSet.homeContentInsets != null) { - mDP.updateInsets(targetSet.homeContentInsets); + mDp.updateInsets(targetSet.homeContentInsets); } if (runningTaskTarget != null) { mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); } - mClipAnimationHelper.prepareAnimation(mDP, false /* isOpening */); + mClipAnimationHelper.prepareAnimation(mDp, false /* isOpening */); initTransitionTarget(); - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + applyTransformUnchecked(); - if (mEndTarget != null) { - finishAnimationTargetSet(); - } + setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED); } private void initTransitionTarget() { mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - mDP, mContext, mTargetRect); - mDragLengthFactor = (float) mDP.heightPx / mTransitionDragLength; + mDp, mContext, mTargetRect); + mDragLengthFactor = (float) mDp.heightPx / mTransitionDragLength; mClipAnimationHelper.updateTargetRect(mTargetRect); } @Override - public void onRecentsAnimationCanceled() { } + public void onRecentsAnimationCanceled() { + mRecentsAnimationWrapper.setController(null); + setStateOnUiThread(STATE_HANDLER_INVALIDATED); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 9114995cc9..86766d99fb 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -35,7 +35,6 @@ import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.ContextWrapper; -import android.content.Intent; import android.graphics.PointF; import android.graphics.RectF; import android.os.Build; @@ -79,7 +78,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final RunningTaskInfo mRunningTask; - private final Intent mHomeIntent; private final OverviewCallbacks mOverviewCallbacks; private final SwipeSharedState mSwipeSharedState; private final InputMonitorCompat mInputMonitorCompat; @@ -117,12 +115,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private float mStartDisplacement; private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> + private Runnable mCancelRecentsAnimationRunnable = () -> { ActivityManagerWrapper.getInstance().cancelRecentsAnimation( true /* restoreHomeStackPosition */); + }; public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo, - Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, + boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, Consumer onCompleteCallback, SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, boolean disableHorizontalSwipe, @@ -131,7 +130,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mMainThreadHandler = new Handler(Looper.getMainLooper()); mRunningTask = runningTaskInfo; - mHomeIntent = homeIntent; mMode = SysUINavigationMode.getMode(base); mSwipeTouchRegion = swipeTouchRegion; mHandlerFactory = handlerFactory; @@ -204,7 +202,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Start the window animation on down to give more time for launcher to draw if the // user didn't start the gesture over the back button if (!mIsDeferredDownTarget) { - startTouchTrackingForWindowAnimation(ev.getEventTime()); + startTouchTrackingForWindowAnimation(ev.getEventTime(), false); } RaceConditionTracker.onEvent(DOWN_EVT, EXIT); @@ -253,6 +251,10 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } } + float horizontalDist = Math.abs(displacementX); + float upDist = -displacement; + boolean isLikelyToStartNewTask = horizontalDist > upDist; + if (!mPassedPilferInputSlop) { float displacementY = mLastPos.y - mDownPos.y; if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) { @@ -268,7 +270,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mIsDeferredDownTarget) { // Deferred gesture, start the animation and gesture tracking once // we pass the actual touch slop - startTouchTrackingForWindowAnimation(ev.getEventTime()); + startTouchTrackingForWindowAnimation( + ev.getEventTime(), isLikelyToStartNewTask); } if (!mPassedWindowMoveSlop) { mPassedWindowMoveSlop = true; @@ -286,9 +289,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mMode == Mode.NO_BUTTON) { - float horizontalDist = Math.abs(displacementX); - float upDist = -displacement; - boolean isLikelyToStartNewTask = horizontalDist > upDist; mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement || isLikelyToStartNewTask); mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); @@ -320,12 +320,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mInteractionHandler.onGestureStarted(); } - private void startTouchTrackingForWindowAnimation(long touchTimeMs) { + private void startTouchTrackingForWindowAnimation( + long touchTimeMs, boolean isLikelyToStartNewTask) { TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener(); final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs, - listenerSet != null); + listenerSet != null, isLikelyToStartNewTask); mInteractionHandler = handler; handler.setGestureEndCallback(this::onInteractionGestureFinished); @@ -340,7 +341,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RecentsAnimationListenerSet newListenerSet = mSwipeSharedState.newRecentsAnimationListenerSet(); newListenerSet.addListener(handler); - startRecentsActivityAsync(mHomeIntent, newListenerSet); + startRecentsActivityAsync(handler.getLaunchIntent(), newListenerSet); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 432f8a1355..6bf3155b41 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -289,7 +289,7 @@ public abstract class RecentsView extends PagedView impl @ViewDebug.ExportedProperty(category = "launcher") private float mContentAlpha = 1; @ViewDebug.ExportedProperty(category = "launcher") - private float mFullscreenProgress = 0; + protected float mFullscreenProgress = 0; // Keeps track of task id whose visual state should not be reset private int mIgnoreResetTaskId = -1; @@ -604,6 +604,7 @@ public abstract class RecentsView extends PagedView impl TaskView taskView = (TaskView) getChildAt(i); if (mIgnoreResetTaskId != taskView.getTask().key.id) { taskView.resetVisualProperties(); + taskView.setStableAlpha(mContentAlpha); } } if (mRunningTaskTileHidden) { From 587c3cef518d744b6d5973fc7da73e817e415d7b Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 12 Jul 2019 10:17:12 -0700 Subject: [PATCH 23/34] Fixing multiwindow transition when using 3P launcher Bug: 137197916 Change-Id: I3c5cfc290972187d9d556a722afc61489d0d0629 --- .../android/quickstep/BaseSwipeUpHandler.java | 76 ++++++++++++++++++- .../android/quickstep/RecentsActivity.java | 14 ++-- .../WindowTransformSwipeHandler.java | 74 +----------------- .../FallbackNoButtonInputConsumer.java | 35 +-------- 4 files changed, 87 insertions(+), 112 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 3032ca3079..23fe2dee10 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -29,7 +29,9 @@ import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; +import android.graphics.Point; import android.graphics.PointF; +import android.graphics.Rect; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -37,21 +39,27 @@ import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; import android.view.animation.Interpolator; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.graphics.RotationMode; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.InputConsumerController; +import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import java.util.function.Consumer; @@ -66,6 +74,7 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { private static final String TAG = "BaseSwipeUpHandler"; + protected static final Rect TEMP_RECT = new Rect(); // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -82,11 +91,13 @@ public abstract class BaseSwipeUpHandler protected final OverviewComponentObserver mOverviewComponentObserver; protected final ActivityControlHelper mActivityControlHelper; protected final RecentsModel mRecentsModel; + protected final int mRunningTaskId; protected final ClipAnimationHelper mClipAnimationHelper; protected final TransformParams mTransformParams = new TransformParams(); private final Vibrator mVibrator; + protected final Mode mMode; // Shift in the range of [0, 1]. // 0 => preview snapShot is completely visible, and hotseat is completely translated down @@ -112,19 +123,23 @@ public abstract class BaseSwipeUpHandler protected BaseSwipeUpHandler(Context context, OverviewComponentObserver overviewComponentObserver, - RecentsModel recentsModel, InputConsumerController inputConsumer) { + RecentsModel recentsModel, InputConsumerController inputConsumer, int runningTaskId) { mContext = context; mOverviewComponentObserver = overviewComponentObserver; mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); mRecentsModel = recentsModel; mActivityInitListener = mActivityControlHelper.createActivityInitListener(this::onActivityInit); + mRunningTaskId = runningTaskId; mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, this::createNewInputProxyHandler); + mMode = SysUINavigationMode.getMode(context); mClipAnimationHelper = new ClipAnimationHelper(context); mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); mVibrator = context.getSystemService(Vibrator.class); + initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext) + .getDeviceProfile(mContext)); } protected void setStateOnUiThread(int stateFlag) { @@ -232,6 +247,65 @@ public abstract class BaseSwipeUpHandler TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); } + @Override + public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); + final Rect overviewStackBounds; + RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); + + if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) { + overviewStackBounds = mActivityControlHelper + .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); + dp = dp.getMultiWindowProfile(mContext, new Point( + overviewStackBounds.width(), overviewStackBounds.height())); + } else { + // If we are not in multi-window mode, home insets should be same as system insets. + dp = dp.copy(mContext); + overviewStackBounds = getStackBounds(dp); + } + dp.updateInsets(targetSet.homeContentInsets); + dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + if (runningTaskTarget != null) { + mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); + } + + mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */); + initTransitionEndpoints(dp); + + mRecentsAnimationWrapper.setController(targetSet); + } + + private Rect getStackBounds(DeviceProfile dp) { + if (mActivity != null) { + int loc[] = new int[2]; + View rootView = mActivity.getRootView(); + rootView.getLocationOnScreen(loc); + return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), + loc[1] + rootView.getHeight()); + } else { + return new Rect(0, 0, dp.widthPx, dp.heightPx); + } + } + + protected void initTransitionEndpoints(DeviceProfile dp) { + mDp = dp; + + mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( + dp, mContext, TEMP_RECT); + if (!dp.isMultiWindowMode) { + // When updating the target rect, also update the home bounds since the location on + // screen of the launcher window may be stale (position is not updated until first + // traversal after the window is resized). We only do this for non-multiwindow because + // we otherwise use the minimized home bounds provided by the system. + mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); + } + mClipAnimationHelper.updateTargetRect(TEMP_RECT); + if (mMode == Mode.NO_BUTTON) { + // We can drag all the way to the top of the screen. + mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength; + } + } + /** * Return true if the window should be translated horizontally if the recents view scrolls */ diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 61767e5f74..60e7b12ec4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -87,12 +87,14 @@ public final class RecentsActivity extends BaseRecentsActivity { @Override protected void onNewIntent(Intent intent) { - int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); - IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); - if (taskID != 0 && thumbnail instanceof ObjectWrapper) { - ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); - mFallbackRecentsView.showCurrentTask(taskID); - mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + if (intent.getExtras() != null) { + int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); + IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); + if (taskID != 0 && thumbnail instanceof ObjectWrapper) { + ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); + mFallbackRecentsView.showCurrentTask(taskID); + mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + } } intent.removeExtra(EXTRA_TASK_ID); intent.removeExtra(EXTRA_THUMBNAIL); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ec16d881a5..d0332529be 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -48,9 +48,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; import android.graphics.Canvas; -import android.graphics.Point; import android.graphics.PointF; -import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.os.SystemClock; @@ -59,13 +57,11 @@ import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; import android.view.WindowInsets; -import android.view.WindowManager; import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; @@ -106,8 +102,6 @@ public class WindowTransformSwipeHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); - private static final Rect TEMP_RECT = new Rect(); - private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null; private static int getFlagForIndex(int index, String name) { @@ -220,9 +214,6 @@ public class WindowTransformSwipeHandler // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; - private final Mode mMode; - - private final int mRunningTaskId; private ThumbnailData mTaskSnapshot; // Used to control launcher components throughout the swipe gesture. @@ -248,16 +239,10 @@ public class WindowTransformSwipeHandler long touchTimeMs, OverviewComponentObserver overviewComponentObserver, boolean continuingLastGesture, InputConsumerController inputConsumer, RecentsModel recentsModel) { - super(context, overviewComponentObserver, recentsModel, inputConsumer); - mRunningTaskId = runningTaskInfo.id; + super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id); mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; - - mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); - - DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); - initTransitionEndpoints(dp); } private void initStateCallbacks() { @@ -320,38 +305,6 @@ public class WindowTransformSwipeHandler } } - private Rect getStackBounds(DeviceProfile dp) { - if (mActivity != null) { - int loc[] = new int[2]; - View rootView = mActivity.getRootView(); - rootView.getLocationOnScreen(loc); - return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), - loc[1] + rootView.getHeight()); - } else { - return new Rect(0, 0, dp.widthPx, dp.heightPx); - } - } - - private void initTransitionEndpoints(DeviceProfile dp) { - mDp = dp; - - Rect tempRect = new Rect(); - mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - dp, mContext, tempRect); - if (!dp.isMultiWindowMode) { - // When updating the target rect, also update the home bounds since the location on - // screen of the launcher window may be stale (position is not updated until first - // traversal after the window is resized). We only do this for non-multiwindow because - // we otherwise use the minimized home bounds provided by the system. - mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); - } - mClipAnimationHelper.updateTargetRect(tempRect); - if (mMode == Mode.NO_BUTTON) { - // We can drag all the way to the top of the screen. - mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength; - } - } - @Override protected boolean onActivityInit(final T activity, Boolean alreadyOnHome) { if (mActivity == activity) { @@ -678,30 +631,7 @@ public class WindowTransformSwipeHandler @Override public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { - DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); - final Rect overviewStackBounds; - RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); - - if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) { - overviewStackBounds = mActivityControlHelper - .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); - dp = dp.getMultiWindowProfile(mContext, new Point( - targetSet.minimizedHomeBounds.width(), targetSet.minimizedHomeBounds.height())); - } else { - // If we are not in multi-window mode, home insets should be same as system insets. - dp = dp.copy(mContext); - overviewStackBounds = getStackBounds(dp); - } - dp.updateInsets(targetSet.homeContentInsets); - dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); - - if (runningTaskTarget != null) { - mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); - } - mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */); - initTransitionEndpoints(dp); - - mRecentsAnimationWrapper.setController(targetSet); + super.onRecentsAnimationStart(targetSet); TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length); setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index a0e806eee3..53e9461de6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -31,11 +31,8 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; -import android.graphics.Rect; import android.os.Bundle; -import android.view.WindowManager; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.quickstep.AnimatedFloat; @@ -52,7 +49,6 @@ import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { @@ -94,10 +90,6 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler mLauncherAlpha.value); initStateCallbacks(); - initTransitionTarget(); } private void initStateCallbacks() { @@ -376,33 +365,13 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler Date: Fri, 12 Jul 2019 14:19:18 -0700 Subject: [PATCH 24/34] Adding support for swipe operation when on home screen Bug: 137197916 Change-Id: Ic85bf9767d4a9a77dafc1c60c02555f3d2a5d8a2 --- .../android/quickstep/BaseSwipeUpHandler.java | 4 +- .../WindowTransformSwipeHandler.java | 3 +- .../fallback/FallbackRecentsView.java | 44 ++++++++++++++++ .../FallbackNoButtonInputConsumer.java | 51 ++++++++++++++++--- .../android/quickstep/views/RecentsView.java | 14 ++--- .../android/quickstep/RecentTasksList.java | 15 ++---- 6 files changed, 104 insertions(+), 27 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 23fe2dee10..72a9da6a36 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -70,7 +70,7 @@ import androidx.annotation.UiThread; * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler +public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { private static final String TAG = "BaseSwipeUpHandler"; @@ -109,7 +109,7 @@ public abstract class BaseSwipeUpHandler protected final RecentsAnimationWrapper mRecentsAnimationWrapper; protected T mActivity; - protected RecentsView mRecentsView; + protected Q mRecentsView; protected DeviceProfile mDp; private final int mPageSpacing; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index d0332529be..922f8e2c10 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -86,6 +86,7 @@ import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.LiveTileOverlay; +import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; @@ -98,7 +99,7 @@ import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler - extends BaseSwipeUpHandler + extends BaseSwipeUpHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index eaf6ebac80..2e9c0a3c4d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -17,6 +17,7 @@ package com.android.quickstep.fallback; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; @@ -31,6 +32,10 @@ import com.android.quickstep.RecentsActivity; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.shared.recents.model.Task.TaskKey; + +import java.util.ArrayList; public class FallbackRecentsView extends RecentsView { @@ -54,6 +59,8 @@ public class FallbackRecentsView extends RecentsView { private float mZoomScale = 1f; private float mZoomTranslationY = 0f; + private RunningTaskInfo mRunningTaskInfo; + public FallbackRecentsView(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -151,4 +158,41 @@ public class FallbackRecentsView extends RecentsView { TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY)); FULLSCREEN_PROGRESS.set(this, mZoomInProgress); } + + public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) { + mRunningTaskInfo = runningTaskInfo; + onGestureAnimationStart(runningTaskInfo == null ? -1 : runningTaskInfo.taskId); + } + + @Override + public void setCurrentTask(int runningTaskId) { + super.setCurrentTask(runningTaskId); + if (mRunningTaskInfo != null && mRunningTaskInfo.taskId != runningTaskId) { + mRunningTaskInfo = null; + } + } + + @Override + protected void applyLoadPlan(ArrayList tasks) { + // When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher + // as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to + // track the index of the next task appropriately, as it we are switching on any other app. + if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) { + // Check if the task list has running task + boolean found = false; + for (Task t : tasks) { + if (t.key.id == mRunningTaskId) { + found = true; + break; + } + } + if (!found) { + ArrayList newList = new ArrayList<>(tasks.size() + 1); + newList.addAll(tasks); + newList.add(Task.from(new TaskKey(mRunningTaskInfo), mRunningTaskInfo, false)); + tasks = newList; + } + } + super.applyLoadPlan(tasks); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index 53e9461de6..7abf62d351 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -47,10 +47,12 @@ import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.InputConsumerController; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { +public class FallbackNoButtonInputConsumer extends + BaseSwipeUpHandler { private static final String[] STATE_NAMES = DEBUG_STATES ? new String[5] : null; @@ -97,6 +99,11 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler mLauncherAlpha.value); + mRunningOverHome = ActivityManagerWrapper.isHomeTask(runningTaskInfo); + mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode; + + if (mSwipeUpOverHome) { + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value); + } else { + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + } + initStateCallbacks(); } @@ -149,10 +165,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler extends PagedView impl private int mTaskListChangeId = -1; // Only valid until the launcher state changes to NORMAL - private int mRunningTaskId = -1; + protected int mRunningTaskId = -1; private boolean mRunningTaskTileHidden; private Task mTmpRunningTask; @@ -532,7 +532,7 @@ public abstract class RecentsView extends PagedView impl return true; } - private void applyLoadPlan(ArrayList tasks) { + protected void applyLoadPlan(ArrayList tasks) { if (mPendingAnimation != null) { mPendingAnimation.addEndListener((onEndListener) -> applyLoadPlan(tasks)); return; @@ -855,12 +855,14 @@ public abstract class RecentsView extends PagedView impl * is called. Also scrolls the view to this task. */ public void showCurrentTask(int runningTaskId) { - if (getChildCount() == 0) { + if (getTaskView(runningTaskId) == null) { + boolean wasEmpty = getChildCount() == 0; // Add an empty view for now until the task plan is loaded and applied final TaskView taskView = mTaskViewPool.getView(); - addView(taskView); - addView(mClearAllButton); - + addView(taskView, 0); + if (wasEmpty) { + addView(mClearAllButton); + } // The temporary running task is only used for the duration between the start of the // gesture and the task list is loaded and applied mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(), diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index 7a1d0e83f6..d807b8973a 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -28,8 +28,6 @@ import com.android.launcher3.MainThreadExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.KeyguardManagerCompat; -import com.android.systemui.shared.system.RecentTaskInfoCompat; -import com.android.systemui.shared.system.TaskDescriptionCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import java.util.ArrayList; import java.util.Collections; @@ -86,8 +84,9 @@ public class RecentTasksList extends TaskStackChangeListener { : () -> callback.accept(copyOf(mTasks)); if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) { - // The list is up to date, callback with the same list - mMainThreadExecutor.execute(resultCallback); + // The list is up to date, send the callback on the next frame, + // so that requestID can be returned first. + mMainThreadExecutor.getHandler().post(resultCallback); return requestLoadId; } @@ -165,15 +164,11 @@ public class RecentTasksList extends TaskStackChangeListener { int taskCount = rawTasks.size(); for (int i = 0; i < taskCount; i++) { ActivityManager.RecentTaskInfo rawTask = rawTasks.get(i); - RecentTaskInfoCompat t = new RecentTaskInfoCompat(rawTask); Task.TaskKey taskKey = new Task.TaskKey(rawTask); Task task; if (!loadKeysOnly) { - ActivityManager.TaskDescription rawTd = t.getTaskDescription(); - TaskDescriptionCompat td = new TaskDescriptionCompat(rawTd); - boolean isLocked = tmpLockedUsers.get(t.getUserId()); - task = new Task(taskKey, td.getPrimaryColor(), td.getBackgroundColor(), - t.supportsSplitScreenMultiWindow(), isLocked, rawTd, t.getTopActivity()); + boolean isLocked = tmpLockedUsers.get(taskKey.userId); + task = Task.from(taskKey, rawTask, isLocked); } else { task = new Task(taskKey); } From 726cccf54a0cc6b7a2545b3554f9b338a9bb1df1 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 11:19:01 -0700 Subject: [PATCH 25/34] Adding message popups to anomaly diagnoser Change-Id: I6bf125ad5c311062c8f2f6953c0a4d6155203672 --- .../android/launcher3/tapl/LauncherInstrumentation.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 0fed337a04..cc403d48f2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -266,11 +266,17 @@ public final class LauncherInstrumentation { } private String getAnomalyMessage() { - final UiObject2 object = mDevice.findObject(By.res("android", "alertTitle")); + UiObject2 object = mDevice.findObject(By.res("android", "alertTitle")); if (object != null) { return "System alert popup is visible: " + object.getText(); } + object = mDevice.findObject(By.res("android", "message")); + if (object != null) { + return "Message popup by " + object.getApplicationPackage() + " is visible: " + + object.getText(); + } + if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked"; if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty"; From 42bd7dad6c6bf5dd5011d0257de745f5a837248c Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 16 Jul 2019 13:49:03 -0700 Subject: [PATCH 26/34] Fix app open/close animation in RTL. Bug: 135165284 Change-Id: Ib50f213904cb7ac7c769fac04dbfc70005fe25b8 --- .../launcher3/views/FloatingIconView.java | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 4fdd83b657..e09a9e8bfc 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -18,6 +18,7 @@ package com.android.launcher3.views; import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.Utilities.getBadge; import static com.android.launcher3.Utilities.getFullDrawable; +import static com.android.launcher3.Utilities.isRtl; import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; @@ -129,6 +130,7 @@ public class FloatingIconView extends View implements private final Launcher mLauncher; private final int mBlurSizeOutline; + private final boolean mIsRtl; private boolean mIsVerticalBarLayout = false; private boolean mIsAdaptiveIcon = false; @@ -174,6 +176,7 @@ public class FloatingIconView extends View implements mLauncher = Launcher.getLauncher(context); mBlurSizeOutline = getResources().getDimensionPixelSize( R.dimen.blur_size_medium_outline); + mIsRtl = Utilities.isRtl(getResources()); mListenerView = new ListenerView(context, attrs); mFgSpringX = new SpringAnimation(this, mFgTransXProperty) @@ -213,7 +216,10 @@ public class FloatingIconView extends View implements setAlpha(alpha); LayoutParams lp = (LayoutParams) getLayoutParams(); - float dX = rect.left - lp.leftMargin; + float dX = mIsRtl + ? rect.left + - (mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width) + : rect.left - lp.getMarginStart(); float dY = rect.top - lp.topMargin; setTranslationX(dX); setTranslationY(dY); @@ -323,14 +329,18 @@ public class FloatingIconView extends View implements mPositionOut.set(position); lp.ignoreInsets = true; // Position the floating view exactly on top of the original - lp.leftMargin = Math.round(position.left); lp.topMargin = Math.round(position.top); - + if (mIsRtl) { + lp.setMarginStart(Math.round(mLauncher.getDeviceProfile().widthPx - position.right)); + } else { + lp.setMarginStart(Math.round(position.left)); + } // Set the properties here already to make sure they are available when running the first // animation frame. - layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin - + lp.height); - + int left = mIsRtl + ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width + : lp.leftMargin; + layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height); } /** @@ -514,8 +524,11 @@ public class FloatingIconView extends View implements } else { lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); } - layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin - + lp.height); + + int left = mIsRtl + ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width + : lp.leftMargin; + layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height); float scale = Math.max((float) lp.height / originalHeight, (float) lp.width / originalWidth); From 2c7917d100fee33eb7817b065fc697f10d4b5b65 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 15 Jul 2019 13:56:41 -0700 Subject: [PATCH 27/34] Reload task list when task is removed Instead of individually removing tasks, ask for all tasks to get accurate list. This method is invoked whenever user presses back on a root activity, which causes the task to be killed from perspective of the activity. Test: Visually inspected, recent task no longer disappears. Open any app, hit back, and then go to overview quickly. App should remain in recents list. Fixes: 135687618 Change-Id: I1c135673ae987016db5df0b83f5ea8e345d3c7c1 (cherry picked from commit 8651219f7e41beee312b206eb543f35166d588f1) --- quickstep/src/com/android/quickstep/RecentTasksList.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index d807b8973a..e41dba94cc 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -119,12 +119,7 @@ public class RecentTasksList extends TaskStackChangeListener { @Override public void onTaskRemoved(int taskId) { - for (int i = mTasks.size() - 1; i >= 0; i--) { - if (mTasks.get(i).key.id == taskId) { - mTasks.remove(i); - return; - } - } + mTasks = loadTasksInBackground(Integer.MAX_VALUE, false); } @Override From 6a75e52f85c751b4b2832c312abd09e7812611e2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 16:19:58 -0700 Subject: [PATCH 28/34] Getting starting point of swipe from overview to all apps via protocol Change-Id: Idf04579b67011dac45b081a81367cde2d1274117 --- .../PortraitStatesTouchController.java | 7 +++++-- .../quickstep/QuickstepTestInformationHandler.java | 11 ++++++++++- .../android/launcher3/testing/TestProtocol.java | 1 + .../tapl/com/android/launcher3/tapl/Overview.java | 14 +++++++++----- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 6030cea938..109d751c48 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -51,7 +51,6 @@ import com.android.quickstep.OverviewInteractionState; import com.android.quickstep.RecentsModel; import com.android.quickstep.TouchInteractionService; import com.android.quickstep.util.LayoutUtils; -import com.android.systemui.shared.system.QuickStepContract; /** * Touch controller for handling various state transitions in portrait UI. @@ -296,9 +295,13 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr * @return true if the event is over the hotseat */ static boolean isTouchOverHotseat(Launcher launcher, MotionEvent ev) { + return (ev.getY() >= getHotseatTop(launcher)); + } + + public static int getHotseatTop(Launcher launcher) { DeviceProfile dp = launcher.getDeviceProfile(); int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom; - return (ev.getY() >= (launcher.getDragLayer().getHeight() - hotseatHeight)); + return launcher.getDragLayer().getHeight() - hotseatHeight; } private static class InterpolatorWrapper implements Interpolator { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index b59e13362d..57ed244d2b 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -6,6 +6,7 @@ import android.os.Bundle; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.states.OverviewState; +import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController; import com.android.quickstep.util.LayoutUtils; public class QuickstepTestInformationHandler extends TestInformationHandler { @@ -34,7 +35,15 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, TouchInteractionService.isInputMonitorInitialized()); - break; + return response; + } + + case TestProtocol.REQUEST_HOTSEAT_TOP: { + if (mLauncher == null) return null; + + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, + PortraitStatesTouchController.getHotseatTop(mLauncher)); + return response; } } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index e28eba8094..f6a26925bc 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -66,6 +66,7 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_HOTSEAT_TOP = "hotseat-top"; public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized"; public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java index 058831f180..da68da3ba6 100644 --- a/tests/tapl/com/android/launcher3/tapl/Overview.java +++ b/tests/tapl/com/android/launcher3/tapl/Overview.java @@ -19,9 +19,9 @@ package com.android.launcher3.tapl; import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; import androidx.annotation.NonNull; -import androidx.test.uiautomator.UiObject2; import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType; +import com.android.launcher3.testing.TestProtocol; /** * Overview pane. @@ -51,11 +51,15 @@ public final class Overview extends BaseOverview { // Swipe from an app icon to the top. LauncherInstrumentation.log("Overview.switchToAllApps before swipe"); - final UiObject2 allApps = mLauncher.waitForLauncherObject("apps_view"); - mLauncher.swipeToState(mLauncher.getDevice().getDisplayWidth() / 2, - allApps.getVisibleBounds().top, + mLauncher.swipeToState( mLauncher.getDevice().getDisplayWidth() / 2, - 0, 50, ALL_APPS_STATE_ORDINAL); + mLauncher.getTestInfo( + TestProtocol.REQUEST_HOTSEAT_TOP). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD), + mLauncher.getDevice().getDisplayWidth() / 2, + 0, + 50, + ALL_APPS_STATE_ORDINAL); try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( "swiped all way up from overview")) { From bf0042107c433de499e10b91a412b6c3e4a3bcbc Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 19:05:57 -0700 Subject: [PATCH 29/34] Temporarily disabling checking TouchInteractionService Change-Id: I953f251373f7bfb471eb203ee4ceda4375f17703 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index cc403d48f2..ec2107fb8a 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -396,7 +396,7 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { - waitForTouchInteractionService(); + //waitForTouchInteractionService(); assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); From e88d8acd85a670272c2d619980658730e6c558c7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 17 Jul 2019 11:38:59 -0700 Subject: [PATCH 30/34] Adding spring animation when swiping up to home in 3P Launcher Bug: 137197916 Change-Id: Ic9808a30e8cd4e0b2a221c4b03bc29489038e092 --- .../android/quickstep/BaseSwipeUpHandler.java | 119 ++++++++++++++++++ .../LauncherActivityControllerHelper.java | 8 +- .../WindowTransformSwipeHandler.java | 103 +-------------- .../FallbackNoButtonInputConsumer.java | 84 +++++++++---- .../quickstep/util/RectFSpringAnim.java | 2 +- .../quickstep/ActivityControlHelper.java | 10 ++ 6 files changed, 198 insertions(+), 128 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 72a9da6a36..e3d622f97e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -19,12 +19,15 @@ import static android.os.VibrationEffect.EFFECT_CLICK; import static android.os.VibrationEffect.createPredefined; import static com.android.launcher3.Utilities.postAsyncCallback; +import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; +import android.animation.Animator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; @@ -32,6 +35,7 @@ import android.content.Intent; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -48,12 +52,19 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.graphics.RotationMode; +import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; @@ -369,9 +380,117 @@ public abstract class BaseSwipeUpHandler * @param startProgress The progress of {@link #mCurrentShift} to start the window from. * @param homeAnimationFactory The home animation factory. */ - private RectFSpringAnim createWindowAnimationToHome(float startProgress, + @Override + protected RectFSpringAnim createWindowAnimationToHome(float startProgress, HomeAnimationFactory homeAnimationFactory) { - final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet; - final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet, - mTransformParams.setProgress(startProgress), false /* launcherOnTop */)); - final RectF targetRect = homeAnimationFactory.getWindowTargetRect(); - - final View floatingView = homeAnimationFactory.getFloatingView(); - final boolean isFloatingIconView = floatingView instanceof FloatingIconView; - RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources()); - if (isFloatingIconView) { - FloatingIconView fiv = (FloatingIconView) floatingView; - anim.addAnimatorListener(fiv); - fiv.setOnTargetChangeListener(anim::onTargetPositionChanged); - } - - AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome(); - - // End on a "round-enough" radius so that the shape reveal doesn't have to do too much - // rounding at the end of the animation. - float startRadius = mClipAnimationHelper.getCurrentCornerRadius(); - float endRadius = startRect.width() / 6f; - // We want the window alpha to be 0 once this threshold is met, so that the - // FolderIconView can be seen morphing into the icon shape. - final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f; - anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() { - @Override - public void onUpdate(RectF currentRect, float progress) { - homeAnim.setPlayFraction(progress); - - float alphaProgress = ACCEL_1_5.getInterpolation(progress); - float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, - windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); - mTransformParams.setProgress(progress) - .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); - if (isFloatingIconView) { - mTransformParams.setCornerRadius(endRadius * progress + startRadius - * (1f - progress)); - } - mClipAnimationHelper.applyTransform(targetSet, mTransformParams, - false /* launcherOnTop */); - - if (isFloatingIconView) { - ((FloatingIconView) floatingView).update(currentRect, 1f, progress, - windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); - } - - updateSysUiFlags(Math.max(progress, mCurrentShift.value)); - } - - @Override - public void onCancel() { - if (isFloatingIconView) { - ((FloatingIconView) floatingView).fastFinish(); - } - } - }); + RectFSpringAnim anim = + super.createWindowAnimationToHome(startProgress, homeAnimationFactory); + anim.addOnUpdateListener((r, p) -> updateSysUiFlags(Math.max(p, mCurrentShift.value))); anim.addAnimatorListener(new AnimationSuccessListener() { @Override public void onAnimationStart(Animator animation) { - homeAnim.dispatchOnStart(); if (mActivity != null) { mActivity.getRootView().getOverlay().remove(mLiveTileOverlay); } @@ -1036,7 +978,6 @@ public class WindowTransformSwipeHandler @Override public void onAnimationSuccess(Animator animator) { - homeAnim.getAnimationPlayer().end(); if (mRecentsView != null) { mRecentsView.post(mRecentsView::resetTaskVisuals); } @@ -1270,38 +1211,4 @@ public class WindowTransformSwipeHandler return app.isNotInRecents || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; } - - private interface RunningWindowAnim { - void end(); - - void cancel(); - - static RunningWindowAnim wrap(Animator animator) { - return new RunningWindowAnim() { - @Override - public void end() { - animator.end(); - } - - @Override - public void cancel() { - animator.cancel(); - } - }; - } - - static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) { - return new RunningWindowAnim() { - @Override - public void end() { - rectFSpringAnim.end(); - } - - @Override - public void cancel() { - rectFSpringAnim.cancel(); - } - }; - } - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index 7abf62d351..631c34c22d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -18,11 +18,12 @@ package com.android.quickstep.inputconsumers; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; -import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; +import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import android.animation.Animator; import android.animation.AnimatorSet; @@ -31,10 +32,13 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; +import android.graphics.RectF; import android.os.Bundle; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.MultiStateCallback; @@ -44,6 +48,7 @@ import com.android.quickstep.RecentsModel; import com.android.quickstep.SwipeSharedState; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ObjectWrapper; +import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -102,10 +107,10 @@ public class FallbackNoButtonInputConsumer extends private final boolean mRunningOverHome; private final boolean mSwipeUpOverHome; - private final RunningTaskInfo mRunningTaskInfo; - private Animator mFinishAnimation; + private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f); + private RunningWindowAnim mFinishAnimation; public FallbackNoButtonInputConsumer(Context context, OverviewComponentObserver overviewComponentObserver, @@ -226,6 +231,8 @@ public class FallbackNoButtonInputConsumer extends @Override public void updateFinalShift() { mTransformParams.setProgress(mCurrentShift.value); + mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode + && (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD)); if (mRecentsAnimationWrapper.targetSet != null) { applyTransformUnchecked(); } @@ -240,6 +247,7 @@ public class FallbackNoButtonInputConsumer extends @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { + mEndVelocityPxPerMs.set(0, velocity.y / 1000); if (mInQuickSwitchMode) { // For now set it to non-null, it will be reset before starting the animation mEndTarget = LAST_TASK; @@ -288,12 +296,14 @@ public class FallbackNoButtonInputConsumer extends } } - private void onHandlerInvalidated() { mActivityInitListener.unregister(); if (mGestureEndCallback != null) { mGestureEndCallback.run(); } + if (mFinishAnimation != null) { + mFinishAnimation.end(); + } } private void onHandlerInvalidatedWithRecents() { @@ -364,31 +374,39 @@ public class FallbackNoButtonInputConsumer extends } float endProgress = mEndTarget.mEndProgress; - + long duration = (long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mCurrentShift.value)); + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } if (mCurrentShift.value != endProgress || mInQuickSwitchMode) { - AnimatorSet anim = new AnimatorSet(); - anim.play(mLauncherAlpha.animateToValue( - mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); - anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); - - - long duration = (long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mCurrentShift.value)); - if (mRecentsView != null) { - duration = Math.max(duration, mRecentsView.getScroller().getDuration()); - } - - anim.setDuration(duration); - anim.addListener(new AnimationSuccessListener() { + AnimationSuccessListener endListener = new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { finishAnimationTargetSetAnimationComplete(); mFinishAnimation = null; } - }); - anim.start(); - mFinishAnimation = anim; + }; + + if (mEndTarget == HOME && !mRunningOverHome) { + RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration); + anim.addAnimatorListener(endListener); + anim.start(mEndVelocityPxPerMs); + mFinishAnimation = RunningWindowAnim.wrap(anim); + } else { + + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue( + mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); + anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); + + anim.setDuration(duration); + anim.addListener(endListener); + anim.start(); + mFinishAnimation = RunningWindowAnim.wrap(anim); + } + } else { finishAnimationTargetSetAnimationComplete(); } @@ -412,4 +430,26 @@ public class FallbackNoButtonInputConsumer extends mRecentsAnimationWrapper.setController(null); setStateOnUiThread(STATE_HANDLER_INVALIDATED); } + + /** + * Creates an animation that transforms the current app window into the home app. + * @param startProgress The progress of {@link #mCurrentShift} to start the window from. + */ + private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) { + HomeAnimationFactory factory = new HomeAnimationFactory() { + @Override + public RectF getWindowTargetRect() { + return HomeAnimationFactory.getDefaultWindowTargetRect(mDp); + } + + @Override + public AnimatorPlaybackController createActivityAnimationToHome() { + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1)); + anim.setDuration(duration); + return AnimatorPlaybackController.wrap(anim, duration); + } + }; + return createWindowAnimationToHome(startProgress, factory); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 9c5cf2042b..c6eafe6a64 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -237,6 +237,6 @@ public class RectFSpringAnim { public interface OnUpdateListener { void onUpdate(RectF currentRect, float progress); - void onCancel(); + default void onCancel() { } } } diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index cd2c9cb1bf..5c9c7d4cab 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -152,5 +152,15 @@ public interface ActivityControlHelper { default void playAtomicAnimation(float velocity) { // No-op } + + static RectF getDefaultWindowTargetRect(DeviceProfile dp) { + final int halfIconSize = dp.iconSizePx / 2; + final float targetCenterX = dp.availableWidthPx / 2f; + final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx; + // Fallback to animate to center of screen. + return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize, + targetCenterX + halfIconSize, targetCenterY + halfIconSize); + } + } } From 20d6a27608146c013cf8da1413d828a5cf52bb80 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 17 Jul 2019 11:42:16 -0700 Subject: [PATCH 31/34] Use non-android package name for context creation - Speculative fix for mismatch between navigation mode reported to the tests vs. what mode the device is in based on the bug report. Original change to the package name was in ag/6866716 Bug: 136033787 Change-Id: I51f964daa8c42b671733cf3fab19d086e19a9063 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index cc403d48f2..831726b8a5 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -208,7 +208,7 @@ public final class LauncherInstrumentation { try { // Workaround, use constructed context because both the instrumentation context and the // app context are not constructed with resources that take overlays into account - final Context ctx = baseContext.createPackageContext("android", 0); + final Context ctx = baseContext.createPackageContext(getLauncherPackageName(), 0); for (int i = 0; i < 100; ++i) { final int currentInteractionMode = getCurrentInteractionMode(ctx); final NavigationModel model = getNavigationModel(currentInteractionMode); @@ -918,7 +918,7 @@ public final class LauncherInstrumentation { int getEdgeSensitivityWidth() { try { final Context context = mInstrumentation.getTargetContext().createPackageContext( - "android", 0); + getLauncherPackageName(), 0); return context.getResources().getDimensionPixelSize( getSystemDimensionResId(context, "config_backGestureInset")) + 1; } catch (PackageManager.NameNotFoundException e) { From 2f7d1fa4a80f8f805f0e64c353b891bf6c612f70 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 17 Jul 2019 14:03:45 -0700 Subject: [PATCH 32/34] Using correct gesture margins in overview Change-Id: I0108858279559e10633825f7de22211515f0e9b7 --- .../QuickstepTestInformationHandler.java | 31 +++++++++++++++++++ .../android/quickstep/views/RecentsView.java | 11 +++++++ .../launcher3/testing/TestProtocol.java | 2 ++ .../android/launcher3/tapl/BaseOverview.java | 15 ++++++--- 4 files changed, 54 insertions(+), 5 deletions(-) rename quickstep/{ => recents_ui_overrides}/src/com/android/quickstep/QuickstepTestInformationHandler.java (58%) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java similarity index 58% rename from quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index 57ed244d2b..b507044e0a 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -3,11 +3,15 @@ package com.android.quickstep; import android.content.Context; import android.os.Bundle; +import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.states.OverviewState; import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController; import com.android.quickstep.util.LayoutUtils; +import com.android.quickstep.views.RecentsView; + +import java.util.concurrent.ExecutionException; public class QuickstepTestInformationHandler extends TestInformationHandler { @@ -45,6 +49,33 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { PortraitStatesTouchController.getHotseatTop(mLauncher)); return response; } + + case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: { + try { + final int leftMargin = new MainThreadExecutor().submit(() -> + mLauncher.getOverviewPanel().getLeftGestureMargin()).get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return response; + } + + case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: { + try { + final int rightMargin = new MainThreadExecutor().submit(() -> + mLauncher.getOverviewPanel().getRightGestureMargin()). + get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return response; + } } return super.call(method); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 66ddc727f5..b566837da6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -73,6 +73,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; +import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ListView; @@ -1742,4 +1743,14 @@ public abstract class RecentsView extends PagedView impl updateEnabledOverlays(); } } + + public int getLeftGestureMargin() { + final WindowInsets insets = getRootWindowInsets(); + return Math.max(insets.getSystemGestureInsets().left, insets.getSystemWindowInsetLeft()); + } + + public int getRightGestureMargin() { + final WindowInsets insets = getRootWindowInsets(); + return Math.max(insets.getSystemGestureInsets().right, insets.getSystemWindowInsetRight()); + } } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index f69b278963..079ab6d8fe 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -71,6 +71,8 @@ public final class TestProtocol { public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; + public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin"; + public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin"; public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index ae93867191..04a0f12714 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -23,6 +23,8 @@ import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; +import com.android.launcher3.testing.TestProtocol; + import java.util.Collections; import java.util.List; @@ -30,7 +32,6 @@ import java.util.List; * Common overview pane for both Launcher and fallback recents */ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { - private static final int FLING_SPEED = LauncherInstrumentation.isAvd() ? 500 : 1500; private static final int FLINGS_FOR_DISMISS_LIMIT = 40; BaseOverview(LauncherInstrumentation launcher) { @@ -51,8 +52,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling forward in overview")) { LauncherInstrumentation.log("Overview.flingForward before fling"); final UiObject2 overview = verifyActiveContainer(); - mLauncher.scroll(overview, Direction.LEFT, 1, - new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0), 20); + final int leftMargin = mLauncher.getTestInfo( + TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + mLauncher.scroll(overview, Direction.LEFT, 1, new Rect(leftMargin, 0, 0, 0), 20); verifyActiveContainer(); } } @@ -87,8 +90,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling backward in overview")) { LauncherInstrumentation.log("Overview.flingBackward before fling"); final UiObject2 overview = verifyActiveContainer(); - mLauncher.scroll(overview, Direction.RIGHT, 1, - new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0), 20); + final int rightMargin = mLauncher.getTestInfo( + TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + mLauncher.scroll(overview, Direction.RIGHT, 1, new Rect(0, 0, rightMargin, 0), 20); verifyActiveContainer(); } } From 04ca73b59019fe731b172d65aee4e7ff0058d2c7 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 17 Jul 2019 18:55:53 -0700 Subject: [PATCH 33/34] Fixing starting scrolls outside of view Change-Id: I0237603d25edc60522c41a3d20615391d5b4f3b6 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 1e74552f76..a5b0d25671 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -782,7 +782,7 @@ public final class LauncherInstrumentation { startX = endX = rect.centerX(); final int vertCenter = rect.centerY(); final float halfGestureHeight = rect.height() * percent / 2.0f; - startY = (int) (vertCenter + halfGestureHeight); + startY = (int) (vertCenter + halfGestureHeight) - 1; endY = (int) (vertCenter - halfGestureHeight); } break; @@ -798,7 +798,7 @@ public final class LauncherInstrumentation { startY = endY = rect.centerY(); final int horizCenter = rect.centerX(); final float halfGestureWidth = rect.width() * percent / 2.0f; - startX = (int) (horizCenter + halfGestureWidth); + startX = (int) (horizCenter + halfGestureWidth) - 1; endX = (int) (horizCenter - halfGestureWidth); } break; From 11b5535556cc3d53d7e521715178ddcd4b708daf Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 17 Jul 2019 21:24:07 -0700 Subject: [PATCH 34/34] Skip TouchInteractionService preload if restore task is pending. Otherwise the preload may cause launcher to restore too early, resulting in data loss. Bug: 131315856 Change-Id: I4412c8f691286ba142e9c748a908a3ed42713a82 --- .../src/com/android/quickstep/TouchInteractionService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 4bc4c761b0..debed898ef 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -76,6 +76,7 @@ import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; +import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; @@ -710,6 +711,12 @@ public class TouchInteractionService extends Service implements return; } + if (RestoreDbTask.isPending(this)) { + // Preloading while a restore is pending may cause launcher to start the restore + // too early. + return; + } + final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); if (activityControl.getCreatedActivity() == null) {