Loading services/core/java/com/android/server/wm/AppTransition.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -449,6 +449,19 @@ public class AppTransition implements Dump { if (mRemoteAnimationController != null) { if (mRemoteAnimationController != null) { mRemoteAnimationController.goodToGo(transit); mRemoteAnimationController.goodToGo(transit); } else if ((isTaskOpenTransitOld(transit) || transit == TRANSIT_OLD_WALLPAPER_CLOSE) && topOpeningAnim != null) { if (mDisplayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition() && mService.getRecentsAnimationController() == null) { final NavBarFadeAnimationController controller = new NavBarFadeAnimationController(mDisplayContent); // For remote animation case, the nav bar fades out and in is controlled by the // remote side. For non-remote animation case, we play the fade out/in animation // here. We play the nav bar fade-out animation when the app transition animation // starts and play the fade-in animation sequentially once the fade-out is finished. controller.fadeOutAndInSequentially(topOpeningAnim.getDurationHint(), null /* fadeOutParent */, topOpeningApp.getSurfaceControl()); } } } return redoLayout; return redoLayout; } } Loading services/core/java/com/android/server/wm/DisplayPolicy.java +0 −19 Original line number Original line Diff line number Diff line Loading @@ -373,7 +373,6 @@ public class DisplayPolicy { * when the navigation bar mode is changed. * when the navigation bar mode is changed. */ */ private boolean mShouldAttachNavBarToAppDuringTransition; private boolean mShouldAttachNavBarToAppDuringTransition; private NavBarFadeAnimationController mNavBarFadeAnimationController; // -------- PolicyHandler -------- // -------- PolicyHandler -------- private static final int MSG_REQUEST_TRANSIENT_BARS = 2; private static final int MSG_REQUEST_TRANSIENT_BARS = 2; Loading Loading @@ -1088,7 +1087,6 @@ public class DisplayPolicy { break; break; case TYPE_NAVIGATION_BAR: case TYPE_NAVIGATION_BAR: mNavigationBar = win; mNavigationBar = win; updateNavBarFadeController(); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win, mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win, (displayFrames, windowState, inOutFrame) -> { (displayFrames, windowState, inOutFrame) -> { Loading Loading @@ -1234,7 +1232,6 @@ public class DisplayPolicy { mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); } else if (mNavigationBar == win || mNavigationBarAlt == win) { } else if (mNavigationBar == win || mNavigationBarAlt == win) { mNavigationBar = null; mNavigationBar = null; updateNavBarFadeController(); mNavigationBarAlt = null; mNavigationBarAlt = null; mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); } else if (mNotificationShade == win) { } else if (mNotificationShade == win) { Loading Loading @@ -2060,7 +2057,6 @@ public class DisplayPolicy { res.getBoolean(R.bool.config_attachNavBarToAppDuringTransition); res.getBoolean(R.bool.config_attachNavBarToAppDuringTransition); if (mShouldAttachNavBarToAppDuringTransition != shouldAttach) { if (mShouldAttachNavBarToAppDuringTransition != shouldAttach) { mShouldAttachNavBarToAppDuringTransition = shouldAttach; mShouldAttachNavBarToAppDuringTransition = shouldAttach; updateNavBarFadeController(); } } } } Loading Loading @@ -3062,19 +3058,4 @@ public class DisplayPolicy { boolean shouldAttachNavBarToAppDuringTransition() { boolean shouldAttachNavBarToAppDuringTransition() { return mShouldAttachNavBarToAppDuringTransition && mNavigationBar != null; return mShouldAttachNavBarToAppDuringTransition && mNavigationBar != null; } } @Nullable NavBarFadeAnimationController getNavBarFadeAnimationController() { return mNavBarFadeAnimationController; } private void updateNavBarFadeController() { if (shouldAttachNavBarToAppDuringTransition()) { if (mNavBarFadeAnimationController == null) { mNavBarFadeAnimationController = new NavBarFadeAnimationController(mDisplayContent); } } else { mNavBarFadeAnimationController = null; } } } } services/core/java/com/android/server/wm/FadeAnimationController.java +20 −12 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,7 @@ import java.io.PrintWriter; */ */ public class FadeAnimationController { public class FadeAnimationController { protected final Context mContext; protected final Context mContext; private final ArrayMap<WindowToken, Runnable> mDeferredFinishCallbacks = new ArrayMap<>(); protected final ArrayMap<WindowToken, Runnable> mDeferredFinishCallbacks = new ArrayMap<>(); public FadeAnimationController(DisplayContent displayContent) { public FadeAnimationController(DisplayContent displayContent) { mContext = displayContent.mWmService.mContext; mContext = displayContent.mWmService.mContext; Loading Loading @@ -69,17 +69,11 @@ public class FadeAnimationController { return; return; } } final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); final FadeAnimationAdapter animationAdapter = createAdapter(show, windowToken); if (animation == null) { if (animationAdapter == null) { return; return; } } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); final FadeAnimationAdapter animationAdapter = new FadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken); // We deferred the end of the animation when hiding the token, so we need to end it now that // We deferred the end of the animation when hiding the token, so we need to end it now that // it's shown again. // it's shown again. final SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> { final SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> { Loading @@ -92,7 +86,21 @@ public class FadeAnimationController { show /* hidden */, animationType, finishedCallback); show /* hidden */, animationType, finishedCallback); } } private LocalAnimationAdapter.AnimationSpec createAnimationSpec(@NonNull Animation animation) { protected FadeAnimationAdapter createAdapter(boolean show, WindowToken windowToken) { final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); if (animation == null) { return null; } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); return new FadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken); } protected LocalAnimationAdapter.AnimationSpec createAnimationSpec( @NonNull Animation animation) { return new LocalAnimationAdapter.AnimationSpec() { return new LocalAnimationAdapter.AnimationSpec() { final Transformation mTransformation = new Transformation(); final Transformation mTransformation = new Transformation(); Loading Loading @@ -130,8 +138,8 @@ public class FadeAnimationController { }; }; } } private class FadeAnimationAdapter extends LocalAnimationAdapter { protected class FadeAnimationAdapter extends LocalAnimationAdapter { private final boolean mShow; protected final boolean mShow; private final WindowToken mToken; private final WindowToken mToken; FadeAnimationAdapter(AnimationSpec windowAnimationSpec, FadeAnimationAdapter(AnimationSpec windowAnimationSpec, Loading services/core/java/com/android/server/wm/NavBarFadeAnimationController.java +98 −1 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import android.view.SurfaceControl; import android.view.animation.AlphaAnimation; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.Animation; import android.view.animation.Interpolator; import android.view.animation.Interpolator; Loading @@ -35,12 +36,17 @@ public class NavBarFadeAnimationController extends FadeAnimationController{ private static final Interpolator FADE_OUT_INTERPOLATOR = private static final Interpolator FADE_OUT_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 1f, 1f); new PathInterpolator(0.2f, 0f, 1f, 1f); private DisplayContent mDisplayContent; private final WindowState mNavigationBar; private final WindowState mNavigationBar; private Animation mFadeInAnimation; private Animation mFadeInAnimation; private Animation mFadeOutAnimation; private Animation mFadeOutAnimation; private SurfaceControl mFadeInParent; private SurfaceControl mFadeOutParent; private boolean mPlaySequentially = false; public NavBarFadeAnimationController(DisplayContent displayContent) { public NavBarFadeAnimationController(DisplayContent displayContent) { super(displayContent); super(displayContent); mDisplayContent = displayContent; mNavigationBar = displayContent.getDisplayPolicy().getNavigationBar(); mNavigationBar = displayContent.getDisplayPolicy().getNavigationBar(); mFadeInAnimation = new AlphaAnimation(0f, 1f); mFadeInAnimation = new AlphaAnimation(0f, 1f); mFadeInAnimation.setDuration(FADE_IN_DURATION); mFadeInAnimation.setDuration(FADE_IN_DURATION); Loading @@ -61,12 +67,103 @@ public class NavBarFadeAnimationController extends FadeAnimationController{ return mFadeOutAnimation; return mFadeOutAnimation; } } @Override protected FadeAnimationAdapter createAdapter(boolean show, WindowToken windowToken) { final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); if (animation == null) { return null; } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); return new NavFadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken, show ? mFadeInParent : mFadeOutParent); } /** /** * Run the fade-in/out animation for the navigation bar. * Run the fade-in/out animation for the navigation bar. * * * @param show true for fade-in, otherwise for fade-out. * @param show true for fade-in, otherwise for fade-out. */ */ public void fadeWindowToken(boolean show) { public void fadeWindowToken(boolean show) { fadeWindowToken(show, mNavigationBar.mToken, ANIMATION_TYPE_APP_TRANSITION); final FadeRotationAnimationController controller = mDisplayContent.getFadeRotationAnimationController(); final Runnable fadeAnim = () -> fadeWindowToken(show, mNavigationBar.mToken, ANIMATION_TYPE_APP_TRANSITION); if (controller == null) { fadeAnim.run(); } else if (!controller.isTargetToken(mNavigationBar.mToken)) { // If fade rotation animation is running and the nav bar is not controlled by it: // - For fade-in animation, defer the animation until fade rotation animation finishes. // - For fade-out animation, just play the animation. if (show) { controller.setOnShowRunnable(fadeAnim); } else { fadeAnim.run(); } } else { // If fade rotation animation is running and controlling the nav bar, make sure we empty // the mDeferredFinishCallbacks and defer the runnable until fade rotation animation // finishes. final Runnable runnable = mDeferredFinishCallbacks.remove(mNavigationBar.mToken); if (runnable != null) { controller.setOnShowRunnable(runnable); } } } void fadeOutAndInSequentially(long totalDuration, SurfaceControl fadeOutParent, SurfaceControl fadeInParent) { mPlaySequentially = true; if (totalDuration > 0) { // The animation duration of each animation varies so we set the fade-out duration to // 1/3 of the total app transition duration and set the fade-in duration to 2/3 of it. final long fadeInDuration = totalDuration * 2L / 3L; mFadeOutAnimation.setDuration(totalDuration - fadeInDuration); mFadeInAnimation.setDuration(fadeInDuration); } mFadeOutParent = fadeOutParent; mFadeInParent = fadeInParent; fadeWindowToken(false); } /** * The animation adapter that is capable of playing fade-out and fade-in sequentially and * reparenting the navigation bar to a specified SurfaceControl when fade animation starts. */ protected class NavFadeAnimationAdapter extends FadeAnimationAdapter { private SurfaceControl mParent; NavFadeAnimationAdapter(AnimationSpec windowAnimationSpec, SurfaceAnimationRunner surfaceAnimationRunner, boolean show, WindowToken token, SurfaceControl parent) { super(windowAnimationSpec, surfaceAnimationRunner, show, token); mParent = parent; } @Override public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) { super.startAnimation(animationLeash, t, type, finishCallback); if (mParent != null && mParent.isValid()) { t.reparent(animationLeash, mParent); // Place the nav bar on top of anything else (e.g. ime and starting window) in the // parent. t.setLayer(animationLeash, Integer.MAX_VALUE); } } @Override public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) { if (mPlaySequentially) { if (!mShow) { fadeWindowToken(true); } return false; } else { return super.shouldDeferAnimationFinish(endDeferFinishCallback); } } } } } } services/core/java/com/android/server/wm/RecentsAnimationController.java +6 −18 Original line number Original line Diff line number Diff line Loading @@ -628,6 +628,7 @@ public class RecentsAnimationController implements DeathRecipient { return; return; } } mNavigationBarAttachedToApp = true; mNavigationBarAttachedToApp = true; navWindow.mToken.cancelAnimation(); final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction(); final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction(); final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl(); final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl(); if (shouldTranslateNavBar) { if (shouldTranslateNavBar) { Loading @@ -648,7 +649,8 @@ public class RecentsAnimationController implements DeathRecipient { } } } } private void restoreNavigationBarFromApp(boolean animate) { @VisibleForTesting void restoreNavigationBarFromApp(boolean animate) { if (!mNavigationBarAttachedToApp) { if (!mNavigationBarAttachedToApp) { return; return; } } Loading @@ -671,23 +673,9 @@ public class RecentsAnimationController implements DeathRecipient { t.setLayer(navToken.getSurfaceControl(), navToken.getLastLayer()); t.setLayer(navToken.getSurfaceControl(), navToken.getLastLayer()); if (animate) { if (animate) { final NavBarFadeAnimationController navBarFadeAnimationController = final NavBarFadeAnimationController controller = mDisplayContent.getDisplayPolicy().getNavBarFadeAnimationController(); new NavBarFadeAnimationController(mDisplayContent); final Runnable fadeInAnim = () -> { controller.fadeWindowToken(true); // Reparent the SurfaceControl of nav bar token back. t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); // Run fade-in animation to show navigation bar back to bottom of the display. if (navBarFadeAnimationController != null) { navBarFadeAnimationController.fadeWindowToken(true); } }; final FadeRotationAnimationController fadeRotationAnimationController = mDisplayContent.getFadeRotationAnimationController(); if (fadeRotationAnimationController != null) { fadeRotationAnimationController.setOnShowRunnable(fadeInAnim); } else { fadeInAnim.run(); } } else { } else { // Reparent the SurfaceControl of nav bar token back. // Reparent the SurfaceControl of nav bar token back. t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); Loading Loading
services/core/java/com/android/server/wm/AppTransition.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -449,6 +449,19 @@ public class AppTransition implements Dump { if (mRemoteAnimationController != null) { if (mRemoteAnimationController != null) { mRemoteAnimationController.goodToGo(transit); mRemoteAnimationController.goodToGo(transit); } else if ((isTaskOpenTransitOld(transit) || transit == TRANSIT_OLD_WALLPAPER_CLOSE) && topOpeningAnim != null) { if (mDisplayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition() && mService.getRecentsAnimationController() == null) { final NavBarFadeAnimationController controller = new NavBarFadeAnimationController(mDisplayContent); // For remote animation case, the nav bar fades out and in is controlled by the // remote side. For non-remote animation case, we play the fade out/in animation // here. We play the nav bar fade-out animation when the app transition animation // starts and play the fade-in animation sequentially once the fade-out is finished. controller.fadeOutAndInSequentially(topOpeningAnim.getDurationHint(), null /* fadeOutParent */, topOpeningApp.getSurfaceControl()); } } } return redoLayout; return redoLayout; } } Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +0 −19 Original line number Original line Diff line number Diff line Loading @@ -373,7 +373,6 @@ public class DisplayPolicy { * when the navigation bar mode is changed. * when the navigation bar mode is changed. */ */ private boolean mShouldAttachNavBarToAppDuringTransition; private boolean mShouldAttachNavBarToAppDuringTransition; private NavBarFadeAnimationController mNavBarFadeAnimationController; // -------- PolicyHandler -------- // -------- PolicyHandler -------- private static final int MSG_REQUEST_TRANSIENT_BARS = 2; private static final int MSG_REQUEST_TRANSIENT_BARS = 2; Loading Loading @@ -1088,7 +1087,6 @@ public class DisplayPolicy { break; break; case TYPE_NAVIGATION_BAR: case TYPE_NAVIGATION_BAR: mNavigationBar = win; mNavigationBar = win; updateNavBarFadeController(); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win, mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win, (displayFrames, windowState, inOutFrame) -> { (displayFrames, windowState, inOutFrame) -> { Loading Loading @@ -1234,7 +1232,6 @@ public class DisplayPolicy { mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); } else if (mNavigationBar == win || mNavigationBarAlt == win) { } else if (mNavigationBar == win || mNavigationBarAlt == win) { mNavigationBar = null; mNavigationBar = null; updateNavBarFadeController(); mNavigationBarAlt = null; mNavigationBarAlt = null; mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); } else if (mNotificationShade == win) { } else if (mNotificationShade == win) { Loading Loading @@ -2060,7 +2057,6 @@ public class DisplayPolicy { res.getBoolean(R.bool.config_attachNavBarToAppDuringTransition); res.getBoolean(R.bool.config_attachNavBarToAppDuringTransition); if (mShouldAttachNavBarToAppDuringTransition != shouldAttach) { if (mShouldAttachNavBarToAppDuringTransition != shouldAttach) { mShouldAttachNavBarToAppDuringTransition = shouldAttach; mShouldAttachNavBarToAppDuringTransition = shouldAttach; updateNavBarFadeController(); } } } } Loading Loading @@ -3062,19 +3058,4 @@ public class DisplayPolicy { boolean shouldAttachNavBarToAppDuringTransition() { boolean shouldAttachNavBarToAppDuringTransition() { return mShouldAttachNavBarToAppDuringTransition && mNavigationBar != null; return mShouldAttachNavBarToAppDuringTransition && mNavigationBar != null; } } @Nullable NavBarFadeAnimationController getNavBarFadeAnimationController() { return mNavBarFadeAnimationController; } private void updateNavBarFadeController() { if (shouldAttachNavBarToAppDuringTransition()) { if (mNavBarFadeAnimationController == null) { mNavBarFadeAnimationController = new NavBarFadeAnimationController(mDisplayContent); } } else { mNavBarFadeAnimationController = null; } } } }
services/core/java/com/android/server/wm/FadeAnimationController.java +20 −12 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,7 @@ import java.io.PrintWriter; */ */ public class FadeAnimationController { public class FadeAnimationController { protected final Context mContext; protected final Context mContext; private final ArrayMap<WindowToken, Runnable> mDeferredFinishCallbacks = new ArrayMap<>(); protected final ArrayMap<WindowToken, Runnable> mDeferredFinishCallbacks = new ArrayMap<>(); public FadeAnimationController(DisplayContent displayContent) { public FadeAnimationController(DisplayContent displayContent) { mContext = displayContent.mWmService.mContext; mContext = displayContent.mWmService.mContext; Loading Loading @@ -69,17 +69,11 @@ public class FadeAnimationController { return; return; } } final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); final FadeAnimationAdapter animationAdapter = createAdapter(show, windowToken); if (animation == null) { if (animationAdapter == null) { return; return; } } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); final FadeAnimationAdapter animationAdapter = new FadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken); // We deferred the end of the animation when hiding the token, so we need to end it now that // We deferred the end of the animation when hiding the token, so we need to end it now that // it's shown again. // it's shown again. final SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> { final SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> { Loading @@ -92,7 +86,21 @@ public class FadeAnimationController { show /* hidden */, animationType, finishedCallback); show /* hidden */, animationType, finishedCallback); } } private LocalAnimationAdapter.AnimationSpec createAnimationSpec(@NonNull Animation animation) { protected FadeAnimationAdapter createAdapter(boolean show, WindowToken windowToken) { final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); if (animation == null) { return null; } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); return new FadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken); } protected LocalAnimationAdapter.AnimationSpec createAnimationSpec( @NonNull Animation animation) { return new LocalAnimationAdapter.AnimationSpec() { return new LocalAnimationAdapter.AnimationSpec() { final Transformation mTransformation = new Transformation(); final Transformation mTransformation = new Transformation(); Loading Loading @@ -130,8 +138,8 @@ public class FadeAnimationController { }; }; } } private class FadeAnimationAdapter extends LocalAnimationAdapter { protected class FadeAnimationAdapter extends LocalAnimationAdapter { private final boolean mShow; protected final boolean mShow; private final WindowToken mToken; private final WindowToken mToken; FadeAnimationAdapter(AnimationSpec windowAnimationSpec, FadeAnimationAdapter(AnimationSpec windowAnimationSpec, Loading
services/core/java/com/android/server/wm/NavBarFadeAnimationController.java +98 −1 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import android.view.SurfaceControl; import android.view.animation.AlphaAnimation; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.Animation; import android.view.animation.Interpolator; import android.view.animation.Interpolator; Loading @@ -35,12 +36,17 @@ public class NavBarFadeAnimationController extends FadeAnimationController{ private static final Interpolator FADE_OUT_INTERPOLATOR = private static final Interpolator FADE_OUT_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 1f, 1f); new PathInterpolator(0.2f, 0f, 1f, 1f); private DisplayContent mDisplayContent; private final WindowState mNavigationBar; private final WindowState mNavigationBar; private Animation mFadeInAnimation; private Animation mFadeInAnimation; private Animation mFadeOutAnimation; private Animation mFadeOutAnimation; private SurfaceControl mFadeInParent; private SurfaceControl mFadeOutParent; private boolean mPlaySequentially = false; public NavBarFadeAnimationController(DisplayContent displayContent) { public NavBarFadeAnimationController(DisplayContent displayContent) { super(displayContent); super(displayContent); mDisplayContent = displayContent; mNavigationBar = displayContent.getDisplayPolicy().getNavigationBar(); mNavigationBar = displayContent.getDisplayPolicy().getNavigationBar(); mFadeInAnimation = new AlphaAnimation(0f, 1f); mFadeInAnimation = new AlphaAnimation(0f, 1f); mFadeInAnimation.setDuration(FADE_IN_DURATION); mFadeInAnimation.setDuration(FADE_IN_DURATION); Loading @@ -61,12 +67,103 @@ public class NavBarFadeAnimationController extends FadeAnimationController{ return mFadeOutAnimation; return mFadeOutAnimation; } } @Override protected FadeAnimationAdapter createAdapter(boolean show, WindowToken windowToken) { final Animation animation = show ? getFadeInAnimation() : getFadeOutAnimation(); if (animation == null) { return null; } final LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); return new NavFadeAnimationAdapter( windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, windowToken, show ? mFadeInParent : mFadeOutParent); } /** /** * Run the fade-in/out animation for the navigation bar. * Run the fade-in/out animation for the navigation bar. * * * @param show true for fade-in, otherwise for fade-out. * @param show true for fade-in, otherwise for fade-out. */ */ public void fadeWindowToken(boolean show) { public void fadeWindowToken(boolean show) { fadeWindowToken(show, mNavigationBar.mToken, ANIMATION_TYPE_APP_TRANSITION); final FadeRotationAnimationController controller = mDisplayContent.getFadeRotationAnimationController(); final Runnable fadeAnim = () -> fadeWindowToken(show, mNavigationBar.mToken, ANIMATION_TYPE_APP_TRANSITION); if (controller == null) { fadeAnim.run(); } else if (!controller.isTargetToken(mNavigationBar.mToken)) { // If fade rotation animation is running and the nav bar is not controlled by it: // - For fade-in animation, defer the animation until fade rotation animation finishes. // - For fade-out animation, just play the animation. if (show) { controller.setOnShowRunnable(fadeAnim); } else { fadeAnim.run(); } } else { // If fade rotation animation is running and controlling the nav bar, make sure we empty // the mDeferredFinishCallbacks and defer the runnable until fade rotation animation // finishes. final Runnable runnable = mDeferredFinishCallbacks.remove(mNavigationBar.mToken); if (runnable != null) { controller.setOnShowRunnable(runnable); } } } void fadeOutAndInSequentially(long totalDuration, SurfaceControl fadeOutParent, SurfaceControl fadeInParent) { mPlaySequentially = true; if (totalDuration > 0) { // The animation duration of each animation varies so we set the fade-out duration to // 1/3 of the total app transition duration and set the fade-in duration to 2/3 of it. final long fadeInDuration = totalDuration * 2L / 3L; mFadeOutAnimation.setDuration(totalDuration - fadeInDuration); mFadeInAnimation.setDuration(fadeInDuration); } mFadeOutParent = fadeOutParent; mFadeInParent = fadeInParent; fadeWindowToken(false); } /** * The animation adapter that is capable of playing fade-out and fade-in sequentially and * reparenting the navigation bar to a specified SurfaceControl when fade animation starts. */ protected class NavFadeAnimationAdapter extends FadeAnimationAdapter { private SurfaceControl mParent; NavFadeAnimationAdapter(AnimationSpec windowAnimationSpec, SurfaceAnimationRunner surfaceAnimationRunner, boolean show, WindowToken token, SurfaceControl parent) { super(windowAnimationSpec, surfaceAnimationRunner, show, token); mParent = parent; } @Override public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) { super.startAnimation(animationLeash, t, type, finishCallback); if (mParent != null && mParent.isValid()) { t.reparent(animationLeash, mParent); // Place the nav bar on top of anything else (e.g. ime and starting window) in the // parent. t.setLayer(animationLeash, Integer.MAX_VALUE); } } @Override public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) { if (mPlaySequentially) { if (!mShow) { fadeWindowToken(true); } return false; } else { return super.shouldDeferAnimationFinish(endDeferFinishCallback); } } } } } }
services/core/java/com/android/server/wm/RecentsAnimationController.java +6 −18 Original line number Original line Diff line number Diff line Loading @@ -628,6 +628,7 @@ public class RecentsAnimationController implements DeathRecipient { return; return; } } mNavigationBarAttachedToApp = true; mNavigationBarAttachedToApp = true; navWindow.mToken.cancelAnimation(); final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction(); final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction(); final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl(); final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl(); if (shouldTranslateNavBar) { if (shouldTranslateNavBar) { Loading @@ -648,7 +649,8 @@ public class RecentsAnimationController implements DeathRecipient { } } } } private void restoreNavigationBarFromApp(boolean animate) { @VisibleForTesting void restoreNavigationBarFromApp(boolean animate) { if (!mNavigationBarAttachedToApp) { if (!mNavigationBarAttachedToApp) { return; return; } } Loading @@ -671,23 +673,9 @@ public class RecentsAnimationController implements DeathRecipient { t.setLayer(navToken.getSurfaceControl(), navToken.getLastLayer()); t.setLayer(navToken.getSurfaceControl(), navToken.getLastLayer()); if (animate) { if (animate) { final NavBarFadeAnimationController navBarFadeAnimationController = final NavBarFadeAnimationController controller = mDisplayContent.getDisplayPolicy().getNavBarFadeAnimationController(); new NavBarFadeAnimationController(mDisplayContent); final Runnable fadeInAnim = () -> { controller.fadeWindowToken(true); // Reparent the SurfaceControl of nav bar token back. t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); // Run fade-in animation to show navigation bar back to bottom of the display. if (navBarFadeAnimationController != null) { navBarFadeAnimationController.fadeWindowToken(true); } }; final FadeRotationAnimationController fadeRotationAnimationController = mDisplayContent.getFadeRotationAnimationController(); if (fadeRotationAnimationController != null) { fadeRotationAnimationController.setOnShowRunnable(fadeInAnim); } else { fadeInAnim.run(); } } else { } else { // Reparent the SurfaceControl of nav bar token back. // Reparent the SurfaceControl of nav bar token back. t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl()); Loading