Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3c5df08 authored by Piotr Wilczyński's avatar Piotr Wilczyński Committed by Android (Google) Code Review
Browse files

Merge "Fix no. of virtual displays per package" into main

parents 0740f70d 56b6db32
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2042,7 +2042,7 @@ public final class DisplayManagerService extends SystemService {
                        // handles stopping the projection.
                        Slog.w(TAG, "Content Recording: failed to start mirroring - "
                                + "releasing virtual display " + displayId);
                        releaseVirtualDisplayInternal(callback.asBinder(), callingUid);
                        releaseVirtualDisplayInternal(callback.asBinder());
                        return Display.INVALID_DISPLAY;
                    } else if (projection != null) {
                        // Indicate that this projection has been used to record, and can't be used
@@ -2131,7 +2131,7 @@ public final class DisplayManagerService extends SystemService {
        // Something weird happened and the logical display was not created.
        Slog.w(TAG, "Rejecting request to create virtual display "
                + "because the logical display was not created.");
        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder(), callingUid);
        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
        mDisplayDeviceRepo.onDisplayDeviceEvent(device,
                DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
        return -1;
@@ -2158,14 +2158,14 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    private void releaseVirtualDisplayInternal(IBinder appToken, int callingUid) {
    private void releaseVirtualDisplayInternal(IBinder appToken) {
        synchronized (mSyncRoot) {
            if (mVirtualDisplayAdapter == null) {
                return;
            }

            DisplayDevice device =
                    mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken, callingUid);
                    mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
            Slog.d(TAG, "Virtual Display: Display Device released");
            if (device != null) {
                // TODO: multi-display - handle virtual displays the same as other display adapters.
@@ -4789,10 +4789,9 @@ public final class DisplayManagerService extends SystemService {

        @Override // Binder call
        public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
            final int callingUid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                releaseVirtualDisplayInternal(callback.asBinder(), callingUid);
                releaseVirtualDisplayInternal(callback.asBinder());
            } finally {
                Binder.restoreCallingIdentity(token);
            }
+16 −8
Original line number Diff line number Diff line
@@ -91,6 +91,13 @@ public class VirtualDisplayAdapter extends DisplayAdapter {

    private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices = new ArrayMap<>();

    // When a virtual display is created, the mapping (appToken -> ownerUid) is stored here. That
    // way, when the display is released later, we can retrieve the ownerUid and decrement
    // the number of virtual displays that exist for that ownerUid. We can't use
    // Binder.getCallingUid() because the display might be released by the system process and not
    // the process that created the display.
    private final ArrayMap<IBinder, Integer> mOwnerUids = new ArrayMap<>();

    private final int mMaxDevices;
    private final int mMaxDevicesPerPackage;
    private final SparseIntArray mNoOfDevicesPerPackage = new SparseIntArray();
@@ -194,6 +201,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
        mVirtualDisplayDevices.put(appToken, device);
        if (getFeatureFlags().isVirtualDisplayLimitEnabled()) {
            mNoOfDevicesPerPackage.put(ownerUid, noOfDevices + 1);
            mOwnerUids.put(appToken, ownerUid);
        }

        try {
@@ -205,7 +213,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
            appToken.linkToDeath(device, 0);
        } catch (RemoteException ex) {
            Slog.e(TAG, "Virtual Display: error while setting up VirtualDisplayDevice", ex);
            removeVirtualDisplayDeviceLocked(appToken, ownerUid);
            removeVirtualDisplayDeviceLocked(appToken);
            device.destroyLocked(false);
            return null;
        }
@@ -252,12 +260,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
    /**
     * Release a virtual display that was previously created
     * @param appToken The token to identify the display
     * @param ownerUid The UID of the package, used to keep track of and limit the number of
     *                 displays created per package
     * @return The display device that has been removed
     */
    public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken, int ownerUid) {
        VirtualDisplayDevice device = removeVirtualDisplayDeviceLocked(appToken, ownerUid);
    public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
        VirtualDisplayDevice device = removeVirtualDisplayDeviceLocked(appToken);
        if (device != null) {
            Slog.v(TAG, "Release VirtualDisplay " + device.mName);
            device.destroyLocked(true);
@@ -299,11 +305,13 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
        }
    }

    private VirtualDisplayDevice removeVirtualDisplayDeviceLocked(IBinder appToken, int ownerUid) {
        int noOfDevices = mNoOfDevicesPerPackage.get(ownerUid, /* valueIfKeyNotFound= */ 0);
    private VirtualDisplayDevice removeVirtualDisplayDeviceLocked(IBinder appToken) {
        if (getFeatureFlags().isVirtualDisplayLimitEnabled()) {
            int ownerUid = mOwnerUids.get(appToken);
            int noOfDevices = mNoOfDevicesPerPackage.get(ownerUid, /* valueIfKeyNotFound= */ 0);
            if (noOfDevices <= 1) {
                mNoOfDevicesPerPackage.delete(ownerUid);
                mOwnerUids.remove(appToken);
            } else {
                mNoOfDevicesPerPackage.put(ownerUid, noOfDevices - 1);
            }
@@ -378,7 +386,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
        @Override
        public void binderDied() {
            synchronized (getSyncRoot()) {
                removeVirtualDisplayDeviceLocked(mAppToken, mOwnerUid);
                removeVirtualDisplayDeviceLocked(mAppToken);
                Slog.i(TAG, "Virtual display device released because application token died: "
                    + mOwnerPackageName);
                destroyLocked(false);
+1 −1
Original line number Diff line number Diff line
@@ -3708,7 +3708,7 @@ public class DisplayManagerServiceTest {
                eq(config));

        bs.releaseVirtualDisplay(mMockAppToken);
        verify(mMockVirtualDisplayAdapter).releaseVirtualDisplayLocked(binder, callingUid);
        verify(mMockVirtualDisplayAdapter).releaseVirtualDisplayLocked(binder);
    }

    @Test
+7 −13
Original line number Diff line number Diff line
@@ -118,14 +118,13 @@ public class VirtualDisplayAdapterTest {
    public void testCreateAndReleaseVirtualDisplay() {
        VirtualDisplayConfig config = new VirtualDisplayConfig.Builder("test", /* width= */ 1,
                /* height= */ 1, /* densityDpi= */ 1).build();
        int ownerUid = 10;

        DisplayDevice result = mAdapter.createVirtualDisplayLocked(mMockCallback,
                /* projection= */ null, ownerUid, /* packageName= */ "testpackage",
                /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage",
                /* uniqueId= */ "uniqueId", /* surface= */ null, /* flags= */ 0, config);
        assertNotNull(result);

        result = mAdapter.releaseVirtualDisplayLocked(mMockBinder, ownerUid);
        result = mAdapter.releaseVirtualDisplayLocked(mMockBinder);
        assertNotNull(result);
    }

@@ -230,7 +229,6 @@ public class VirtualDisplayAdapterTest {

        // Displays for the same package
        for (int i = 0; i < MAX_DEVICES_PER_PACKAGE * 2; i++) {
            // Same owner UID
            IVirtualDisplayCallback callback = createCallback();
            DisplayDevice device = mAdapter.createVirtualDisplayLocked(callback,
                    mMediaProjectionMock, 1234, "test.package", "123",
@@ -240,7 +238,6 @@ public class VirtualDisplayAdapterTest {

        // Displays for different packages
        for (int i = 0; i < MAX_DEVICES * 2; i++) {
            // Same owner UID
            IVirtualDisplayCallback callback = createCallback();
            DisplayDevice device = mAdapter.createVirtualDisplayLocked(callback,
                    mMediaProjectionMock, 1234 + i, "test.package", "123",
@@ -270,8 +267,7 @@ public class VirtualDisplayAdapterTest {
        }

        // Release one display
        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder(),
                ownerUid);
        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder());
        assertNotNull(device);
        callbacks.remove(0);

@@ -292,7 +288,7 @@ public class VirtualDisplayAdapterTest {

        // Release all the displays
        for (IVirtualDisplayCallback cb : callbacks) {
            device = mAdapter.releaseVirtualDisplayLocked(cb.asBinder(), ownerUid);
            device = mAdapter.releaseVirtualDisplayLocked(cb.asBinder());
            assertNotNull(device);
        }
        callbacks.clear();
@@ -342,8 +338,7 @@ public class VirtualDisplayAdapterTest {
        }

        // Release one display
        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder(),
                firstOwnerUid);
        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder());
        assertNotNull(device);
        callbacks.remove(0);

@@ -363,9 +358,8 @@ public class VirtualDisplayAdapterTest {
        assertNull(device);

        // Release all the displays
        for (int i = 0; i < callbacks.size(); i++) {
            device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(i).asBinder(),
                    firstOwnerUid + i);
        for (IVirtualDisplayCallback iVirtualDisplayCallback : callbacks) {
            device = mAdapter.releaseVirtualDisplayLocked(iVirtualDisplayCallback.asBinder());
            assertNotNull(device);
        }
        callbacks.clear();