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

Commit a5e45ad4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixing jump when swiping up in landscape and in waterfall cutout" into ub-launcher3-rvc-dev

parents f13a51c4 b64fc6c2
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -121,6 +121,10 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
        });

        mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
            // Wait until the first scroll event before applying scroll to taskViewSimulator.
            // Since, by default the current/running task already centered, this ensures that we
            // do not move the running task, in case RecentsView has not yet laid out completely.
            mRecentsViewScrollLinked = true;
            if (moveWindowWithRecentsScroll()) {
                updateFinalShift();
            }
@@ -128,7 +132,6 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
        runOnRecentsAnimationStart(() ->
                mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
                        mRecentsAnimationTargets));
        mRecentsViewScrollLinked = true;
    }

    protected void startNewTask(Consumer<Boolean> resultCallback) {
@@ -205,10 +208,17 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
        mRecentsAnimationController = recentsAnimationController;
        mRecentsAnimationTargets = targets;
        mTransformParams.setTargetSet(mRecentsAnimationTargets);
        DeviceProfile dp = mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile();
        RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
                mGestureState.getRunningTaskId());

        if (runningTaskTarget != null) {
            mTaskViewSimulator.setPreview(runningTaskTarget);
        }

        // Only initialize the device profile, if it has not been initialized before, as in some
        // configurations targets.homeContentInsets may not be correct.
        if (mActivity == null) {
            DeviceProfile dp = mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile();
            if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
                Rect overviewStackBounds = mActivityInterface
                        .getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
@@ -220,11 +230,8 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
            }
            dp.updateInsets(targets.homeContentInsets);
            dp.updateIsSeascape(mContext);
        if (runningTaskTarget != null) {
            mTaskViewSimulator.setPreview(runningTaskTarget);
        }

            initTransitionEndpoints(dp);
        }

        // Notify when the animation starts
        if (!mRecentsAnimationStartCallbacks.isEmpty()) {
+1 −1
Original line number Diff line number Diff line
@@ -256,8 +256,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
        float taskHeight = mTaskRect.height();

        mMatrix.set(mPositionHelper.getMatrix());
        mMatrix.postScale(scale, scale);
        mMatrix.postTranslate(insets.left, insets.top);
        mMatrix.postScale(scale, scale);

        // Apply TaskView matrix: translate, scale, scroll
        mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
+4 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
        mDwbToastShown = false;
        mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
        LayoutUtils.setViewEnabled(mActionsView, true);
        mOrientationState.setGestureActive(false);
    }

    public @Nullable TaskView getRunningTaskView() {
@@ -1037,6 +1038,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
     */
    public void onGestureAnimationStart(int runningTaskId) {
        // This needs to be called before the other states are set since it can create the task view
        mOrientationState.setGestureActive(true);
        showCurrentTask(runningTaskId);
        setEnableFreeScroll(false);
        setEnableDrawingLiveTile(false);
@@ -1099,6 +1101,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
     * Called when a gesture from an app has finished.
     */
    public void onGestureAnimationEnd() {
        mOrientationState.setGestureActive(false);

        setOnScrollChangeListener(null);
        setEnableFreeScroll(true);
        setEnableDrawingLiveTile(true);
+203 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 static android.view.Display.DEFAULT_DISPLAY;

import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.display.DisplayManager;
import android.view.Surface;
import android.view.SurfaceControl;

import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.shadows.LShadowDisplay;
import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.LauncherActivityInterface;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.LooperMode;
import org.robolectric.annotation.LooperMode.Mode;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowDisplayManager;

@RunWith(RobolectricTestRunner.class)
@LooperMode(Mode.PAUSED)
public class TaskViewSimulatorTest {

    @Test
    public void taskProperlyScaled_portrait_noRotation_sameInsets1() {
        new TaskMatrixVerifier()
                .withLauncherSize(1200, 2450)
                .withInsets(new Rect(0, 80, 0, 120))
                .verifyNoTransforms();
    }

    @Test
    public void taskProperlyScaled_portrait_noRotation_sameInsets2() {
        new TaskMatrixVerifier()
                .withLauncherSize(1200, 2450)
                .withInsets(new Rect(55, 80, 55, 120))
                .verifyNoTransforms();
    }

    @Test
    public void taskProperlyScaled_landscape_noRotation_sameInsets1() {
        new TaskMatrixVerifier()
                .withLauncherSize(2450, 1250)
                .withInsets(new Rect(0, 80, 0, 40))
                .verifyNoTransforms();
    }

    @Test
    public void taskProperlyScaled_landscape_noRotation_sameInsets2() {
        new TaskMatrixVerifier()
                .withLauncherSize(2450, 1250)
                .withInsets(new Rect(0, 80, 120, 0))
                .verifyNoTransforms();
    }

    @Test
    public void taskProperlyScaled_landscape_noRotation_sameInsets3() {
        new TaskMatrixVerifier()
                .withLauncherSize(2450, 1250)
                .withInsets(new Rect(55, 80, 55, 120))
                .verifyNoTransforms();
    }

    @Test
    public void taskProperlyScaled_landscape_rotated() {
        new TaskMatrixVerifier()
                .withLauncherSize(1200, 2450)
                .withInsets(new Rect(0, 80, 0, 120))
                .withAppBounds(
                        new Rect(0, 0, 2450, 1200),
                        new Rect(0, 80, 0, 120),
                        Surface.ROTATION_90)
                .verifyNoTransforms();
    }

    private static class TaskMatrixVerifier extends TransformParams {

        private final Context mContext = RuntimeEnvironment.application;

        private Rect mAppBounds = new Rect();
        private Rect mLauncherInsets = new Rect();

        private Rect mAppInsets;

        private int mAppRotation = -1;
        private DeviceProfile mDeviceProfile;

        TaskMatrixVerifier withLauncherSize(int width, int height) {
            ShadowDisplayManager.changeDisplay(DEFAULT_DISPLAY,
                    String.format("w%sdp-h%sdp-mdpi", width, height));
            if (mAppBounds.isEmpty()) {
                mAppBounds.set(0, 0, width, height);
            }
            return this;
        }

        TaskMatrixVerifier withInsets(Rect insets) {
            LShadowDisplay shadowDisplay = Shadow.extract(
                    mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
            shadowDisplay.setInsets(insets);
            mLauncherInsets.set(insets);
            return this;
        }

        TaskMatrixVerifier withAppBounds(Rect bounds, Rect insets, int appRotation) {
            mAppBounds.set(bounds);
            mAppInsets = insets;
            mAppRotation = appRotation;
            return this;
        }

        void verifyNoTransforms() {
            mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(mContext)
                    .getDeviceProfile(mContext);
            mDeviceProfile.updateInsets(mLauncherInsets);

            TaskViewSimulator tvs = new TaskViewSimulator(mContext,
                    LauncherActivityInterface.INSTANCE);
            tvs.setDp(mDeviceProfile);

            int launcherRotation = DefaultDisplay.INSTANCE.get(mContext).getInfo().rotation;
            if (mAppRotation < 0) {
                mAppRotation = launcherRotation;
            }
            tvs.setLayoutRotation(launcherRotation, mAppRotation);
            if (mAppInsets == null) {
                mAppInsets = new Rect(mLauncherInsets);
            }
            tvs.setPreviewBounds(mAppBounds, mAppInsets);

            tvs.fullScreenProgress.value = 1;
            tvs.recentsViewScale.value = tvs.getFullScreenScale();
            tvs.apply(this);
        }

        @Override
        public SurfaceParams[] createSurfaceParams(BuilderProxy proxy) {
            SurfaceParams.Builder builder = new SurfaceParams.Builder((SurfaceControl) null);
            proxy.onBuildTargetParams(builder, null, this);
            return new SurfaceParams[] {builder.build()};
        }

        @Override
        public void applySurfaceParams(SurfaceParams[] params) {
            // Verify that the task position remains the same
            RectF newAppBounds = new RectF(mAppBounds);
            params[0].matrix.mapRect(newAppBounds);
            Assert.assertThat(newAppBounds, new AlmostSame(mAppBounds));

            System.err.println("Bounds mapped: " + mAppBounds + " => " + newAppBounds);
        }
    }

    private static class AlmostSame extends TypeSafeMatcher<RectF>  {

        // Allow 1px error margin to account for float to int conversions
        private final float mError = 1f;
        private final Rect mExpected;

        AlmostSame(Rect expected) {
            mExpected = expected;
        }

        @Override
        protected boolean matchesSafely(RectF item) {
            return Math.abs(item.left - mExpected.left) < mError
                    && Math.abs(item.top - mExpected.top) < mError
                    && Math.abs(item.right - mExpected.right) < mError
                    && Math.abs(item.bottom - mExpected.bottom) < mError;
        }

        @Override
        public void describeTo(Description description) {
            description.appendValue(mExpected);
        }
    }
}
+13 −1
Original line number Diff line number Diff line
@@ -105,6 +105,9 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
    private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 6;
    // Enable home rotation for UI tests, ignoring home rotation value from prefs
    private static final int FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING = 1 << 7;
    // Whether the swipe gesture is running, so the recents would stay locked in the
    // current orientation
    private static final int FLAG_SWIPE_UP_NOT_RUNNING = 1 << 8;

    private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
            FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
@@ -114,7 +117,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
    // multi-window is enabled as in that case, activity itself rotates.
    private static final int VALUE_ROTATION_WATCHER_ENABLED =
            MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE | FLAG_SYSTEM_ROTATION_ALLOWED
                    | FLAG_ROTATION_WATCHER_SUPPORTED | FLAG_ROTATION_WATCHER_ENABLED;
                    | FLAG_ROTATION_WATCHER_SUPPORTED | FLAG_ROTATION_WATCHER_ENABLED
                    | FLAG_SWIPE_UP_NOT_RUNNING;

    private final Context mContext;
    private final ContentResolver mContentResolver;
@@ -156,6 +160,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
        if (originalSmallestWidth < 600) {
            mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
        }
        mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
        initFlags();
    }

@@ -166,6 +171,13 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
        setFlag(FLAG_MULTIWINDOW_ROTATION_ALLOWED, isMultiWindow);
    }

    /**
     * Sets if the swipe up gesture is currently running or not
     */
    public void setGestureActive(boolean isGestureActive) {
        setFlag(FLAG_SWIPE_UP_NOT_RUNNING, !isGestureActive);
    }

    /**
     * Sets the appropriate {@link PagedOrientationHandler} for {@link #mOrientationHandler}
     * @param touchRotation The rotation the nav bar region that is touched is in
Loading