Merge "Avoid requesting multiple sync for display rotation" into tm-qpr-dev
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user