From f1128d9f5efb051cd5c068e42304e240bb29063e Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Wed, 5 Jun 2019 16:01:16 -0700 Subject: [PATCH 01/26] Task footer - use temporary motion for show and hide. Bug: 125844074 Test: manual Change-Id: I9a26760f4bd976d0c3475db1322ee0da639d8209 --- .../src/com/android/quickstep/views/TaskView.java | 2 ++ quickstep/res/layout/task.xml | 2 ++ 2 files changed, 4 insertions(+) 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 bf3e91ff68..726d798747 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 @@ -498,6 +498,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA); setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation)); + float fade = Utilities.boundToRange(1.0f - 2 * scrollState.linearInterpolation, 0f, 1f); + mTaskFooterContainer.setAlpha(fade); if (mMenuView != null) { mMenuView.setPosition(getX() - getRecentsView().getScrollX(), getY()); mMenuView.setScaleX(getScaleX()); diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index 18691889ff..6a595a16e5 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -40,6 +40,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:animateLayoutChanges="true" + android:forceHasOverlappingRendering="true" android:layout_gravity="bottom|center_horizontal"> Date: Fri, 7 Jun 2019 14:14:50 -0700 Subject: [PATCH 02/26] Removing unused method Change-Id: I25016d58b130e99c8983af48fde32e05bf6c66b1 --- .../inputconsumers/OverviewInputConsumer.java | 10 ---------- 1 file changed, 10 deletions(-) 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 4851e67e9d..56db2095fe 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 @@ -27,7 +27,6 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Utilities; import com.android.launcher3.views.BaseDragLayer; -import com.android.quickstep.ActivityControlHelper; import com.android.quickstep.OverviewCallbacks; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; @@ -114,13 +113,4 @@ public class OverviewInputConsumer mActivity.dispatchKeyEvent(ev); } } - - public static InputConsumer newInstanceWithinActivityBounds( - ActivityControlHelper activityHelper) { - BaseDraggingActivity activity = activityHelper.getCreatedActivity(); - if (activity == null) { - return InputConsumer.NO_OP; - } - return new OverviewInputConsumer(activity, null, true); - } } \ No newline at end of file From 34b2f03b308a7e3afcebe6e57d929d2950461b3c Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 10 Jun 2019 11:26:37 -0700 Subject: [PATCH 03/26] More tracing for b/133009122 Bug: 133009122 Change-Id: I09a95b88ea55e1759151b2bcd5ede0c1efa38e7e --- .../android/launcher3/dragndrop/BaseItemDragListener.java | 4 ++++ .../android/launcher3/popup/PopupContainerWithArrow.java | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index e204c63017..c719c1c986 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -37,6 +37,7 @@ import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.states.InternalStateHandler; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.widget.PendingItemDragHelper; import java.util.UUID; @@ -136,6 +137,9 @@ 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/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 7b14fa2491..9719a1892f 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -36,6 +36,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; +import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; @@ -67,6 +68,7 @@ import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.PackageUserKey; @@ -447,6 +449,11 @@ 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; } From 76ba0a328da7229cb123a9aa983a0b180c2c110e Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 10 Jun 2019 11:56:11 -0700 Subject: [PATCH 04/26] Saving instance state so that widget cache is updated properly before rebind List widgets use a static cache which is initialized as part of saveInstanceState. Calling this ensures that no extra binder calls are made on rotation Bug: 134707989 Change-Id: I8d4450134168bd412ba2911c57354a603868bc47 --- src/com/android/launcher3/Launcher.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 57a9b161f9..9db2ec0476 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -465,6 +465,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, reapplyUi(); mDragLayer.recreateControllers(); + // Calling onSaveInstanceState ensures that static cache used by listWidgets is + // initialized properly. + onSaveInstanceState(new Bundle()); // TODO: We can probably avoid rebind when only screen size changed. rebindModel(); } From 915fd75faede1b5cb2f5ef4a60b8b2bdae41f979 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 10 Jun 2019 12:24:10 -0700 Subject: [PATCH 05/26] Not assuming that the activity is Launcher for the fallback recents Bug: 134919468 Change-Id: Ibb3b11a5bf57848212c806f2023e4cf43c8a862b --- .../android/quickstep/views/DigitalWellBeingToast.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java index 204dd56872..5aab944a32 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java @@ -37,7 +37,7 @@ import android.widget.TextView; import androidx.annotation.StringRes; -import com.android.launcher3.Launcher; +import com.android.launcher3.BaseActivity; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -187,12 +187,12 @@ public final class DigitalWellBeingToast extends LinearLayout { mTask.getTopComponent().getPackageName()).addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); try { - final Launcher launcher = Launcher.getLauncher(getContext()); + final BaseActivity activity = BaseActivity.fromContext(getContext()); final ActivityOptions options = ActivityOptions.makeScaleUpAnimation( this, 0, 0, getWidth(), getHeight()); - launcher.startActivity(intent, options.toBundle()); - launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP, + activity.startActivity(intent, options.toBundle()); + activity.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP, LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this); } catch (ActivityNotFoundException e) { Log.e(TAG, "Failed to open app usage settings for task " From 8758311c2af2da1a78332f187d1461804d92a6ed Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 10 Jun 2019 14:20:58 -0700 Subject: [PATCH 06/26] Defer listening for notification changes until resume Bug: 134964922 Test: Take a systrace while swiping up, ensure there are no resource icon loads other than the icon for the current app while launcher is starting Change-Id: I469a2089df02434918125b005cd795f5514ec389 --- src/com/android/launcher3/Launcher.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 57a9b161f9..ca410aa4d6 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -888,7 +888,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mLauncherCallbacks.onStart(); } mAppWidgetHost.setListenIfResumed(true); - NotificationListener.setNotificationsChangedListener(mPopupDataProvider); RaceConditionTracker.onEvent(ON_START_EVT, EXIT); } @@ -908,6 +907,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // Refresh shortcuts if the permission changed. mModel.refreshShortcutsIfRequired(); + // Set the notification listener and fetch updated notifications when we resume + NotificationListener.setNotificationsChangedListener(mPopupDataProvider); + DiscoveryBounce.showForHomeIfNeeded(this); if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) { From fa37c529e1f3587a4fe8362a0c66daa639d372a3 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 3 Jun 2019 10:21:20 -0700 Subject: [PATCH 07/26] Translate recents when attaching to app window instead of fading When attaching recents, translate it offscreen and use a spring to pull it into position. When detaching, use the same spring to pull it back offscreen. Bug: 129985827 Change-Id: I05339e2ec0932070365023bfafc83cbf2a4e178e --- .../LauncherActivityControllerHelper.java | 98 +++++++++++++++---- .../WindowTransformSwipeHandler.java | 30 +++--- .../android/quickstep/views/RecentsView.java | 10 ++ .../quickstep/ActivityControlHelper.java | 1 + 4 files changed, 106 insertions(+), 33 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 1b82bcb578..7809e454a5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -16,16 +16,23 @@ package com.android.quickstep; import static android.view.View.TRANSLATION_Y; + import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.LauncherStateManager.ANIM_ALL; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS; +import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; +import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION; +import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY; +import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -44,14 +51,18 @@ import android.view.animation.Interpolator; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherInitListenerEx; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.SpringObjectAnimator; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; @@ -99,6 +110,13 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe DiscoveryBounce.showForOverviewIfNeeded(activity); } + @Override + public void onSwipeUpToHomeComplete(Launcher activity) { + // Ensure recents is at the correct position for NORMAL state. For example, when we detach + // recents, we assume the first task is invisible, making translation off by one task. + activity.getStateManager().reapplyState(); + } + @Override public void onAssistantVisibilityChanged(float visibility) { Launcher launcher = getCreatedActivity(); @@ -156,18 +174,23 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe public AnimatorPlaybackController createActivityAnimationToHome() { // Return an empty APC here since we have an non-user controlled animation to home. long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx); - AnimatorSet as = new AnimatorSet(); - as.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - activity.getStateManager().goToState(NORMAL, false); - } - }); - return AnimatorPlaybackController.wrap(as, accuracy); + return activity.getStateManager().createAnimationToNewWorkspace(NORMAL, accuracy, + 0 /* animComponents */); } @Override public void playAtomicAnimation(float velocity) { + // Setup workspace with 0 duration to prepare for our staggered animation. + LauncherStateManager stateManager = activity.getStateManager(); + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + // setRecentsAttachedToAppWindow() will animate recents out. + builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW); + stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0); + builder.build().start(); + + // Stop scrolling so that it doesn't interfere with the translation offscreen. + recentsView.getScroller().forceFinished(true); + new StaggeredWorkspaceAnim(activity, workspaceView, velocity).start(); } }; @@ -201,7 +224,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return new AnimationFactory() { private Animator mShelfAnim; private ShelfAnimState mShelfState; - private Animator mAttachToWindowAnim; + private Animator mAttachToWindowFadeAnim; + private SpringAnimation mAttachToWindowTranslationXAnim; private boolean mIsAttachedToWindow; @Override @@ -267,20 +291,60 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return; } mIsAttachedToWindow = attached; - if (mAttachToWindowAnim != null) { - mAttachToWindowAnim.cancel(); + if (mAttachToWindowFadeAnim != null) { + mAttachToWindowFadeAnim.cancel(); } - mAttachToWindowAnim = ObjectAnimator.ofFloat(activity.getOverviewPanel(), + RecentsView recentsView = activity.getOverviewPanel(); + mAttachToWindowFadeAnim = ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, attached ? 1 : 0); - mAttachToWindowAnim.addListener(new AnimatorListenerAdapter() { + + int runningTaskIndex = recentsView.getRunningTaskIndex(); + if (runningTaskIndex == 0) { + // If we are on the first task (we haven't quick switched), translate recents in + // from the side. Calculate the start translation based on current scale/scroll. + float currScale = recentsView.getScaleX(); + float scrollOffsetX = recentsView.getScrollOffset(); + + float offscreenX = NORMAL.getOverviewScaleAndTranslation(activity).translationX; + // The first task is hidden, so offset by its width. + int firstTaskWidth = recentsView.getTaskViewAt(0).getWidth(); + offscreenX -= (firstTaskWidth + recentsView.getPageSpacing()) * currScale; + // Offset since scale pushes tasks outwards. + offscreenX += firstTaskWidth * (currScale - 1) / 2; + offscreenX = Math.max(0, offscreenX); + if (recentsView.isRtl()) { + offscreenX = -offscreenX; + } + + float fromTranslationX = attached ? offscreenX - scrollOffsetX : 0; + float toTranslationX = attached ? 0 : offscreenX - scrollOffsetX; + if (mAttachToWindowTranslationXAnim == null) { + mAttachToWindowTranslationXAnim = new SpringAnimation(recentsView, + SpringAnimation.TRANSLATION_X).setSpring(new SpringForce() + .setDampingRatio(DAMPING_RATIO_LOW_BOUNCY) + .setStiffness(STIFFNESS_LOW)); + } + if (!recentsView.isShown() && animate) { + recentsView.setTranslationX(fromTranslationX); + mAttachToWindowTranslationXAnim.setStartValue(fromTranslationX); + } + mAttachToWindowTranslationXAnim.animateToFinalPosition(toTranslationX); + if (!animate && mAttachToWindowTranslationXAnim.canSkipToEnd()) { + mAttachToWindowTranslationXAnim.skipToEnd(); + } + + mAttachToWindowFadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2); + } else { + mAttachToWindowFadeAnim.setInterpolator(ACCEL_DEACCEL); + } + mAttachToWindowFadeAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mAttachToWindowAnim = null; + mAttachToWindowFadeAnim = null; } }); - mAttachToWindowAnim.setInterpolator(ACCEL_DEACCEL); - mAttachToWindowAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0); - mAttachToWindowAnim.start(); + mAttachToWindowFadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0); + mAttachToWindowFadeAnim.start(); } }; } 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 c7841d98e3..7d17f85f69 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -21,7 +21,6 @@ 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.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -218,7 +217,7 @@ public class WindowTransformSwipeHandler Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW)); private static final String SCREENSHOT_CAPTURED_EVT = "ScreenshotCaptured"; - private static final long SHELF_ANIM_DURATION = 120; + 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. @@ -602,7 +601,7 @@ public class WindowTransformSwipeHandler } public void onMotionPauseChanged(boolean isPaused) { - setShelfState(isPaused ? PEEK : HIDE, FAST_OUT_SLOW_IN, SHELF_ANIM_DURATION); + setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); } public void maybeUpdateRecentsAttachedState() { @@ -625,7 +624,10 @@ public class WindowTransformSwipeHandler : mRecentsAnimationWrapper.targetSet.findTask(mRunningTaskId); final boolean recentsAttachedToAppWindow; int runningTaskIndex = mRecentsView.getRunningTaskIndex(); - if (mContinuingLastGesture) { + if (mGestureEndTarget != null) { + recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow; + } else if (mContinuingLastGesture + && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) { recentsAttachedToAppWindow = true; animate = false; } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) { @@ -633,17 +635,16 @@ public class WindowTransformSwipeHandler recentsAttachedToAppWindow = true; animate = false; } else { - if (mGestureEndTarget != null) { - recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow; - } else { - recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask; - } + recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask; if (animate) { // Only animate if an adjacent task view is visible on screen. TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1); TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1); + float prevTranslationX = mRecentsView.getTranslationX(); + mRecentsView.setTranslationX(0); animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT)) || (adjacentTask2 != null && adjacentTask2.getGlobalVisibleRect(TEMP_RECT)); + mRecentsView.setTranslationX(prevTranslationX); } } mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); @@ -701,13 +702,7 @@ public class WindowTransformSwipeHandler SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); if (controller != null) { - float offsetX = 0; - if (mRecentsView != null) { - int startScroll = mRecentsView.getScrollForPage(mRecentsView.indexOfChild( - mRecentsView.getRunningTaskView())); - offsetX = startScroll - mRecentsView.getScrollX(); - offsetX *= mRecentsView.getScaleX(); - } + float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); float offsetScale = getTaskCurveScaleForOffsetX(offsetX, mClipAnimationHelper.getTargetRect().width()); mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); @@ -1217,6 +1212,9 @@ public class WindowTransformSwipeHandler if (mRecentsView != null) { mRecentsView.post(mRecentsView::resetTaskVisuals); } + // Make sure recents is in its final state + maybeUpdateRecentsAttachedState(false); + mActivityControlHelper.onSwipeUpToHomeComplete(mActivity); } }); return anim; 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 e38a315f8a..90e123e847 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 @@ -1676,6 +1676,16 @@ public abstract class RecentsView extends PagedView impl return mClearAllButton; } + /** + * @return How many pixels the running task is offset on the x-axis due to the current scrollX. + */ + public float getScrollOffset() { + int startScroll = getScrollForPage(getRunningTaskIndex()); + int offsetX = startScroll - getScrollX(); + offsetX *= getScaleX(); + return offsetX; + } + public Consumer getEventDispatcher(RotationMode rotationMode) { if (rotationMode.isTransposed) { Matrix transform = new Matrix(); diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index b17d8d69c7..dcc1ace883 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -53,6 +53,7 @@ public interface ActivityControlHelper { void onSwipeUpToRecentsComplete(T activity); + default void onSwipeUpToHomeComplete(T activity) { } void onAssistantVisibilityChanged(float visibility); @NonNull HomeAnimationFactory prepareHomeUI(T activity); From c026bf2f95a39cb3f6f074b7ea4a110adcadfb39 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 10 Jun 2019 15:36:30 -0700 Subject: [PATCH 08/26] Making sure that we drag icon far enough to cross the threshold Tests dragged icon from all apps to workspace by dragging it to the center of the screen. If the icon is close enough to the center, this may not trigger the dragging condition. Fixing by dragging far enough. Bug: 133009122 Change-Id: I68127714ab3694f2639b4acf530e2736ca4dbdf3 --- tests/tapl/com/android/launcher3/tapl/Launchable.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 5190f001a7..d4bdafa764 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -20,7 +20,6 @@ import android.graphics.Point; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; -import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; @@ -70,11 +69,16 @@ abstract class Launchable { * Drags an object to the center of homescreen. */ public Workspace dragToWorkspace() { - final UiDevice device = mLauncher.getDevice(); + final Point launchableCenter = getObject().getVisibleCenter(); + final Point displaySize = mLauncher.getRealDisplaySize(); + final int width = displaySize.x / 2; Workspace.dragIconToWorkspace( mLauncher, this, - new Point(device.getDisplayWidth() / 2, device.getDisplayHeight() / 2), + new Point( + launchableCenter.x >= width ? + launchableCenter.x - width / 2 : launchableCenter.x + width / 2, + displaySize.y / 2), getLongPressIndicator()); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "dragged launchable to workspace")) { From 47860cf593c231dd10b7ae9912ef75ce4f614702 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 10 Jun 2019 16:00:36 -0700 Subject: [PATCH 09/26] Fixing some thread errors in TouchInteractionService Accessing internal objects only on the main thread and after the user has been unlocked. Bug: 134971634 Change-Id: Iaf6a1e3ab9417836c5d34673997b0a03a76862c1 --- .../quickstep/TouchInteractionService.java | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 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 dc354404af..4a40c64f99 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -27,7 +27,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.annotation.TargetApi; @@ -61,6 +60,7 @@ import android.view.Surface; import android.view.WindowManager; import androidx.annotation.BinderThread; +import androidx.annotation.UiThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.MainThreadExecutor; @@ -94,7 +94,6 @@ import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -146,10 +145,7 @@ public class TouchInteractionService extends Service implements mISystemUiProxy = ISystemUiProxy.Stub .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); - runWhenUserUnlocked(() -> { - mRecentsModel.setSystemUiProxy(mISystemUiProxy); - mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); - }); + MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); } @Override @@ -182,16 +178,9 @@ public class TouchInteractionService extends Service implements @Override public void onAssistantVisibilityChanged(float visibility) { - if (mOverviewComponentObserver == null) { - // Save the visibility to be applied when the user is unlocked - mPendingAssistantVisibility = visibility; - return; - } - - MAIN_THREAD_EXECUTOR.execute(() -> { - mOverviewComponentObserver.getActivityControlHelper() - .onAssistantVisibilityChanged(visibility); - }); + mLastAssistantVisibility = visibility; + MAIN_THREAD_EXECUTOR.execute( + TouchInteractionService.this::onAssistantVisibilityChanged); } public void onBackAction(boolean completed, int downX, int downY, boolean isButton, @@ -208,8 +197,7 @@ public class TouchInteractionService extends Service implements public void onSystemUiStateChanged(int stateFlags) { mSystemUiStateFlags = stateFlags; - mOverviewInteractionState.setSystemUiStateFlags(stateFlags); - mOverviewComponentObserver.onSystemUiStateChanged(stateFlags); + MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged); } /** Deprecated methods **/ @@ -248,11 +236,10 @@ public class TouchInteractionService extends Service implements private InputConsumerController mInputConsumer; private SwipeSharedState mSwipeSharedState; private boolean mAssistantAvailable; - private float mPendingAssistantVisibility = 0; + private float mLastAssistantVisibility = 0; private @SystemUiStateFlags int mSystemUiStateFlags; private boolean mIsUserUnlocked; - private List mOnUserUnlockedCallbacks; private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -286,7 +273,6 @@ public class TouchInteractionService extends Service implements // Everything else should be initialized in initWhenUserUnlocked() below. mKM = getSystemService(KeyguardManager.class); mMainChoreographer = Choreographer.getInstance(); - mOnUserUnlockedCallbacks = new ArrayList<>(); if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) { initWhenUserUnlocked(); @@ -413,13 +399,9 @@ public class TouchInteractionService extends Service implements } private void initWhenUserUnlocked() { - mIsUserUnlocked = true; - mAM = ActivityManagerWrapper.getInstance(); mRecentsModel = RecentsModel.INSTANCE.get(this); mOverviewComponentObserver = new OverviewComponentObserver(this); - mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged( - mPendingAssistantVisibility); mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver); mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this); @@ -427,12 +409,12 @@ public class TouchInteractionService extends Service implements mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this); mSwipeSharedState = new SwipeSharedState(mOverviewComponentObserver); mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); - mInputConsumer.registerInputConsumer(); + mIsUserUnlocked = true; - for (Runnable callback : mOnUserUnlockedCallbacks) { - callback.run(); - } - mOnUserUnlockedCallbacks.clear(); + mInputConsumer.registerInputConsumer(); + onSystemUiProxySet(); + onSystemUiFlagsChanged(); + onAssistantVisibilityChanged(); // Temporarily disable model preload // new ModelPreload().start(this); @@ -440,11 +422,27 @@ public class TouchInteractionService extends Service implements Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); } - private void runWhenUserUnlocked(Runnable callback) { + @UiThread + private void onSystemUiProxySet() { if (mIsUserUnlocked) { - callback.run(); - } else { - mOnUserUnlockedCallbacks.add(callback); + mRecentsModel.setSystemUiProxy(mISystemUiProxy); + mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); + } + } + + @UiThread + private void onSystemUiFlagsChanged() { + if (mIsUserUnlocked) { + mOverviewInteractionState.setSystemUiStateFlags(mSystemUiStateFlags); + mOverviewComponentObserver.onSystemUiStateChanged(mSystemUiStateFlags); + } + } + + @UiThread + private void onAssistantVisibilityChanged() { + if (mIsUserUnlocked) { + mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged( + mLastAssistantVisibility); } } From 8f9cf2f38fb3ae3a6401e1a7a121f98a529a4c9a Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 10 Jun 2019 18:01:58 -0700 Subject: [PATCH 10/26] Calling sendStateEventToTest() from a place guaranteed to be called See discussion in the bug Bug: 133867119 Change-Id: Id162cfa3b0a0aafe17dd9b41e2c4b5d02c411830 --- .../android/quickstep/LauncherActivityControllerHelper.java | 3 --- src/com/android/launcher3/LauncherStateManager.java | 3 +++ .../launcher3/touch/AbstractStateChangeTouchController.java | 2 -- 3 files changed, 3 insertions(+), 5 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 7809e454a5..fd4cdfe009 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -64,7 +64,6 @@ import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.SpringObjectAnimator; -import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.views.FloatingIconView; @@ -219,8 +218,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe // Optimization, hide the all apps view to prevent layout while initializing activity.getAppsView().getContentView().setVisibility(View.GONE); - AccessibilityManagerCompat.sendStateEventToTest(activity, fromState.ordinal); - return new AnimationFactory() { private Animator mShelfAnim; private ShelfAnimState mShelfState; diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index fe6b522970..8b03691c81 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -49,6 +49,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.UiFactory; @@ -496,6 +497,8 @@ public class LauncherStateManager { for (int i = mListeners.size() - 1; i >= 0; i--) { mListeners.get(i).onStateTransitionComplete(state); } + + AccessibilityManagerCompat.sendStateEventToTest(mLauncher, state.ordinal); } public void onWindowFocusChanged() { diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 4e5f7a59a9..6f53140eab 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -43,7 +43,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.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -541,7 +540,6 @@ public abstract class AbstractStateChangeTouchController android.util.Log.e( TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 2"); } - AccessibilityManagerCompat.sendStateEventToTest(mLauncher, targetState.ordinal); } } From f0d2e0064e3c49f3e4922bd952718c6ca242f790 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 11 Jun 2019 11:44:34 -0700 Subject: [PATCH 11/26] Fix potential NPE in BackgroundAppState Bug: 134559760 Change-Id: I08be7563ec8306ede6c0c7e62b0b5fc0a7c5f998 --- .../launcher3/uioverrides/states/BackgroundAppState.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index f1d6450a5f..1c66968582 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -64,10 +64,12 @@ public class BackgroundAppState extends OverviewState { public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) { // Initialize the recents view scale to what it would be when starting swipe up RecentsView recentsView = launcher.getOverviewPanel(); - if (recentsView.getTaskViewCount() == 0) { + int taskCount = recentsView.getTaskViewCount(); + if (taskCount == 0) { return super.getOverviewScaleAndTranslation(launcher); } - TaskView dummyTask = recentsView.getTaskViewAt(recentsView.getCurrentPage()); + TaskView dummyTask = recentsView.getTaskViewAt(Math.max(taskCount - 1, + recentsView.getCurrentPage())); return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask) .getScaleAndTranslation(); } From 87cfe640c251d540750bdc3d4eee79c082ff5f0d Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 11 Jun 2019 12:56:39 -0700 Subject: [PATCH 12/26] Fix state/anim clobbering when touching down during recents animation Addresses 2 problems: - Set mLauncherTransitionController = null after ending it, to prevent a subsequent end from re-setting OVERVIEW state. - Cancel the shelf animation so that it doesn't clobber the animation to all apps (for instance). Bug: 134309036 Bug: 134309189 Change-Id: I019084a1ba38c6208a6256843cb5c4b6dbb4a662 --- .../com/android/quickstep/WindowTransformSwipeHandler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 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 7d17f85f69..edeae81165 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -868,9 +868,7 @@ public class WindowTransformSwipeHandler @UiThread private InputConsumer createNewInputProxyHandler() { endRunningWindowAnim(); - if (mLauncherTransitionController != null) { - mLauncherTransitionController.getAnimationPlayer().end(); - } + endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha); @@ -1312,6 +1310,7 @@ public class WindowTransformSwipeHandler } private void endLauncherTransitionController() { + setShelfState(ShelfAnimState.CANCEL, LINEAR, 0); if (mLauncherTransitionController != null) { mLauncherTransitionController.getAnimationPlayer().end(); mLauncherTransitionController = null; From 6594390a79bb00227370fd8ac03ff0228696805e Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Tue, 11 Jun 2019 13:42:25 -0700 Subject: [PATCH 13/26] Check if RecentsView is null before setting live tile icon. Fixes: 134969824 Test: N/A Change-Id: Ibd6d8ec729c6809d385ea5f0153ae7ff376801b9 --- .../android/quickstep/TouchInteractionService.java | 12 ++++++++++++ .../src/com/android/quickstep/views/TaskView.java | 8 ++++++-- 2 files changed, 18 insertions(+), 2 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 4a40c64f99..30178a685a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -17,7 +17,12 @@ package com.android.quickstep; import static android.view.MotionEvent.ACTION_DOWN; +import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; +import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME; +import static com.android.launcher3.config.FeatureFlags.ENABLE_HINTS_IN_OVERVIEW; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.config.FeatureFlags.FAKE_LANDSCAPE_UI; +import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; @@ -664,6 +669,13 @@ public class TouchInteractionService extends Service implements mSwipeSharedState.dump(" ", pw); } pw.println(" mConsumer=" + mConsumer.getName()); + pw.println("FeatureFlags:"); + pw.println(" APPLY_CONFIG_AT_RUNTIME=" + APPLY_CONFIG_AT_RUNTIME.get()); + pw.println(" QUICKSTEP_SPRINGS=" + QUICKSTEP_SPRINGS.get()); + pw.println(" ADAPTIVE_ICON_WINDOW_ANIM=" + ADAPTIVE_ICON_WINDOW_ANIM.get()); + pw.println(" ENABLE_QUICKSTEP_LIVE_TILE=" + ENABLE_QUICKSTEP_LIVE_TILE.get()); + pw.println(" ENABLE_HINTS_IN_OVERVIEW=" + ENABLE_HINTS_IN_OVERVIEW.get()); + pw.println(" FAKE_LANDSCAPE_UI=" + FAKE_LANDSCAPE_UI.get()); TOUCH_INTERACTION_LOG.dump("", pw); } 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 bf3e91ff68..e0a4bcad84 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 @@ -353,14 +353,15 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconLoadRequest = iconCache.updateIconInBackground(mTask, (task) -> { setIcon(task.icon); - if (isRunningTask()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask()) { getRecentsView().updateLiveTileIcon(task.icon); } mDigitalWellBeingToast.initialize( mTask, contentDescription -> { setContentDescription(contentDescription); - if (mDigitalWellBeingToast.getVisibility() == VISIBLE) { + if (mDigitalWellBeingToast.getVisibility() == VISIBLE + && getRecentsView() != null) { getRecentsView().onDigitalWellbeingToastShown(); } }); @@ -716,6 +717,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } public boolean isRunningTask() { + if (getRecentsView() == null) { + return false; + } return this == getRecentsView().getRunningTaskView(); } From 0bdd28e2044b8123f5f5139f9914c56298fe6d62 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 11 Jun 2019 14:35:53 -0700 Subject: [PATCH 14/26] Fix double swipe on nav bar from an app Use normal OverviewInputConsumer instead of OverviewWithoutFocusInputConsumer if we are animating to launcher. This allows launcher to properly handle a second swipe in the nav region. Test: enable 2-button mode, double swipe up on nav bar to all apps Bug: 135050372 Change-Id: I0b96f6236bed4f9ac3284a921e4259e1b0d00c75 --- .../src/com/android/quickstep/TouchInteractionService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4a40c64f99..d84adabe14 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -614,7 +614,7 @@ public class TouchInteractionService extends Service implements return InputConsumer.NO_OP; } - if (activity.getRootView().hasWindowFocus()) { + if (activity.getRootView().hasWindowFocus() || mSwipeSharedState.goingToLauncher) { return new OverviewInputConsumer(activity, mInputMonitorCompat, false /* startingInActivityBounds */); } else { From 91683e2bc87af332e75372d37b8c4eed15f940dd Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 11 Jun 2019 15:25:54 -0700 Subject: [PATCH 15/26] Tweak spring stiffness/damping for attaching recents Bug: 129985827 Change-Id: Ife70528a3cdc101260df3425ec0501b318d558e7 --- .../quickstep/LauncherActivityControllerHelper.java | 7 ++----- 1 file changed, 2 insertions(+), 5 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 7809e454a5..bb5efd008f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -30,9 +30,6 @@ import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION; -import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY; -import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW; - import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -321,8 +318,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe if (mAttachToWindowTranslationXAnim == null) { mAttachToWindowTranslationXAnim = new SpringAnimation(recentsView, SpringAnimation.TRANSLATION_X).setSpring(new SpringForce() - .setDampingRatio(DAMPING_RATIO_LOW_BOUNCY) - .setStiffness(STIFFNESS_LOW)); + .setDampingRatio(0.8f) + .setStiffness(250)); } if (!recentsView.isShown() && animate) { recentsView.setTranslationX(fromTranslationX); From a36c8004edb2f2af1d896aae03d4fb55734e0205 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 11 Jun 2019 16:15:54 -0700 Subject: [PATCH 16/26] Reset the overview sysui state when returning to the previous task - Otherwise, it gets stuck until the next time launcher pauses/task launch Bug: 135008910 Change-Id: Ia0696d764522e36a4064583cb82003c1e9c0cb7a --- src/com/android/launcher3/BaseActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 424ffde1ff..64550560ff 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -175,6 +175,10 @@ public abstract class BaseActivity extends Activity mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE; mForceInvisible = 0; super.onStop(); + + // Reset the overridden sysui flags used for the task-swipe launch animation, this is a + // catch all for if we do not get resumed (and therefore not paused below) + getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0); } @Override From a0f9110e5200f0d00114b8657d42fff074563d47 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 12 Jun 2019 00:17:53 -0700 Subject: [PATCH 17/26] Adding support for custom callback when starting ProxyActivity Bug: 133443741 Change-Id: Ifd6a289b7f49d52efe0767b600cecc2b460a87fc --- .../launcher3/proxy/StartActivityParams.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java index 1e8bd933f9..bee8bb8132 100644 --- a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java +++ b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java @@ -31,7 +31,7 @@ public class StartActivityParams implements Parcelable { private static final String TAG = "StartActivityParams"; - private final PendingIntent mCallback; + private final PendingIntent mPICallback; public final int requestCode; public Intent intent; @@ -44,13 +44,17 @@ public class StartActivityParams implements Parcelable { public Bundle options; public StartActivityParams(Activity activity, int requestCode) { - mCallback = activity.createPendingResult(requestCode, new Intent(), - PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); + this(activity.createPendingResult(requestCode, new Intent(), + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT), requestCode); + } + + public StartActivityParams(PendingIntent pendingIntent, int requestCode) { + this.mPICallback = pendingIntent; this.requestCode = requestCode; } private StartActivityParams(Parcel parcel) { - mCallback = parcel.readTypedObject(PendingIntent.CREATOR); + mPICallback = parcel.readTypedObject(PendingIntent.CREATOR); requestCode = parcel.readInt(); intent = parcel.readTypedObject(Intent.CREATOR); @@ -70,7 +74,7 @@ public class StartActivityParams implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeTypedObject(mCallback, flags); + parcel.writeTypedObject(mPICallback, flags); parcel.writeInt(requestCode); parcel.writeTypedObject(intent, flags); @@ -84,7 +88,9 @@ public class StartActivityParams implements Parcelable { public void deliverResult(Context context, int resultCode, Intent data) { try { - mCallback.send(context, resultCode, data); + if (mPICallback != null) { + mPICallback.send(context, resultCode, data); + } } catch (CanceledException e) { Log.e(TAG, "Unable to send back result", e); } From a327e6a3d12d689abd5a2fa014fdfa60249eb4c7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 12 Jun 2019 07:41:14 -0700 Subject: [PATCH 18/26] Initializing ActivityManagerWrapper before device unlock Bug: 134406364 Change-Id: I30339c3790efeaa60db7ea3cbae76d97474c16cc --- .../src/com/android/quickstep/TouchInteractionService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 30178a685a..a952db94ec 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -278,6 +278,7 @@ public class TouchInteractionService extends Service implements // Everything else should be initialized in initWhenUserUnlocked() below. mKM = getSystemService(KeyguardManager.class); mMainChoreographer = Choreographer.getInstance(); + mAM = ActivityManagerWrapper.getInstance(); if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) { initWhenUserUnlocked(); @@ -404,7 +405,6 @@ public class TouchInteractionService extends Service implements } private void initWhenUserUnlocked() { - mAM = ActivityManagerWrapper.getInstance(); mRecentsModel = RecentsModel.INSTANCE.get(this); mOverviewComponentObserver = new OverviewComponentObserver(this); From a029a8b2d59a12720c09f778bb69d49d0d2cc7e2 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 10 Jun 2019 16:03:53 -0700 Subject: [PATCH 19/26] Bypass systemstate check when using shared state System state can change using the interaction, for eg: an app can enter immersive mode in the middle of quickswitch. Ignore such changes to prevent system gestures getting blocked by an app > Fixing nullpointer in device locked consumer construction when user is not locked yet > Creating a fallback resetGesture input consumer, which cancels any pending transition in case we missed to cancel it Bug: 134091263 Bug: 134406364 Change-Id: Iafc4e53691f50862b013ad9c4023839044cf1d72 --- .../android/quickstep/SwipeSharedState.java | 22 ++++++--- .../quickstep/TouchInteractionService.java | 27 ++++++----- .../inputconsumers/InputConsumer.java | 39 +++++++++------- .../ResetGestureInputConsumer.java | 45 +++++++++++++++++++ .../util/RecentsAnimationListenerSet.java | 22 ++++++--- .../util/SwipeAnimationTargetSet.java | 5 ++- 6 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java index 5a039cd905..6689ce3d78 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java @@ -15,8 +15,11 @@ */ package com.android.quickstep; +import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; + import android.util.Log; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.RecentsAnimationListenerSet; @@ -29,7 +32,7 @@ import java.io.PrintWriter; */ public class SwipeSharedState implements SwipeAnimationListener { - private final OverviewComponentObserver mOverviewComponentObserver; + private OverviewComponentObserver mOverviewComponentObserver; private RecentsAnimationListenerSet mRecentsAnimationListener; private SwipeAnimationTargetSet mLastAnimationTarget; @@ -42,8 +45,8 @@ public class SwipeSharedState implements SwipeAnimationListener { public boolean recentsAnimationFinishInterrupted; public int nextRunningTaskId = -1; - public SwipeSharedState(OverviewComponentObserver overviewComponentObserver) { - mOverviewComponentObserver = overviewComponentObserver; + public void setOverviewComponentObserver(OverviewComponentObserver observer) { + mOverviewComponentObserver = observer; } @Override @@ -72,6 +75,12 @@ public class SwipeSharedState implements SwipeAnimationListener { private void clearListenerState() { if (mRecentsAnimationListener != null) { mRecentsAnimationListener.removeListener(this); + mRecentsAnimationListener.cancelListener(); + if (mLastAnimationRunning && mLastAnimationTarget != null) { + Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), + mLastAnimationTarget::cancelAnimation); + mLastAnimationTarget = null; + } } mRecentsAnimationListener = null; clearAnimationTarget(); @@ -98,9 +107,10 @@ public class SwipeSharedState implements SwipeAnimationListener { } clearListenerState(); - mRecentsAnimationListener = new RecentsAnimationListenerSet(mOverviewComponentObserver - .getActivityControlHelper().shouldMinimizeSplitScreen(), - this::onSwipeAnimationFinished); + boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false + : mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen(); + mRecentsAnimationListener = new RecentsAnimationListenerSet( + shouldMinimiseSplitScreen, this::onSwipeAnimationFinished); mRecentsAnimationListener.addListener(this); return mRecentsAnimationListener; } 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 4a40c64f99..a3aeac3611 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -81,6 +81,7 @@ import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.inputconsumers.OtherActivityInputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer; import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer; +import com.android.quickstep.inputconsumers.ResetGestureInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -224,6 +225,10 @@ public class TouchInteractionService extends Service implements return sConnected; } + private final SwipeSharedState mSwipeSharedState = new SwipeSharedState(); + private final InputConsumer mResetGestureInputConsumer = + new ResetGestureInputConsumer(mSwipeSharedState); + private KeyguardManager mKM; private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; @@ -234,7 +239,6 @@ public class TouchInteractionService extends Service implements private OverviewCallbacks mOverviewCallbacks; private TaskOverlayFactory mTaskOverlayFactory; private InputConsumerController mInputConsumer; - private SwipeSharedState mSwipeSharedState; private boolean mAssistantAvailable; private float mLastAssistantVisibility = 0; private @SystemUiStateFlags int mSystemUiStateFlags; @@ -407,10 +411,10 @@ public class TouchInteractionService extends Service implements mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this); mOverviewCallbacks = OverviewCallbacks.get(this); mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this); - mSwipeSharedState = new SwipeSharedState(mOverviewComponentObserver); mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); mIsUserUnlocked = true; + mSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver); mInputConsumer.registerInputConsumer(); onSystemUiProxySet(); onSystemUiFlagsChanged(); @@ -508,12 +512,14 @@ public class TouchInteractionService extends Service implements // launched while device is locked even after exiting direct boot mode (e.g. camera). return createDeviceLockedInputConsumer(mAM.getRunningTask(0)); } else { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } } - InputConsumer base = isInValidSystemUiState - ? newBaseConsumer(useSharedState, event) : InputConsumer.NO_OP; + // When using sharedState, bypass systemState check as this is a followup gesture and the + // first gesture started in a valid system state. + InputConsumer base = isInValidSystemUiState || useSharedState + ? newBaseConsumer(useSharedState, event) : mResetGestureInputConsumer; if (mMode == Mode.NO_BUTTON) { final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); @@ -558,7 +564,7 @@ public class TouchInteractionService extends Service implements if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher && !mSwipeSharedState.recentsAnimationFinishInterrupted) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } else if (mSwipeSharedState.recentsAnimationFinishInterrupted) { // If the finish animation was interrupted, then continue using the other activity input // consumer but with the next task as the running task @@ -571,7 +577,7 @@ public class TouchInteractionService extends Service implements return createOverviewInputConsumer(event); } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } else { return createOtherActivityInputConsumer(event, runningTaskInfo); } @@ -602,7 +608,7 @@ public class TouchInteractionService extends Service implements return new DeviceLockedInputConsumer(this, mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, taskInfo.taskId); } else { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } } @@ -611,7 +617,7 @@ public class TouchInteractionService extends Service implements mOverviewComponentObserver.getActivityControlHelper(); BaseDraggingActivity activity = activityControl.getCreatedActivity(); if (activity == null) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } if (activity.getRootView().hasWindowFocus()) { @@ -628,7 +634,8 @@ public class TouchInteractionService extends Service implements */ private void onConsumerInactive(InputConsumer caller) { if (mConsumer == caller) { - mConsumer = InputConsumer.NO_OP; + mConsumer = mResetGestureInputConsumer; + mUncheckedConsumer = mConsumer; } } 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 489eb278fd..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 @@ -32,6 +32,19 @@ public interface InputConsumer { int TYPE_ACCESSIBILITY = 1 << 5; int TYPE_SCREEN_PINNED = 1 << 6; int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; + int TYPE_RESET_GESTURE = 1 << 8; + + String[] NAMES = new String[] { + "TYPE_NO_OP", // 0 + "TYPE_OVERVIEW", // 1 + "TYPE_OTHER_ACTIVITY", // 2 + "TYPE_ASSISTANT", // 3 + "TYPE_DEVICE_LOCKED", // 4 + "TYPE_ACCESSIBILITY", // 5 + "TYPE_SCREEN_PINNED", // 6 + "TYPE_OVERVIEW_WITHOUT_FOCUS", // 7 + "TYPE_RESET_GESTURE", // 8 + }; InputConsumer NO_OP = () -> TYPE_NO_OP; @@ -66,23 +79,15 @@ public interface InputConsumer { } default String getName() { - switch (getType()) { - case TYPE_OVERVIEW: - return "OVERVIEW"; - case TYPE_OTHER_ACTIVITY: - return "OTHER_ACTIVITY"; - case TYPE_ASSISTANT: - return "ASSISTANT"; - case TYPE_DEVICE_LOCKED: - return "DEVICE_LOCKED"; - case TYPE_ACCESSIBILITY: - return "ACCESSIBILITY"; - case TYPE_SCREEN_PINNED: - return "SCREEN_PINNED"; - case TYPE_OVERVIEW_WITHOUT_FOCUS: - return "TYPE_OVERVIEW_WITHOUT_FOCUS"; - default: - return "NO_OP"; + String name = ""; + for (int i = 0; i < NAMES.length; i++) { + if ((getType() & (1 << i)) != 0) { + if (name.length() > 0) { + name += ":"; + } + name += NAMES[i]; + } } + return name; } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java new file mode 100644 index 0000000000..56cba2192a --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java @@ -0,0 +1,45 @@ +/* + * 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.inputconsumers; + +import android.view.MotionEvent; + +import com.android.quickstep.SwipeSharedState; + +/** + * A NO_OP input consumer which also resets any pending gesture + */ +public class ResetGestureInputConsumer implements InputConsumer { + + private final SwipeSharedState mSwipeSharedState; + + public ResetGestureInputConsumer(SwipeSharedState swipeSharedState) { + mSwipeSharedState = swipeSharedState; + } + + @Override + public int getType() { + return TYPE_RESET_GESTURE; + } + + @Override + public void onMotionEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN + && mSwipeSharedState.getActiveListener() != null) { + mSwipeSharedState.clearAllState(); + } + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java index 94e704a716..83601e6175 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java @@ -49,6 +49,8 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { private final Consumer mOnFinishListener; private RecentsAnimationControllerCompat mController; + private boolean mCancelled; + public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen, Consumer onFinishListener) { mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen; @@ -75,11 +77,16 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, targets, homeContentInsets, minimizedHomeBounds, mShouldMinimizeSplitScreen, mOnFinishListener); - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { - for (SwipeAnimationListener listener : getListeners()) { - listener.onRecentsAnimationStart(targetSet); - } - }); + + if (mCancelled) { + targetSet.cancelAnimation(); + } else { + Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + for (SwipeAnimationListener listener : getListeners()) { + listener.onRecentsAnimationStart(targetSet); + } + }); + } } @Override @@ -99,4 +106,9 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { private SwipeAnimationListener[] getListeners() { return mListeners.toArray(new SwipeAnimationListener[mListeners.size()]); } + + public void cancelListener() { + mCancelled = true; + onAnimationCanceled(false); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java index f5a9e8a058..df9efa2477 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java @@ -36,7 +36,6 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { private final boolean mShouldMinimizeSplitScreen; private final Consumer mOnFinishListener; - public final RecentsAnimationControllerCompat controller; public final Rect homeContentInsets; public final Rect minimizedHomeBounds; @@ -103,6 +102,10 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { return controller != null ? controller.screenshotTask(taskId) : null; } + public void cancelAnimation() { + finishController(false /* toRecents */, null, false /* sendUserLeaveHint */); + } + public interface SwipeAnimationListener { void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet); From d0308dbd144fb6714c59cfa41caa4fdfe7896045 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 12 Jun 2019 09:10:31 -0700 Subject: [PATCH 20/26] Resetting taskView alpha to proper value onAnimationEnd Bug: 135114549 Change-Id: I4effc4c9d8e6c03e41c8f06c441477076ce7a622 --- .../src/com/android/quickstep/views/RecentsView.java | 4 ++-- .../src/com/android/quickstep/views/TaskView.java | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) 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 90e123e847..f66e401f9a 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 @@ -892,7 +892,7 @@ public abstract class RecentsView extends PagedView impl mRunningTaskTileHidden = isHidden; TaskView runningTask = getRunningTaskView(); if (runningTask != null) { - runningTask.setAlpha(isHidden ? 0 : mContentAlpha); + runningTask.setStableAlpha(isHidden ? 0 : mContentAlpha); } } @@ -1294,7 +1294,7 @@ public abstract class RecentsView extends PagedView impl for (int i = getTaskViewCount() - 1; i >= 0; i--) { TaskView child = getTaskViewAt(i); if (!mRunningTaskTileHidden || child.getTask().key.id != mRunningTaskId) { - getChildAt(i).setAlpha(alpha); + child.setStableAlpha(alpha); } } mClearAllButton.setContentAlpha(mContentAlpha); 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 e0a4bcad84..354241b0cd 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 @@ -163,6 +163,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; + private float mStableAlpha = 1; private boolean mShowScreenshot; @@ -469,7 +470,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { setTranslationX(0f); setTranslationY(0f); setTranslationZ(0); - setAlpha(1f); + setAlpha(mStableAlpha); setIconScaleAndDim(1); } @@ -478,6 +479,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { setFullscreenProgress(0); } + public void setStableAlpha(float parentAlpha) { + mStableAlpha = parentAlpha; + setAlpha(mStableAlpha); + } + @Override public void onRecycle() { resetViewTransforms(); From c8502c1df5c236fa2ab58b5618bfc2c18cb84d37 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 10 Jun 2019 12:14:47 -0700 Subject: [PATCH 21/26] Do not rebind when when deviceProfile has not changed This avoids UI flicker when using fakeLandscape UI during swipe-up animation Bug: 131360075 Change-Id: I651e0acb79b54be66b93c746eed6e9b099f2f767 --- src/com/android/launcher3/Launcher.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 2c9a37a65c..4e905c7265 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -461,6 +461,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private void onIdpChanged(InvariantDeviceProfile idp) { mUserEventDispatcher = null; + DeviceProfile oldWallpaperProfile = getWallpaperDeviceProfile(); initDeviceProfile(idp); dispatchDeviceProfileChanged(); reapplyUi(); @@ -469,8 +470,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // Calling onSaveInstanceState ensures that static cache used by listWidgets is // initialized properly. onSaveInstanceState(new Bundle()); - // TODO: We can probably avoid rebind when only screen size changed. - rebindModel(); + if (oldWallpaperProfile != getWallpaperDeviceProfile()) { + rebindModel(); + } } public void onAssistantVisibilityChanged(float visibility) { From 022b18263468282979e84fd8864bee4f67919f2d Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 12 Jun 2019 08:44:09 -0700 Subject: [PATCH 22/26] Updating consumed insets when dispatching to child views Bug: 134963243 Change-Id: I4fa072128398cfd22b906037c6c444495781c9d0 --- .../android/launcher3/LauncherRootView.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 49b380b41f..f964b8d9ee 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -8,18 +8,22 @@ import android.app.ActivityManager; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Insets; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewDebug; +import android.view.WindowInsets; import java.util.Collections; import java.util.List; public class LauncherRootView extends InsettableFrameLayout { + private final Rect mTempRect = new Rect(); + private final Launcher mLauncher; private final Paint mOpaquePaint; @@ -56,9 +60,7 @@ public class LauncherRootView extends InsettableFrameLayout { super.onFinishInflate(); } - @TargetApi(23) - @Override - protected boolean fitSystemWindows(Rect insets) { + private void handleSystemWindowInsets(Rect insets) { mConsumedInsets.setEmpty(); boolean drawInsetBar = false; if (mLauncher.isInMultiWindowMode() @@ -66,13 +68,13 @@ public class LauncherRootView extends InsettableFrameLayout { mConsumedInsets.left = insets.left; mConsumedInsets.right = insets.right; mConsumedInsets.bottom = insets.bottom; - insets = new Rect(0, insets.top, 0, 0); + insets.set(0, insets.top, 0, 0); drawInsetBar = true; } else if ((insets.right > 0 || insets.left > 0) && getContext().getSystemService(ActivityManager.class).isLowRamDevice()) { mConsumedInsets.left = insets.left; mConsumedInsets.right = insets.right; - insets = new Rect(0, insets.top, 0, insets.bottom); + insets.set(0, insets.top, 0, insets.bottom); drawInsetBar = true; } @@ -99,8 +101,19 @@ public class LauncherRootView extends InsettableFrameLayout { if (resetState) { mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */); } + } - return false; // Let children get the full insets + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), + insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); + handleSystemWindowInsets(mTempRect); + if (Utilities.ATLEAST_Q) { + return insets.inset(mConsumedInsets.left, mConsumedInsets.top, + mConsumedInsets.right, mConsumedInsets.bottom); + } else { + return insets.replaceSystemWindowInsets(mTempRect); + } } @Override From e8836dc0823a4b7115f2bc7b5f93c4d6b8cc9f7a Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 11 Jun 2019 18:31:15 -0700 Subject: [PATCH 23/26] Gracefully handle failed task launches during quick switch When quick switching from home or overview, go to OverviewState if the task launch failed. Otherwise we get stuck in BackgroundAppState. Bug: 135038270 Change-Id: I42785c261cef0df95666bc106ec5ca6ef0553cc7 --- .../quickstep/GoActivityControlHelper.java | 5 +++++ .../uioverrides/states/QuickSwitchState.java | 12 +++++++++++- .../FallbackActivityControllerHelper.java | 6 ++++++ .../LauncherActivityControllerHelper.java | 5 +++++ .../quickstep/WindowTransformSwipeHandler.java | 15 ++++++++++++++- .../android/quickstep/ActivityControlHelper.java | 2 ++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java index 2db8b39d94..274a347cbb 100644 --- a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java +++ b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java @@ -61,4 +61,9 @@ public abstract class GoActivityControlHelper im // Go does not support live tiles. return false; } + + @Override + public void onLaunchTaskFailed(T activity) { + // Go does not support gestures from one task to another. + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java index ed511f5f2f..cdc271fdd3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java @@ -15,6 +15,9 @@ */ package com.android.launcher3.uioverrides.states; +import android.os.Handler; +import android.os.Looper; + import com.android.launcher3.Launcher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.views.RecentsView; @@ -27,6 +30,8 @@ import com.android.quickstep.views.TaskView; */ public class QuickSwitchState extends BackgroundAppState { + private static final String TAG = "QuickSwitchState"; + public QuickSwitchState(int id) { super(id, LauncherLogProto.ContainerType.APP); } @@ -48,7 +53,12 @@ public class QuickSwitchState extends BackgroundAppState { public void onStateTransitionEnd(Launcher launcher) { TaskView tasktolaunch = launcher.getOverviewPanel().getTaskViewAt(0); if (tasktolaunch != null) { - tasktolaunch.launchTask(false); + tasktolaunch.launchTask(false, success -> { + if (!success) { + launcher.getStateManager().goToState(OVERVIEW); + tasktolaunch.notifyTaskLaunchFailed(TAG); + } + }, new Handler(Looper.getMainLooper())); } else { launcher.getStateManager().goToState(NORMAL); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java index 2c42fd63a6..4ae6d87b8d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java @@ -224,4 +224,10 @@ public final class FallbackActivityControllerHelper implements public boolean isInLiveTileMode() { return false; } + + @Override + public void onLaunchTaskFailed(RecentsActivity activity) { + // TODO: probably go back to overview instead. + activity.getOverviewPanel().startHome(); + } } 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 7809e454a5..5449b47e0d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -512,4 +512,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return launcher != null && launcher.getStateManager().getState() == OVERVIEW && launcher.isStarted(); } + + @Override + public void onLaunchTaskFailed(Launcher launcher) { + launcher.getStateManager().goToState(OVERVIEW); + } } \ No newline at end of file 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 7d17f85f69..06abb80188 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -746,6 +746,9 @@ public class WindowTransformSwipeHandler ? 0 : (progress - mShiftAtGestureStart) / (1 - mShiftAtGestureStart)); } + /** + * @param windowProgress 0 == app, 1 == overview + */ private void updateSysUiFlags(float windowProgress) { if (mRecentsView != null) { TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView @@ -1249,7 +1252,17 @@ public class WindowTransformSwipeHandler if (!mCanceled) { TaskView nextTask = mRecentsView.getTaskView(taskId); if (nextTask != null) { - nextTask.launchTask(false /* animate */, true /* freezeTaskList */); + 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 */); + } + }, mMainThreadHandler); doLogGesture(NEW_TASK); } reset(); diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index dcc1ace883..8675c3e02e 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -93,6 +93,8 @@ public interface ActivityControlHelper { boolean isInLiveTileMode(); + void onLaunchTaskFailed(T activity); + interface ActivityInitListener { void register(); From 87fbd33a3702bc77a68a824dd1e36d4010574767 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 12 Jun 2019 15:26:27 -0700 Subject: [PATCH 24/26] Not using settings app in tests Change-Id: I7542dab07a0d5a76cc90f4b5eee0d376b5d8ca11 --- .../tests/src/com/android/quickstep/FallbackRecentsTest.java | 3 ++- tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 20fdff2c55..013591171c 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -22,6 +22,7 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS; import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage; import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess; +import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp; import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification; import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand; import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON; @@ -108,7 +109,7 @@ public class FallbackRecentsTest { @NavigationModeSwitch(mode = THREE_BUTTON) @Test public void goToOverviewFromApp() { - startAppFast("com.android.settings"); + startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); mLauncher.getBackground().switchToOverview(); } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 64fe2d7d79..abc93cd4b7 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -395,7 +395,7 @@ public abstract class AbstractLauncherUiTest { DEFAULT_UI_TIMEOUT)); } - protected static String resolveSystemApp(String category) { + public static String resolveSystemApp(String category) { return getInstrumentation().getContext().getPackageManager().resolveActivity( new Intent(Intent.ACTION_MAIN).addCategory(category), PackageManager.MATCH_SYSTEM_ONLY). From 16284b956c6f185c1b3d65d9cfcdaeecd8a455ac Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 12 Jun 2019 15:27:33 -0700 Subject: [PATCH 25/26] Fading out the home surface if home and recents are shown in separate surface Bug: 134725160 Change-Id: Ia4c5e0eefc4d8b869840645f403d943831c471f1 --- .../src/com/android/quickstep/util/ClipAnimationHelper.java | 6 +++++- .../android/quickstep/util/RemoteAnimationTargetSet.java | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) 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 aca23e4e40..de671e04aa 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 @@ -192,6 +192,7 @@ public class ClipAnimationHelper { 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); if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL); mTmpMatrix.postTranslate(app.position.x, app.position.y); @@ -208,8 +209,11 @@ public class ClipAnimationHelper { } mCurrentCornerRadius = cornerRadius; } + } else if (targetSet.hasRecents) { + // If home has a different target then recents, reverse anim the + // home target. + alpha = 1 - (progress * params.targetAlpha); } - alpha = mTaskAlphaCallback.apply(app, params.targetAlpha); } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { crop = null; layer = Integer.MAX_VALUE; diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java index 0df4e947d3..1229293e6e 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java @@ -33,20 +33,26 @@ public class RemoteAnimationTargetSet { public final RemoteAnimationTargetCompat[] unfilteredApps; public final RemoteAnimationTargetCompat[] apps; public final int targetMode; + public final boolean hasRecents; public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps, int targetMode) { ArrayList filteredApps = new ArrayList<>(); + boolean hasRecents = false; if (apps != null) { for (RemoteAnimationTargetCompat target : apps) { if (target.mode == targetMode) { filteredApps.add(target); } + + hasRecents |= target.activityType == + RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS; } } this.unfilteredApps = apps; this.apps = filteredApps.toArray(new RemoteAnimationTargetCompat[filteredApps.size()]); this.targetMode = targetMode; + this.hasRecents = hasRecents; } public RemoteAnimationTargetCompat findTask(int taskId) { From 3827b3afd391fc91161b2aee3c45f1f57a48556b Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Wed, 12 Jun 2019 15:40:54 -0700 Subject: [PATCH 26/26] Expose getTaskView to Overlays. Test: Manual Change-Id: Ie8583606e65f9a77536de4a7cbd1aa3d88e81e1e --- .../src/com/android/quickstep/TaskOverlayFactory.java | 3 ++- .../src/com/android/quickstep/views/TaskThumbnailView.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 5104fb8801..b90f6c2b17 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -24,6 +24,7 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.ResourceBasedOverride; +import com.android.quickstep.views.TaskThumbnailView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -62,7 +63,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { return shortcuts; } - public TaskOverlay createOverlay(View thumbnailView) { + public TaskOverlay createOverlay(TaskThumbnailView thumbnailView) { return new TaskOverlay(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index 8b8240d0a5..6f10b42fba 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -252,7 +252,7 @@ public class TaskThumbnailView extends View { } } - protected TaskView getTaskView() { + public TaskView getTaskView() { return (TaskView) getParent(); }