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
This commit is contained in:
Evan Rosky
2020-09-24 17:18:20 -07:00
parent f4f842b65f
commit 9335d2bfbb
8 changed files with 45 additions and 36 deletions

View File

@@ -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<Integer> 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);
});
}
}

View File

@@ -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<Pair<RunningTaskInfo, SurfaceControl>> 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);
}
/**

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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<RunningTaskInfo> 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

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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