Loading libs/WindowManager/Shell/res/values/dimen.xml +3 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ <!-- The width and height of the background for custom action in PiP menu. --> <dimen name="pip_custom_close_bg_size">32dp</dimen> <!-- Extra padding between picture-in-picture windows and any registered keep clear areas. --> <dimen name="pip_keep_clear_areas_padding">16dp</dimen> <dimen name="dismiss_target_x_size">24dp</dimen> <dimen name="floating_dismiss_bottom_margin">50dp</dimen> Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +8 −6 Original line number Diff line number Diff line Loading @@ -72,9 +72,9 @@ import com.android.wm.shell.pip.PipTransition; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip.PipTransitionState; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PhonePipKeepClearAlgorithm; import com.android.wm.shell.pip.phone.PhonePipMenuController; import com.android.wm.shell.pip.phone.PipController; import com.android.wm.shell.pip.phone.PipKeepClearAlgorithm; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.recents.RecentTasksController; Loading Loading @@ -320,7 +320,7 @@ public abstract class WMShellModule { DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipKeepClearAlgorithm pipKeepClearAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, Loading Loading @@ -357,15 +357,17 @@ public abstract class WMShellModule { @WMSingleton @Provides static PipKeepClearAlgorithm providePipKeepClearAlgorithm() { return new PipKeepClearAlgorithm(); static PhonePipKeepClearAlgorithm providePhonePipKeepClearAlgorithm(Context context) { return new PhonePipKeepClearAlgorithm(context); } @WMSingleton @Provides static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) { return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm); PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm) { return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm); } // Handler is used by Icon.loadDrawableAsync Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -37,12 +37,13 @@ interface IPip { * @param activityInfo ActivityInfo tied to the Activity * @param pictureInPictureParams PictureInPictureParams tied to the Activity * @param launcherRotation Launcher rotation to calculate the PiP destination bounds * @param shelfHeight Shelf height of launcher to calculate the PiP destination bounds * @param hotseatKeepClearArea Bounds of Hotseat to avoid used to calculate PiP destination bounds * @return destination bounds the PiP window should land into */ Rect startSwipePipToHome(in ComponentName componentName, in ActivityInfo activityInfo, in PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) = 1; int launcherRotation, in Rect hotseatKeepClearArea) = 1; /** * Notifies the swiping Activity to PiP onto home transition is finished Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +20 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ public class PipBoundsAlgorithm { private final @NonNull PipBoundsState mPipBoundsState; private final PipSnapAlgorithm mSnapAlgorithm; private final PipKeepClearAlgorithm mPipKeepClearAlgorithm; private float mDefaultSizePercent; private float mMinAspectRatioForMinSize; Loading @@ -60,9 +61,11 @@ public class PipBoundsAlgorithm { protected Point mScreenEdgeInsets; public PipBoundsAlgorithm(Context context, @NonNull PipBoundsState pipBoundsState, @NonNull PipSnapAlgorithm pipSnapAlgorithm) { @NonNull PipSnapAlgorithm pipSnapAlgorithm, @NonNull PipKeepClearAlgorithm pipKeepClearAlgorithm) { mPipBoundsState = pipBoundsState; mSnapAlgorithm = pipSnapAlgorithm; mPipKeepClearAlgorithm = pipKeepClearAlgorithm; reloadResources(context); // 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 @@ -129,8 +132,21 @@ public class PipBoundsAlgorithm { return getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */); } /** Returns the destination bounds to place the PIP window on entry. */ /** * Returns the destination bounds to place the PIP window on entry. * If there are any keep clear areas registered, the position will try to avoid occluding them. */ public Rect getEntryDestinationBounds() { Rect entryBounds = getEntryDestinationBoundsIgnoringKeepClearAreas(); Rect insets = new Rect(); getInsetBounds(insets); return mPipKeepClearAlgorithm.findUnoccludedPosition(entryBounds, mPipBoundsState.getRestrictedKeepClearAreas(), mPipBoundsState.getUnrestrictedKeepClearAreas(), insets); } /** Returns the destination bounds to place the PIP window on entry. */ public Rect getEntryDestinationBoundsIgnoringKeepClearAreas() { final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState(); final Rect destinationBounds = reentryState != null Loading @@ -138,9 +154,10 @@ public class PipBoundsAlgorithm { : getDefaultBounds(); final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; return transformBoundsToAspectRatioIfValid(destinationBounds, Rect aspectRatioBounds = transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, useCurrentSize); return aspectRatioBounds; } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithm.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.wm.shell.pip; import android.graphics.Rect; import java.util.Set; /** * Interface for interacting with keep clear algorithm used to move PiP window out of the way of * keep clear areas. */ public interface PipKeepClearAlgorithm { /** * Adjust the position of picture in picture window based on the registered keep clear areas. * @param pipBoundsState state of the PiP to use for the calculations * @param pipBoundsAlgorithm algorithm implementation used to get the entry destination bounds * @return */ default Rect adjust(PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm) { return pipBoundsState.getBounds(); } /** * Calculate the bounds so that none of the keep clear areas are occluded, while the bounds stay * within the allowed bounds. If such position is not feasible, return original bounds. * @param defaultBounds initial bounds used in the calculation * @param restrictedKeepClearAreas registered restricted keep clear areas * @param unrestrictedKeepClearAreas registered unrestricted keep clear areas * @param allowedBounds bounds that define the allowed space for the output, result will always * be inside those bounds * @return bounds that don't cover any of the keep clear areas and are within allowed bounds */ default Rect findUnoccludedPosition(Rect defaultBounds, Set<Rect> restrictedKeepClearAreas, Set<Rect> unrestrictedKeepClearAreas, Rect allowedBounds) { return defaultBounds; } } Loading
libs/WindowManager/Shell/res/values/dimen.xml +3 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ <!-- The width and height of the background for custom action in PiP menu. --> <dimen name="pip_custom_close_bg_size">32dp</dimen> <!-- Extra padding between picture-in-picture windows and any registered keep clear areas. --> <dimen name="pip_keep_clear_areas_padding">16dp</dimen> <dimen name="dismiss_target_x_size">24dp</dimen> <dimen name="floating_dismiss_bottom_margin">50dp</dimen> Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +8 −6 Original line number Diff line number Diff line Loading @@ -72,9 +72,9 @@ import com.android.wm.shell.pip.PipTransition; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip.PipTransitionState; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PhonePipKeepClearAlgorithm; import com.android.wm.shell.pip.phone.PhonePipMenuController; import com.android.wm.shell.pip.phone.PipController; import com.android.wm.shell.pip.phone.PipKeepClearAlgorithm; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.recents.RecentTasksController; Loading Loading @@ -320,7 +320,7 @@ public abstract class WMShellModule { DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipKeepClearAlgorithm pipKeepClearAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, Loading Loading @@ -357,15 +357,17 @@ public abstract class WMShellModule { @WMSingleton @Provides static PipKeepClearAlgorithm providePipKeepClearAlgorithm() { return new PipKeepClearAlgorithm(); static PhonePipKeepClearAlgorithm providePhonePipKeepClearAlgorithm(Context context) { return new PhonePipKeepClearAlgorithm(context); } @WMSingleton @Provides static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) { return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm); PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm) { return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm); } // Handler is used by Icon.loadDrawableAsync Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -37,12 +37,13 @@ interface IPip { * @param activityInfo ActivityInfo tied to the Activity * @param pictureInPictureParams PictureInPictureParams tied to the Activity * @param launcherRotation Launcher rotation to calculate the PiP destination bounds * @param shelfHeight Shelf height of launcher to calculate the PiP destination bounds * @param hotseatKeepClearArea Bounds of Hotseat to avoid used to calculate PiP destination bounds * @return destination bounds the PiP window should land into */ Rect startSwipePipToHome(in ComponentName componentName, in ActivityInfo activityInfo, in PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) = 1; int launcherRotation, in Rect hotseatKeepClearArea) = 1; /** * Notifies the swiping Activity to PiP onto home transition is finished Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +20 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ public class PipBoundsAlgorithm { private final @NonNull PipBoundsState mPipBoundsState; private final PipSnapAlgorithm mSnapAlgorithm; private final PipKeepClearAlgorithm mPipKeepClearAlgorithm; private float mDefaultSizePercent; private float mMinAspectRatioForMinSize; Loading @@ -60,9 +61,11 @@ public class PipBoundsAlgorithm { protected Point mScreenEdgeInsets; public PipBoundsAlgorithm(Context context, @NonNull PipBoundsState pipBoundsState, @NonNull PipSnapAlgorithm pipSnapAlgorithm) { @NonNull PipSnapAlgorithm pipSnapAlgorithm, @NonNull PipKeepClearAlgorithm pipKeepClearAlgorithm) { mPipBoundsState = pipBoundsState; mSnapAlgorithm = pipSnapAlgorithm; mPipKeepClearAlgorithm = pipKeepClearAlgorithm; reloadResources(context); // 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 @@ -129,8 +132,21 @@ public class PipBoundsAlgorithm { return getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */); } /** Returns the destination bounds to place the PIP window on entry. */ /** * Returns the destination bounds to place the PIP window on entry. * If there are any keep clear areas registered, the position will try to avoid occluding them. */ public Rect getEntryDestinationBounds() { Rect entryBounds = getEntryDestinationBoundsIgnoringKeepClearAreas(); Rect insets = new Rect(); getInsetBounds(insets); return mPipKeepClearAlgorithm.findUnoccludedPosition(entryBounds, mPipBoundsState.getRestrictedKeepClearAreas(), mPipBoundsState.getUnrestrictedKeepClearAreas(), insets); } /** Returns the destination bounds to place the PIP window on entry. */ public Rect getEntryDestinationBoundsIgnoringKeepClearAreas() { final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState(); final Rect destinationBounds = reentryState != null Loading @@ -138,9 +154,10 @@ public class PipBoundsAlgorithm { : getDefaultBounds(); final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; return transformBoundsToAspectRatioIfValid(destinationBounds, Rect aspectRatioBounds = transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, useCurrentSize); return aspectRatioBounds; } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithm.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.wm.shell.pip; import android.graphics.Rect; import java.util.Set; /** * Interface for interacting with keep clear algorithm used to move PiP window out of the way of * keep clear areas. */ public interface PipKeepClearAlgorithm { /** * Adjust the position of picture in picture window based on the registered keep clear areas. * @param pipBoundsState state of the PiP to use for the calculations * @param pipBoundsAlgorithm algorithm implementation used to get the entry destination bounds * @return */ default Rect adjust(PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm) { return pipBoundsState.getBounds(); } /** * Calculate the bounds so that none of the keep clear areas are occluded, while the bounds stay * within the allowed bounds. If such position is not feasible, return original bounds. * @param defaultBounds initial bounds used in the calculation * @param restrictedKeepClearAreas registered restricted keep clear areas * @param unrestrictedKeepClearAreas registered unrestricted keep clear areas * @param allowedBounds bounds that define the allowed space for the output, result will always * be inside those bounds * @return bounds that don't cover any of the keep clear areas and are within allowed bounds */ default Rect findUnoccludedPosition(Rect defaultBounds, Set<Rect> restrictedKeepClearAreas, Set<Rect> unrestrictedKeepClearAreas, Rect allowedBounds) { return defaultBounds; } }