summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiddle Hsu <riddlehsu@google.com>2023-10-06 12:15:01 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 07:19:34 +0000
commit7f17bb5c5a6e33e3891ae3ba38a0aa21f889b550 (patch)
tree33c1a7b02efbfe47fc99a422088370c818540594
parent1de674b401c71305fe8bbcf60191d64bc822e8b9 (diff)
downloadbase-7f17bb5c5a6e33e3891ae3ba38a0aa21f889b550.tar.gz
Improve surface visibility recovering with transition
For example: 1. A transition contains an incorrect info which will set X to be invisible. 2. When the transition is playing, set the surface of X to visible directly if there is no collecting transition. 3. The transition of step 1 finishes, which applies invisible to X, then the recovering of step 2 doesn't help. So it will be more robust to recover until the playing transitions are finished. Then it can also cover some cases of other visibility validators. Bug: 303613521 Test: Finish several activities when switching display. The surface of foreground activity and its parent should keep visible. (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3fc49ae16be0c421a9afa6fcfaa5d771747f059d) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b81e181cc5581e2acb174bcf1687c61efd741786) Merged-In: I2ecb714ef0eaf94f8950bd4cd3857abfb1c46fbc Change-Id: I2ecb714ef0eaf94f8950bd4cd3857abfb1c46fbc
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java15
-rw-r--r--services/core/java/com/android/server/wm/Transition.java24
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java30
3 files changed, 34 insertions, 35 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index cd0a4efad77e..d570c9e1acab 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5346,18 +5346,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);
}
}
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index e7c6ff4d887f..7ef90fe12824 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1374,7 +1374,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
@@ -2734,29 +2733,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
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index a43a6f6292ae..577e755c310c 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -951,6 +951,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.