Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +8 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.os.RemoteException; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.view.Display; Loading @@ -36,6 +37,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * This module deals with display rotations coming from WM. When WM starts a rotation: after it has Loading Loading @@ -245,8 +247,8 @@ public class DisplayController { } } private void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) { private void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) { synchronized (mDisplays) { if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown" Loading Loading @@ -323,7 +325,8 @@ public class DisplayController { public void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) { mMainExecutor.execute(() -> { DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted); DisplayController.this.onKeepClearAreasChanged(displayId, new ArraySet<>(restricted), new ArraySet<>(unrestricted)); }); } } Loading Loading @@ -364,7 +367,7 @@ public class DisplayController { /** * Called when keep-clear areas on a display have changed. */ default void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) {} default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) {} } } libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ public abstract class TvPipModule { PipTransitionController pipTransitionController, TvPipNotificationController tvPipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper windowManagerShellWrapper, @ShellMainThread ShellExecutor mainExecutor) { return Optional.of( Loading @@ -81,6 +82,7 @@ public abstract class TvPipModule { pipMediaController, tvPipNotificationController, taskStackListener, displayController, windowManagerShellWrapper, mainExecutor)); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +39 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; import android.util.Size; import android.view.Display; Loading @@ -43,6 +44,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; /** Loading Loading @@ -90,6 +92,24 @@ public class PipBoundsState { private int mShelfHeight; /** Whether the user has resized the PIP manually. */ private boolean mHasUserResizedPip; /** * Areas defined by currently visible apps that they prefer to keep clear from overlays such as * the PiP. Restricted areas may only move the PiP a limited amount from its anchor position. * The system will try to respect these areas, but when not possible will ignore them. * * @see android.view.View#setPreferKeepClearRects */ private final Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>(); /** * Areas defined by currently visible apps holding * {@link android.Manifest.permission#SET_UNRESTRICTED_KEEP_CLEAR_AREAS} that they prefer to * keep clear from overlays such as the PiP. * Unrestricted areas can move the PiP farther than restricted areas, and the system will try * harder to respect these areas. * * @see android.view.View#setPreferKeepClearRects */ private final Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>(); private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; Loading Loading @@ -367,6 +387,25 @@ public class PipBoundsState { } } /** Set the keep clear areas onscreen. The PiP should ideally not cover them. */ public void setKeepClearAreas(@NonNull Set<Rect> restrictedAreas, @NonNull Set<Rect> unrestrictedAreas) { mRestrictedKeepClearAreas.clear(); mRestrictedKeepClearAreas.addAll(restrictedAreas); mUnrestrictedKeepClearAreas.clear(); mUnrestrictedKeepClearAreas.addAll(unrestrictedAreas); } @NonNull public Set<Rect> getRestrictedKeepClearAreas() { return mRestrictedKeepClearAreas; } @NonNull public Set<Rect> getUnrestrictedKeepClearAreas() { return mUnrestrictedKeepClearAreas; } /** * Initialize states when first entering PiP. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +17 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.view.Gravity; import com.android.wm.shell.R; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; Loading @@ -50,12 +51,14 @@ import com.android.wm.shell.pip.PipTransitionController; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Set; /** * Manages the picture-in-picture (PIP) UI and states. */ public class TvPipController implements PipTransitionController.PipTransitionCallback, TvPipMenuController.Delegate, TvPipNotificationController.Delegate { TvPipMenuController.Delegate, TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener { private static final String TAG = "TvPipController"; static final boolean DEBUG = false; Loading Loading @@ -112,6 +115,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipMediaController pipMediaController, TvPipNotificationController pipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper wmShell, ShellExecutor mainExecutor) { return new TvPipController( Loading @@ -124,6 +128,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal pipMediaController, pipNotificationController, taskStackListener, displayController, wmShell, mainExecutor).mImpl; } Loading @@ -138,6 +143,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipMediaController pipMediaController, TvPipNotificationController pipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper wmShell, ShellExecutor mainExecutor) { mContext = context; Loading @@ -163,6 +169,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal registerTaskStackListenerCallback(taskStackListener); registerWmShellPinnedStackListener(wmShell); displayController.addDisplayWindowListener(this); } private void onConfigurationChanged(Configuration newConfig) { Loading Loading @@ -253,6 +260,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal return mTvPipBoundsState.getTvFixedPipOrientation(); } @Override public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) { if (mTvPipBoundsState.getDisplayId() == displayId) { mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted); movePinnedStack(); } } /** * Animate to the updated position of the PiP based on the state and position of the PiP. */ Loading services/core/java/com/android/server/wm/DisplayContent.java +17 −8 Original line number Diff line number Diff line Loading @@ -414,6 +414,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private final Region mSystemGestureExclusionUnrestricted = new Region(); private int mSystemGestureExclusionLimit; private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>(); private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>(); /** * For default display it contains real metrics, empty for others. * @see WindowManagerService#createWatermark() Loading Loading @@ -3351,7 +3354,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp pw.println(mSystemGestureExclusion); } final List<Rect> keepClearAreas = getKeepClearAreas(); final Set<Rect> keepClearAreas = getKeepClearAreas(); if (!keepClearAreas.isEmpty()) { pw.println(); pw.print(" keepClearAreas="); Loading Loading @@ -5453,12 +5456,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } void updateKeepClearAreas() { final List<Rect> restrictedKeepClearAreas = new ArrayList(); final List<Rect> unrestrictedKeepClearAreas = new ArrayList(); final Set<Rect> restrictedKeepClearAreas = new ArraySet<>(); final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>(); getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas); if (!mRestrictedKeepClearAreas.equals(restrictedKeepClearAreas) || !mUnrestrictedKeepClearAreas.equals(unrestrictedKeepClearAreas)) { mRestrictedKeepClearAreas = restrictedKeepClearAreas; mUnrestrictedKeepClearAreas = unrestrictedKeepClearAreas; mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged( this, restrictedKeepClearAreas, unrestrictedKeepClearAreas); } } /** * Fills {@param outRestricted} with all keep-clear areas from visible, relevant windows Loading @@ -5469,7 +5478,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * For context on restricted vs unrestricted keep-clear areas, see * {@link android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS}. */ void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) { void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) { final Matrix tmpMatrix = new Matrix(); final float[] tmpFloat9 = new float[9]; forAllWindows(w -> { Loading @@ -5486,8 +5495,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** * Returns all keep-clear areas from visible, relevant windows on this display. */ ArrayList<Rect> getKeepClearAreas() { final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>(); Set<Rect> getKeepClearAreas() { final Set<Rect> keepClearAreas = new ArraySet<>(); getKeepClearAreas(keepClearAreas, keepClearAreas); return keepClearAreas; } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +8 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.os.RemoteException; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.view.Display; Loading @@ -36,6 +37,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * This module deals with display rotations coming from WM. When WM starts a rotation: after it has Loading Loading @@ -245,8 +247,8 @@ public class DisplayController { } } private void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) { private void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) { synchronized (mDisplays) { if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown" Loading Loading @@ -323,7 +325,8 @@ public class DisplayController { public void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) { mMainExecutor.execute(() -> { DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted); DisplayController.this.onKeepClearAreasChanged(displayId, new ArraySet<>(restricted), new ArraySet<>(unrestricted)); }); } } Loading Loading @@ -364,7 +367,7 @@ public class DisplayController { /** * Called when keep-clear areas on a display have changed. */ default void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) {} default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) {} } }
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ public abstract class TvPipModule { PipTransitionController pipTransitionController, TvPipNotificationController tvPipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper windowManagerShellWrapper, @ShellMainThread ShellExecutor mainExecutor) { return Optional.of( Loading @@ -81,6 +82,7 @@ public abstract class TvPipModule { pipMediaController, tvPipNotificationController, taskStackListener, displayController, windowManagerShellWrapper, mainExecutor)); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +39 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; import android.util.Size; import android.view.Display; Loading @@ -43,6 +44,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; /** Loading Loading @@ -90,6 +92,24 @@ public class PipBoundsState { private int mShelfHeight; /** Whether the user has resized the PIP manually. */ private boolean mHasUserResizedPip; /** * Areas defined by currently visible apps that they prefer to keep clear from overlays such as * the PiP. Restricted areas may only move the PiP a limited amount from its anchor position. * The system will try to respect these areas, but when not possible will ignore them. * * @see android.view.View#setPreferKeepClearRects */ private final Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>(); /** * Areas defined by currently visible apps holding * {@link android.Manifest.permission#SET_UNRESTRICTED_KEEP_CLEAR_AREAS} that they prefer to * keep clear from overlays such as the PiP. * Unrestricted areas can move the PiP farther than restricted areas, and the system will try * harder to respect these areas. * * @see android.view.View#setPreferKeepClearRects */ private final Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>(); private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; Loading Loading @@ -367,6 +387,25 @@ public class PipBoundsState { } } /** Set the keep clear areas onscreen. The PiP should ideally not cover them. */ public void setKeepClearAreas(@NonNull Set<Rect> restrictedAreas, @NonNull Set<Rect> unrestrictedAreas) { mRestrictedKeepClearAreas.clear(); mRestrictedKeepClearAreas.addAll(restrictedAreas); mUnrestrictedKeepClearAreas.clear(); mUnrestrictedKeepClearAreas.addAll(unrestrictedAreas); } @NonNull public Set<Rect> getRestrictedKeepClearAreas() { return mRestrictedKeepClearAreas; } @NonNull public Set<Rect> getUnrestrictedKeepClearAreas() { return mUnrestrictedKeepClearAreas; } /** * Initialize states when first entering PiP. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +17 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.view.Gravity; import com.android.wm.shell.R; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; Loading @@ -50,12 +51,14 @@ import com.android.wm.shell.pip.PipTransitionController; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Set; /** * Manages the picture-in-picture (PIP) UI and states. */ public class TvPipController implements PipTransitionController.PipTransitionCallback, TvPipMenuController.Delegate, TvPipNotificationController.Delegate { TvPipMenuController.Delegate, TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener { private static final String TAG = "TvPipController"; static final boolean DEBUG = false; Loading Loading @@ -112,6 +115,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipMediaController pipMediaController, TvPipNotificationController pipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper wmShell, ShellExecutor mainExecutor) { return new TvPipController( Loading @@ -124,6 +128,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal pipMediaController, pipNotificationController, taskStackListener, displayController, wmShell, mainExecutor).mImpl; } Loading @@ -138,6 +143,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipMediaController pipMediaController, TvPipNotificationController pipNotificationController, TaskStackListenerImpl taskStackListener, DisplayController displayController, WindowManagerShellWrapper wmShell, ShellExecutor mainExecutor) { mContext = context; Loading @@ -163,6 +169,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal registerTaskStackListenerCallback(taskStackListener); registerWmShellPinnedStackListener(wmShell); displayController.addDisplayWindowListener(this); } private void onConfigurationChanged(Configuration newConfig) { Loading Loading @@ -253,6 +260,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal return mTvPipBoundsState.getTvFixedPipOrientation(); } @Override public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) { if (mTvPipBoundsState.getDisplayId() == displayId) { mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted); movePinnedStack(); } } /** * Animate to the updated position of the PiP based on the state and position of the PiP. */ Loading
services/core/java/com/android/server/wm/DisplayContent.java +17 −8 Original line number Diff line number Diff line Loading @@ -414,6 +414,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private final Region mSystemGestureExclusionUnrestricted = new Region(); private int mSystemGestureExclusionLimit; private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>(); private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>(); /** * For default display it contains real metrics, empty for others. * @see WindowManagerService#createWatermark() Loading Loading @@ -3351,7 +3354,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp pw.println(mSystemGestureExclusion); } final List<Rect> keepClearAreas = getKeepClearAreas(); final Set<Rect> keepClearAreas = getKeepClearAreas(); if (!keepClearAreas.isEmpty()) { pw.println(); pw.print(" keepClearAreas="); Loading Loading @@ -5453,12 +5456,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } void updateKeepClearAreas() { final List<Rect> restrictedKeepClearAreas = new ArrayList(); final List<Rect> unrestrictedKeepClearAreas = new ArrayList(); final Set<Rect> restrictedKeepClearAreas = new ArraySet<>(); final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>(); getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas); if (!mRestrictedKeepClearAreas.equals(restrictedKeepClearAreas) || !mUnrestrictedKeepClearAreas.equals(unrestrictedKeepClearAreas)) { mRestrictedKeepClearAreas = restrictedKeepClearAreas; mUnrestrictedKeepClearAreas = unrestrictedKeepClearAreas; mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged( this, restrictedKeepClearAreas, unrestrictedKeepClearAreas); } } /** * Fills {@param outRestricted} with all keep-clear areas from visible, relevant windows Loading @@ -5469,7 +5478,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * For context on restricted vs unrestricted keep-clear areas, see * {@link android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS}. */ void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) { void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) { final Matrix tmpMatrix = new Matrix(); final float[] tmpFloat9 = new float[9]; forAllWindows(w -> { Loading @@ -5486,8 +5495,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** * Returns all keep-clear areas from visible, relevant windows on this display. */ ArrayList<Rect> getKeepClearAreas() { final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>(); Set<Rect> getKeepClearAreas() { final Set<Rect> keepClearAreas = new ArraySet<>(); getKeepClearAreas(keepClearAreas, keepClearAreas); return keepClearAreas; } Loading