Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −12 Original line number Diff line number Diff line Loading @@ -1350,8 +1350,7 @@ public final class ActivityStackSupervisor implements DisplayListener { r.launchFailed = false; if (stack.updateLRUListLocked(r)) { Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); } if (andResume) { Loading Loading @@ -3118,16 +3117,6 @@ public final class ActivityStackSupervisor implements DisplayListener { ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); if (!kept) { resumeTopActivitiesLocked(stack, null, null); if (changedStacks && stackId == FULLSCREEN_WORKSPACE_STACK_ID) { // We are about to relaunch the activity because its configuration changed // due to being maximized, i.e. size change. The activity will first // remove the old window and then add a new one. This call will tell window // manager about this, so it can preserve the old window until the new // one is drawn. This prevents having a gap between the removal and // addition, in which no window is visible. We also want the entrace of the // new window to be properly animated. mWindowManager.setReplacingWindow(r.appToken, true /* animate */); } } } } Loading Loading @@ -3256,6 +3245,16 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } final String reason = "moveTaskToStack"; if (stackId == DOCKED_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID) { // We are about to relaunch the activity because its configuration changed due to // being maximized, i.e. size change. The activity will first remove the old window // and then add a new one. This call will tell window manager about this, so it can // preserve the old window until the new one is drawn. This prevents having a gap // between the removal and addition, in which no window is visible. We also want the // entrace of the new window to be properly animated. ActivityRecord r = task.getTopActivity(); mWindowManager.setReplacingWindow(r.appToken, true /* animate */); } final ActivityStack stack = moveTaskToStackUncheckedLocked(task, stackId, toTop, forceFocus, reason); Loading services/core/java/com/android/server/wm/AppTransition.java +28 −6 Original line number Diff line number Diff line Loading @@ -1003,17 +1003,33 @@ public class AppTransition implements Dump { return prepareThumbnailAnimation(a, appWidth, appHeight, transit); } private Animation createRelaunchAnimation(int appWidth, int appHeight) { private Animation createRelaunchAnimation(int appWidth, int appHeight, Rect containingFrame) { getDefaultNextAppTransitionStartRect(mTmpFromClipRect); final int left = mTmpFromClipRect.left; final int top = mTmpFromClipRect.top; mTmpFromClipRect.offset(-left, -top); mTmpToClipRect.set(0, 0, appWidth, appHeight); AnimationSet set = new AnimationSet(true); ClipRectAnimation clip = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); TranslateAnimation translate = new TranslateAnimation(left, 0, top, 0); clip.setInterpolator(mDecelerateInterpolator); set.addAnimation(clip); float fromWidth = mTmpFromClipRect.width(); float toWidth = mTmpToClipRect.width(); float fromHeight = mTmpFromClipRect.height(); float toHeight = mTmpToClipRect.height(); if (fromWidth <= toWidth && fromHeight <= toHeight) { // The final window is larger in both dimensions than current window (e.g. we are // maximizing), so we can simply unclip the new window and there will be no disappearing // frame. set.addAnimation(new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)); } else { // The disappearing window has one larger dimension. We need to apply scaling, so the // first frame of the entry animation matches the old window. set.addAnimation(new ScaleAnimation(fromWidth / toWidth, 1, fromHeight / toHeight, 1)); } // We might not be going exactly full screen, but instead be aligned under the status bar. // We need to take this into account when creating the translate animation. TranslateAnimation translate = new TranslateAnimation(left - containingFrame.left, 0, top - containingFrame.top, 0); set.addAnimation(translate); set.setDuration(DEFAULT_APP_TRANSITION_DURATION); return set; Loading Loading @@ -1056,7 +1072,12 @@ public class AppTransition implements Dump { + " anim=" + a + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (transit == TRANSIT_ACTIVITY_RELAUNCH) { a = createRelaunchAnimation(appWidth, appHeight); a = createRelaunchAnimation(appWidth, appHeight, containingFrame); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=" + mNextAppTransition + " transit=" + appTransitionToString(transit) + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { a = loadAnimationRes(mNextAppTransitionPackage, enter ? mNextAppTransitionEnter : mNextAppTransitionExit); Loading @@ -1077,6 +1098,7 @@ public class AppTransition implements Dump { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL" + " transit=" + appTransitionToString(transit) + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) { a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight); Loading services/core/java/com/android/server/wm/TaskStack.java +1 −2 Original line number Diff line number Diff line Loading @@ -438,8 +438,7 @@ public class TaskStack implements DimLayer.DimLayerUser { for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) { // We are in the middle of changing the state of displays/stacks/tasks. We need // to finish that, before we let layout interfere with it. mService.removeWindowInnerLocked(appWindows.get(winNdx), false /* performLayout */); mService.removeWindowLocked(appWindows.get(winNdx)); doAnotherLayoutPass = true; } } Loading services/core/java/com/android/server/wm/WindowManagerService.java +8 −2 Original line number Diff line number Diff line Loading @@ -2206,7 +2206,7 @@ public class WindowManagerService extends IWindowManager.Stub removeWindowInnerLocked(win, true); } void removeWindowInnerLocked(WindowState win, boolean performLayout) { private void removeWindowInnerLocked(WindowState win, boolean performLayout) { if (win.mRemoved) { // Nothing to do. return; Loading Loading @@ -8317,7 +8317,7 @@ public class WindowManagerService extends IWindowManager.Stub final int numTokens = tokens.size(); for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { final AppWindowToken wtoken = tokens.get(tokenNdx); if (wtoken.mIsExiting) { if (wtoken.mIsExiting && !wtoken.mReplacingWindow) { continue; } i = reAddAppWindowsLocked(displayContent, i, wtoken); Loading Loading @@ -9909,6 +9909,12 @@ public class WindowManagerService extends IWindowManager.Stub return mWindowMap; } /** * Hint to a token that its activity will relaunch, which will trigger removal and addition of * a window. * @param token Application token for which the activity will be relaunched. * @param animate Whether to animate the addition of the new window. */ public void setReplacingWindow(IBinder token, boolean animate) { synchronized (mWindowMap) { AppWindowToken appWindowToken = findAppWindowToken(token); Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +6 −1 Original line number Diff line number Diff line Loading @@ -1369,7 +1369,12 @@ class WindowStateAnimator { // so we need to translate to match the actual surface coordinates. clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top); // We don't want to clip to stack bounds windows that are currently doing entrance // animation. This is necessary for docking operation, otherwise the window will be // suddenly cut off. if (!mAnimator.mAnimating) { adjustCropToStackBounds(w, clipRect); } if (!clipRect.equals(mLastClipRect)) { mLastClipRect.set(clipRect); Loading Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −12 Original line number Diff line number Diff line Loading @@ -1350,8 +1350,7 @@ public final class ActivityStackSupervisor implements DisplayListener { r.launchFailed = false; if (stack.updateLRUListLocked(r)) { Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); } if (andResume) { Loading Loading @@ -3118,16 +3117,6 @@ public final class ActivityStackSupervisor implements DisplayListener { ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); if (!kept) { resumeTopActivitiesLocked(stack, null, null); if (changedStacks && stackId == FULLSCREEN_WORKSPACE_STACK_ID) { // We are about to relaunch the activity because its configuration changed // due to being maximized, i.e. size change. The activity will first // remove the old window and then add a new one. This call will tell window // manager about this, so it can preserve the old window until the new // one is drawn. This prevents having a gap between the removal and // addition, in which no window is visible. We also want the entrace of the // new window to be properly animated. mWindowManager.setReplacingWindow(r.appToken, true /* animate */); } } } } Loading Loading @@ -3256,6 +3245,16 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } final String reason = "moveTaskToStack"; if (stackId == DOCKED_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID) { // We are about to relaunch the activity because its configuration changed due to // being maximized, i.e. size change. The activity will first remove the old window // and then add a new one. This call will tell window manager about this, so it can // preserve the old window until the new one is drawn. This prevents having a gap // between the removal and addition, in which no window is visible. We also want the // entrace of the new window to be properly animated. ActivityRecord r = task.getTopActivity(); mWindowManager.setReplacingWindow(r.appToken, true /* animate */); } final ActivityStack stack = moveTaskToStackUncheckedLocked(task, stackId, toTop, forceFocus, reason); Loading
services/core/java/com/android/server/wm/AppTransition.java +28 −6 Original line number Diff line number Diff line Loading @@ -1003,17 +1003,33 @@ public class AppTransition implements Dump { return prepareThumbnailAnimation(a, appWidth, appHeight, transit); } private Animation createRelaunchAnimation(int appWidth, int appHeight) { private Animation createRelaunchAnimation(int appWidth, int appHeight, Rect containingFrame) { getDefaultNextAppTransitionStartRect(mTmpFromClipRect); final int left = mTmpFromClipRect.left; final int top = mTmpFromClipRect.top; mTmpFromClipRect.offset(-left, -top); mTmpToClipRect.set(0, 0, appWidth, appHeight); AnimationSet set = new AnimationSet(true); ClipRectAnimation clip = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); TranslateAnimation translate = new TranslateAnimation(left, 0, top, 0); clip.setInterpolator(mDecelerateInterpolator); set.addAnimation(clip); float fromWidth = mTmpFromClipRect.width(); float toWidth = mTmpToClipRect.width(); float fromHeight = mTmpFromClipRect.height(); float toHeight = mTmpToClipRect.height(); if (fromWidth <= toWidth && fromHeight <= toHeight) { // The final window is larger in both dimensions than current window (e.g. we are // maximizing), so we can simply unclip the new window and there will be no disappearing // frame. set.addAnimation(new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)); } else { // The disappearing window has one larger dimension. We need to apply scaling, so the // first frame of the entry animation matches the old window. set.addAnimation(new ScaleAnimation(fromWidth / toWidth, 1, fromHeight / toHeight, 1)); } // We might not be going exactly full screen, but instead be aligned under the status bar. // We need to take this into account when creating the translate animation. TranslateAnimation translate = new TranslateAnimation(left - containingFrame.left, 0, top - containingFrame.top, 0); set.addAnimation(translate); set.setDuration(DEFAULT_APP_TRANSITION_DURATION); return set; Loading Loading @@ -1056,7 +1072,12 @@ public class AppTransition implements Dump { + " anim=" + a + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (transit == TRANSIT_ACTIVITY_RELAUNCH) { a = createRelaunchAnimation(appWidth, appHeight); a = createRelaunchAnimation(appWidth, appHeight, containingFrame); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=" + mNextAppTransition + " transit=" + appTransitionToString(transit) + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { a = loadAnimationRes(mNextAppTransitionPackage, enter ? mNextAppTransitionEnter : mNextAppTransitionExit); Loading @@ -1077,6 +1098,7 @@ public class AppTransition implements Dump { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL" + " transit=" + appTransitionToString(transit) + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) { a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight); Loading
services/core/java/com/android/server/wm/TaskStack.java +1 −2 Original line number Diff line number Diff line Loading @@ -438,8 +438,7 @@ public class TaskStack implements DimLayer.DimLayerUser { for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) { // We are in the middle of changing the state of displays/stacks/tasks. We need // to finish that, before we let layout interfere with it. mService.removeWindowInnerLocked(appWindows.get(winNdx), false /* performLayout */); mService.removeWindowLocked(appWindows.get(winNdx)); doAnotherLayoutPass = true; } } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +8 −2 Original line number Diff line number Diff line Loading @@ -2206,7 +2206,7 @@ public class WindowManagerService extends IWindowManager.Stub removeWindowInnerLocked(win, true); } void removeWindowInnerLocked(WindowState win, boolean performLayout) { private void removeWindowInnerLocked(WindowState win, boolean performLayout) { if (win.mRemoved) { // Nothing to do. return; Loading Loading @@ -8317,7 +8317,7 @@ public class WindowManagerService extends IWindowManager.Stub final int numTokens = tokens.size(); for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { final AppWindowToken wtoken = tokens.get(tokenNdx); if (wtoken.mIsExiting) { if (wtoken.mIsExiting && !wtoken.mReplacingWindow) { continue; } i = reAddAppWindowsLocked(displayContent, i, wtoken); Loading Loading @@ -9909,6 +9909,12 @@ public class WindowManagerService extends IWindowManager.Stub return mWindowMap; } /** * Hint to a token that its activity will relaunch, which will trigger removal and addition of * a window. * @param token Application token for which the activity will be relaunched. * @param animate Whether to animate the addition of the new window. */ public void setReplacingWindow(IBinder token, boolean animate) { synchronized (mWindowMap) { AppWindowToken appWindowToken = findAppWindowToken(token); Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +6 −1 Original line number Diff line number Diff line Loading @@ -1369,7 +1369,12 @@ class WindowStateAnimator { // so we need to translate to match the actual surface coordinates. clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top); // We don't want to clip to stack bounds windows that are currently doing entrance // animation. This is necessary for docking operation, otherwise the window will be // suddenly cut off. if (!mAnimator.mAnimating) { adjustCropToStackBounds(w, clipRect); } if (!clipRect.equals(mLastClipRect)) { mLastClipRect.set(clipRect); Loading