From b28fb721f5be06818bedc8601e02118ddcbd4739 Mon Sep 17 00:00:00 2001
From: Charles Chen This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}
Note that this flag doesn't work without {@link #FLAG_TRUSTED}
* + * @see #getFlags() * @hide */ // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6; + /** + * Flag: The display is trusted to show system decorations and receive inputs without users' + * touch. + * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS + * + * @see #getFlags() + * @hide + */ + @TestApi + public static final int FLAG_TRUSTED = 1 << 7; + /** * 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 @@ -564,6 +577,7 @@ public final class Display { * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS * @see #FLAG_SECURE * @see #FLAG_PRIVATE + * @see #FLAG_ROUND */ public int getFlags() { return mFlags; @@ -1222,6 +1236,16 @@ public final class Display { Display.FLAG_PRESENTATION; } + /** + * @return {@code true} if the display is a trusted display. + * + * @see #FLAG_TRUSTED + * @hide + */ + public boolean isTrusted() { + return (mFlags & FLAG_TRUSTED) == FLAG_TRUSTED; + } + private void updateDisplayInfoLocked() { // Note: The display manager caches display info objects on our behalf. DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId); diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index d369883f3ac3..b1ede4102bec 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -717,6 +717,15 @@ public final class DisplayInfo implements Parcelable { if ((flags & Display.FLAG_ROUND) != 0) { result.append(", FLAG_ROUND"); } + if ((flags & Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { + result.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); + } + if ((flags & Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { + result.append(", FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS"); + } + if ((flags & Display.FLAG_TRUSTED) != 0) { + result.append(", FLAG_TRUSTED"); + } return result.toString(); } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index f71d4063b847..07d52968e43e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5026,6 +5026,10 @@Note that this flag doesn't work without {@link #FLAG_TRUSTED}
* @hide */ // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12; + /** + * Flag: The display is trusted to show system decorations and receive inputs without users' + * touch. + * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS + */ + public static final int FLAG_TRUSTED = 1 << 13; + /** * Touch attachment: Display does not receive touch. */ diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index dee6cd02917f..1058000e0b68 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -16,6 +16,7 @@ package com.android.server.display; +import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT; import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; @@ -25,6 +26,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_C 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_SHOULD_SHOW_SYSTEM_DECORATIONS; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; @@ -2189,16 +2191,25 @@ public final class DisplayManagerService extends SystemService { } } + if (callingUid == Process.SYSTEM_UID + || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { + flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; + } else { + flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; + } + // Sometimes users can have sensitive information in system decoration windows. An app // could create a virtual display with system decorations support and read the user info // from the surface. // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS - // to virtual displays that are owned by the system. - if (callingUid != Process.SYSTEM_UID - && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { - if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { + // to trusted virtual displays. + final int trustedDisplayWithSysDecorFlag = + (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS + | VIRTUAL_DISPLAY_FLAG_TRUSTED); + if ((flags & trustedDisplayWithSysDecorFlag) + == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS + && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); - } } final long token = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 2a65b33461cf..2c08420af42d 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -577,6 +577,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_hdmi_display_name); } + // The display is trusted since it is created by system. + mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED; } return mInfo; } diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 0261f388f7cb..8556f084a072 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -269,6 +269,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED; + } Rect maskingInsets = getMaskingInsets(deviceInfo); int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right; int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom; diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 8fb384070e25..69943e3904ed 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -16,6 +16,8 @@ package com.android.server.display; +import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED; + import android.annotation.Nullable; import android.content.Context; import android.database.ContentObserver; @@ -356,6 +358,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mInfo.type = Display.TYPE_OVERLAY; mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL; mInfo.state = mState; + // The display is trusted since it is created by system. + mInfo.flags |= FLAG_TRUSTED; } return mInfo; } diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index ccd88483593a..210d2979c807 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -25,6 +25,9 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTAT import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; + +import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED; import android.content.Context; import android.hardware.display.IVirtualDisplayCallback; @@ -412,6 +415,9 @@ public class VirtualDisplayAdapter extends DisplayAdapter { if ((mFlags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } + if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { + mInfo.flags |= FLAG_TRUSTED; + } mInfo.type = Display.TYPE_VIRTUAL; mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ? diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index 5584dcf69f50..57323170b327 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -651,6 +651,8 @@ final class WifiDisplayAdapter extends DisplayAdapter { mInfo.address = mAddress; mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight); + // The display is trusted since it is created by system. + mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED; } return mInfo; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4e19a5224bb4..923128e7c228 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2175,6 +2175,10 @@ class DisplayContent extends WindowContainer