summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimationRunner.java269
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java1
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);