Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9335d2bf authored by Evan Rosky's avatar Evan Rosky
Browse files

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
parent f4f842b6
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -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,10 +42,10 @@ 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);
            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);
@@ -53,7 +53,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
                t.setAlpha(leash, 1f);
                t.setMatrix(leash, 1, 0, 0, 1);
                t.show(leash);
            t.apply();
            });
        }
    }

+5 −5
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -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,
+2 −5
Original line number Diff line number Diff line
@@ -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;
    }

+3 −3
Original line number Diff line number Diff line
@@ -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
Loading