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

Commit 67c036b1 authored by David Stevens's avatar David Stevens
Browse files

Handle showWhenLocked on secondary displays

The keyguard has windows on the default display and the remote display
selected by MediaRouter. Keyguard occlusion only applies to the default
display. To make the activity showWhenLocked flag work on secondary
displays, pass the display id of the locked secondary display from the
SystemUi to KeyguardController and make its isKeyguardShowing method
take a displayId.

Test: android.server.cts.ActivityManagerDisplayTests
Test: #testSecondaryDisplayShowWhenLocked
Bug: 64994006
Merged-In: Ib31fc76e9df469e97a59a181f09d457ceed4ef5f
Change-Id: Ib31fc76e9df469e97a59a181f09d457ceed4ef5f
parent 50877231
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -308,7 +308,15 @@ interface IActivityManager {
    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity);
    boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
            in Intent resultData);
    void setLockScreenShown(boolean showing);
    /**
     * Informs ActivityManagerService that the keyguard is showing.
     *
     * @param showing True if the keyguard is showing, false otherwise.
     * @param secondaryDisplayShowing The displayId of the secondary display on which the keyguard
     *        is showing, or INVALID_DISPLAY if there is no such display. Only meaningful if
     *        showing is true.
     */
    void setLockScreenShown(boolean showing, int secondaryDisplayShowing);
    boolean finishActivityAffinity(in IBinder token);
    // This is not public because you need to be very careful in how you
    // manage your activity to make sure it is always the uid you expect.
+18 −3
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.keyguard;

import static android.view.Display.INVALID_DISPLAY;

import android.app.Presentation;
import android.content.Context;
import android.content.DialogInterface;
@@ -28,16 +30,21 @@ import android.view.Display;
import android.view.View;
import android.view.WindowManager;

// TODO(multi-display): Support multiple external displays
public class KeyguardDisplayManager {
    protected static final String TAG = "KeyguardDisplayManager";
    private static boolean DEBUG = KeyguardConstants.DEBUG;

    private final ViewMediatorCallback mCallback;
    private final MediaRouter mMediaRouter;
    private final Context mContext;

    Presentation mPresentation;
    private MediaRouter mMediaRouter;
    private Context mContext;
    private boolean mShowing;

    public KeyguardDisplayManager(Context context) {
    public KeyguardDisplayManager(Context context, ViewMediatorCallback callback) {
        mContext = context;
        mCallback = callback;
        mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
    }

@@ -90,6 +97,7 @@ public class KeyguardDisplayManager {
    };

    protected void updateDisplays(boolean showing) {
        Presentation originalPresentation = mPresentation;
        if (showing) {
            MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
                    MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
@@ -121,6 +129,13 @@ public class KeyguardDisplayManager {
                mPresentation = null;
            }
        }

        // mPresentation is only updated when the display changes
        if (mPresentation != originalPresentation) {
            final int displayId = mPresentation != null
                    ? mPresentation.getDisplay().getDisplayId() : INVALID_DISPLAY;
            mCallback.onSecondaryDisplayShowingChanged(displayId);
        }
    }

    private final static class KeyguardPresentation extends Presentation {
+5 −0
Original line number Diff line number Diff line
@@ -88,4 +88,9 @@ public interface ViewMediatorCallback {
     *         {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}.
     */
    int getBouncerPromptReason();

    /**
     * Invoked when the secondary display showing a keyguard window changes.
     */
    void onSecondaryDisplayShowingChanged(int displayId);
}
+43 −22
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard;

import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.internal.telephony.IccCardConstants.State.ABSENT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
@@ -239,6 +240,9 @@ public class KeyguardViewMediator extends SystemUI {
    // answer whether the input should be restricted)
    private boolean mShowing;

    // display id of the secondary display on which we have put a keyguard window
    private int mSecondaryDisplayShowing = INVALID_DISPLAY;

    /** Cached value of #isInputRestricted */
    private boolean mInputRestricted;

@@ -646,6 +650,13 @@ public class KeyguardViewMediator extends SystemUI {
            }
            return KeyguardSecurityView.PROMPT_REASON_NONE;
        }

        @Override
        public void onSecondaryDisplayShowingChanged(int displayId) {
            synchronized (KeyguardViewMediator.this) {
                setShowingLocked(mShowing, displayId, false);
            }
        }
    };

    public void userActivity() {
@@ -670,7 +681,7 @@ public class KeyguardViewMediator extends SystemUI {
        filter.addAction(Intent.ACTION_SHUTDOWN);
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext, mViewMediatorCallback);

        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

@@ -685,7 +696,8 @@ public class KeyguardViewMediator extends SystemUI {
                com.android.keyguard.R.bool.config_enableKeyguardService)) {
            setShowingLocked(!shouldWaitForProvisioning()
                    && !mLockPatternUtils.isLockScreenDisabled(
                            KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */);
                            KeyguardUpdateMonitor.getCurrentUser()),
                    mSecondaryDisplayShowing, true /* forceCallbacks */);
        }

