Loading services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java +71 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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()); } Loading Loading @@ -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 Loading @@ -269,7 +274,6 @@ public class TunerResourceManagerService extends SystemService { Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")"); } removeClientProfile(clientId); mListeners.remove(clientId); } @VisibleForTesting Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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); } Loading services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java +26 −29 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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 = Loading @@ -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 Loading Loading @@ -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]); Loading Loading @@ -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(); } Loading @@ -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]); Loading Loading @@ -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 Loading Loading @@ -516,6 +512,7 @@ public class TunerResourceManagerServiceTest { .isInUse()).isFalse(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId()) .isInUse()).isFalse(); assertThat(mTunerResourceManagerService.checkClientExists(clientId[0])).isFalse(); } } Loading
services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java +71 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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()); } Loading Loading @@ -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 Loading @@ -269,7 +274,6 @@ public class TunerResourceManagerService extends SystemService { Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")"); } removeClientProfile(clientId); mListeners.remove(clientId); } @VisibleForTesting Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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); } Loading
services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java +26 −29 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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 = Loading @@ -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 Loading Loading @@ -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]); Loading Loading @@ -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(); } Loading @@ -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]); Loading Loading @@ -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 Loading Loading @@ -516,6 +512,7 @@ public class TunerResourceManagerServiceTest { .isInUse()).isFalse(); assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId()) .isInUse()).isFalse(); assertThat(mTunerResourceManagerService.checkClientExists(clientId[0])).isFalse(); } }