Support show KeyguardPresentation on all public displays.
Support show keyguard presentation on all public displays when Keyguard
is show.
Modify API ActivityTaskManager#setLockScreenShown, extends to multi-displayIds.
bug: 111955725
Test: Manual test with chromecast.
Test: atest SystemUITests
Test: atest ActivityManagerMultiDisplayTests
Test: atest ActivityManagerDisplayKeyguardTests
Change-Id: I9967e1b1adcb796593332b46853a10101e206013
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 519a274..e759762 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -265,17 +265,6 @@
void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
boolean killProcessesBelowForeground(in String reason);
UserInfo getCurrentUser();
- /**
- * Informs ActivityManagerService that the keyguard is showing.
- *
- * @param showingKeyguard True if the keyguard is showing, false otherwise.
- * @param showingAod True if AOD 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 showingKeyguard, boolean showingAod,
- int secondaryDisplayShowing);
// 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.
int getLaunchedFromUid(in IBinder activityToken);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index fcfcc21..6f11a76 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -245,16 +245,16 @@
ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType);
/**
- * Informs ActivityManagerService that the keyguard is showing.
+ * Informs ActivityTaskManagerService that the keyguard is showing.
*
* @param showingKeyguard True if the keyguard is showing, false otherwise.
* @param showingAod True if AOD 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.
+ * @param secondaryDisplaysShowing The displayId's of the secondary displays on which the
+ * keyguard is showing, or {@code null} if there is no such display. Only meaningful if showing
+ * is {@code true}.
*/
void setLockScreenShown(boolean showingKeyguard, boolean showingAod,
- int secondaryDisplayShowing);
+ in int[] secondaryDisplaysShowing);
Bundle getAssistContextExtras(int requestType);
boolean launchAssistIntent(in Intent intent, int requestType, in String hint, int userHandle,
in Bundle args);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 2bc0e45c..e051317 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -15,54 +15,164 @@
*/
package com.android.keyguard;
-import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Display.DEFAULT_DISPLAY;
+import android.annotation.Nullable;
import android.app.Presentation;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
import android.graphics.Point;
+import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
import android.os.Bundle;
-import android.util.Slog;
+import android.util.Log;
+import android.util.SparseArray;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
+import java.util.function.BooleanSupplier;
+
// 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 DisplayManager mDisplayService;
private final Context mContext;
- Presentation mPresentation;
private boolean mShowing;
+ private final SparseArray<Presentation> mPresentations = new SparseArray<>();
+
+ private final DisplayManager.DisplayListener mDisplayListener =
+ new DisplayManager.DisplayListener() {
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ final Display display = mDisplayService.getDisplay(displayId);
+ if (mShowing) {
+ notifyIfChanged(() -> showPresentation(display));
+ }
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId == DEFAULT_DISPLAY) return;
+ final Display display = mDisplayService.getDisplay(displayId);
+ if (display != null && mShowing) {
+ final Presentation presentation = mPresentations.get(displayId);
+ if (presentation != null && !presentation.getDisplay().equals(display)) {
+ hidePresentation(displayId);
+ showPresentation(display);
+ }
+ }
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ notifyIfChanged(() -> hidePresentation(displayId));
+ }
+ };
+
public KeyguardDisplayManager(Context context, ViewMediatorCallback callback) {
mContext = context;
mCallback = callback;
- mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mMediaRouter = mContext.getSystemService(MediaRouter.class);
+ mDisplayService = mContext.getSystemService(DisplayManager.class);
+ mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
+ }
+
+ /**
+ * @param display The display to show the presentation on.
+ * @return {@code true} if a presentation was added.
+ * {@code false} if the presentation cannot be added on that display or the presentation
+ * was already there.
+ */
+ private boolean showPresentation(Display display) {
+ if (display == null || display.getDisplayId() == DEFAULT_DISPLAY) return false;
+ if (DEBUG) Log.i(TAG, "Keyguard enabled on display: " + display);
+ final int displayId = display.getDisplayId();
+ Presentation presentation = mPresentations.get(displayId);
+ if (presentation == null) {
+ presentation = new KeyguardPresentation(mContext, display);
+ presentation.setOnDismissListener(dialog -> {
+ if (null != mPresentations.get(displayId)) {
+ mPresentations.remove(displayId);
+ }
+ });
+ try {
+ presentation.show();
+ } catch (WindowManager.InvalidDisplayException ex) {
+ Log.w(TAG, "Invalid display:", ex);
+ presentation = null;
+ }
+ if (presentation != null) {
+ mPresentations.append(displayId, presentation);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param displayId The id of the display to hide the presentation off.
+ * @return {@code true} if the a presentation was removed.
+ * {@code false} if the presentation was not added before.
+ */
+ private boolean hidePresentation(int displayId) {
+ final Presentation presentation = mPresentations.get(displayId);
+ if (presentation != null) {
+ presentation.dismiss();
+ mPresentations.remove(displayId);
+ return true;
+ }
+ return false;
+ }
+
+ private void notifyIfChanged(BooleanSupplier updateMethod) {
+ if (updateMethod.getAsBoolean()) {
+ final int[] displayList = getPresentationDisplayIds();
+ mCallback.onSecondaryDisplayShowingChanged(displayList);
+ }
+ }
+
+ /**
+ * @return An array of displayId's on which a {@link KeyguardPresentation} is showing on.
+ */
+ @Nullable
+ private int[] getPresentationDisplayIds() {
+ final int size = mPresentations.size();
+ if (size == 0) return null;
+
+ final int[] displayIds = new int[size];
+ for (int i = mPresentations.size() - 1; i >= 0; i--) {
+ final Presentation presentation = mPresentations.valueAt(i);
+ if (presentation != null) {
+ displayIds[i] = presentation.getDisplay().getDisplayId();
+ }
+ }
+ return displayIds;
}
public void show() {
if (!mShowing) {
- if (DEBUG) Slog.v(TAG, "show");
+ if (DEBUG) Log.v(TAG, "show");
mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
- updateDisplays(true);
+ notifyIfChanged(() -> updateDisplays(true /* showing */));
}
mShowing = true;
}
public void hide() {
if (mShowing) {
- if (DEBUG) Slog.v(TAG, "hide");
+ if (DEBUG) Log.v(TAG, "hide");
mMediaRouter.removeCallback(mMediaRouterCallback);
- updateDisplays(false);
+ notifyIfChanged(() -> updateDisplays(false /* showing */));
}
mShowing = false;
}
@@ -71,71 +181,38 @@
new MediaRouter.SimpleCallback() {
@Override
public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
- updateDisplays(mShowing);
+ if (DEBUG) Log.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
@Override
public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
- updateDisplays(mShowing);
+ if (DEBUG) Log.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
@Override
public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
- updateDisplays(mShowing);
+ if (DEBUG) Log.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
};
- private OnDismissListener mOnDismissListener = new OnDismissListener() {
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- mPresentation = null;
- }
- };
-
- protected void updateDisplays(boolean showing) {
- Presentation originalPresentation = mPresentation;
+ protected boolean updateDisplays(boolean showing) {
+ boolean changed = false;
if (showing) {
- MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
- MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
- boolean useDisplay = route != null
- && route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
- Display presentationDisplay = useDisplay ? route.getPresentationDisplay() : null;
-
- if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
- if (DEBUG) Slog.v(TAG, "Display gone: " + mPresentation.getDisplay());
- mPresentation.dismiss();
- mPresentation = null;
- }
-
- if (mPresentation == null && presentationDisplay != null) {
- if (DEBUG) Slog.i(TAG, "Keyguard enabled on display: " + presentationDisplay);
- mPresentation = new KeyguardPresentation(mContext, presentationDisplay,
- R.style.keyguard_presentation_theme);
- mPresentation.setOnDismissListener(mOnDismissListener);
- try {
- mPresentation.show();
- } catch (WindowManager.InvalidDisplayException ex) {
- Slog.w(TAG, "Invalid display:", ex);
- mPresentation = null;
- }
+ final Display[] displays = mDisplayService.getDisplays();
+ for (Display display : displays) {
+ changed |= showPresentation(display);
}
} else {
- if (mPresentation != null) {
- mPresentation.dismiss();
- mPresentation = null;
+ changed = mPresentations.size() > 0;
+ for (int i = mPresentations.size() - 1; i >= 0; i--) {
+ mPresentations.valueAt(i).dismiss();
}
+ mPresentations.clear();
}
-
- // mPresentation is only updated when the display changes
- if (mPresentation != originalPresentation) {
- final int displayId = mPresentation != null
- ? mPresentation.getDisplay().getDisplayId() : INVALID_DISPLAY;
- mCallback.onSecondaryDisplayShowingChanged(displayId);
- }
+ return changed;
}
private final static class KeyguardPresentation extends Presentation {
@@ -157,9 +234,10 @@
}
};
- public KeyguardPresentation(Context context, Display display, int theme) {
- super(context, display, theme);
+ KeyguardPresentation(Context context, Display display) {
+ super(context, display, R.style.keyguard_presentation_theme);
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ setCancelable(false);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 50b98a1..79966f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -17,6 +17,8 @@
package com.android.keyguard;
import static android.app.slice.Slice.HINT_LIST_ITEM;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
@@ -80,6 +82,7 @@
private float mDarkAmount = 0;
private LiveData<Slice> mLiveData;
+ private int mDisplayId = INVALID_DISPLAY;
private int mIconSize;
/**
* Runnable called whenever the view contents change.
@@ -129,6 +132,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mDisplayId = getDisplay().getDisplayId();
// Make sure we always have the most current slice
mLiveData.observeForever(this);
Dependency.get(ConfigurationController.class).addCallback(this);
@@ -138,7 +142,10 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mLiveData.removeObserver(this);
+ // TODO(b/117344873) Remove below work around after this issue be fixed.
+ if (mDisplayId == DEFAULT_DISPLAY) {
+ mLiveData.removeObserver(this);
+ }
Dependency.get(ConfigurationController.class).removeCallback(this);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
index 41b86a7..a07c5cb 100644
--- a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
@@ -96,9 +96,9 @@
int getBouncerPromptReason();
/**
- * Invoked when the secondary display showing a keyguard window changes.
+ * Invoked when the secondary displays showing a keyguard window changes.
*/
- void onSecondaryDisplayShowingChanged(int displayId);
+ void onSecondaryDisplayShowingChanged(int[] displayId);
/**
* Consumes a message that was enqueued to be displayed on the next time the bouncer shows up.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4988f07..fe1b356 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -17,7 +17,6 @@
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.telephony.IccCardConstants.State.PIN_REQUIRED;
@@ -95,6 +94,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Mediates requests related to the keyguard. This includes queries about the
@@ -246,8 +246,8 @@
// AOD is enabled and status bar is in AOD state.
private boolean mAodShowing;
- // display id of the secondary display on which we have put a keyguard window
- private int mSecondaryDisplayShowing = INVALID_DISPLAY;
+ // display ids of the external display on which we have put a keyguard window
+ private int[] mSecondaryDisplaysShowing;
/** Cached value of #isInputRestricted */
private boolean mInputRestricted;
@@ -700,9 +700,9 @@
}
@Override
- public void onSecondaryDisplayShowingChanged(int displayId) {
+ public void onSecondaryDisplayShowingChanged(int[] displayIds) {
synchronized (KeyguardViewMediator.this) {
- setShowingLocked(mShowing, mAodShowing, displayId, false);
+ setShowingLocked(mShowing, mAodShowing, displayIds, false);
}
}
};
@@ -749,10 +749,10 @@
setShowingLocked(!shouldWaitForProvisioning()
&& !mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser()),
- mAodShowing, mSecondaryDisplayShowing, true /* forceCallbacks */);
+ mAodShowing, mSecondaryDisplaysShowing, true /* forceCallbacks */);
} else {
// The system's keyguard is disabled or missing.
- setShowingLocked(false, mAodShowing, mSecondaryDisplayShowing, true);
+ setShowingLocked(false, mAodShowing, mSecondaryDisplaysShowing, true);
}
mStatusBarKeyguardViewManager =
@@ -1776,11 +1776,11 @@
}
private void updateActivityLockScreenState(boolean showing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
mUiOffloadThread.submit(() -> {
try {
ActivityTaskManager.getService().setLockScreenShown(showing, aodShowing,
- secondaryDisplayShowing);
+ secondaryDisplaysShowing);
} catch (RemoteException e) {
}
});
@@ -1895,7 +1895,8 @@
if (!mHiding) {
// Tell ActivityManager that we canceled the keyguardExitAnimation.
- setShowingLocked(mShowing, mAodShowing, mSecondaryDisplayShowing, true /* force */);
+ setShowingLocked(mShowing, mAodShowing, mSecondaryDisplaysShowing,
+ true /* force */);
return;
}
mHiding = false;
@@ -2164,22 +2165,23 @@
}
private void setShowingLocked(boolean showing, boolean aodShowing) {
- setShowingLocked(showing, aodShowing, mSecondaryDisplayShowing,
+ setShowingLocked(showing, aodShowing, mSecondaryDisplaysShowing,
false /* forceCallbacks */);
}
- private void setShowingLocked(boolean showing, boolean aodShowing, int secondaryDisplayShowing,
- boolean forceCallbacks) {
+ private void setShowingLocked(boolean showing, boolean aodShowing,
+ int[] secondaryDisplaysShowing, boolean forceCallbacks) {
final boolean notifyDefaultDisplayCallbacks = showing != mShowing
|| aodShowing != mAodShowing || forceCallbacks;
- if (notifyDefaultDisplayCallbacks || secondaryDisplayShowing != mSecondaryDisplayShowing) {
+ if (notifyDefaultDisplayCallbacks
+ || !Arrays.equals(secondaryDisplaysShowing, mSecondaryDisplaysShowing)) {
mShowing = showing;
mAodShowing = aodShowing;
- mSecondaryDisplayShowing = secondaryDisplayShowing;
+ mSecondaryDisplaysShowing = secondaryDisplaysShowing;
if (notifyDefaultDisplayCallbacks) {
notifyDefaultDisplayCallbacks(showing);
}
- updateActivityLockScreenState(showing, aodShowing, secondaryDisplayShowing);
+ updateActivityLockScreenState(showing, aodShowing, secondaryDisplaysShowing);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d631fa8..45f41e0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -127,6 +127,11 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
+import static com.android.server.am.MemoryStatUtil.hasMemcg;
+import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
@@ -144,11 +149,6 @@
import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.ActivityTaskManagerService.relaunchReasonToString;
-import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
-import static com.android.server.am.MemoryStatUtil.hasMemcg;
-import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import android.Manifest;
import android.Manifest.permission;
@@ -7320,13 +7320,6 @@
}
@Override
- public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
- mActivityTaskManager.setLockScreenShown(
- keyguardShowing, aodShowing, secondaryDisplayShowing);
- }
-
- @Override
public void notifyLockedProfile(@UserIdInt int userId) {
mAtmInternal.notifyLockedProfile(userId, mUserController.getCurrentUserId());
}
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 1e0b52a..ae1090c 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,13 +1,11 @@
package com.android.server.policy.keyguard;
-import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.wm.KeyguardServiceDelegateProto.INTERACTIVE_STATE;
import static com.android.server.wm.KeyguardServiceDelegateProto.OCCLUDED;
import static com.android.server.wm.KeyguardServiceDelegateProto.SCREEN_STATE;
import static com.android.server.wm.KeyguardServiceDelegateProto.SECURE;
import static com.android.server.wm.KeyguardServiceDelegateProto.SHOWING;
-import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
@@ -212,10 +210,10 @@
mHandler.post(() -> {
try {
// 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.
+ // {@code null}. All that means is that showWhenLocked activities on
+ // external displays now get to show.
ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */,
- false /* aodShowing */, INVALID_DISPLAY);
+ false /* aodShowing */, null /* secondaryDisplaysShowing */);
} catch (RemoteException e) {
// Local call.
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3ede8bc8..3359eac8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -114,17 +114,17 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
-import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
-import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
-import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
+import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
+import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
+import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
+import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import android.Manifest;
import android.annotation.NonNull;
@@ -2885,7 +2885,7 @@
@Override
public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
@@ -2903,7 +2903,7 @@
}
try {
mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
- secondaryDisplayShowing);
+ secondaryDisplaysShowing);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 3560635..c91af73 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -18,7 +18,6 @@
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.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
@@ -30,13 +29,13 @@
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING;
import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID;
import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.os.IBinder;
import android.os.RemoteException;
@@ -50,6 +49,7 @@
import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
import java.io.PrintWriter;
+import java.util.Arrays;
/**
* Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
@@ -67,10 +67,9 @@
private boolean mAodShowing;
private boolean mKeyguardGoingAway;
private boolean mDismissalRequested;
+ private int[] mSecondaryDisplayIdsShowing;
private int mBeforeUnoccludeTransit;
private int mVisibilityTransactionDepth;
- // TODO(b/111955725): Support multiple external displays
- private int mSecondaryDisplayShowing = INVALID_DISPLAY;
private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
private final ActivityTaskManagerService mService;
@@ -90,7 +89,9 @@
*/
boolean isKeyguardOrAodShowing(int displayId) {
return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
- && !isDisplayOccluded(displayId);
+ && (displayId == DEFAULT_DISPLAY
+ ? !isDisplayOccluded(DEFAULT_DISPLAY)
+ : isShowingOnSecondaryDisplay(displayId));
}
/**
@@ -98,7 +99,10 @@
* display, false otherwise
*/
boolean isKeyguardShowing(int displayId) {
- return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
+ return mKeyguardShowing && !mKeyguardGoingAway
+ && (displayId == DEFAULT_DISPLAY
+ ? !isDisplayOccluded(DEFAULT_DISPLAY)
+ : isShowingOnSecondaryDisplay(displayId));
}
/**
@@ -120,16 +124,17 @@
* Update the Keyguard showing state.
*/
void setKeyguardShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
boolean showingChanged = keyguardShowing != mKeyguardShowing || aodShowing != mAodShowing;
// If keyguard is going away, but SystemUI aborted the transition, need to reset state.
showingChanged |= mKeyguardGoingAway && keyguardShowing;
- if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
+ if (!showingChanged && Arrays.equals(secondaryDisplaysShowing,
+ mSecondaryDisplayIdsShowing)) {
return;
}
mKeyguardShowing = keyguardShowing;
mAodShowing = aodShowing;
- mSecondaryDisplayShowing = secondaryDisplayShowing;
+ mSecondaryDisplayIdsShowing = secondaryDisplaysShowing;
mWindowManager.setAodShowing(aodShowing);
if (showingChanged) {
dismissDockedStackIfNeeded();
@@ -145,6 +150,14 @@
updateKeyguardSleepToken();
}
+ private boolean isShowingOnSecondaryDisplay(int displayId) {
+ if (mSecondaryDisplayIdsShowing == null) return false;
+ for (int showingId : mSecondaryDisplayIdsShowing) {
+ if (displayId == showingId) return true;
+ }
+ return false;
+ }
+
/**
* Called when Keyguard is going away.
*
@@ -386,16 +399,18 @@
}
private KeyguardDisplayState getDisplay(int displayId) {
- if (mDisplayStates.get(displayId) == null) {
- mDisplayStates.append(displayId,
- new KeyguardDisplayState(mService, displayId));
+ KeyguardDisplayState state = mDisplayStates.get(displayId);
+ if (state == null) {
+ state = new KeyguardDisplayState(mService, displayId);
+ mDisplayStates.append(displayId, state);
}
- return mDisplayStates.get(displayId);
+ return state;
}
void onDisplayRemoved(int displayId) {
- if (mDisplayStates.get(displayId) != null) {
- mDisplayStates.get(displayId).onRemoved();
+ final KeyguardDisplayState state = mDisplayStates.get(displayId);
+ if (state != null) {
+ state.onRemoved();
mDisplayStates.remove(displayId);
}
}
@@ -456,7 +471,8 @@
mOccluded |= controller.mWindowManager.isShowingDream();
}
- // TODO(b/113840485): Handle app transition for individual display.
+ // TODO(b/113840485): Handle app transition for individual display, and apply occluded
+ // state change to secondary displays.
// For now, only default display can change occluded.
if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
controller.handleOccludedChanged();