From 311c25b03b6f42dff86e4c3df6be587bf2417347 Mon Sep 17 00:00:00 2001 From: Issei Suzuki Date: Tue, 28 Sep 2021 12:24:24 +0200 Subject: [PATCH] Revised logic to sync keyguard occlude status. WM and SysUI must be in sync about keyguard occlude status, so WM calls IKeyguardService#setOccluded to notify to SysUI whether the top activity can occlude the keyguard or not. In case remote animation is used for keyguard (un)occlude transition, SysUI receives a binder call to start keyguard (un)occlude animation and updates its internal state. So WM doesn't need to call IKeyguardService#setOccluded. Note: Keyguard occlude state can be changed without running app transition animation. In such case, WM still needs to call IKeyguardService#setOccluded even if remote animation is enabled. Bug: 191349992 Test: Existing tests pass. Change-Id: I3991809302cf151c382af5821f5a64df939ecb79 --- .../systemui/keyguard/KeyguardService.java | 2 +- .../server/policy/PhoneWindowManager.java | 42 ++++++++++++------- .../server/policy/WindowManagerPolicy.java | 7 +++- .../keyguard/KeyguardServiceDelegate.java | 10 +---- .../com/android/server/wm/AppTransition.java | 9 ++-- .../com/android/server/wm/DisplayPolicy.java | 3 +- .../server/wm/RecentsAnimationController.java | 5 ++- .../com/android/server/wm/Transition.java | 3 +- .../server/wm/TransitionController.java | 5 ++- .../server/wm/WindowManagerInternal.java | 8 ++-- .../wm/RecentsAnimationControllerTest.java | 2 +- .../server/wm/TestWindowManagerPolicy.java | 2 +- 12 files changed, 59 insertions(+), 39 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index a5dd6a11c388b..3c580791879b7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -358,7 +358,7 @@ public class KeyguardService extends Service { if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE) { mBinder.setOccluded(true /* isOccluded */, true /* animate */); } else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE) { - mBinder.setOccluded(false /* isOccluded */, true /* animate */); + mBinder.setOccluded(false /* isOccluded */, false /* animate */); } // TODO(bc-unlock): Implement (un)occlude animation. finishedCallback.onAnimationFinished(); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5acff2b6c7435..7e5fe08d022f0 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1814,18 +1814,22 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() { @Override - public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration, - long statusBarAnimationStartTime, long statusBarAnimationDuration) { + public int onAppTransitionStartingLocked(boolean keyguardGoingAway, + boolean keyguardOccluding, long duration, long statusBarAnimationStartTime, + long statusBarAnimationDuration) { // When remote animation is enabled for KEYGUARD_GOING_AWAY transition, SysUI // receives IRemoteAnimationRunner#onAnimationStart to start animation, so we don't // need to call IKeyguardService#keyguardGoingAway here. return handleStartTransitionForKeyguardLw(keyguardGoingAway - && !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation, duration); + && !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation, + keyguardOccluding, duration); } @Override public void onAppTransitionCancelledLocked(boolean keyguardGoingAway) { - handleStartTransitionForKeyguardLw(keyguardGoingAway, 0 /* duration */); + handleStartTransitionForKeyguardLw( + keyguardGoingAway, false /* keyguardOccludingStarted */, + 0 /* duration */); } }); @@ -3048,26 +3052,29 @@ public class PhoneWindowManager implements WindowManagerPolicy { mPendingKeyguardOccluded = occluded; mKeyguardOccludedChanged = true; } else { - setKeyguardOccludedLw(occluded, false /* force */); + setKeyguardOccludedLw(occluded, false /* force */, + false /* transitionStarted */); } } @Override - public int applyKeyguardOcclusionChange() { + public int applyKeyguardOcclusionChange(boolean transitionStarted) { if (mKeyguardOccludedChanged) { if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded=" + mPendingKeyguardOccluded); mKeyguardOccludedChanged = false; - if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */)) { + if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */, + transitionStarted)) { return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER; } } return 0; } - private int handleStartTransitionForKeyguardLw(boolean keyguardGoingAway, long duration) { - final int res = applyKeyguardOcclusionChange(); - if (res != 0) return res; + private int handleStartTransitionForKeyguardLw(boolean keyguardGoingAway, + boolean keyguardOccluding, long duration) { + final int redoLayout = applyKeyguardOcclusionChange(keyguardOccluding); + if (redoLayout != 0) return redoLayout; if (keyguardGoingAway) { if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration); @@ -3269,7 +3276,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void setKeyguardCandidateLw(WindowState win) { mKeyguardCandidate = win; - setKeyguardOccludedLw(isKeyguardOccluded(), true /* force */); + setKeyguardOccludedLw(isKeyguardOccluded(), true /* force */, + false /* keyguardOccludingStarted */); } /** @@ -3278,9 +3286,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { * @param isOccluded Whether the Keyguard is occluded by another window. * @param force notify the occluded status to KeyguardService and update flags even though * occlude status doesn't change. + * @param transitionStarted {@code true} if keyguard (un)occluded transition started. * @return Whether the flags have changed and we have to redo the layout. */ - private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) { + private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force, + boolean transitionStarted) { if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); if (isKeyguardOccluded() == isOccluded && !force) { return false; @@ -3288,8 +3298,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean showing = mKeyguardDelegate.isShowing(); final boolean animate = showing && !isOccluded; - mKeyguardDelegate.setOccluded(isOccluded, animate); - + // When remote animation is enabled for keyguard (un)occlude transition, KeyguardService + // uses remote animation start as a signal to update its occlusion status ,so we don't need + // to notify here. + final boolean notify = !WindowManagerService.sEnableRemoteKeyguardOccludeAnimation + || !transitionStarted; + mKeyguardDelegate.setOccluded(isOccluded, animate, notify); if (!showing) { return false; } diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 78b03b2b88e76..c3ec6a4ab6b58 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -173,8 +173,11 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { */ void onKeyguardOccludedChangedLw(boolean occluded); - /** Applies a keyguard occlusion change if one happened. */ - int applyKeyguardOcclusionChange(); + /** + * Applies a keyguard occlusion change if one happened. + * @param transitionStarted Whether keyguard (un)occlude transition is starting or not. + */ + int applyKeyguardOcclusionChange(boolean transitionStarted); /** * Interface to the Window Manager state associated with a particular diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 86ff33e8cc423..8978fabbb9d24 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -29,7 +29,6 @@ import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; import com.android.server.UiThread; import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult; -import com.android.server.wm.WindowManagerService; import java.io.PrintWriter; @@ -259,13 +258,8 @@ public class KeyguardServiceDelegate { } } - /** - * @deprecated Notify occlude status change via remote animation. - */ - @Deprecated - public void setOccluded(boolean isOccluded, boolean animate) { - if (!WindowManagerService.sEnableRemoteKeyguardOccludeAnimation - && mKeyguardService != null) { + public void setOccluded(boolean isOccluded, boolean animate, boolean notify) { + if (mKeyguardService != null && notify) { if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); mKeyguardService.setOccluded(isOccluded, animate); } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index e21a00b4aec67..bd08d01768e30 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -443,6 +443,7 @@ public class AppTransition implements Dump { int redoLayout = notifyAppTransitionStartingLocked( AppTransition.isKeyguardGoingAwayTransitOld(transit), + AppTransition.isKeyguardOccludeTransitOld(transit), topOpeningAnim != null ? topOpeningAnim.getDurationHint() : 0, topOpeningAnim != null ? topOpeningAnim.getStatusBarTransitionsStartTime() @@ -557,12 +558,14 @@ public class AppTransition implements Dump { } } - private int notifyAppTransitionStartingLocked(boolean keyguardGoingAway, long duration, - long statusBarAnimationStartTime, long statusBarAnimationDuration) { + private int notifyAppTransitionStartingLocked(boolean keyguardGoingAway, + boolean keyguardOcclude, long duration, long statusBarAnimationStartTime, + long statusBarAnimationDuration) { int redoLayout = 0; for (int i = 0; i < mListeners.size(); i++) { redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(keyguardGoingAway, - duration, statusBarAnimationStartTime, statusBarAnimationDuration); + keyguardOcclude, duration, statusBarAnimationStartTime, + statusBarAnimationDuration); } return redoLayout; } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index a7c496e5af39e..50c56de491346 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -618,7 +618,8 @@ public class DisplayPolicy { } @Override - public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration, + public int onAppTransitionStartingLocked(boolean keyguardGoingAway, + boolean keyguardOccluding, long duration, long statusBarAnimationStartTime, long statusBarAnimationDuration) { mHandler.post(() -> { StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 22c84590fcfc0..78de0edd7b294 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -169,8 +169,9 @@ public class RecentsAnimationController implements DeathRecipient { */ final AppTransitionListener mAppTransitionListener = new AppTransitionListener() { @Override - public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration, - long statusBarAnimationStartTime, long statusBarAnimationDuration) { + public int onAppTransitionStartingLocked(boolean keyguardGoingAway, + boolean keyguardOccluding, long duration, long statusBarAnimationStartTime, + long statusBarAnimationDuration) { continueDeferredCancel(); return 0; } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index e537c0afc1475..8bd62576bd3f8 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -789,7 +789,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } } if ((flags & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0) { - mController.mAtm.mWindowManager.mPolicy.applyKeyguardOcclusionChange(); + mController.mAtm.mWindowManager.mPolicy.applyKeyguardOcclusionChange( + true /* keyguardOccludingStarted */); } } diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index ff4cc3d1b7848..b849170d8f3f6 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -388,9 +388,10 @@ class TransitionController { void dispatchLegacyAppTransitionStarting(TransitionInfo info) { final boolean keyguardGoingAway = info.isKeyguardGoingAway(); for (int i = 0; i < mLegacyListeners.size(); ++i) { + // TODO(shell-transitions): handle (un)occlude transition. mLegacyListeners.get(i).onAppTransitionStartingLocked(keyguardGoingAway, - 0 /* durationHint */, SystemClock.uptimeMillis(), - AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); + false /* keyguardOcclude */, 0 /* durationHint */, + SystemClock.uptimeMillis(), AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index ba0266a575bfd..4e51a17e03e02 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -194,7 +194,7 @@ public abstract class WindowManagerInternal { /** * Called when a pending app transition gets cancelled. * - * @param keyguardGoingAway true if keyguard going away transition transition got cancelled. + * @param keyguardGoingAway true if keyguard going away transition got cancelled. */ public void onAppTransitionCancelledLocked(boolean keyguardGoingAway) {} @@ -207,6 +207,7 @@ public abstract class WindowManagerInternal { * Called when an app transition gets started * * @param keyguardGoingAway true if keyguard going away transition is started. + * @param keyguardOccluding true if keyguard (un)occlude transition is started. * @param duration the total duration of the transition * @param statusBarAnimationStartTime the desired start time for all visual animations in * the status bar caused by this app transition in uptime millis @@ -218,8 +219,9 @@ public abstract class WindowManagerInternal { * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER}, * or {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}. */ - public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration, - long statusBarAnimationStartTime, long statusBarAnimationDuration) { + public int onAppTransitionStartingLocked(boolean keyguardGoingAway, + boolean keyguardOccluding, long duration, long statusBarAnimationStartTime, + long statusBarAnimationDuration) { return 0; } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index a680cba8b2667..9d2a69197013e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -257,7 +257,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { verify(mMockRunner).onAnimationCanceled(null /* taskSnapshot */); // Simulate the app transition finishing - mController.mAppTransitionListener.onAppTransitionStartingLocked(false, 0, 0, 0); + mController.mAppTransitionListener.onAppTransitionStartingLocked(false, false, 0, 0, 0); verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, false); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java index acadb74d333f0..16d75ca884f1d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -368,7 +368,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { } @Override - public int applyKeyguardOcclusionChange() { + public int applyKeyguardOcclusionChange(boolean keyguardOccludingStarted) { return 0; }