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

Commit 509563f2 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Get PiP bounds from layout dimensions if applicable" into rvc-dev am: ca111769

Change-Id: I4347cecc59006929296504bd920f815e7b8168ef
parents a6bc2f04 ca111769
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Parcel;
import android.os.RemoteException;
@@ -161,6 +162,13 @@ public class TaskInfo {
     */
    public @WindowConfiguration.ActivityType int topActivityType;

    /**
     * The {@link ActivityInfo} of the top activity in this task.
     * @hide
     */
    @Nullable
    public ActivityInfo topActivityInfo;

    TaskInfo() {
        // Do nothing
    }
@@ -219,6 +227,9 @@ public class TaskInfo {
        pictureInPictureParams = source.readInt() != 0
                ? PictureInPictureParams.CREATOR.createFromParcel(source)
                : null;
        topActivityInfo = source.readInt() != 0
                ? ActivityInfo.CREATOR.createFromParcel(source)
                : null;
    }

    /**
@@ -262,6 +273,12 @@ public class TaskInfo {
            dest.writeInt(1);
            pictureInPictureParams.writeToParcel(dest, flags);
        }
        if (topActivityInfo == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            topActivityInfo.writeToParcel(dest, flags);
        }
    }

    @Override
@@ -278,6 +295,7 @@ public class TaskInfo {
                + " resizeMode=" + resizeMode
                + " token=" + token
                + " topActivityType=" + topActivityType
                + " pictureInPictureParams=" + pictureInPictureParams;
                + " pictureInPictureParams=" + pictureInPictureParams
                + " topActivityInfo=" + topActivityInfo;
    }
}
+34 −3
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public class PipBoundsHandler {

    private ComponentName mLastPipComponentName;
    private float mReentrySnapFraction = INVALID_SNAP_FRACTION;
    private Size mReentrySize = null;
    private Size mReentrySize;

    private float mDefaultAspectRatio;
    private float mMinAspectRatio;
@@ -77,6 +77,7 @@ public class PipBoundsHandler {
    private int mDefaultMinSize;
    private Point mScreenEdgeInsets;
    private int mCurrentMinSize;
    private Size mOverrideMinimalSize;

    private boolean mIsImeShowing;
    private int mImeHeight;
@@ -226,11 +227,14 @@ public class PipBoundsHandler {
    /**
     * @return {@link Rect} of the destination PiP window bounds.
     */
    Rect getDestinationBounds(float aspectRatio, Rect bounds) {
    Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) {
        final Rect destinationBounds;
        final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
        if (bounds == null) {
            destinationBounds = new Rect(defaultBounds);
            if (mReentrySnapFraction == INVALID_SNAP_FRACTION && mReentrySize == null) {
                mOverrideMinimalSize = minimalSize;
            }
        } else {
            destinationBounds = new Rect(bounds);
        }
@@ -335,7 +339,6 @@ public class PipBoundsHandler {
     */
    private void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
            boolean useCurrentMinEdgeSize) {

        // Save the snap fraction and adjust the size based on the new aspect ratio.
        final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
                getMovementBounds(stackBounds));
@@ -354,9 +357,37 @@ public class PipBoundsHandler {
        final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
        final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
        stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
        // apply the override minimal size if applicable, this minimal size is specified by app
        if (mOverrideMinimalSize != null) {
            transformBoundsToMinimalSize(stackBounds, aspectRatio, mOverrideMinimalSize);
        }
        mSnapAlgorithm.applySnapFraction(stackBounds, getMovementBounds(stackBounds), snapFraction);
    }

    /**
     * Transforms a given bounds to meet the minimal size constraints.
     * This function assumes the given {@param stackBounds} qualifies {@param aspectRatio}.
     */
    private void transformBoundsToMinimalSize(Rect stackBounds, float aspectRatio,
            Size minimalSize) {
        if (minimalSize == null) return;
        final Size adjustedMinimalSize;
        final float minimalSizeAspectRatio =
                minimalSize.getWidth() / (float) minimalSize.getHeight();
        if (minimalSizeAspectRatio > aspectRatio) {
            // minimal size is wider, fixed the width and increase the height
            adjustedMinimalSize = new Size(
                    minimalSize.getWidth(), (int) (minimalSize.getWidth() / aspectRatio));
        } else {
            adjustedMinimalSize = new Size(
                    (int) (minimalSize.getHeight() * aspectRatio), minimalSize.getHeight());
        }
        final Rect containerBounds = new Rect(stackBounds);
        Gravity.apply(mDefaultStackGravity,
                adjustedMinimalSize.getWidth(), adjustedMinimalSize.getHeight(),
                containerBounds, stackBounds);
    }

    /**
     * @return the default bounds to show the PIP, if a {@param snapFraction} and {@param size} are
     * provided, then it will apply the default bounds to the provided snap fraction and size.
+14 −17
Original line number Diff line number Diff line
@@ -30,11 +30,13 @@ import android.app.ActivityTaskManager;
import android.app.ITaskOrganizerController;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
import android.view.ITaskOrganizer;
import android.view.IWindowContainer;
import android.view.SurfaceControl;
@@ -204,26 +206,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mOneShotAnimationType = animationType;
    }

    /**
     * Callback to issue the final {@link WindowContainerTransaction} on end of movements.
     * @param destinationBounds the final bounds.
     */
    public void onMotionMovementEnd(Rect destinationBounds) {
        try {
            mLastReportedBounds.set(destinationBounds);
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            wct.setBounds(mToken, destinationBounds);
            mTaskOrganizerController.applyContainerTransaction(wct, null /* ITaskOrganizer */);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to apply window container transaction", e);
        }
    }

    @Override
    public void taskAppeared(ActivityManager.RunningTaskInfo info) {
        Objects.requireNonNull(info, "Requires RunningTaskInfo");
        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                getAspectRatioOrDefault(info.pictureInPictureParams), null /* bounds */);
                getAspectRatioOrDefault(info.pictureInPictureParams),
                null /* bounds */, getMinimalSize(info.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        mTaskInfo = info;
        mToken = mTaskInfo.token;
@@ -276,7 +264,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            return;
        }
        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                getAspectRatioOrDefault(newParams), null /* bounds */);
                getAspectRatioOrDefault(newParams),
                null /* bounds */, getMinimalSize(info.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null);
    }
