Merge "Add WCT#setDragResizing to optimize fluid resizing" into tm-qpr-dev
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user