Merge "Fix unfreeze on unstarted freezer" into sc-v2-dev
This commit is contained in:
@@ -57,8 +57,11 @@ class SurfaceAnimator {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
SurfaceControl mLeash;
|
SurfaceControl mLeash;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
SurfaceFreezer.Snapshot mSnapshot;
|
||||||
|
@VisibleForTesting
|
||||||
final Animatable mAnimatable;
|
final Animatable mAnimatable;
|
||||||
private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
|
@VisibleForTesting
|
||||||
|
final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static callback to run on all animations started through this SurfaceAnimator
|
* Static callback to run on all animations started through this SurfaceAnimator
|
||||||
@@ -151,12 +154,14 @@ class SurfaceAnimator {
|
|||||||
* @param animationFinishedCallback The callback being triggered when the animation finishes.
|
* @param animationFinishedCallback The callback being triggered when the animation finishes.
|
||||||
* @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a
|
* @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a
|
||||||
* cancel call to the underlying AnimationAdapter.
|
* cancel call to the underlying AnimationAdapter.
|
||||||
|
* @param snapshotAnim The animation to run for the snapshot. {@code null} if there is no
|
||||||
|
* snapshot.
|
||||||
*/
|
*/
|
||||||
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
||||||
@AnimationType int type,
|
@AnimationType int type,
|
||||||
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
|
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
|
||||||
@Nullable Runnable animationCancelledCallback,
|
@Nullable Runnable animationCancelledCallback,
|
||||||
@Nullable SurfaceFreezer freezer) {
|
@Nullable AnimationAdapter snapshotAnim, @Nullable SurfaceFreezer freezer) {
|
||||||
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
|
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
|
||||||
mAnimation = anim;
|
mAnimation = anim;
|
||||||
mAnimationType = type;
|
mAnimationType = type;
|
||||||
@@ -181,12 +186,16 @@ class SurfaceAnimator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
|
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
|
||||||
|
if (snapshotAnim != null) {
|
||||||
|
mSnapshot = freezer.takeSnapshotForAnimation();
|
||||||
|
mSnapshot.startAnimation(t, snapshotAnim, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
||||||
@AnimationType int type) {
|
@AnimationType int type) {
|
||||||
startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */,
|
startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */,
|
||||||
null /* animationCancelledCallback */, null /* freezer */);
|
null /* animationCancelledCallback */, null /* snapshotAnim */, null /* freezer */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,6 +337,7 @@ class SurfaceAnimator {
|
|||||||
final OnAnimationFinishedCallback animationFinishedCallback =
|
final OnAnimationFinishedCallback animationFinishedCallback =
|
||||||
mSurfaceAnimationFinishedCallback;
|
mSurfaceAnimationFinishedCallback;
|
||||||
final Runnable animationCancelledCallback = mAnimationCancelledCallback;
|
final Runnable animationCancelledCallback = mAnimationCancelledCallback;
|
||||||
|
final SurfaceFreezer.Snapshot snapshot = mSnapshot;
|
||||||
reset(t, false);
|
reset(t, false);
|
||||||
if (animation != null) {
|
if (animation != null) {
|
||||||
if (!mAnimationStartDelayed && forwardCancel) {
|
if (!mAnimationStartDelayed && forwardCancel) {
|
||||||
@@ -346,10 +356,15 @@ class SurfaceAnimator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forwardCancel && leash != null) {
|
if (forwardCancel) {
|
||||||
|
if (snapshot != null) {
|
||||||
|
snapshot.cancelAnimation(t, false /* restarting */);
|
||||||
|
}
|
||||||
|
if (leash != null) {
|
||||||
t.remove(leash);
|
t.remove(leash);
|
||||||
mService.scheduleAnimationLocked();
|
mService.scheduleAnimationLocked();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!restarting) {
|
if (!restarting) {
|
||||||
mAnimationStartDelayed = false;
|
mAnimationStartDelayed = false;
|
||||||
@@ -361,6 +376,12 @@ class SurfaceAnimator {
|
|||||||
mAnimation = null;
|
mAnimation = null;
|
||||||
mSurfaceAnimationFinishedCallback = null;
|
mSurfaceAnimationFinishedCallback = null;
|
||||||
mAnimationType = ANIMATION_TYPE_NONE;
|
mAnimationType = ANIMATION_TYPE_NONE;
|
||||||
|
final SurfaceFreezer.Snapshot snapshot = mSnapshot;
|
||||||
|
mSnapshot = null;
|
||||||
|
if (snapshot != null) {
|
||||||
|
// Reset the mSnapshot reference before calling the callback to prevent circular reset.
|
||||||
|
snapshot.cancelAnimation(t, !destroyLeash);
|
||||||
|
}
|
||||||
if (mLeash == null) {
|
if (mLeash == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -377,11 +398,15 @@ class SurfaceAnimator {
|
|||||||
boolean scheduleAnim = false;
|
boolean scheduleAnim = false;
|
||||||
final SurfaceControl surface = animatable.getSurfaceControl();
|
final SurfaceControl surface = animatable.getSurfaceControl();
|
||||||
final SurfaceControl parent = animatable.getParentSurfaceControl();
|
final SurfaceControl parent = animatable.getParentSurfaceControl();
|
||||||
|
final SurfaceControl curAnimationLeash = animatable.getAnimationLeash();
|
||||||
|
|
||||||
// If the surface was destroyed or the leash is invalid, we don't care to reparent it back.
|
// If the surface was destroyed or the leash is invalid, we don't care to reparent it back.
|
||||||
// Note that we also set this variable to true even if the parent isn't valid anymore, in
|
// Note that we also set this variable to true even if the parent isn't valid anymore, in
|
||||||
// order to ensure onAnimationLeashLost still gets called in this case.
|
// order to ensure onAnimationLeashLost still gets called in this case.
|
||||||
final boolean reparent = surface != null;
|
// If the animation leash is set, and it is different from the removing leash, it means the
|
||||||
|
// surface now has a new animation surface. We don't want to reparent for that.
|
||||||
|
final boolean reparent = surface != null && (curAnimationLeash == null
|
||||||
|
|| curAnimationLeash.equals(leash));
|
||||||
if (reparent) {
|
if (reparent) {
|
||||||
if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to original parent: " + parent);
|
if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to original parent: " + parent);
|
||||||
// We shouldn't really need these isValid checks but we do
|
// We shouldn't really need these isValid checks but we do
|
||||||
@@ -607,6 +632,14 @@ class SurfaceAnimator {
|
|||||||
*/
|
*/
|
||||||
void onAnimationLeashLost(Transaction t);
|
void onAnimationLeashLost(Transaction t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last created animation leash that has not lost yet.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default SurfaceControl getAnimationLeash() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A new surface to be used for the animation leash, inserted at the correct
|
* @return A new surface to be used for the animation leash, inserted at the correct
|
||||||
* position in the hierarchy.
|
* position in the hierarchy.
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
|
||||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
|
|
||||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
|
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -27,13 +26,11 @@ import android.graphics.PixelFormat;
|
|||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
import android.view.Surface;
|
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles "freezing" of an Animatable. The Animatable in question should implement
|
* This class handles "freezing" of an Animatable. The Animatable in question should implement
|
||||||
* Freezable.
|
* Freezable.
|
||||||
@@ -54,7 +51,8 @@ class SurfaceFreezer {
|
|||||||
|
|
||||||
private final Freezable mAnimatable;
|
private final Freezable mAnimatable;
|
||||||
private final WindowManagerService mWmService;
|
private final WindowManagerService mWmService;
|
||||||
private SurfaceControl mLeash;
|
@VisibleForTesting
|
||||||
|
SurfaceControl mLeash;
|
||||||
Snapshot mSnapshot = null;
|
Snapshot mSnapshot = null;
|
||||||
final Rect mFreezeBounds = new Rect();
|
final Rect mFreezeBounds = new Rect();
|
||||||
|
|
||||||
@@ -94,7 +92,7 @@ class SurfaceFreezer {
|
|||||||
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
|
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mSnapshot = new Snapshot(mWmService.mSurfaceFactory, t, screenshotBuffer, mLeash);
|
mSnapshot = new Snapshot(t, screenshotBuffer, mLeash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +106,18 @@ class SurfaceFreezer {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by {@link SurfaceAnimator}. This "transfers" the snapshot leash to be used for
|
||||||
|
* animation. By transferring the leash, this will no longer try to clean-up the leash when
|
||||||
|
* finished.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Snapshot takeSnapshotForAnimation() {
|
||||||
|
final Snapshot out = mSnapshot;
|
||||||
|
mSnapshot = null;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean-up the snapshot and remove leash. If the leash was taken, this just cleans-up the
|
* Clean-up the snapshot and remove leash. If the leash was taken, this just cleans-up the
|
||||||
* snapshot.
|
* snapshot.
|
||||||
@@ -115,6 +125,7 @@ class SurfaceFreezer {
|
|||||||
void unfreeze(SurfaceControl.Transaction t) {
|
void unfreeze(SurfaceControl.Transaction t) {
|
||||||
if (mSnapshot != null) {
|
if (mSnapshot != null) {
|
||||||
mSnapshot.cancelAnimation(t, false /* restarting */);
|
mSnapshot.cancelAnimation(t, false /* restarting */);
|
||||||
|
mSnapshot = null;
|
||||||
}
|
}
|
||||||
if (mLeash == null) {
|
if (mLeash == null) {
|
||||||
return;
|
return;
|
||||||
@@ -163,13 +174,12 @@ class SurfaceFreezer {
|
|||||||
class Snapshot {
|
class Snapshot {
|
||||||
private SurfaceControl mSurfaceControl;
|
private SurfaceControl mSurfaceControl;
|
||||||
private AnimationAdapter mAnimation;
|
private AnimationAdapter mAnimation;
|
||||||
private SurfaceAnimator.OnAnimationFinishedCallback mFinishedCallback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param t Transaction to create the thumbnail in.
|
* @param t Transaction to create the thumbnail in.
|
||||||
* @param screenshotBuffer A thumbnail or placeholder for thumbnail to initialize with.
|
* @param screenshotBuffer A thumbnail or placeholder for thumbnail to initialize with.
|
||||||
*/
|
*/
|
||||||
Snapshot(Supplier<Surface> surfaceFactory, SurfaceControl.Transaction t,
|
Snapshot(SurfaceControl.Transaction t,
|
||||||
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
|
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
|
||||||
// We can't use a delegating constructor since we need to
|
// We can't use a delegating constructor since we need to
|
||||||
// reference this::onAnimationFinished
|
// reference this::onAnimationFinished
|
||||||
@@ -211,19 +221,15 @@ class SurfaceFreezer {
|
|||||||
* component responsible for running the animation. It runs the animation with
|
* component responsible for running the animation. It runs the animation with
|
||||||
* {@link AnimationAdapter#startAnimation} once the hierarchy with
|
* {@link AnimationAdapter#startAnimation} once the hierarchy with
|
||||||
* the Leash has been set up.
|
* the Leash has been set up.
|
||||||
* @param animationFinishedCallback The callback being triggered when the animation
|
|
||||||
* finishes.
|
|
||||||
*/
|
*/
|
||||||
void startAnimation(SurfaceControl.Transaction t, AnimationAdapter anim, int type,
|
void startAnimation(SurfaceControl.Transaction t, AnimationAdapter anim, int type) {
|
||||||
@Nullable SurfaceAnimator.OnAnimationFinishedCallback animationFinishedCallback) {
|
|
||||||
cancelAnimation(t, true /* restarting */);
|
cancelAnimation(t, true /* restarting */);
|
||||||
mAnimation = anim;
|
mAnimation = anim;
|
||||||
mFinishedCallback = animationFinishedCallback;
|
|
||||||
if (mSurfaceControl == null) {
|
if (mSurfaceControl == null) {
|
||||||
cancelAnimation(t, false /* restarting */);
|
cancelAnimation(t, false /* restarting */);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAnimation.startAnimation(mSurfaceControl, t, type, animationFinishedCallback);
|
mAnimation.startAnimation(mSurfaceControl, t, type, null /* finishCallback */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -235,18 +241,9 @@ class SurfaceFreezer {
|
|||||||
void cancelAnimation(SurfaceControl.Transaction t, boolean restarting) {
|
void cancelAnimation(SurfaceControl.Transaction t, boolean restarting) {
|
||||||
final SurfaceControl leash = mSurfaceControl;
|
final SurfaceControl leash = mSurfaceControl;
|
||||||
final AnimationAdapter animation = mAnimation;
|
final AnimationAdapter animation = mAnimation;
|
||||||
final SurfaceAnimator.OnAnimationFinishedCallback animationFinishedCallback =
|
|
||||||
mFinishedCallback;
|
|
||||||
mAnimation = null;
|
mAnimation = null;
|
||||||
mFinishedCallback = null;
|
|
||||||
if (animation != null) {
|
if (animation != null) {
|
||||||
animation.onAnimationCancelled(leash);
|
animation.onAnimationCancelled(leash);
|
||||||
if (!restarting) {
|
|
||||||
if (animationFinishedCallback != null) {
|
|
||||||
animationFinishedCallback.onAnimationFinished(
|
|
||||||
ANIMATION_TYPE_APP_TRANSITION, animation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!restarting) {
|
if (!restarting) {
|
||||||
destroy(t);
|
destroy(t);
|
||||||
|
|||||||
@@ -178,6 +178,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
*/
|
*/
|
||||||
protected final SurfaceAnimator mSurfaceAnimator;
|
protected final SurfaceAnimator mSurfaceAnimator;
|
||||||
|
|
||||||
|
/** The parent leash added for animation. */
|
||||||
|
@Nullable
|
||||||
|
private SurfaceControl mAnimationLeash;
|
||||||
|
|
||||||
final SurfaceFreezer mSurfaceFreezer;
|
final SurfaceFreezer mSurfaceFreezer;
|
||||||
protected final WindowManagerService mWmService;
|
protected final WindowManagerService mWmService;
|
||||||
final TransitionController mTransitionController;
|
final TransitionController mTransitionController;
|
||||||
@@ -2561,11 +2565,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
* @param animationFinishedCallback The callback being triggered when the animation finishes.
|
* @param animationFinishedCallback The callback being triggered when the animation finishes.
|
||||||
* @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a
|
* @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a
|
||||||
* cancel call to the underlying AnimationAdapter.
|
* cancel call to the underlying AnimationAdapter.
|
||||||
|
* @param snapshotAnim The animation to run for the snapshot. {@code null} if there is no
|
||||||
|
* snapshot.
|
||||||
*/
|
*/
|
||||||
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
||||||
@AnimationType int type,
|
@AnimationType int type,
|
||||||
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
|
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
|
||||||
@Nullable Runnable animationCancelledCallback) {
|
@Nullable Runnable animationCancelledCallback,
|
||||||
|
@Nullable AnimationAdapter snapshotAnim) {
|
||||||
if (DEBUG_ANIM) {
|
if (DEBUG_ANIM) {
|
||||||
Slog.v(TAG, "Starting animation on " + this + ": type=" + type + ", anim=" + anim);
|
Slog.v(TAG, "Starting animation on " + this + ": type=" + type + ", anim=" + anim);
|
||||||
}
|
}
|
||||||
@@ -2573,14 +2580,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
// TODO: This should use isVisible() but because isVisible has a really weird meaning at
|
// TODO: This should use isVisible() but because isVisible has a really weird meaning at
|
||||||
// the moment this doesn't work for all animatable window containers.
|
// the moment this doesn't work for all animatable window containers.
|
||||||
mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback,
|
mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback,
|
||||||
animationCancelledCallback, mSurfaceFreezer);
|
animationCancelledCallback, snapshotAnim, mSurfaceFreezer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
||||||
@AnimationType int type,
|
@AnimationType int type,
|
||||||
@Nullable OnAnimationFinishedCallback animationFinishedCallback) {
|
@Nullable OnAnimationFinishedCallback animationFinishedCallback) {
|
||||||
startAnimation(t, anim, hidden, type, animationFinishedCallback,
|
startAnimation(t, anim, hidden, type, animationFinishedCallback,
|
||||||
null /* adapterAnimationCancelledCallback */);
|
null /* adapterAnimationCancelledCallback */, null /* snapshotAnim */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
|
||||||
@@ -2832,17 +2839,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
? taskDisplayArea::clearBackgroundColor : () -> {};
|
? taskDisplayArea::clearBackgroundColor : () -> {};
|
||||||
|
|
||||||
startAnimation(getPendingTransaction(), adapter, !isVisible(),
|
startAnimation(getPendingTransaction(), adapter, !isVisible(),
|
||||||
ANIMATION_TYPE_APP_TRANSITION,
|
ANIMATION_TYPE_APP_TRANSITION, (type, anim) -> cleanUpCallback.run(),
|
||||||
(type, anim) -> cleanUpCallback.run(),
|
cleanUpCallback, thumbnailAdapter);
|
||||||
cleanUpCallback);
|
|
||||||
|
|
||||||
if (adapter.getShowWallpaper()) {
|
if (adapter.getShowWallpaper()) {
|
||||||
getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
|
getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
|
||||||
}
|
}
|
||||||
if (thumbnailAdapter != null) {
|
|
||||||
mSurfaceFreezer.mSnapshot.startAnimation(getPendingTransaction(),
|
|
||||||
thumbnailAdapter, ANIMATION_TYPE_APP_TRANSITION, (type, anim) -> { });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2972,6 +2974,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
@Override
|
@Override
|
||||||
public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
|
public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
|
||||||
mLastLayer = -1;
|
mLastLayer = -1;
|
||||||
|
mAnimationLeash = leash;
|
||||||
reassignLayer(t);
|
reassignLayer(t);
|
||||||
|
|
||||||
// Leash is now responsible for position, so set our position to 0.
|
// Leash is now responsible for position, so set our position to 0.
|
||||||
@@ -2981,11 +2984,16 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
@Override
|
@Override
|
||||||
public void onAnimationLeashLost(Transaction t) {
|
public void onAnimationLeashLost(Transaction t) {
|
||||||
mLastLayer = -1;
|
mLastLayer = -1;
|
||||||
mSurfaceFreezer.unfreeze(t);
|
mAnimationLeash = null;
|
||||||
reassignLayer(t);
|
reassignLayer(t);
|
||||||
updateSurfacePosition(t);
|
updateSurfacePosition(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SurfaceControl getAnimationLeash() {
|
||||||
|
return mAnimationLeash;
|
||||||
|
}
|
||||||
|
|
||||||
private void doAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
|
private void doAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
|
||||||
for (int i = 0; i < mSurfaceAnimationSources.size(); ++i) {
|
for (int i = 0; i < mSurfaceAnimationSources.size(); ++i) {
|
||||||
mSurfaceAnimationSources.valueAt(i).onAnimationFinished(type, anim);
|
mSurfaceAnimationSources.valueAt(i).onAnimationFinished(type, anim);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
|||||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
|
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
|
||||||
@@ -52,6 +53,7 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -1106,6 +1108,71 @@ public class WindowContainerTests extends WindowTestsBase {
|
|||||||
verify(surfaceAnimator, never()).setRelativeLayer(any(), any(), anyInt());
|
verify(surfaceAnimator, never()).setRelativeLayer(any(), any(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartChangeTransitionWhenPreviousIsNotFinished() {
|
||||||
|
final WindowContainer container = createTaskFragmentWithParentTask(
|
||||||
|
createTask(mDisplayContent), false);
|
||||||
|
container.mSurfaceControl = mock(SurfaceControl.class);
|
||||||
|
final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator;
|
||||||
|
final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
|
||||||
|
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
|
||||||
|
spyOn(container);
|
||||||
|
spyOn(surfaceAnimator);
|
||||||
|
spyOn(surfaceFreezer);
|
||||||
|
doReturn(t).when(container).getPendingTransaction();
|
||||||
|
doReturn(t).when(container).getSyncTransaction();
|
||||||
|
|
||||||
|
// Leash and snapshot created for change transition.
|
||||||
|
container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
|
||||||
|
// Can't really take a snapshot, manually set one.
|
||||||
|
surfaceFreezer.mSnapshot = mock(SurfaceFreezer.Snapshot.class);
|
||||||
|
|
||||||
|
assertNotNull(surfaceFreezer.mLeash);
|
||||||
|
assertEquals(surfaceFreezer.mLeash, container.getAnimationLeash());
|
||||||
|
|
||||||
|
// Start animation: surfaceAnimator take over the leash and snapshot from surfaceFreezer.
|
||||||
|
container.applyAnimationUnchecked(null /* lp */, true /* enter */,
|
||||||
|
TRANSIT_OLD_TASK_FRAGMENT_CHANGE, false /* isVoiceInteraction */,
|
||||||
|
null /* sources */);
|
||||||
|
|
||||||
|
assertNull(surfaceFreezer.mLeash);
|
||||||
|
assertNull(surfaceFreezer.mSnapshot);
|
||||||
|
assertNotNull(surfaceAnimator.mLeash);
|
||||||
|
assertNotNull(surfaceAnimator.mSnapshot);
|
||||||
|
final SurfaceControl prevLeash = surfaceAnimator.mLeash;
|
||||||
|
final SurfaceFreezer.Snapshot prevSnapshot = surfaceAnimator.mSnapshot;
|
||||||
|
|
||||||
|
// Prepare another change transition.
|
||||||
|
container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
|
||||||
|
surfaceFreezer.mSnapshot = mock(SurfaceFreezer.Snapshot.class);
|
||||||
|
|
||||||
|
assertNotNull(surfaceFreezer.mLeash);
|
||||||
|
assertEquals(surfaceFreezer.mLeash, container.getAnimationLeash());
|
||||||
|
assertNotEquals(prevLeash, container.getAnimationLeash());
|
||||||
|
|
||||||
|
// Start another animation before the previous one is finished, it should reset the previous
|
||||||
|
// one, but not change the current one.
|
||||||
|
container.applyAnimationUnchecked(null /* lp */, true /* enter */,
|
||||||
|
TRANSIT_OLD_TASK_FRAGMENT_CHANGE, false /* isVoiceInteraction */,
|
||||||
|
null /* sources */);
|
||||||
|
|
||||||
|
verify(container, never()).onAnimationLeashLost(any());
|
||||||
|
verify(surfaceFreezer, never()).unfreeze(any());
|
||||||
|
assertNotNull(surfaceAnimator.mLeash);
|
||||||
|
assertNotNull(surfaceAnimator.mSnapshot);
|
||||||
|
assertEquals(surfaceAnimator.mLeash, container.getAnimationLeash());
|
||||||
|
assertNotEquals(prevLeash, surfaceAnimator.mLeash);
|
||||||
|
assertNotEquals(prevSnapshot, surfaceAnimator.mSnapshot);
|
||||||
|
|
||||||
|
// Clean up after animation finished.
|
||||||
|
surfaceAnimator.mInnerAnimationFinishedCallback.onAnimationFinished(
|
||||||
|
ANIMATION_TYPE_APP_TRANSITION, surfaceAnimator.getAnimation());
|
||||||
|
|
||||||
|
verify(container).onAnimationLeashLost(any());
|
||||||
|
assertNull(surfaceAnimator.mLeash);
|
||||||
|
assertNull(surfaceAnimator.mSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
|
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
|
||||||
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
|
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
|
||||||
private final int mLayer;
|
private final int mLayer;
|
||||||
|
|||||||
Reference in New Issue
Block a user