Fixing multiwindow transition when using 3P launcher
Bug: 137197916 Change-Id: I3c5cfc290972187d9d556a722afc61489d0d0629
This commit is contained in:
@@ -29,7 +29,9 @@ import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -37,21 +39,27 @@ import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.inputconsumers.InputConsumer;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@@ -66,6 +74,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
|
||||
implements SwipeAnimationListener {
|
||||
|
||||
private static final String TAG = "BaseSwipeUpHandler";
|
||||
protected static final Rect TEMP_RECT = new Rect();
|
||||
|
||||
// Start resisting when swiping past this factor of mTransitionDragLength.
|
||||
private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f;
|
||||
@@ -82,11 +91,13 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
|
||||
protected final OverviewComponentObserver mOverviewComponentObserver;
|
||||
protected final ActivityControlHelper<T> mActivityControlHelper;
|
||||
protected final RecentsModel mRecentsModel;
|
||||
protected final int mRunningTaskId;
|
||||
|
||||
protected final ClipAnimationHelper mClipAnimationHelper;
|
||||
protected final TransformParams mTransformParams = new TransformParams();
|
||||
|
||||
private final Vibrator mVibrator;
|
||||
protected final Mode mMode;
|
||||
|
||||
// Shift in the range of [0, 1].
|
||||
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
||||
@@ -112,19 +123,23 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
|
||||
|
||||
protected BaseSwipeUpHandler(Context context,
|
||||
OverviewComponentObserver overviewComponentObserver,
|
||||
RecentsModel recentsModel, InputConsumerController inputConsumer) {
|
||||
RecentsModel recentsModel, InputConsumerController inputConsumer, int runningTaskId) {
|
||||
mContext = context;
|
||||
mOverviewComponentObserver = overviewComponentObserver;
|
||||
mActivityControlHelper = overviewComponentObserver.getActivityControlHelper();
|
||||
mRecentsModel = recentsModel;
|
||||
mActivityInitListener =
|
||||
mActivityControlHelper.createActivityInitListener(this::onActivityInit);
|
||||
mRunningTaskId = runningTaskId;
|
||||
mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer,
|
||||
this::createNewInputProxyHandler);
|
||||
mMode = SysUINavigationMode.getMode(context);
|
||||
|
||||
mClipAnimationHelper = new ClipAnimationHelper(context);
|
||||
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
||||
mVibrator = context.getSystemService(Vibrator.class);
|
||||
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
|
||||
.getDeviceProfile(mContext));
|
||||
}
|
||||
|
||||
protected void setStateOnUiThread(int stateFlag) {
|
||||
@@ -232,6 +247,65 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
|
||||
TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
|
||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
||||
final Rect overviewStackBounds;
|
||||
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
|
||||
|
||||
if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) {
|
||||
overviewStackBounds = mActivityControlHelper
|
||||
.getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget);
|
||||
dp = dp.getMultiWindowProfile(mContext, new Point(
|
||||
overviewStackBounds.width(), overviewStackBounds.height()));
|
||||
} else {
|
||||
// If we are not in multi-window mode, home insets should be same as system insets.
|
||||
dp = dp.copy(mContext);
|
||||
overviewStackBounds = getStackBounds(dp);
|
||||
}
|
||||
dp.updateInsets(targetSet.homeContentInsets);
|
||||
dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
|
||||
if (runningTaskTarget != null) {
|
||||
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
|
||||
}
|
||||
|
||||
mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */);
|
||||
initTransitionEndpoints(dp);
|
||||
|
||||
mRecentsAnimationWrapper.setController(targetSet);
|
||||
}
|
||||
|
||||
private Rect getStackBounds(DeviceProfile dp) {
|
||||
if (mActivity != null) {
|
||||
int loc[] = new int[2];
|
||||
View rootView = mActivity.getRootView();
|
||||
rootView.getLocationOnScreen(loc);
|
||||
return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(),
|
||||
loc[1] + rootView.getHeight());
|
||||
} else {
|
||||
return new Rect(0, 0, dp.widthPx, dp.heightPx);
|
||||
}
|
||||
}
|
||||
|
||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||
mDp = dp;
|
||||
|
||||
mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
|
||||
dp, mContext, TEMP_RECT);
|
||||
if (!dp.isMultiWindowMode) {
|
||||
// When updating the target rect, also update the home bounds since the location on
|
||||
// screen of the launcher window may be stale (position is not updated until first
|
||||
// traversal after the window is resized). We only do this for non-multiwindow because
|
||||
// we otherwise use the minimized home bounds provided by the system.
|
||||
mClipAnimationHelper.updateHomeBounds(getStackBounds(dp));
|
||||
}
|
||||
mClipAnimationHelper.updateTargetRect(TEMP_RECT);
|
||||
if (mMode == Mode.NO_BUTTON) {
|
||||
// We can drag all the way to the top of the screen.
|
||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the window should be translated horizontally if the recents view scrolls
|
||||
*/
|
||||
|
||||
@@ -87,12 +87,14 @@ public final class RecentsActivity extends BaseRecentsActivity {
|
||||
|
||||
@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);
|
||||
if (intent.getExtras() != null) {
|
||||
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);
|
||||
|
||||
+2
-72
@@ -48,9 +48,7 @@ import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
@@ -59,13 +57,11 @@ import android.view.View;
|
||||
import android.view.View.OnApplyWindowInsetsListener;
|
||||
import android.view.ViewTreeObserver.OnDrawListener;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
@@ -106,8 +102,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
implements OnApplyWindowInsetsListener {
|
||||
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
|
||||
|
||||
private static final Rect TEMP_RECT = new Rect();
|
||||
|
||||
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null;
|
||||
|
||||
private static int getFlagForIndex(int index, String name) {
|
||||
@@ -220,9 +214,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
// To avoid UI jump when gesture is started, we offset the animation by the threshold.
|
||||
private float mShiftAtGestureStart = 0;
|
||||
|
||||
private final Mode mMode;
|
||||
|
||||
private final int mRunningTaskId;
|
||||
private ThumbnailData mTaskSnapshot;
|
||||
|
||||
// Used to control launcher components throughout the swipe gesture.
|
||||
@@ -248,16 +239,10 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
long touchTimeMs, OverviewComponentObserver overviewComponentObserver,
|
||||
boolean continuingLastGesture,
|
||||
InputConsumerController inputConsumer, RecentsModel recentsModel) {
|
||||
super(context, overviewComponentObserver, recentsModel, inputConsumer);
|
||||
mRunningTaskId = runningTaskInfo.id;
|
||||
super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
|
||||
mTouchTimeMs = touchTimeMs;
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
|
||||
mMode = SysUINavigationMode.getMode(context);
|
||||
initStateCallbacks();
|
||||
|
||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
||||
initTransitionEndpoints(dp);
|
||||
}
|
||||
|
||||
private void initStateCallbacks() {
|
||||
@@ -320,38 +305,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
}
|
||||
|
||||
private Rect getStackBounds(DeviceProfile dp) {
|
||||
if (mActivity != null) {
|
||||
int loc[] = new int[2];
|
||||
View rootView = mActivity.getRootView();
|
||||
rootView.getLocationOnScreen(loc);
|
||||
return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(),
|
||||
loc[1] + rootView.getHeight());
|
||||
} else {
|
||||
return new Rect(0, 0, dp.widthPx, dp.heightPx);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTransitionEndpoints(DeviceProfile dp) {
|
||||
mDp = dp;
|
||||
|
||||
Rect tempRect = new Rect();
|
||||
mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
|
||||
dp, mContext, tempRect);
|
||||
if (!dp.isMultiWindowMode) {
|
||||
// When updating the target rect, also update the home bounds since the location on
|
||||
// screen of the launcher window may be stale (position is not updated until first
|
||||
// traversal after the window is resized). We only do this for non-multiwindow because
|
||||
// we otherwise use the minimized home bounds provided by the system.
|
||||
mClipAnimationHelper.updateHomeBounds(getStackBounds(dp));
|
||||
}
|
||||
mClipAnimationHelper.updateTargetRect(tempRect);
|
||||
if (mMode == Mode.NO_BUTTON) {
|
||||
// We can drag all the way to the top of the screen.
|
||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onActivityInit(final T activity, Boolean alreadyOnHome) {
|
||||
if (mActivity == activity) {
|
||||
@@ -678,30 +631,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
|
||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
||||
final Rect overviewStackBounds;
|
||||
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
|
||||
|
||||
if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) {
|
||||
overviewStackBounds = mActivityControlHelper
|
||||
.getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget);
|
||||
dp = dp.getMultiWindowProfile(mContext, new Point(
|
||||
targetSet.minimizedHomeBounds.width(), targetSet.minimizedHomeBounds.height()));
|
||||
} else {
|
||||
// If we are not in multi-window mode, home insets should be same as system insets.
|
||||
dp = dp.copy(mContext);
|
||||
overviewStackBounds = getStackBounds(dp);
|
||||
}
|
||||
dp.updateInsets(targetSet.homeContentInsets);
|
||||
dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
|
||||
|
||||
if (runningTaskTarget != null) {
|
||||
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
|
||||
}
|
||||
mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */);
|
||||
initTransitionEndpoints(dp);
|
||||
|
||||
mRecentsAnimationWrapper.setController(targetSet);
|
||||
super.onRecentsAnimationStart(targetSet);
|
||||
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length);
|
||||
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
||||
|
||||
|
||||
+2
-33
@@ -31,11 +31,8 @@ import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
@@ -52,7 +49,6 @@ 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.InputConsumerController;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsActivity> {
|
||||
|
||||
@@ -94,10 +90,6 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
|
||||
}
|
||||
}
|
||||
|
||||
private final int mRunningTaskId;
|
||||
|
||||
private final Rect mTargetRect = new Rect();
|
||||
|
||||
private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged);
|
||||
|
||||
private boolean mIsMotionPaused = false;
|
||||
@@ -113,16 +105,13 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
|
||||
RunningTaskInfo runningTaskInfo, RecentsModel recentsModel,
|
||||
InputConsumerController inputConsumer,
|
||||
boolean isLikelyToStartNewTask, boolean continuingLastGesture) {
|
||||
super(context, overviewComponentObserver, recentsModel, inputConsumer);
|
||||
mRunningTaskId = runningTaskInfo.id;
|
||||
mDp = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context);
|
||||
super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
|
||||
mLauncherAlpha.value = 1;
|
||||
|
||||
mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
|
||||
initStateCallbacks();
|
||||
initTransitionTarget();
|
||||
}
|
||||
|
||||
private void initStateCallbacks() {
|
||||
@@ -376,33 +365,13 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
|
||||
mRecentsAnimationWrapper.setController(targetSet);
|
||||
super.onRecentsAnimationStart(targetSet);
|
||||
mRecentsAnimationWrapper.enableInputConsumer();
|
||||
Rect overviewStackBounds = new Rect(0, 0, mDp.widthPx, mDp.heightPx);
|
||||
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 */);
|
||||
initTransitionTarget();
|
||||
applyTransformUnchecked();
|
||||
|
||||
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
||||
}
|
||||
|
||||
private void initTransitionTarget() {
|
||||
mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
|
||||
mDp, mContext, mTargetRect);
|
||||
mDragLengthFactor = (float) mDp.heightPx / mTransitionDragLength;
|
||||
mClipAnimationHelper.updateTargetRect(mTargetRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled() {
|
||||
mRecentsAnimationWrapper.setController(null);
|
||||
|
||||
Reference in New Issue
Block a user