summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Stevens <stevensd@google.com> 2017-08-23 18:41:49 -0700
committer David Stevens <stevensd@google.com> 2017-09-12 12:19:50 -0700
commit53a39eacc28b8e022499a208ff74b11e260ea204 (patch)
tree3dc226962d6066dcb471b8942d17fff3f3b808ee
parent9ac371a81e7d144a8e31f77b085867a92bfd2bd5 (diff)
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 Change-Id: Ib31fc76e9df469e97a59a181f09d457ceed4ef5f
-rw-r--r--core/java/android/app/IActivityManager.aidl10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java21
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java65
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java7
-rw-r--r--services/core/java/com/android/server/am/KeyguardController.java30
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java7
8 files changed, 108 insertions, 45 deletions
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 0ceb28841e40..c567946a830d 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -307,7 +307,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.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 8de1d317c5ed..2bc0e45c725d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -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 {
diff --git a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
index 327d218913d2..b194de43a718 100644
--- a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
@@ -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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 3eb68f5214c0..28adca97b8bf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -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 =
@@ -1694,10 +1706,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) {
}
});
@@ -2060,30 +2072,39 @@ 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;
- int size = mKeyguardStateCallbacks.size();
- for (int i = size - 1; i >= 0; i--) {
- IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
- try {
- callback.onShowingStateChanged(showing);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to call onShowingStateChanged", e);
- if (e instanceof DeadObjectException) {
- mKeyguardStateCallbacks.remove(callback);
- }
+ 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);
+ try {
+ callback.onShowingStateChanged(showing);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onShowingStateChanged", e);
+ if (e instanceof DeadObjectException) {
+ mKeyguardStateCallbacks.remove(callback);
}
}
- updateInputRestrictedLocked();
- mUiOffloadThread.submit(() -> {
- mTrustManager.reportKeyguardShowingChanged();
- });
- updateActivityLockScreenState(showing);
}
+ updateInputRestrictedLocked();
+ mUiOffloadThread.submit(() -> {
+ mTrustManager.reportKeyguardShowingChanged();
+ });
}
private void notifyTrustedChangedLocked(boolean trusted) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d51532653beb..ccf9ff14acfd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -714,7 +714,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());
}
@@ -12551,7 +12551,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 "
@@ -12561,7 +12561,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);
}
@@ -24025,7 +24025,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);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 88357bbd0029..5a8947e879a4 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1967,7 +1967,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
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 keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing(
+ mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
final boolean showWhenLocked = r.canShowWhenLocked() && !isInPinnedStack;
final boolean dismissKeyguard = r.hasDismissKeyguardWindows();
@@ -5199,8 +5200,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
voiceInteractor);
// add the task to stack first, mTaskPositioner might need the stack association
addTask(task, toTop, "createTaskRecord");
- final boolean isLockscreenShown =
- mService.mStackSupervisor.mKeyguardController.isKeyguardShowing();
+ final boolean isLockscreenShown = mService.mStackSupervisor.mKeyguardController
+ .isKeyguardShowing(mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
&& !isLockscreenShown) {
task.updateOverrideConfiguration(mBounds);
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index cea80c8d0e9d..85961135d84f 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -19,6 +19,7 @@ package com.android.server.am;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
@@ -66,6 +67,7 @@ class KeyguardController {
private int mBeforeUnoccludeTransit;
private int mVisibilityTransactionDepth;
private SleepToken mSleepToken;
+ private int mSecondaryDisplayShowing = INVALID_DISPLAY;
KeyguardController(ActivityManagerService service,
ActivityStackSupervisor stackSupervisor) {
@@ -78,10 +80,12 @@ class KeyguardController {
}
/**
- * @return true if Keyguard is showing, not going away, and not being occluded, false otherwise
+ * @return true if Keyguard is showing, not going away, and not being occluded on the given
+ * display, false otherwise
*/
- boolean isKeyguardShowing() {
- return mKeyguardShowing && !mKeyguardGoingAway && !mOccluded;
+ boolean isKeyguardShowing(int displayId) {
+ return mKeyguardShowing && !mKeyguardGoingAway &&
+ (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
}
/**
@@ -94,15 +98,19 @@ class KeyguardController {
/**
* Update the Keyguard showing state.
*/
- void setKeyguardShown(boolean showing) {
- if (showing == mKeyguardShowing) {
+ void setKeyguardShown(boolean showing, int secondaryDisplayShowing) {
+ boolean showingChanged = showing != mKeyguardShowing;
+ if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
return;
}
mKeyguardShowing = showing;
- dismissDockedStackIfNeeded();
- if (showing) {
- setKeyguardGoingAway(false);
- mDismissalRequested = false;
+ mSecondaryDisplayShowing = secondaryDisplayShowing;
+ if (showingChanged) {
+ dismissDockedStackIfNeeded();
+ if (showing) {
+ setKeyguardGoingAway(false);
+ mDismissalRequested = false;
+ }
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
updateKeyguardSleepToken();
@@ -337,9 +345,9 @@ class KeyguardController {
}
private void updateKeyguardSleepToken() {
- if (mSleepToken == null && isKeyguardShowing()) {
+ if (mSleepToken == null && isKeyguardShowing(DEFAULT_DISPLAY)) {
mSleepToken = mService.acquireSleepToken("Keyguard", DEFAULT_DISPLAY);
- } else if (mSleepToken != null && !isKeyguardShowing()) {
+ } else if (mSleepToken != null && !isKeyguardShowing(DEFAULT_DISPLAY)) {
mSleepToken.release();
mSleepToken = null;
}
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 50e5e7bd2312..5a5471b1b4f5 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,5 +1,7 @@
package com.android.server.policy.keyguard;
+import static android.view.Display.INVALID_DISPLAY;
+
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -201,7 +203,10 @@ public class KeyguardServiceDelegate {
mKeyguardState.reset();
mHandler.post(() -> {
try {
- ActivityManager.getService().setLockScreenShown(true);
+ // There are no longer any keyguard windows on secondary displays, so pass
+ // INVALID_DISPLAY. All that means is that showWhenLocked activities on
+ // secondary displays now get to show.
+ ActivityManager.getService().setLockScreenShown(true, INVALID_DISPLAY);
} catch (RemoteException e) {
// Local call.
}