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

Commit ebf1808a authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Move rotation bounds calculation into SysUI

Also included in this CL
- Cleanup all bounds calculation in PinnedStackController
- Move PipSnapAlgorithm to SysUI

Bug: 139016833
Bug: 139016576
Bug: 145133340
Test: atest PinnedStackTests
Test: atest MultiDisplayActivityLaunchTest
Test: atest MultiDisplaySystemDecorationTests
Change-Id: Ifa0621a1cb69e76498e020aef7d8fa815df4ce48
parent 0d2e2c2b
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -45,4 +45,17 @@ interface IPinnedStackController {
     * {@param animationDuration} suggests the animation duration transitioning to PiP window.
     */
    void startAnimation(in Rect destinationBounds, in Rect sourceRectHint, int animationDuration);

    /**
     * Notifies the controller to reset on bounds animation, if there is any.
     * This could happen when screen rotation is happening and we need to notify the WM to reset
     * any running bounds animation on the pinned stack.
     * {@param bounds} here is the final destination bounds.
     */
    void resetBoundsAnimation(in Rect bounds);

    /**
     * Reports the current default and movement bounds to controller.
     */
    void reportBounds(in Rect defaultBounds, in Rect movementBounds);
}
+3 −1
Original line number Diff line number Diff line
@@ -20,11 +20,13 @@ import android.content.Context;
import android.content.res.Configuration;

import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.wm.DisplayWindowController;

import java.io.PrintWriter;

public interface BasePipManager {
    void initialize(Context context, BroadcastDispatcher broadcastDispatcher);
    void initialize(Context context, BroadcastDispatcher broadcastDispatcher,
            DisplayWindowController displayWindowController);
    void showPictureInPictureMenu();
    default void expandPip() {}
    default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
+84 −3
Original line number Diff line number Diff line
@@ -16,8 +16,14 @@

package com.android.systemui.pip;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;

import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
@@ -32,10 +38,9 @@ import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IPinnedStackController;
import android.view.IWindowManager;
import android.view.WindowContainerTransaction;
import android.view.WindowManagerGlobal;

import com.android.internal.policy.PipSnapAlgorithm;

import java.io.PrintWriter;

/**
@@ -154,6 +159,7 @@ public class PipBoundsHandler {
     */
    public void onMinimizedStateChanged(boolean minimized) {
        mIsMinimized = minimized;
        mSnapAlgorithm.setMinimized(minimized);
    }

    /**
@@ -199,6 +205,7 @@ public class PipBoundsHandler {
        mReentrySnapFraction = INVALID_SNAP_FRACTION;
        mReentrySize = null;
        mLastPipComponentName = null;
        mLastDestinationBounds.setEmpty();
    }

    public Rect getLastDestinationBounds() {
@@ -235,8 +242,9 @@ public class PipBoundsHandler {
     */
    public void onPrepareAnimation(Rect sourceRectHint, float aspectRatio, Rect bounds) {
        final Rect destinationBounds;
        final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
        if (bounds == null) {
            destinationBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
            destinationBounds = new Rect(defaultBounds);
        } else {
            destinationBounds = new Rect(bounds);
        }
@@ -253,11 +261,84 @@ public class PipBoundsHandler {
            mPinnedStackController.startAnimation(destinationBounds, sourceRectHint,
                    -1 /* animationDuration */);
            mLastDestinationBounds.set(destinationBounds);
            mPinnedStackController.reportBounds(defaultBounds,
                    getMovementBounds(defaultBounds));
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to start PiP animation from SysUI", e);
        }
    }

    /**
     * Updates the display info, calculating and returning the new stack and movement bounds in the
     * new orientation of the device if necessary.
     *
     * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise.
     */
    public boolean onDisplayRotationChanged(Rect outBounds, int displayId, int fromRotation,
            int toRotation, WindowContainerTransaction t) {
        // Bail early if the event is not sent to current {@link #mDisplayInfo}
        if ((displayId != mDisplayInfo.displayId) || (fromRotation == toRotation)) {
            return false;
        }

        // Bail early if the pinned stack is staled.
        final ActivityManager.StackInfo pinnedStackInfo;
        try {
            pinnedStackInfo = ActivityTaskManager.getService()
                    .getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
            if (pinnedStackInfo == null) return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get StackInfo for pinned stack", e);
            return false;
        }

        // Calculate the snap fraction of the current stack along the old movement bounds
        final Rect postChangeStackBounds = new Rect(mLastDestinationBounds);
        final float snapFraction = getSnapFraction(postChangeStackBounds);

        // Populate the new {@link #mDisplayInfo}.
        // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
        // therefore, the width/height may require a swap first.
        // Moving forward, we should get the new dimensions after rotation from DisplayLayout.
        mDisplayInfo.rotation = toRotation;
        updateDisplayInfoIfNeeded();

        // Calculate the stack bounds in the new orientation based on same fraction along the
        // rotated movement bounds.
        final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
                false /* adjustForIme */);
        mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
                snapFraction);
        if (mIsMinimized) {
            applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
        }

        try {
            outBounds.set(postChangeStackBounds);
            mLastDestinationBounds.set(outBounds);
            mPinnedStackController.resetBoundsAnimation(outBounds);
            mPinnedStackController.reportBounds(outBounds, getMovementBounds(outBounds));
            t.setBounds(pinnedStackInfo.stackToken, outBounds);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to resize PiP on display rotation", e);
        }
        return true;
    }

    private void updateDisplayInfoIfNeeded() {
        final boolean updateNeeded;
        if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) {
            updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
        } else {
            updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
        }
        if (updateNeeded) {
            final int newLogicalHeight = mDisplayInfo.logicalWidth;
            mDisplayInfo.logicalWidth = mDisplayInfo.logicalHeight;
            mDisplayInfo.logicalHeight = newLogicalHeight;
        }
    }

    /**
     * @return whether the given {@param aspectRatio} is valid.
     */
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.internal.policy;
package com.android.systemui.pip;

import android.content.Context;
import android.content.res.Configuration;
+6 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.UserManager;
import com.android.systemui.SystemUI;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.wm.DisplayWindowController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -44,15 +45,17 @@ public class PipUI extends SystemUI implements CommandQueue.Callbacks {
    private final CommandQueue mCommandQueue;
    private BasePipManager mPipManager;
    private final BroadcastDispatcher mBroadcastDispatcher;

    private final DisplayWindowController mDisplayWindowController;
    private boolean mSupportsPip;

    @Inject
    public PipUI(Context context, CommandQueue commandQueue,
            BroadcastDispatcher broadcastDispatcher) {
            BroadcastDispatcher broadcastDispatcher,
            DisplayWindowController displayWindowController) {
        super(context);
        mBroadcastDispatcher = broadcastDispatcher;
        mCommandQueue = commandQueue;
        mDisplayWindowController = displayWindowController;
    }

    @Override
@@ -72,7 +75,7 @@ public class PipUI extends SystemUI implements CommandQueue.Callbacks {
        mPipManager = pm.hasSystemFeature(FEATURE_LEANBACK_ONLY)
                ? com.android.systemui.pip.tv.PipManager.getInstance()
                : com.android.systemui.pip.phone.PipManager.getInstance();
        mPipManager.initialize(mContext, mBroadcastDispatcher);
        mPipManager.initialize(mContext, mBroadcastDispatcher, mDisplayWindowController);

        mCommandQueue.addCallback(this);
    }
Loading