@@ -446,6 +435,14 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
                .start());
    }

    private Size getMinimalSize(ActivityInfo activityInfo) {
        if (activityInfo == null || activityInfo.windowLayout == null) {
            return null;
        }
        final ActivityInfo.WindowLayout windowLayout = activityInfo.windowLayout;
        return new Size(windowLayout.minWidth, windowLayout.minHeight);
    }

    private float getAspectRatioOrDefault(@Nullable PictureInPictureParams params) {
        return params == null
                ? mPipBoundsHandler.getDefaultAspectRatio()
+1 −1
Original line number Diff line number Diff line
@@ -426,7 +426,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cancelAnimations();

        mAnimatedBoundsPhysicsAnimator
                .withEndActions(() ->  mPipTaskOrganizer.onMotionMovementEnd(mAnimatedBounds))
                .withEndActions(() ->  mPipTaskOrganizer.scheduleFinishResizePip(mAnimatedBounds))
                .addUpdateListener(mResizePipUpdateListener)
                .start();
    }
+59 −13
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.util.Size;
import android.view.DisplayInfo;
import android.view.Gravity;

@@ -51,6 +52,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
    private static final float MIN_ASPECT_RATIO = 0.5f;
    private static final float MAX_ASPECT_RATIO = 2f;
    private static final Rect EMPTY_CURRENT_BOUNDS = null;
    private static final Size EMPTY_MINIMAL_SIZE = null;

    private PipBoundsHandler mPipBoundsHandler;
    private DisplayInfo mDefaultDisplayInfo;
@@ -119,7 +121,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
        };
        for (float aspectRatio : aspectRatios) {
            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                    aspectRatio, EMPTY_CURRENT_BOUNDS);
                    aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
            final float actualAspectRatio =
                    destinationBounds.width() / (destinationBounds.height() * 1f);
            assertEquals("Destination bounds matches the given aspect ratio",
@@ -135,7 +137,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
        };
        for (float aspectRatio : invalidAspectRatios) {
            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                    aspectRatio, EMPTY_CURRENT_BOUNDS);
                    aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
            final float actualAspectRatio =
                    destinationBounds.width() / (destinationBounds.height() * 1f);
            assertEquals("Destination bounds fallbacks to default aspect ratio",
@@ -151,7 +153,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
        currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;

        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                aspectRatio, currentBounds);
                aspectRatio, currentBounds, EMPTY_MINIMAL_SIZE);

        final float actualAspectRatio =
                destinationBounds.width() / (destinationBounds.height() * 1f);
