Merge "Prevent timeout of async rotation by invisible windows" into udc-dev
This commit is contained in:
@@ -217,6 +217,34 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
|||||||
if (DEBUG) Slog.d(TAG, "Requested to sync draw transaction");
|
if (DEBUG) Slog.d(TAG, "Requested to sync draw transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If an async window is not requested to redraw or its surface is removed, then complete its
|
||||||
|
* operation directly to avoid waiting until timeout.
|
||||||
|
*/
|
||||||
|
void updateTargetWindows() {
|
||||||
|
if (mTransitionOp == OP_LEGACY || !mIsStartTransactionCommitted) return;
|
||||||
|
for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
|
||||||
|
final Operation op = mTargetWindowTokens.valueAt(i);
|
||||||
|
if (op.mIsCompletionPending || op.mAction == Operation.ACTION_SEAMLESS) {
|
||||||
|
// Skip completed target. And seamless windows use the signal from blast sync.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final WindowToken token = mTargetWindowTokens.keyAt(i);
|
||||||
|
int readyCount = 0;
|
||||||
|
final int childCount = token.getChildCount();
|
||||||
|
for (int j = childCount - 1; j >= 0; j--) {
|
||||||
|
final WindowState w = token.getChildAt(j);
|
||||||
|
// If the token no longer contains pending drawn windows, then it is ready.
|
||||||
|
if (w.isDrawn() || !w.mWinAnimator.getShown()) {
|
||||||
|
readyCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readyCount == childCount) {
|
||||||
|
mDisplayContent.finishAsyncRotation(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Lets the window fit in new rotation naturally. */
|
/** Lets the window fit in new rotation naturally. */
|
||||||
private void finishOp(WindowToken windowToken) {
|
private void finishOp(WindowToken windowToken) {
|
||||||
final Operation op = mTargetWindowTokens.remove(windowToken);
|
final Operation op = mTargetWindowTokens.remove(windowToken);
|
||||||
|
|||||||
@@ -4761,6 +4761,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
|
|
||||||
void updateWindowsForAnimator() {
|
void updateWindowsForAnimator() {
|
||||||
forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
|
forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
|
||||||
|
if (mAsyncRotationController != null) {
|
||||||
|
mAsyncRotationController.updateTargetWindows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isInputMethodClientFocus(int uid, int pid) {
|
boolean isInputMethodClientFocus(int uid, int pid) {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
|
|||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
|
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
|
||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
|
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;
|
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
|
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
|
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
|
||||||
@@ -424,7 +423,7 @@ class WindowStateAnimator {
|
|||||||
|
|
||||||
computeShownFrameLocked();
|
computeShownFrameLocked();
|
||||||
|
|
||||||
if (w.isParentWindowHidden() || !w.isOnScreen()) {
|
if (!w.isOnScreen()) {
|
||||||
hide(t, "prepareSurfaceLocked");
|
hide(t, "prepareSurfaceLocked");
|
||||||
mWallpaperControllerLocked.hideWallpapers(w);
|
mWallpaperControllerLocked.hideWallpapers(w);
|
||||||
|
|
||||||
@@ -449,30 +448,23 @@ class WindowStateAnimator {
|
|||||||
|
|
||||||
if (prepared && mDrawState == HAS_DRAWN) {
|
if (prepared && mDrawState == HAS_DRAWN) {
|
||||||
if (mLastHidden) {
|
if (mLastHidden) {
|
||||||
if (showSurfaceRobustlyLocked(t)) {
|
mSurfaceController.showRobustly(t);
|
||||||
mAnimator.requestRemovalOfReplacedWindows(w);
|
mAnimator.requestRemovalOfReplacedWindows(w);
|
||||||
mLastHidden = false;
|
mLastHidden = false;
|
||||||
final DisplayContent displayContent = w.getDisplayContent();
|
final DisplayContent displayContent = w.getDisplayContent();
|
||||||
if (!displayContent.getLastHasContent()) {
|
if (!displayContent.getLastHasContent()) {
|
||||||
// This draw means the difference between unique content and mirroring.
|
// This draw means the difference between unique content and mirroring.
|
||||||
// Run another pass through performLayout to set mHasContent in the
|
// Run another pass through performLayout to set mHasContent in the
|
||||||
// LogicalDisplay.
|
// LogicalDisplay.
|
||||||
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
|
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
|
||||||
if (DEBUG_LAYOUT_REPEATS) {
|
if (DEBUG_LAYOUT_REPEATS) {
|
||||||
mService.mWindowPlacerLocked.debugLayoutRepeats(
|
mService.mWindowPlacerLocked.debugLayoutRepeats(
|
||||||
"showSurfaceRobustlyLocked " + w,
|
"showSurfaceRobustlyLocked " + w,
|
||||||
displayContent.pendingLayoutChanges);
|
displayContent.pendingLayoutChanges);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
w.setOrientationChanging(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (mWin.isAnimating(TRANSITION | PARENTS)) {
|
|
||||||
ProtoLog.v(WM_DEBUG_ANIM, "prepareSurface: No changes in animation for %s", this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w.getOrientationChanging()) {
|
if (w.getOrientationChanging()) {
|
||||||
@@ -511,22 +503,6 @@ class WindowStateAnimator {
|
|||||||
mSurfaceController.setColorSpaceAgnostic(mWin.getPendingTransaction(), agnostic);
|
mSurfaceController.setColorSpaceAgnostic(mWin.getPendingTransaction(), agnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Have the surface flinger show a surface, robustly dealing with
|
|
||||||
* error conditions. In particular, if there is not enough memory
|
|
||||||
* to show the surface, then we will try to get rid of other surfaces
|
|
||||||
* in order to succeed.
|
|
||||||
*
|
|
||||||
* @return Returns true if the surface was successfully shown.
|
|
||||||
*/
|
|
||||||
private boolean showSurfaceRobustlyLocked(SurfaceControl.Transaction t) {
|
|
||||||
boolean shown = mSurfaceController.showRobustly(t);
|
|
||||||
if (!shown)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyEnterAnimationLocked() {
|
void applyEnterAnimationLocked() {
|
||||||
// If we are the new part of a window replacement transition and we have requested
|
// If we are the new part of a window replacement transition and we have requested
|
||||||
// not to animate, we instead want to make it seamless, so we don't want to apply
|
// not to animate, we instead want to make it seamless, so we don't want to apply
|
||||||
|
|||||||
@@ -245,13 +245,13 @@ class WindowSurfaceController {
|
|||||||
t.setColorSpaceAgnostic(mSurfaceControl, agnostic);
|
t.setColorSpaceAgnostic(mSurfaceControl, agnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean showRobustly(SurfaceControl.Transaction t) {
|
void showRobustly(SurfaceControl.Transaction t) {
|
||||||
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
|
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
|
||||||
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
|
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
|
||||||
+ " during relayout");
|
+ " during relayout");
|
||||||
|
|
||||||
if (mSurfaceShown) {
|
if (mSurfaceShown) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setShown(true);
|
setShown(true);
|
||||||
@@ -262,7 +262,6 @@ class WindowSurfaceController {
|
|||||||
dc.mDisplayId, 1 /* request shown */,
|
dc.mDisplayId, 1 /* request shown */,
|
||||||
String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
|
String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean clearWindowContentFrameStats() {
|
boolean clearWindowContentFrameStats() {
|
||||||
|
|||||||
@@ -1018,6 +1018,10 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayRotationChange() {
|
public void testDisplayRotationChange() {
|
||||||
|
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
|
||||||
|
spyOn(displayPolicy);
|
||||||
|
// Simulate gesture navigation (non-movable) so it is not seamless.
|
||||||
|
doReturn(false).when(displayPolicy).navigationBarCanMove();
|
||||||
final Task task = createActivityRecord(mDisplayContent).getTask();
|
final Task task = createActivityRecord(mDisplayContent).getTask();
|
||||||
final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
|
final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
|
||||||
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
|
final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
|
||||||
@@ -1072,7 +1076,8 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
|
|
||||||
// Navigation bar finishes drawing after the start transaction, so its fade-in animation
|
// Navigation bar finishes drawing after the start transaction, so its fade-in animation
|
||||||
// can execute directly.
|
// can execute directly.
|
||||||
asyncRotationController.handleFinishDrawing(navBar, mMockT);
|
navBar.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
|
||||||
|
asyncRotationController.updateTargetWindows();
|
||||||
assertFalse(asyncRotationController.isTargetToken(navBar.mToken));
|
assertFalse(asyncRotationController.isTargetToken(navBar.mToken));
|
||||||
assertNull(mDisplayContent.getAsyncRotationController());
|
assertNull(mDisplayContent.getAsyncRotationController());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user