summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/SplashScreenView.java20
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java137
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java43
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java10
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java85
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java13
8 files changed, 182 insertions, 147 deletions
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 933760c8bf18..8debe5d569a3 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -70,6 +70,7 @@ public final class SplashScreenView extends FrameLayout {
private static final boolean DEBUG = false;
private boolean mNotCopyable;
+ private boolean mRevealAnimationSupported = true;
private int mInitBackgroundColor;
private int mInitIconBackgroundColor;
private View mIconView;
@@ -264,6 +265,25 @@ public final class SplashScreenView extends FrameLayout {
}
/**
+ * If set to true, indicates to the system that this view can be dismissed by playing the
+ * Reveal animation.
+ * <p>
+ * If the exit animation is handled by the client, the animation won't be played anyway.
+ * @hide
+ */
+ public void setRevealAnimationSupported(boolean support) {
+ mRevealAnimationSupported = support;
+ }
+
+ /**
+ * Whether this view support reveal animation.
+ * @hide
+ */
+ public boolean isRevealAnimationSupported() {
+ return mRevealAnimationSupported;
+ }
+
+ /**
* Returns the duration of the icon animation if icon is animatable.
*
* @see android.R.attr#windowSplashScreenAnimatedIcon
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index e8757b5d96f4..edf000b5e68a 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -52,9 +52,6 @@
when the PIP menu is shown in center. -->
<string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
- <!-- Animation duration when exit starting window: icon going away -->
- <integer name="starting_window_icon_exit_anim_duration">166</integer>
-
<!-- Animation duration when exit starting window: reveal app -->
<integer name="starting_window_app_reveal_anim_duration">333</integer>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
index 5bc2afd11fe8..3fe57c61c0bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.startingsurface;
+import static android.view.Choreographer.CALLBACK_COMMIT;
import static android.view.View.GONE;
import android.animation.Animator;
@@ -29,13 +30,12 @@ import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.Slog;
+import android.view.Choreographer;
import android.view.SurfaceControl;
+import android.view.SyncRtSurfaceTransactionApplier;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.view.animation.Transformation;
@@ -53,51 +53,36 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
private static final boolean DEBUG_EXIT_ANIMATION_BLEND = false;
private static final String TAG = StartingSurfaceDrawer.TAG;
- private static final Interpolator ICON_EXIT_INTERPOLATOR = new PathInterpolator(1f, 0f, 1f, 1f);
private static final Interpolator APP_EXIT_INTERPOLATOR = new PathInterpolator(0f, 0f, 0f, 1f);
- private static final int EXTRA_REVEAL_DELAY = 133;
private final Matrix mTmpTransform = new Matrix();
- private final float[] mTmpFloat9 = new float[9];
- private SurfaceControl mFirstWindowSurface;
+ private final SurfaceControl mFirstWindowSurface;
private final Rect mFirstWindowFrame = new Rect();
private final SplashScreenView mSplashScreenView;
private final int mMainWindowShiftLength;
- private final int mIconShiftLength;
private final int mAppDuration;
- private final int mIconDuration;
private final TransactionPool mTransactionPool;
private ValueAnimator mMainAnimator;
- private Animation mShiftUpAnimation;
- private AnimationSet mIconAnimationSet;
+ private ShiftUpAnimation mShiftUpAnimation;
private Runnable mFinishCallback;
SplashScreenExitAnimation(SplashScreenView view, SurfaceControl leash, Rect frame,
- int appDuration, int iconDuration, int mainWindowShiftLength, int iconShiftLength,
- TransactionPool pool, Runnable handleFinish) {
+ int appDuration, int mainWindowShiftLength, TransactionPool pool,
+ Runnable handleFinish) {
mSplashScreenView = view;
mFirstWindowSurface = leash;
if (frame != null) {
mFirstWindowFrame.set(frame);
}
mAppDuration = appDuration;
- mIconDuration = iconDuration;
mMainWindowShiftLength = mainWindowShiftLength;
- mIconShiftLength = iconShiftLength;
mFinishCallback = handleFinish;
mTransactionPool = pool;
}
- void prepareAnimations() {
- prepareRevealAnimation();
- prepareShiftAnimation();
- }
-
void startAnimations() {
- if (mIconAnimationSet != null) {
- mIconAnimationSet.start();
- }
+ prepareRevealAnimation();
if (mMainAnimator != null) {
mMainAnimator.start();
}
@@ -114,8 +99,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mMainAnimator.setInterpolator(APP_EXIT_INTERPOLATOR);
mMainAnimator.addListener(this);
- final int startDelay = mIconDuration + EXTRA_REVEAL_DELAY;
- final float transparentRatio = 0.95f;
+ final float transparentRatio = 0.8f;
final int globalHeight = mSplashScreenView.getHeight();
final int verticalCircleCenter = 0;
final int finalVerticalLength = globalHeight - verticalCircleCenter;
@@ -130,9 +114,8 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
final float[] stops = {0f, transparentRatio, 1f};
radialVanishAnimation.setRadialPaintParam(colors, stops);
radialVanishAnimation.setReady();
- mMainAnimator.setStartDelay(startDelay);
- if (mFirstWindowSurface != null) {
+ if (mFirstWindowSurface != null && mFirstWindowSurface.isValid()) {
// shift up main window
View occludeHoleView = new View(mSplashScreenView.getContext());
if (DEBUG_EXIT_ANIMATION_BLEND) {
@@ -144,59 +127,16 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
WindowManager.LayoutParams.MATCH_PARENT, mMainWindowShiftLength);
mSplashScreenView.addView(occludeHoleView, params);
- mShiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength);
+ mShiftUpAnimation = new ShiftUpAnimation(0, -mMainWindowShiftLength, occludeHoleView);
mShiftUpAnimation.setDuration(mAppDuration);
mShiftUpAnimation.setInterpolator(APP_EXIT_INTERPOLATOR);
- mShiftUpAnimation.setStartOffset(startDelay);
occludeHoleView.setAnimation(mShiftUpAnimation);
}
}
- // shift down icon and branding view
- private void prepareShiftAnimation() {
- final View iconView = mSplashScreenView.getIconView();
- if (iconView == null) {
- return;
- }
- if (mIconShiftLength > 0) {
- mIconAnimationSet = new AnimationSet(true /* shareInterpolator */);
- if (DEBUG_EXIT_ANIMATION) {
- Slog.v(TAG, "first exit animation, shift length: " + mIconShiftLength);
- }
- mIconAnimationSet.addAnimation(new TranslateYAnimation(0, mIconShiftLength));
- mIconAnimationSet.addAnimation(new AlphaAnimation(1, 0));
- mIconAnimationSet.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- if (DEBUG_EXIT_ANIMATION) {
- Slog.v(TAG, "first exit animation finished");
- }
- iconView.post(() -> iconView.setVisibility(GONE));
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- // ignore
- }
- });
- mIconAnimationSet.setDuration(mIconDuration);
- mIconAnimationSet.setInterpolator(ICON_EXIT_INTERPOLATOR);
- iconView.setAnimation(mIconAnimationSet);
- final View brandingView = mSplashScreenView.getBrandingView();
- if (brandingView != null) {
- brandingView.setAnimation(mIconAnimationSet);
- }
- }
- }
-
private static class RadialVanishAnimation extends View {
- private SplashScreenView mView;
+ private final SplashScreenView mView;
private int mInitRadius;
private int mFinishRadius;
private boolean mReady;
@@ -217,7 +157,7 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mVanishMatrix.setScale(scale, scale);
mVanishMatrix.postTranslate(mCircleCenter.x, mCircleCenter.y);
mVanishPaint.getShader().setLocalMatrix(mVanishMatrix);
- mView.postInvalidate();
+ postInvalidate();
});
mView.addView(this);
}
@@ -262,28 +202,57 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
}
private final class ShiftUpAnimation extends TranslateYAnimation {
- ShiftUpAnimation(float fromYDelta, float toYDelta) {
+ final SyncRtSurfaceTransactionApplier mApplier;
+ ShiftUpAnimation(float fromYDelta, float toYDelta, View targetView) {
super(fromYDelta, toYDelta);
+ mApplier = new SyncRtSurfaceTransactionApplier(targetView);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
- if (mFirstWindowSurface == null) {
+ if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
return;
}
mTmpTransform.set(t.getMatrix());
+
+ // set the vsyncId to ensure the transaction doesn't get applied too early.
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
+ tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
mTmpTransform.postTranslate(mFirstWindowFrame.left,
mFirstWindowFrame.top + mMainWindowShiftLength);
- tx.setMatrix(mFirstWindowSurface, mTmpTransform, mTmpFloat9);
- // TODO set the vsyncId to ensure the transaction doesn't get applied too early.
- // Additionally, do you want to have this synchronized with your view animations?
- // If so, you'll need to use SyncRtSurfaceTransactionApplier
- tx.apply();
+
+ SyncRtSurfaceTransactionApplier.SurfaceParams
+ params = new SyncRtSurfaceTransactionApplier.SurfaceParams
+ .Builder(mFirstWindowSurface)
+ .withMatrix(mTmpTransform)
+ .withMergeTransaction(tx)
+ .build();
+ mApplier.scheduleApply(params);
+
mTransactionPool.release(tx);
}
+
+ void finish() {
+ if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
+ return;
+ }
+ final SurfaceControl.Transaction tx = mTransactionPool.acquire();
+ tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
+
+ SyncRtSurfaceTransactionApplier.SurfaceParams
+ params = new SyncRtSurfaceTransactionApplier.SurfaceParams
+ .Builder(mFirstWindowSurface)
+ .withWindowCrop(null)
+ .withMergeTransaction(tx)
+ .build();
+ mApplier.scheduleApply(params);
+ mTransactionPool.release(tx);
+
+ Choreographer.getSfInstance().postCallback(CALLBACK_COMMIT,
+ mFirstWindowSurface::release, null);
+ }
}
private void reset() {
@@ -297,12 +266,8 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
mFinishCallback = null;
}
});
- if (mFirstWindowSurface != null) {
- final SurfaceControl.Transaction tx = mTransactionPool.acquire();
- tx.setWindowCrop(mFirstWindowSurface, null);
- tx.apply();
- mFirstWindowSurface.release();
- mFirstWindowSurface = null;
+ if (mShiftUpAnimation != null) {
+ mShiftUpAnimation.finish();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 1d3a60b8193d..e2051fedf67e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -76,20 +76,15 @@ public class SplashscreenContentDrawer {
private int mBrandingImageWidth;
private int mBrandingImageHeight;
private final int mAppRevealDuration;
- private final int mIconExitDuration;
private int mMainWindowShiftLength;
- private int mIconNormalExitDistance;
- private int mIconEarlyExitDistance;
private final TransactionPool mTransactionPool;
private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs();
private final Handler mSplashscreenWorkerHandler;
- SplashscreenContentDrawer(Context context, int iconExitAnimDuration, int appRevealAnimDuration,
- TransactionPool pool) {
+ SplashscreenContentDrawer(Context context, int appRevealAnimDuration, TransactionPool pool) {
mContext = context;
mIconProvider = new IconProvider(context);
mAppRevealDuration = appRevealAnimDuration;
- mIconExitDuration = iconExitAnimDuration;
mTransactionPool = pool;
// Initialize Splashscreen worker thread
@@ -144,10 +139,6 @@ public class SplashscreenContentDrawer {
com.android.wm.shell.R.dimen.starting_surface_brand_image_height);
mMainWindowShiftLength = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
- mIconNormalExitDistance = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.starting_surface_normal_exit_icon_distance);
- mIconEarlyExitDistance = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.starting_surface_early_exit_icon_distance);
}
private int getSystemBGColor() {
@@ -428,6 +419,7 @@ public class SplashscreenContentDrawer {
}
if (mEmptyView) {
splashScreenView.setNotCopyable();
+ splashScreenView.setRevealAnimationSupported(false);
}
splashScreenView.makeSystemUIColorsTransparent();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -724,12 +716,10 @@ public class SplashscreenContentDrawer {
* Create and play the default exit animation for splash screen view.
*/
void applyExitAnimation(SplashScreenView view, SurfaceControl leash,
- Rect frame, boolean isEarlyExit, Runnable finishCallback) {
+ Rect frame, Runnable finishCallback) {
final SplashScreenExitAnimation animation = new SplashScreenExitAnimation(view, leash,
- frame, mAppRevealDuration, mIconExitDuration, mMainWindowShiftLength,
- isEarlyExit ? mIconEarlyExitDistance : mIconNormalExitDistance, mTransactionPool,
+ frame, mAppRevealDuration, mMainWindowShiftLength, mTransactionPool,
finishCallback);
- animation.prepareAnimations();
animation.startAnimations();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 6d3eeae43a96..2dc900945b53 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -35,7 +35,7 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
-import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
@@ -106,6 +106,8 @@ public class StartingSurfaceDrawer {
private final SplashscreenContentDrawer mSplashscreenContentDrawer;
private Choreographer mChoreographer;
+ private static final boolean DEBUG_ENABLE_REVEAL_ANIMATION =
+ SystemProperties.getBoolean("persist.debug.enable_reveal_animation", false);
/**
* @param splashScreenExecutor The thread used to control add and remove starting window.
*/
@@ -114,12 +116,10 @@ public class StartingSurfaceDrawer {
mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mSplashScreenExecutor = splashScreenExecutor;
- final int iconExitAnimDuration = context.getResources().getInteger(
- com.android.wm.shell.R.integer.starting_window_icon_exit_anim_duration);
final int appRevealAnimDuration = context.getResources().getInteger(
com.android.wm.shell.R.integer.starting_window_app_reveal_anim_duration);
- mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconExitAnimDuration,
- appRevealAnimDuration, pool);
+ mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, appRevealAnimDuration,
+ pool);
mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
}
@@ -471,20 +471,24 @@ public class StartingSurfaceDrawer {
if (DEBUG_SPLASH_SCREEN) {
Slog.v(TAG, "Removing splash screen window for task: " + taskId);
}
- if (record.mContentView != null) {
- if (leash != null || playRevealAnimation) {
- mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
- leash, frame, record.isEarlyExit(),
- () -> removeWindowInner(record.mDecorView, true));
+ if (record.mContentView != null
+ && record.mContentView.isRevealAnimationSupported()) {
+ if (playRevealAnimation) {
+ if (DEBUG_ENABLE_REVEAL_ANIMATION) {
+ mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
+ leash, frame,
+ () -> removeWindowInner(record.mDecorView, true));
+ } else {
+ // using the default exit animation from framework
+ removeWindowInner(record.mDecorView, false);
+ }
} else {
- // TODO(183004107) Always hide decorView when playRevealAnimation is enabled
- // from TaskOrganizerController#removeStartingWindow
- // the SplashScreenView has been copied to client, skip default exit
- // animation
- removeWindowInner(record.mDecorView, false);
+ // the SplashScreenView has been copied to client, hide the view to skip
+ // default exit animation
+ removeWindowInner(record.mDecorView, true);
}
} else {
- // no animation will be applied
+ // this is a blank splash screen, don't apply reveal animation
removeWindowInner(record.mDecorView, false);
}
}
@@ -518,12 +522,10 @@ public class StartingSurfaceDrawer {
* Record the view or surface for a starting window.
*/
private static class StartingWindowRecord {
- private static final long EARLY_START_MINIMUM_TIME_MS = 250;
private final View mDecorView;
private final TaskSnapshotWindow mTaskSnapshotWindow;
private SplashScreenView mContentView;
private boolean mSetSplashScreen;
- private long mContentCreateTime;
StartingWindowRecord(View decorView, TaskSnapshotWindow taskSnapshotWindow) {
mDecorView = decorView;
@@ -535,12 +537,7 @@ public class StartingSurfaceDrawer {
return;
}
mContentView = splashScreenView;
- mContentCreateTime = SystemClock.uptimeMillis();
mSetSplashScreen = true;
}
-
- boolean isEarlyExit() {
- return SystemClock.uptimeMillis() - mContentCreateTime < EARLY_START_MINIMUM_TIME_MS;
- }
}
}
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 6e0efbf8bd51..ba188937cfea 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -488,6 +488,12 @@ class SurfaceAnimator {
public static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6;
/**
+ * Animation when a reveal starting window animation is applied to app window.
+ * @hide
+ */
+ public static final int ANIMATION_TYPE_STARTING_REVEAL = 1 << 7;
+
+ /**
* Bitmask to include all animation types. This is NOT an {@link AnimationType}
* @hide
*/
@@ -505,7 +511,8 @@ class SurfaceAnimator {
ANIMATION_TYPE_RECENTS,
ANIMATION_TYPE_WINDOW_ANIMATION,
ANIMATION_TYPE_INSETS_CONTROL,
- ANIMATION_TYPE_FIXED_TRANSFORM
+ ANIMATION_TYPE_FIXED_TRANSFORM,
+ ANIMATION_TYPE_STARTING_REVEAL
})
@Retention(RetentionPolicy.SOURCE)
@interface AnimationType {}
@@ -523,6 +530,7 @@ class SurfaceAnimator {
case ANIMATION_TYPE_WINDOW_ANIMATION: return "window_animation";
case ANIMATION_TYPE_INSETS_CONTROL: return "insets_animation";
case ANIMATION_TYPE_FIXED_TRANSFORM: return "fixed_rotation";
+ case ANIMATION_TYPE_STARTING_REVEAL: return "starting_reveal";
default: return "unknown type:" + type;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index ccc0916cf25b..fb481b41c0af 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS;
@@ -38,6 +39,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
@@ -134,29 +136,72 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
}
+ // Capture the animation surface control for activity's main window
+ private class StartingWindowAnimationAdaptor implements AnimationAdapter {
+ private SurfaceControl mAnimationLeash;
+ @Override
+ public boolean getShowWallpaper() {
+ return false;
+ }
+
+ @Override
+ public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
+ int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
+ mAnimationLeash = animationLeash;
+ }
+
+ @Override
+ public void onAnimationCancelled(SurfaceControl animationLeash) {
+ if (mAnimationLeash == animationLeash) {
+ mAnimationLeash = null;
+ }
+ }
+
+ @Override
+ public long getDurationHint() {
+ return 0;
+ }
+
+ @Override
+ public long getStatusBarTransitionsStartTime() {
+ return 0;
+ }
+
+ @Override
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix + "StartingWindowAnimationAdaptor mCapturedLeash=");
+ pw.print(mAnimationLeash);
+ pw.println();
+ }
+
+ @Override
+ public void dumpDebug(ProtoOutputStream proto) {
+ }
+ }
+
void removeStartingWindow(Task task, boolean prepareAnimation) {
- SurfaceControl firstWindowLeash = null;
+ SurfaceControl windowAnimationLeash = null;
Rect mainFrame = null;
- // TODO enable shift up animation once we fix flicker test
-// final boolean playShiftUpAnimation = !task.inMultiWindowMode();
-// if (prepareAnimation && playShiftUpAnimation) {
-// final ActivityRecord topActivity = task.topActivityWithStartingWindow();
-// if (topActivity != null) {
-// final WindowState mainWindow =
-// topActivity.findMainWindow(false/* includeStartingApp */);
-// if (mainWindow != null) {
- // TODO create proper leash instead of the copied SC
-// firstWindowLeash = new SurfaceControl(mainWindow.getSurfaceControl(),
-// "TaskOrganizerController.removeStartingWindow");
-// mainFrame = mainWindow.getRelativeFrame();
-// }
-// }
-// }
+ final boolean playShiftUpAnimation = !task.inMultiWindowMode();
+ if (prepareAnimation && playShiftUpAnimation) {
+ final ActivityRecord topActivity = task.topActivityWithStartingWindow();
+ if (topActivity != null) {
+ final WindowState mainWindow =
+ topActivity.findMainWindow(false/* includeStartingApp */);
+ if (mainWindow != null) {
+ final StartingWindowAnimationAdaptor adaptor =
+ new StartingWindowAnimationAdaptor();
+ final SurfaceControl.Transaction t = mainWindow.getPendingTransaction();
+ mainWindow.startAnimation(t, adaptor, false,
+ ANIMATION_TYPE_STARTING_REVEAL);
+ windowAnimationLeash = adaptor.mAnimationLeash;
+ mainFrame = mainWindow.getRelativeFrame();
+ }
+ }
+ }
try {
- mTaskOrganizer.removeStartingWindow(task.mTaskId, firstWindowLeash, mainFrame,
- /* TODO(183004107) Revert this when jankiness is solved
- prepareAnimation); */ false);
-
+ mTaskOrganizer.removeStartingWindow(task.mTaskId, windowAnimationLeash,
+ mainFrame, prepareAnimation);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2e8d4cd4e7f8..b40223f6eed7 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -133,6 +133,7 @@ import static com.android.server.wm.MoveAnimationSpecProto.TO;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -2410,6 +2411,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
ProtoLog.d(WM_DEBUG_STARTING_WINDOW, "Starting window removed %s", this);
}
+ if (startingWindow && StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
+ // cancel the remove starting window animation on shell
+ if (mActivityRecord != null) {
+ final WindowState mainWindow =
+ mActivityRecord.findMainWindow(false/* includeStartingApp */);
+ if (mainWindow != null && mainWindow.isSelfAnimating(0 /* flags */,
+ ANIMATION_TYPE_STARTING_REVEAL)) {
+ mainWindow.cancelAnimation();
+ }
+ }
+ }
+
ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s",
System.identityHashCode(mClient.asBinder()),
mWinAnimator.mSurfaceController,