diff options
9 files changed, 78 insertions, 24 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index 6d4773bdeb1f..c0734e95ecb7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -112,11 +112,17 @@ public interface Pip { default void showPictureInPictureMenu() {} /** - * Called by NavigationBar in order to listen in for PiP bounds change. This is mostly used - * for times where the PiP bounds could conflict with SystemUI elements, such as a stashed - * PiP and the Back-from-Edge gesture. + * Called by NavigationBar and TaskbarDelegate in order to listen in for PiP bounds change. This + * is mostly used for times where the PiP bounds could conflict with SystemUI elements, such as + * a stashed PiP and the Back-from-Edge gesture. */ - default void setPipExclusionBoundsChangeListener(Consumer<Rect> listener) { } + default void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) { } + + /** + * Remove a callback added previously. This is used when NavigationBar is removed from the + * view hierarchy or destroyed. + */ + default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { } /** * Dump the current state and information if need. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java index e3674dc920d5..b3558ad4b91e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java @@ -38,6 +38,8 @@ import com.android.wm.shell.common.DisplayLayout; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.function.Consumer; @@ -89,7 +91,7 @@ public final class PipBoundsState { private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; - private @Nullable Consumer<Rect> mOnPipExclusionBoundsChangeCallback; + private List<Consumer<Rect>> mOnPipExclusionBoundsChangeCallbacks = new ArrayList<>(); public PipBoundsState(@NonNull Context context) { mContext = context; @@ -108,8 +110,8 @@ public final class PipBoundsState { /** Set the current PIP bounds. */ public void setBounds(@NonNull Rect bounds) { mBounds.set(bounds); - if (mOnPipExclusionBoundsChangeCallback != null) { - mOnPipExclusionBoundsChangeCallback.accept(bounds); + for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) { + callback.accept(bounds); } } @@ -407,17 +409,25 @@ public final class PipBoundsState { } /** - * Set a callback to watch out for PiP bounds. This is mostly used by SystemUI's + * Add a callback to watch out for PiP bounds. This is mostly used by SystemUI's * Back-gesture handler, to avoid conflicting with PiP when it's stashed. */ - public void setPipExclusionBoundsChangeCallback( + public void addPipExclusionBoundsChangeCallback( @Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) { - mOnPipExclusionBoundsChangeCallback = onPipExclusionBoundsChangeCallback; - if (mOnPipExclusionBoundsChangeCallback != null) { - mOnPipExclusionBoundsChangeCallback.accept(getBounds()); + mOnPipExclusionBoundsChangeCallbacks.add(onPipExclusionBoundsChangeCallback); + for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) { + callback.accept(getBounds()); } } + /** + * Remove a callback that was previously added. + */ + public void removePipExclusionBoundsChangeCallback( + @Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) { + mOnPipExclusionBoundsChangeCallbacks.remove(onPipExclusionBoundsChangeCallback); + } + /** Source of truth for the current bounds of PIP that may be in motion. */ public static class MotionBoundsState { /** The bounds used when PIP is in motion (e.g. during a drag or animation) */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 26fd962ea6c5..a41fd8429e35 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -843,9 +843,16 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void setPipExclusionBoundsChangeListener(Consumer<Rect> listener) { + public void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) { mMainExecutor.execute(() -> { - mPipBoundsState.setPipExclusionBoundsChangeCallback(listener); + mPipBoundsState.addPipExclusionBoundsChangeCallback(listener); + }); + } + + @Override + public void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { + mMainExecutor.execute(() -> { + mPipBoundsState.removePipExclusionBoundsChangeCallback(listener); }); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java index a6215d3347a8..8e30f65cee78 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java @@ -188,7 +188,7 @@ public class PipBoundsStateTest extends ShellTestCase { final Rect newBounds = new Rect(50, 50, 100, 75); mPipBoundsState.setBounds(currentBounds); - mPipBoundsState.setPipExclusionBoundsChangeCallback(callback); + mPipBoundsState.addPipExclusionBoundsChangeCallback(callback); // Setting the listener immediately calls back with the current bounds. verify(callback).accept(currentBounds); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 7a12ecc097a2..963576bc7dc2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -628,7 +628,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener); - mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener); + mPipOptional.ifPresent(mNavigationBarView::addPipExclusionBoundsChangeListener); prepareNavigationBarView(); checkNavBarModes(); @@ -699,6 +699,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mHandler.removeCallbacks(mOnVariableDurationHomeLongClick); mHandler.removeCallbacks(mEnableLayoutTransitions); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mPipOptional.ifPresent(mNavigationBarView::removePipExclusionBoundsChangeListener); mFrame = null; mNavigationBarView = null; mOrientationHandle = null; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index bfabf716803b..a984974c6bba 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -59,9 +59,11 @@ import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.wm.shell.pip.Pip; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Optional; import javax.inject.Inject; @@ -106,7 +108,8 @@ public class NavigationBarController implements NavigationBar.Factory navigationBarFactory, DumpManager dumpManager, AutoHideController autoHideController, - LightBarController lightBarController) { + LightBarController lightBarController, + Optional<Pip> pipOptional) { mContext = context; mHandler = mainHandler; mNavigationBarFactory = navigationBarFactory; @@ -118,7 +121,7 @@ public class NavigationBarController implements mTaskbarDelegate = taskbarDelegate; mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService, navBarHelper, navigationModeController, sysUiFlagsContainer, - dumpManager, autoHideController, lightBarController); + dumpManager, autoHideController, lightBarController, pipOptional); mIsTablet = isTablet(mContext); dumpManager.registerDumpable(this); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 7c8c3e0dce44..7adb7ac92dc1 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -75,12 +75,12 @@ import com.android.systemui.navigationbar.buttons.KeyButtonDrawable; import com.android.systemui.navigationbar.buttons.NearestTouchFrame; import com.android.systemui.navigationbar.buttons.RotationContextButton; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; -import com.android.systemui.shared.rotation.FloatingRotationButton; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.shared.navigationbar.RegionSamplingHelper; +import com.android.systemui.shared.rotation.FloatingRotationButton; import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback; import com.android.systemui.shared.rotation.RotationButtonController; -import com.android.systemui.shared.navigationbar.RegionSamplingHelper; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; @@ -1386,8 +1386,12 @@ public class NavigationBarView extends FrameLayout implements legacySplitScreen.registerInSplitScreenListener(mDockedListener); } - void registerPipExclusionBoundsChangeListener(Pip pip) { - pip.setPipExclusionBoundsChangeListener(mPipListener); + void addPipExclusionBoundsChangeListener(Pip pip) { + pip.addPipExclusionBoundsChangeListener(mPipListener); + } + + void removePipExclusionBoundsChangeListener(Pip pip) { + pip.removePipExclusionBoundsChangeListener(mPipListener); } private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 68f4aeaa7f17..feda99fd3471 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -40,6 +40,7 @@ import android.app.StatusBarManager.WindowVisibleState; import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; +import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.inputmethodservice.InputMethodService; import android.os.IBinder; @@ -68,9 +69,12 @@ import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarTransitionsController; +import com.android.wm.shell.pip.Pip; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Optional; +import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Singleton; @@ -91,6 +95,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, private AutoHideController mAutoHideController; private LightBarController mLightBarController; private LightBarTransitionsController mLightBarTransitionsController; + private Optional<Pip> mPipOptional; private int mDisplayId; private int mNavigationIconHints; private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater = @@ -113,6 +118,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, private Context mWindowContext; private ScreenPinningNotify mScreenPinningNotify; private int mNavigationMode; + private final Consumer<Rect> mPipListener; /** * Tracks the system calls for when taskbar should transiently show or hide so we can return @@ -143,6 +149,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, .create(context); mContext = context; mDisplayManager = mContext.getSystemService(DisplayManager.class); + mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds; } public void setDependencies(CommandQueue commandQueue, @@ -151,7 +158,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, NavigationModeController navigationModeController, SysUiState sysUiState, DumpManager dumpManager, AutoHideController autoHideController, - LightBarController lightBarController) { + LightBarController lightBarController, + Optional<Pip> pipOptional) { // TODO: adding this in the ctor results in a dagger dependency cycle :( mCommandQueue = commandQueue; mOverviewProxyService = overviewProxyService; @@ -162,6 +170,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mAutoHideController = autoHideController; mLightBarController = lightBarController; mLightBarTransitionsController = createLightBarTransitionsController(); + mPipOptional = pipOptional; } // Separated into a method to keep setDependencies() clean/readable. @@ -207,6 +216,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, updateSysuiFlags(); mAutoHideController.setNavigationBar(mAutoHideUiElement); mLightBarController.setNavigationBar(mLightBarTransitionsController); + mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener); mInitialized = true; } @@ -228,9 +238,18 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mAutoHideController.setNavigationBar(null); mLightBarTransitionsController.destroy(mContext); mLightBarController.setNavigationBar(null); + mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener); mInitialized = false; } + void addPipExclusionBoundsChangeListener(Pip pip) { + pip.addPipExclusionBoundsChangeListener(mPipListener); + } + + void removePipExclusionBoundsChangeListener(Pip pip) { + pip.removePipExclusionBoundsChangeListener(mPipListener); + } + /** * Returns {@code true} if this taskBar is {@link #init(int)}. Returns {@code false} if this * taskbar has not yet been {@link #init(int)} or has been {@link #destroy()}. diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java index 9d2541c0150f..3e8e8748a679 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java @@ -47,6 +47,7 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.wm.shell.pip.Pip; import org.junit.After; import org.junit.Before; @@ -55,6 +56,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; + /** atest NavigationBarControllerTest */ @RunWith(AndroidTestingRunner.class) @RunWithLooper @@ -88,7 +91,8 @@ public class NavigationBarControllerTest extends SysuiTestCase { mNavigationBarFactory, mock(DumpManager.class), mock(AutoHideController.class), - mock(LightBarController.class))); + mock(LightBarController.class), + Optional.of(mock(Pip.class)))); initializeNavigationBars(); } |