Merge "Trust System UI owned display to receive keys" into rvc-dev

This commit is contained in:
Charles Chen
2020-06-16 13:56:55 +00:00
committed by Android (Google) Code Review
19 changed files with 109 additions and 29 deletions

View File

@@ -5103,6 +5103,7 @@ package android.view {
method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
method public int getType();
method public boolean hasAccess(int);
field public static final int FLAG_TRUSTED = 128; // 0x80
field public static final int TYPE_EXTERNAL = 2; // 0x2
field public static final int TYPE_INTERNAL = 1; // 0x1
field public static final int TYPE_OVERLAY = 4; // 0x4

View File

@@ -303,13 +303,25 @@ public final class DisplayManager {
/**
* Virtual display flag: Indicates that the display should support system decorations. Virtual
* displays without this flag shouldn't show home, IME or any other system decorations.
* <p>This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}</p>
*
* @see #createVirtualDisplay
* @see #VIRTUAL_DISPLAY_FLAG_TRUSTED
* @hide
*/
// TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
/**
* Virtual display flags: Indicates that the display is trusted to show system decorations and
* receive inputs without users' touch.
*
* @see #createVirtualDisplay
* @see #VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
* @hide
*/
public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
/** @hide */
public DisplayManager(Context context) {
mContext = context;

View File

@@ -241,12 +241,25 @@ public final class Display {
* This flag identifies secondary displays that should show system decorations, such as status
* bar, navigation bar, home activity or IME.
* </p>
* <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
*
* @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);

View File

@@ -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();
}
}

View File

@@ -5028,6 +5028,10 @@
<permission android:name="android.permission.ACCESS_TV_DESCRAMBLER"
android:protectionLevel="signature|privileged|vendorPrivileged" />
<!-- Allows an application to create trusted displays. @hide -->
<permission android:name="android.permission.ADD_TRUSTED_DISPLAY"
android:protectionLevel="signature" />
<!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
<permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
android:protectionLevel="signature|appPredictor" />

View File

@@ -263,6 +263,9 @@
<!-- Restore settings (used by QS) even if they have been modified -->
<uses-permission android:name="android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE" />
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />

View File

@@ -116,11 +116,19 @@ final class DisplayDeviceInfo {
/**
* Flag: This flag identifies secondary displays that should show system decorations, such as
* status bar, navigation bar, home activity or IME.
* <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
* @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.
*/

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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) ?

View File

@@ -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;
}

View File

@@ -2175,6 +2175,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
}
boolean isTrusted() {
return mDisplay.isTrusted();
}
/**
* Returns the topmost stack on the display that is compatible with the input windowing mode and
* activity type. Null is no compatible stack on the display.
@@ -3522,7 +3526,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
boolean canShowIme() {
if (isUntrustedVirtualDisplay()) {
if (!isTrusted()) {
return false;
}
return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
@@ -4753,15 +4757,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// VR virtual display will be used to run and render 2D app within a VR experience.
&& mDisplayId != mWmService.mVr2dDisplayId
// Do not show system decorations on untrusted virtual display.
&& !isUntrustedVirtualDisplay();
}
/**
* @return {@code true} if the display is non-system created virtual display.
*/
boolean isUntrustedVirtualDisplay() {
return mDisplay.getType() == Display.TYPE_VIRTUAL
&& mDisplay.getOwnerUid() != Process.SYSTEM_UID;
&& isTrusted();
}
/**

View File

@@ -353,7 +353,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
}
// We don't allow untrusted display to top when task stack moves to top,
// until user tapping this display to change display position as top intentionally.
if (mDisplayContent.isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
if (!mDisplayContent.isTrusted() && !getParent().isOnTop()) {
includingParents = false;
}
final int targetPosition = findPositionForStack(position, child, false /* adding */);
@@ -1529,8 +1529,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
@Nullable
ActivityStack getOrCreateRootHomeTask(boolean onTop) {
ActivityStack homeTask = getRootHomeTask();
if (homeTask == null && mDisplayContent.supportsSystemDecorations()
&& !mDisplayContent.isUntrustedVirtualDisplay()) {
if (homeTask == null && mDisplayContent.supportsSystemDecorations()) {
homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);
}
return homeTask;

View File

@@ -7150,9 +7150,6 @@ public class WindowManagerService extends IWindowManager.Stub
+ "not exist: %d", displayId);
return false;
}
if (displayContent.isUntrustedVirtualDisplay()) {
return false;
}
return displayContent.supportsSystemDecorations();
}
}
@@ -7171,7 +7168,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ "does not exist: %d", displayId);
return;
}
if (displayContent.isUntrustedVirtualDisplay()) {
if (!displayContent.isTrusted()) {
throw new SecurityException("Attempted to set system decors flag to an "
+ "untrusted virtual display: " + displayId);
}
@@ -7219,7 +7216,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ "exist: %d", displayId);
return;
}
if (displayContent.isUntrustedVirtualDisplay()) {
if (!displayContent.isTrusted()) {
throw new SecurityException("Attempted to set IME flag to an untrusted "
+ "virtual display: " + displayId);
}

View File

@@ -2830,7 +2830,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Do not allow untrusted virtual display to receive keys unless user intentionally
// touches the display.
return fromUserTouch || getDisplayContent().isOnTop()
|| !getDisplayContent().isUntrustedVirtualDisplay();
|| getDisplayContent().isTrusted();
}
@Override

View File

@@ -1287,7 +1287,6 @@ public class DisplayContentTests extends WindowTestsBase {
public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
DisplayContent display = createNewDisplay();
doReturn(true).when(display).supportsSystemDecorations();
doReturn(false).when(display).isUntrustedVirtualDisplay();
// Remove the current home stack if it exists so a new one can be created below.
TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
@@ -1311,10 +1310,10 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
public void testGetOrCreateRootHomeTask_untrustedVirtualDisplay() {
public void testGetOrCreateRootHomeTask_untrustedDisplay() {
DisplayContent display = createNewDisplay();
TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
doReturn(true).when(display).isUntrustedVirtualDisplay();
doReturn(false).when(display).isTrusted();
assertNull(taskDisplayArea.getRootHomeTask());
assertNull(taskDisplayArea.getOrCreateRootHomeTask());

View File

@@ -150,9 +150,9 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
@Test
public void testDisplayPositionWithPinnedStack() {
// Make sure the display is system owned display which capable to move the stack to top.
// Make sure the display is trusted display which capable to move the stack to top.
spyOn(mDisplayContent);
doReturn(false).when(mDisplayContent).isUntrustedVirtualDisplay();
doReturn(true).when(mDisplayContent).isTrusted();
// The display contains pinned stack that was added in {@link #setUp}.
final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);