Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21f6fdd8 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Change the activity reparent to animate at TaskFragment level." into sc-v2-dev

parents 13e33418 ae9155a4
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -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);
+0 −3
Original line number Diff line number Diff line
@@ -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:
+5 −2
Original line number Diff line number Diff line
@@ -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);
+11 −7
Original line number Diff line number Diff line
@@ -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() {
+12 −1
Original line number Diff line number Diff line
@@ -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 {