Merge changes from topic "t-activity-backport" into tm-dev
* changes: Use new T activity transitions in legacy Backport window extension animation support
This commit is contained in:
@@ -98,10 +98,6 @@ public class TransitionAnimation {
|
||||
|
||||
private static final String DEFAULT_PACKAGE = "android";
|
||||
|
||||
// TODO (b/215515255): remove once we full migrate to shell transitions
|
||||
private static final boolean SHELL_TRANSITIONS_ENABLED =
|
||||
SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
|
||||
|
||||
private final Context mContext;
|
||||
private final String mTag;
|
||||
|
||||
@@ -256,9 +252,6 @@ public class TransitionAnimation {
|
||||
resId = ent.array.getResourceId(animAttr, 0);
|
||||
}
|
||||
}
|
||||
if (!SHELL_TRANSITIONS_ENABLED) {
|
||||
resId = updateToLegacyIfNeeded(resId);
|
||||
}
|
||||
resId = updateToTranslucentAnimIfNeeded(resId, transit);
|
||||
if (ResourceId.isValid(resId)) {
|
||||
return loadAnimationSafely(context, resId, mTag);
|
||||
@@ -266,24 +259,6 @@ public class TransitionAnimation {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace animations that are not compatible with the legacy transition system with ones that
|
||||
* are compatible with it.
|
||||
* TODO (b/215515255): remove once we full migrate to shell transitions
|
||||
*/
|
||||
private int updateToLegacyIfNeeded(int anim) {
|
||||
if (anim == R.anim.activity_open_enter) {
|
||||
return R.anim.activity_open_enter_legacy;
|
||||
} else if (anim == R.anim.activity_open_exit) {
|
||||
return R.anim.activity_open_exit_legacy;
|
||||
} else if (anim == R.anim.activity_close_enter) {
|
||||
return R.anim.activity_close_enter_legacy;
|
||||
} else if (anim == R.anim.activity_close_exit) {
|
||||
return R.anim.activity_close_exit_legacy;
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
/** Load animation by attribute Id from a specific AnimationStyle resource. */
|
||||
@Nullable
|
||||
public Animation loadAnimationAttr(String packageName, int animStyleResId, int animAttr,
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2009, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false">
|
||||
<scale
|
||||
android:fromXScale="1.1"
|
||||
android:toXScale="1"
|
||||
android:fromYScale="1.1"
|
||||
android:toYScale="1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/fast_out_extra_slow_in"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2009, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false"
|
||||
android:zAdjustment="top">
|
||||
<alpha
|
||||
android:fromAlpha="1"
|
||||
android:toAlpha="0.0"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/linear"
|
||||
android:startOffset="33"
|
||||
android:duration="50"/>
|
||||
<scale
|
||||
android:fromXScale="1"
|
||||
android:toXScale="0.9"
|
||||
android:fromYScale="1"
|
||||
android:toYScale="0.9"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/fast_out_extra_slow_in"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
/*
|
||||
** Copyright 2009, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false">
|
||||
<alpha
|
||||
android:fromAlpha="0"
|
||||
android:toAlpha="1.0"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/linear"
|
||||
android:startOffset="50"
|
||||
android:duration="50"/>
|
||||
<scale
|
||||
android:fromXScale="0.85"
|
||||
android:toXScale="1"
|
||||
android:fromYScale="0.85"
|
||||
android:toYScale="1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/fast_out_extra_slow_in"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
/*
|
||||
** Copyright 2009, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false">
|
||||
|
||||
<!-- Fade out, over a black surface, which simulates a black scrim -->
|
||||
<alpha
|
||||
android:fromAlpha="1"
|
||||
android:toAlpha="0.4"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/linear"
|
||||
android:startOffset="83"
|
||||
android:duration="167"/>
|
||||
|
||||
<scale
|
||||
android:fromXScale="1"
|
||||
android:toXScale="1.05"
|
||||
android:fromYScale="1"
|
||||
android:toYScale="1.05"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fillEnabled="true"
|
||||
android:fillBefore="true"
|
||||
android:fillAfter="true"
|
||||
android:interpolator="@interpolator/fast_out_extra_slow_in"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1713,10 +1713,6 @@
|
||||
<java-symbol type="anim" name="activity_open_exit" />
|
||||
<java-symbol type="anim" name="activity_close_enter" />
|
||||
<java-symbol type="anim" name="activity_close_exit" />
|
||||
<java-symbol type="anim" name="activity_open_enter_legacy" />
|
||||
<java-symbol type="anim" name="activity_open_exit_legacy" />
|
||||
<java-symbol type="anim" name="activity_close_enter_legacy" />
|
||||
<java-symbol type="anim" name="activity_close_exit_legacy" />
|
||||
<java-symbol type="anim" name="task_fragment_close_enter" />
|
||||
<java-symbol type="anim" name="task_fragment_close_exit" />
|
||||
<java-symbol type="anim" name="task_fragment_open_enter" />
|
||||
|
||||
@@ -174,5 +174,9 @@ class LocalAnimationAdapter implements AnimationAdapter {
|
||||
}
|
||||
|
||||
void dumpDebugInner(ProtoOutputStream proto);
|
||||
|
||||
default WindowAnimationSpec asWindowAnimationSpec() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,22 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.Nullable;
|
||||
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.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 com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -40,6 +49,8 @@ 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.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@@ -71,6 +82,10 @@ class SurfaceAnimationRunner {
|
||||
@VisibleForTesting
|
||||
final ArrayMap<SurfaceControl, RunningAnimation> mPendingAnimations = new ArrayMap<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@VisibleForTesting
|
||||
final ArrayMap<SurfaceControl, RunningAnimation> mPreProcessingAnimations = new ArrayMap<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@VisibleForTesting
|
||||
final ArrayMap<SurfaceControl, RunningAnimation> mRunningAnimations = new ArrayMap<>();
|
||||
@@ -136,23 +151,64 @@ class SurfaceAnimationRunner {
|
||||
synchronized (mLock) {
|
||||
final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
|
||||
finishCallback);
|
||||
mPendingAnimations.put(animationLeash, runningAnim);
|
||||
if (!mAnimationStartDeferred) {
|
||||
mChoreographer.postFrameCallback(this::startAnimations);
|
||||
boolean requiresEdgeExtension = requiresEdgeExtension(a);
|
||||
|
||||
if (requiresEdgeExtension) {
|
||||
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(Runnable::run, () -> {
|
||||
final WindowAnimationSpec animationSpec = a.asWindowAnimationSpec();
|
||||
final Runnable cleanUpEdgeExtension = edgeExtendWindow(animationLeash,
|
||||
animationSpec.getRootTaskBounds(), animationSpec.getAnimation(),
|
||||
mFrameTransaction);
|
||||
|
||||
runningAnim.mFinishCallback = () -> {
|
||||
cleanUpEdgeExtension.run();
|
||||
finishCallback.run();
|
||||
};
|
||||
|
||||
synchronized (mLock) {
|
||||
// only run if animation is not yet canceled by this point
|
||||
if (mPreProcessingAnimations.get(animationLeash) == runningAnim) {
|
||||
mPreProcessingAnimations.remove(animationLeash);
|
||||
mPendingAnimations.put(animationLeash, runningAnim);
|
||||
if (!mAnimationStartDeferred) {
|
||||
mChoreographer.postFrameCallback(this::startAnimations);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Some animations (e.g. move animations) require the initial transform to be applied
|
||||
// immediately.
|
||||
applyTransformation(runningAnim, t, 0 /* currentPlayTime */);
|
||||
if (!requiresEdgeExtension) {
|
||||
mPendingAnimations.put(animationLeash, runningAnim);
|
||||
if (!mAnimationStartDeferred) {
|
||||
mChoreographer.postFrameCallback(this::startAnimations);
|
||||
}
|
||||
|
||||
// Some animations (e.g. move animations) require the initial transform to be
|
||||
// applied immediately.
|
||||
applyTransformation(runningAnim, t, 0 /* currentPlayTime */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requiresEdgeExtension(AnimationSpec a) {
|
||||
return a.asWindowAnimationSpec() != null && a.asWindowAnimationSpec().hasExtension();
|
||||
}
|
||||
|
||||
void onAnimationCancelled(SurfaceControl leash) {
|
||||
synchronized (mLock) {
|
||||
if (mPendingAnimations.containsKey(leash)) {
|
||||
mPendingAnimations.remove(leash);
|
||||
return;
|
||||
}
|
||||
if (mPreProcessingAnimations.containsKey(leash)) {
|
||||
mPreProcessingAnimations.remove(leash);
|
||||
return;
|
||||
}
|
||||
final RunningAnimation anim = mRunningAnimations.get(leash);
|
||||
if (anim != null) {
|
||||
mRunningAnimations.remove(leash);
|
||||
@@ -264,10 +320,133 @@ class SurfaceAnimationRunner {
|
||||
mApplyScheduled = false;
|
||||
}
|
||||
|
||||
private Runnable 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();
|
||||
|
||||
final List<SurfaceControl> extensionSurfaces = new ArrayList<>();
|
||||
|
||||
if (maxExtensionInsets.left < 0) {
|
||||
final Rect edgeBounds = new Rect(0, 0, 1, targetSurfaceHeight);
|
||||
final Rect extensionRect = new Rect(0, 0,
|
||||
-maxExtensionInsets.left, targetSurfaceHeight);
|
||||
final int xPos = maxExtensionInsets.left;
|
||||
final int yPos = 0;
|
||||
final SurfaceControl extensionSurface = createExtensionSurface(leash, edgeBounds,
|
||||
extensionRect, xPos, yPos, "Left Edge Extension", transaction);
|
||||
extensionSurfaces.add(extensionSurface);
|
||||
}
|
||||
|
||||
if (maxExtensionInsets.top < 0) {
|
||||
final Rect edgeBounds = new Rect(0, 0, targetSurfaceWidth, 1);
|
||||
final Rect extensionRect = new Rect(0, 0,
|
||||
targetSurfaceWidth, -maxExtensionInsets.top);
|
||||
final int xPos = 0;
|
||||
final int yPos = maxExtensionInsets.top;
|
||||
final SurfaceControl extensionSurface = createExtensionSurface(leash, edgeBounds,
|
||||
extensionRect, xPos, yPos, "Top Edge Extension", transaction);
|
||||
extensionSurfaces.add(extensionSurface);
|
||||
}
|
||||
|
||||
if (maxExtensionInsets.right < 0) {
|
||||
final Rect edgeBounds = new Rect(targetSurfaceWidth - 1, 0,
|
||||
targetSurfaceWidth, targetSurfaceHeight);
|
||||
final Rect extensionRect = new Rect(0, 0,
|
||||
-maxExtensionInsets.right, targetSurfaceHeight);
|
||||
final int xPos = targetSurfaceWidth;
|
||||
final int yPos = 0;
|
||||
final SurfaceControl extensionSurface = createExtensionSurface(leash, edgeBounds,
|
||||
extensionRect, xPos, yPos, "Right Edge Extension", transaction);
|
||||
extensionSurfaces.add(extensionSurface);
|
||||
}
|
||||
|
||||
if (maxExtensionInsets.bottom < 0) {
|
||||
final Rect edgeBounds = new Rect(0, targetSurfaceHeight - 1,
|
||||
targetSurfaceWidth, targetSurfaceHeight);
|
||||
final Rect extensionRect = new Rect(0, 0,
|
||||
targetSurfaceWidth, -maxExtensionInsets.bottom);
|
||||
final int xPos = maxExtensionInsets.left;
|
||||
final int yPos = targetSurfaceHeight;
|
||||
final SurfaceControl extensionSurface = createExtensionSurface(leash, edgeBounds,
|
||||
extensionRect, xPos, yPos, "Bottom Edge Extension", transaction);
|
||||
extensionSurfaces.add(extensionSurface);
|
||||
}
|
||||
|
||||
Runnable cleanUp = () -> {
|
||||
for (final SurfaceControl extensionSurface : extensionSurfaces) {
|
||||
if (extensionSurface != null) {
|
||||
transaction.remove(extensionSurface);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return cleanUp;
|
||||
}
|
||||
|
||||
private SurfaceControl createExtensionSurface(SurfaceControl surfaceToExtend, Rect edgeBounds,
|
||||
Rect extensionRect, int xPos, int yPos, String layerName,
|
||||
Transaction startTransaction) {
|
||||
final SurfaceControl edgeExtensionLayer = new SurfaceControl.Builder()
|
||||
.setName(layerName)
|
||||
.setParent(surfaceToExtend)
|
||||
.setHidden(true)
|
||||
.setCallsite("DefaultTransitionHandler#startAnimation")
|
||||
.setOpaque(true)
|
||||
.setBufferSize(extensionRect.width(), extensionRect.height())
|
||||
.build();
|
||||
|
||||
SurfaceControl.LayerCaptureArgs captureArgs =
|
||||
new SurfaceControl.LayerCaptureArgs.Builder(surfaceToExtend)
|
||||
.setSourceCrop(edgeBounds)
|
||||
.setFrameScale(1)
|
||||
.setPixelFormat(PixelFormat.RGBA_8888)
|
||||
.setChildrenOnly(true)
|
||||
.setAllowProtected(true)
|
||||
.build();
|
||||
final SurfaceControl.ScreenshotHardwareBuffer edgeBuffer =
|
||||
SurfaceControl.captureLayers(captureArgs);
|
||||
|
||||
if (edgeBuffer == null) {
|
||||
Log.e("SurfaceAnimationRunner", "Failed to create edge extension - "
|
||||
+ "edge buffer is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
android.graphics.BitmapShader shader =
|
||||
new android.graphics.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();
|
||||
|
||||
startTransaction.setLayer(edgeExtensionLayer, Integer.MIN_VALUE);
|
||||
startTransaction.setPosition(edgeExtensionLayer, xPos, yPos);
|
||||
startTransaction.setVisibility(edgeExtensionLayer, true);
|
||||
|
||||
return edgeExtensionLayer;
|
||||
}
|
||||
|
||||
private static final class RunningAnimation {
|
||||
final AnimationSpec mAnimSpec;
|
||||
final SurfaceControl mLeash;
|
||||
final Runnable mFinishCallback;
|
||||
Runnable mFinishCallback;
|
||||
ValueAnimator mAnim;
|
||||
|
||||
@GuardedBy("mCancelLock")
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.server.wm.AnimationSpecProto.WINDOW;
|
||||
import static com.android.server.wm.WindowAnimationSpecProto.ANIMATION;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
|
||||
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.SystemClock;
|
||||
@@ -74,6 +75,11 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowAnimationSpec asWindowAnimationSpec() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getShowWallpaper() {
|
||||
return mAnimation.getShowWallpaper();
|
||||
@@ -89,11 +95,27 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
return mAnimation.getBackgroundColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If a window animation has outsets applied to it.
|
||||
* @see Animation#hasExtension()
|
||||
*/
|
||||
public boolean hasExtension() {
|
||||
return mAnimation.hasExtension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
return mAnimation.computeDurationHint();
|
||||
}
|
||||
|
||||
public Rect getRootTaskBounds() {
|
||||
return mRootTaskBounds;
|
||||
}
|
||||
|
||||
public Animation getAnimation() {
|
||||
return mAnimation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
|
||||
final TmpValues tmp = mThreadLocalTmps.get();
|
||||
@@ -106,7 +128,9 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
boolean cropSet = false;
|
||||
if (mRootTaskClipMode == ROOT_TASK_CLIP_NONE) {
|
||||
if (tmp.transformation.hasClipRect()) {
|
||||
t.setWindowCrop(leash, tmp.transformation.getClipRect());
|
||||
final Rect clipRect = tmp.transformation.getClipRect();
|
||||
accountForExtension(tmp.transformation, clipRect);
|
||||
t.setWindowCrop(leash, clipRect);
|
||||
cropSet = true;
|
||||
}
|
||||
} else {
|
||||
@@ -114,6 +138,7 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
if (tmp.transformation.hasClipRect()) {
|
||||
mTmpRect.intersect(tmp.transformation.getClipRect());
|
||||
}
|
||||
accountForExtension(tmp.transformation, mTmpRect);
|
||||
t.setWindowCrop(leash, mTmpRect);
|
||||
cropSet = true;
|
||||
}
|
||||
@@ -125,6 +150,14 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
}
|
||||
}
|
||||
|
||||
private void accountForExtension(Transformation transformation, Rect clipRect) {
|
||||
Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE);
|
||||
if (!extensionInsets.equals(Insets.NONE)) {
|
||||
// Extend the surface to allow for the edge extension to be visible
|
||||
clipRect.inset(extensionInsets);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long calculateStatusBarTransitionStartTime() {
|
||||
TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);
|
||||
|
||||
Reference in New Issue
Block a user