Fix IndexOutOfBoundsException on VirtualDisplay removal

We were accidentally calling remove() on an ArrayList<Integer> using a
primitive integer, which is interpreted as an index, when we intended to
be removing by Integer value. This CL fixes that by switching to using a
ArraySet for the data structure, since we were only using it as a Set
anyway and don't need List semantics.

Test: atest VirtualDeviceManagerServiceTest
Fixes: 215381936
Change-Id: I730f5f4001fd6b3627d2ab70e7af5860ce367049
This commit is contained in:
Antony Sargent
2022-01-19 11:34:15 -08:00
parent a26e957b9b
commit ed0481d2f6
2 changed files with 17 additions and 3 deletions

View File

@@ -53,8 +53,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
final class VirtualDeviceImpl extends IVirtualDevice.Stub
@@ -69,7 +68,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
private final int mOwnerUid;
private final InputController mInputController;
@VisibleForTesting
final List<Integer> mVirtualDisplayIds = new ArrayList<>();
final Set<Integer> mVirtualDisplayIds = new ArraySet<>();
private final OnDeviceCloseListener mListener;
private final IBinder mAppToken;
private final VirtualDeviceParams mParams;

View File

@@ -23,9 +23,11 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
import android.Manifest;
import android.app.admin.DevicePolicyManager;
import android.companion.virtual.VirtualDeviceParams;
import android.content.Context;
import android.content.ContextWrapper;
@@ -73,6 +75,8 @@ public class VirtualDeviceManagerServiceTest {
private DisplayManagerInternal mDisplayManagerInternalMock;
@Mock
private VirtualDeviceImpl.PendingTrampolineCallback mPendingTrampolineCallback;
@Mock
private DevicePolicyManager mDevicePolicyManagerMock;
@Before
public void setUp() {
@@ -84,6 +88,9 @@ public class VirtualDeviceManagerServiceTest {
mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
doNothing().when(mContext).enforceCallingOrSelfPermission(
eq(Manifest.permission.CREATE_VIRTUAL_DEVICE), anyString());
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
mDevicePolicyManagerMock);
mInputController = new InputController(new Object(), mNativeWrapperMock);
mDeviceImpl = new VirtualDeviceImpl(mContext,
/* association info */ null, new Binder(), /* uid */ 0, mInputController,
@@ -91,6 +98,14 @@ public class VirtualDeviceManagerServiceTest {
new VirtualDeviceParams.Builder().build());
}
@Test
public void onVirtualDisplayRemovedLocked_doesNotThrowException() {
final int displayId = 2;
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
// This call should not throw any exceptions.
mDeviceImpl.onVirtualDisplayRemovedLocked(displayId);
}
@Test
public void createVirtualKeyboard_noDisplay_failsSecurityException() {
assertThrows(