diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index fadde374ba..dc270566ef 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -31,7 +31,6 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; -import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; @@ -46,7 +45,6 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.VibratorWrapper; import com.android.launcher3.views.FloatingIconView; @@ -133,8 +131,7 @@ public abstract class BaseSwipeUpHandler activityInterface = mOverviewComponentObserver.getActivityInterface(); + final Intent overviewIntent = new Intent( + mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState()); if (activityInterface.getCreatedActivity() == null) { // Make sure that UI states will be initialized. activityInterface.createActivityInitListener((wasVisible) -> { AppLaunchTracker.INSTANCE.get(TouchInteractionService.this); return false; - }).register(); + }).register(overviewIntent); } else if (fromInit) { // The activity has been created before the initialization of overview service. It is // usually happens when booting or launcher is the top activity, so we should already @@ -752,8 +753,7 @@ public class TouchInteractionService extends Service implements PluginListener ActivityManagerWrapper.getInstance() - .startRecentsActivity(intent, null, listener, null, null)); - } - @Override public void onPluginConnected(OverscrollPlugin overscrollPlugin, Context context) { mOverscrollPlugin = overscrollPlugin; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index fe9ef2befe..1f6c506d3a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -333,7 +333,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mTaskAnimationManager.isRecentsAnimationRunning(), isLikelyToStartNewTask); mInteractionHandler.setGestureEndCallback(this::onInteractionGestureFinished); mMotionPauseDetector.setOnMotionPauseListener(mInteractionHandler::onMotionPauseChanged); - mInteractionHandler.initWhenReady(); + Intent intent = new Intent(mInteractionHandler.getLaunchIntent()); + mInteractionHandler.initWhenReady(intent); if (mTaskAnimationManager.isRecentsAnimationRunning()) { mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(mGestureState); @@ -341,7 +342,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mTaskAnimationManager.notifyRecentsAnimationState(mInteractionHandler); notifyGestureStarted(); } else { - Intent intent = mInteractionHandler.getLaunchIntent(); intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId()); mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, mInteractionHandler); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java index 0a21413fb4..c49b8f2d14 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java @@ -36,17 +36,14 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.quickstep.GestureState; import com.android.quickstep.InputConsumer; -import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; import com.android.systemui.plugins.OverscrollPlugin; import com.android.systemui.shared.system.InputMonitorCompat; /** * Input consumer for handling events to pass to an {@code OverscrollPlugin}. - * - * @param Draggable activity subclass used by RecentsView */ -public class OverscrollInputConsumer extends DelegateInputConsumer { +public class OverscrollInputConsumer extends DelegateInputConsumer { private static final String TAG = "OverscrollInputConsumer"; @@ -61,12 +58,12 @@ public class OverscrollInputConsumer extends Del private final float mSquaredSlop; - private final Context mContext; private final GestureState mGestureState; @Nullable private final OverscrollPlugin mPlugin; private final GestureDetector mGestureDetector; + @Nullable private RecentsView mRecentsView; public OverscrollInputConsumer(Context context, GestureState gestureState, @@ -77,7 +74,6 @@ public class OverscrollInputConsumer extends Del .getInteger(R.integer.assistant_gesture_corner_deg_threshold); mFlingThresholdPx = context.getResources() .getDimension(R.dimen.gestures_overscroll_fling_threshold); - mContext = context; mGestureState = gestureState; mPlugin = plugin; @@ -85,9 +81,6 @@ public class OverscrollInputConsumer extends Del mSquaredSlop = slop * slop; mGestureDetector = new GestureDetector(context, new FlingGestureListener()); - - gestureState.getActivityInterface().createActivityInitListener(this::onActivityInit) - .register(); } @Override @@ -95,12 +88,6 @@ public class OverscrollInputConsumer extends Del return TYPE_OVERSCROLL | mDelegate.getType(); } - private boolean onActivityInit(Boolean alreadyOnHome) { - mRecentsView = mGestureState.getActivityInterface().getCreatedActivity().getOverviewPanel(); - - return true; - } - @Override public void onMotionEvent(MotionEvent ev) { switch (ev.getActionMasked()) { @@ -191,10 +178,17 @@ public class OverscrollInputConsumer extends Del } private boolean isOverscrolled() { + if (mRecentsView == null) { + BaseDraggingActivity activity = mGestureState.getActivityInterface() + .getCreatedActivity(); + if (activity != null) { + mRecentsView = activity.getOverviewPanel(); + } + } + // Make sure there isn't an app to quick switch to on our right int maxIndex = 0; - if ((mRecentsView instanceof LauncherRecentsView) - && ((LauncherRecentsView) mRecentsView).hasRecentsExtraCard()) { + if (mRecentsView != null && mRecentsView.hasRecentsExtraCard()) { maxIndex = 1; } diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java index fbd7a8a4b6..7fb0d43600 100644 --- a/quickstep/src/com/android/launcher3/LauncherInitListener.java +++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java @@ -23,7 +23,6 @@ import android.os.Build; import android.os.CancellationSignal; import android.os.Handler; -import com.android.launcher3.util.ActivityTracker; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.RemoteAnimationProvider; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -45,7 +44,7 @@ public class LauncherInitListener extends ActivityInitListener { } @Override - public boolean init(Launcher launcher, boolean alreadyOnHome) { + public boolean handleInit(Launcher launcher, boolean alreadyOnHome) { if (mRemoteAnimationProvider != null) { QuickstepAppTransitionManagerImpl appTransitionManager = (QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager(); @@ -71,7 +70,7 @@ public class LauncherInitListener extends ActivityInitListener { }, cancellationSignal); } launcher.deferOverlayCallbacksUntilNextResumeOrStop(); - return super.init(launcher, alreadyOnHome); + return super.handleInit(launcher, alreadyOnHome); } @Override diff --git a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java index b1c72ce729..2a0fe32574 100644 --- a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java +++ b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java @@ -31,6 +31,8 @@ public class ActivityInitListener implements SchedulerCa private final BiPredicate mOnInitListener; private final ActivityTracker mActivityTracker; + private boolean mIsRegistered = false; + /** * @param onInitListener a callback made when the activity is initialized. The callback should * return true to continue receiving callbacks (ie. for if the activity is @@ -43,27 +45,45 @@ public class ActivityInitListener implements SchedulerCa } @Override - public boolean init(T activity, boolean alreadyOnHome) { + public final boolean init(T activity, boolean alreadyOnHome) { + if (!mIsRegistered) { + return false; + } + return handleInit(activity, alreadyOnHome); + } + + protected boolean handleInit(T activity, boolean alreadyOnHome) { return mOnInitListener.test(activity, alreadyOnHome); } /** * Registers the activity-created listener. If the activity is already created, then the * callback provided in the constructor will be called synchronously. + * @param intent The intent that will be used to initialize the activity, if the activity + * doesn't already exist. We add the callback as an extra on this intent. */ - public void register() { - mActivityTracker.schedule(this); + public void register(Intent intent) { + mIsRegistered = true; + mActivityTracker.runCallbackWhenActivityExists(this, intent); } + /** + * After calling this, we won't {@link #init} even when the activity is ready. + */ public void unregister() { - mActivityTracker.clearReference(this); + mIsRegistered = false; } + /** + * Starts the given intent with the provided animation. Unlike {@link #register(Intent)}, this + * method will not call {@link #init} if the activity already exists, it will only call it when + * we get handleIntent() for the provided intent that we're starting. + */ public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider, Context context, Handler handler, long duration) { - register(); + mIsRegistered = true; Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle(); - context.startActivity(addToIntent(new Intent((intent))), options); + context.startActivity(addToIntent(new Intent(intent)), options); } } diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java index fc29a30d74..064868208d 100644 --- a/src/com/android/launcher3/allapps/DiscoveryBounce.java +++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java @@ -172,8 +172,7 @@ public class DiscoveryBounce extends AbstractFloatingView { if (withDelay) { new Handler().postDelayed(() -> showForOverviewIfNeeded(launcher, false), DELAY_MS); return; - } else if (Launcher.ACTIVITY_TRACKER.hasPending() - || AbstractFloatingView.getTopOpenView(launcher) != null) { + } else if (AbstractFloatingView.getTopOpenView(launcher) != null) { // TODO: Move these checks to the top and call this method after invalidate handler. return; } diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 6c40b8a287..0df67133ab 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -170,16 +170,14 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener } }, null, View.DRAG_FLAG_GLOBAL); - - Intent homeIntent = listener.addToIntent( - new Intent(Intent.ACTION_MAIN) + Intent homeIntent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) .setPackage(getPackageName()) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); - - Launcher.ACTIVITY_TRACKER.schedule(listener); + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Launcher.ACTIVITY_TRACKER.runCallbackWhenActivityExists(listener, homeIntent); startActivity(homeIntent, - ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle()); + ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out) + .toBundle()); mFinishOnPause = true; return false; } diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index e47a16f722..707fd06519 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -161,7 +161,6 @@ public abstract class BaseItemDragListener implements View.OnDragListener, DragS } protected void postCleanup() { - Launcher.ACTIVITY_TRACKER.clearReference(this); if (mLauncher != null) { // Remove any drag params from the launcher intent since the drag operation is complete. Intent newIntent = new Intent(mLauncher.getIntent()); diff --git a/src/com/android/launcher3/util/ActivityTracker.java b/src/com/android/launcher3/util/ActivityTracker.java index 499f655df1..59266b4daa 100644 --- a/src/com/android/launcher3/util/ActivityTracker.java +++ b/src/com/android/launcher3/util/ActivityTracker.java @@ -15,27 +15,23 @@ */ package com.android.launcher3.util; -import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; - import android.content.Intent; import android.os.Bundle; import android.os.IBinder; -import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; -import com.android.launcher3.testing.TestProtocol; import java.lang.ref.WeakReference; /** * Helper class to statically track activity creation + * @param The activity type to track */ -public final class ActivityTracker implements Runnable { +public final class ActivityTracker { private WeakReference mCurrentActivity = new WeakReference<>(null); - private WeakReference> mPendingCallback = new WeakReference<>(null); private static final String EXTRA_SCHEDULER_CALLBACK = "launcher.scheduler_callback"; @@ -51,76 +47,32 @@ public final class ActivityTracker implements Runnable { } /** - * Schedules the callback to be notified when the activity is created. - * @return true if the activity is already created, false otherwise + * Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the activity is ready. + * If the activity is already created, this is called immediately, otherwise we add the + * callback as an extra on the intent, and will call init() when we get handleIntent(). + * @param callback The callback to call init() on when the activity is ready. + * @param intent The intent that will be used to initialize the activity, if the activity + * doesn't already exist. We add the callback as an extra on this intent. */ - public boolean schedule(SchedulerCallback callback) { - synchronized (this) { - mPendingCallback = new WeakReference<>((SchedulerCallback) callback); - } - if (!notifyInitIfPending()) { - // If the activity doesn't already exist, then post and wait for the activity to start - MAIN_EXECUTOR.execute(this); - return false; - } - return true; - } - - @Override - public void run() { - notifyInitIfPending(); - } - - /** - * Notifies the pending callback if the activity is now created. - * @return true if the activity is now created. - */ - private boolean notifyInitIfPending() { + public void runCallbackWhenActivityExists(SchedulerCallback callback, Intent intent) { T activity = mCurrentActivity.get(); if (activity != null) { - notifyInitIfPending(activity, activity.isStarted()); - return true; + callback.init(activity, activity.isStarted()); + } else { + callback.addToIntent(intent); } - return false; - } - - public boolean notifyInitIfPending(T activity, boolean alreadyOnHome) { - SchedulerCallback pendingCallback = mPendingCallback.get(); - if (pendingCallback != null) { - if (!pendingCallback.init(activity, alreadyOnHome)) { - clearReference(pendingCallback); - } - return true; - } - return false; - } - - public boolean clearReference(SchedulerCallback handler) { - synchronized (this) { - if (mPendingCallback.get() == handler) { - mPendingCallback.clear(); - return true; - } - return false; - } - } - - public boolean hasPending() { - return mPendingCallback.get() != null; } public boolean handleCreate(T activity) { mCurrentActivity = new WeakReference<>(activity); - return handleIntent(activity, activity.getIntent(), false, false); + return handleIntent(activity, activity.getIntent(), false); } public boolean handleNewIntent(T activity, Intent intent) { - return handleIntent(activity, intent, activity.isStarted(), true); + return handleIntent(activity, intent, activity.isStarted()); } - private boolean handleIntent( - T activity, Intent intent, boolean alreadyOnHome, boolean explicitIntent) { - boolean result = false; + private boolean handleIntent(T activity, Intent intent, boolean alreadyOnHome) { if (intent != null && intent.getExtras() != null) { IBinder stateBinder = intent.getExtras().getBinder(EXTRA_SCHEDULER_CALLBACK); if (stateBinder instanceof ObjectWrapper) { @@ -129,19 +81,26 @@ public final class ActivityTracker implements Runnable { if (!handler.init(activity, alreadyOnHome)) { intent.getExtras().remove(EXTRA_SCHEDULER_CALLBACK); } - result = true; + return true; } } - if (!result && !explicitIntent) { - result = notifyInitIfPending(activity, alreadyOnHome); - } - return result; + return false; } public interface SchedulerCallback { + /** + * Called when the activity is ready. + * @param alreadyOnHome Whether the activity is already started. + * @return Whether to continue receiving callbacks (i.e. if the activity is recreated). + */ boolean init(T activity, boolean alreadyOnHome); + /** + * Adds this callback as an extra on the intent, so we can retrieve it in handleIntent() and + * call {@link #init}. The intent should be used to start the activity after calling this + * method in order for us to get handleIntent(). + */ default Intent addToIntent(Intent intent) { Bundle extras = new Bundle(); extras.putBinder(EXTRA_SCHEDULER_CALLBACK, ObjectWrapper.wrap(this));