Merge "Delay PiP transition to fullscreen until activities draw." into oc-dev

This commit is contained in:
TreeHugger Robot
2017-04-20 01:23:19 +00:00
committed by Android (Google) Code Review
6 changed files with 80 additions and 12 deletions

View File

@@ -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();
}
}
}

View File

@@ -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;
@@ -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
@@ -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();
@@ -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);
}
}

View File

@@ -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;
@@ -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
@@ -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) {

View File

@@ -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);
@@ -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) {

View File

@@ -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()) {
@@ -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);

View File

@@ -152,6 +152,8 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
mAwaitingAnimationStart = false;
mAnimationStarted = true;
mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
mController.onAllWindowsDrawn();
}
@Override