diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/SurfaceAnimationRunner.java | 269 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowContainer.java | 1 |
2 files changed, 3 insertions, 267 deletions
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index bbc35a35e93f..fba29d47d4d4 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.util.TimeUtils.NANOS_PER_MS; import static android.view.Choreographer.CALLBACK_TRAVERSAL; import static android.view.Choreographer.getSfInstance; @@ -27,25 +26,13 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.Nullable; -import android.graphics.BitmapShader; -import android.graphics.Canvas; -import android.graphics.Insets; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Rect; import android.hardware.power.Boost; import android.os.Handler; import android.os.PowerManagerInternal; -import android.os.Trace; import android.util.ArrayMap; -import android.util.Log; import android.view.Choreographer; -import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; -import android.view.animation.Animation; -import android.view.animation.Transformation; -import android.window.ScreenCapture; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -53,9 +40,6 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.server.AnimationThread; import com.android.server.wm.LocalAnimationAdapter.AnimationSpec; -import java.util.ArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.function.Supplier; /** @@ -73,12 +57,6 @@ class SurfaceAnimationRunner { */ private final Object mCancelLock = new Object(); - /** - * Lock for synchronizing {@link #mEdgeExtensions} to prevent race conditions when managing - * created edge extension surfaces. - */ - private final Object mEdgeExtensionLock = new Object(); - @VisibleForTesting Choreographer mChoreographer; @@ -91,12 +69,6 @@ class SurfaceAnimationRunner { private final PowerManagerInternal mPowerManagerInternal; private boolean mApplyScheduled; - // Executor to perform the edge extension. - // With two threads because in practice we will want to extend two surfaces in one animation, - // in which case we want to be able to parallelize those two extensions to cut down latency in - // starting the animation. - private final ExecutorService mEdgeExtensionExecutor = Executors.newFixedThreadPool(2); - @GuardedBy("mLock") @VisibleForTesting final ArrayMap<SurfaceControl, RunningAnimation> mPendingAnimations = new ArrayMap<>(); @@ -112,11 +84,6 @@ class SurfaceAnimationRunner { @GuardedBy("mLock") private boolean mAnimationStartDeferred; - // Mapping animation leashes to a list of edge extension surfaces associated with them - @GuardedBy("mEdgeExtensionLock") - private final ArrayMap<SurfaceControl, ArrayList<SurfaceControl>> mEdgeExtensions = - new ArrayMap<>(); - /** * There should only ever be one instance of this class. Usual spot for it is with * {@link WindowManagerService} @@ -175,64 +142,9 @@ class SurfaceAnimationRunner { synchronized (mLock) { final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash, finishCallback); - boolean requiresEdgeExtension = requiresEdgeExtension(a); - - if (requiresEdgeExtension) { - final ArrayList<SurfaceControl> extensionSurfaces = new ArrayList<>(); - synchronized (mEdgeExtensionLock) { - mEdgeExtensions.put(animationLeash, extensionSurfaces); - } - - mPreProcessingAnimations.put(animationLeash, runningAnim); - - // We must wait for t to be committed since otherwise the leash doesn't have the - // windows we want to screenshot and extend as children. - t.addTransactionCommittedListener(mEdgeExtensionExecutor, () -> { - if (!animationLeash.isValid()) { - Log.e(TAG, "Animation leash is not valid"); - synchronized (mEdgeExtensionLock) { - mEdgeExtensions.remove(animationLeash); - } - synchronized (mLock) { - mPreProcessingAnimations.remove(animationLeash); - } - return; - } - final WindowAnimationSpec animationSpec = a.asWindowAnimationSpec(); - - final Transaction edgeExtensionCreationTransaction = new Transaction(); - edgeExtendWindow(animationLeash, - animationSpec.getRootTaskBounds(), animationSpec.getAnimation(), - edgeExtensionCreationTransaction); - - synchronized (mLock) { - // only run if animation is not yet canceled by this point - if (mPreProcessingAnimations.get(animationLeash) == runningAnim) { - // In the case the animation is cancelled, edge extensions are removed - // onAnimationLeashLost which is called before onAnimationCancelled. - // So we need to check if the edge extensions have already been removed - // or not, and if so we don't want to apply the transaction. - synchronized (mEdgeExtensionLock) { - if (!mEdgeExtensions.isEmpty()) { - edgeExtensionCreationTransaction.apply(); - } - } - - mPreProcessingAnimations.remove(animationLeash); - mPendingAnimations.put(animationLeash, runningAnim); - if (!mAnimationStartDeferred && mPreProcessingAnimations.isEmpty()) { - mChoreographer.postFrameCallback(this::startAnimations); - } - } - } - }); - } - - if (!requiresEdgeExtension) { - mPendingAnimations.put(animationLeash, runningAnim); - if (!mAnimationStartDeferred && mPreProcessingAnimations.isEmpty()) { - mChoreographer.postFrameCallback(this::startAnimations); - } + mPendingAnimations.put(animationLeash, runningAnim); + if (!mAnimationStartDeferred && mPreProcessingAnimations.isEmpty()) { + mChoreographer.postFrameCallback(this::startAnimations); } // Some animations (e.g. move animations) require the initial transform to be @@ -241,10 +153,6 @@ class SurfaceAnimationRunner { } } - private boolean requiresEdgeExtension(AnimationSpec a) { - return a.asWindowAnimationSpec() != null && a.asWindowAnimationSpec().hasExtension(); - } - void onAnimationCancelled(SurfaceControl leash) { synchronized (mLock) { if (mPendingAnimations.containsKey(leash)) { @@ -374,161 +282,6 @@ class SurfaceAnimationRunner { mApplyScheduled = false; } - private void edgeExtendWindow(SurfaceControl leash, Rect bounds, Animation a, - Transaction transaction) { - final Transformation transformationAtStart = new Transformation(); - a.getTransformationAt(0, transformationAtStart); - final Transformation transformationAtEnd = new Transformation(); - a.getTransformationAt(1, transformationAtEnd); - - // We want to create an extension surface that is the maximal size and the animation will - // take care of cropping any part that overflows. - final Insets maxExtensionInsets = Insets.min( - transformationAtStart.getInsets(), transformationAtEnd.getInsets()); - - final int targetSurfaceHeight = bounds.height(); - final int targetSurfaceWidth = bounds.width(); - - if (maxExtensionInsets.left < 0) { - final Rect edgeBounds = new Rect(bounds.left, bounds.top, bounds.left + 1, - bounds.bottom); - final Rect extensionRect = new Rect(0, 0, - -maxExtensionInsets.left, targetSurfaceHeight); - final int xPos = bounds.left + maxExtensionInsets.left; - final int yPos = bounds.top; - createExtensionSurface(leash, edgeBounds, - extensionRect, xPos, yPos, "Left Edge Extension", transaction); - } - - if (maxExtensionInsets.top < 0) { - final Rect edgeBounds = new Rect(bounds.left, bounds.top, targetSurfaceWidth, - bounds.top + 1); - final Rect extensionRect = new Rect(0, 0, - targetSurfaceWidth, -maxExtensionInsets.top); - final int xPos = bounds.left; - final int yPos = bounds.top + maxExtensionInsets.top; - createExtensionSurface(leash, edgeBounds, - extensionRect, xPos, yPos, "Top Edge Extension", transaction); - } - - if (maxExtensionInsets.right < 0) { - final Rect edgeBounds = new Rect(bounds.right - 1, bounds.top, bounds.right, - bounds.bottom); - final Rect extensionRect = new Rect(0, 0, - -maxExtensionInsets.right, targetSurfaceHeight); - final int xPos = bounds.right; - final int yPos = bounds.top; - createExtensionSurface(leash, edgeBounds, - extensionRect, xPos, yPos, "Right Edge Extension", transaction); - } - - if (maxExtensionInsets.bottom < 0) { - final Rect edgeBounds = new Rect(bounds.left, bounds.bottom - 1, - bounds.right, bounds.bottom); - final Rect extensionRect = new Rect(0, 0, - targetSurfaceWidth, -maxExtensionInsets.bottom); - final int xPos = bounds.left; - final int yPos = bounds.bottom; - createExtensionSurface(leash, edgeBounds, - extensionRect, xPos, yPos, "Bottom Edge Extension", transaction); - } - } - - private void createExtensionSurface(SurfaceControl leash, Rect edgeBounds, - Rect extensionRect, int xPos, int yPos, String layerName, - Transaction startTransaction) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createExtensionSurface"); - doCreateExtensionSurface(leash, edgeBounds, extensionRect, xPos, yPos, layerName, - startTransaction); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - - private void doCreateExtensionSurface(SurfaceControl leash, Rect edgeBounds, - Rect extensionRect, int xPos, int yPos, String layerName, - Transaction startTransaction) { - ScreenCapture.LayerCaptureArgs captureArgs = - new ScreenCapture.LayerCaptureArgs.Builder(leash /* surfaceToExtend */) - .setSourceCrop(edgeBounds) - .setFrameScale(1) - .setPixelFormat(PixelFormat.RGBA_8888) - .setChildrenOnly(true) - .setAllowProtected(true) - .setCaptureSecureLayers(true) - .build(); - final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer = - ScreenCapture.captureLayers(captureArgs); - - if (edgeBuffer == null) { - // The leash we are trying to screenshot may have been removed by this point, which is - // likely the reason for ending up with a null edgeBuffer, in which case we just want to - // return and do nothing. - Log.e(TAG, "Failed to create edge extension - edge buffer is null"); - return; - } - - final SurfaceControl edgeExtensionLayer = new SurfaceControl.Builder() - .setName(layerName) - .setHidden(true) - .setCallsite("DefaultTransitionHandler#startAnimation") - .setOpaque(true) - .setBufferSize(extensionRect.width(), extensionRect.height()) - .build(); - - BitmapShader shader = new BitmapShader(edgeBuffer.asBitmap(), - android.graphics.Shader.TileMode.CLAMP, - android.graphics.Shader.TileMode.CLAMP); - final Paint paint = new Paint(); - paint.setShader(shader); - - final Surface surface = new Surface(edgeExtensionLayer); - Canvas c = surface.lockHardwareCanvas(); - c.drawRect(extensionRect, paint); - surface.unlockCanvasAndPost(c); - surface.release(); - - synchronized (mEdgeExtensionLock) { - if (!mEdgeExtensions.containsKey(leash)) { - // The animation leash has already been removed, so we don't want to attach the - // edgeExtension layer and should immediately remove it instead. - startTransaction.remove(edgeExtensionLayer); - return; - } - - startTransaction.reparent(edgeExtensionLayer, leash); - startTransaction.setLayer(edgeExtensionLayer, Integer.MIN_VALUE); - startTransaction.setPosition(edgeExtensionLayer, xPos, yPos); - startTransaction.setVisibility(edgeExtensionLayer, true); - - mEdgeExtensions.get(leash).add(edgeExtensionLayer); - } - } - - private float getScaleXForExtensionSurface(Rect edgeBounds, Rect extensionRect) { - if (edgeBounds.width() == extensionRect.width()) { - // Top or bottom edge extension, no need to scale the X axis of the extension surface. - return 1; - } - if (edgeBounds.width() == 1) { - // Left or right edge extension, scale the surface to be the extensionRect's width. - return extensionRect.width(); - } - - throw new RuntimeException("Unexpected edgeBounds and extensionRect widths"); - } - - private float getScaleYForExtensionSurface(Rect edgeBounds, Rect extensionRect) { - if (edgeBounds.height() == extensionRect.height()) { - // Left or right edge extension, no need to scale the Y axis of the extension surface. - return 1; - } - if (edgeBounds.height() == 1) { - // Top or bottom edge extension, scale the surface to be the extensionRect's height. - return extensionRect.height(); - } - - throw new RuntimeException("Unexpected edgeBounds and extensionRect heights"); - } - private static final class RunningAnimation { final AnimationSpec mAnimSpec; final SurfaceControl mLeash; @@ -545,22 +298,6 @@ class SurfaceAnimationRunner { } } - protected void onAnimationLeashLost(SurfaceControl animationLeash, - Transaction t) { - synchronized (mEdgeExtensionLock) { - if (!mEdgeExtensions.containsKey(animationLeash)) { - return; - } - - final ArrayList<SurfaceControl> edgeExtensions = mEdgeExtensions.get(animationLeash); - for (int i = 0; i < edgeExtensions.size(); i++) { - final SurfaceControl extension = edgeExtensions.get(i); - t.remove(extension); - } - mEdgeExtensions.remove(animationLeash); - } - } - @VisibleForTesting interface AnimatorFactory { ValueAnimator makeAnimator(); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 54a3d4179e3d..3c599b79400f 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3537,7 +3537,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< @Override public void onAnimationLeashLost(Transaction t) { mLastLayer = -1; - mWmService.mSurfaceAnimationRunner.onAnimationLeashLost(mAnimationLeash, t); mAnimationLeash = null; mNeedsZBoost = false; reassignLayer(t); |