summaryrefslogtreecommitdiffstats
path: root/quickstep/recents_ui_overrides
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2019-06-13 08:34:48 -0700
committerSunny Goyal <sunnygoyal@google.com>2019-06-13 15:36:46 +0000
commit0e57817adce06277b7ae07fdc5c0d1c4e1723958 (patch)
tree55dec84a639d2e1a979301523a9f3aded6e6debc /quickstep/recents_ui_overrides
parent0ea61abe1012fa25e9b15e95e04b368471c4ac6a (diff)
parent3d6e96d5265cdea78ad4e01b0f9fde0eea539094 (diff)
downloadandroid_packages_apps_Trebuchet-0e57817adce06277b7ae07fdc5c0d1c4e1723958.tar.gz
android_packages_apps_Trebuchet-0e57817adce06277b7ae07fdc5c0d1c4e1723958.tar.bz2
android_packages_apps_Trebuchet-0e57817adce06277b7ae07fdc5c0d1c4e1723958.zip
Merging ub-launcher3-qt-dev, build 5656472
Test: Manual Bug:125844074 P2 Final UX and animations for Launcher DWB integration Bug:129985827 P1 [Fully Gestural Navigation] Delay Recents animation when swiping up Bug:131360075 P1 [Gesture Nav] Polish/finish landscape Bug:132900132 P1 Apparently, tests start running while provisioning is still in progress Bug:133009122 P2 Rare flake: dragged launchable to workspace, but the current state is not WORKSPACE; Can't find a launcher object; selector: BySelector [RES='\Qcom.google.android.apps.nexuslauncher:id/apps_view\E'] Bug:133443741 P2 Provide a ImageApi.cropBitmap API between Launcher/UI library Bug:133765434 P1 [Flaky test] Launching task didn't open a new window Bug:133867119 P2 Lab-only flake: want to switch from workspace to all apps; Swipe failed to receive an event for the swipe end Bug:134091263 P1 Can't swipe up Bug:134164918 P1 STOPSHIP: Disable chips hard-coded value in qt_dev Launcher Bug:134309036 P1 Immediately dragging up after opening recents causes a flicker with fully gestural navigation enabled Bug:134309189 P1 Immediately dragging up from recents doesn't open all apps with fully gestural navigation enabled Bug:134406364 P2 [Multiuser] Pixel launcher crashed after switching to secondary user. Bug:134559760 P2 Launcher crashed when keeping phone in face enroll page for 2~3 minutes. (fail rate: 3 of 10 trials) Bug:134707989 P1 List widgets are reinitialized on rotation Bug:134725160 P2 Swiping up on two-button nav does not hide icons with 3p launcher Bug:134919468 P2 [Q-Preview4] Quickstep crash on app remaining time tap on Essential phone Bug:134963243 P4 In multiwindow mode, seeing a shade on scrolling all apps screen. Bug:134964922 P1 Wrap createLegacyIconExtras in a target sdk check Bug:134969824 P4 Pixel launcher crashed while resuming chrome video in PIP mode Bug:134971634 P1 onSystemUiStateChanged and some other binder calls can crash Launcher Bug:135008910 P1 Launcher with black status bar/nav bar icons Bug:135038270 P1 Apps getting stuck while switching in the overiew screen. Bug:135050372 P1 Regression: Can no longer double swipe nav bar from an app to go to all apps in 2-button mode Bug:135114549 P1 TaskView becomes visible at the end to swipe-down Bug:issue priority summary Change-Id: Ief4ecb36f17e168cdeb7aef930bcb051e29dbc02
Diffstat (limited to 'quickstep/recents_ui_overrides')
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java12
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java103
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java22
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java109
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java50
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java39
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java11
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java45
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java22
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java8
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java14
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java18
18 files changed, 341 insertions, 140 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 f1d6450a5..1c6696858 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();
}
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 ed511f5f2..cdc271fdd 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.<RecentsView>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 2c42fd63a..4ae6d87b8 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.<RecentsView>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 1b82bcb57..0d06c19ab 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -16,13 +16,17 @@
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;
@@ -44,16 +48,19 @@ 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;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
@@ -100,6 +107,13 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
}
@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();
if (launcher != null) {
@@ -156,18 +170,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();
}
};
@@ -196,12 +215,11 @@ 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;
- private Animator mAttachToWindowAnim;
+ private Animator mAttachToWindowFadeAnim;
+ private SpringAnimation mAttachToWindowTranslationXAnim;
private boolean mIsAttachedToWindow;
@Override
@@ -267,20 +285,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(0.8f)
+ .setStiffness(250));
+ }
+ 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();
}
};
}
@@ -448,4 +506,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/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index 5a039cd90..6689ce3d7 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/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 5104fb880..b90f6c2b1 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/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index dc354404a..097ff4659 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;
@@ -27,7 +32,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 +65,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;
@@ -81,6 +86,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;
@@ -94,7 +100,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 +151,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 +184,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 +203,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 **/
@@ -236,6 +230,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;
@@ -246,13 +244,11 @@ public class TouchInteractionService extends Service implements
private OverviewCallbacks mOverviewCallbacks;
private TaskOverlayFactory mTaskOverlayFactory;
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<Runnable> mOnUserUnlockedCallbacks;
private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -286,7 +282,7 @@ public class TouchInteractionService extends Service implements
// Everything else should be initialized in initWhenUserUnlocked() below.
mKM = getSystemService(KeyguardManager.class);
mMainChoreographer = Choreographer.getInstance();
- mOnUserUnlockedCallbacks = new ArrayList<>();
+ mAM = ActivityManagerWrapper.getInstance();
if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
initWhenUserUnlocked();
@@ -413,26 +409,21 @@ 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);
mOverviewCallbacks = OverviewCallbacks.get(this);
mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
- mSwipeSharedState = new SwipeSharedState(mOverviewComponentObserver);
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
- mInputConsumer.registerInputConsumer();
+ mIsUserUnlocked = true;
- for (Runnable callback : mOnUserUnlockedCallbacks) {
- callback.run();
- }
- mOnUserUnlockedCallbacks.clear();
+ mSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
+ mInputConsumer.registerInputConsumer();
+ onSystemUiProxySet();
+ onSystemUiFlagsChanged();
+ onAssistantVisibilityChanged();
// Temporarily disable model preload
// new ModelPreload().start(this);
@@ -440,11 +431,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);
}
}
@@ -510,12 +517,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();
@@ -560,7 +569,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
@@ -573,7 +582,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);
}
@@ -604,7 +613,7 @@ public class TouchInteractionService extends Service implements
return new DeviceLockedInputConsumer(this, mSwipeSharedState, mInputMonitorCompat,
mSwipeTouchRegion, taskInfo.taskId);
} else {
- return InputConsumer.NO_OP;
+ return mResetGestureInputConsumer;
}
}
@@ -613,10 +622,10 @@ 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()) {
+ if (activity.getRootView().hasWindowFocus() || mSwipeSharedState.goingToLauncher) {
return new OverviewInputConsumer(activity, mInputMonitorCompat,
false /* startingInActivityBounds */);
} else {
@@ -630,7 +639,8 @@ public class TouchInteractionService extends Service implements
*/
private void onConsumerInactive(InputConsumer caller) {
if (mConsumer == caller) {
- mConsumer = InputConsumer.NO_OP;
+ mConsumer = mResetGestureInputConsumer;
+ mUncheckedConsumer = mConsumer;
}
}
@@ -666,6 +676,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/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index c7841d98e..e9aa6d078 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<T extends BaseDraggingActivity>
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<T extends BaseDraggingActivity>
}
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<T extends BaseDraggingActivity>
: 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<T extends BaseDraggingActivity>
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<T extends BaseDraggingActivity>
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);
@@ -751,6 +746,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
? 0 : (progress - mShiftAtGestureStart) / (1 - mShiftAtGestureStart));
}
+ /**
+ * @param windowProgress 0 == app, 1 == overview
+ */
private void updateSysUiFlags(float windowProgress) {
if (mRecentsView != null) {
TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView
@@ -873,9 +871,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@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);
@@ -1217,6 +1213,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
if (mRecentsView != null) {
mRecentsView.post(mRecentsView::resetTaskVisuals);
}
+ // Make sure recents is in its final state
+ maybeUpdateRecentsAttachedState(false);
+ mActivityControlHelper.onSwipeUpToHomeComplete(mActivity);
}
});
return anim;
@@ -1251,7 +1250,17 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
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();
@@ -1314,6 +1323,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
}
private void endLauncherTransitionController() {
+ setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
if (mLauncherTransitionController != null) {
mLauncherTransitionController.getAnimationPlayer().end();
mLauncherTransitionController = null;
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 489eb278f..a1e5d47a5 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/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 70ea62796..b021df877 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,5 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
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);
- }
}
+
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 000000000..56cba2192
--- /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/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
index 19a496346..6dc672ecf 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/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
index 94e704a71..83601e617 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<SwipeAnimationTargetSet> mOnFinishListener;
private RecentsAnimationControllerCompat mController;
+ private boolean mCancelled;
+
public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen,
Consumer<SwipeAnimationTargetSet> 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 f5a9e8a05..df9efa247 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<SwipeAnimationTargetSet> 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);
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 204dd5687..5aab944a3 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 "
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 e38a315f8..f66e401f9 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<T extends BaseActivity> 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<T extends BaseActivity> 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);
@@ -1676,6 +1676,16 @@ public abstract class RecentsView<T extends BaseActivity> 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<MotionEvent> getEventDispatcher(RotationMode rotationMode) {
if (rotationMode.isTransposed) {
Matrix transform = new Matrix();
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 8b8240d0a..6f10b42fb 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();
}
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 bf3e91ff6..694d50190 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;
@@ -353,14 +354,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();
}
});
@@ -468,7 +470,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
setTranslationX(0f);
setTranslationY(0f);
setTranslationZ(0);
- setAlpha(1f);
+ setAlpha(mStableAlpha);
setIconScaleAndDim(1);
}
@@ -477,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();
@@ -498,6 +505,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());
@@ -716,6 +725,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
}
public boolean isRunningTask() {
+ if (getRecentsView() == null) {
+ return false;
+ }
return this == getRecentsView().getRunningTaskView();
}