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

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

Merge "Move reentry state into PipBoundsState"

parents ce2ae195 5b8d2440
Loading
Loading
Loading
Loading
+24 −57
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;

import android.annotation.NonNull;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
@@ -52,14 +52,11 @@ public class PipBoundsHandler {
    private static final String TAG = PipBoundsHandler.class.getSimpleName();
    private static final float INVALID_SNAP_FRACTION = -1f;

    private final @NonNull PipBoundsState mPipBoundsState;
    private final PipSnapAlgorithm mSnapAlgorithm;
    private final DisplayInfo mDisplayInfo = new DisplayInfo();
    private DisplayLayout mDisplayLayout;

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

    private float mDefaultAspectRatio;
    private float mMinAspectRatio;
    private float mMaxAspectRatio;
@@ -75,7 +72,8 @@ public class PipBoundsHandler {
    private boolean mIsShelfShowing;
    private int mShelfHeight;

    public PipBoundsHandler(Context context) {
    public PipBoundsHandler(Context context, @NonNull PipBoundsState pipBoundsState) {
        mPipBoundsState = pipBoundsState;
        mSnapAlgorithm = new PipSnapAlgorithm(context);
        mDisplayLayout = new DisplayLayout();
        reloadResources(context);
@@ -174,40 +172,6 @@ public class PipBoundsHandler {
        displayInfo.copyFrom(mDisplayInfo);
    }

    /**
     * Responds to IPinnedStackListener on saving reentry snap fraction and size
     * for a given {@link ComponentName}.
     */
    public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
        mReentrySnapFraction = getSnapFraction(bounds);
        mReentrySize = new Size(bounds.width(), bounds.height());
        mLastPipComponentName = componentName;
    }

    /**
     * Responds to IPinnedStackListener on resetting reentry snap fraction and size
     * for a given {@link ComponentName}.
     */
    public void onResetReentryBounds(ComponentName componentName) {
        if (componentName.equals(mLastPipComponentName)) {
            onResetReentryBoundsUnchecked();
        }
    }

    private void onResetReentryBoundsUnchecked() {
        mReentrySnapFraction = INVALID_SNAP_FRACTION;
        mReentrySize = null;
        mLastPipComponentName = null;
    }

    /**
     * Returns ture if there's a valid snap fraction. This is used with {@link EXTRA_IS_FIRST_ENTRY}
     * to see if this is the first time user has entered PIP for the component.
     */
    public boolean hasSaveReentryBounds() {
        return mReentrySnapFraction != INVALID_SNAP_FRACTION;
    }

    /**
     * The {@link PipSnapAlgorithm} is couple on display bounds
     * @return {@link PipSnapAlgorithm}.
@@ -250,37 +214,43 @@ public class PipBoundsHandler {
    }

    /**
     * See {@link #getDestinationBounds(ComponentName, float, Rect, Size, boolean)}
     * See {@link #getDestinationBounds(float, Rect, Size, boolean)}
     */
    public Rect getDestinationBounds(ComponentName componentName, float aspectRatio, Rect bounds,
            Size minimalSize) {
        return getDestinationBounds(componentName, aspectRatio, bounds, minimalSize,
    public Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) {
        return getDestinationBounds(aspectRatio, bounds, minimalSize,
                false /* useCurrentMinEdgeSize */);
    }

    /**
     * @return {@link Rect} of the destination PiP window bounds.
     */
    public Rect getDestinationBounds(ComponentName componentName, float aspectRatio, Rect bounds,
    public Rect getDestinationBounds(float aspectRatio, Rect bounds,
            Size minimalSize, boolean useCurrentMinEdgeSize) {
        if (!componentName.equals(mLastPipComponentName)) {
            onResetReentryBoundsUnchecked();
            mLastPipComponentName = componentName;
        }
        boolean isReentryBounds = false;
        final Rect destinationBounds;
        if (bounds == null) {
            final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
            destinationBounds = new Rect(defaultBounds);
            if (mReentrySnapFraction == INVALID_SNAP_FRACTION && mReentrySize == null) {
            // Calculating initial entry bounds
            final PipBoundsState.PipReentryState state = mPipBoundsState.getReentryState();

            final Rect defaultBounds;
            if (state != null) {
                // Restore to reentry bounds.
                defaultBounds = getDefaultBounds(state.getSnapFraction(), state.getSize());
                isReentryBounds = true;
            } else {
                // Get actual default bounds.
                defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */);
                mOverrideMinimalSize = minimalSize;
            }

            destinationBounds = new Rect(defaultBounds);
        } else {
            // Just adjusting bounds (e.g. on aspect ratio changed).
            destinationBounds = new Rect(bounds);
        }
        if (isValidPictureInPictureAspectRatio(aspectRatio)) {
            boolean useCurrentSize = bounds == null && mReentrySize != null;
            transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize,
                    useCurrentSize);
                    isReentryBounds);
        }
        mAspectRatio = aspectRatio;
        return destinationBounds;
@@ -533,9 +503,6 @@ public class PipBoundsHandler {
    public void dump(PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + TAG);
        pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
        pw.println(innerPrefix + "mReentrySnapFraction=" + mReentrySnapFraction);
        pw.println(innerPrefix + "mReentrySize=" + mReentrySize);
        pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
        pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio);
        pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);
+80 −0
Original line number Diff line number Diff line
@@ -17,9 +17,15 @@
package com.android.wm.shell.pip;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.graphics.Rect;
import android.util.Size;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.Objects;

/**
 * Singleton source of truth for the current state of PIP bounds.
@@ -28,6 +34,8 @@ public final class PipBoundsState {
    private static final String TAG = PipBoundsState.class.getSimpleName();

    private final @NonNull Rect mBounds = new Rect();
    private PipReentryState mPipReentryState;
    private ComponentName mLastPipComponentName;

    void setBounds(@NonNull Rect bounds) {
        mBounds.set(bounds);
@@ -38,6 +46,72 @@ public final class PipBoundsState {
        return new Rect(mBounds);
    }

    /**
     * Save the reentry state to restore to when re-entering PIP mode.
     *
     * TODO(b/169373982): consider refactoring this so that this class alone can use mBounds and
     * calculate the snap fraction to save for re-entry.
     */
    public void saveReentryState(@NonNull Rect bounds, float fraction) {
        mPipReentryState = new PipReentryState(new Size(bounds.width(), bounds.height()), fraction);
    }

    /**
     * Returns the saved reentry state.
     */
    @Nullable
    public PipReentryState getReentryState() {
        return mPipReentryState;
    }

    /**
     * Set the last {@link ComponentName} to enter PIP mode.
     */
    public void setLastPipComponentName(ComponentName lastPipComponentName) {
        final boolean changed = !Objects.equals(mLastPipComponentName, lastPipComponentName);
        mLastPipComponentName = lastPipComponentName;
        if (changed) {
            clearReentryState();
        }
    }

    public ComponentName getLastPipComponentName() {
        return mLastPipComponentName;
    }

    @VisibleForTesting
    void clearReentryState() {
        mPipReentryState = null;
    }

    static final class PipReentryState {
        private static final String TAG = PipReentryState.class.getSimpleName();

        private final @NonNull Size mSize;
        private final float mSnapFraction;

        PipReentryState(@NonNull Size size, float snapFraction) {
            mSize = size;
            mSnapFraction = snapFraction;
        }

        @NonNull
        Size getSize() {
            return mSize;
        }

        float getSnapFraction() {
            return mSnapFraction;
        }

        void dump(PrintWriter pw, String prefix) {
            final String innerPrefix = prefix + "  ";
            pw.println(prefix + TAG);
            pw.println(innerPrefix + "mSize=" + mSize);
            pw.println(innerPrefix + "mSnapFraction=" + mSnapFraction);
        }
    }

    /**
     * Dumps internal state.
     */
@@ -45,5 +119,11 @@ public final class PipBoundsState {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + TAG);
        pw.println(innerPrefix + "mBounds=" + mBounds);
        pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
        if (mPipReentryState == null) {
            pw.println(innerPrefix + "mPipReentryState=null");
        } else {
            mPipReentryState.dump(pw, innerPrefix);
        }
    }
}
+8 −5
Original line number Diff line number Diff line
@@ -329,7 +329,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            PictureInPictureParams pictureInPictureParams) {
        mShouldIgnoreEnteringPipTransition = true;
        mState = State.ENTERING_PIP;
        return mPipBoundsHandler.getDestinationBounds(componentName,
        mPipBoundsState.setLastPipComponentName(componentName);
        return mPipBoundsHandler.getDestinationBounds(
                getAspectRatioOrDefault(pictureInPictureParams),
                null /* bounds */, getMinimalSize(activityInfo));
    }
@@ -465,6 +466,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mLeash = leash;
        mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
        mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
        mPipBoundsState.setLastPipComponentName(mTaskInfo.topActivity);

        mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);
        mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER);
