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

Commit 1f17bf7e authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "Add WCT#setDragResizing to optimize fluid resizing" into tm-qpr-dev

parents 6f9c9792 5a95db04
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -466,6 +466,23 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Sets whether a container is being drag-resized.
     * When {@code true}, the client will reuse a single (larger) surface size to avoid
     * continuous allocations on every size change.
     *
     * @param container WindowContainerToken of the task that changed its drag resizing state
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setDragResizing(@NonNull WindowContainerToken container,
            boolean dragResizing) {
        final Change change = getOrCreateChange(container.asBinder());
        change.mChangeMask |= Change.CHANGE_DRAG_RESIZING;
        change.mDragResizing = dragResizing;
        return this;
    }

    /**
     * Sends a pending intent in sync.
     * @param sender The PendingIntent sender.
@@ -906,12 +923,14 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5;
        public static final int CHANGE_FORCE_NO_PIP = 1 << 6;
        public static final int CHANGE_FORCE_TRANSLUCENT = 1 << 7;
        public static final int CHANGE_DRAG_RESIZING = 1 << 8;

        private final Configuration mConfiguration = new Configuration();
        private boolean mFocusable = true;
        private boolean mHidden = false;
        private boolean mIgnoreOrientationRequest = false;
        private boolean mForceTranslucent = false;
        private boolean mDragResizing = false;

        private int mChangeMask = 0;
        private @ActivityInfo.Config int mConfigSetMask = 0;
@@ -932,6 +951,7 @@ public final class WindowContainerTransaction implements Parcelable {
            mHidden = in.readBoolean();
            mIgnoreOrientationRequest = in.readBoolean();
            mForceTranslucent = in.readBoolean();
            mDragResizing = in.readBoolean();
            mChangeMask = in.readInt();
            mConfigSetMask = in.readInt();
            mWindowSetMask = in.readInt();
@@ -980,6 +1000,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((other.mChangeMask & CHANGE_FORCE_TRANSLUCENT) != 0) {
                mForceTranslucent = other.mForceTranslucent;
            }
            if ((other.mChangeMask & CHANGE_DRAG_RESIZING) != 0) {
                mDragResizing = other.mDragResizing;
            }
            mChangeMask |= other.mChangeMask;
            if (other.mActivityWindowingMode >= 0) {
                mActivityWindowingMode = other.mActivityWindowingMode;
@@ -1039,6 +1062,15 @@ public final class WindowContainerTransaction implements Parcelable {
            return mForceTranslucent;
        }

        /** Gets the requested drag resizing state. */
        public boolean getDragResizing() {
            if ((mChangeMask & CHANGE_DRAG_RESIZING) == 0) {
                throw new RuntimeException("Drag resizing not set. "
                        + "Check CHANGE_DRAG_RESIZING first");
            }
            return mDragResizing;
        }

        public int getChangeMask() {
            return mChangeMask;
        }
@@ -1100,6 +1132,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
                sb.append("focusable:" + mFocusable + ",");
            }
            if ((mChangeMask & CHANGE_DRAG_RESIZING) != 0) {
                sb.append("dragResizing:" + mDragResizing + ",");
            }
            if (mBoundsChangeTransaction != null) {
                sb.append("hasBoundsTransaction,");
            }
@@ -1117,6 +1152,7 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeBoolean(mHidden);
            dest.writeBoolean(mIgnoreOrientationRequest);
            dest.writeBoolean(mForceTranslucent);
            dest.writeBoolean(mDragResizing);
            dest.writeInt(mChangeMask);
            dest.writeInt(mConfigSetMask);
            dest.writeInt(mWindowSetMask);
