diff options
11 files changed, 101 insertions, 15 deletions
diff --git a/api/current.txt b/api/current.txt index 19faf5eee979..31114842036c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -15246,6 +15246,7 @@ package android.hardware.display { field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2 field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1 field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4 + field public static final int VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 } public static abstract interface DisplayManager.DisplayListener { @@ -42575,6 +42576,7 @@ package android.view { field public static final int FLAG_PRIVATE = 4; // 0x4 field public static final int FLAG_ROUND = 16; // 0x10 field public static final int FLAG_SECURE = 2; // 0x2 + field public static final int FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 field public static final int INVALID_DISPLAY = -1; // 0xffffffff field public static final int STATE_DOZE = 3; // 0x3 diff --git a/api/system-current.txt b/api/system-current.txt index 8e7258334cf5..29179cfc8fcf 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -15823,6 +15823,7 @@ package android.hardware.display { field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2 field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1 field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4 + field public static final int VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 } public static abstract interface DisplayManager.DisplayListener { @@ -45976,6 +45977,7 @@ package android.view { field public static final int FLAG_PRIVATE = 4; // 0x4 field public static final int FLAG_ROUND = 16; // 0x10 field public static final int FLAG_SECURE = 2; // 0x2 + field public static final int FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 field public static final int INVALID_DISPLAY = -1; // 0xffffffff field public static final int STATE_DOZE = 3; // 0x3 diff --git a/api/test-current.txt b/api/test-current.txt index bd3b1255c16a..334f4e62c97f 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -15279,6 +15279,7 @@ package android.hardware.display { field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2 field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1 field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4 + field public static final int VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 } public static abstract interface DisplayManager.DisplayListener { @@ -42877,6 +42878,7 @@ package android.view { field public static final int FLAG_PRIVATE = 4; // 0x4 field public static final int FLAG_ROUND = 16; // 0x10 field public static final int FLAG_SECURE = 2; // 0x2 + field public static final int FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 32; // 0x20 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 field public static final int INVALID_DISPLAY = -1; // 0xffffffff field public static final int STATE_DOZE = 3; // 0x3 diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 12e1963a2e3e..6788b67197e3 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -108,13 +108,14 @@ public final class DisplayManager { * </p> * * <p> - * A private virtual display belongs to the application that created it. - * Only the a owner of a private virtual display is allowed to place windows upon it. - * The private virtual display also does not participate in display mirroring: it will - * neither receive mirrored content from another display nor allow its own content to - * be mirrored elsewhere. More precisely, the only processes that are allowed to - * enumerate or interact with the private display are those that have the same UID as the - * application that originally created the private virtual display. + * A private virtual display belongs to the application that created it. Only the a owner of a + * private virtual display and the apps that are already on that display are allowed to place + * windows upon it. The private virtual display also does not participate in display mirroring: + * it will neither receive mirrored content from another display nor allow its own content to be + * mirrored elsewhere. More precisely, the only processes that are allowed to enumerate or + * interact with the private display are those that have the same UID as the application that + * originally created the private virtual display or as the activities that are already on that + * display. * </p> * * @see #createVirtualDisplay @@ -234,6 +235,21 @@ public final class DisplayManager { */ public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 1 << 4; + /** + * Virtual display flag: Allows content to be displayed on private virtual displays when + * keyguard is shown but is insecure. + * + * <p> + * This flag can only be applied to private displays as defined by the + * {@link Display#FLAG_PRIVATE} display flag. It is mutually exclusive with + * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}. If both flags are specified then this flag's behavior + * will not be applied. + * </p> + * + * @see #createVirtualDisplay + */ + public static final int VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 1 << 5; + /** @hide */ public DisplayManager(Context context) { mContext = context; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index a534ca7c94bb..ebb9cf974516 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -163,7 +163,7 @@ public final class Display { /** * Display flag: Indicates that the display is private. Only the application that - * owns the display can create windows on it. + * owns the display and apps that are already on the display can create windows on it. * * @see #getFlags */ @@ -194,6 +194,19 @@ public final class Display { public static final int FLAG_ROUND = 1 << 4; /** + * Display flag: Indicates that the display can show its content when non-secure keyguard is + * shown. + * <p> + * This flag identifies secondary displays that won't show keyguard if it can be dismissed + * without entering credentials. Display content will be shown even if other displays are + * locked. + * </p> + * + * @see #getFlags + */ + public static final int FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 1 << 5; + + /** * Display flag: Indicates that the contents of the display should not be scaled * to fit the physical screen dimensions. Used for development only to emulate * devices with smaller physicals screens while preserving density. diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 163e2b64a4cb..6d5678c63b86 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -26,6 +26,8 @@ import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING; import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.Display.FLAG_SHOW_WITH_INSECURE_LOCKSCREEN; + import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP; @@ -1884,6 +1886,12 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL if (isTop) { mTopActivityOccludesKeyguard |= showWhenLocked; } + + final boolean canShowWithKeyguard = isOnShowWhenLockedInsecureDisplay() + && mStackSupervisor.mKeyguardController.canDismissKeyguard(); + if (canShowWithKeyguard) { + return true; + } } if (keyguardShowing) { @@ -1899,6 +1907,22 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL } } + /** + * Check if the display to which this stack is attached has + * {@link Display#FLAG_SHOW_WITH_INSECURE_LOCKSCREEN} applied. + */ + private boolean isOnShowWhenLockedInsecureDisplay() { + final ActivityStackSupervisor.ActivityDisplay activityDisplay + = mActivityContainer.mActivityDisplay; + if (activityDisplay == null) { + throw new IllegalStateException("Stack is not attached to any display, stackId=" + + mStackId); + } + + final int flags = activityDisplay.mDisplay.getFlags(); + return (flags & FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0; + } + private void checkTranslucentActivityWaiting(ActivityRecord top) { if (mTranslucentActivityWaiting != top) { mUndrawnActivitiesBelowTopTranslucent.clear(); diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java index b0a4746b8ff1..2bd119ec177d 100644 --- a/services/core/java/com/android/server/am/KeyguardController.java +++ b/services/core/java/com/android/server/am/KeyguardController.java @@ -280,7 +280,7 @@ class KeyguardController { /** * @return true if Keyguard can be currently dismissed without entering credentials. */ - private boolean canDismissKeyguard() { + boolean canDismissKeyguard() { return mWindowManager.isKeyguardTrusted() || !mWindowManager.isKeyguardSecure(); } diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 671918209b25..4798880a3f15 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -93,6 +93,11 @@ final class DisplayDeviceInfo { public static final int FLAG_ROUND = 1 << 8; /** + * Flag: This display can show its content when non-secure keyguard is shown. + */ + public static final int FLAG_SHOW_WITH_INSECURE_LOCKSCREEN = 1 << 9; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; @@ -420,6 +425,9 @@ final class DisplayDeviceInfo { if ((flags & FLAG_ROUND) != 0) { msg.append(", FLAG_ROUND"); } + if ((flags & FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0) { + msg.append(", FLAG_SHOW_WITH_INSECURE_LOCKSCREEN"); + } return msg.toString(); } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index cd0779324194..7d18d36aa4cc 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -16,6 +16,13 @@ package com.android.server.display; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; +import static android.hardware.display.DisplayManager + .VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN; + import com.android.internal.util.IndentingPrintWriter; import android.Manifest; @@ -1446,11 +1453,17 @@ public final class DisplayManagerService extends SystemService { throw new IllegalArgumentException("Surface can't be single-buffered"); } - if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { - flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; + if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { + flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; + + // Public displays can't be allowed to show content when locked. + if ((flags & VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0) { + throw new IllegalArgumentException( + "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE"); + } } - if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { - flags &= ~DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; + if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { + flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; } if (projection != null) { @@ -1465,7 +1478,7 @@ public final class DisplayManagerService extends SystemService { } if (callingUid != Process.SYSTEM_UID && - (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { + (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { if (!canProjectVideo(projection)) { throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " @@ -1473,7 +1486,7 @@ public final class DisplayManagerService extends SystemService { + "display."); } } - if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { + if ((flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { if (!canProjectSecureVideo(projection)) { throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " + "or an appropriate MediaProjection token to create a " diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 287a25aa9b3e..d9422ca2c6c2 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -223,6 +223,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_ROUND; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_SHOW_WITH_INSECURE_LOCKSCREEN; + } mBaseDisplayInfo.type = deviceInfo.type; mBaseDisplayInfo.address = deviceInfo.address; mBaseDisplayInfo.name = deviceInfo.name; diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 9d0fde5f2027..6a1ef85101b8 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -333,6 +333,9 @@ final class VirtualDisplayAdapter extends DisplayAdapter { } } } + if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_SHOW_WITH_INSECURE_LOCKSCREEN; + } mInfo.type = Display.TYPE_VIRTUAL; mInfo.touch = DisplayDeviceInfo.TOUCH_NONE; mInfo.state = mSurface != null ? Display.STATE_ON : Display.STATE_OFF; |