        mStatusBarKeyguardViewManager =
@@ -1688,10 +1700,10 @@ public class KeyguardViewMediator extends SystemUI {
        playSound(mTrustedSoundId);
    }

    private void updateActivityLockScreenState(boolean showing) {
    private void updateActivityLockScreenState(boolean showing, int secondaryDisplayShowing) {
        mUiOffloadThread.submit(() -> {
            try {
                ActivityManager.getService().setLockScreenShown(showing);
                ActivityManager.getService().setLockScreenShown(showing, secondaryDisplayShowing);
            } catch (RemoteException e) {
            }
        });
@@ -2054,12 +2066,23 @@ public class KeyguardViewMediator extends SystemUI {
    }

    private void setShowingLocked(boolean showing) {
        setShowingLocked(showing, false /* forceCallbacks */);
        setShowingLocked(showing, mSecondaryDisplayShowing, false /* forceCallbacks */);
    }

    private void setShowingLocked(boolean showing, boolean forceCallbacks) {
        if (showing != mShowing || forceCallbacks) {
    private void setShowingLocked(
            boolean showing, int secondaryDisplayShowing, boolean forceCallbacks) {
        final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
        if (notifyDefaultDisplayCallbacks || secondaryDisplayShowing != mSecondaryDisplayShowing) {
            mShowing = showing;
            mSecondaryDisplayShowing = secondaryDisplayShowing;
            if (notifyDefaultDisplayCallbacks) {
                notifyDefaultDisplayCallbacks(showing);
            }
            updateActivityLockScreenState(showing, secondaryDisplayShowing);
        }
    }

    private void notifyDefaultDisplayCallbacks(boolean showing) {
        int size = mKeyguardStateCallbacks.size();
        for (int i = size - 1; i >= 0; i--) {
            IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
@@ -2076,8 +2099,6 @@ public class KeyguardViewMediator extends SystemUI {
        mUiOffloadThread.submit(() -> {
            mTrustManager.reportKeyguardShowingChanged();
        });
            updateActivityLockScreenState(showing);
        }
    }

    private void notifyTrustedChangedLocked(boolean trusted) {
+4 −4
Original line number Diff line number Diff line
@@ -715,7 +715,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    public boolean canShowErrorDialogs() {
        return mShowDialogs && !mSleeping && !mShuttingDown
                && !mKeyguardController.isKeyguardShowing()
                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
                && !(UserManager.isDeviceInDemoMode(mContext)
                        && mUserController.getCurrentUser().isDemo());
    }
@@ -12576,7 +12576,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    @Override
    public void setLockScreenShown(boolean showing) {
    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires permission "
@@ -12586,7 +12586,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        synchronized(this) {
            long ident = Binder.clearCallingIdentity();
            try {
                mKeyguardController.setKeyguardShown(showing);
                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
@@ -24007,7 +24007,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public void notifyKeyguardTrustedChanged() {
            synchronized (ActivityManagerService.this) {
                if (mKeyguardController.isKeyguardShowing()) {
                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                }
            }
Loading