Merge "Avoid requesting multiple sync for display rotation" into tm-qpr-dev

This commit is contained in:
Riddle Hsu
2022-06-08 11:19:43 +00:00
committed by Android (Google) Code Review
7 changed files with 49 additions and 30 deletions

View File

@@ -18,7 +18,6 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_TOKEN_TRANSFORM;
@@ -152,8 +151,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
/** Assigns the operation for the window tokens which can update rotation asynchronously. */
@Override
public void accept(WindowState w) {
if (w.mActivityRecord != null || !w.mHasSurface || w.mIsWallpaper || w.mIsImWindow
|| w.mAttrs.type == TYPE_NOTIFICATION_SHADE) {
if (!w.mHasSurface || !canBeAsync(w.mToken)) {
return;
}
if (mTransitionOp == OP_LEGACY && w.mForceSeamlesslyRotate) {
@@ -185,23 +183,28 @@ class AsyncRotationController extends FadeAnimationController implements Consume
mTargetWindowTokens.put(w.mToken, new Operation(action));
}
/** Returns {@code true} if the window token can update rotation independently. */
static boolean canBeAsync(WindowToken token) {
final int type = token.windowType;
return type > WindowManager.LayoutParams.LAST_APPLICATION_WINDOW
&& type != WindowManager.LayoutParams.TYPE_INPUT_METHOD
&& type != WindowManager.LayoutParams.TYPE_WALLPAPER
&& type != WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
}
/**
* Enables {@link #handleFinishDrawing(WindowState, SurfaceControl.Transaction)} to capture the
* draw transactions of the target windows if needed.
*/
void keepAppearanceInPreviousRotation() {
if (mIsSyncDrawRequested) return;
// The transition sync group may be finished earlier because it doesn't wait for these
// target windows. But the windows still need to use sync transaction to keep the appearance
// in previous rotation, so request a no-op sync to keep the state.
for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
if (mHasScreenRotationAnimation
&& mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
// The windows are hidden (leash is alpha 0) before finishing drawing so it is
// unnecessary to request sync.
continue;
}
final WindowToken token = mTargetWindowTokens.keyAt(i);
for (int j = token.getChildCount() - 1; j >= 0; j--) {
// TODO(b/234585256): The consumer should be handleFinishDrawing().
token.getChildAt(j).applyWithNextDraw(t -> {});
}
}
@@ -387,6 +390,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
* transition starts. And associate transaction callback to consume pending animations.
*/
void setupStartTransaction(SurfaceControl.Transaction t) {
if (mIsStartTransactionCommitted) return;
for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
final Operation op = mTargetWindowTokens.valueAt(i);
final SurfaceControl leash = op.mLeash;
@@ -414,7 +418,6 @@ class AsyncRotationController extends FadeAnimationController implements Consume
}
}
if (mIsStartTransactionCommitted) return;
// If there are windows have redrawn in new rotation but the start transaction has not
// been applied yet, the fade-in animation will be deferred. So once the transaction is
// committed, the fade-in animation can run with screen rotation animation.
@@ -471,23 +474,18 @@ class AsyncRotationController extends FadeAnimationController implements Consume
* by this controller.
*/
boolean handleFinishDrawing(WindowState w, SurfaceControl.Transaction postDrawTransaction) {
if (mTransitionOp == OP_LEGACY || postDrawTransaction == null
|| !mIsSyncDrawRequested || !w.mTransitionController.inTransition()) {
if (mTransitionOp == OP_LEGACY || postDrawTransaction == null || !mIsSyncDrawRequested) {
return false;
}
final Operation op = mTargetWindowTokens.get(w.mToken);
if (op == null) return false;
final boolean keepUntilTransitionFinish =
mTransitionOp == OP_APP_SWITCH && op.mAction == Operation.ACTION_FADE;
final boolean keepUntilStartTransaction =
!mIsStartTransactionCommitted && op.mAction == Operation.ACTION_SEAMLESS;
if (!keepUntilTransitionFinish && !keepUntilStartTransaction) return false;
if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w);
if (op.mDrawTransaction == null) {
op.mDrawTransaction = postDrawTransaction;
} else {
op.mDrawTransaction.merge(postDrawTransaction);
}
if (DEBUG) Slog.d(TAG, "Capture draw transaction " + w);
mDisplayContent.finishAsyncRotation(w.mToken);
return true;
}

View File

@@ -1882,7 +1882,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/** Returns {@code true} if the decided new rotation has not applied to configuration yet. */
private boolean isRotationChanging() {
boolean isRotationChanging() {
return mDisplayRotation.getRotation() != getWindowConfiguration().getRotation();
}

View File

@@ -1635,7 +1635,9 @@ public class DisplayRotation {
final WindowContainer<?> source = dc.getLastOrientationSource();
if (source != null) {
mLastOrientationSource = source.toString();
mSourceOrientation = source.mOrientation;
final WindowState w = source.asWindowState();
mSourceOrientation =
w != null ? w.mAttrs.screenOrientation : source.mOrientation;
} else {
mLastOrientationSource = null;
mSourceOrientation = SCREEN_ORIENTATION_UNSET;

View File

@@ -3664,10 +3664,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mChildren.get(i).finishSync(outMergedTransaction, cancel);
}
if (cancel && mSyncGroup != null) mSyncGroup.onCancelSync(this);
clearSyncState();
}
void clearSyncState() {
mSyncState = SYNC_STATE_NONE;
mSyncGroup = null;
}

View File

@@ -3894,6 +3894,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mDragResizingChangeReported = true;
mWindowFrames.clearReportResizeHints();
final int prevRotation = mLastReportedConfiguration
.getMergedConfiguration().windowConfiguration.getRotation();
fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration,
true /* useLatestConfig */, false /* relayoutVisible */);
final boolean syncRedraw = shouldSendRedrawForSync();
@@ -3926,7 +3928,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId,
mSyncSeqId, resizeMode);
if (drawPending && mOrientationChanging) {
if (drawPending && prevRotation != mLastReportedConfiguration
.getMergedConfiguration().windowConfiguration.getRotation()) {
mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Requested redraw for orientation change: %s", this);
@@ -5914,6 +5917,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
boolean prepareSync() {
if (!mDrawHandlers.isEmpty()) {
Slog.w(TAG, "prepareSync with mDrawHandlers, " + this + ", " + Debug.getCallers(8));
}
if (!super.prepareSync()) {
return false;
}
@@ -5975,11 +5981,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (asyncRotationController != null
&& asyncRotationController.handleFinishDrawing(this, postDrawTransaction)) {
// Consume the transaction because the controller will apply it with fade animation.
// Layout is not needed because the window will be hidden by the fade leash. Clear
// sync state because its sync transaction doesn't need to be merged to sync group.
// Layout is not needed because the window will be hidden by the fade leash.
postDrawTransaction = null;
skipLayout = true;
clearSyncState();
} else if (onSyncFinishedDrawing() && postDrawTransaction != null) {
mSyncTransaction.merge(postDrawTransaction);
// Consume the transaction because the sync group will merge it.
@@ -6033,7 +6037,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mRedrawForSyncReported) {
return false;
}
if (mInRelayout) {
// TODO(b/233286785): Remove mIsWallpaper once WallpaperService handles syncId of relayout.
if (mInRelayout && !mIsWallpaper) {
// The last sync seq id will return to the client, so there is no need to request the
// client to redraw.
return false;
@@ -6070,6 +6075,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* See {@link WindowState#mDrawHandlers}
*/
void applyWithNextDraw(Consumer<SurfaceControl.Transaction> consumer) {
if (mSyncState != SYNC_STATE_NONE) {
Slog.w(TAG, "applyWithNextDraw with mSyncState=" + mSyncState + ", " + this
+ ", " + Debug.getCallers(8));
}
mSyncSeqId++;
mDrawHandlers.add(new DrawHandler(mSyncSeqId, consumer));

View File

@@ -668,6 +668,15 @@ class WindowToken extends WindowContainer<WindowState> {
}
}
@Override
boolean prepareSync() {
if (mDisplayContent != null && mDisplayContent.isRotationChanging()
&& AsyncRotationController.canBeAsync(this)) {
return false;
}
return super.prepareSync();
}
@CallSuper
@Override
public void dumpDebug(ProtoOutputStream proto, long fieldId,

View File

@@ -665,6 +665,11 @@ public class TransitionTests extends WindowTestsBase {
mDisplayContent.setLastHasContent();
mDisplayContent.requestChangeTransitionIfNeeded(1 /* any changes */,
null /* displayChange */);
assertEquals(WindowContainer.SYNC_STATE_NONE, statusBar.mSyncState);
assertEquals(WindowContainer.SYNC_STATE_NONE, navBar.mSyncState);
assertEquals(WindowContainer.SYNC_STATE_NONE, screenDecor.mSyncState);
assertEquals(WindowContainer.SYNC_STATE_WAITING_FOR_DRAW, ime.mSyncState);
final AsyncRotationController asyncRotationController =
mDisplayContent.getAsyncRotationController();
assertNotNull(asyncRotationController);
@@ -778,7 +783,7 @@ public class TransitionTests extends WindowTestsBase {
player.start();
player.finish();
app.getTask().clearSyncState();
app.getTask().finishSync(mWm.mTransactionFactory.get(), false /* cancel */);
// The open transition is finished. Continue to play seamless display change transition,
// so the previous async rotation controller should still exist.