Allow VDM virtual displays to get FLAG_OWN_DISPLAY_GROUP
For virtual displays that are created through VDM, allow FLAG_OWN_DISPLAY_GROUP to be added. This applies to every display created through VDM, because VDM adds this flag on behalf of the caller by default. Bug: 194949534 Test: atest DisplayManagerServiceTest.java Change-Id: I1826dbd0cb7f4c4a76abbf25741b9862c5ff7355
This commit is contained in:
@@ -196,9 +196,7 @@ public final class VirtualDeviceManager {
|
||||
|
||||
/**
|
||||
* Creates a virtual display for this virtual device. All displays created on the same
|
||||
* device belongs to the same display group. Requires the ADD_TRUSTED_DISPLAY permission
|
||||
* to create a virtual display which is not in the default DisplayGroup, and to create
|
||||
* trusted displays.
|
||||
* device belongs to the same display group.
|
||||
*
|
||||
* @param width The width of the virtual display in pixels, must be greater than 0.
|
||||
* @param height The height of the virtual display in pixels, must be greater than 0.
|
||||
|
||||
@@ -1318,7 +1318,9 @@ public final class DisplayManagerService extends SystemService {
|
||||
|
||||
if (callingUid != Process.SYSTEM_UID
|
||||
&& (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
|
||||
if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
|
||||
// The virtualDevice instance has been validated above using isValidVirtualDevice
|
||||
if (virtualDevice == null
|
||||
&& !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
|
||||
throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
|
||||
+ "create a virtual display which is not in the default DisplayGroup.");
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PropertyInvalidatedCache;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.compat.testing.PlatformCompatChangeRule;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
@@ -73,6 +74,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||
import com.android.server.display.DisplayManagerService.SyncRoot;
|
||||
import com.android.server.lights.LightsManager;
|
||||
import com.android.server.sensors.SensorManagerInternal;
|
||||
@@ -167,6 +169,7 @@ public class DisplayManagerServiceTest {
|
||||
};
|
||||
|
||||
@Mock InputManagerInternal mMockInputManagerInternal;
|
||||
@Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal;
|
||||
@Mock IVirtualDisplayCallback.Stub mMockAppToken;
|
||||
@Mock IVirtualDisplayCallback.Stub mMockAppToken2;
|
||||
@Mock WindowManagerInternal mMockWindowManagerInternal;
|
||||
@@ -187,6 +190,9 @@ public class DisplayManagerServiceTest {
|
||||
LocalServices.addService(LightsManager.class, mMockLightsManager);
|
||||
LocalServices.removeServiceForTest(SensorManagerInternal.class);
|
||||
LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal);
|
||||
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||
LocalServices.addService(
|
||||
VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal);
|
||||
|
||||
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
||||
mDeviceConfig = new FakeDeviceConfigInterface();
|
||||
@@ -660,6 +666,101 @@ public class DisplayManagerServiceTest {
|
||||
/*deviceConfigAllows*/ false, /*flagExpected*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission
|
||||
* ADD_TRUSTED_DISPLAY is granted.
|
||||
*/
|
||||
@Test
|
||||
public void testOwnDisplayGroup_allowCreationWithAddTrustedDisplayPermission() {
|
||||
DisplayManagerService displayManager =
|
||||
new DisplayManagerService(mContext, mBasicInjector);
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
DisplayManagerService.BinderService bs = displayManager.new BinderService();
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
|
||||
when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
|
||||
PackageManager.PERMISSION_GRANTED);
|
||||
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
|
||||
builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
|
||||
builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
|
||||
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
|
||||
assertNotNull(ddi);
|
||||
assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is blocked when the permission
|
||||
* ADD_TRUSTED_DISPLAY is denied.
|
||||
*/
|
||||
@Test
|
||||
public void testOwnDisplayGroup_withoutAddTrustedDisplayPermission_throwsSecurityException() {
|
||||
DisplayManagerService displayManager =
|
||||
new DisplayManagerService(mContext, mBasicInjector);
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
DisplayManagerService.BinderService bs = displayManager.new BinderService();
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
|
||||
when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
|
||||
PackageManager.PERMISSION_DENIED);
|
||||
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
|
||||
builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
|
||||
builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
|
||||
|
||||
try {
|
||||
bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without "
|
||||
+ "ADD_TRUSTED_DISPLAY permission should throw SecurityException.");
|
||||
} catch (SecurityException e) {
|
||||
// SecurityException is expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when called with
|
||||
* a virtual device, even if ADD_TRUSTED_DISPLAY is not granted.
|
||||
*/
|
||||
@Test
|
||||
public void testOwnDisplayGroup_allowCreationWithVirtualDevice() {
|
||||
DisplayManagerService displayManager =
|
||||
new DisplayManagerService(mContext, mBasicInjector);
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
DisplayManagerService.BinderService bs = displayManager.new BinderService();
|
||||
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
|
||||
|
||||
when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
|
||||
PackageManager.PERMISSION_DENIED);
|
||||
|
||||
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
|
||||
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
|
||||
builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
|
||||
builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
|
||||
|
||||
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
|
||||
when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
|
||||
.thenReturn(true);
|
||||
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, virtualDevice /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
|
||||
assertNotNull(ddi);
|
||||
assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that there is a display change notification if the frame rate override
|
||||
* list is updated.
|
||||
|
||||
Reference in New Issue
Block a user