Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 587c3cef authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fixing multiwindow transition when using 3P launcher

Bug: 137197916
Change-Id: I3c5cfc290972187d9d556a722afc61489d0d0629
parent 160134e0
Loading
Loading
Loading
Loading
+75 −1
Original line number Diff line number Diff line
@@ -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
     */
+8 −6
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ public final class RecentsActivity extends BaseRecentsActivity {

    @Override
    protected void onNewIntent(Intent intent) {
        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) {
@@ -94,6 +95,7 @@ public final class RecentsActivity extends BaseRecentsActivity {
                mFallbackRecentsView.showCurrentTask(taskID);
                mFallbackRecentsView.updateThumbnail(taskID, thumbnailData);
            }
        }
        intent.removeExtra(EXTRA_TASK_ID);
        intent.removeExtra(EXTRA_THUMBNAIL);
        super.onNewIntent(intent);
+2 −72
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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);