Loading services/core/java/com/android/server/wm/ActivityRecord.java +4 −11 Original line number Diff line number Diff line Loading @@ -5367,18 +5367,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // rather than just direct membership. inFinishingTransition = mTransitionController.inFinishingTransition(this); if (!inFinishingTransition && (visible || !mDisplayContent.isSleeping())) { Slog.e(TAG, "setVisibility=" + visible + " while transition is not collecting or finishing " + this + " caller=" + Debug.getCallers(8)); // Force showing the parents because they may be hidden by previous transition. if (visible) { final Transaction t = getSyncTransaction(); for (WindowContainer<?> p = getParent(); p != null && p != mDisplayContent; p = p.getParent()) { if (p.mSurfaceControl != null) { t.show(p.mSurfaceControl); } } mTransitionController.onVisibleWithoutCollectingTransition(this, Debug.getCallers(1, 1)); } else { Slog.w(TAG, "Set invisible without transition " + this); } } } Loading services/core/java/com/android/server/wm/Transition.java +0 −24 Original line number Diff line number Diff line Loading @@ -1391,7 +1391,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { dc.handleCompleteDeferredRemoval(); } validateKeyguardOcclusion(); validateVisibility(); mState = STATE_FINISHED; // Rotation change may be deferred while there is a display change transition, so check Loading Loading @@ -2766,29 +2765,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } } private void validateVisibility() { for (int i = mTargets.size() - 1; i >= 0; --i) { if (reduceMode(mTargets.get(i).mReadyMode) != TRANSIT_CLOSE) { return; } } // All modes are CLOSE. The surfaces may be hidden by the animation unexpectedly. // If the window container should be visible, then recover it. mController.mStateValidators.add(() -> { for (int i = mTargets.size() - 1; i >= 0; --i) { final ChangeInfo change = mTargets.get(i); if (!change.mContainer.isVisibleRequested() || change.mContainer.mSurfaceControl == null) { continue; } Slog.e(TAG, "Force show for visible " + change.mContainer + " which may be hidden by transition unexpectedly"); change.mContainer.getSyncTransaction().show(change.mContainer.mSurfaceControl); change.mContainer.scheduleAnimation(); } }); } /** * Returns {@code true} if the transition and the corresponding transaction should be applied * on display thread. Currently, this only checks for display rotation change because the order Loading services/core/java/com/android/server/wm/TransitionController.java +30 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,36 @@ class TransitionController { mValidateDisplayVis.clear(); } void onVisibleWithoutCollectingTransition(WindowContainer<?> wc, String caller) { final boolean isPlaying = !mPlayingTransitions.isEmpty(); Slog.e(TAG, "Set visible without transition " + wc + " playing=" + isPlaying + " caller=" + caller); if (!isPlaying) { enforceSurfaceVisible(wc); return; } // Update surface visibility after the playing transitions are finished, so the last // visibility won't be replaced by the finish transaction of transition. mStateValidators.add(() -> { if (wc.isVisibleRequested()) { enforceSurfaceVisible(wc); } }); } private void enforceSurfaceVisible(WindowContainer<?> wc) { if (wc.mSurfaceControl == null) return; wc.getSyncTransaction().show(wc.mSurfaceControl); // Force showing the parents because they may be hidden by previous transition. for (WindowContainer<?> p = wc.getParent(); p != null && p != wc.mDisplayContent; p = p.getParent()) { if (p.mSurfaceControl != null) { p.getSyncTransaction().show(p.mSurfaceControl); } } wc.scheduleAnimation(); } /** * Called when the transition has a complete set of participants for its operation. In other * words, it is when the transition is "ready" but is still waiting for participants to draw. Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +4 −11 Original line number Diff line number Diff line Loading @@ -5367,18 +5367,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // rather than just direct membership. inFinishingTransition = mTransitionController.inFinishingTransition(this); if (!inFinishingTransition && (visible || !mDisplayContent.isSleeping())) { Slog.e(TAG, "setVisibility=" + visible + " while transition is not collecting or finishing " + this + " caller=" + Debug.getCallers(8)); // Force showing the parents because they may be hidden by previous transition. if (visible) { final Transaction t = getSyncTransaction(); for (WindowContainer<?> p = getParent(); p != null && p != mDisplayContent; p = p.getParent()) { if (p.mSurfaceControl != null) { t.show(p.mSurfaceControl); } } mTransitionController.onVisibleWithoutCollectingTransition(this, Debug.getCallers(1, 1)); } else { Slog.w(TAG, "Set invisible without transition " + this); } } } Loading
services/core/java/com/android/server/wm/Transition.java +0 −24 Original line number Diff line number Diff line Loading @@ -1391,7 +1391,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { dc.handleCompleteDeferredRemoval(); } validateKeyguardOcclusion(); validateVisibility(); mState = STATE_FINISHED; // Rotation change may be deferred while there is a display change transition, so check Loading Loading @@ -2766,29 +2765,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } } private void validateVisibility() { for (int i = mTargets.size() - 1; i >= 0; --i) { if (reduceMode(mTargets.get(i).mReadyMode) != TRANSIT_CLOSE) { return; } } // All modes are CLOSE. The surfaces may be hidden by the animation unexpectedly. // If the window container should be visible, then recover it. mController.mStateValidators.add(() -> { for (int i = mTargets.size() - 1; i >= 0; --i) { final ChangeInfo change = mTargets.get(i); if (!change.mContainer.isVisibleRequested() || change.mContainer.mSurfaceControl == null) { continue; } Slog.e(TAG, "Force show for visible " + change.mContainer + " which may be hidden by transition unexpectedly"); change.mContainer.getSyncTransaction().show(change.mContainer.mSurfaceControl); change.mContainer.scheduleAnimation(); } }); } /** * Returns {@code true} if the transition and the corresponding transaction should be applied * on display thread. Currently, this only checks for display rotation change because the order Loading
services/core/java/com/android/server/wm/TransitionController.java +30 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,36 @@ class TransitionController { mValidateDisplayVis.clear(); } void onVisibleWithoutCollectingTransition(WindowContainer<?> wc, String caller) { final boolean isPlaying = !mPlayingTransitions.isEmpty(); Slog.e(TAG, "Set visible without transition " + wc + " playing=" + isPlaying + " caller=" + caller); if (!isPlaying) { enforceSurfaceVisible(wc); return; } // Update surface visibility after the playing transitions are finished, so the last // visibility won't be replaced by the finish transaction of transition. mStateValidators.add(() -> { if (wc.isVisibleRequested()) { enforceSurfaceVisible(wc); } }); } private void enforceSurfaceVisible(WindowContainer<?> wc) { if (wc.mSurfaceControl == null) return; wc.getSyncTransaction().show(wc.mSurfaceControl); // Force showing the parents because they may be hidden by previous transition. for (WindowContainer<?> p = wc.getParent(); p != null && p != wc.mDisplayContent; p = p.getParent()) { if (p.mSurfaceControl != null) { p.getSyncTransaction().show(p.mSurfaceControl); } } wc.scheduleAnimation(); } /** * Called when the transition has a complete set of participants for its operation. In other * words, it is when the transition is "ready" but is still waiting for participants to draw. Loading