summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java50
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java49
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java77
3 files changed, 130 insertions, 46 deletions
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index a11dd3b7f213..9427c270c57f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -37,10 +37,12 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_S
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
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_STEAL_TOP_FOCUS_DISABLED;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static android.hardware.display.DisplayManagerGlobal.DisplayEvent;
import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
@@ -1800,7 +1802,11 @@ public final class DisplayManagerService extends SystemService {
}
if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
- flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+ if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) == 0) {
+ Slog.d(TAG, "Public virtual displays are auto mirror by default, hence adding "
+ + "VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR.");
+ flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+ }
// Public displays can't be allowed to show content when locked.
if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
@@ -1808,10 +1814,16 @@ public final class DisplayManagerService extends SystemService {
"Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
}
}
- if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
+ if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+ Slog.d(TAG, "Own content displays cannot auto mirror other displays, hence ignoring "
+ + "VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR.");
flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
}
- if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+ if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
+ Slog.d(TAG, "Auto mirror displays must be in the default display group, hence ignoring "
+ + "VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP.");
flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
}
// Put the display in the virtual device's display group only if it's not a mirror display,
@@ -1821,6 +1833,8 @@ public final class DisplayManagerService extends SystemService {
&& (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0
&& (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == VIRTUAL_DISPLAY_FLAG_TRUSTED
&& virtualDevice != null) {
+ Slog.d(TAG, "Own content displays owned by virtual devices are put in that device's "
+ + "display group, hence adding VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP.");
flags |= VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP;
}
@@ -1852,8 +1866,7 @@ public final class DisplayManagerService extends SystemService {
Binder.restoreCallingIdentity(firstToken);
}
- if (callingUid != Process.SYSTEM_UID
- && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+ if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
// Only a valid media projection or a virtual device can create a mirror virtual
// display.
if (!canProjectVideo(projection) && !canCreateMirrorDisplays(virtualDevice)
@@ -1901,6 +1914,14 @@ public final class DisplayManagerService extends SystemService {
}
}
+ if ((flags & VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) == 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP) == 0) {
+ Slog.d(TAG, "Always unlocked displays cannot be in the default display group, hence "
+ + "ignoring flag VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED.");
+ flags &= ~VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
+ }
+
if ((flags & VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) != 0) {
if (callingUid != Process.SYSTEM_UID
&& !checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY,
@@ -1911,7 +1932,24 @@ public final class DisplayManagerService extends SystemService {
}
}
- if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
+ if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_FOCUS) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
+ Slog.d(TAG, "Untrusted displays cannot have own focus, hence ignoring flag "
+ + "VIRTUAL_DISPLAY_FLAG_OWN_FOCUS.");
+ flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
+ }
+
+ if ((flags & VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_OWN_FOCUS) == 0) {
+ Slog.d(TAG, "Virtual displays that cannot steal top focus must have their own "
+ + " focus, hence ignoring flag VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED.");
+ flags &= ~VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED;
+ }
+
+ if ((flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
+ Slog.d(TAG, "Untrusted displays cannot show system decorations, hence ignoring flag "
+ + "VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.");
flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 558afd1da380..abbdeb9da364 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -33,13 +33,6 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPO
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_DEVICE_DISPLAY_GROUP;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED;
-import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
-
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Point;
@@ -574,15 +567,13 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
} else {
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
-
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
- mInfo.flags |= FLAG_OWN_DISPLAY_GROUP;
- }
+ }
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP) != 0) {
- mInfo.flags |= FLAG_DEVICE_DISPLAY_GROUP;
+ mInfo.flags |= DisplayDeviceInfo.FLAG_DEVICE_DISPLAY_GROUP;
}
-
if ((mFlags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
}
@@ -611,41 +602,19 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
- mInfo.flags |= FLAG_TRUSTED;
+ mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) != 0) {
- if ((mInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0
- || (mFlags & VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP) != 0) {
- mInfo.flags |= FLAG_ALWAYS_UNLOCKED;
- } else {
- Slog.w(
- TAG,
- "Ignoring VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED as it requires"
- + " VIRTUAL_DISPLAY_FLAG_DEVICE_DISPLAY_GROUP or"
- + " VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP.");
- }
+ mInfo.flags |= DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
- mInfo.flags |= FLAG_TOUCH_FEEDBACK_DISABLED;
+ mInfo.flags |= DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_FOCUS) != 0) {
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_FOCUS;
- } else {
- Slog.w(TAG, "Ignoring VIRTUAL_DISPLAY_FLAG_OWN_FOCUS as it requires "
- + "VIRTUAL_DISPLAY_FLAG_TRUSTED.");
- }
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_FOCUS;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) {
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0
- && (mFlags & VIRTUAL_DISPLAY_FLAG_OWN_FOCUS) != 0) {
- mInfo.flags |= FLAG_STEAL_TOP_FOCUS_DISABLED;
- } else {
- Slog.w(TAG,
- "Ignoring VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED as it "
- + "requires VIRTUAL_DISPLAY_FLAG_OWN_FOCUS which requires "
- + "VIRTUAL_DISPLAY_FLAG_TRUSTED.");
- }
+ mInfo.flags |= DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED;
}
mInfo.type = Display.TYPE_VIRTUAL;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index b5ea0df98204..72f08dd07658 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -759,6 +759,83 @@ public class DisplayManagerServiceTest {
}
@Test
+ public void testCreateVirtualDisplayStealTopFocusDisabled() throws RemoteException {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ // This is effectively the DisplayManager service published to ServiceManager.
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+ String uniqueId = "uniqueId --- Steal Top Focus Test";
+ int width = 600;
+ int height = 800;
+ int dpi = 320;
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED
+ | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS
+ | DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, width, height, dpi);
+ builder.setFlags(flags);
+ builder.setUniqueId(uniqueId);
+ int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken,
+ /* projection= */ null, PACKAGE_NAME);
+ verify(mMockProjectionService, never()).setContentRecordingSession(any(),
+ nullable(IMediaProjection.class));
+
+ performTraversalInternal(displayManager);
+
+ // flush the handler
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
+
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0);
+ }
+
+ @Test
+ public void testCreateVirtualDisplayOwnFocus_nonOwnFocusDisplay() throws RemoteException {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ // This is effectively the DisplayManager service published to ServiceManager.
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+ String uniqueId = "uniqueId --- Steal Top Focus Test -- nonOwnFocusDisplay";
+ int width = 600;
+ int height = 800;
+ int dpi = 320;
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED
+ | DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, width, height, dpi);
+ builder.setFlags(flags);
+ builder.setUniqueId(uniqueId);
+ int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken,
+ /* projection= */ null, PACKAGE_NAME);
+ verify(mMockProjectionService, never()).setContentRecordingSession(any(),
+ nullable(IMediaProjection.class));
+
+ performTraversalInternal(displayManager);
+
+ // flush the handler
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
+
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) == 0);
+ }
+
+ @Test
public void testCreateVirtualDisplayOwnFocus_checkDisplayDeviceInfo() throws RemoteException {
DisplayManagerService displayManager =
new DisplayManagerService(mContext, mBasicInjector);