@@ -491,7 +493,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }

        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                getAspectRatioOrDefault(mPictureInPictureParams),
                null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
@@ -686,13 +688,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
        Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
        mPipBoundsState.setLastPipComponentName(info.topActivity);
        final PictureInPictureParams newParams = info.pictureInPictureParams;
        if (newParams == null || !applyPictureInPictureParams(newParams)) {
            Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
            return;
        }
        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                info.topActivity, getAspectRatioOrDefault(newParams),
                getAspectRatioOrDefault(newParams),
                mPipBoundsState.getBounds(), getMinimalSize(info.topActivityInfo),
                true /* userCurrentMinEdgeSize */);
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
@@ -709,7 +712,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    public void onFixedRotationFinished(int displayId) {
        if (mShouldDeferEnteringPip && mState.isInPip()) {
            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                    mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                    getAspectRatioOrDefault(mPictureInPictureParams),
                    null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
            // schedule a regular animation to ensure all the callbacks are still being sent
            enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
@@ -783,7 +786,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }

        final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(
                mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                getAspectRatioOrDefault(mPictureInPictureParams),
                null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
        if (newDestinationBounds.equals(currentDestinationBounds)) return;
        if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {
+9 −2
Original line number Diff line number Diff line
@@ -173,7 +173,13 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac

        @Override
        public void onActivityHidden(ComponentName componentName) {
            mHandler.post(() -> mPipBoundsHandler.onResetReentryBounds(componentName));
            mHandler.post(() -> {
                if (componentName.equals(mPipBoundsState.getLastPipComponentName())) {
                    // The activity was removed, we don't want to restore to the reentry state
                    // saved for this component anymore.
                    mPipBoundsState.setLastPipComponentName(null);
                }
            });
        }

        @Override
@@ -384,7 +390,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
        if (isOutPipDirection(direction)) {
            // Exiting PIP, save the reentry bounds to restore to when re-entering.
            updateReentryBounds(pipBounds);
            mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds);
            final float snapFraction = mPipBoundsHandler.getSnapFraction(mReentryBounds);
            mPipBoundsState.saveReentryState(mReentryBounds, snapFraction);
        }
        // Disable touches while the animation is running
        mTouchHandler.setTouchEnabled(false);
+51 −100

File changed.

Preview size limit exceeded, changes collapsed.

Loading