Merge "Update PiP exclusion bounds in TaskBarDelegate." into sc-v2-dev

This commit is contained in:
Ben Lin
2021-12-14 20:49:06 +00:00
committed by Android (Google) Code Review
9 changed files with 78 additions and 24 deletions

View File

@@ -112,11 +112,17 @@ public interface Pip {
default void showPictureInPictureMenu() {} default void showPictureInPictureMenu() {}
/** /**
* Called by NavigationBar in order to listen in for PiP bounds change. This is mostly used * Called by NavigationBar and TaskbarDelegate in order to listen in for PiP bounds change. This
* for times where the PiP bounds could conflict with SystemUI elements, such as a stashed * is mostly used for times where the PiP bounds could conflict with SystemUI elements, such as
* PiP and the Back-from-Edge gesture. * 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. * Dump the current state and information if need.

View File

@@ -38,6 +38,8 @@ import com.android.wm.shell.common.DisplayLayout;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -89,7 +91,7 @@ public final class PipBoundsState {
private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable Runnable mOnMinimalSizeChangeCallback;
private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback;
private @Nullable Consumer<Rect> mOnPipExclusionBoundsChangeCallback; private List<Consumer<Rect>> mOnPipExclusionBoundsChangeCallbacks = new ArrayList<>();
public PipBoundsState(@NonNull Context context) { public PipBoundsState(@NonNull Context context) {
mContext = context; mContext = context;
@@ -108,8 +110,8 @@ public final class PipBoundsState {
/** Set the current PIP bounds. */ /** Set the current PIP bounds. */
public void setBounds(@NonNull Rect bounds) { public void setBounds(@NonNull Rect bounds) {
mBounds.set(bounds); mBounds.set(bounds);
if (mOnPipExclusionBoundsChangeCallback != null) { for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) {
mOnPipExclusionBoundsChangeCallback.accept(bounds); 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. * Back-gesture handler, to avoid conflicting with PiP when it's stashed.
*/ */
public void setPipExclusionBoundsChangeCallback( public void addPipExclusionBoundsChangeCallback(
@Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) { @Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) {
mOnPipExclusionBoundsChangeCallback = onPipExclusionBoundsChangeCallback; mOnPipExclusionBoundsChangeCallbacks.add(onPipExclusionBoundsChangeCallback);
if (mOnPipExclusionBoundsChangeCallback != null) { for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) {
mOnPipExclusionBoundsChangeCallback.accept(getBounds()); 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. */ /** Source of truth for the current bounds of PIP that may be in motion. */
public static class MotionBoundsState { public static class MotionBoundsState {
/** The bounds used when PIP is in motion (e.g. during a drag or animation) */ /** The bounds used when PIP is in motion (e.g. during a drag or animation) */

View File

@@ -843,9 +843,16 @@ public class PipController implements PipTransitionController.PipTransitionCallb
} }
@Override @Override
public void setPipExclusionBoundsChangeListener(Consumer<Rect> listener) { public void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) {
mMainExecutor.execute(() -> { mMainExecutor.execute(() -> {
mPipBoundsState.setPipExclusionBoundsChangeCallback(listener); mPipBoundsState.addPipExclusionBoundsChangeCallback(listener);
});
}
@Override
public void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) {
mMainExecutor.execute(() -> {
mPipBoundsState.removePipExclusionBoundsChangeCallback(listener);
}); });
} }

View File

@@ -188,7 +188,7 @@ public class PipBoundsStateTest extends ShellTestCase {
final Rect newBounds = new Rect(50, 50, 100, 75); final Rect newBounds = new Rect(50, 50, 100, 75);
mPipBoundsState.setBounds(currentBounds); mPipBoundsState.setBounds(currentBounds);
mPipBoundsState.setPipExclusionBoundsChangeCallback(callback); mPipBoundsState.addPipExclusionBoundsChangeCallback(callback);
// Setting the listener immediately calls back with the current bounds. // Setting the listener immediately calls back with the current bounds.
verify(callback).accept(currentBounds); verify(callback).accept(currentBounds);

View File

@@ -628,7 +628,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener); mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener); mPipOptional.ifPresent(mNavigationBarView::addPipExclusionBoundsChangeListener);
prepareNavigationBarView(); prepareNavigationBarView();
checkNavBarModes(); checkNavBarModes();
@@ -699,6 +699,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mHandler.removeCallbacks(mOnVariableDurationHomeLongClick); mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
mHandler.removeCallbacks(mEnableLayoutTransitions); mHandler.removeCallbacks(mEnableLayoutTransitions);
mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mPipOptional.ifPresent(mNavigationBarView::removePipExclusionBoundsChangeListener);
mFrame = null; mFrame = null;
mNavigationBarView = null; mNavigationBarView = null;
mOrientationHandle = null; mOrientationHandle = null;

View File

@@ -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.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.wm.shell.pip.Pip;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
@@ -106,7 +108,8 @@ public class NavigationBarController implements
NavigationBar.Factory navigationBarFactory, NavigationBar.Factory navigationBarFactory,
DumpManager dumpManager, DumpManager dumpManager,
AutoHideController autoHideController, AutoHideController autoHideController,
LightBarController lightBarController) { LightBarController lightBarController,
Optional<Pip> pipOptional) {
mContext = context; mContext = context;
mHandler = mainHandler; mHandler = mainHandler;
mNavigationBarFactory = navigationBarFactory; mNavigationBarFactory = navigationBarFactory;
@@ -118,7 +121,7 @@ public class NavigationBarController implements
mTaskbarDelegate = taskbarDelegate; mTaskbarDelegate = taskbarDelegate;
mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService, mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
navBarHelper, navigationModeController, sysUiFlagsContainer, navBarHelper, navigationModeController, sysUiFlagsContainer,
dumpManager, autoHideController, lightBarController); dumpManager, autoHideController, lightBarController, pipOptional);
mIsTablet = isTablet(mContext); mIsTablet = isTablet(mContext);
dumpManager.registerDumpable(this); dumpManager.registerDumpable(this);
} }

