diff options
| author | 2023-04-21 01:00:42 +0000 | |
|---|---|---|
| committer | 2023-04-21 01:00:42 +0000 | |
| commit | 331d9987bc024d76dc35d308ea5b3222f52d681c (patch) | |
| tree | 7cbc344e36e4e9d91cb805919dcb8e0a28dd7bbf | |
| parent | 1c9c183adb511d8b5535cfbaf67efdf1f37fec0e (diff) | |
| parent | c5dfdd152061f6e766c47e14a4df50c9fad791a2 (diff) | |
Merge "Prevent desktop mode corner handles from triggering back gesture." into udc-dev
10 files changed, 251 insertions, 16 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java index cbd544cc4b86..e732a0354806 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java @@ -16,9 +16,12 @@ package com.android.wm.shell.desktopmode; +import android.graphics.Region; + import com.android.wm.shell.common.annotations.ExternalThread; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * Interface to interact with desktop mode feature in shell. @@ -32,7 +35,16 @@ public interface DesktopMode { * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ - void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, + void addVisibleTasksListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor); + /** + * Adds a consumer to listen for Desktop task corner changes. This is used for gesture + * exclusion. The SparseArray contains a list of four corner resize handles mapped to each + * desktop task's taskId. The resize handle Rects are stored in the following order: + * left-top, left-bottom, right-top, right-bottom. + */ + default void addDesktopGestureExclusionRegionListener(Consumer<Region> listener, + Executor callbackExecutor) { } + } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java index 2bdbde1b71d4..86ea72582a52 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java @@ -34,6 +34,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; +import android.graphics.Region; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -69,6 +70,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * Handles windowing changes when desktop mode system setting changes @@ -149,11 +151,21 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ - public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, + public void addVisibleTasksListener(DesktopModeTaskRepository.VisibleTasksListener listener, Executor callbackExecutor) { mDesktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor); } + /** + * Adds a listener to track changes to corners of desktop mode tasks. + * @param listener the listener to add. + * @param callbackExecutor the executor to call the listener on. + */ + public void addTaskCornerListener(Consumer<Region> listener, + Executor callbackExecutor) { + mDesktopModeTaskRepository.setTaskCornerListener(listener, callbackExecutor); + } + @VisibleForTesting void updateDesktopModeActive(boolean active) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active); @@ -312,6 +324,23 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll } /** + * Update corner rects stored for a specific task + * @param taskId task to update + * @param taskCorners task's new corner handles + */ + public void onTaskCornersChanged(int taskId, Region taskCorners) { + mDesktopModeTaskRepository.updateTaskCorners(taskId, taskCorners); + } + + /** + * Remove corners saved for a task. Likely used due to task closure. + * @param taskId task to remove + */ + public void removeCornersForTask(int taskId) { + mDesktopModeTaskRepository.removeTaskCorners(taskId); + } + + /** * Moves a specifc task to the front. * @param taskInfo the task to show in front. */ @@ -426,10 +455,19 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll private final class DesktopModeImpl implements DesktopMode { @Override - public void addListener(DesktopModeTaskRepository.VisibleTasksListener listener, + public void addVisibleTasksListener( + DesktopModeTaskRepository.VisibleTasksListener listener, + Executor callbackExecutor) { + mMainExecutor.execute(() -> { + DesktopModeController.this.addVisibleTasksListener(listener, callbackExecutor); + }); + } + + @Override + public void addDesktopGestureExclusionRegionListener(Consumer<Region> listener, Executor callbackExecutor) { mMainExecutor.execute(() -> { - DesktopModeController.this.addListener(listener, callbackExecutor); + DesktopModeController.this.addTaskCornerListener(listener, callbackExecutor); }); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt index 47342c9f21ee..12f8ea23ac8f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt @@ -16,9 +16,13 @@ package com.android.wm.shell.desktopmode +import android.graphics.Region import android.util.ArrayMap import android.util.ArraySet +import android.util.SparseArray +import androidx.core.util.valueIterator import java.util.concurrent.Executor +import java.util.function.Consumer /** * Keeps track of task data related to desktop mode. @@ -38,6 +42,10 @@ class DesktopModeTaskRepository { private val activeTasksListeners = ArraySet<ActiveTasksListener>() // Track visible tasks separately because a task may be part of the desktop but not visible. private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>() + // Track corners of desktop tasks, used to determine gesture exclusion + private val desktopCorners = SparseArray<Region>() + private var desktopGestureExclusionListener: Consumer<Region>? = null + private var desktopGestureExclusionExecutor: Executor? = null /** * Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. @@ -56,6 +64,28 @@ class DesktopModeTaskRepository { } /** + * Add a Consumer which will inform other classes of changes to corners for all Desktop tasks. + */ + fun setTaskCornerListener(cornersListener: Consumer<Region>, executor: Executor) { + desktopGestureExclusionListener = cornersListener + desktopGestureExclusionExecutor = executor + executor.execute { + desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion()) + } + } + + /** + * Create a new merged region representative of all corners in all desktop tasks. + */ + private fun calculateDesktopExclusionRegion(): Region { + val desktopCornersRegion = Region() + desktopCorners.valueIterator().forEach { taskCorners -> + desktopCornersRegion.op(taskCorners, Region.Op.UNION) + } + return desktopCornersRegion + } + + /** * Remove a previously registered [ActiveTasksListener] */ fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) { @@ -167,6 +197,28 @@ class DesktopModeTaskRepository { } /** + * Updates the active desktop corners; if desktopCorners has been accepted by + * desktopCornersListener, it will be updated in the appropriate classes. + */ + fun updateTaskCorners(taskId: Int, taskCorners: Region) { + desktopCorners.put(taskId, taskCorners) + desktopGestureExclusionExecutor?.execute { + desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion()) + } + } + + /** + * Removes the active desktop corners for the specified task; if desktopCorners has been + * accepted by desktopCornersListener, it will be updated in the appropriate classes. + */ + fun removeTaskCorners(taskId: Int) { + desktopCorners.delete(taskId) + desktopGestureExclusionExecutor?.execute { + desktopGestureExclusionListener?.accept(calculateDesktopExclusionRegion()) + } + } + + /** * Defines interface for classes that can listen to changes for active tasks in desktop mode. */ interface ActiveTasksListener { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 0400963a47e8..0d5602365578 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -27,6 +27,7 @@ import android.app.WindowConfiguration.WindowingMode import android.content.Context import android.graphics.Point import android.graphics.Rect +import android.graphics.Region import android.os.IBinder import android.os.SystemProperties import android.view.SurfaceControl @@ -487,6 +488,20 @@ class DesktopTasksController( return 2 * getStatusBarHeight(taskInfo) } + /** + * Update the corner region for a specified task + */ + fun onTaskCornersChanged(taskId: Int, corner: Region) { + desktopModeTaskRepository.updateTaskCorners(taskId, corner) + } + + /** + * Remove a previously tracked corner region for a specified task. + */ + fun removeCornersForTask(taskId: Int) { + desktopModeTaskRepository.removeTaskCorners(taskId) + } + /** * Adds a listener to find out about changes in the visibility of freeform tasks. @@ -494,20 +509,47 @@ class DesktopTasksController( * @param listener the listener to add. * @param callbackExecutor the executor to call the listener on. */ - fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) { + fun addVisibleTasksListener(listener: VisibleTasksListener, callbackExecutor: Executor) { desktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor) } + /** + * Adds a listener to track changes to desktop task corners + * + * @param listener the listener to add. + * @param callbackExecutor the executor to call the listener on. + */ + fun setTaskCornerListener( + listener: Consumer<Region>, + callbackExecutor: Executor + ) { + desktopModeTaskRepository.setTaskCornerListener(listener, callbackExecutor) + } + /** The interface for calls from outside the shell, within the host process. */ @ExternalThread private inner class DesktopModeImpl : DesktopMode { - override fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) { + override fun addVisibleTasksListener( + listener: VisibleTasksListener, + callbackExecutor: Executor + ) { mainExecutor.execute { - this@DesktopTasksController.addListener(listener, callbackExecutor) + this@DesktopTasksController.addVisibleTasksListener(listener, callbackExecutor) + } + } + + override fun addDesktopGestureExclusionRegionListener( + listener: Consumer<Region>, + callbackExecutor: Executor + ) { + mainExecutor.execute { + this@DesktopTasksController.setTaskCornerListener(listener, callbackExecutor) } } } + + /** The interface for calls from outside the host process. */ @BinderThread private class IDesktopModeImpl(private var controller: DesktopTasksController?) : diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 49a5eac5fd07..8fb56fc2561b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -36,6 +36,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.Region; import android.hardware.input.InputManager; import android.os.Handler; import android.os.IBinder; @@ -69,6 +70,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.transition.Transitions; +import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.TaskCornersListener; import java.util.Optional; import java.util.function.Supplier; @@ -95,9 +97,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>(); + private final TaskCornersListener mCornersListener = new TaskCornersListenerImpl(); + private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId = new SparseArray<>(); - private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl(); + private final DragListenerImpl mDragStartListener = new DragListenerImpl(); private final InputMonitorFactory mInputMonitorFactory; private TaskOperations mTaskOperations; private final Supplier<SurfaceControl.Transaction> mTransactionFactory; @@ -779,6 +783,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeTouchEventListener touchEventListener = new DesktopModeTouchEventListener(taskInfo, taskPositioner); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); + windowDecoration.setCornersListener(mCornersListener); windowDecoration.setDragPositioningCallback(taskPositioner); windowDecoration.setDragDetector(touchEventListener.mDragDetector); windowDecoration.relayout(taskInfo, startT, finishT, @@ -786,7 +791,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { incrementEventReceiverTasks(taskInfo.displayId); } - private class DragStartListenerImpl implements TaskPositioner.DragStartListener { + private class DragListenerImpl implements TaskPositioner.DragStartListener { @Override public void onDragStart(int taskId) { mWindowDecorByTaskId.get(taskId).closeHandleMenu(); @@ -798,6 +803,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { return inputManager.monitorGestureInput("caption-touch", context.getDisplayId()); } } + + private class TaskCornersListenerImpl + implements DesktopModeWindowDecoration.TaskCornersListener { + + @Override + public void onTaskCornersChanged(int taskId, Region corner) { + mDesktopModeController.ifPresent(d -> d.onTaskCornersChanged(taskId, corner)); + mDesktopTasksController.ifPresent(d -> d.onTaskCornersChanged(taskId, corner)); + } + + @Override + public void onTaskCornersRemoved(int taskId) { + mDesktopModeController.ifPresent(d -> d.removeCornersForTask(taskId)); + mDesktopTasksController.ifPresent(d -> d.removeCornersForTask(taskId)); + } + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index af3fb0ead55c..619e963aaea6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -30,6 +30,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; +import android.graphics.Region; import android.graphics.drawable.Drawable; import android.os.Handler; import android.util.Log; @@ -80,6 +81,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult = new WindowDecoration.RelayoutResult<>(); + private final Point mPositionInParent = new Point(); private final PointF mHandleMenuAppInfoPillPosition = new PointF(); private final PointF mHandleMenuWindowingPillPosition = new PointF(); private final PointF mHandleMenuMoreActionsPillPosition = new PointF(); @@ -92,6 +94,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private Drawable mAppIcon; private CharSequence mAppName; + private TaskCornersListener mCornersListener; + private int mMenuWidth; private int mMarginMenuTop; private int mMarginMenuStart; @@ -161,6 +165,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionTouchListener = onCaptionTouchListener; } + void setCornersListener(TaskCornersListener cornersListener) { + mCornersListener = cornersListener; + } + void setDragPositioningCallback(DragPositioningCallback dragPositioningCallback) { mDragPositioningCallback = dragPositioningCallback; } @@ -278,8 +286,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin .getDimensionPixelSize(R.dimen.freeform_resize_handle); final int resize_corner = mResult.mRootView.getResources() .getDimensionPixelSize(R.dimen.freeform_resize_corner); - mDragResizeListener.setGeometry( - mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop); + + // If either task geometry or position have changed, update this task's cornersListener + if (mDragResizeListener.setGeometry( + mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop) + || !mTaskInfo.positionInParent.equals(mPositionInParent)) { + mCornersListener.onTaskCornersChanged(mTaskInfo.taskId, getGlobalCornersRegion()); + } + mPositionInParent.set(mTaskInfo.positionInParent); } boolean isHandleMenuActive() { @@ -586,6 +600,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin public void close() { closeDragResizeListener(); closeHandleMenu(); + mCornersListener.onTaskCornersRemoved(mTaskInfo.taskId); super.close(); } @@ -598,6 +613,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin : R.layout.desktop_mode_focused_window_decor; } + /** + * Create a new region out of the corner rects of this task. + */ + Region getGlobalCornersRegion() { + Region cornersRegion = mDragResizeListener.getCornersRegion(); + cornersRegion.translate(mPositionInParent.x, mPositionInParent.y); + return cornersRegion; + } + static class Factory { DesktopModeWindowDecoration create( @@ -620,4 +644,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin syncQueue); } } + + interface TaskCornersListener { + /** Inform the implementing class of this task's change in corner resize handles */ + void onTaskCornersChanged(int taskId, Region corner); + + /** Inform the implementing class that this task no longer needs its corners tracked, + * likely due to it closing. */ + void onTaskCornersRemoved(int taskId); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java index d5437c72acac..34c8c087cf95 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java @@ -134,13 +134,14 @@ class DragResizeInputListener implements AutoCloseable { * @param cornerSize The size of the resize handle centered in each corner. * @param touchSlop The distance in pixels user has to drag with touch for it to register as * a resize action. + * @return whether the geometry has changed or not */ - void setGeometry(int taskWidth, int taskHeight, int resizeHandleThickness, int cornerSize, + boolean setGeometry(int taskWidth, int taskHeight, int resizeHandleThickness, int cornerSize, int touchSlop) { if (mTaskWidth == taskWidth && mTaskHeight == taskHeight && mResizeHandleThickness == resizeHandleThickness && mCornerSize == cornerSize) { - return; + return false; } mTaskWidth = taskWidth; @@ -220,6 +221,19 @@ class DragResizeInputListener implements AutoCloseable { } catch (RemoteException e) { e.rethrowFromSystemServer(); } + return true; + } + + /** + * Generate a Region that encapsulates all 4 corner handles + */ + Region getCornersRegion() { + Region region = new Region(); + region.union(mLeftTopCornerBounds); + region.union(mLeftBottomCornerBounds); + region.union(mRightTopCornerBounds); + region.union(mRightBottomCornerBounds); + return region; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index b9ef916eebdf..41e3e6d83eea 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -89,6 +89,7 @@ import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto; import com.android.systemui.tracing.nano.SystemUiTraceProto; import com.android.systemui.util.Assert; import com.android.wm.shell.back.BackAnimation; +import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.pip.Pip; import java.io.PrintWriter; @@ -190,6 +191,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack private final WindowManager mWindowManager; private final IWindowManager mWindowManagerService; private final Optional<Pip> mPipOptional; + private final Optional<DesktopMode> mDesktopModeOptional; private final FalsingManager mFalsingManager; private final Configuration mLastReportedConfig = new Configuration(); // Activities which should not trigger Back gesture. @@ -204,6 +206,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack private final Rect mPipExcludedBounds = new Rect(); private final Rect mNavBarOverlayExcludedBounds = new Rect(); private final Region mExcludeRegion = new Region(); + private final Region mDesktopModeExcludeRegion = new Region(); private final Region mUnrestrictedExcludeRegion = new Region(); private final Provider<NavigationBarEdgePanel> mNavBarEdgePanelProvider; private final Provider<BackGestureTfClassifierProvider> @@ -328,6 +331,9 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack private final Consumer<Boolean> mOnIsInPipStateChangedListener = (isInPip) -> mIsInPip = isInPip; + private final Consumer<Region> mDesktopCornersChangedListener = + (desktopExcludeRegion) -> mDesktopModeExcludeRegion.set(desktopExcludeRegion); + private final UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() { @Override @@ -352,6 +358,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack WindowManager windowManager, IWindowManager windowManagerService, Optional<Pip> pipOptional, + Optional<DesktopMode> desktopModeOptional, FalsingManager falsingManager, Provider<NavigationBarEdgePanel> navigationBarEdgePanelProvider, Provider<BackGestureTfClassifierProvider> backGestureTfClassifierProviderProvider, @@ -372,6 +379,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack mWindowManager = windowManager; mWindowManagerService = windowManagerService; mPipOptional = pipOptional; + mDesktopModeOptional = desktopModeOptional; mFalsingManager = falsingManager; mNavBarEdgePanelProvider = navigationBarEdgePanelProvider; mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider; @@ -580,6 +588,9 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack mMainExecutor::execute, mOnPropertiesChangedListener); mPipOptional.ifPresent( pip -> pip.setOnIsInPipStateChangedListener(mOnIsInPipStateChangedListener)); + mDesktopModeOptional.ifPresent( + dm -> dm.addDesktopGestureExclusionRegionListener( + mDesktopCornersChangedListener, mMainExecutor)); try { mWindowManagerService.registerSystemGestureExclusionListener( @@ -802,11 +813,17 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack mDisplaySize.y - insets.bottom); } + private boolean desktopExcludeRegionContains(int x, int y) { + return mDesktopModeExcludeRegion.contains(x, y); + } + private boolean isWithinTouchRegion(int x, int y) { // If the point is inside the PiP or Nav bar overlay excluded bounds, then ignore the back // gesture final boolean isInsidePip = mIsInPip && mPipExcludedBounds.contains(x, y); - if (isInsidePip || mNavBarOverlayExcludedBounds.contains(x, y)) { + final boolean isInDesktopExcludeRegion = desktopExcludeRegionContains(x, y); + if (isInsidePip || isInDesktopExcludeRegion + || mNavBarOverlayExcludedBounds.contains(x, y)) { return false; } @@ -1136,6 +1153,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack pw.println(" mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion); pw.println(" mIsInPip=" + mIsInPip); pw.println(" mPipExcludedBounds=" + mPipExcludedBounds); + pw.println(" mDesktopModeExclusionRegion=" + mDesktopModeExcludeRegion); pw.println(" mNavBarOverlayExcludedBounds=" + mNavBarOverlayExcludedBounds); pw.println(" mEdgeWidthLeft=" + mEdgeWidthLeft); pw.println(" mEdgeWidthRight=" + mEdgeWidthRight); @@ -1206,6 +1224,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack private final WindowManager mWindowManager; private final IWindowManager mWindowManagerService; private final Optional<Pip> mPipOptional; + private final Optional<DesktopMode> mDesktopModeOptional; private final FalsingManager mFalsingManager; private final Provider<NavigationBarEdgePanel> mNavBarEdgePanelProvider; private final Provider<BackGestureTfClassifierProvider> @@ -1227,6 +1246,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack WindowManager windowManager, IWindowManager windowManagerService, Optional<Pip> pipOptional, + Optional<DesktopMode> desktopModeOptional, FalsingManager falsingManager, Provider<NavigationBarEdgePanel> navBarEdgePanelProvider, Provider<BackGestureTfClassifierProvider> @@ -1246,6 +1266,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack mWindowManager = windowManager; mWindowManagerService = windowManagerService; mPipOptional = pipOptional; + mDesktopModeOptional = desktopModeOptional; mFalsingManager = falsingManager; mNavBarEdgePanelProvider = navBarEdgePanelProvider; mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider; @@ -1270,6 +1291,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack mWindowManager, mWindowManagerService, mPipOptional, + mDesktopModeOptional, mFalsingManager, mNavBarEdgePanelProvider, mBackGestureTfClassifierProviderProvider, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index e492534b3ff6..b3e7cb0c77eb 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -345,7 +345,8 @@ public final class WMShell implements } void initDesktopMode(DesktopMode desktopMode) { - desktopMode.addListener(new DesktopModeTaskRepository.VisibleTasksListener() { + desktopMode.addVisibleTasksListener( + new DesktopModeTaskRepository.VisibleTasksListener() { @Override public void onVisibilityChanged(boolean hasFreeformTasks) { mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, hasFreeformTasks) diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 8cae99893496..9de7a87c8b82 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -128,7 +128,7 @@ public class WMShellTest extends SysuiTestCase { @Test public void initDesktopMode_registersListener() { mWMShell.initDesktopMode(mDesktopMode); - verify(mDesktopMode).addListener( + verify(mDesktopMode).addVisibleTasksListener( any(DesktopModeTaskRepository.VisibleTasksListener.class), any(Executor.class)); } |