diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-12-15 07:21:20 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-12-15 07:21:20 +0000 |
commit | c43d4f80b2913fec5303d59136041d336c6537e7 (patch) | |
tree | 44fd0c8e23556fdf473727940720dfba65e2ef06 | |
parent | 1de674b401c71305fe8bbcf60191d64bc822e8b9 (diff) | |
parent | 19f6b2f62c8865130b028a1a9258fd548a34e152 (diff) | |
download | base-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
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); } /** |