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

Commit b6e804de authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Handle binderDied on the resource reclaim listeners in TRM" into...

Merge "Handle binderDied on the resource reclaim listeners in TRM" into rvc-dev am: ec53ce71 am: ec0c3ac3 am: 115ba73c

Change-Id: If28f88680053c97ef71e3def855ebf3a2add8c82
parents 5fd19558 115ba73c
Loading
Loading
Loading
Loading
+71 −18
Original line number Diff line number Diff line
@@ -29,11 +29,12 @@ import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
import android.media.tv.tunerresourcemanager.TunerLnbRequest;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.SystemService;

@@ -61,7 +62,8 @@ public class TunerResourceManagerService extends SystemService {
    // Map of the current available frontend resources
    private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();

    private SparseArray<IResourcesReclaimListener> mListeners = new SparseArray<>();
    @GuardedBy("mLock")
    private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>();

    private TvInputManager mManager;
    private UseCasePriorityHints mPriorityCongfig = new UseCasePriorityHints();
@@ -101,6 +103,10 @@ public class TunerResourceManagerService extends SystemService {
                throw new RemoteException("clientId can't be null!");
            }

            if (listener == null) {
                throw new RemoteException("IResourcesReclaimListener can't be null!");
            }

            if (!mPriorityCongfig.isDefinedUseCase(profile.getUseCase())) {
                throw new RemoteException("Use undefined client use case:" + profile.getUseCase());
            }
@@ -259,8 +265,7 @@ public class TunerResourceManagerService extends SystemService {
                                              .build();
        clientProfile.setPriority(getClientPriority(profile.getUseCase(), pid));

        addClientProfile(clientId[0], clientProfile);
        mListeners.append(clientId[0], listener);
        addClientProfile(clientId[0], clientProfile, listener);
    }

    @VisibleForTesting
@@ -269,7 +274,6 @@ public class TunerResourceManagerService extends SystemService {
            Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")");
        }
        removeClientProfile(clientId);
        mListeners.remove(clientId);
    }

    @VisibleForTesting
