Loading services/core/java/com/android/server/wm/AppWindowToken.java +5 −0 Original line number Diff line number Diff line Loading @@ -1280,6 +1280,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked(). dc.setLayoutNeeded(); mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); final TaskStack s = getStack(); if (s != null) { s.onAllWindowsDrawn(); } } } Loading services/core/java/com/android/server/wm/BoundsAnimationController.java +36 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,8 @@ public class BoundsAnimationController { private final Interpolator mFastOutSlowInInterpolator; private boolean mFinishAnimationAfterTransition = false; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; BoundsAnimationController(Context context, AppTransition transition, Handler handler) { mHandler = handler; mAppTransition = transition; Loading Loading @@ -175,6 +177,13 @@ public class BoundsAnimationController { } } final Runnable mResumeRunnable = new Runnable() { @Override public void run() { resume(); } }; @Override public void onAnimationStart(Animator animation) { if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget Loading @@ -196,9 +205,25 @@ public class BoundsAnimationController { // the starting position so we don't jump at the beginning of the animation. if (animatingToLargerSize()) { mTarget.setPinnedStackSize(mFrom, mTmpRect); // We pause the animation until the app has drawn at the new size. // The target will notify us via BoundsAnimationController#resume. // We do this here and pause the animation, rather than just defer starting it // so we can enter the animating state and have WindowStateAnimator apply the // correct logic to make this resize seamless. if (mMoveToFullscreen) { pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } } } @Override public void resume() { mHandler.removeCallbacks(mResumeRunnable); super.resume(); } @Override public void onAnimationUpdate(ValueAnimator animation) { final float value = (Float) animation.getAnimatedValue(); Loading Loading @@ -371,4 +396,15 @@ public class BoundsAnimationController { animator.start(); return animator; } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); b.resume(); } } public void onAllWindowsDrawn() { mHandler.post(this::resume); } } services/core/java/com/android/server/wm/TaskStack.java +16 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.server.EventLogTags; import com.android.server.UiThread; import java.io.PrintWriter; Loading Loading @@ -1475,6 +1476,14 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye return true; } void onAllWindowsDrawn() { if (!mBoundsAnimating) { return; } mService.mBoundsAnimationController.onAllWindowsDrawn(); } @Override // AnimatesBounds public void onAnimationStart(boolean schedulePipModeChangedCallback) { // Hold the lock since this is called from the BoundsAnimator running on the UiThread Loading @@ -1482,6 +1491,13 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye mBoundsAnimatingRequested = false; mBoundsAnimating = true; mCancelCurrentBoundsAnimation = false; // If we are changing UI mode, as in the PiP to fullscreen // transition, then we need to wait for the window to draw. if (schedulePipModeChangedCallback) { forAllWindows((w) -> { w.mWinAnimator.resetDrawState(); }, false /* traverseTopToBottom */); } } if (mStackId == PINNED_STACK_ID) { Loading services/core/java/com/android/server/wm/WindowState.java +4 −2 Original line number Diff line number Diff line Loading @@ -4329,7 +4329,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges, int oldVisibility) { result |= !isVisibleLw() ? RELAYOUT_RES_FIRST_TIME : 0; final boolean wasVisible = isVisibleLw(); result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0; if (mAnimatingExit) { Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit=" + mRemoveOnExit + ", mDestroying=" + mDestroying); Loading @@ -4348,7 +4350,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mLastVisibleLayoutRotation = getDisplayContent().getRotation(); mWinAnimator.mEnteringAnimation = true; if ((result & RELAYOUT_RES_FIRST_TIME) != 0) { if (!wasVisible) { prepareWindowToDisplayDuringRelayout(mergedConfiguration); } if ((attrChanges & FORMAT_CHANGED) != 0) { Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +17 −10 Original line number Diff line number Diff line Loading @@ -602,6 +602,22 @@ class WindowStateAnimator { } } void resetDrawState() { mDrawState = DRAW_PENDING; if (mWin.mAppToken == null) { return; } if (mWin.mAppToken.mAppAnimator.animation == null) { mWin.mAppToken.clearAllDrawn(); } else { // Currently animating, persist current state of allDrawn until animation // is complete. mWin.mAppToken.deferClearAllDrawn = true; } } WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) { final WindowState w = mWin; if (w.restoreSavedSurface()) { Loading @@ -619,16 +635,7 @@ class WindowStateAnimator { if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING"); mDrawState = DRAW_PENDING; if (w.mAppToken != null) { if (w.mAppToken.mAppAnimator.animation == null) { w.mAppToken.clearAllDrawn(); } else { // Currently animating, persist current state of allDrawn until animation // is complete. w.mAppToken.deferClearAllDrawn = true; } } resetDrawState(); mService.makeWindowFreezingScreenIfNeededLocked(w); Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +5 −0 Original line number Diff line number Diff line Loading @@ -1280,6 +1280,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked(). dc.setLayoutNeeded(); mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); final TaskStack s = getStack(); if (s != null) { s.onAllWindowsDrawn(); } } } Loading
services/core/java/com/android/server/wm/BoundsAnimationController.java +36 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,8 @@ public class BoundsAnimationController { private final Interpolator mFastOutSlowInInterpolator; private boolean mFinishAnimationAfterTransition = false; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; BoundsAnimationController(Context context, AppTransition transition, Handler handler) { mHandler = handler; mAppTransition = transition; Loading Loading @@ -175,6 +177,13 @@ public class BoundsAnimationController { } } final Runnable mResumeRunnable = new Runnable() { @Override public void run() { resume(); } }; @Override public void onAnimationStart(Animator animation) { if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget Loading @@ -196,9 +205,25 @@ public class BoundsAnimationController { // the starting position so we don't jump at the beginning of the animation. if (animatingToLargerSize()) { mTarget.setPinnedStackSize(mFrom, mTmpRect); // We pause the animation until the app has drawn at the new size. // The target will notify us via BoundsAnimationController#resume. // We do this here and pause the animation, rather than just defer starting it // so we can enter the animating state and have WindowStateAnimator apply the // correct logic to make this resize seamless. if (mMoveToFullscreen) { pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } } } @Override public void resume() { mHandler.removeCallbacks(mResumeRunnable); super.resume(); } @Override public void onAnimationUpdate(ValueAnimator animation) { final float value = (Float) animation.getAnimatedValue(); Loading Loading @@ -371,4 +396,15 @@ public class BoundsAnimationController { animator.start(); return animator; } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); b.resume(); } } public void onAllWindowsDrawn() { mHandler.post(this::resume); } }
services/core/java/com/android/server/wm/TaskStack.java +16 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.server.EventLogTags; import com.android.server.UiThread; import java.io.PrintWriter; Loading Loading @@ -1475,6 +1476,14 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye return true; } void onAllWindowsDrawn() { if (!mBoundsAnimating) { return; } mService.mBoundsAnimationController.onAllWindowsDrawn(); } @Override // AnimatesBounds public void onAnimationStart(boolean schedulePipModeChangedCallback) { // Hold the lock since this is called from the BoundsAnimator running on the UiThread Loading @@ -1482,6 +1491,13 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye mBoundsAnimatingRequested = false; mBoundsAnimating = true; mCancelCurrentBoundsAnimation = false; // If we are changing UI mode, as in the PiP to fullscreen // transition, then we need to wait for the window to draw. if (schedulePipModeChangedCallback) { forAllWindows((w) -> { w.mWinAnimator.resetDrawState(); }, false /* traverseTopToBottom */); } } if (mStackId == PINNED_STACK_ID) { Loading
services/core/java/com/android/server/wm/WindowState.java +4 −2 Original line number Diff line number Diff line Loading @@ -4329,7 +4329,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges, int oldVisibility) { result |= !isVisibleLw() ? RELAYOUT_RES_FIRST_TIME : 0; final boolean wasVisible = isVisibleLw(); result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0; if (mAnimatingExit) { Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit=" + mRemoveOnExit + ", mDestroying=" + mDestroying); Loading @@ -4348,7 +4350,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mLastVisibleLayoutRotation = getDisplayContent().getRotation(); mWinAnimator.mEnteringAnimation = true; if ((result & RELAYOUT_RES_FIRST_TIME) != 0) { if (!wasVisible) { prepareWindowToDisplayDuringRelayout(mergedConfiguration); } if ((attrChanges & FORMAT_CHANGED) != 0) { Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +17 −10 Original line number Diff line number Diff line Loading @@ -602,6 +602,22 @@ class WindowStateAnimator { } } void resetDrawState() { mDrawState = DRAW_PENDING; if (mWin.mAppToken == null) { return; } if (mWin.mAppToken.mAppAnimator.animation == null) { mWin.mAppToken.clearAllDrawn(); } else { // Currently animating, persist current state of allDrawn until animation // is complete. mWin.mAppToken.deferClearAllDrawn = true; } } WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) { final WindowState w = mWin; if (w.restoreSavedSurface()) { Loading @@ -619,16 +635,7 @@ class WindowStateAnimator { if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING"); mDrawState = DRAW_PENDING; if (w.mAppToken != null) { if (w.mAppToken.mAppAnimator.animation == null) { w.mAppToken.clearAllDrawn(); } else { // Currently animating, persist current state of allDrawn until animation // is complete. w.mAppToken.deferClearAllDrawn = true; } } resetDrawState(); mService.makeWindowFreezingScreenIfNeededLocked(w); Loading