Loading services/core/java/com/android/server/wm/AsyncRotationController.java +38 −5 Original line number Diff line number Diff line Loading @@ -275,15 +275,18 @@ class AsyncRotationController extends FadeAnimationController implements Consume // The previous animation leash will be dropped when preparing fade-in animation, so // simply apply new animation without restoring the transformation. fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM); } else if (op.mAction == Operation.ACTION_SEAMLESS && op.mLeash != null && op.mLeash.isValid()) { } else if (op.isValidSeamless()) { if (DEBUG) Slog.d(TAG, "finishOp undo seamless " + windowToken.getTopChild()); final SurfaceControl.Transaction t = windowToken.getSyncTransaction(); t.setMatrix(op.mLeash, 1, 0, 0, 1); t.setPosition(op.mLeash, 0, 0); clearTransform(t, op.mLeash); } } private static void clearTransform(SurfaceControl.Transaction t, SurfaceControl sc) { t.setMatrix(sc, 1, 0, 0, 1); t.setPosition(sc, 0, 0); } /** * Completes all operations such as applying fade-in animation on the previously hidden window * tokens. This is called if all windows are ready in new rotation or timed out. Loading Loading @@ -400,7 +403,19 @@ class AsyncRotationController extends FadeAnimationController implements Consume synchronized (mService.mGlobalLock) { Slog.i(TAG, "Async rotation timeout: " + (!mIsStartTransactionCommitted ? " start transaction is not committed" : mTargetWindowTokens)); mIsStartTransactionCommitted = true; if (!mIsStartTransactionCommitted) { // The transaction commit timeout will be handled by: // 1. BLASTSyncEngine will notify onTransactionCommitTimeout() and then // apply the start transaction of transition. // 2. The TransactionCommittedListener in setupStartTransaction() will be // notified to finish the operations of mTargetWindowTokens. // 3. The slow remote side will also apply the start transaction which may // contain stale surface transform. // 4. Finally, the slow remote reports transition finished. The cleanup // transaction from step (1) will be applied when finishing transition, // which will recover the stale state from (3). return; } mDisplayContent.finishAsyncRotationIfPossible(); mService.mWindowPlacerLocked.performSurfacePlacement(); } Loading Loading @@ -539,6 +554,20 @@ class AsyncRotationController extends FadeAnimationController implements Consume }); } /** Called when the start transition is ready, but it is not applied in time. */ void onTransactionCommitTimeout(SurfaceControl.Transaction t) { if (mIsStartTransactionCommitted) return; for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) { final Operation op = mTargetWindowTokens.valueAt(i); op.mIsCompletionPending = true; if (op.isValidSeamless()) { Slog.d(TAG, "Transaction timeout. Clear transform for " + mTargetWindowTokens.keyAt(i).getTopChild()); clearTransform(t, op.mLeash); } } } /** Called when the transition by shell is done. */ void onTransitionFinished() { if (mTransitionOp == OP_CHANGE) { Loading Loading @@ -681,6 +710,10 @@ class AsyncRotationController extends FadeAnimationController implements Consume mAction = action; } boolean isValidSeamless() { return mAction == ACTION_SEAMLESS && mLeash != null && mLeash.isValid(); } @Override public String toString() { return "Operation{a=" + mAction + " pending=" + mIsCompletionPending + '}'; Loading services/core/java/com/android/server/wm/BLASTSyncEngine.java +2 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ class BLASTSyncEngine { interface TransactionReadyListener { void onTransactionReady(int mSyncId, SurfaceControl.Transaction transaction); default void onTransactionCommitTimeout() {} } /** Loading Loading @@ -249,6 +250,7 @@ class BLASTSyncEngine { " commit callback. Application ANR likely to follow."); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); synchronized (mWm.mGlobalLock) { mListener.onTransactionCommitTimeout(); onCommitted(merged.mNativeObject != 0 ? merged : mWm.mTransactionFactory.get()); } Loading services/core/java/com/android/server/wm/Transition.java +12 −0 Original line number Diff line number Diff line Loading @@ -1683,6 +1683,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } } @Override public void onTransactionCommitTimeout() { if (mCleanupTransaction == null) return; for (int i = mTargetDisplays.size() - 1; i >= 0; --i) { final DisplayContent dc = mTargetDisplays.get(i); final AsyncRotationController asyncRotationController = dc.getAsyncRotationController(); if (asyncRotationController != null && containsChangeFor(dc, mTargets)) { asyncRotationController.onTransactionCommitTimeout(mCleanupTransaction); } } } /** * Collect tasks which moved-to-top as part of this transition. This also updates the * controller's latest-reported when relevant. Loading Loading
services/core/java/com/android/server/wm/AsyncRotationController.java +38 −5 Original line number Diff line number Diff line Loading @@ -275,15 +275,18 @@ class AsyncRotationController extends FadeAnimationController implements Consume // The previous animation leash will be dropped when preparing fade-in animation, so // simply apply new animation without restoring the transformation. fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM); } else if (op.mAction == Operation.ACTION_SEAMLESS && op.mLeash != null && op.mLeash.isValid()) { } else if (op.isValidSeamless()) { if (DEBUG) Slog.d(TAG, "finishOp undo seamless " + windowToken.getTopChild()); final SurfaceControl.Transaction t = windowToken.getSyncTransaction(); t.setMatrix(op.mLeash, 1, 0, 0, 1); t.setPosition(op.mLeash, 0, 0); clearTransform(t, op.mLeash); } } private static void clearTransform(SurfaceControl.Transaction t, SurfaceControl sc) { t.setMatrix(sc, 1, 0, 0, 1); t.setPosition(sc, 0, 0); } /** * Completes all operations such as applying fade-in animation on the previously hidden window * tokens. This is called if all windows are ready in new rotation or timed out. Loading Loading @@ -400,7 +403,19 @@ class AsyncRotationController extends FadeAnimationController implements Consume synchronized (mService.mGlobalLock) { Slog.i(TAG, "Async rotation timeout: " + (!mIsStartTransactionCommitted ? " start transaction is not committed" : mTargetWindowTokens)); mIsStartTransactionCommitted = true; if (!mIsStartTransactionCommitted) { // The transaction commit timeout will be handled by: // 1. BLASTSyncEngine will notify onTransactionCommitTimeout() and then // apply the start transaction of transition. // 2. The TransactionCommittedListener in setupStartTransaction() will be // notified to finish the operations of mTargetWindowTokens. // 3. The slow remote side will also apply the start transaction which may // contain stale surface transform. // 4. Finally, the slow remote reports transition finished. The cleanup // transaction from step (1) will be applied when finishing transition, // which will recover the stale state from (3). return; } mDisplayContent.finishAsyncRotationIfPossible(); mService.mWindowPlacerLocked.performSurfacePlacement(); } Loading Loading @@ -539,6 +554,20 @@ class AsyncRotationController extends FadeAnimationController implements Consume }); } /** Called when the start transition is ready, but it is not applied in time. */ void onTransactionCommitTimeout(SurfaceControl.Transaction t) { if (mIsStartTransactionCommitted) return; for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) { final Operation op = mTargetWindowTokens.valueAt(i); op.mIsCompletionPending = true; if (op.isValidSeamless()) { Slog.d(TAG, "Transaction timeout. Clear transform for " + mTargetWindowTokens.keyAt(i).getTopChild()); clearTransform(t, op.mLeash); } } } /** Called when the transition by shell is done. */ void onTransitionFinished() { if (mTransitionOp == OP_CHANGE) { Loading Loading @@ -681,6 +710,10 @@ class AsyncRotationController extends FadeAnimationController implements Consume mAction = action; } boolean isValidSeamless() { return mAction == ACTION_SEAMLESS && mLeash != null && mLeash.isValid(); } @Override public String toString() { return "Operation{a=" + mAction + " pending=" + mIsCompletionPending + '}'; Loading
services/core/java/com/android/server/wm/BLASTSyncEngine.java +2 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ class BLASTSyncEngine { interface TransactionReadyListener { void onTransactionReady(int mSyncId, SurfaceControl.Transaction transaction); default void onTransactionCommitTimeout() {} } /** Loading Loading @@ -249,6 +250,7 @@ class BLASTSyncEngine { " commit callback. Application ANR likely to follow."); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); synchronized (mWm.mGlobalLock) { mListener.onTransactionCommitTimeout(); onCommitted(merged.mNativeObject != 0 ? merged : mWm.mTransactionFactory.get()); } Loading
services/core/java/com/android/server/wm/Transition.java +12 −0 Original line number Diff line number Diff line Loading @@ -1683,6 +1683,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } } @Override public void onTransactionCommitTimeout() { if (mCleanupTransaction == null) return; for (int i = mTargetDisplays.size() - 1; i >= 0; --i) { final DisplayContent dc = mTargetDisplays.get(i); final AsyncRotationController asyncRotationController = dc.getAsyncRotationController(); if (asyncRotationController != null && containsChangeFor(dc, mTargets)) { asyncRotationController.onTransactionCommitTimeout(mCleanupTransaction); } } } /** * Collect tasks which moved-to-top as part of this transition. This also updates the * controller's latest-reported when relevant. Loading