Fallback recents activity fixes:
> Always deferring the start activity call
> Fixing quickscrub when start activtiy is deferred
> Preventing finish() call on the activity
> Fixing initTrack to work when the activity already exists
Bug: 75979063
Change-Id: Id6038c1f6c2680ec920222fb6a85c0ecc0172ed4
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 5841285..95947d7 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
@@ -46,9 +47,6 @@
import com.android.quickstep.views.LauncherRecentsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.AssistDataReceiver;
-import com.android.systemui.shared.system.RecentsAnimationListener;
import java.util.function.BiPredicate;
@@ -85,9 +83,6 @@
ActivityInitListener createActivityInitListener(BiPredicate<T, Boolean> onInitListener);
- void startRecentsFromSwipe(Intent intent, AssistDataReceiver assistDataReceiver,
- final RecentsAnimationListener remoteAnimationListener);
-
@Nullable
T getCreatedActivity();
@@ -98,6 +93,12 @@
@UiThread
boolean switchToRecentsIfVisible();
+ /**
+ * @return {@code true} if recents activity should be started immediately on touchDown,
+ * {@code false} if it should deferred until some threshold is crossed.
+ */
+ boolean deferStartingActivity(int downHitTarget);
+
class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {
@Override
@@ -220,13 +221,6 @@
return new LauncherInitListener(onInitListener);
}
- @Override
- public void startRecentsFromSwipe(Intent intent, AssistDataReceiver assistDataReceiver,
- final RecentsAnimationListener remoteAnimationListener) {
- ActivityManagerWrapper.getInstance().startRecentsActivity(
- intent, assistDataReceiver, remoteAnimationListener, null, null);
- }
-
@Nullable
@Override
public Launcher getCreatedActivity() {
@@ -262,6 +256,11 @@
}
return false;
}
+
+ @Override
+ public boolean deferStartingActivity(int downHitTarget) {
+ return downHitTarget == HIT_TARGET_BACK;
+ }
}
class FallbackActivityControllerHelper implements ActivityControlHelper<RecentsActivity> {
@@ -353,14 +352,6 @@
return new RecentsActivityTracker(onInitListener);
}
- @Override
- public void startRecentsFromSwipe(Intent intent, AssistDataReceiver assistDataReceiver,
- final RecentsAnimationListener remoteAnimationListener) {
- // We can use the normal recents animation for swipe up
- ActivityManagerWrapper.getInstance().startRecentsActivity(
- intent, assistDataReceiver, remoteAnimationListener, null, null);
- }
-
@Nullable
@Override
public RecentsActivity getCreatedActivity() {
@@ -381,6 +372,12 @@
public boolean switchToRecentsIfVisible() {
return false;
}
+
+ @Override
+ public boolean deferStartingActivity(int downHitTarget) {
+ // Always defer starting the activity when using fallback
+ return true;
+ }
}
interface LayoutListener {
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 4d695de..28c950b 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -21,8 +21,7 @@
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
+
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_DRAG_SLOP_PX;
import android.annotation.TargetApi;
@@ -55,7 +54,6 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -66,8 +64,6 @@
public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
- private static final int[] DEFERRED_HIT_TARGETS = false
- ? new int[] {HIT_TARGET_BACK, HIT_TARGET_OVERVIEW} : new int[] {HIT_TARGET_BACK};
private final RunningTaskInfo mRunningTask;
private final RecentsModel mRecentsModel;
@@ -102,7 +98,7 @@
mActivityControlHelper = activityControl;
mMainThreadExecutor = mainThreadExecutor;
mBackgroundThreadChoreographer = backgroundThreadChoreographer;
- mIsDeferredDownTarget = Arrays.binarySearch(DEFERRED_HIT_TARGETS, downHitTarget) >= 0;
+ mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
}
@Override
@@ -218,7 +214,8 @@
handler.initWhenReady();
TraceHelper.beginSection("RecentsController");
- Runnable startActivity = () -> mActivityControlHelper.startRecentsFromSwipe(mHomeIntent,
+ Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
+ mHomeIntent,
new AssistDataReceiver() {
@Override
public void onHandleAssistData(Bundle bundle) {
@@ -247,7 +244,7 @@
handler.onRecentsAnimationCanceled();
}
}
- });
+ }, null, null);
if (Looper.myLooper() != Looper.getMainLooper()) {
startActivity.run();
@@ -305,6 +302,13 @@
@Override
public void updateTouchTracking(int interactionType) {
+ if (!mPassedInitialSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
+ // If we deferred starting the window animation on touch down, then
+ // start tracking now
+ startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
+ mPassedInitialSlop = true;
+ }
+
notifyGestureStarted();
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index cf60fdf..19ef8ab 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import android.app.ActivityOptions;
+import android.content.Intent;
import android.os.Bundle;
import android.view.View;
@@ -103,8 +104,26 @@
}
@Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ RecentsActivityTracker.onRecentsActivityNewIntent(this);
+ }
+
+ @Override
protected void onDestroy() {
super.onDestroy();
RecentsActivityTracker.onRecentsActivityDestroy(this);
}
+
+ @Override
+ public void onBackPressed() {
+ // TODO: Launch the task we came from
+ startHome();
+ }
+
+ public void startHome() {
+ startActivity(new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
index 77f0e7a..fb6090e 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
@@ -22,6 +22,7 @@
import android.os.Bundle;
import android.os.Handler;
+import com.android.launcher3.MainThreadExecutor;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
@@ -34,9 +35,8 @@
@TargetApi(Build.VERSION_CODES.P)
public class RecentsActivityTracker implements ActivityInitListener {
- private static final Object LOCK = new Object();
- private static WeakReference<RecentsActivityTracker> sTracker = new WeakReference<>(null);
private static WeakReference<RecentsActivity> sCurrentActivity = new WeakReference<>(null);
+ private static final Scheduler sScheduler = new Scheduler();
private final BiPredicate<RecentsActivity, Boolean> mOnInitListener;
@@ -46,42 +46,20 @@
@Override
public void register() {
- synchronized (LOCK) {
- sTracker = new WeakReference<>(this);
- }
+ sScheduler.schedule(this);
}
@Override
public void unregister() {
- synchronized (LOCK) {
- if (sTracker.get() == this) {
- sTracker.clear();
- }
- }
+ sScheduler.clearReference(this);
}
- public static void onRecentsActivityCreate(RecentsActivity activity) {
- synchronized (LOCK) {
- RecentsActivityTracker tracker = sTracker.get();
- if (tracker != null && tracker.mOnInitListener.test(activity, false)) {
- sTracker.clear();
- }
- sCurrentActivity = new WeakReference<>(activity);
- }
- }
-
- public static void onRecentsActivityDestroy(RecentsActivity activity) {
- synchronized (LOCK) {
- if (sCurrentActivity.get() == activity) {
- sCurrentActivity.clear();
- }
- }
+ private boolean init(RecentsActivity activity, boolean visible) {
+ return mOnInitListener.test(activity, visible);
}
public static RecentsActivity getCurrentActivity() {
- synchronized (LOCK) {
- return sCurrentActivity.get();
- }
+ return sCurrentActivity.get();
}
@Override
@@ -92,4 +70,62 @@
Bundle options = animProvider.toActivityOptions(handler, duration).toBundle();
context.startActivity(intent, options);
}
+
+ public static void onRecentsActivityCreate(RecentsActivity activity) {
+ sCurrentActivity = new WeakReference<>(activity);
+ sScheduler.initIfPending(activity, false);
+ }
+
+
+ public static void onRecentsActivityNewIntent(RecentsActivity activity) {
+ sScheduler.initIfPending(activity, activity.isStarted());
+ }
+
+ public static void onRecentsActivityDestroy(RecentsActivity activity) {
+ if (sCurrentActivity.get() == activity) {
+ sCurrentActivity.clear();
+ }
+ }
+
+
+ private static class Scheduler implements Runnable {
+
+ private WeakReference<RecentsActivityTracker> mPendingTracker = new WeakReference<>(null);
+ private MainThreadExecutor mMainThreadExecutor;
+
+ public synchronized void schedule(RecentsActivityTracker tracker) {
+ mPendingTracker = new WeakReference<>(tracker);
+ if (mMainThreadExecutor == null) {
+ mMainThreadExecutor = new MainThreadExecutor();
+ }
+ mMainThreadExecutor.execute(this);
+ }
+
+ @Override
+ public void run() {
+ RecentsActivity activity = sCurrentActivity.get();
+ if (activity != null) {
+ initIfPending(activity, activity.isStarted());
+ }
+ }
+
+ public synchronized boolean initIfPending(RecentsActivity activity, boolean alreadyOnHome) {
+ RecentsActivityTracker tracker = mPendingTracker.get();
+ if (tracker != null) {
+ if (!tracker.init(activity, alreadyOnHome)) {
+ mPendingTracker.clear();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized boolean clearReference(RecentsActivityTracker tracker) {
+ if (mPendingTracker.get() == tracker) {
+ mPendingTracker.clear();
+ return true;
+ }
+ return false;
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index d4c35e0..fb061d0 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -164,6 +164,7 @@
private float mCurrentDisplacement;
private boolean mGestureStarted;
private int mLogAction = Touch.SWIPE;
+ private float mCurrentQuickScrubProgress;
private @InteractionType int mInteractionType = INTERACTION_NORMAL;
@@ -228,11 +229,11 @@
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START,
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START,
this::onQuickScrubStart);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
| STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
| STATE_QUICK_SCRUB_END, this::switchToFinalAppAfterQuickScrub);
}
@@ -308,7 +309,6 @@
return;
}
- mStateCallback.setState(STATE_LAUNCHER_STARTED);
mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible);
AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible);
@@ -343,6 +343,7 @@
mRecentsView.showTask(mRunningTaskId);
mRecentsView.setFirstTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
mLayoutListener.open();
+ mStateCallback.setState(STATE_LAUNCHER_STARTED);
}
public void setLauncherOnDrawCallback(Runnable callback) {
@@ -684,6 +685,9 @@
private void onQuickScrubStart() {
mActivityControlHelper.onQuickInteractionStart(mActivity, mWasLauncherAlreadyVisible);
mQuickScrubController.onQuickScrubStart(false);
+
+ // Inform the last progress in case we skipped before.
+ mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
}
private void onFinishedTransitionToQuickScrub() {
@@ -691,10 +695,8 @@
}
public void onQuickScrubProgress(float progress) {
+ mCurrentQuickScrubProgress = progress;
if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null) {
- // TODO: We can still get progress events while launcher is not ready on the worker
- // thread. Keep track of last received progress and apply that progress when launcher
- // is ready
return;
}
mQuickScrubController.onQuickScrubProgress(progress);
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 4ed1656..89422af 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -41,7 +41,7 @@
@Override
protected void onAllTasksRemoved() {
- mActivity.finish();
+ mActivity.startHome();
}
@Override