Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c0e223f authored by Jerry Chang's avatar Jerry Chang
Browse files

Dismiss staged split when keyguard is occluded

Dismiss staged split if there's show-when-locked activity showing on top
of keyguard. Add a callback to monitor keyguard occluded state and
delegate it to StageController in WMShell, so that it could dismiss
staged split properly when keyguard is occluded.

Bug: 188010345
Fix: 187360909
Test: WMShellUnitTests
Test: launch show-when-locked activity while keyguard showing and staged
split activated, observed the staged split will be dismissed.

Change-Id: If93b36f3fcef969d449c505086459997c27b8c75
parent d86db44b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -64,6 +64,12 @@ public interface SplitScreen {
        return null;
    }

    /**
     * Called when the keyguard occluded state changes.
     * @param occluded Indicates if the keyguard is now occluded.
     */
    void onKeyguardOccludedChanged(boolean occluded);

    /** Get a string representation of a stage type */
    static String stageTypeToString(@StageType int stage) {
        switch (stage) {
+11 −0
Original line number Diff line number Diff line
@@ -157,6 +157,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        mStageCoordinator.exitSplitScreen();
    }

    public void onKeyguardOccludedChanged(boolean occluded) {
        mStageCoordinator.onKeyguardOccludedChanged(occluded);
    }

    public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
        mStageCoordinator.exitSplitScreenOnHide(exitSplitScreenOnHide);
    }
@@ -284,6 +288,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
            mISplitScreen = new ISplitScreenImpl(SplitScreenController.this);
            return mISplitScreen;
        }

        @Override
        public void onKeyguardOccludedChanged(boolean occluded) {
            mMainExecutor.execute(() -> {
                SplitScreenController.this.onKeyguardOccludedChanged(occluded);
            });
        }
    }

    /**
+14 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    private final DisplayImeController mDisplayImeController;
    private final SplitScreenTransitions mSplitTransitions;
    private boolean mExitSplitScreenOnHide = true;
    private boolean mKeyguardOccluded;

    // TODO(b/187041611): remove this flag after totally deprecated legacy split
    /** Whether the device is supporting legacy split or not. */
@@ -275,6 +276,12 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mTaskOrganizer.applyTransaction(wct);
    }

    void onKeyguardOccludedChanged(boolean occluded) {
        // Do not exit split directly, because it needs to wait for task info update to determine
        // which task should remain on top after split dismissed.
        mKeyguardOccluded = occluded;
    }

    void exitSplitScreen() {
        exitSplitScreen(null /* childrenToTop */);
    }
@@ -407,6 +414,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // Exit split-screen if both stage are not visible.
            // TODO: This is only a temporary request from UX and is likely to be removed soon...
            exitSplitScreen();
        } else if (mKeyguardOccluded) {
            // At least one of the stages is visible while keyguard occluded. Dismiss split because
            // there's show-when-locked activity showing on top of keyguard. Also make sure the
            // task contains show-when-locked activity remains on top after split dismissed.
            final StageTaskListener toTop =
                    mainStageVisible ? mMainStage : (sideStageVisible ? mSideStage : null);
            exitSplitScreen(toTop);
        }

        if (mainStageVisible) {
+15 −0
Original line number Diff line number Diff line
@@ -2738,6 +2738,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        updateBiometricListeningState();
    }

    /** Notifies that the occluded state changed. */
    public void onKeyguardOccludedChanged(boolean occluded) {
        Assert.isMainThread();
        if (DEBUG) {
            Log.d(TAG, "onKeyguardOccludedChanged(" + occluded + ")");
        }
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onKeyguardOccludedChanged(occluded);
            }
        }
    }

    /**
     * Handle {@link #MSG_KEYGUARD_RESET}
     */
@@ -2920,6 +2934,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        callback.onPhoneStateChanged(mPhoneState);
        callback.onRefreshCarrierInfo();
        callback.onClockVisibilityChanged();
        callback.onKeyguardOccludedChanged(mKeyguardOccluded);
        callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
        callback.onTelephonyCapable(mTelephonyCapable);
        callback.onLockScreenModeChanged(mLockScreenMode);
+6 −0
Original line number Diff line number Diff line
@@ -88,6 +88,12 @@ public class KeyguardUpdateMonitorCallback {
     */
    public void onKeyguardVisibilityChanged(boolean showing) { }

    /**
     * Called when the keyguard occluded state changes.
     * @param occluded Indicates if the keyguard is now occluded.
     */
    public void onKeyguardOccludedChanged(boolean occluded) { }

    public void onKeyguardVisibilityChangedRaw(boolean showing) {
        final long now = SystemClock.elapsedRealtime();
        if (showing == mShowing
Loading