summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vinit Nayak <peanutbutter@google.com> 2024-05-07 18:12:00 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-05-07 18:12:00 +0000
commitdbf456427983fed124f23ee68d1566963c424db3 (patch)
tree59f0fa8285661e0aff53a5a7f2cd1667f4de8a11
parent03f260634761c7f741bb978124da1851a3cee27e (diff)
parente0bf32a0ee04110cc0c5bb7243bd42ca84d4bf63 (diff)
Merge "Disable recents gesture when split animation running in shell" into main
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java16
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java8
8 files changed, 108 insertions, 17 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 6aad4e2c9da4..8df287d12cbc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -69,7 +69,9 @@ public interface SplitScreen {
default void onSplitVisibilityChanged(boolean visible) {}
}
- /** Callback interface for listening to requests to enter split select */
+ /**
+ * Callback interface for listening to requests to enter split select. Used for desktop -> split
+ */
interface SplitSelectListener {
default boolean onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
@@ -90,6 +92,24 @@ public interface SplitScreen {
/** Unregisters listener that gets split screen callback. */
void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);
+ interface SplitInvocationListener {
+ /**
+ * Called whenever shell starts or stops the split screen animation
+ * @param animationRunning if {@code true} the animation has begun, if {@code false} the
+ * animation has finished
+ */
+ default void onSplitAnimationInvoked(boolean animationRunning) { }
+ }
+
+ /**
+ * Registers a {@link SplitInvocationListener} to notify when the animation to enter split
+ * screen has started and stopped
+ *
+ * @param executor callbacks to the listener will be executed on this executor
+ */
+ void registerSplitAnimationListener(@NonNull SplitInvocationListener listener,
+ @NonNull Executor executor);
+
/** Called when device waking up finished. */
void onFinishedWakingUp();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 547457b018a1..b9d70e1a599d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -1166,6 +1166,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
+ public void registerSplitAnimationListener(@NonNull SplitInvocationListener listener,
+ @NonNull Executor executor) {
+ mStageCoordinator.registerSplitAnimationListener(listener, executor);
+ }
+
+ @Override
public void onFinishedWakingUp() {
mMainExecutor.execute(SplitScreenController.this::onFinishedWakingUp);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 1a53a1d10dd2..6e5b7673e206 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -55,6 +55,7 @@ import com.android.wm.shell.transition.OneShotRemoteHandler;
import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
+import java.util.concurrent.Executor;
/** Manages transition animations for split-screen. */
class SplitScreenTransitions {
@@ -79,6 +80,8 @@ class SplitScreenTransitions {
private Transitions.TransitionFinishCallback mFinishCallback = null;
private SurfaceControl.Transaction mFinishTransaction;
+ private SplitScreen.SplitInvocationListener mSplitInvocationListener;
+ private Executor mSplitInvocationListenerExecutor;
SplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
@NonNull Runnable onFinishCallback, StageCoordinator stageCoordinator) {
@@ -353,6 +356,10 @@ class SplitScreenTransitions {
+ " skip to start enter split transition since it already exist. ");
return null;
}
+ if (mSplitInvocationListenerExecutor != null && mSplitInvocationListener != null) {
+ mSplitInvocationListenerExecutor.execute(() -> mSplitInvocationListener
+ .onSplitAnimationInvoked(true /*animationRunning*/));
+ }
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
setEnterTransition(transition, remoteTransition, extraTransitType, resizeAnim);
return transition;
@@ -457,6 +464,7 @@ class SplitScreenTransitions {
mPendingEnter.onConsumed(aborted);
mPendingEnter = null;
+ mStageCoordinator.notifySplitAnimationFinished();
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for enter transition");
} else if (isPendingDismiss(transition)) {
mPendingDismiss.onConsumed(aborted);
@@ -529,6 +537,12 @@ class SplitScreenTransitions {
mTransitions.getAnimExecutor().execute(va::start);
}
+ public void registerSplitAnimListener(@NonNull SplitScreen.SplitInvocationListener listener,
+ @NonNull Executor executor) {
+ mSplitInvocationListener = listener;
+ mSplitInvocationListenerExecutor = executor;
+ }
+
/** Calls when the transition got consumed. */
interface TransitionConsumedCallback {
void onConsumed(boolean aborted);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 5e9451a09d41..b10176df5826 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -157,6 +157,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.Executor;
/**
* Coordinates the staging (visibility, sizing, ...) of the split-screen {@link MainStage} and
@@ -237,6 +238,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private DefaultMixedHandler mMixedHandler;
private final Toast mSplitUnsupportedToast;
private SplitRequest mSplitRequest;
+ /** Used to notify others of when shell is animating into split screen */
+ private SplitScreen.SplitInvocationListener mSplitInvocationListener;
+ private Executor mSplitInvocationListenerExecutor;
/**
* Since StageCoordinator only coordinates MainStage and SideStage, it shouldn't support
@@ -247,6 +251,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return false;
}
+ /** NOTE: Will overwrite any previously set {@link #mSplitInvocationListener} */
+ public void registerSplitAnimationListener(
+ @NonNull SplitScreen.SplitInvocationListener listener, @NonNull Executor executor) {
+ mSplitInvocationListener = listener;
+ mSplitInvocationListenerExecutor = executor;
+ mSplitTransitions.registerSplitAnimListener(listener, executor);
+ }
+
class SplitRequest {
@SplitPosition
int mActivatePosition;
@@ -535,7 +547,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* childrenToTop */, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("startShortcut",
"side stage was not populated"));
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
}
if (finishedCallback != null) {
@@ -666,7 +678,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* childrenToTop */, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("startIntentLegacy",
"side stage was not populated"));
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
}
if (apps != null) {
@@ -1287,7 +1299,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("onRemoteAnimationFinishedOrCancelled",
"main or side stage was not populated."));
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
} else {
mSyncQueue.queue(evictWct);
mSyncQueue.runInSync(t -> {
@@ -1308,7 +1320,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("onRemoteAnimationFinished",
"main or side stage was not populated"));
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
return;
}
@@ -2890,6 +2902,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (hasEnteringPip) {
mMixedHandler.animatePendingEnterPipFromSplit(transition, info,
startTransaction, finishTransaction, finishCallback);
+ notifySplitAnimationFinished();
return true;
}
@@ -2924,6 +2937,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// the transition, or synchronize task-org callbacks.
}
// Use normal animations.
+ notifySplitAnimationFinished();
return false;
} else if (mMixedHandler != null && TransitionUtil.hasDisplayChange(info)) {
// A display-change has been un-expectedly inserted into the transition. Redirect
@@ -2937,6 +2951,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.update(startTransaction, true /* resetImePosition */);
startTransaction.apply();
}
+ notifySplitAnimationFinished();
return true;
}
}
@@ -3110,7 +3125,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
pendingEnter.mRemoteHandler.onTransitionConsumed(transition,
false /*aborted*/, finishT);
}
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
return true;
}
}
@@ -3139,6 +3154,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final TransitionInfo.Change finalMainChild = mainChild;
final TransitionInfo.Change finalSideChild = sideChild;
enterTransition.setFinishedCallback((callbackWct, callbackT) -> {
+ notifySplitAnimationFinished();
if (finalMainChild != null) {
if (!mainNotContainOpenTask) {
mMainStage.evictOtherChildren(callbackWct, finalMainChild.getTaskInfo().taskId);
@@ -3560,6 +3576,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.isLeftRightSplit());
}
+ private void handleUnsupportedSplitStart() {
+ mSplitUnsupportedToast.show();
+ notifySplitAnimationFinished();
+ }
+
+ void notifySplitAnimationFinished() {
+ if (mSplitInvocationListener == null || mSplitInvocationListenerExecutor == null) {
+ return;
+ }
+ mSplitInvocationListenerExecutor.execute(() ->
+ mSplitInvocationListener.onSplitAnimationInvoked(false /*animationRunning*/));
+ }
+
/**
* Logs the exit of splitscreen to a specific stage. This must be called before the exit is
* executed.
@@ -3622,7 +3651,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!ENABLE_SHELL_TRANSITIONS) {
StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
return;
}
@@ -3642,7 +3671,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
"app package " + taskInfo.baseActivity.getPackageName()
+ " does not support splitscreen, or is a controlled activity type"));
if (splitScreenVisible) {
- mSplitUnsupportedToast.show();
+ handleUnsupportedSplitStart();
}
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index befc702b01aa..34b2eebb15a1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -39,10 +39,13 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -63,6 +66,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -105,6 +109,8 @@ public class SplitTransitionTests extends ShellTestCase {
@Mock private ShellExecutor mMainExecutor;
@Mock private LaunchAdjacentController mLaunchAdjacentController;
@Mock private DefaultMixedHandler mMixedHandler;
+ @Mock private SplitScreen.SplitInvocationListener mInvocationListener;
+ private final TestShellExecutor mTestShellExecutor = new TestShellExecutor();
private SplitLayout mSplitLayout;
private MainStage mMainStage;
private SideStage mSideStage;
@@ -147,6 +153,7 @@ public class SplitTransitionTests extends ShellTestCase {
.setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
+ mStageCoordinator.registerSplitAnimationListener(mInvocationListener, mTestShellExecutor);
}
@Test
@@ -452,6 +459,15 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.activate(new WindowContainerTransaction(), true /* includingTopTask */);
}
+ @Test
+ @UiThreadTest
+ public void testSplitInvocationCallback() {
+ enterSplit();
+ mTestShellExecutor.flushAll();
+ verify(mInvocationListener, times(1))
+ .onSplitAnimationInvoked(eq(true));
+ }
+
private boolean containsSplitEnter(@NonNull WindowContainerTransaction wct) {
for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
WindowContainerTransaction.HierarchyOp op = wct.getHierarchyOps().get(i);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index c08b0837da8e..69aa90996946 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -77,7 +77,7 @@ public class QuickStepContract {
// settings is expanded.
public static final int SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1 << 11;
// Winscope tracing is enabled
- public static final int SYSUI_STATE_TRACING_ENABLED = 1 << 12;
+ public static final int SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION = 1 << 12;
// The Assistant gesture should be constrained. It is up to the launcher implementation to
// decide how to constrain it
public static final int SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1 << 13;
@@ -148,7 +148,7 @@ public class QuickStepContract {
SYSUI_STATE_OVERVIEW_DISABLED,
SYSUI_STATE_HOME_DISABLED,
SYSUI_STATE_SEARCH_DISABLED,
- SYSUI_STATE_TRACING_ENABLED,
+ SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION,
SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED,
SYSUI_STATE_BUBBLES_EXPANDED,
SYSUI_STATE_DIALOG_SHOWING,
@@ -211,8 +211,8 @@ public class QuickStepContract {
if ((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0) {
str.add("a11y_long_click");
}
- if ((flags & SYSUI_STATE_TRACING_ENABLED) != 0) {
- str.add("tracing");
+ if ((flags & SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION) != 0) {
+ str.add("disable_gesture_split_invocation");
}
if ((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0) {
str.add("asst_gesture_constrain");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 0673dcd5194b..76bd80ff6f79 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -37,7 +37,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_F
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_TRANSITION;
@@ -118,8 +117,6 @@ import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInterface;
-import dagger.Lazy;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -131,6 +128,8 @@ import java.util.function.Supplier;
import javax.inject.Inject;
import javax.inject.Provider;
+import dagger.Lazy;
+
/**
* Class to send information from overview to launcher with a binder.
*/
@@ -701,8 +700,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
// Listen for tracing state changes
@Override
public void onTracingStateChanged(boolean enabled) {
- mSysUiState.setFlag(SYSUI_STATE_TRACING_ENABLED, enabled)
- .commitUpdate(mContext.getDisplayId());
+ // TODO(b/286509643) Cleanup callers of this; Unused downstream
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 263ddc175647..b86a7c92ba47 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -21,6 +21,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_B
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -273,6 +274,13 @@ public final class WMShell implements
splitScreen.setSplitscreenFocus(leftOrTop);
}
});
+ splitScreen.registerSplitAnimationListener(new SplitScreen.SplitInvocationListener() {
+ @Override
+ public void onSplitAnimationInvoked(boolean animationRunning) {
+ mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION, animationRunning)
+ .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+ }
+ }, mSysUiMainExecutor);
}
@VisibleForTesting