@@ -159,15 +161,59 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
                aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
    }

    @Test
    public void getDestinationBounds_withMinSize_returnMinBounds() {
        final float[] aspectRatios = new float[] {
                (MIN_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2,
                DEFAULT_ASPECT_RATIO,
                (MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2
        };
        final Size[] minimalSizes = new Size[] {
                new Size((int) (100 * aspectRatios[0]), 100),
                new Size((int) (100 * aspectRatios[1]), 100),
                new Size((int) (100 * aspectRatios[2]), 100)
        };
        for (int i = 0; i < aspectRatios.length; i++) {
            final float aspectRatio = aspectRatios[i];
            final Size minimalSize = minimalSizes[i];
            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                    aspectRatio, EMPTY_CURRENT_BOUNDS, minimalSize);
            assertTrue("Destination bounds is no smaller than minimal requirement",
                    (destinationBounds.width() == minimalSize.getWidth()
                            && destinationBounds.height() >= minimalSize.getHeight())
                            || (destinationBounds.height() == minimalSize.getHeight()
                            && destinationBounds.width() >= minimalSize.getWidth()));
            final float actualAspectRatio =
                    destinationBounds.width() / (destinationBounds.height() * 1f);
            assertEquals("Destination bounds matches the given aspect ratio",
                    aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
        }
    }

    @Test
    public void getDestinationBounds_withCurrentBounds_ignoreMinBounds() {
        final float aspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2;
        final Rect currentBounds = new Rect(0, 0, 0, 100);
        currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
        final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2);

        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                aspectRatio, currentBounds, minSize);

        assertTrue("Destination bounds ignores minimal size",
                destinationBounds.width() > minSize.getWidth()
                        && destinationBounds.height() > minSize.getHeight());
    }

    @Test
    public void setShelfHeight_offsetBounds() {
        final int shelfHeight = 100;
        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        mPipBoundsHandler.setShelfHeight(true, shelfHeight);
        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        oldPosition.offset(0, -shelfHeight);
        assertBoundsWithMargin("offsetBounds by shelf", oldPosition, newPosition);
@@ -177,11 +223,11 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
    public void onImeVisibilityChanged_offsetBounds() {
        final int imeHeight = 100;
        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        oldPosition.offset(0, -imeHeight);
        assertBoundsWithMargin("offsetBounds by IME", oldPosition, newPosition);
@@ -191,13 +237,13 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
    public void onSaveReentryBounds_restoreLastPosition() {
        final ComponentName componentName = new ComponentName(mContext, "component1");
        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        oldPosition.offset(0, -100);
        mPipBoundsHandler.onSaveReentryBounds(componentName, oldPosition);

        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        assertBoundsWithMargin("restoreLastPosition", oldPosition, newPosition);
    }
@@ -206,14 +252,14 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
    public void onResetReentryBounds_useDefaultBounds() {
        final ComponentName componentName = new ComponentName(mContext, "component1");
        final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
        final Rect newBounds = new Rect(defaultBounds);
        newBounds.offset(0, -100);
        mPipBoundsHandler.onSaveReentryBounds(componentName, newBounds);

        mPipBoundsHandler.onResetReentryBounds(componentName);
        final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        assertBoundsWithMargin("useDefaultBounds", defaultBounds, actualBounds);
    }
@@ -222,14 +268,14 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
    public void onResetReentryBounds_componentMismatch_restoreLastPosition() {
        final ComponentName componentName = new ComponentName(mContext, "component1");
        final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
        final Rect newBounds = new Rect(defaultBounds);
        newBounds.offset(0, -100);
        mPipBoundsHandler.onSaveReentryBounds(componentName, newBounds);

        mPipBoundsHandler.onResetReentryBounds(new ComponentName(mContext, "component2"));
        final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS);
                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);

        assertBoundsWithMargin("restoreLastPosition", newBounds, actualBounds);
    }
Loading