+1 −1
Original line number Diff line number Diff line
@@ -2402,7 +2402,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            return;
        }
        final ThreadedRenderer renderer = getThreadedRenderer();
        if (renderer != null) {
        if (renderer != null && !CAPTION_ON_SHELL) {
            loadBackgroundDrawablesIfNeeded();
            WindowInsets rootInsets = getRootWindowInsets();
            mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
+26 −5
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ class TaskPositioner implements DragResizeCallback {
    private final Rect mTaskBoundsAtDragStart = new Rect();
    private final PointF mResizeStartPoint = new PointF();
    private final Rect mResizeTaskBounds = new Rect();
    // Whether the |dragResizing| hint should be sent with the next bounds change WCT.
    // Used to optimized fluid resizing of freeform tasks.
    private boolean mPendingDragResizeHint = false;

    private int mCtrlType;
    private DragStartListener mDragStartListener;
@@ -53,6 +56,12 @@ class TaskPositioner implements DragResizeCallback {

    @Override
    public void onDragResizeStart(int ctrlType, float x, float y) {
        if (ctrlType != CTRL_TYPE_UNDEFINED) {
            // The task is being resized, send the |dragResizing| hint to core with the first
            // bounds-change wct.
            mPendingDragResizeHint = true;
        }

        mDragStartListener.onDragStart(mWindowDecoration.mTaskInfo.taskId);
        mCtrlType = ctrlType;

@@ -63,19 +72,31 @@ class TaskPositioner implements DragResizeCallback {

    @Override
    public void onDragResizeMove(float x, float y) {
        changeBounds(x, y);
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        if (changeBounds(wct, x, y)) {
            if (mPendingDragResizeHint) {
                // This is the first bounds change since drag resize operation started.
                wct.setDragResizing(mWindowDecoration.mTaskInfo.token, true /* dragResizing */);
                mPendingDragResizeHint = false;
            }
            mTaskOrganizer.applyTransaction(wct);
        }
    }

    @Override
    public void onDragResizeEnd(float x, float y) {
        changeBounds(x, y);
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        wct.setDragResizing(mWindowDecoration.mTaskInfo.token, false /* dragResizing */);
        changeBounds(wct, x, y);
        mTaskOrganizer.applyTransaction(wct);

        mCtrlType = 0;
        mTaskBoundsAtDragStart.setEmpty();
        mResizeStartPoint.set(0, 0);
        mPendingDragResizeHint = false;
    }

    private void changeBounds(float x, float y) {
    private boolean changeBounds(WindowContainerTransaction wct, float x, float y) {
        float deltaX = x - mResizeStartPoint.x;
        mResizeTaskBounds.set(mTaskBoundsAtDragStart);
        if ((mCtrlType & CTRL_TYPE_LEFT) != 0) {
@@ -96,10 +117,10 @@ class TaskPositioner implements DragResizeCallback {
        }

        if (!mResizeTaskBounds.isEmpty()) {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            wct.setBounds(mWindowDecoration.mTaskInfo.token, mResizeTaskBounds);
            mTaskOrganizer.applyTransaction(wct);
            return true;
        }
        return false;
    }

    interface DragStartListener {
+130 −0
Original line number Diff line number Diff line
package com.android.wm.shell.windowdecor

import android.app.ActivityManager
import android.graphics.Rect
import android.os.IBinder
import android.testing.AndroidTestingRunner
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_RIGHT
import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_UNDEFINED
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.argThat
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

/**
 * Tests for [TaskPositioner].
 *
 * Build/Install/Run:
 * atest WMShellUnitTests:TaskPositionerTest
 */
@SmallTest
@RunWith(AndroidTestingRunner::class)
class TaskPositionerTest : ShellTestCase() {

    @Mock
    private lateinit var mockShellTaskOrganizer: ShellTaskOrganizer
    @Mock
    private lateinit var mockWindowDecoration: WindowDecoration<*>
    @Mock
    private lateinit var mockDragStartListener: TaskPositioner.DragStartListener

    @Mock
    private lateinit var taskToken: WindowContainerToken
    @Mock
    private lateinit var taskBinder: IBinder

    private lateinit var taskPositioner: TaskPositioner

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        taskPositioner = TaskPositioner(
                mockShellTaskOrganizer,
                mockWindowDecoration,
                mockDragStartListener
        )
        `when`(taskToken.asBinder()).thenReturn(taskBinder)
        mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
            taskId = TASK_ID
            token = taskToken
            configuration.windowConfiguration.bounds = STARTING_BOUNDS
        }
    }

    @Test
    fun testDragResize_move_skipsDragResizingFlag() {
        taskPositioner.onDragResizeStart(
                CTRL_TYPE_UNDEFINED, // Move
                STARTING_BOUNDS.left.toFloat(),
                STARTING_BOUNDS.top.toFloat()
        )

        // Move the task 10px to the right.
        val newX = STARTING_BOUNDS.left.toFloat() + 10
        val newY = STARTING_BOUNDS.top.toFloat()
        taskPositioner.onDragResizeMove(
                newX,
                newY
        )

        taskPositioner.onDragResizeEnd(newX, newY)

        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
            return@argThat wct.changes.any { (token, change) ->
                token == taskBinder &&
                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
                        change.dragResizing
            }
        })
    }

    @Test
    fun testDragResize_resize_setsDragResizingFlag() {
        taskPositioner.onDragResizeStart(
                CTRL_TYPE_RIGHT, // Resize right
                STARTING_BOUNDS.left.toFloat(),
                STARTING_BOUNDS.top.toFloat()
        )

        // Resize the task by 10px to the right.
        val newX = STARTING_BOUNDS.right.toFloat() + 10
        val newY = STARTING_BOUNDS.top.toFloat()
        taskPositioner.onDragResizeMove(
                newX,
                newY
        )

        taskPositioner.onDragResizeEnd(newX, newY)

        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
            return@argThat wct.changes.any { (token, change) ->
                token == taskBinder &&
                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
                        change.dragResizing
            }
        })
        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
            return@argThat wct.changes.any { (token, change) ->
                token == taskBinder &&
                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
                        !change.dragResizing
            }
        })
    }

    companion object {
        private const val TASK_ID = 5
        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
@@ -725,6 +726,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            effects = TRANSACT_EFFECTS_LIFECYCLE;
        }

        if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING) != 0) {
            tr.setDragResizing(c.getDragResizing(), DRAG_RESIZE_MODE_FREEFORM);
        }

        final int childWindowingMode = c.getActivityWindowingMode();
        if (childWindowingMode > -1) {
            tr.setActivityWindowingMode(childWindowingMode);