From 9de25c7c70c34c09bc1abafb4ef2b7e3f43c4a4d Mon Sep 17 00:00:00 2001 From: Weilin Xu Date: Tue, 13 Sep 2022 01:10:48 +0000 Subject: [PATCH] Add test for AIDL radio client program list update Added unit tests for program list update using filter in AIDL broadcast radio HAL client. Also added unit tests for handing expcetion and non-current user cases during program list update. Bug: 241118988 Test: com.android.server.broadcastradio.aidl.ProgramInfoCacheTest Change-Id: I1ce5770207f11933c16dfb19c2c6b967b77d36fc --- .../broadcastradio/aidl/AidlTestUtils.java | 47 ++- .../aidl/ConversionUtilsTest.java | 4 +- .../broadcastradio/aidl/TunerSessionTest.java | 307 +++++++++++++++++- .../hal2/TunerSessionHidlTest.java | 34 +- 4 files changed, 376 insertions(+), 16 deletions(-) diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java index 82db716fcdc24..e2e9bd9695553 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java @@ -21,10 +21,15 @@ import android.hardware.broadcastradio.ProgramIdentifier; import android.hardware.broadcastradio.ProgramInfo; import android.hardware.broadcastradio.ProgramListChunk; import android.hardware.broadcastradio.VendorKeyValue; +import android.hardware.radio.ProgramList; import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; import android.hardware.radio.RadioMetadata; +import android.os.RemoteException; import android.util.ArrayMap; +import android.util.ArraySet; + +import java.util.List; final class AidlTestUtils { @@ -94,6 +99,14 @@ final class AidlTestUtils { return makeHalProgramInfo(hwSel, hwSel.primaryId, hwSel.primaryId, hwSignalQuality); } + static ProgramInfo programInfoToHalProgramInfo(RadioManager.ProgramInfo info) { + return makeHalProgramInfo( + ConversionUtils.programSelectorToHalProgramSelector(info.getSelector()), + ConversionUtils.identifierToHalProgramIdentifier(info.getLogicallyTunedTo()), + ConversionUtils.identifierToHalProgramIdentifier(info.getPhysicallyTunedTo()), + info.getSignalStrength()); + } + static ProgramInfo makeHalProgramInfo( android.hardware.broadcastradio.ProgramSelector hwSel, ProgramIdentifier logicallyTunedTo, ProgramIdentifier physicallyTunedTo, @@ -108,7 +121,23 @@ final class AidlTestUtils { return hwInfo; } - static ProgramListChunk makeProgramListChunk(boolean purge, boolean complete, + static ProgramListChunk makeHalChunk(boolean purge, List modified, + List removed) { + ProgramInfo[] halModified = + new android.hardware.broadcastradio.ProgramInfo[modified.size()]; + for (int i = 0; i < modified.size(); i++) { + halModified[i] = programInfoToHalProgramInfo(modified.get(i)); + } + + ProgramIdentifier[] halRemoved = + new android.hardware.broadcastradio.ProgramIdentifier[removed.size()]; + for (int i = 0; i < removed.size(); i++) { + halRemoved[i] = ConversionUtils.identifierToHalProgramIdentifier(removed.get(i)); + } + return makeHalChunk(purge, /* complete= */ true, halModified, halRemoved); + } + + static ProgramListChunk makeHalChunk(boolean purge, boolean complete, ProgramInfo[] modified, ProgramIdentifier[] removed) { ProgramListChunk halChunk = new ProgramListChunk(); halChunk.purge = purge; @@ -118,6 +147,22 @@ final class AidlTestUtils { return halChunk; } + static ProgramList.Chunk makeChunk(boolean purge, + List modified, + List removed) throws RemoteException { + ArraySet modifiedSet = new ArraySet<>(); + if (modified != null) { + modifiedSet.addAll(modified); + } + ArraySet removedSet = new ArraySet<>(); + if (removed != null) { + removedSet.addAll(removed); + } + ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ purge, /* complete= */true, + modifiedSet, removedSet); + return chunk; + } + static VendorKeyValue makeVendorKeyValue(String vendorKey, String vendorValue) { VendorKeyValue vendorKeyValue = new VendorKeyValue(); vendorKeyValue.key = vendorKey; diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java index 710c150c006cf..5d0e07613a98f 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java @@ -328,7 +328,7 @@ public final class ConversionUtilsTest { TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY); RadioManager.ProgramInfo dabInfo = ConversionUtils.programInfoFromHalProgramInfo(halDabInfo); - ProgramListChunk halChunk = AidlTestUtils.makeProgramListChunk(purge, complete, + ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete, new ProgramInfo[]{halDabInfo}, new ProgramIdentifier[]{TEST_HAL_VENDOR_ID, TEST_HAL_FM_FREQUENCY_ID}); @@ -353,7 +353,7 @@ public final class ConversionUtilsTest { TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID}); ProgramInfo halDabInfo = AidlTestUtils.makeHalProgramInfo(halDabSelector, TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY); - ProgramListChunk halChunk = AidlTestUtils.makeProgramListChunk(purge, complete, + ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete, new ProgramInfo[]{halDabInfo}, new ProgramIdentifier[]{TEST_HAL_FM_FREQUENCY_ID}); ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java index d7723acf6f05f..62846b1c4cc0a 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java @@ -37,7 +37,9 @@ import android.graphics.Bitmap; import android.hardware.broadcastradio.IBroadcastRadio; import android.hardware.broadcastradio.ITunerCallback; import android.hardware.broadcastradio.IdentifierType; +import android.hardware.broadcastradio.ProgramFilter; import android.hardware.broadcastradio.ProgramInfo; +import android.hardware.broadcastradio.ProgramListChunk; import android.hardware.broadcastradio.Result; import android.hardware.broadcastradio.VendorKeyValue; import android.hardware.radio.ProgramList; @@ -61,8 +63,10 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.verification.VerificationWithTimeout; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; /** * Tests for AIDL HAL TunerSession. @@ -72,7 +76,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT; private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(/* millis= */ 200); - private static final int SIGNAL_QUALITY = 1; + private static final int SIGNAL_QUALITY = 90; private static final long AM_FM_FREQUENCY_SPACING = 500; private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100}; private static final RadioManager.FmBandDescriptor FM_BAND_DESCRIPTOR = @@ -84,6 +88,27 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { new RadioManager.FmBandConfig(FM_BAND_DESCRIPTOR); private static final int UNSUPPORTED_CONFIG_FLAG = 0; + private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID = + new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, + /* value= */ 88_500); + private static final ProgramSelector.Identifier TEST_RDS_PI_ID = + new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI, + /* value= */ 15_019); + + private static final RadioManager.ProgramInfo TEST_FM_INFO = AidlTestUtils.makeProgramInfo( + AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, + TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, TEST_FM_FREQUENCY_ID, + SIGNAL_QUALITY); + private static final RadioManager.ProgramInfo TEST_FM_INFO_MODIFIED = + AidlTestUtils.makeProgramInfo(AidlTestUtils.makeProgramSelector( + ProgramSelector.PROGRAM_TYPE_FM, TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, + TEST_FM_FREQUENCY_ID, /* signalQuality= */ 100); + private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo( + AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID), + TEST_RDS_PI_ID, new ProgramSelector.Identifier( + ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 89_500), + SIGNAL_QUALITY); + // Mocks @Mock private IBroadcastRadio mBroadcastRadioMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; @@ -393,7 +418,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test - public void tune_withHalHasUnknownError_fails() throws Exception { + public void tune_withUnknownErrorFromHal_fails() throws Exception { openAidlClients(/* numClients= */ 1); ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); doThrow(new ServiceSpecificException(Result.UNKNOWN_ERROR)) @@ -403,7 +428,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].tune(sel); }); - assertWithMessage("Exception for tuning when HAL has unknown error") + assertWithMessage("Unknown error HAL exception when tuning") .that(thrown).hasMessageThat().contains("UNKNOWN_ERROR"); } @@ -536,7 +561,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test - public void seek_withHalHasInternalError_fails() throws Exception { + public void seek_withInternalErrorFromHal_fails() throws Exception { openAidlClients(/* numClients= */ 1); doThrow(new ServiceSpecificException(Result.INTERNAL_ERROR)) .when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean()); @@ -545,7 +570,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); }); - assertWithMessage("Exception for seeking when HAL has internal error") + assertWithMessage("Internal error HAL exception when seeking") .that(thrown).hasMessageThat().contains("INTERNAL_ERROR"); } @@ -643,12 +668,276 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete(); } + @Test + public void startProgramListUpdates_withEmptyFilter() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(filter); + List modified = List.of(TEST_FM_INFO, TEST_RDS_INFO); + List removed = new ArrayList<>(); + ProgramListChunk halProgramList = + AidlTestUtils.makeHalChunk(/* purge= */ true, modified, removed); + ProgramList.Chunk expectedProgramList = + AidlTestUtils.makeChunk(/* purge= */ true, modified, removed); + + mTunerSessions[0].startProgramListUpdates(filter); + mHalTunerCallback.onProgramListUpdated(halProgramList); + + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT) + .onProgramListUpdated(expectedProgramList); + } + + @Test + public void startProgramListUpdates_withCallbackCalledForMultipleTimes() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + mTunerSessions[0].startProgramListUpdates(filter); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true, + List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>())); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), + new ArrayList<>())); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID))); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED), + List.of(TEST_RDS_PI_ID))); + } + + @Test + public void startProgramListUpdates_withTheSameFilterForMultipleTimes() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + mTunerSessions[0].startProgramListUpdates(filter); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true, + List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>())); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), + new ArrayList<>())); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID))); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED), + List.of(TEST_RDS_PI_ID))); + + mTunerSessions[0].startProgramListUpdates(filter); + + verify(mBroadcastRadioMock).startProgramListUpdates(any()); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO_MODIFIED), + new ArrayList<>())); + } + + @Test + public void startProgramListUpdates_withNullFilter() throws Exception { + openAidlClients(/* numClients= */ 1); + + mTunerSessions[0].startProgramListUpdates(/* filter= */ null); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true, + List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>())); + + verify(mBroadcastRadioMock).startProgramListUpdates(any()); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), + new ArrayList<>())); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID))); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED), + List.of(TEST_RDS_PI_ID))); + } + + @Test + public void startProgramListUpdates_withIdFilter() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter idFilter = new ProgramList.Filter(new ArraySet<>(), + Set.of(TEST_RDS_PI_ID), /* includeCategories= */ true, + /* excludeModifications= */ true); + ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(idFilter); + + mTunerSessions[0].startProgramListUpdates(idFilter); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_RDS_INFO), new ArrayList<>())); + + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_RDS_INFO), + new ArrayList<>())); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO), new ArrayList<>())); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any()); + } + + @Test + public void startProgramListUpdates_withFilterExcludingModifications() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filterExcludingModifications = new ProgramList.Filter( + Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ true); + ProgramFilter halFilter = + ConversionUtils.filterToHalProgramFilter(filterExcludingModifications); + + mTunerSessions[0].startProgramListUpdates(filterExcludingModifications); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO), new ArrayList<>())); + + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO), + new ArrayList<>())); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>())); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any()); + } + + @Test + public void startProgramListUpdates_withFilterIncludingModifications() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filterIncludingModifications = new ProgramList.Filter( + Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + ProgramFilter halFilter = + ConversionUtils.filterToHalProgramFilter(filterIncludingModifications); + + mTunerSessions[0].startProgramListUpdates(filterIncludingModifications); + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO), new ArrayList<>())); + + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO), + new ArrayList<>())); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>())); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated( + AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED), + new ArrayList<>())); + } + + @Test + public void onProgramListUpdated_afterSessionClosed_doesNotUpdates() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + mTunerSessions[0].startProgramListUpdates(filter); + + mTunerSessions[0].close(); + + verify(mBroadcastRadioMock).stopProgramListUpdates(); + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO), new ArrayList<>())); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any()); + } + + @Test + public void startProgramListUpdates_forMultipleSessions() throws Exception { + int numSessions = 3; + openAidlClients(numSessions); + ProgramList.Filter fmIdFilter = new ProgramList.Filter(new ArraySet<>(), + Set.of(TEST_FM_FREQUENCY_ID), /* includeCategories= */ false, + /* excludeModifications= */ true); + ProgramList.Filter filterExcludingCategories = new ProgramList.Filter(new ArraySet<>(), + new ArraySet<>(), /* includeCategories= */ true, + /* excludeModifications= */ true); + ProgramList.Filter rdsTypeFilter = new ProgramList.Filter( + Set.of(ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + + mTunerSessions[0].startProgramListUpdates(fmIdFilter); + + ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(fmIdFilter); + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + + mTunerSessions[1].startProgramListUpdates(filterExcludingCategories); + + halFilter.identifiers = new android.hardware.broadcastradio.ProgramIdentifier[]{}; + halFilter.includeCategories = true; + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + + mTunerSessions[2].startProgramListUpdates(rdsTypeFilter); + + halFilter.excludeModifications = false; + verify(mBroadcastRadioMock).startProgramListUpdates(halFilter); + } + + @Test + public void onProgramListUpdated_forMultipleSessions() throws Exception { + int numSessions = 3; + openAidlClients(numSessions); + List filters = List.of(new ProgramList.Filter( + Set.of(ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false), + new ProgramList.Filter(new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID), + /* includeCategories= */ false, /* excludeModifications= */ true), + new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ true)); + + for (int index = 0; index < numSessions; index++) { + mTunerSessions[index].startProgramListUpdates(filters.get(index)); + } + + mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, + List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>())); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT) + .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false, + List.of(TEST_RDS_INFO), new ArrayList<>())); + verify(mAidlTunerCallbackMocks[1], CALLBACK_TIMEOUT) + .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false, + List.of(TEST_FM_INFO), new ArrayList<>())); + verify(mAidlTunerCallbackMocks[2], CALLBACK_TIMEOUT) + .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false, + List.of(TEST_RDS_INFO, TEST_FM_INFO), new ArrayList<>())); + } + + @Test + public void startProgramListUpdates_forNonCurrentUser_doesNotStartUpdates() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + + mTunerSessions[0].startProgramListUpdates(filter); + + verify(mBroadcastRadioMock, never()).startProgramListUpdates(any()); + } + + @Test + public void startProgramListUpdates_withUnknownErrorFromHal_fails() throws Exception { + openAidlClients(/* numClients= */ 1); + doThrow(new ServiceSpecificException(Result.UNKNOWN_ERROR)) + .when(mBroadcastRadioMock).startProgramListUpdates(any()); + + ParcelableException thrown = assertThrows(ParcelableException.class, () -> { + mTunerSessions[0].startProgramListUpdates(/* filter= */ null); + }); + + assertWithMessage("Unknown error HAL exception when updating program list") + .that(thrown).hasMessageThat().contains("UNKNOWN_ERROR"); + } + @Test public void stopProgramListUpdates() throws Exception { openAidlClients(/* numClients= */ 1); - ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - mTunerSessions[0].startProgramListUpdates(aidlFilter); + mTunerSessions[0].startProgramListUpdates(filter); mTunerSessions[0].stopProgramListUpdates(); @@ -658,9 +947,9 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void stopProgramListUpdates_forNonCurrentUser_doesNotStopUpdates() throws Exception { openAidlClients(/* numClients= */ 1); - ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - mTunerSessions[0].startProgramListUpdates(aidlFilter); + mTunerSessions[0].startProgramListUpdates(filter); doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); mTunerSessions[0].stopProgramListUpdates(); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java index ea9a8461ad928..3815008bd4fb3 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java @@ -373,7 +373,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } @Test - public void tune_withHalHasUnknownError_fails() throws Exception { + public void tune_withUnknownErrorFromHal_fails() throws Exception { openAidlClients(/* numClients= */ 1); ProgramSelector sel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); doAnswer(invocation -> Result.UNKNOWN_ERROR).when(mHalTunerSessionMock).tune(any()); @@ -382,7 +382,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].tune(sel); }); - assertWithMessage("Exception for tuning when HAL has unknown error") + assertWithMessage("Unknown error HAL exception when tuning") .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR)); } @@ -513,7 +513,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } @Test - public void seek_withHalHasInternalError_fails() throws Exception { + public void seek_withInternalErrorFromHal_fails() throws Exception { openAidlClients(/* numClients= */ 1); doAnswer(invocation -> Result.INTERNAL_ERROR).when(mHalTunerSessionMock) .scan(anyBoolean(), anyBoolean()); @@ -522,7 +522,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); }); - assertWithMessage("Exception for seeking when HAL has internal error") + assertWithMessage("Internal error HAL exception when seeking") .that(thrown).hasMessageThat().contains(Result.toString(Result.INTERNAL_ERROR)); } @@ -632,6 +632,32 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete(); } + @Test + public void startProgramListUpdates_forNonCurrentUser_doesNotStartUpdates() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), + /* includeCategories= */ true, /* excludeModifications= */ false); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + + mTunerSessions[0].startProgramListUpdates(filter); + + verify(mHalTunerSessionMock, never()).startProgramListUpdates(any()); + } + + @Test + public void startProgramListUpdates_withUnknownErrorFromHal_fails() throws Exception { + openAidlClients(/* numClients= */ 1); + doAnswer(invocation -> Result.UNKNOWN_ERROR).when(mHalTunerSessionMock) + .startProgramListUpdates(any()); + + ParcelableException thrown = assertThrows(ParcelableException.class, () -> { + mTunerSessions[0].startProgramListUpdates(/* filter= */ null); + }); + + assertWithMessage("Unknown error HAL exception when updating program list") + .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR)); + } + @Test public void stopProgramListUpdates() throws Exception { openAidlClients(/* numClients= */ 1);