Merge "Change the activity reparent to animate at TaskFragment level." into sc-v2-dev am: 21f6fdd842 am: a310195b5e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15938346

Change-Id: I41d25dc88f931b76344d545fec221d2acf6764e6
This commit is contained in:
Chris Li
2021-10-01 12:20:10 +00:00
committed by Automerger Merge Worker
5 changed files with 30 additions and 16 deletions

View File

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

View File

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

View File

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

View File

@@ -2624,23 +2624,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() {

View File

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