@@ -392,6 +396,62 @@ public class TunerResourceManagerService extends SystemService {
        return false;
    }

    @VisibleForTesting
    protected class ResourcesReclaimListenerRecord implements IBinder.DeathRecipient {
        private final IResourcesReclaimListener mListener;
        private final int mClientId;

        public ResourcesReclaimListenerRecord(IResourcesReclaimListener listener, int clientId) {
            mListener = listener;
            mClientId = clientId;
        }

        @Override
        public void binderDied() {
            synchronized (mLock) {
                removeClientProfile(mClientId);
            }
        }

        public int getId() {
            return mClientId;
        }

        public IResourcesReclaimListener getListener() {
            return mListener;
        }
    }

    private void addResourcesReclaimListener(int clientId, IResourcesReclaimListener listener) {
        if (listener == null) {
            if (DEBUG) {
                Slog.w(TAG, "Listener is null when client " + clientId + " registered!");
            }
            return;
        }

        ResourcesReclaimListenerRecord record =
                new ResourcesReclaimListenerRecord(listener, clientId);

        try {
            listener.asBinder().linkToDeath(record, 0);
        } catch (RemoteException e) {
            Slog.w(TAG, "Listener already died.");
            return;
        }

        mListeners.put(clientId, record);
    }

    @VisibleForTesting
    protected void reclaimFrontendResource(int reclaimingId) {
        try {
            mListeners.get(reclaimingId).getListener().onReclaimResources();
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingId, e);
        }
    }

    @VisibleForTesting
    protected int getClientPriority(int useCase, int pid) {
        if (DEBUG) {
@@ -411,17 +471,6 @@ public class TunerResourceManagerService extends SystemService {
        return true;
    }

    @VisibleForTesting
    protected void reclaimFrontendResource(int reclaimingId) throws RemoteException {
        if (mListeners.get(reclaimingId) != null) {
            try {
                mListeners.get(reclaimingId).onReclaimResources();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    private void updateFrontendClientMappingOnNewGrant(int grantingId, int ownerClientId) {
        FrontendResource grantingFrontend = getFrontendResource(grantingId);
        ClientProfile ownerProfile = getClientProfile(ownerClientId);
@@ -487,8 +536,10 @@ public class TunerResourceManagerService extends SystemService {
        return mClientProfiles.get(clientId);
    }

    private void addClientProfile(int clientId, ClientProfile profile) {
    private void addClientProfile(int clientId, ClientProfile profile,
            IResourcesReclaimListener listener) {
        mClientProfiles.put(clientId, profile);
        addResourcesReclaimListener(clientId, listener);
    }

    private void removeClientProfile(int clientId) {
@@ -499,9 +550,11 @@ public class TunerResourceManagerService extends SystemService {
            }
        }
        mClientProfiles.remove(clientId);
        mListeners.remove(clientId);
    }

    private boolean checkClientExists(int clientId) {
    @VisibleForTesting
    protected boolean checkClientExists(int clientId) {
        return mClientProfiles.keySet().contains(clientId);
    }

+26 −29
Original line number Diff line number Diff line
@@ -26,12 +26,12 @@ import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputService;
import android.media.tv.tuner.frontend.FrontendSettings;
import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
import android.media.tv.tunerresourcemanager.ResourceClientProfile;
import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.RemoteException;
import android.util.SparseArray;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -45,9 +45,7 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
@@ -60,7 +58,19 @@ public class TunerResourceManagerServiceTest {
    private Context mContextSpy;
    @Mock private ITvInputManager mITvInputManagerMock;
    private TunerResourceManagerService mTunerResourceManagerService;
    private int mReclaimingId;

    private static final class TestResourcesReclaimListener extends IResourcesReclaimListener.Stub {
        boolean mReclaimed;

        @Override
        public void onReclaimResources() {
            mReclaimed = true;
        }

        public boolean isRelaimed() {
            return mReclaimed;
        }
    }

    // A correspondence to compare a FrontendResource and a TunerFrontendInfo.
    private static final Correspondence<FrontendResource, TunerFrontendInfo> FR_TFI_COMPARE =
@@ -82,31 +92,14 @@ public class TunerResourceManagerServiceTest {
            }
        };

    private static <T> List<T> sparseArrayToList(SparseArray<T> sparseArray) {
        if (sparseArray == null) {
            return null;
        }
        List<T> arrayList = new ArrayList<T>(sparseArray.size());
        for (int i = 0; i < sparseArray.size(); i++) {
            arrayList.add(sparseArray.valueAt(i));
        }
        return arrayList;
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        TvInputManager tvInputManager = new TvInputManager(mITvInputManagerMock, 0);
        mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
        when(mContextSpy.getSystemService(Context.TV_INPUT_SERVICE)).thenReturn(tvInputManager);
        mTunerResourceManagerService = new TunerResourceManagerService(mContextSpy) {
            @Override
            protected void reclaimFrontendResource(int reclaimingId) {
                mReclaimingId = reclaimingId;
            }
        };
        mTunerResourceManagerService = new TunerResourceManagerService(mContextSpy);
        mTunerResourceManagerService.onStart(true /*isForTesting*/);
        mReclaimingId = -1;
    }

    @Test
@@ -366,13 +359,15 @@ public class TunerResourceManagerServiceTest {
        int[] clientPriorities = {100, 50};
        int[] clientId0 = new int[1];
        int[] clientId1 = new int[1];
        TestResourcesReclaimListener listener = new TestResourcesReclaimListener();

        mTunerResourceManagerService.registerClientProfileInternal(
                profiles[0], null /*listener*/, clientId0);
                profiles[0], listener, clientId0);
        assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
        mTunerResourceManagerService.getClientProfile(clientId0[0])
                .setPriority(clientPriorities[0]);
        mTunerResourceManagerService.registerClientProfileInternal(
                profiles[1], null /*listener*/, clientId1);
                profiles[1], new TestResourcesReclaimListener(), clientId1);
        assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
        mTunerResourceManagerService.getClientProfile(clientId1[0])
                .setPriority(clientPriorities[1]);
@@ -400,17 +395,17 @@ public class TunerResourceManagerServiceTest {
        try {
            assertThat(mTunerResourceManagerService.requestFrontendInternal(request, frontendId))
                    .isFalse();
            assertThat(listener.isRelaimed()).isFalse();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        assertThat(mReclaimingId).isEqualTo(-1);

        request =
                new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
        try {
            assertThat(mTunerResourceManagerService.requestFrontendInternal(request, frontendId))
                    .isFalse();
            assertThat(mReclaimingId).isEqualTo(-1);
            assertThat(listener.isRelaimed()).isFalse();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -427,13 +422,14 @@ public class TunerResourceManagerServiceTest {
        int[] clientPriorities = {100, 500};
        int[] clientId0 = new int[1];
        int[] clientId1 = new int[1];
        TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
        mTunerResourceManagerService.registerClientProfileInternal(
                profiles[0], null /*listener*/, clientId0);
                profiles[0], listener, clientId0);
        assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
        mTunerResourceManagerService.getClientProfile(clientId0[0])
                .setPriority(clientPriorities[0]);
        mTunerResourceManagerService.registerClientProfileInternal(
                profiles[1], null /*listener*/, clientId1);
                profiles[1], new TestResourcesReclaimListener(), clientId1);
        assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
        mTunerResourceManagerService.getClientProfile(clientId1[0])
                .setPriority(clientPriorities[1]);
@@ -474,7 +470,7 @@ public class TunerResourceManagerServiceTest {
                .getOwnerClientId()).isEqualTo(clientId1[0]);
        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
                .getOwnerClientId()).isEqualTo(clientId1[0]);
        assertThat(mReclaimingId).isEqualTo(clientId0[0]);
        assertThat(listener.isRelaimed()).isTrue();
    }

    @Test
@@ -516,6 +512,7 @@ public class TunerResourceManagerServiceTest {
                .isInUse()).isFalse();
        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
                .isInUse()).isFalse();
        assertThat(mTunerResourceManagerService.checkClientExists(clientId[0])).isFalse();

    }
}