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

Commit 2ed44b97 authored by Chris Li's avatar Chris Li Committed by Automerger Merge Worker
Browse files

Merge "Fix NPE for animate frozen snapshot" into sc-v2-dev am: 5cef72a6

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

Change-Id: Ia3dd7eee53b308fe8418861611e75c8fa1b39cfd
parents 4a955cf3 5cef72a6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -188,6 +188,10 @@ class SurfaceAnimator {
        mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
        if (snapshotAnim != null) {
            mSnapshot = freezer.takeSnapshotForAnimation();
            if (mSnapshot == null) {
                Slog.e(TAG, "No snapshot target to start animation on for " + mAnimatable);
                return;
            }
            mSnapshot.startAnimation(t, snapshotAnim, type);
        }
    }
+31 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.util.Slog;
import android.view.SurfaceControl;

import com.android.internal.annotations.VisibleForTesting;
@@ -49,8 +50,10 @@ import com.android.internal.protolog.common.ProtoLog;
 */
class SurfaceFreezer {

    private final Freezable mAnimatable;
    private final WindowManagerService mWmService;
    private static final String TAG = "SurfaceFreezer";

    private final @NonNull Freezable mAnimatable;
    private final @NonNull WindowManagerService mWmService;
    @VisibleForTesting
    SurfaceControl mLeash;
    Snapshot mSnapshot = null;
@@ -59,7 +62,7 @@ class SurfaceFreezer {
    /**
     * @param animatable The object to animate.
     */
    SurfaceFreezer(Freezable animatable, WindowManagerService service) {
    SurfaceFreezer(@NonNull Freezable animatable, @NonNull WindowManagerService service) {
        mAnimatable = animatable;
        mWmService = service;
    }
@@ -86,11 +89,14 @@ class SurfaceFreezer {

        freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
        if (freezeTarget != null) {
            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer(
            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner(
                    freezeTarget, startBounds);
            final HardwareBuffer buffer = screenshotBuffer == null ? null
                    : screenshotBuffer.getHardwareBuffer();
            if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
                // This can happen when display is not ready.
                Slog.w(TAG, "Failed to capture screenshot for " + mAnimatable);
                unfreeze(t);
                return;
            }
            mSnapshot = new Snapshot(t, screenshotBuffer, mLeash);
@@ -124,6 +130,11 @@ class SurfaceFreezer {
     * snapshot.
     */
    void unfreeze(SurfaceControl.Transaction t) {
        unfreezeInner(t);
        mAnimatable.onUnfrozen();
    }

    private void unfreezeInner(SurfaceControl.Transaction t) {
        if (mSnapshot != null) {
            mSnapshot.cancelAnimation(t, false /* restarting */);
            mSnapshot = null;
@@ -188,6 +199,18 @@ class SurfaceFreezer {
        return SurfaceControl.captureLayers(captureArgs);
    }

    @VisibleForTesting
    SurfaceControl.ScreenshotHardwareBuffer createSnapshotBufferInner(
            SurfaceControl target, Rect bounds) {
        return createSnapshotBuffer(target, bounds);
    }

    @VisibleForTesting
    GraphicBuffer createFromHardwareBufferInner(
            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) {
        return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer());
    }

    class Snapshot {
        private SurfaceControl mSurfaceControl;
        private AnimationAdapter mAnimation;
@@ -198,10 +221,7 @@ class SurfaceFreezer {
         */
        Snapshot(SurfaceControl.Transaction t,
                SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
            // We can't use a delegating constructor since we need to
            // reference this::onAnimationFinished
            GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
                    screenshotBuffer.getHardwareBuffer());
            GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer);

            mSurfaceControl = mAnimatable.makeAnimationLeash()
                    .setName("snapshot anim: " + mAnimatable.toString())
@@ -275,5 +295,8 @@ class SurfaceFreezer {
         *         will be generated (but the rest of the freezing logic will still happen).
         */
        @Nullable SurfaceControl getFreezeSnapshotTarget();

        /** Called when the {@link #unfreeze(SurfaceControl.Transaction)} is called. */
        void onUnfrozen();
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -614,7 +614,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        final DisplayContent dc = getDisplayContent();
        if (dc != null) {
            mSurfaceFreezer.unfreeze(getSyncTransaction());
            dc.mChangingContainers.remove(this);
        }
        while (!mChildren.isEmpty()) {
            final E child = mChildren.peekLast();
@@ -1067,9 +1066,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        // part of a change transition.
        if (!visible) {
            mSurfaceFreezer.unfreeze(getSyncTransaction());
            if (mDisplayContent != null) {
                mDisplayContent.mChangingContainers.remove(this);
            }
        }
        WindowContainer parent = getParent();
        if (parent != null) {
@@ -2647,6 +2643,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        return getSurfaceControl();
    }

    @Override
    public void onUnfrozen() {
        if (mDisplayContent != null) {
            mDisplayContent.mChangingContainers.remove(this);
        }
    }

    @Override
    public Builder makeAnimationLeash() {
        return makeSurface().setContainerLayer();
+1 −0
Original line number Diff line number Diff line
@@ -419,6 +419,7 @@ public class AppTransitionTests extends WindowTestsBase {
        task.getBounds(taskBounds);
        taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom);
        spyOn(taskFragment);
        mockSurfaceFreezerSnapshot(taskFragment.mSurfaceFreezer);

        assertTrue(mDc.mChangingContainers.isEmpty());
        assertFalse(mDc.mAppTransition.isTransitionSet());
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ public class TaskFragmentTest extends WindowTestsBase {

    @Test
    public void testStartChangeTransition_resetSurface() {
        mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
        final Rect startBounds = new Rect(0, 0, 1000, 1000);
        final Rect endBounds = new Rect(500, 500, 1000, 1000);
        mTaskFragment.setBounds(startBounds);
Loading