summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/hardware/display/DisplayManager.java30
-rw-r--r--core/java/android/view/Display.java15
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java24
-rw-r--r--services/core/java/com/android/server/am/KeyguardController.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceInfo.java8
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java25
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java3
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java3
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;