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;
|
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.
|
* Sends a pending intent in sync.
|
||||||
* @param sender The PendingIntent sender.
|
* @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_IGNORE_ORIENTATION_REQUEST = 1 << 5;
|
||||||
public static final int CHANGE_FORCE_NO_PIP = 1 << 6;
|
public static final int CHANGE_FORCE_NO_PIP = 1 << 6;
|
||||||
public static final int CHANGE_FORCE_TRANSLUCENT = 1 << 7;
|
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 final Configuration mConfiguration = new Configuration();
|
||||||
private boolean mFocusable = true;
|
private boolean mFocusable = true;
|
||||||
private boolean mHidden = false;
|
private boolean mHidden = false;
|
||||||
private boolean mIgnoreOrientationRequest = false;
|
private boolean mIgnoreOrientationRequest = false;
|
||||||
private boolean mForceTranslucent = false;
|
private boolean mForceTranslucent = false;
|
||||||
|
private boolean mDragResizing = false;
|
||||||
|
|
||||||
private int mChangeMask = 0;
|
private int mChangeMask = 0;
|
||||||
private @ActivityInfo.Config int mConfigSetMask = 0;
|
private @ActivityInfo.Config int mConfigSetMask = 0;
|
||||||
@@ -932,6 +951,7 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
mHidden = in.readBoolean();
|
mHidden = in.readBoolean();
|
||||||
mIgnoreOrientationRequest = in.readBoolean();
|
mIgnoreOrientationRequest = in.readBoolean();
|
||||||
mForceTranslucent = in.readBoolean();
|
mForceTranslucent = in.readBoolean();
|
||||||
|
mDragResizing = in.readBoolean();
|
||||||
mChangeMask = in.readInt();
|
mChangeMask = in.readInt();
|
||||||
mConfigSetMask = in.readInt();
|
mConfigSetMask = in.readInt();
|
||||||
mWindowSetMask = in.readInt();
|
mWindowSetMask = in.readInt();
|
||||||
@@ -980,6 +1000,9 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
if ((other.mChangeMask & CHANGE_FORCE_TRANSLUCENT) != 0) {
|
if ((other.mChangeMask & CHANGE_FORCE_TRANSLUCENT) != 0) {
|
||||||
mForceTranslucent = other.mForceTranslucent;
|
mForceTranslucent = other.mForceTranslucent;
|
||||||
}
|
}
|
||||||
|
if ((other.mChangeMask & CHANGE_DRAG_RESIZING) != 0) {
|
||||||
|
mDragResizing = other.mDragResizing;
|
||||||
|
}
|
||||||
mChangeMask |= other.mChangeMask;
|
mChangeMask |= other.mChangeMask;
|
||||||
if (other.mActivityWindowingMode >= 0) {
|
if (other.mActivityWindowingMode >= 0) {
|
||||||
mActivityWindowingMode = other.mActivityWindowingMode;
|
mActivityWindowingMode = other.mActivityWindowingMode;
|
||||||
@@ -1039,6 +1062,15 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
return mForceTranslucent;
|
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() {
|
public int getChangeMask() {
|
||||||
return mChangeMask;
|
return mChangeMask;
|
||||||
}
|
}
|
||||||
@@ -1100,6 +1132,9 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
|
if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
|
||||||
sb.append("focusable:" + mFocusable + ",");
|
sb.append("focusable:" + mFocusable + ",");
|
||||||
}
|
}
|
||||||
|
if ((mChangeMask & CHANGE_DRAG_RESIZING) != 0) {
|
||||||
|
sb.append("dragResizing:" + mDragResizing + ",");
|
||||||
|
}
|
||||||
if (mBoundsChangeTransaction != null) {
|
if (mBoundsChangeTransaction != null) {
|
||||||
sb.append("hasBoundsTransaction,");
|
sb.append("hasBoundsTransaction,");
|
||||||
}
|
}
|
||||||
@@ -1117,6 +1152,7 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
dest.writeBoolean(mHidden);
|
dest.writeBoolean(mHidden);
|
||||||
dest.writeBoolean(mIgnoreOrientationRequest);
|
dest.writeBoolean(mIgnoreOrientationRequest);
|
||||||
dest.writeBoolean(mForceTranslucent);
|
dest.writeBoolean(mForceTranslucent);
|
||||||
|
dest.writeBoolean(mDragResizing);
|
||||||
dest.writeInt(mChangeMask);
|
dest.writeInt(mChangeMask);
|
||||||
dest.writeInt(mConfigSetMask);
|
dest.writeInt(mConfigSetMask);
|
||||||
dest.writeInt(mWindowSetMask);
|
dest.writeInt(mWindowSetMask);
|
||||||
|
|||||||
@@ -2402,7 +2402,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ThreadedRenderer renderer = getThreadedRenderer();
|
final ThreadedRenderer renderer = getThreadedRenderer();
|
||||||
if (renderer != null) {
|
if (renderer != null && !CAPTION_ON_SHELL) {
|
||||||
loadBackgroundDrawablesIfNeeded();
|
loadBackgroundDrawablesIfNeeded();
|
||||||
WindowInsets rootInsets = getRootWindowInsets();
|
WindowInsets rootInsets = getRootWindowInsets();
|
||||||
mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
|
mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ class TaskPositioner implements DragResizeCallback {
|
|||||||
private final Rect mTaskBoundsAtDragStart = new Rect();
|
private final Rect mTaskBoundsAtDragStart = new Rect();
|
||||||
private final PointF mResizeStartPoint = new PointF();
|
private final PointF mResizeStartPoint = new PointF();
|
||||||
private final Rect mResizeTaskBounds = new Rect();
|
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 int mCtrlType;
|
||||||
private DragStartListener mDragStartListener;
|
private DragStartListener mDragStartListener;
|
||||||
@@ -53,6 +56,12 @@ class TaskPositioner implements DragResizeCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDragResizeStart(int ctrlType, float x, float y) {
|
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);
|
mDragStartListener.onDragStart(mWindowDecoration.mTaskInfo.taskId);
|
||||||
mCtrlType = ctrlType;
|
mCtrlType = ctrlType;
|
||||||
|
|
||||||
@@ -63,19 +72,31 @@ class TaskPositioner implements DragResizeCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDragResizeMove(float x, float y) {
|
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
|
@Override
|
||||||
public void onDragResizeEnd(float x, float y) {
|
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;
|
mCtrlType = 0;
|
||||||
mTaskBoundsAtDragStart.setEmpty();
|
mTaskBoundsAtDragStart.setEmpty();
|
||||||
mResizeStartPoint.set(0, 0);
|
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;
|
float deltaX = x - mResizeStartPoint.x;
|
||||||
mResizeTaskBounds.set(mTaskBoundsAtDragStart);
|
mResizeTaskBounds.set(mTaskBoundsAtDragStart);
|
||||||
if ((mCtrlType & CTRL_TYPE_LEFT) != 0) {
|
if ((mCtrlType & CTRL_TYPE_LEFT) != 0) {
|
||||||
@@ -96,10 +117,10 @@ class TaskPositioner implements DragResizeCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mResizeTaskBounds.isEmpty()) {
|
if (!mResizeTaskBounds.isEmpty()) {
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
|
||||||
wct.setBounds(mWindowDecoration.mTaskInfo.token, mResizeTaskBounds);
|
wct.setBounds(mWindowDecoration.mTaskInfo.token, mResizeTaskBounds);
|
||||||
mTaskOrganizer.applyTransaction(wct);
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DragStartListener {
|
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.LAYOUT_REASON_CONFIG_CHANGED;
|
||||||
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
|
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
|
||||||
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
|
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_PINNED_TASK;
|
||||||
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
|
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
|
||||||
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
|
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
|
||||||
@@ -725,6 +726,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
effects = TRANSACT_EFFECTS_LIFECYCLE;
|
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();
|
final int childWindowingMode = c.getActivityWindowingMode();
|
||||||
if (childWindowingMode > -1) {
|
if (childWindowingMode > -1) {
|
||||||
tr.setActivityWindowingMode(childWindowingMode);
|
tr.setActivityWindowingMode(childWindowingMode);
|
||||||
|
|||||||
Reference in New Issue
Block a user