summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2021-09-29 18:32:24 +0800
committer Chris Li <lihongyu@google.com> 2021-10-01 08:30:13 +0800
commitae9155a47bdb9f1cb58466decc8749b092dc1ea9 (patch)
tree001d0e9e59dbe93a7a493d2f58cf2b6587d3b683
parentd8dac94e0d2c7bec9408d22f531f09ed5e12c76d (diff)
Change the activity reparent to animate at TaskFragment level.
Before, we are animating at activity level, but that wouldn't work after we set the TaskFragment window crop. Now, we animate the change transition on the TaskFragment level instead. Bug: 196173550 Test: atest WmTests:AppTransitionTests #testActivityRecordReparentToTaskFragment Change-Id: Ie777dc8bf438300f59f8a2565cd999c6a29561d8
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java5
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java3
-rw-r--r--services/core/java/com/android/server/wm/SurfaceFreezer.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java13
5 files changed, 30 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index db44dd8f70d1..c1fcf71b38d2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1411,9 +1411,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
this.task = newTask;
if (shouldStartChangeTransition(newParent, oldParent)) {
- // The new parent and old parent may be in different position. Need to offset the
- // animation surface to keep it in its original position.
- initializeChangeTransition(getBounds(), newParent.getBounds());
+ // Animate change transition on TaskFragment level to get the correct window crop.
+ newParent.initializeChangeTransition(getBounds(), getSurfaceControl());
}
super.onParentChanged(newParent, oldParent);
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 82377b34d22a..3fc785a25454 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -343,9 +343,6 @@ public class AppTransitionController {
switch (changingType) {
case TYPE_TASK:
return TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
- case TYPE_ACTIVITY:
- // ActivityRecord is put in a change transition only when it is reparented
- // to an organized TaskFragment. See ActivityRecord#shouldStartChangeTransition.
case TYPE_TASK_FRAGMENT:
return TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
default:
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index 9c4f6f574487..89986cefb207 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -72,8 +72,11 @@ class SurfaceFreezer {
*
* @param startBounds The original bounds (on screen) of the surface we are snapshotting.
* @param relativePosition The related position of the snapshot surface to its parent.
+ * @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
+ * snapshot from the {@link #mAnimatable} surface.
*/
- void freeze(SurfaceControl.Transaction t, Rect startBounds, Point relativePosition) {
+ void freeze(SurfaceControl.Transaction t, Rect startBounds, Point relativePosition,
+ @Nullable SurfaceControl freezeTarget) {
mFreezeBounds.set(startBounds);
mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
@@ -82,7 +85,7 @@ class SurfaceFreezer {
mWmService.mTransactionFactory);
mAnimatable.onAnimationLeashCreated(t, mLeash);
- SurfaceControl freezeTarget = mAnimatable.getFreezeSnapshotTarget();
+ freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
if (freezeTarget != null) {
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer(
freezeTarget, startBounds);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0bc3712d7946..38e20555f236 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2620,23 +2620,27 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* For now, this will only be called for the following cases:
* 1. {@link Task} is changing windowing mode between fullscreen and freeform.
* 2. {@link TaskFragment} is organized and is changing window bounds.
- * 3. {@link ActivityRecord} is reparented into an organized {@link TaskFragment}.
+ * 3. {@link ActivityRecord} is reparented into an organized {@link TaskFragment}. (The
+ * transition will happen on the {@link TaskFragment} for this case).
*
- * This shouldn't be called on other {@link WindowContainer} unless there is a valid use case.
+ * This shouldn't be called on other {@link WindowContainer} unless there is a valid
+ * use case.
*
* @param startBounds The original bounds (on screen) of the surface we are snapshotting.
- * @param parentBounds The parent bounds (on screen) to calculate the animation surface
- * position.
+ * @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
+ * snapshot from {@link #getFreezeSnapshotTarget()}.
*/
- void initializeChangeTransition(Rect startBounds, Rect parentBounds) {
+ void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
mDisplayContent.mChangingContainers.add(this);
+ // Calculate the relative position in parent container.
+ final Rect parentBounds = getParent().getBounds();
mTmpPoint.set(startBounds.left - parentBounds.left, startBounds.top - parentBounds.top);
- mSurfaceFreezer.freeze(getSyncTransaction(), startBounds, mTmpPoint);
+ mSurfaceFreezer.freeze(getSyncTransaction(), startBounds, mTmpPoint, freezeTarget);
}
void initializeChangeTransition(Rect startBounds) {
- initializeChangeTransition(startBounds, getParent().getBounds());
+ initializeChangeTransition(startBounds, null /* freezeTarget */);
}
ArraySet<WindowContainer> getAnimationSources() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 405d714256ab..fb8bc7be38ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -35,6 +35,8 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
@@ -42,6 +44,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
import android.graphics.Rect;
import android.os.Binder;
@@ -54,6 +57,7 @@ import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentOrganizer;
@@ -397,7 +401,9 @@ public class AppTransitionTests extends WindowTestsBase {
@Test
public void testActivityRecordReparentToTaskFragment() {
final ActivityRecord activity = createActivityRecord(mDc);
+ final SurfaceControl activityLeash = mock(SurfaceControl.class);
activity.setVisibility(true);
+ activity.setSurfaceControl(activityLeash);
final Task task = activity.getTask();
// Add a TaskFragment of half of the Task size.
@@ -412,15 +418,20 @@ public class AppTransitionTests extends WindowTestsBase {
final Rect taskBounds = new Rect();
task.getBounds(taskBounds);
taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom);
+ spyOn(taskFragment);
assertTrue(mDc.mChangingContainers.isEmpty());
assertFalse(mDc.mAppTransition.isTransitionSet());
// Schedule app transition when reparent activity to a TaskFragment of different size.
+ final Rect startBounds = new Rect(activity.getBounds());
activity.reparent(taskFragment, POSITION_TOP);
- assertTrue(mDc.mChangingContainers.contains(activity));
+ // It should transit at TaskFragment level with snapshot on the activity surface.
+ verify(taskFragment).initializeChangeTransition(activity.getBounds(), activityLeash);
+ assertTrue(mDc.mChangingContainers.contains(taskFragment));
assertTrue(mDc.mAppTransition.containsTransitRequest(TRANSIT_CHANGE));
+ assertEquals(startBounds, taskFragment.mSurfaceFreezer.mFreezeBounds);
}
private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {