Merge "Change the activity reparent to animate at TaskFragment level." into sc-v2-dev am: 21f6fdd842
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15938346 Change-Id: I7289e0d841942d52bca2d4fd6d621958a71741f8
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user