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;
|
this.task = newTask;
|
||||||
|
|
||||||
if (shouldStartChangeTransition(newParent, oldParent)) {
|
if (shouldStartChangeTransition(newParent, oldParent)) {
|
||||||
// The new parent and old parent may be in different position. Need to offset the
|
// Animate change transition on TaskFragment level to get the correct window crop.
|
||||||
// animation surface to keep it in its original position.
|
newParent.initializeChangeTransition(getBounds(), getSurfaceControl());
|
||||||
initializeChangeTransition(getBounds(), newParent.getBounds());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onParentChanged(newParent, oldParent);
|
super.onParentChanged(newParent, oldParent);
|
||||||
|
|||||||
@@ -343,9 +343,6 @@ public class AppTransitionController {
|
|||||||
switch (changingType) {
|
switch (changingType) {
|
||||||
case TYPE_TASK:
|
case TYPE_TASK:
|
||||||
return TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
|
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:
|
case TYPE_TASK_FRAGMENT:
|
||||||
return TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
|
return TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -72,8 +72,11 @@ class SurfaceFreezer {
|
|||||||
*
|
*
|
||||||
* @param startBounds The original bounds (on screen) of the surface we are snapshotting.
|
* @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 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);
|
mFreezeBounds.set(startBounds);
|
||||||
|
|
||||||
mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
|
mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
|
||||||
@@ -82,7 +85,7 @@ class SurfaceFreezer {
|
|||||||
mWmService.mTransactionFactory);
|
mWmService.mTransactionFactory);
|
||||||
mAnimatable.onAnimationLeashCreated(t, mLeash);
|
mAnimatable.onAnimationLeashCreated(t, mLeash);
|
||||||
|
|
||||||
SurfaceControl freezeTarget = mAnimatable.getFreezeSnapshotTarget();
|
freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
|
||||||
if (freezeTarget != null) {
|
if (freezeTarget != null) {
|
||||||
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer(
|
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer(
|
||||||
freezeTarget, startBounds);
|
freezeTarget, startBounds);
|
||||||
|
|||||||
@@ -2620,23 +2620,27 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
* For now, this will only be called for the following cases:
|
* For now, this will only be called for the following cases:
|
||||||
* 1. {@link Task} is changing windowing mode between fullscreen and freeform.
|
* 1. {@link Task} is changing windowing mode between fullscreen and freeform.
|
||||||
* 2. {@link TaskFragment} is organized and is changing window bounds.
|
* 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 startBounds The original bounds (on screen) of the surface we are snapshotting.
|
||||||
* @param parentBounds The parent bounds (on screen) to calculate the animation surface
|
* @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
|
||||||
* position.
|
* snapshot from {@link #getFreezeSnapshotTarget()}.
|
||||||
*/
|
*/
|
||||||
void initializeChangeTransition(Rect startBounds, Rect parentBounds) {
|
void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
|
||||||
mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
|
mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
|
||||||
mDisplayContent.mChangingContainers.add(this);
|
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);
|
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) {
|
void initializeChangeTransition(Rect startBounds) {
|
||||||
initializeChangeTransition(startBounds, getParent().getBounds());
|
initializeChangeTransition(startBounds, null /* freezeTarget */);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArraySet<WindowContainer> getAnimationSources() {
|
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.doNothing;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
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 com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
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.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
@@ -54,6 +57,7 @@ import android.view.IRemoteAnimationFinishedCallback;
|
|||||||
import android.view.IRemoteAnimationRunner;
|
import android.view.IRemoteAnimationRunner;
|
||||||
import android.view.RemoteAnimationAdapter;
|
import android.view.RemoteAnimationAdapter;
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.window.ITaskFragmentOrganizer;
|
import android.window.ITaskFragmentOrganizer;
|
||||||
import android.window.TaskFragmentOrganizer;
|
import android.window.TaskFragmentOrganizer;
|
||||||
@@ -397,7 +401,9 @@ public class AppTransitionTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testActivityRecordReparentToTaskFragment() {
|
public void testActivityRecordReparentToTaskFragment() {
|
||||||
final ActivityRecord activity = createActivityRecord(mDc);
|
final ActivityRecord activity = createActivityRecord(mDc);
|
||||||
|
final SurfaceControl activityLeash = mock(SurfaceControl.class);
|
||||||
activity.setVisibility(true);
|
activity.setVisibility(true);
|
||||||
|
activity.setSurfaceControl(activityLeash);
|
||||||
final Task task = activity.getTask();
|
final Task task = activity.getTask();
|
||||||
|
|
||||||
// Add a TaskFragment of half of the Task size.
|
// Add a TaskFragment of half of the Task size.
|
||||||
@@ -412,15 +418,20 @@ public class AppTransitionTests extends WindowTestsBase {
|
|||||||
final Rect taskBounds = new Rect();
|
final Rect taskBounds = new Rect();
|
||||||
task.getBounds(taskBounds);
|
task.getBounds(taskBounds);
|
||||||
taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom);
|
taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom);
|
||||||
|
spyOn(taskFragment);
|
||||||
|
|
||||||
assertTrue(mDc.mChangingContainers.isEmpty());
|
assertTrue(mDc.mChangingContainers.isEmpty());
|
||||||
assertFalse(mDc.mAppTransition.isTransitionSet());
|
assertFalse(mDc.mAppTransition.isTransitionSet());
|
||||||
|
|
||||||
// Schedule app transition when reparent activity to a TaskFragment of different size.
|
// Schedule app transition when reparent activity to a TaskFragment of different size.
|
||||||
|
final Rect startBounds = new Rect(activity.getBounds());
|
||||||
activity.reparent(taskFragment, POSITION_TOP);
|
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));
|
assertTrue(mDc.mAppTransition.containsTransitRequest(TRANSIT_CHANGE));
|
||||||
|
assertEquals(startBounds, taskFragment.mSurfaceFreezer.mFreezeBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
|
private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
|
||||||
|
|||||||
Reference in New Issue
Block a user