diff options
10 files changed, 136 insertions, 16 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index c0734e95ecb7..3b3091a9caf3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -44,11 +44,6 @@ public interface Pip { } /** - * Hides the PIP menu. - */ - default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {} - - /** * Called when configuration is changed. */ default void onConfigurationChanged(Configuration newConfig) { @@ -125,6 +120,23 @@ public interface Pip { default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { } /** + * Called when the visibility of keyguard is changed. + * @param showing {@code true} if keyguard is now showing, {@code false} otherwise. + * @param animating {@code true} if system is animating between keyguard and surface behind, + * this only makes sense when showing is {@code false}. + */ + default void onKeyguardVisibilityChanged(boolean showing, boolean animating) { } + + /** + * Called when the dismissing animation keyguard and surfaces behind is finished. + * See also {@link #onKeyguardVisibilityChanged(boolean, boolean)}. + * + * TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of + * keyguard dismiss animation. + */ + default void onKeyguardDismissAnimationFinished() { } + + /** * Dump the current state and information if need. * * @param pw The stream to dump information to. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 4690e16bc385..45c9a958a42a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -965,6 +965,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mDeferredAnimEndTransaction = null; } + /** Explicitly set the visibility of PiP window. */ + public void setPipVisibility(boolean visible) { + if (!isInPip()) { + return; + } + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + mSurfaceTransactionHelper.alpha(tx, mLeash, visible ? 1f : 0f); + tx.apply(); + } + @Override public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { mCurrentRotation = newConfig.windowConfiguration.getRotation(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 42ceb42f39e8..dad261ad9580 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -129,6 +129,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb protected PinnedStackListenerForwarder.PinnedTaskListener mPinnedTaskListener = new PipControllerPinnedTaskListener(); + private boolean mIsKeyguardShowingOrAnimating; + private interface PipAnimationListener { /** * Notifies the listener that the Pip animation is started. @@ -593,6 +595,33 @@ public class PipController implements PipTransitionController.PipTransitionCallb } /** + * If {@param keyguardShowing} is {@code false} and {@param animating} is {@code true}, + * we would wait till the dismissing animation of keyguard and surfaces behind to be + * finished first to reset the visibility of PiP window. + * See also {@link #onKeyguardDismissAnimationFinished()} + */ + private void onKeyguardVisibilityChanged(boolean keyguardShowing, boolean animating) { + if (!mPipTaskOrganizer.isInPip()) { + return; + } + if (keyguardShowing) { + mIsKeyguardShowingOrAnimating = true; + hidePipMenu(null /* onStartCallback */, null /* onEndCallback */); + mPipTaskOrganizer.setPipVisibility(false); + } else if (!animating) { + mIsKeyguardShowingOrAnimating = false; + mPipTaskOrganizer.setPipVisibility(true); + } + } + + private void onKeyguardDismissAnimationFinished() { + if (mPipTaskOrganizer.isInPip()) { + mIsKeyguardShowingOrAnimating = false; + mPipTaskOrganizer.setPipVisibility(true); + } + } + + /** * Sets a customized touch gesture that replaces the default one. */ public void setTouchGesture(PipTouchGesture gesture) { @@ -603,7 +632,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb * Sets both shelf visibility and its height. */ private void setShelfHeight(boolean visible, int height) { - setShelfHeightLocked(visible, height); + if (!mIsKeyguardShowingOrAnimating) { + setShelfHeightLocked(visible, height); + } } private void setShelfHeightLocked(boolean visible, int height) { @@ -834,13 +865,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) { - mMainExecutor.execute(() -> { - PipController.this.hidePipMenu(onStartCallback, onEndCallback); - }); - } - - @Override public void expandPip() { mMainExecutor.execute(() -> { PipController.this.expandPip(); @@ -918,6 +942,18 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override + public void onKeyguardVisibilityChanged(boolean showing, boolean animating) { + mMainExecutor.execute(() -> { + PipController.this.onKeyguardVisibilityChanged(showing, animating); + }); + } + + @Override + public void onKeyguardDismissAnimationFinished() { + mMainExecutor.execute(PipController.this::onKeyguardDismissAnimationFinished); + } + + @Override public void dump(PrintWriter pw) { try { mMainExecutor.executeBlocking(() -> { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index f5e31dd84e8a..38e52953ff08 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -188,6 +188,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final int MSG_KEYGUARD_GOING_AWAY = 342; private static final int MSG_TIME_FORMAT_UPDATE = 344; private static final int MSG_REQUIRE_NFC_UNLOCK = 345; + private static final int MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED = 346; /** Biometric authentication state: Not listening. */ private static final int BIOMETRIC_STATE_STOPPED = 0; @@ -2025,6 +2026,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab case MSG_REQUIRE_NFC_UNLOCK: handleRequireUnlockForNfc(); break; + case MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED: + handleKeyguardDismissAnimationFinished(); + break; default: super.handleMessage(msg); break; @@ -3297,6 +3301,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } /** + * Handle {@link #MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED} + */ + private void handleKeyguardDismissAnimationFinished() { + Assert.isMainThread(); + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onKeyguardDismissAnimationFinished(); + } + } + } + + /** * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION} */ private void handleReportEmergencyCallAction() { @@ -3634,6 +3651,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.sendMessage(mHandler.obtainMessage(MSG_KEYGUARD_GOING_AWAY, goingAway)); } + /** + * Sends a message to notify the keyguard dismiss animation is finished. + */ + public void dispatchKeyguardDismissAnimationFinished() { + mHandler.sendEmptyMessage(MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED); + } + public boolean isDeviceInteractive() { return mDeviceInteractive; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 2620195ae8c4..051b81e484d8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -109,6 +109,14 @@ public class KeyguardUpdateMonitorCallback { public void onKeyguardBouncerFullyShowingChanged(boolean bouncerIsFullyShowing) { } /** + * Called when the dismissing animation of keyguard and surfaces behind is finished. + * If the surface behind is the Launcher, we may still be playing in-window animations + * when this is called (since it's only called once we dismiss the keyguard and end the + * remote animation). + */ + public void onKeyguardDismissAnimationFinished() { } + + /** * Called when visibility of lockscreen clock changes, such as when * obscured by a widget. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 14a7e3c7f013..404e5311961b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -857,6 +857,13 @@ class KeyguardUnlockAnimationController @Inject constructor( } /** + * Whether the RemoteAnimation on the app/launcher surface behind the keyguard is 'running'. + */ + fun isAnimatingBetweenKeyguardAndSurfaceBehind(): Boolean { + return keyguardViewMediator.get().isAnimatingBetweenKeyguardAndSurfaceBehind + } + + /** * Whether we are playing a canned unlock animation, vs. unlocking from a touch gesture such as * a swipe. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 4d59f1a8e363..e379d766f0ca 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2625,6 +2625,9 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, // The remote animation is over, so we're not going away anymore. mKeyguardStateController.notifyKeyguardGoingAway(false); + + // Dispatch the callback on animation finishes. + mUpdateMonitor.dispatchKeyguardDismissAnimationFinished(); }); mKeyguardUnlockAnimationControllerLazy.get().notifyFinishedKeyguardExitAnimation( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java index 15ee553da457..dce24122aa7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.app.IActivityTaskManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.KeyguardStateController.Callback; @@ -94,6 +95,15 @@ public interface KeyguardStateController extends CallbackController<Callback> { boolean isKeyguardGoingAway(); /** + * Whether we're currently animating between the keyguard and the app/launcher surface behind + * it, or will be shortly (which happens if we started a fling to dismiss the keyguard). + * @see {@link KeyguardViewMediator#isAnimatingBetweenKeyguardAndSurfaceBehind()} + */ + default boolean isAnimatingBetweenKeyguardAndSurfaceBehind() { + return false; + }; + + /** * @return a shortened fading away duration similar to * {{@link #getKeyguardFadingAwayDuration()}} which may only span half of the duration, unless * we're bypassing diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index 77e285d1e15d..2a225b909f90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -279,6 +279,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum } @Override + public boolean isAnimatingBetweenKeyguardAndSurfaceBehind() { + return mUnlockAnimationControllerLazy.get().isAnimatingBetweenKeyguardAndSurfaceBehind(); + } + + @Override public boolean isBypassFadingAnimation() { return mBypassFadingAnimation; } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index cddfd4498cfb..a6db2aa48a88 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -200,9 +200,13 @@ public final class WMShell extends CoreStartable mPipKeyguardCallback = new KeyguardUpdateMonitorCallback() { @Override public void onKeyguardVisibilityChanged(boolean showing) { - if (showing) { - pip.hidePipMenu(null, null); - } + pip.onKeyguardVisibilityChanged(showing, + mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind()); + } + + @Override + public void onKeyguardDismissAnimationFinished() { + pip.onKeyguardDismissAnimationFinished(); } }; mKeyguardUpdateMonitor.registerCallback(mPipKeyguardCallback); |