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

This commit is contained in:
Jorge Gil
2022-11-14 21:09:24 +00:00
committed by Android (Google) Code Review
5 changed files with 198 additions and 6 deletions

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,130 @@
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)
}
}

View File

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