summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 07:21:20 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 07:21:20 +0000
commitc43d4f80b2913fec5303d59136041d336c6537e7 (patch)
tree44fd0c8e23556fdf473727940720dfba65e2ef06
parent1de674b401c71305fe8bbcf60191d64bc822e8b9 (diff)
parent19f6b2f62c8865130b028a1a9258fd548a34e152 (diff)
downloadbase-android14-qpr1-release.tar.gz
Merge cherrypicks of ['googleplex-android-review.googlesource.com/24969087', 'googleplex-android-review.googlesource.com/25518130'] into udc-qpr1-release.android-14.0.0_r27android-14.0.0_r26android-14.0.0_r25android-14.0.0_r24android-14.0.0_r23android-14.0.0_r22android14-qpr1-release
Change-Id: I4072e8c97b7ef281c288cac251302dfe0c191844
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java19
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecordInputSink.java2
-rw-r--r--services/core/java/com/android/server/wm/Transition.java24
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java38
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java16
5 files changed, 60 insertions, 39 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..add27078b00f 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -700,7 +700,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private boolean mCurrentLaunchCanTurnScreenOn = true;
/** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
- private boolean mLastSurfaceShowing;
+ boolean mLastSurfaceShowing;
/**
* The activity is opaque and fills the entire space of this task.
@@ -5345,19 +5345,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Finish should only ever commit visibility=false, so we can check full containment
// 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 (!inFinishingTransition) {
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);
- }
+ if (!mDisplayContent.isSleeping() || canShowWhenLocked()) {
+ mTransitionController.onVisibleWithoutCollectingTransition(this,
+ Debug.getCallers(1, 1));
}
+ } else if (!mDisplayContent.isSleeping()) {
+ Slog.w(TAG, "Set invisible without transition " + this);
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index be7d9b63f779..15a3f9349007 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -87,9 +87,11 @@ class ActivityRecordInputSink {
activityBelowInTask.mAllowedTouchUid == mActivityRecord.getUid()
|| activityBelowInTask.isUid(mActivityRecord.getUid()));
if (allowPassthrough || !mIsCompatEnabled || mActivityRecord.isInTransition()) {
+ // Set to non-touchable, so the touch events can pass through.
mInputWindowHandleWrapper.setInputConfigMasked(InputConfig.NOT_TOUCHABLE,
InputConfig.NOT_TOUCHABLE);
} else {
+ // Set to touchable, so it can block by intercepting the touch events.
mInputWindowHandleWrapper.setInputConfigMasked(0, InputConfig.NOT_TOUCHABLE);
}
mInputWindowHandleWrapper.setDisplayId(mActivityRecord.getDisplayId());
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..3ad42328a2df 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -951,6 +951,44 @@ 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);
+ final ActivityRecord ar = wc.asActivityRecord();
+ if (ar != null) {
+ ar.mLastSurfaceShowing = true;
+ }
+ // 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);
+ final Task task = p.asTask();
+ if (task != null) {
+ task.mLastSurfaceShowing = true;
+ }
+ }
+ }
+ 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.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 3eed0b72e0bb..185f5ba9316e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1179,10 +1179,12 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testFinishActivityIfPossible_nonVisibleNoAppTransition() {
registerTestTransitionPlayer();
+ spyOn(mRootWindowContainer.mTransitionController);
+ final ActivityRecord bottomActivity = createActivityWithTask();
+ bottomActivity.setVisibility(false);
+ bottomActivity.setState(STOPPED, "test");
+ bottomActivity.mLastSurfaceShowing = false;
final ActivityRecord activity = createActivityWithTask();
- // Put an activity on top of test activity to make it invisible and prevent us from
- // accidentally resuming the topmost one again.
- new ActivityBuilder(mAtm).build();
activity.setVisibleRequested(false);
activity.setState(STOPPED, "test");
@@ -1190,6 +1192,14 @@ public class ActivityRecordTests extends WindowTestsBase {
verify(activity.mDisplayContent, never()).prepareAppTransition(eq(TRANSIT_CLOSE));
assertFalse(activity.inTransition());
+
+ // finishIfPossible -> completeFinishing -> addToFinishingAndWaitForIdle
+ // -> resumeFocusedTasksTopActivities
+ assertTrue(bottomActivity.isState(RESUMED));
+ assertTrue(bottomActivity.isVisible());
+ verify(mRootWindowContainer.mTransitionController).onVisibleWithoutCollectingTransition(
+ eq(bottomActivity), any());
+ assertTrue(bottomActivity.mLastSurfaceShowing);
}
/**