diff options
| author | 2023-08-01 08:24:17 +0000 | |
|---|---|---|
| committer | 2023-08-02 07:56:52 +0000 | |
| commit | b102d8e75d85e41e1ee5f9293c503a3f6cb61ed5 (patch) | |
| tree | 69bc7037de3424e90f281b25a861faa0eb85ce84 | |
| parent | 099b03abc96a5778f375ec377eeb1a1b85f2551e (diff) | |
Do not allow to register VirtualDevice with same appToken
For more details see b/289376167 comment 25
Bug: b/289376167
Test: atest VirtualDisplayAdapterTest
Change-Id: I5a7ca6a58d71d975093f0c92cce6d033956ce5c8
3 files changed, 120 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 4f7a2ba58570..619186157cce 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -80,8 +80,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { @VisibleForTesting static final String UNIQUE_ID_PREFIX = "virtual:"; - private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices = - new ArrayMap<IBinder, VirtualDisplayDevice>(); + private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices = new ArrayMap<>(); private final Handler mHandler; private final SurfaceControlDisplayFactory mSurfaceControlDisplayFactory; @@ -113,9 +112,16 @@ public class VirtualDisplayAdapter extends DisplayAdapter { public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback, IMediaProjection projection, int ownerUid, String ownerPackageName, Surface surface, int flags, VirtualDisplayConfig virtualDisplayConfig) { + IBinder appToken = callback.asBinder(); + if (mVirtualDisplayDevices.containsKey(appToken)) { + Slog.wtfStack(TAG, + "Can't create virtual display, display with same appToken already exists"); + return null; + } + String name = virtualDisplayConfig.getName(); boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0; - IBinder appToken = callback.asBinder(); + IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure, virtualDisplayConfig.getRequestedRefreshRate()); final String baseUniqueId = 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 d16c9c59bb1b..bf2311761891 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -248,6 +248,8 @@ public class DisplayManagerServiceTest { @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock IVirtualDisplayCallback.Stub mMockAppToken2; + + @Mock IVirtualDisplayCallback.Stub mMockAppToken3; @Mock WindowManagerInternal mMockWindowManagerInternal; @Mock LightsManager mMockLightsManager; @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; @@ -838,6 +840,7 @@ public class DisplayManagerServiceTest { registerDefaultDisplays(displayManager); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); + when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); @@ -851,7 +854,7 @@ public class DisplayManagerServiceTest { int displayId1 = localService.createVirtualDisplay( builder1.build(), - mMockAppToken /* callback */, + mMockAppToken2 /* callback */, virtualDevice /* virtualDeviceToken */, mock(DisplayWindowPolicyController.class), PACKAGE_NAME); @@ -893,6 +896,7 @@ public class DisplayManagerServiceTest { registerDefaultDisplays(displayManager); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); + when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); @@ -927,7 +931,7 @@ public class DisplayManagerServiceTest { int displayId2 = localService.createVirtualDisplay( builder2.build(), - mMockAppToken /* callback */, + mMockAppToken2 /* callback */, virtualDevice /* virtualDeviceToken */, mock(DisplayWindowPolicyController.class), PACKAGE_NAME); @@ -950,6 +954,8 @@ public class DisplayManagerServiceTest { registerDefaultDisplays(displayManager); when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); + when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2); + when(mMockAppToken3.asBinder()).thenReturn(mMockAppToken3); IVirtualDevice virtualDevice = mock(IVirtualDevice.class); when(virtualDevice.getDeviceId()).thenReturn(1); @@ -999,7 +1005,7 @@ public class DisplayManagerServiceTest { int ownDisplayGroupDisplayId = localService.createVirtualDisplay( ownDisplayGroupConfig, - mMockAppToken /* callback */, + mMockAppToken2 /* callback */, virtualDevice /* virtualDeviceToken */, mock(DisplayWindowPolicyController.class), PACKAGE_NAME); @@ -1024,7 +1030,7 @@ public class DisplayManagerServiceTest { int defaultDisplayGroupDisplayId = localService.createVirtualDisplay( defaultDisplayGroupConfig, - mMockAppToken /* callback */, + mMockAppToken3 /* callback */, null /* virtualDeviceToken */, mock(DisplayWindowPolicyController.class), PACKAGE_NAME); diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java new file mode 100644 index 000000000000..8bbacc494efd --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.hardware.display.IVirtualDisplayCallback; +import android.hardware.display.VirtualDisplayConfig; +import android.os.IBinder; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.server.testutils.TestHandler; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class VirtualDisplayAdapterTest { + + @Mock + Context mContextMock; + + @Mock + VirtualDisplayAdapter.SurfaceControlDisplayFactory mMockSufaceControlDisplayFactory; + + @Mock + DisplayAdapter.Listener mMockListener; + + @Mock + IVirtualDisplayCallback mMockCallback; + + @Mock + IBinder mMockBinder; + + private TestHandler mHandler; + + private VirtualDisplayAdapter mVirtualDisplayAdapter; + + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mHandler = new TestHandler(null); + mVirtualDisplayAdapter = new VirtualDisplayAdapter(new DisplayManagerService.SyncRoot(), + mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory); + + when(mMockCallback.asBinder()).thenReturn(mMockBinder); + } + + @Test + public void testCreatesVirtualDisplay() { + VirtualDisplayConfig config = new VirtualDisplayConfig.Builder("test", /* width= */ 1, + /* height= */ 1, /* densityDpi= */ 1).build(); + + DisplayDevice result = mVirtualDisplayAdapter.createVirtualDisplayLocked(mMockCallback, + /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage", + /* surface= */ null, /* flags= */ 0, config); + + assertNotNull(result); + } + + @Test + public void testDoesNotCreateVirtualDisplayForSameCallback() { + VirtualDisplayConfig config1 = new VirtualDisplayConfig.Builder("test", /* width= */ 1, + /* height= */ 1, /* densityDpi= */ 1).build(); + VirtualDisplayConfig config2 = new VirtualDisplayConfig.Builder("test2", /* width= */ 1, + /* height= */ 1, /* densityDpi= */ 1).build(); + mVirtualDisplayAdapter.createVirtualDisplayLocked(mMockCallback, /* projection= */ null, + /* ownerUid= */ 10, /* packageName= */ "testpackage", /* surface= */ null, + /* flags= */ 0, config1); + + DisplayDevice result = mVirtualDisplayAdapter.createVirtualDisplayLocked(mMockCallback, + /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage", + /* surface= */ null, /* flags= */ 0, config2); + + assertNull(result); + } +} |