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

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

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

Change-Id: Ia25e4e56bd036c414db74c9eb415a0c8dc6fa44e
parents a37da3be ec53ce71
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();

    }
}