From 9335d2bfbb48a29b73ae86e932d6659aad5756c7 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 24 Sep 2020 17:18:20 -0700 Subject: [PATCH] Reset Fullscreen Task Surface via SyncTransactionQueue Split-screen dismisses itself on the SyncTransactionQueue to prevent glitches/jank. The result, however, is that when one of the split tasks gets unsplit, it becomes organized. Just before it becomes organized, though, its windowcrop gets updated on the sync transaction. Then onTaskAppeared gets called. Then the sync transaction is applied once drawing completes. To resolve this, put the fullscreen transaction on the syncTransactionQueue as well. In the future, everything that shell does should probably be serialized in this way (eg. PiP). Bug: 169330989 Test: Open app, put it into split, expand the app to fullscreen, rotate device and observer no half black screen. Change-Id: I3a7d3d8650a475b4aa4208bf6be9285e530514a0 --- .../wm/shell/FullscreenTaskListener.java | 28 +++++++++---------- .../android/wm/shell/ShellTaskOrganizer.java | 10 +++---- .../splitscreen/SplitScreenController.java | 6 ++-- .../shell/splitscreen/WindowManagerProxy.java | 7 ++--- .../wm/shell/ShellTaskOrganizerTests.java | 6 ++-- .../systemui/wmshell/TvWMShellModule.java | 6 ++-- .../systemui/wmshell/WMShellBaseModule.java | 12 ++++++-- .../systemui/wmshell/WMShellModule.java | 6 ++-- 8 files changed, 45 insertions(+), 36 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java index 9047b71253dad..b275331fa9539 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java @@ -22,18 +22,18 @@ import android.util.Slog; import android.view.SurfaceControl; import com.android.internal.protolog.common.ProtoLog; -import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.protolog.ShellProtoLogGroup; class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private static final String TAG = "FullscreenTaskOrg"; - private final TransactionPool mTransactionPool; + private final SyncTransactionQueue mSyncQueue; private final ArraySet mTasks = new ArraySet<>(); - FullscreenTaskListener(TransactionPool transactionPool) { - mTransactionPool = transactionPool; + FullscreenTaskListener(SyncTransactionQueue syncQueue) { + mSyncQueue = syncQueue; } @Override @@ -42,18 +42,18 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { if (mTasks.contains(taskInfo.taskId)) { throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId); } - mTasks.add(taskInfo.taskId); - final SurfaceControl.Transaction t = mTransactionPool.acquire(); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", taskInfo.taskId); - // Reset several properties back to fullscreen (PiP, for example, leaves all these - // properties in a bad state). - t.setPosition(leash, 0, 0); - t.setWindowCrop(leash, null); - t.setAlpha(leash, 1f); - t.setMatrix(leash, 1, 0, 0, 1); - t.show(leash); - t.apply(); + mTasks.add(taskInfo.taskId); + mSyncQueue.runInSync(t -> { + // Reset several properties back to fullscreen (PiP, for example, leaves all these + // properties in a bad state). + t.setPosition(leash, 0, 0); + t.setWindowCrop(leash, null); + t.setAlpha(leash, 1f); + t.setMatrix(leash, 1, 0, 0, 1); + t.show(leash); + }); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 2d82fb1d3a212..d650a958a2036 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -28,7 +28,7 @@ import android.window.TaskOrganizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; -import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.util.ArrayList; @@ -59,16 +59,16 @@ public class ShellTaskOrganizer extends TaskOrganizer { // require us to report to both old and new listeners) private final SparseArray> mTasks = new SparseArray<>(); - public ShellTaskOrganizer(TransactionPool transactionPool) { + public ShellTaskOrganizer(SyncTransactionQueue syncQueue) { super(); - addListener(new FullscreenTaskListener(transactionPool), WINDOWING_MODE_FULLSCREEN); + addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); } @VisibleForTesting ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController, - TransactionPool transactionPool) { + SyncTransactionQueue syncQueue) { super(taskOrganizerController); - addListener(new FullscreenTaskListener(transactionPool), WINDOWING_MODE_FULLSCREEN); + addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); } /** 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 eed5092ea96ba..70ef7b397ec89 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 @@ -40,6 +40,7 @@ import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; @@ -99,7 +100,7 @@ public class SplitScreenController implements SplitScreen, public SplitScreenController(Context context, DisplayController displayController, SystemWindows systemWindows, DisplayImeController imeController, Handler handler, TransactionPool transactionPool, - ShellTaskOrganizer shellTaskOrganizer) { + ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue) { mContext = context; mDisplayController = displayController; mSystemWindows = systemWindows; @@ -107,8 +108,7 @@ public class SplitScreenController implements SplitScreen, mHandler = handler; mForcedResizableController = new ForcedResizableInfoActivityController(context, this); mTransactionPool = transactionPool; - mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler, - shellTaskOrganizer); + mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer); mTaskOrganizer = shellTaskOrganizer; mSplits = new SplitScreenTaskOrganizer(this, shellTaskOrganizer); mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java index 25827cdb9e248..47e7c99d22681 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java @@ -28,7 +28,6 @@ import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.graphics.Rect; -import android.os.Handler; import android.os.RemoteException; import android.util.Log; import android.view.Display; @@ -41,7 +40,6 @@ import android.window.WindowOrganizer; import com.android.internal.annotations.GuardedBy; import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.common.TransactionPool; import java.util.ArrayList; import java.util.List; @@ -85,9 +83,8 @@ class WindowManagerProxy { private final TaskOrganizer mTaskOrganizer; - WindowManagerProxy(TransactionPool transactionPool, Handler handler, - TaskOrganizer taskOrganizer) { - mSyncTransactionQueue = new SyncTransactionQueue(transactionPool, handler); + WindowManagerProxy(SyncTransactionQueue syncQueue, TaskOrganizer taskOrganizer) { + mSyncTransactionQueue = syncQueue; mTaskOrganizer = taskOrganizer; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java index 7b499d4d6e7d3..823e0b7f03c55 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java @@ -33,7 +33,7 @@ import android.window.ITaskOrganizerController; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.SyncTransactionQueue; import org.junit.Before; import org.junit.Test; @@ -54,7 +54,7 @@ public class ShellTaskOrganizerTests { private ITaskOrganizerController mTaskOrganizerController; ShellTaskOrganizer mOrganizer; - private final TransactionPool mTransactionPool = mock(TransactionPool.class); + private final SyncTransactionQueue mSyncTransactionQueue = mock(SyncTransactionQueue.class); private class TrackingTaskListener implements ShellTaskOrganizer.TaskListener { final ArrayList appeared = new ArrayList<>(); @@ -85,7 +85,7 @@ public class ShellTaskOrganizerTests { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mOrganizer = new ShellTaskOrganizer(mTaskOrganizerController, mTransactionPool); + mOrganizer = new ShellTaskOrganizer(mTaskOrganizerController, mSyncTransactionQueue); } @Test diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java index 524eca389cebc..edd532e991dcb 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java @@ -26,6 +26,7 @@ import com.android.systemui.pip.tv.dagger.TvPipModule; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.splitscreen.SplitScreen; @@ -54,8 +55,9 @@ public class TvWMShellModule { static SplitScreen provideSplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, DisplayImeController displayImeController, @Main Handler handler, - TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer) { + TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, + SyncTransactionQueue syncQueue) { return new SplitScreenController(context, displayController, systemWindows, - displayImeController, handler, transactionPool, shellTaskOrganizer); + displayImeController, handler, transactionPool, shellTaskOrganizer, syncQueue); } } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 7c129ac92fe3c..18f28cd59fb88 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -34,6 +34,7 @@ import com.android.systemui.util.FloatingContentCoordinator; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.animation.FlingAnimationUtils; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.onehanded.OneHanded; @@ -98,8 +99,15 @@ public abstract class WMShellBaseModule { @SysUISingleton @Provides - static ShellTaskOrganizer provideShellTaskOrganizer(TransactionPool transactionPool) { - ShellTaskOrganizer organizer = new ShellTaskOrganizer(transactionPool); + static SyncTransactionQueue provideSyncTransactionQueue(@Main Handler handler, + TransactionPool pool) { + return new SyncTransactionQueue(pool, handler); + } + + @SysUISingleton + @Provides + static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue) { + ShellTaskOrganizer organizer = new ShellTaskOrganizer(syncQueue); organizer.registerOrganizer(); return organizer; } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index 16fb2cacc9508..2546812d17640 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -36,6 +36,7 @@ import com.android.systemui.util.FloatingContentCoordinator; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.onehanded.OneHanded; @@ -88,9 +89,10 @@ public class WMShellModule { static SplitScreen provideSplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, DisplayImeController displayImeController, @Main Handler handler, - TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer) { + TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, + SyncTransactionQueue syncQueue) { return new SplitScreenController(context, displayController, systemWindows, - displayImeController, handler, transactionPool, shellTaskOrganizer); + displayImeController, handler, transactionPool, shellTaskOrganizer, syncQueue); } @SysUISingleton