View File

@@ -75,12 +75,12 @@ import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import com.android.systemui.navigationbar.buttons.NearestTouchFrame; import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
import com.android.systemui.navigationbar.buttons.RotationContextButton; import com.android.systemui.navigationbar.buttons.RotationContextButton;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; 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.OverviewProxyService;
import com.android.systemui.recents.Recents; 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.RotationButton.RotationButtonUpdatesCallback;
import com.android.systemui.shared.rotation.RotationButtonController; 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.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.SysUiStatsLog;
@@ -1386,8 +1386,12 @@ public class NavigationBarView extends FrameLayout implements
legacySplitScreen.registerInSplitScreenListener(mDockedListener); legacySplitScreen.registerInSplitScreenListener(mDockedListener);
} }
void registerPipExclusionBoundsChangeListener(Pip pip) { void addPipExclusionBoundsChangeListener(Pip pip) {
pip.setPipExclusionBoundsChangeListener(mPipListener); pip.addPipExclusionBoundsChangeListener(mPipListener);
}
void removePipExclusionBoundsChangeListener(Pip pip) {
pip.removePipExclusionBoundsChangeListener(mPipListener);
} }
private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) { private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {

View File

@@ -40,6 +40,7 @@ import android.app.StatusBarManager.WindowVisibleState;
import android.content.ComponentCallbacks; import android.content.ComponentCallbacks;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.IBinder; 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.BarTransitions;
import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController; import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.wm.shell.pip.Pip;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Optional;
import java.util.function.Consumer;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -91,6 +95,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
private AutoHideController mAutoHideController; private AutoHideController mAutoHideController;
private LightBarController mLightBarController; private LightBarController mLightBarController;
private LightBarTransitionsController mLightBarTransitionsController; private LightBarTransitionsController mLightBarTransitionsController;
private Optional<Pip> mPipOptional;
private int mDisplayId; private int mDisplayId;
private int mNavigationIconHints; private int mNavigationIconHints;
private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater = private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
@@ -113,6 +118,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
private Context mWindowContext; private Context mWindowContext;
private ScreenPinningNotify mScreenPinningNotify; private ScreenPinningNotify mScreenPinningNotify;
private int mNavigationMode; private int mNavigationMode;
private final Consumer<Rect> mPipListener;
/** /**
* Tracks the system calls for when taskbar should transiently show or hide so we can return * 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); .create(context);
mContext = context; mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class); mDisplayManager = mContext.getSystemService(DisplayManager.class);
mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds;
} }
public void setDependencies(CommandQueue commandQueue, public void setDependencies(CommandQueue commandQueue,
@@ -151,7 +158,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
NavigationModeController navigationModeController, NavigationModeController navigationModeController,
SysUiState sysUiState, DumpManager dumpManager, SysUiState sysUiState, DumpManager dumpManager,
AutoHideController autoHideController, AutoHideController autoHideController,
LightBarController lightBarController) { LightBarController lightBarController,
Optional<Pip> pipOptional) {
// TODO: adding this in the ctor results in a dagger dependency cycle :( // TODO: adding this in the ctor results in a dagger dependency cycle :(
mCommandQueue = commandQueue; mCommandQueue = commandQueue;
mOverviewProxyService = overviewProxyService; mOverviewProxyService = overviewProxyService;
@@ -162,6 +170,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
mAutoHideController = autoHideController; mAutoHideController = autoHideController;
mLightBarController = lightBarController; mLightBarController = lightBarController;
mLightBarTransitionsController = createLightBarTransitionsController(); mLightBarTransitionsController = createLightBarTransitionsController();
mPipOptional = pipOptional;
} }
// Separated into a method to keep setDependencies() clean/readable. // Separated into a method to keep setDependencies() clean/readable.
@@ -207,6 +216,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
updateSysuiFlags(); updateSysuiFlags();
mAutoHideController.setNavigationBar(mAutoHideUiElement); mAutoHideController.setNavigationBar(mAutoHideUiElement);
mLightBarController.setNavigationBar(mLightBarTransitionsController); mLightBarController.setNavigationBar(mLightBarTransitionsController);
mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener);
mInitialized = true; mInitialized = true;
} }
@@ -228,9 +238,18 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
mAutoHideController.setNavigationBar(null); mAutoHideController.setNavigationBar(null);
mLightBarTransitionsController.destroy(mContext); mLightBarTransitionsController.destroy(mContext);
mLightBarController.setNavigationBar(null); mLightBarController.setNavigationBar(null);
mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
mInitialized = false; 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 * 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()}. * taskbar has not yet been {@link #init(int)} or has been {@link #destroy()}.

View File

@@ -47,6 +47,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.wm.shell.pip.Pip;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -55,6 +56,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.Optional;
/** atest NavigationBarControllerTest */ /** atest NavigationBarControllerTest */
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@RunWithLooper @RunWithLooper
@@ -88,7 +91,8 @@ public class NavigationBarControllerTest extends SysuiTestCase {
mNavigationBarFactory, mNavigationBarFactory,
mock(DumpManager.class), mock(DumpManager.class),
mock(AutoHideController.class), mock(AutoHideController.class),
mock(LightBarController.class))); mock(LightBarController.class),
Optional.of(mock(Pip.class))));
initializeNavigationBars(); initializeNavigationBars();
} }