Merge "Support enable default splash screen reveal aninatmion" into sc-dev
This commit is contained in:
@@ -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;
|
||||
@@ -263,6 +264,25 @@ public final class SplashScreenView extends FrameLayout {
|
||||
return !mNotCopyable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,20 +75,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
|
||||
@@ -139,10 +134,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() {
|
||||
@@ -406,6 +397,7 @@ public class SplashscreenContentDrawer {
|
||||
}
|
||||
if (mEmptyView) {
|
||||
splashScreenView.setNotCopyable();
|
||||
splashScreenView.setRevealAnimationSupported(false);
|
||||
}
|
||||
splashScreenView.makeSystemUIColorsTransparent();
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
@@ -678,12 +670,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -467,20 +467,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);
|
||||
}
|
||||
}
|
||||
@@ -514,12 +518,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;
|
||||
@@ -531,12 +533,7 @@ public class StartingSurfaceDrawer {
|
||||
return;
|
||||
}
|
||||
mContentView = splashScreenView;
|
||||
mContentCreateTime = SystemClock.uptimeMillis();
|
||||
mSetSplashScreen = true;
|
||||
}
|
||||
|
||||
boolean isEarlyExit() {
|
||||
return SystemClock.uptimeMillis() - mContentCreateTime < EARLY_START_MINIMUM_TIME_MS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +487,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
void removeStartingWindow(Task task, boolean prepareAnimation) {
|
||||
SurfaceControl firstWindowLeash = 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();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
mTaskOrganizer.removeStartingWindow(task.mTaskId, firstWindowLeash, mainFrame,
|
||||
/* TODO(183004107) Revert this when jankiness is solved
|
||||
prepareAnimation); */ false);
|
||||
// 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 windowAnimationLeash = null;
|
||||
Rect mainFrame = null;
|
||||
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, windowAnimationLeash,
|
||||
mainFrame, prepareAnimation);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user