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

Commit 0655da03 authored by Winson Chung's avatar Winson Chung
Browse files

Disallow entering PiP without dismissing keyguard.

- If an activity is showing on the keyguard and enters picture-
  in-picture, then prompt the user to authenticate first
- Fixing NPE in SystemUI due to null runnable being added to the
  post-keyguard-gone callbacks
- Prevent FLAG_SHOW_WHEN_LOCKED from applying when determining
  visibility over keyguard for activities that are in the pinned
  stack

Bug: 33660880
Test: android.server.cts.KeyguardLockedTests
Test: #testEnterPipOverKeyguard

Change-Id: I89477a8a0067e285e5d0122e918fac45274c57ad
parent e097432e
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -3613,17 +3613,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            final boolean dismissShade,
            final boolean afterKeyguardGone,
            final boolean deferred) {
        final Runnable dismissAction = () -> {
            if (runnable != null) {
                AsyncTask.execute(runnable);
            }
        };
        dismissKeyguardThenExecute(() -> {
            if (runnable != null) {
                if (mStatusBarKeyguardViewManager.isShowing()
                        && mStatusBarKeyguardViewManager.isOccluded()) {
                    mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
                } else {
                dismissAction.run();
                    AsyncTask.execute(runnable);
                }
            }
            if (dismissShade) {
                if (mExpandedVisible) {
+40 −3
Original line number Diff line number Diff line
@@ -6710,6 +6710,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    /**
     * @return whther the keyguard is currently locked.
     */
    boolean isKeyguardLocked() {
        return mKeyguardController.isKeyguardLocked();
    }
    final void finishBooting() {
        synchronized (this) {
            if (!mBootAnimationComplete) {
@@ -7557,10 +7564,40 @@ public class ActivityManagerService extends IActivityManager.Stub
                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
                        "enterPictureInPictureMode", token, aspectRatio, checkAspectRatio,
                        true /* checkActivityVisibility */);
                final Runnable enterPipRunnable = () -> {
                    r.pictureInPictureArgs.aspectRatio = aspectRatio;
                    enterPictureInPictureModeLocked(r, displayId, r.pictureInPictureArgs,
                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
                };
                if (isKeyguardLocked()) {
                    // If the keyguard is showing or occluded, then try and dismiss it before
                    // entering picture-in-picture (this will prompt the user to authenticate if the
                    // device is currently locked).
                    try {
                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
                            @Override
                            public void onDismissError() throws RemoteException {
                                // Do nothing
                            }
                            @Override
                            public void onDismissSucceeded() throws RemoteException {
                                mHandler.post(enterPipRunnable);
                            }
                            @Override
                            public void onDismissCancelled() throws RemoteException {
                                // Do nothing
                            }
                        });
                    } catch (RemoteException e) {
                        // Local call
                    }
                } else {
                    // Enter picture in picture immediately otherwise
                    enterPipRunnable.run();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
+7 −3
Original line number Diff line number Diff line
@@ -1810,9 +1810,10 @@ final class ActivityStack extends ConfigurationContainer {
     */
    private boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
            boolean isTop) {
        final boolean isInPinnedStack = r.getStack().getStackId() == PINNED_STACK_ID;
        final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
        final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
        final boolean showWhenLocked = r.hasShowWhenLockedWindows();
        final boolean showWhenLocked = r.hasShowWhenLockedWindows() && !isInPinnedStack;
        final boolean dismissKeyguard = r.hasDismissKeyguardWindows();
        if (shouldBeVisible) {
            if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
@@ -1885,10 +1886,13 @@ final class ActivityStack extends ConfigurationContainer {
    private boolean enterPictureInPictureOnActivityInvisible(ActivityRecord r) {
        final boolean hasPinnedStack =
                mStackSupervisor.getStack(PINNED_STACK_ID) != null;
        final boolean isKeyguardLocked = mService.isKeyguardLocked();
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, " enterPictureInPictureOnInvisible="
                + r.shouldEnterPictureInPictureOnInvisible()
                + " hasPinnedStack=" + hasPinnedStack);
        if (!hasPinnedStack && r.visible && r.shouldEnterPictureInPictureOnInvisible()) {
                + " hasPinnedStack=" + hasPinnedStack
                + " isKeyguardLocked=" + isKeyguardLocked);
        if (!hasPinnedStack && !isKeyguardLocked && r.visible &&
                r.shouldEnterPictureInPictureOnInvisible()) {
            r.setEnterPipOnMoveToBackground(false);

            // Enter picture in picture, but don't move the home stack to the front