Loading packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +31 −17 Original line number Diff line number Diff line Loading @@ -36,10 +36,11 @@ import android.util.Size; import android.util.TypedValue; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IWindowManager; import android.view.WindowManagerGlobal; import android.window.WindowContainerTransaction; import com.android.systemui.wm.DisplayController; import com.android.systemui.wm.DisplayLayout; import java.io.PrintWriter; import javax.inject.Inject; Loading @@ -56,10 +57,10 @@ public class PipBoundsHandler { private static final float INVALID_SNAP_FRACTION = -1f; private final Context mContext; private final IWindowManager mWindowManager; private final PipSnapAlgorithm mSnapAlgorithm; private final DisplayInfo mDisplayInfo = new DisplayInfo(); private final Rect mTmpInsets = new Rect(); private final DisplayController mDisplayController; private final DisplayLayout mDisplayLayout; private ComponentName mLastPipComponentName; private float mReentrySnapFraction = INVALID_SNAP_FRACTION; Loading @@ -80,11 +81,24 @@ public class PipBoundsHandler { private boolean mIsShelfShowing; private int mShelfHeight; private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener = new DisplayController.OnDisplaysChangedListener() { @Override public void onDisplayAdded(int displayId) { if (displayId == mContext.getDisplayId()) { mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId)); } } }; @Inject public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm) { public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm, DisplayController displayController) { mContext = context; mSnapAlgorithm = pipSnapAlgorithm; mWindowManager = WindowManagerGlobal.getWindowManagerService(); mDisplayLayout = new DisplayLayout(); mDisplayController = displayController; mDisplayController.addDisplayWindowListener(mDisplaysChangedListener); reloadResources(); // Initialize the aspect ratio to the default aspect ratio. Don't do this in reload // resources as it would clobber mAspectRatio when entering PiP from fullscreen which Loading Loading @@ -272,8 +286,8 @@ public class PipBoundsHandler { * * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise. */ public boolean onDisplayRotationChanged(Rect outBounds, Rect oldBounds, int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) { public boolean onDisplayRotationChanged(Rect outBounds, Rect oldBounds, Rect outInsetBounds, 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; Loading @@ -294,6 +308,9 @@ public class PipBoundsHandler { final Rect postChangeStackBounds = new Rect(oldBounds); final float snapFraction = getSnapFraction(postChangeStackBounds); // Update the display layout mDisplayLayout.rotateTo(mContext.getResources(), toRotation); // 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. Loading @@ -308,6 +325,7 @@ public class PipBoundsHandler { mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds, snapFraction); getInsetBounds(outInsetBounds); outBounds.set(postChangeStackBounds); t.setBounds(pinnedStackInfo.stackToken, outBounds); return true; Loading Loading @@ -425,15 +443,11 @@ public class PipBoundsHandler { * Populates the bounds on the screen that the PIP can be visible in. */ protected void getInsetBounds(Rect outRect) { try { mWindowManager.getStableInsets(mContext.getDisplayId(), mTmpInsets); outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y, mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x, mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y); } catch (RemoteException e) { Log.e(TAG, "Failed to get stable insets from WM", e); } Rect insets = mDisplayLayout.stableInsets(); outRect.set(insets.left + mScreenEdgeInsets.x, insets.top + mScreenEdgeInsets.y, mDisplayInfo.logicalWidth - insets.right - mScreenEdgeInsets.x, mDisplayInfo.logicalHeight - insets.bottom - mScreenEdgeInsets.y); } /** Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +17 −3 Original line number Diff line number Diff line Loading @@ -95,8 +95,21 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private final DisplayChangeController.OnDisplayChangingListener mRotationController = ( int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> { final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds, mPipTaskOrganizer.getLastReportedBounds(), displayId, fromRotation, toRotation, t); mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds, displayId, fromRotation, toRotation, t); if (changed) { // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // movement bounds mTouchHandler.adjustBoundsForRotation(mTmpNormalBounds, mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds); // The bounds are being applied to a specific snap fraction, so reset any known offsets // for the previous orientation before updating the movement bounds mPipBoundsHandler.setShelfHeight(false , 0); mPipBoundsHandler.onImeVisibilityChanged(false, 0); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); updateMovementBounds(mTmpNormalBounds, true /* fromRotation */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */); } Loading Loading @@ -290,9 +303,10 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void setShelfHeight(boolean visible, int height) { mHandler.post(() -> { final boolean changed = mPipBoundsHandler.setShelfHeight(visible, height); final int shelfHeight = visible ? height : 0; final boolean changed = mPipBoundsHandler.setShelfHeight(visible, shelfHeight); if (changed) { mTouchHandler.onShelfVisibilityChanged(visible, height); mTouchHandler.onShelfVisibilityChanged(visible, shelfHeight); updateMovementBounds(mPipTaskOrganizer.getLastReportedBounds(), false /* fromRotation */, false /* fromImeAdjustment */, true /* fromShelfAdjustment */); Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +9 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,15 @@ public class PipTouchHandler { mShelfHeight = shelfHeight; } public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) { final Rect toMovementBounds = new Rect(); mSnapAlgorithm.getMovementBounds(outBounds, insetBounds, toMovementBounds, 0); final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets; if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) { outBounds.offsetTo(outBounds.left, toMovementBounds.bottom); } } public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) { final int bottomOffset = mIsImeShowing ? mImeHeight : 0; Loading packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.pip; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.ComponentName; import android.graphics.Rect; Loading @@ -32,6 +33,7 @@ import android.view.Gravity; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.wm.DisplayController; import org.junit.Before; import org.junit.Test; Loading Loading @@ -63,7 +65,8 @@ public class PipBoundsHandlerTest extends SysuiTestCase { @Before public void setUp() throws Exception { initializeMockResources(); mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext)); mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext), mock(DisplayController.class)); mTestComponentName1 = new ComponentName(mContext, "component1"); mTestComponentName2 = new ComponentName(mContext, "component2"); Loading Loading
packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +31 −17 Original line number Diff line number Diff line Loading @@ -36,10 +36,11 @@ import android.util.Size; import android.util.TypedValue; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IWindowManager; import android.view.WindowManagerGlobal; import android.window.WindowContainerTransaction; import com.android.systemui.wm.DisplayController; import com.android.systemui.wm.DisplayLayout; import java.io.PrintWriter; import javax.inject.Inject; Loading @@ -56,10 +57,10 @@ public class PipBoundsHandler { private static final float INVALID_SNAP_FRACTION = -1f; private final Context mContext; private final IWindowManager mWindowManager; private final PipSnapAlgorithm mSnapAlgorithm; private final DisplayInfo mDisplayInfo = new DisplayInfo(); private final Rect mTmpInsets = new Rect(); private final DisplayController mDisplayController; private final DisplayLayout mDisplayLayout; private ComponentName mLastPipComponentName; private float mReentrySnapFraction = INVALID_SNAP_FRACTION; Loading @@ -80,11 +81,24 @@ public class PipBoundsHandler { private boolean mIsShelfShowing; private int mShelfHeight; private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener = new DisplayController.OnDisplaysChangedListener() { @Override public void onDisplayAdded(int displayId) { if (displayId == mContext.getDisplayId()) { mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId)); } } }; @Inject public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm) { public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm, DisplayController displayController) { mContext = context; mSnapAlgorithm = pipSnapAlgorithm; mWindowManager = WindowManagerGlobal.getWindowManagerService(); mDisplayLayout = new DisplayLayout(); mDisplayController = displayController; mDisplayController.addDisplayWindowListener(mDisplaysChangedListener); reloadResources(); // Initialize the aspect ratio to the default aspect ratio. Don't do this in reload // resources as it would clobber mAspectRatio when entering PiP from fullscreen which Loading Loading @@ -272,8 +286,8 @@ public class PipBoundsHandler { * * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise. */ public boolean onDisplayRotationChanged(Rect outBounds, Rect oldBounds, int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) { public boolean onDisplayRotationChanged(Rect outBounds, Rect oldBounds, Rect outInsetBounds, 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; Loading @@ -294,6 +308,9 @@ public class PipBoundsHandler { final Rect postChangeStackBounds = new Rect(oldBounds); final float snapFraction = getSnapFraction(postChangeStackBounds); // Update the display layout mDisplayLayout.rotateTo(mContext.getResources(), toRotation); // 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. Loading @@ -308,6 +325,7 @@ public class PipBoundsHandler { mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds, snapFraction); getInsetBounds(outInsetBounds); outBounds.set(postChangeStackBounds); t.setBounds(pinnedStackInfo.stackToken, outBounds); return true; Loading Loading @@ -425,15 +443,11 @@ public class PipBoundsHandler { * Populates the bounds on the screen that the PIP can be visible in. */ protected void getInsetBounds(Rect outRect) { try { mWindowManager.getStableInsets(mContext.getDisplayId(), mTmpInsets); outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y, mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x, mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y); } catch (RemoteException e) { Log.e(TAG, "Failed to get stable insets from WM", e); } Rect insets = mDisplayLayout.stableInsets(); outRect.set(insets.left + mScreenEdgeInsets.x, insets.top + mScreenEdgeInsets.y, mDisplayInfo.logicalWidth - insets.right - mScreenEdgeInsets.x, mDisplayInfo.logicalHeight - insets.bottom - mScreenEdgeInsets.y); } /** Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +17 −3 Original line number Diff line number Diff line Loading @@ -95,8 +95,21 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private final DisplayChangeController.OnDisplayChangingListener mRotationController = ( int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> { final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds, mPipTaskOrganizer.getLastReportedBounds(), displayId, fromRotation, toRotation, t); mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds, displayId, fromRotation, toRotation, t); if (changed) { // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // movement bounds mTouchHandler.adjustBoundsForRotation(mTmpNormalBounds, mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds); // The bounds are being applied to a specific snap fraction, so reset any known offsets // for the previous orientation before updating the movement bounds mPipBoundsHandler.setShelfHeight(false , 0); mPipBoundsHandler.onImeVisibilityChanged(false, 0); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); updateMovementBounds(mTmpNormalBounds, true /* fromRotation */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */); } Loading Loading @@ -290,9 +303,10 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void setShelfHeight(boolean visible, int height) { mHandler.post(() -> { final boolean changed = mPipBoundsHandler.setShelfHeight(visible, height); final int shelfHeight = visible ? height : 0; final boolean changed = mPipBoundsHandler.setShelfHeight(visible, shelfHeight); if (changed) { mTouchHandler.onShelfVisibilityChanged(visible, height); mTouchHandler.onShelfVisibilityChanged(visible, shelfHeight); updateMovementBounds(mPipTaskOrganizer.getLastReportedBounds(), false /* fromRotation */, false /* fromImeAdjustment */, true /* fromShelfAdjustment */); Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +9 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,15 @@ public class PipTouchHandler { mShelfHeight = shelfHeight; } public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) { final Rect toMovementBounds = new Rect(); mSnapAlgorithm.getMovementBounds(outBounds, insetBounds, toMovementBounds, 0); final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets; if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) { outBounds.offsetTo(outBounds.left, toMovementBounds.bottom); } } public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) { final int bottomOffset = mIsImeShowing ? mImeHeight : 0; Loading
packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.pip; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.ComponentName; import android.graphics.Rect; Loading @@ -32,6 +33,7 @@ import android.view.Gravity; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.wm.DisplayController; import org.junit.Before; import org.junit.Test; Loading Loading @@ -63,7 +65,8 @@ public class PipBoundsHandlerTest extends SysuiTestCase { @Before public void setUp() throws Exception { initializeMockResources(); mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext)); mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext), mock(DisplayController.class)); mTestComponentName1 = new ComponentName(mContext, "component1"); mTestComponentName2 = new ComponentName(mContext, "component2"); Loading