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:
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user