Merge "Fix bug where floating icon and workspace icon visible at the same time." into ub-launcher3-qt-r1-dev
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 900b94e..917800f 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -34,6 +34,8 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.UiThreadHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -137,6 +139,9 @@
return sConnected;
}
+ public static final LooperExecutor BACKGROUND_EXECUTOR =
+ new LooperExecutor(UiThreadHelper.getBackgroundLooper());
+
private RecentsModel mRecentsModel;
private OverviewComponentObserver mOverviewComponentObserver;
private OverviewCommandHelper mOverviewCommandHelper;
@@ -180,4 +185,8 @@
}
return mMyBinder;
}
+
+ public static boolean isInputMonitorInitialized() {
+ return true;
+ }
}
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 332e0fa..5465480 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -23,6 +23,7 @@
package="com.android.launcher3" >
<uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS" />
+ <uses-permission android:name="android.permission.VIBRATE" />
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
new file mode 100644
index 0000000..d34b604
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -0,0 +1,164 @@
+/*
+ * 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;
+
+import static android.os.VibrationEffect.EFFECT_CLICK;
+import static android.os.VibrationEffect.createPredefined;
+
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.graphics.PointF;
+import android.os.Build;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.view.MotionEvent;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Utilities;
+import com.android.launcher3.graphics.RotationMode;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.views.RecentsView;
+
+import java.util.function.Consumer;
+
+import androidx.annotation.UiThread;
+
+/**
+ * Base class for swipe up handler with some utility methods
+ */
+@TargetApi(Build.VERSION_CODES.Q)
+public abstract class BaseSwipeUpHandler implements SwipeAnimationListener {
+
+ // Start resisting when swiping past this factor of mTransitionDragLength.
+ private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f;
+ // This is how far down we can scale down, where 0f is full screen and 1f is recents.
+ private static final float DRAG_LENGTH_FACTOR_MAX_PULLBACK = 1.8f;
+ private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
+
+ // The distance needed to drag to reach the task size in recents.
+ protected int mTransitionDragLength;
+ // How much further we can drag past recents, as a factor of mTransitionDragLength.
+ protected float mDragLengthFactor = 1;
+
+ protected final Context mContext;
+
+ protected final ClipAnimationHelper mClipAnimationHelper;
+ protected final TransformParams mTransformParams = new TransformParams();
+
+ private final Vibrator mVibrator;
+
+ // Shift in the range of [0, 1].
+ // 0 => preview snapShot is completely visible, and hotseat is completely translated down
+ // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
+ // visible.
+ protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+
+ protected RecentsView mRecentsView;
+
+ protected Runnable mGestureEndCallback;
+
+ protected BaseSwipeUpHandler(Context context) {
+ mContext = context;
+ mClipAnimationHelper = new ClipAnimationHelper(context);
+
+ mVibrator = context.getSystemService(Vibrator.class);
+ }
+
+ public void performHapticFeedback() {
+ if (!mVibrator.hasVibrator()) {
+ return;
+ }
+ if (Settings.System.getInt(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
+ return;
+ }
+
+ VibrationEffect effect = createPredefined(EFFECT_CLICK);
+ if (effect == null) {
+ return;
+ }
+ BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect));
+ }
+
+ public Consumer<MotionEvent> getRecentsViewDispatcher(RotationMode rotationMode) {
+ return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null;
+ }
+
+ @UiThread
+ public void updateDisplacement(float displacement) {
+ // We are moving in the negative x/y direction
+ displacement = -displacement;
+ float shift;
+ if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) {
+ shift = mDragLengthFactor;
+ } else {
+ float translation = Math.max(displacement, 0);
+ shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
+ if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) {
+ float pullbackProgress = Utilities.getProgress(shift,
+ DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor);
+ pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress);
+ shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress
+ * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK);
+ }
+ }
+
+ mCurrentShift.updateValue(shift);
+ }
+
+ public void setGestureEndCallback(Runnable gestureEndCallback) {
+ mGestureEndCallback = gestureEndCallback;
+ }
+
+ /**
+ * Called when the value of {@link #mCurrentShift} changes
+ */
+ public abstract void updateFinalShift();
+
+
+ /**
+ * Called when motion pause is detected
+ */
+ public abstract void onMotionPauseChanged(boolean isPaused);
+
+ @UiThread
+ public void onGestureStarted() { }
+
+ @UiThread
+ public abstract void onGestureCancelled();
+
+ @UiThread
+ public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos);
+
+ public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { }
+
+ public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { }
+
+ public void initWhenReady() { }
+
+ public interface Factory {
+
+ BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask,
+ long touchTimeMs, boolean continuingLastGesture);
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index fc29a56..61767e5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -28,8 +28,10 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.app.ActivityOptions;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.view.View;
@@ -42,7 +44,9 @@
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsRootView;
import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
@@ -54,6 +58,9 @@
*/
public final class RecentsActivity extends BaseRecentsActivity {
+ public static final String EXTRA_THUMBNAIL = "thumbnailData";
+ public static final String EXTRA_TASK_ID = "taskID";
+
private Handler mUiHandler = new Handler(Looper.getMainLooper());
private RecentsRootView mRecentsRootView;
private FallbackRecentsView mFallbackRecentsView;
@@ -79,6 +86,20 @@
}
@Override
+ protected void onNewIntent(Intent intent) {
+ int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0);
+ IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL);
+ if (taskID != 0 && thumbnail instanceof ObjectWrapper) {
+ ThumbnailData thumbnailData = ((ObjectWrapper<ThumbnailData>) thumbnail).get();
+ mFallbackRecentsView.showCurrentTask(taskID);
+ mFallbackRecentsView.updateThumbnail(taskID, thumbnailData);
+ }
+ intent.removeExtra(EXTRA_TASK_ID);
+ intent.removeExtra(EXTRA_THUMBNAIL);
+ super.onNewIntent(intent);
+ }
+
+ @Override
protected void onHandleConfigChanged() {
super.onHandleConfigChanged();
mRecentsRootView.setup();
@@ -178,6 +199,12 @@
mFallbackRecentsView.resetTaskVisuals();
}
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mFallbackRecentsView.reset();
+ }
+
public void onTaskLaunched() {
mFallbackRecentsView.resetTaskVisuals();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index bf9d531..58d974a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -43,7 +43,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.RectF;
@@ -95,12 +94,12 @@
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import java.io.FileDescriptor;
@@ -124,10 +123,6 @@
public String nextArg() {
return pollFirst().toLowerCase();
}
-
- public String nextArgExact() {
- return pollFirst();
- }
}
/**
@@ -231,12 +226,17 @@
};
private static boolean sConnected = false;
+ private static boolean sInputMonitorInitialized = false;
private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
public static boolean isConnected() {
return sConnected;
}
+ public static boolean isInputMonitorInitialized() {
+ return sInputMonitorInitialized;
+ }
+
public static SwipeSharedState getSwipeSharedState() {
return sSwipeSharedState;
}
@@ -244,6 +244,11 @@
private final InputConsumer mResetGestureInputConsumer =
new ResetGestureInputConsumer(sSwipeSharedState);
+ private final BaseSwipeUpHandler.Factory mWindowTreansformFactory =
+ this::createWindowTransformSwipeHandler;
+ private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory =
+ this::createFallbackNoButtonSwipeHandler;
+
private ActivityManagerWrapper mAM;
private RecentsModel mRecentsModel;
private ISystemUiProxy mISystemUiProxy;
@@ -330,6 +335,7 @@
mInputMonitorCompat.dispose();
mInputMonitorCompat = null;
}
+ sInputMonitorInitialized = false;
}
private void initInputMonitor() {
@@ -347,6 +353,7 @@
Log.e(TAG, "Unable to create input monitor", e);
}
initTouchBounds();
+ sInputMonitorInitialized = true;
}
private int getNavbarSize(String resName) {
@@ -628,10 +635,6 @@
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
return mResetGestureInputConsumer;
- } else if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
- return new FallbackNoButtonInputConsumer(this, activityControl,
- mInputMonitorCompat, sSwipeSharedState, mSwipeTouchRegion,
- mOverviewComponentObserver, disableHorizontalSwipe(event), runningTaskInfo);
} else {
return createOtherActivityInputConsumer(event, runningTaskInfo);
}
@@ -644,17 +647,28 @@
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
}
- private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
+ private InputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
- final ActivityControlHelper activityControl =
- mOverviewComponentObserver.getActivityControlHelper();
- boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
- return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
- mOverviewComponentObserver.getOverviewIntent(), activityControl,
- shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
+ final boolean shouldDefer;
+ final BaseSwipeUpHandler.Factory factory;
+ final Intent homeIntent;
+
+ if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
+ shouldDefer = true;
+ factory = mFallbackNoButtonFactory;
+ homeIntent = mOverviewComponentObserver.getHomeIntent();
+ } else {
+ shouldDefer = mOverviewComponentObserver.getActivityControlHelper()
+ .deferStartingActivity(mActiveNavBarRegion, event);
+ factory = mWindowTreansformFactory;
+ homeIntent = mOverviewComponentObserver.getOverviewIntent();
+ }
+
+ return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent,
+ shouldDefer, mOverviewCallbacks, this::onConsumerInactive,
sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
- disableHorizontalSwipe(event));
+ disableHorizontalSwipe(event), factory);
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
@@ -714,11 +728,7 @@
}
// Pass null animation handler to indicate this start is preload.
- BackgroundExecutor.get().submit(
- () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
- mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(),
- null /* assistDataReceiver */, null /* animationHandler */,
- null /* resultCallback */, null /* resultCallbackHandler */));
+ startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), null);
}
@Override
@@ -796,4 +806,22 @@
break;
}
}
+
+ private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask,
+ long touchTimeMs, boolean continuingLastGesture) {
+ return new WindowTransformSwipeHandler(
+ runningTask, this, touchTimeMs,
+ mOverviewComponentObserver.getActivityControlHelper(),
+ continuingLastGesture, mInputConsumer, mRecentsModel);
+ }
+
+ private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask,
+ long touchTimeMs, boolean continuingLastGesture) {
+ return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask);
+ }
+
+ public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) {
+ BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
+ .startRecentsActivity(intent, null, listener, null, null));
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index f8e0c24..206173c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -43,7 +43,6 @@
import android.animation.Animator;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -59,8 +58,6 @@
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
-import android.view.HapticFeedbackConstants;
-import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.ViewTreeObserver.OnDrawListener;
@@ -68,10 +65,6 @@
import android.view.WindowManager;
import android.view.animation.Interpolator;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
@@ -81,7 +74,6 @@
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
@@ -97,13 +89,11 @@
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
import com.android.quickstep.views.LiveTileOverlay;
-import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputConsumerController;
@@ -112,12 +102,12 @@
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.WindowCallbacksCompat;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
+import androidx.annotation.NonNull;
+import androidx.annotation.UiThread;
@TargetApi(Build.VERSION_CODES.O)
-public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
- implements SwipeAnimationListener, OnApplyWindowInsetsListener {
+public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> extends BaseSwipeUpHandler
+ implements OnApplyWindowInsetsListener {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
private static final Rect TEMP_RECT = new Rect();
@@ -220,45 +210,26 @@
private static final long SHELF_ANIM_DURATION = 240;
public static final long RECENTS_ATTACH_DURATION = 300;
- // Start resisting when swiping past this factor of mTransitionDragLength.
- private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f;
- // This is how far down we can scale down, where 0f is full screen and 1f is recents.
- private static final float DRAG_LENGTH_FACTOR_MAX_PULLBACK = 1.8f;
- private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
-
/**
* Used as the page index for logging when we return to the last task at the end of the gesture.
*/
private static final int LOG_NO_OP_PAGE_INDEX = -1;
- private final ClipAnimationHelper mClipAnimationHelper;
- private final ClipAnimationHelper.TransformParams mTransformParams;
-
- private Runnable mGestureEndCallback;
private GestureEndTarget mGestureEndTarget;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
private RunningWindowAnim mRunningWindowAnim;
private boolean mIsShelfPeeking;
private DeviceProfile mDp;
- // The distance needed to drag to reach the task size in recents.
- private int mTransitionDragLength;
- // How much further we can drag past recents, as a factor of mTransitionDragLength.
- private float mDragLengthFactor = 1;
- // Shift in the range of [0, 1].
- // 0 => preview snapShot is completely visible, and hotseat is completely translated down
- // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
- // visible.
- private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
private boolean mContinuingLastGesture;
// To avoid UI jump when gesture is started, we offset the animation by the threshold.
private float mShiftAtGestureStart = 0;
private final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler();
- private final Context mContext;
private final ActivityControlHelper<T> mActivityControlHelper;
private final ActivityInitListener mActivityInitListener;
+ private final RecentsModel mRecentsModel;
private final SysUINavigationMode.Mode mMode;
@@ -271,7 +242,6 @@
private boolean mHasLauncherTransitionControllerStarted;
private T mActivity;
- private RecentsView mRecentsView;
private AnimationFactory mAnimationFactory = (t) -> { };
private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay();
@@ -293,18 +263,17 @@
public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
long touchTimeMs, ActivityControlHelper<T> controller, boolean continuingLastGesture,
- InputConsumerController inputConsumer) {
- mContext = context;
+ InputConsumerController inputConsumer, RecentsModel recentsModel) {
+ super(context);
mRunningTaskId = runningTaskInfo.id;
mTouchTimeMs = touchTimeMs;
mActivityControlHelper = controller;
+ mRecentsModel = recentsModel;
mActivityInitListener = mActivityControlHelper
.createActivityInitListener(this::onActivityInit);
mContinuingLastGesture = continuingLastGesture;
mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer,
this::createNewInputProxyHandler);
- mClipAnimationHelper = new ClipAnimationHelper(context);
- mTransformParams = new ClipAnimationHelper.TransformParams();
mMode = SysUINavigationMode.getMode(context);
initStateCallbacks();
@@ -394,19 +363,11 @@
}
}
- private long getFadeInDuration() {
- if (mCurrentShift.getCurrentAnimation() != null) {
- ObjectAnimator anim = mCurrentShift.getCurrentAnimation();
- long theirDuration = anim.getDuration() - anim.getCurrentPlayTime();
-
- // TODO: Find a better heuristic
- return Math.min(MAX_SWIPE_DURATION, Math.max(theirDuration, MIN_SWIPE_DURATION));
- } else {
- return MAX_SWIPE_DURATION;
- }
- }
-
+ @Override
public void initWhenReady() {
+ // Preload the plan
+ mRecentsModel.getTasks(null);
+
mActivityInitListener.register();
}
@@ -577,30 +538,7 @@
return TaskView.getCurveScaleForInterpolation(interpolation);
}
- public Consumer<MotionEvent> getRecentsViewDispatcher(RotationMode rotationMode) {
- return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null;
- }
-
- @UiThread
- public void updateDisplacement(float displacement) {
- // We are moving in the negative x/y direction
- displacement = -displacement;
- if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) {
- mCurrentShift.updateValue(mDragLengthFactor);
- } else {
- float translation = Math.max(displacement, 0);
- float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
- if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) {
- float pullbackProgress = Utilities.getProgress(shift,
- DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor);
- pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress);
- shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress
- * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK);
- }
- mCurrentShift.updateValue(shift);
- }
- }
-
+ @Override
public void onMotionPauseChanged(boolean isPaused) {
setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION);
}
@@ -651,6 +589,7 @@
mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
}
+ @Override
public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
mIsLikelyToStartNewTask = isLikelyToStartNewTask;
@@ -666,9 +605,8 @@
if (mIsShelfPeeking != wasShelfPeeking) {
maybeUpdateRecentsAttachedState();
}
- if (mRecentsView != null && shelfState.shouldPreformHaptic) {
- mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ if (shelfState.shouldPreformHaptic) {
+ performHapticFeedback();
}
}
@@ -698,7 +636,8 @@
}
@UiThread
- private void updateFinalShift() {
+ @Override
+ public void updateFinalShift() {
float shift = mCurrentShift.value;
SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
@@ -722,9 +661,8 @@
final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
if (passed != mPassedOverviewThreshold) {
mPassedOverviewThreshold = passed;
- if (mRecentsView != null && mMode != Mode.NO_BUTTON) {
- mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ if (mMode != Mode.NO_BUTTON) {
+ performHapticFeedback();
}
}
@@ -814,7 +752,7 @@
TOUCH_INTERACTION_LOG.addLog("cancelRecentsAnimation");
}
- @UiThread
+ @Override
public void onGestureStarted() {
notifyGestureStartedAsync();
mShiftAtGestureStart = mCurrentShift.value;
@@ -838,7 +776,7 @@
/**
* Called as a result on ACTION_CANCEL to return the UI to the start state.
*/
- @UiThread
+ @Override
public void onGestureCancelled() {
updateDisplacement(0);
setStateOnUiThread(STATE_GESTURE_COMPLETED);
@@ -851,7 +789,7 @@
* @param velocity The x and y components of the velocity when the gesture ends.
* @param downPos The x and y value of where the gesture started.
*/
- @UiThread
+ @Override
public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
float flingThreshold = mContext.getResources()
.getDimension(R.dimen.quickstep_fling_threshold_velocity);
@@ -1236,11 +1174,18 @@
return anim;
}
- /**
- * @return The GestureEndTarget if the gesture has ended, else null.
- */
- public @Nullable GestureEndTarget getGestureEndTarget() {
- return mGestureEndTarget;
+ @Override
+ public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) {
+ if (mGestureEndTarget != null) {
+ sharedState.canGestureBeContinued = mGestureEndTarget.canBeContinued;
+ sharedState.goingToLauncher = mGestureEndTarget.isLauncher;
+ }
+
+ if (sharedState.canGestureBeContinued) {
+ cancelCurrentAnimation(sharedState);
+ } else {
+ reset();
+ }
}
@UiThread
@@ -1289,7 +1234,7 @@
TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
}
- public void reset() {
+ private void reset() {
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
}
@@ -1297,7 +1242,7 @@
* Cancels any running animation so that the active target can be overriden by a new swipe
* handle (in case of quick switch).
*/
- public void cancelCurrentAnimation(SwipeSharedState sharedState) {
+ private void cancelCurrentAnimation(SwipeSharedState sharedState) {
mCanceled = true;
mCurrentShift.cancelAnimation();
if (mLauncherTransitionController != null && mLauncherTransitionController
@@ -1460,17 +1405,12 @@
reset();
}
- public void setGestureEndCallback(Runnable gestureEndCallback) {
- mGestureEndCallback = gestureEndCallback;
- }
-
- private void setTargetAlphaProvider(
- BiFunction<RemoteAnimationTargetCompat, Float, Float> provider) {
+ private void setTargetAlphaProvider(TargetAlphaProvider provider) {
mClipAnimationHelper.setTaskAlphaCallback(provider);
updateFinalShift();
}
- public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) {
+ public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, float expectedAlpha) {
if (!isNotInRecents(app)) {
return 0;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index db2af59..3d763ab 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -23,6 +23,7 @@
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
+import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
import android.content.ComponentName;
import android.content.Context;
@@ -44,8 +45,6 @@
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -209,9 +208,7 @@
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
mInputMonitorCompat.pilferPointers();
- BackgroundExecutor.get().submit(
- () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
- intent, null, newListenerSet, null, null));
+ startRecentsActivityAsync(intent, newListenerSet);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index d05ca2a..a5a8f38 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -15,305 +15,181 @@
*/
package com.android.quickstep.inputconsumers;
-import static android.view.MotionEvent.ACTION_CANCEL;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_MOVE;
-import static android.view.MotionEvent.ACTION_POINTER_DOWN;
-import static android.view.MotionEvent.ACTION_POINTER_UP;
-import static android.view.MotionEvent.ACTION_UP;
-import static android.view.MotionEvent.INVALID_POINTER_ID;
-
-import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION;
+import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
+import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
-import static com.android.quickstep.WindowTransformSwipeHandler.MIN_SWIPE_DURATION;
-import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO;
-import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME;
+import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK;
+import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
+import android.animation.AnimatorSet;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.ViewConfiguration;
+import android.os.Bundle;
import android.view.WindowManager;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.quickstep.ActivityControlHelper;
+import com.android.quickstep.AnimatedFloat;
+import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.OverviewComponentObserver;
-import com.android.quickstep.SwipeSharedState;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
-import com.android.quickstep.util.NavBarPosition;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
+import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
-import com.android.systemui.shared.system.InputMonitorCompat;
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimationListener {
+public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler {
- private static final int STATE_NOT_FINISHED = 0;
- private static final int STATE_FINISHED_TO_HOME = 1;
- private static final int STATE_FINISHED_TO_APP = 2;
+ public enum GestureEndTarget {
+ HOME(3, 100, 1),
+ RECENTS(1, 300, 0),
+ LAST_TASK(0, 150, 1);
- private static final float PROGRESS_TO_END_GESTURE = -2;
+ private final float mEndProgress;
+ private final long mDurationMultiplier;
+ private final float mLauncherAlpha;
+
+ GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) {
+ mEndProgress = endProgress;
+ mDurationMultiplier = durationMultiplier;
+ mLauncherAlpha = launcherAlpha;
+ }
+ }
private final ActivityControlHelper mActivityControlHelper;
- private final InputMonitorCompat mInputMonitor;
- private final Context mContext;
- private final NavBarPosition mNavBarPosition;
- private final SwipeSharedState mSwipeSharedState;
private final OverviewComponentObserver mOverviewComponentObserver;
private final int mRunningTaskId;
- private final ClipAnimationHelper mClipAnimationHelper;
- private final TransformParams mTransformParams = new TransformParams();
- private final float mTransitionDragLength;
private final DeviceProfile mDP;
+ private final Rect mTargetRect = new Rect();
- private final RectF mSwipeTouchRegion;
- private final boolean mDisableHorizontalSwipe;
+ private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged);
- private final PointF mDownPos = new PointF();
- private final PointF mLastPos = new PointF();
-
- private int mActivePointerId = -1;
- // Slop used to determine when we say that the gesture has started.
- private boolean mPassedPilferInputSlop;
-
- private VelocityTracker mVelocityTracker;
-
- // Distance after which we start dragging the window.
- private final float mTouchSlop;
-
- // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar.
- private float mStartDisplacement;
private SwipeAnimationTargetSet mSwipeAnimationTargetSet;
- private float mProgress;
- private int mState = STATE_NOT_FINISHED;
+ private boolean mIsMotionPaused = false;
+ private GestureEndTarget mEndTarget;
public FallbackNoButtonInputConsumer(Context context,
- ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor,
- SwipeSharedState swipeSharedState, RectF swipeTouchRegion,
OverviewComponentObserver overviewComponentObserver,
- boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) {
- mContext = context;
- mActivityControlHelper = activityControlHelper;
- mInputMonitor = inputMonitor;
+ RunningTaskInfo runningTaskInfo) {
+ super(context);
mOverviewComponentObserver = overviewComponentObserver;
+ mActivityControlHelper = overviewComponentObserver.getActivityControlHelper();
mRunningTaskId = runningTaskInfo.id;
-
- mSwipeSharedState = swipeSharedState;
- mSwipeTouchRegion = swipeTouchRegion;
- mDisableHorizontalSwipe = disableHorizontalSwipe;
-
- mNavBarPosition = new NavBarPosition(context);
- mVelocityTracker = VelocityTracker.obtain();
-
- mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO
- * ViewConfiguration.get(context).getScaledTouchSlop();
-
- mClipAnimationHelper = new ClipAnimationHelper(context);
-
mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context);
- Rect tempRect = new Rect();
- mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
- mDP, context, tempRect);
- mClipAnimationHelper.updateTargetRect(tempRect);
+ mLauncherAlpha.value = 1;
+
+ mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
+ initTransitionTarget();
+ }
+
+ private void onLauncherAlphaChanged() {
+ if (mSwipeAnimationTargetSet != null && mEndTarget == null) {
+ mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams);
+ }
}
@Override
- public int getType() {
- return TYPE_FALLBACK_NO_BUTTON;
+ public void onMotionPauseChanged(boolean isPaused) {
+ mIsMotionPaused = isPaused;
+ mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1)
+ .setDuration(150).start();
+ performHapticFeedback();
}
@Override
- public void onMotionEvent(MotionEvent ev) {
- if (mVelocityTracker == null) {
- return;
- }
-
- mVelocityTracker.addMovement(ev);
- if (ev.getActionMasked() == ACTION_POINTER_UP) {
- mVelocityTracker.clear();
- }
-
- switch (ev.getActionMasked()) {
- case ACTION_DOWN: {
- mActivePointerId = ev.getPointerId(0);
- mDownPos.set(ev.getX(), ev.getY());
- mLastPos.set(mDownPos);
- break;
- }
- case ACTION_POINTER_DOWN: {
- if (!mPassedPilferInputSlop) {
- // Cancel interaction in case of multi-touch interaction
- int ptrIdx = ev.getActionIndex();
- if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
- forceCancelGesture(ev);
- }
- }
- break;
- }
- case ACTION_POINTER_UP: {
- int ptrIdx = ev.getActionIndex();
- int ptrId = ev.getPointerId(ptrIdx);
- if (ptrId == mActivePointerId) {
- final int newPointerIdx = ptrIdx == 0 ? 1 : 0;
- mDownPos.set(
- ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x),
- ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y));
- mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx));
- mActivePointerId = ev.getPointerId(newPointerIdx);
- }
- break;
- }
- case ACTION_MOVE: {
- int pointerIndex = ev.findPointerIndex(mActivePointerId);
- if (pointerIndex == INVALID_POINTER_ID) {
- break;
- }
- mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
- float displacement = getDisplacement(ev);
-
- if (!mPassedPilferInputSlop) {
- if (mDisableHorizontalSwipe && Math.abs(mLastPos.x - mDownPos.x)
- > Math.abs(mLastPos.y - mDownPos.y)) {
- // Horizontal gesture is not allowed in this region
- forceCancelGesture(ev);
- break;
- }
-
- if (Math.abs(displacement) >= mTouchSlop) {
- mPassedPilferInputSlop = true;
-
- // Deferred gesture, start the animation and gesture tracking once
- // we pass the actual touch slop
- startTouchTrackingForWindowAnimation(displacement);
- }
- } else {
- updateDisplacement(displacement - mStartDisplacement);
- }
- break;
- }
- case ACTION_CANCEL:
- case ACTION_UP: {
- finishTouchTracking(ev);
- break;
- }
- }
- }
-
- private void startTouchTrackingForWindowAnimation(float displacement) {
- mStartDisplacement = Math.min(displacement, -mTouchSlop);
-
- RecentsAnimationListenerSet listenerSet =
- mSwipeSharedState.newRecentsAnimationListenerSet();
- listenerSet.addListener(this);
- Intent homeIntent = mOverviewComponentObserver.getHomeIntent();
- BackgroundExecutor.get().submit(
- () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
- homeIntent, null, listenerSet, null, null));
-
- ActivityManagerWrapper.getInstance().closeSystemWindows(
- CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- mInputMonitor.pilferPointers();
- }
-
- private void updateDisplacement(float displacement) {
- mProgress = displacement / mTransitionDragLength;
- mTransformParams.setProgress(mProgress);
-
+ public void updateFinalShift() {
+ mTransformParams.setProgress(mCurrentShift.value);
if (mSwipeAnimationTargetSet != null) {
mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams);
}
}
- private void forceCancelGesture(MotionEvent ev) {
- int action = ev.getAction();
- ev.setAction(ACTION_CANCEL);
- finishTouchTracking(ev);
- ev.setAction(action);
+ @Override
+ public void onGestureCancelled() {
+ updateDisplacement(0);
+ mEndTarget = LAST_TASK;
+ finishAnimationTargetSetAnimationComplete();
}
- /**
- * Called when the gesture has ended. Does not correlate to the completion of the interaction as
- * the animation can still be running.
- */
- private void finishTouchTracking(MotionEvent ev) {
- if (ev.getAction() == ACTION_CANCEL) {
- mState = STATE_FINISHED_TO_APP;
+ @Override
+ public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
+ float flingThreshold = mContext.getResources()
+ .getDimension(R.dimen.quickstep_fling_threshold_velocity);
+ boolean isFling = Math.abs(endVelocity) > flingThreshold;
+
+ if (isFling) {
+ mEndTarget = endVelocity < 0 ? HOME : LAST_TASK;
+ } else if (mIsMotionPaused) {
+ mEndTarget = RECENTS;
} else {
- mVelocityTracker.computeCurrentVelocity(1000,
- ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity());
- float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
- float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
- float velocity = mNavBarPosition.isRightEdge() ? velocityX
- : mNavBarPosition.isLeftEdge() ? -velocityX
- : velocityY;
- float flingThreshold = mContext.getResources()
- .getDimension(R.dimen.quickstep_fling_threshold_velocity);
- boolean isFling = Math.abs(velocity) > flingThreshold;
-
- boolean goingHome;
- if (!isFling) {
- goingHome = -mProgress >= MIN_PROGRESS_FOR_OVERVIEW;
- } else {
- goingHome = velocity < 0;
- }
-
- if (goingHome) {
- mState = STATE_FINISHED_TO_HOME;
- } else {
- mState = STATE_FINISHED_TO_APP;
- }
+ mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK;
}
-
if (mSwipeAnimationTargetSet != null) {
finishAnimationTargetSet();
}
}
- private void finishAnimationTargetSet() {
- if (mState == STATE_FINISHED_TO_APP) {
- mSwipeAnimationTargetSet.finishController(false, null, false);
- } else {
- if (mProgress < PROGRESS_TO_END_GESTURE) {
+ private void finishAnimationTargetSetAnimationComplete() {
+ switch (mEndTarget) {
+ case HOME:
mSwipeAnimationTargetSet.finishController(true, null, true);
- } else {
- long duration = (long) (Math.min(mProgress - PROGRESS_TO_END_GESTURE, 1)
- * MAX_SWIPE_DURATION / Math.abs(PROGRESS_TO_END_GESTURE));
- if (duration < 0) {
- duration = MIN_SWIPE_DURATION;
- }
+ break;
+ case LAST_TASK:
+ mSwipeAnimationTargetSet.finishController(false, null, false);
+ break;
+ case RECENTS: {
+ ThumbnailData thumbnail =
+ mSwipeAnimationTargetSet.controller.screenshotTask(mRunningTaskId);
+ mSwipeAnimationTargetSet.controller.setCancelWithDeferredScreenshot(true);
- ValueAnimator anim = ValueAnimator.ofFloat(mProgress, PROGRESS_TO_END_GESTURE);
- anim.addUpdateListener(a -> {
- float p = (Float) anim.getAnimatedValue();
- mTransformParams.setProgress(p);
- mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams);
- });
- anim.setDuration(duration);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mSwipeAnimationTargetSet.finishController(true, null, true);
- }
- });
- anim.start();
+ ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
+ Bundle extras = new Bundle();
+ extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail));
+ extras.putInt(EXTRA_TASK_ID, mRunningTaskId);
+
+ Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent())
+ .putExtras(extras);
+ mContext.startActivity(intent, options.toBundle());
+ mSwipeAnimationTargetSet.controller.cleanupScreenshot();
+ break;
}
}
+ if (mGestureEndCallback != null) {
+ mGestureEndCallback.run();
+ }
+ }
+
+ private void finishAnimationTargetSet() {
+ float endProgress = mEndTarget.mEndProgress;
+
+ if (mCurrentShift.value != endProgress) {
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(mLauncherAlpha.animateToValue(
+ mLauncherAlpha.value, mEndTarget.mLauncherAlpha));
+ anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
+
+ anim.setDuration((long) (mEndTarget.mDurationMultiplier *
+ Math.abs(endProgress - mCurrentShift.value)));
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishAnimationTargetSetAnimationComplete();
+ }
+ });
+ anim.start();
+ } else {
+ finishAnimationTargetSetAnimationComplete();
+ }
}
@Override
@@ -323,36 +199,29 @@
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
mDP.updateIsSeascape(mContext.getSystemService(WindowManager.class));
+ if (targetSet.homeContentInsets != null) {
+ mDP.updateInsets(targetSet.homeContentInsets);
+ }
+
if (runningTaskTarget != null) {
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
}
mClipAnimationHelper.prepareAnimation(mDP, false /* isOpening */);
-
- overviewStackBounds
- .inset(-overviewStackBounds.width() / 5, -overviewStackBounds.height() / 5);
- mClipAnimationHelper.updateTargetRect(overviewStackBounds);
+ initTransitionTarget();
mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams);
- if (mState != STATE_NOT_FINISHED) {
+ if (mEndTarget != null) {
finishAnimationTargetSet();
}
}
+ private void initTransitionTarget() {
+ mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
+ mDP, mContext, mTargetRect);
+ mDragLengthFactor = (float) mDP.heightPx / mTransitionDragLength;
+ mClipAnimationHelper.updateTargetRect(mTargetRect);
+ }
+
@Override
public void onRecentsAnimationCanceled() { }
-
- private float getDisplacement(MotionEvent ev) {
- if (mNavBarPosition.isRightEdge()) {
- return ev.getX() - mDownPos.x;
- } else if (mNavBarPosition.isLeftEdge()) {
- return mDownPos.x - ev.getX();
- } else {
- return ev.getY() - mDownPos.y;
- }
- }
-
- @Override
- public boolean allowInterceptByParent() {
- return !mPassedPilferInputSlop;
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
index f5cf654..a1e5d47 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
@@ -33,7 +33,6 @@
int TYPE_SCREEN_PINNED = 1 << 6;
int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
int TYPE_RESET_GESTURE = 1 << 8;
- int TYPE_FALLBACK_NO_BUTTON = 1 << 9;
String[] NAMES = new String[] {
"TYPE_NO_OP", // 0
@@ -45,7 +44,6 @@
"TYPE_SCREEN_PINNED", // 6
"TYPE_OVERVIEW_WITHOUT_FOCUS", // 7
"TYPE_RESET_GESTURE", // 8
- "TYPE_FALLBACK_NO_BUTTON", // 9
};
InputConsumer NO_OP = () -> TYPE_NO_OP;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 4c137d3..9114995 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -28,6 +28,7 @@
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
+import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import android.annotation.TargetApi;
@@ -48,21 +49,16 @@
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RaceConditionTracker;
import com.android.launcher3.util.TraceHelper;
-import com.android.quickstep.ActivityControlHelper;
+import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.OverviewCallbacks;
-import com.android.quickstep.RecentsModel;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
-import com.android.quickstep.WindowTransformSwipeHandler;
-import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
-import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
import java.util.function.Consumer;
@@ -83,16 +79,15 @@
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final RunningTaskInfo mRunningTask;
- private final RecentsModel mRecentsModel;
private final Intent mHomeIntent;
- private final ActivityControlHelper mActivityControlHelper;
private final OverviewCallbacks mOverviewCallbacks;
- private final InputConsumerController mInputConsumer;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
private final SysUINavigationMode.Mode mMode;
private final RectF mSwipeTouchRegion;
+ private final BaseSwipeUpHandler.Factory mHandlerFactory;
+
private final NavBarPosition mNavBarPosition;
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
@@ -100,7 +95,7 @@
private final float mMotionPauseMinDisplacement;
private VelocityTracker mVelocityTracker;
- private WindowTransformSwipeHandler mInteractionHandler;
+ private BaseSwipeUpHandler mInteractionHandler;
private final boolean mIsDeferredDownTarget;
private final PointF mDownPos = new PointF();
@@ -114,7 +109,7 @@
private final boolean mDisableHorizontalSwipe;
// Slop used to check when we start moving window.
- private boolean mPaddedWindowMoveSlop;
+ private boolean mPassedWindowMoveSlop;
// Slop used to determine when we say that the gesture has started.
private boolean mPassedPilferInputSlop;
@@ -122,26 +117,24 @@
private float mStartDisplacement;
private Handler mMainThreadHandler;
- private Runnable mCancelRecentsAnimationRunnable = () -> {
+ private Runnable mCancelRecentsAnimationRunnable = () ->
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
true /* restoreHomeStackPosition */);
- };
public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
- RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
- boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
- InputConsumerController inputConsumer,
+ Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
- RectF swipeTouchRegion, boolean disableHorizontalSwipe) {
+ RectF swipeTouchRegion, boolean disableHorizontalSwipe,
+ BaseSwipeUpHandler.Factory handlerFactory) {
super(base);
mMainThreadHandler = new Handler(Looper.getMainLooper());
mRunningTask = runningTaskInfo;
- mRecentsModel = recentsModel;
mHomeIntent = homeIntent;
mMode = SysUINavigationMode.getMode(base);
mSwipeTouchRegion = swipeTouchRegion;
+ mHandlerFactory = handlerFactory;
mMotionPauseDetector = new MotionPauseDetector(base);
mMotionPauseMinDisplacement = base.getResources().getDimension(
@@ -150,11 +143,9 @@
mVelocityTracker = VelocityTracker.obtain();
mInputMonitorCompat = inputMonitorCompat;
- mActivityControlHelper = activityControl;
boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null;
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
mOverviewCallbacks = overviewCallbacks;
- mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
mNavBarPosition = new NavBarPosition(base);
@@ -163,7 +154,7 @@
float slop = QUICKSTEP_TOUCH_SLOP_RATIO * mTouchSlop;
mSquaredTouchSlop = slop * slop;
- mPassedPilferInputSlop = mPaddedWindowMoveSlop = continuingPreviousGesture;
+ mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
}
@@ -186,7 +177,7 @@
}
// Proxy events to recents view
- if (mPaddedWindowMoveSlop && mInteractionHandler != null
+ if (mPassedWindowMoveSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
mNavBarPosition.getRotationMode()));
@@ -251,12 +242,12 @@
float displacement = getDisplacement(ev);
float displacementX = mLastPos.x - mDownPos.x;
- if (!mPaddedWindowMoveSlop) {
+ if (!mPassedWindowMoveSlop) {
if (!mIsDeferredDownTarget) {
// Normal gesture, ensure we pass the drag slop before we start tracking
// the gesture
if (Math.abs(displacement) > mTouchSlop) {
- mPaddedWindowMoveSlop = true;
+ mPassedWindowMoveSlop = true;
mStartDisplacement = Math.min(displacement, -mTouchSlop);
}
}
@@ -279,8 +270,8 @@
// we pass the actual touch slop
startTouchTrackingForWindowAnimation(ev.getEventTime());
}
- if (!mPaddedWindowMoveSlop) {
- mPaddedWindowMoveSlop = true;
+ if (!mPassedWindowMoveSlop) {
+ mPassedWindowMoveSlop = true;
mStartDisplacement = Math.min(displacement, -mTouchSlop);
}
@@ -289,7 +280,7 @@
}
if (mInteractionHandler != null) {
- if (mPaddedWindowMoveSlop) {
+ if (mPassedWindowMoveSlop) {
// Move
mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
}
@@ -333,12 +324,9 @@
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
- final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
- mRunningTask, this, touchTimeMs, mActivityControlHelper,
- listenerSet != null, mInputConsumer);
+ final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs,
+ listenerSet != null);
- // Preload the plan
- mRecentsModel.getTasks(null);
mInteractionHandler = handler;
handler.setGestureEndCallback(this::onInteractionGestureFinished);
mMotionPauseDetector.setOnMotionPauseListener(handler::onMotionPauseChanged);
@@ -352,9 +340,7 @@
RecentsAnimationListenerSet newListenerSet =
mSwipeSharedState.newRecentsAnimationListenerSet();
newListenerSet.addListener(handler);
- BackgroundExecutor.get().submit(
- () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
- mHomeIntent, null, newListenerSet, null, null));
+ startRecentsActivityAsync(mHomeIntent, newListenerSet);
}
}
@@ -366,7 +352,7 @@
RaceConditionTracker.onEvent(UP_EVT, ENTER);
TraceHelper.endSection("TouchInt");
- if (mPaddedWindowMoveSlop && mInteractionHandler != null) {
+ if (mPassedWindowMoveSlop && mInteractionHandler != null) {
if (ev.getActionMasked() == ACTION_CANCEL) {
mInteractionHandler.onGestureCancelled();
} else {
@@ -409,14 +395,7 @@
// The consumer is being switched while we are active. Set up the shared state to be
// used by the next animation
removeListener();
- GestureEndTarget endTarget = mInteractionHandler.getGestureEndTarget();
- mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued;
- mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher;
- if (mSwipeSharedState.canGestureBeContinued) {
- mInteractionHandler.cancelCurrentAnimation(mSwipeSharedState);
- } else {
- mInteractionHandler.reset();
- }
+ mInteractionHandler.onConsumerAboutToBeSwitched(mSwipeSharedState);
}
}
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 de671e0..f0a2903 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -99,8 +99,8 @@
// Whether to boost the opening animation target layers, or the closing
private int mBoostModeTargetLayers = -1;
- private BiFunction<RemoteAnimationTargetCompat, Float, Float> mTaskAlphaCallback =
- (t, a1) -> a1;
+ private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
+ private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1;
public ClipAnimationHelper(Context context) {
mWindowCornerRadius = getWindowCornerRadius(context.getResources());
@@ -187,12 +187,12 @@
Rect crop = mTmpRect;
crop.set(app.sourceContainerBounds);
crop.offsetTo(0, 0);
- float alpha = 1f;
+ float alpha;
int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
float cornerRadius = 0f;
float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width();
if (app.mode == targetSet.targetMode) {
- alpha = mTaskAlphaCallback.apply(app, params.targetAlpha);
+ alpha = mTaskAlphaCallback.getAlpha(app, params.targetAlpha);
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL);
mTmpMatrix.postTranslate(app.position.x, app.position.y);
@@ -214,9 +214,12 @@
// home target.
alpha = 1 - (progress * params.targetAlpha);
}
- } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) {
- crop = null;
- layer = Integer.MAX_VALUE;
+ } else {
+ alpha = mBaseAlphaCallback.getAlpha(app, progress);
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) {
+ crop = null;
+ layer = Integer.MAX_VALUE;
+ }
}
// Since radius is in Surface space, but we draw the rounded corners in screen space, we
@@ -247,11 +250,14 @@
}
}
- public void setTaskAlphaCallback(
- BiFunction<RemoteAnimationTargetCompat, Float, Float> callback) {
+ public void setTaskAlphaCallback(TargetAlphaProvider callback) {
mTaskAlphaCallback = callback;
}
+ public void setBaseAlphaCallback(TargetAlphaProvider callback) {
+ mBaseAlphaCallback = callback;
+ }
+
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) {
fromTaskThumbnailView(ttv, rv, null);
}
@@ -357,6 +363,10 @@
return mCurrentCornerRadius;
}
+ public interface TargetAlphaProvider {
+ float getAlpha(RemoteAnimationTargetCompat target, float expectedAlpha);
+ }
+
public static class TransformParams {
float progress;
public float offsetX;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java
new file mode 100644
index 0000000..abfe3ad
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.os.Binder;
+import android.os.IBinder;
+
+/**
+ * Utility class to pass non-parcealable objects within same process using parcealable payload.
+ *
+ * It wraps the object in a binder as binders are singleton within a process
+ */
+public class ObjectWrapper<T> extends Binder {
+
+ private final T mObject;
+
+ public ObjectWrapper(T object) {
+ mObject = object;
+ }
+
+ public T get() {
+ return mObject;
+ }
+
+ public static IBinder wrap(Object obj) {
+ return new ObjectWrapper<>(obj);
+ }
+}
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 6a9abd5..432f8a1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -37,6 +37,7 @@
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -108,7 +109,6 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.LauncherEventUtil;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
@@ -226,7 +226,7 @@
return;
}
- BackgroundExecutor.get().submit(() -> {
+ BACKGROUND_EXECUTOR.execute(() -> {
TaskView taskView = getTaskView(taskId);
if (taskView == null) {
return;
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 8951363..b59e133 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -10,7 +10,8 @@
public class QuickstepTestInformationHandler extends TestInformationHandler {
- public QuickstepTestInformationHandler(Context context) { }
+ public QuickstepTestInformationHandler(Context context) {
+ }
@Override
public Bundle call(String method) {
@@ -29,6 +30,12 @@
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
return response;
}
+
+ case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: {
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ TouchInteractionService.isInputMonitorInitialized());
+ break;
+ }
}
return super.call(method);
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index f27ba85..7a1d0e8 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
+import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
+
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
@@ -25,7 +27,6 @@
import com.android.launcher3.MainThreadExecutor;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.systemui.shared.system.RecentTaskInfoCompat;
import com.android.systemui.shared.system.TaskDescriptionCompat;
@@ -43,7 +44,6 @@
private final KeyguardManagerCompat mKeyguardManager;
private final MainThreadExecutor mMainThreadExecutor;
- private final BackgroundExecutor mBgThreadExecutor;
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -56,7 +56,6 @@
public RecentTasksList(Context context) {
mMainThreadExecutor = new MainThreadExecutor();
- mBgThreadExecutor = BackgroundExecutor.get();
mKeyguardManager = new KeyguardManagerCompat(context);
mChangeId = 1;
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
@@ -67,7 +66,7 @@
*/
public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
// Kick off task loading in the background
- mBgThreadExecutor.submit(() -> {
+ BACKGROUND_EXECUTOR.execute(() -> {
ArrayList<Task> tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */);
mMainThreadExecutor.execute(() -> callback.accept(tasks));
});
@@ -93,7 +92,7 @@
}
// Kick off task loading in the background
- mBgThreadExecutor.submit(() -> {
+ BACKGROUND_EXECUTOR.execute(() -> {
ArrayList<Task> tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly);
mMainThreadExecutor.execute(() -> {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d9af4da..bc3aa7e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -952,10 +952,14 @@
mHandler.removeCallbacks(mHandleDeferredResume);
Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
- for (OnResumeCallback cb : mOnResumeCallbacks) {
- cb.onLauncherResume();
+ if (!mOnResumeCallbacks.isEmpty()) {
+ final ArrayList<OnResumeCallback> resumeCallbacks = new ArrayList<>(mOnResumeCallbacks);
+ mOnResumeCallbacks.clear();
+ for (int i = resumeCallbacks.size() - 1; i >= 0; i--) {
+ resumeCallbacks.get(i).onLauncherResume();
+ }
+ resumeCallbacks.clear();
}
- mOnResumeCallbacks.clear();
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onResume();
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index d2e1961..bab454f 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -74,6 +74,11 @@
break;
}
+ case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: {
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, true);
+ break;
+ }
+
case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING:
TestProtocol.sDebugTracing = true;
break;
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 3774042..3a07be0 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -66,6 +66,7 @@
"all-apps-to-overview-swipe-height";
public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT =
"home-to-all-apps-swipe-height";
+ public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized";
public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list";
public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list";
public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 11b0665..2b0a794 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -444,6 +444,8 @@
}
private UiObject2 verifyContainerType(ContainerType containerType) {
+ waitForTouchInteractionService();
+
assertEquals("Unexpected display rotation",
mExpectedRotation, mDevice.getDisplayRotation());
@@ -514,6 +516,18 @@
}
}
+ private void waitForTouchInteractionService() {
+ for (int i = 0; i < 100; ++i) {
+ if (getTestInfo(
+ TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED).
+ getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD)) {
+ return;
+ }
+ SystemClock.sleep(100);
+ }
+ fail("TouchInteractionService didn't connect");
+ }
+
Parcelable executeAndWaitForEvent(Runnable command,
UiAutomation.AccessibilityEventFilter eventFilter, String message) {
try {