diff options
7 files changed, 335 insertions, 44 deletions
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 5f78b2a8a5f0..42501c1bf461 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 @@ -27,6 +27,7 @@ import android.hardware.broadcastradio.ConfigFlag; import android.hardware.broadcastradio.DabTableEntry; import android.hardware.broadcastradio.IdentifierType; import android.hardware.broadcastradio.Metadata; +import android.hardware.broadcastradio.ProgramFilter; import android.hardware.broadcastradio.ProgramIdentifier; import android.hardware.broadcastradio.ProgramInfo; import android.hardware.broadcastradio.Properties; @@ -41,6 +42,7 @@ import android.hardware.radio.RadioMetadata; import android.hardware.radio.UniqueProgramIdentifier; import android.os.ServiceSpecificException; import android.platform.test.flag.junit.SetFlagsRule; +import android.util.ArraySet; import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; @@ -93,6 +95,11 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { private static final long TEST_HD_LOCATION_VALUE = 0x4E647007665CF6L; private static final long TEST_VENDOR_ID_VALUE = 9_901; + private static final ProgramSelector.Identifier TEST_INVALID_ID = + new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_INVALID, 1); + private static final ProgramIdentifier TEST_HAL_INVALID_ID = + AidlTestUtils.makeHalIdentifier(IdentifierType.INVALID, 1); + private static final ProgramSelector.Identifier TEST_DAB_SID_EXT_ID = new ProgramSelector.Identifier( ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT, TEST_DAB_DMB_SID_EXT_VALUE); @@ -139,7 +146,7 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { private static final int TEST_ANNOUNCEMENT_FREQUENCY = FM_LOWER_LIMIT + FM_SPACING; private static final RadioManager.ModuleProperties MODULE_PROPERTIES = - convertToModuleProperties(); + createModuleProperties(); private static final Announcement ANNOUNCEMENT = ConversionUtils.announcementFromHalAnnouncement( AidlTestUtils.makeAnnouncement(TEST_ENABLED_TYPE, TEST_ANNOUNCEMENT_FREQUENCY)); @@ -291,6 +298,37 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { } @Test + public void propertiesFromHalProperties_withoutAmFmAndDabConfigs() { + RadioManager.ModuleProperties properties = createModuleProperties(/* amFmConfig= */ null, + new DabTableEntry[]{}); + + expect.withMessage("Empty AM/FM config") + .that(properties.getBands()).asList().isEmpty(); + expect.withMessage("Empty DAB config") + .that(properties.getDabFrequencyTable()).isNull(); + } + + @Test + public void propertiesFromHalProperties_withInvalidBand() { + AmFmRegionConfig amFmRegionConfig = new AmFmRegionConfig(); + amFmRegionConfig.ranges = new AmFmBandRange[]{createAmFmBandRange(/* lowerBound= */ 50000, + /* upperBound= */ 60000, /* spacing= */ 10), + createAmFmBandRange(FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING)}; + + RadioManager.ModuleProperties properties = createModuleProperties(amFmRegionConfig, + new DabTableEntry[]{}); + + RadioManager.BandDescriptor[] bands = properties.getBands(); + expect.withMessage("Band descriptors").that(bands).hasLength(1); + expect.withMessage("FM band frequency lower limit") + .that(bands[0].getLowerLimit()).isEqualTo(FM_LOWER_LIMIT); + expect.withMessage("FM band frequency upper limit") + .that(bands[0].getUpperLimit()).isEqualTo(FM_UPPER_LIMIT); + expect.withMessage("FM band frequency spacing") + .that(bands[0].getSpacing()).isEqualTo(FM_SPACING); + } + + @Test public void identifierToHalProgramIdentifier_withDabId() { ProgramIdentifier halDabId = ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_SID_EXT_ID); @@ -358,6 +396,13 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { } @Test + public void identifierFromHalProgramIdentifier_withInvalidIdentifier() { + expect.withMessage("Identifier converted from invalid HAL identifier") + .that(ConversionUtils.identifierFromHalProgramIdentifier(TEST_HAL_INVALID_ID)) + .isNull(); + } + + @Test public void programSelectorToHalProgramSelector_withValidSelector() { android.hardware.broadcastradio.ProgramSelector halDabSelector = ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR); @@ -370,6 +415,23 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { } @Test + public void programSelectorToHalProgramSelector_withInvalidSecondaryId() { + ProgramSelector dabSelector = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB, + TEST_DAB_SID_EXT_ID, new ProgramSelector.Identifier[]{TEST_INVALID_ID, + TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID}, /* vendorIds= */ null); + + android.hardware.broadcastradio.ProgramSelector halDabSelector = + ConversionUtils.programSelectorToHalProgramSelector(dabSelector); + + expect.withMessage("Primary identifier of converted HAL DAB selector with invalid " + + "secondary id").that(halDabSelector.primaryId) + .isEqualTo(TEST_HAL_DAB_SID_EXT_ID); + expect.withMessage("Secondary identifiers of converted HAL DAB selector with " + + "invalid secondary id").that(halDabSelector.secondaryIds).asList() + .containsExactly(TEST_HAL_DAB_FREQUENCY_ID, TEST_HAL_DAB_ENSEMBLE_ID); + } + + @Test public void programSelectorFromHalProgramSelector_withValidSelector() { android.hardware.broadcastradio.ProgramSelector halDabSelector = AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{ @@ -386,6 +448,33 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { } @Test + public void programSelectorFromHalProgramSelector_withInvalidSelector() { + android.hardware.broadcastradio.ProgramSelector invalidSelector = + AidlTestUtils.makeHalSelector(TEST_HAL_INVALID_ID, new ProgramIdentifier[]{}); + + expect.withMessage("Selector converted from invalid HAL selector") + .that(ConversionUtils.programSelectorFromHalProgramSelector(invalidSelector)) + .isNull(); + } + + @Test + public void programSelectorFromHalProgramSelector_withInvalidSecondaryId() { + android.hardware.broadcastradio.ProgramSelector halDabSelector = + AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{ + TEST_HAL_INVALID_ID, TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID}); + + ProgramSelector dabSelector = + ConversionUtils.programSelectorFromHalProgramSelector(halDabSelector); + + expect.withMessage("Primary identifier of converted DAB selector with invalid " + + "secondary id").that(dabSelector.getPrimaryId()) + .isEqualTo(TEST_DAB_SID_EXT_ID); + expect.withMessage("Secondary identifiers of converted DAB selector with invalid " + + "secondary id").that(dabSelector.getSecondaryIds()).asList() + .containsExactly(TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID); + } + + @Test public void programInfoFromHalProgramInfo_withValidProgramInfo() { android.hardware.broadcastradio.ProgramSelector halDabSelector = AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{ @@ -628,11 +717,41 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase { .that(Utils.getBand(/* freq= */ 110000)).isEqualTo(Utils.FrequencyBand.UNKNOWN); } - private static RadioManager.ModuleProperties convertToModuleProperties() { + @Test + public void filterToHalProgramFilter_withNullFilter() { + ProgramFilter filter = ConversionUtils.filterToHalProgramFilter(null); + + expect.withMessage("Filter identifier types").that(filter.identifierTypes) + .asList().isEmpty(); + expect.withMessage("Filter identifiers").that(filter.identifiers).asList() + .isEmpty(); + } + + @Test + public void filterToHalProgramFilter_withInvalidIdentifier() { + Set<ProgramSelector.Identifier> identifiers = + new ArraySet<ProgramSelector.Identifier>(2); + identifiers.add(TEST_INVALID_ID); + identifiers.add(TEST_DAB_SID_EXT_ID); + ProgramList.Filter filter = new ProgramList.Filter(/* identifierTypes */ new ArraySet<>(), + identifiers, /* includeCategories= */ true, /* excludeModifications= */ false); + ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(filter); + + expect.withMessage("Filter identifiers with invalid ones removed") + .that(halFilter.identifiers).asList().containsExactly( + ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_SID_EXT_ID)); + } + + private static RadioManager.ModuleProperties createModuleProperties() { AmFmRegionConfig amFmConfig = createAmFmRegionConfig(); DabTableEntry[] dabTableEntries = new DabTableEntry[]{ createDabTableEntry(DAB_ENTRY_LABEL_1, DAB_ENTRY_FREQUENCY_1), createDabTableEntry(DAB_ENTRY_LABEL_2, DAB_ENTRY_FREQUENCY_2)}; + return createModuleProperties(amFmConfig, dabTableEntries); + } + + private static RadioManager.ModuleProperties createModuleProperties( + AmFmRegionConfig amFmConfig, DabTableEntry[] dabTableEntries) { Properties properties = createHalProperties(); return ConversionUtils.propertiesFromHalProperties(TEST_ID, TEST_SERVICE_NAME, properties, diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java index 10ac05d66c62..a952bde956d8 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java @@ -16,13 +16,12 @@ package com.android.server.broadcastradio.aidl; -import static com.google.common.truth.Truth.assertWithMessage; - import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,9 +31,13 @@ import android.hardware.radio.Announcement; import android.hardware.radio.IAnnouncementListener; import android.hardware.radio.ICloseHandle; import android.hardware.radio.RadioManager; +import android.os.ParcelableException; import android.os.RemoteException; +import com.google.common.truth.Expect; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -50,6 +53,9 @@ public final class RadioModuleTest { private static final RadioManager.ModuleProperties TEST_MODULE_PROPERTIES = AidlTestUtils.makeDefaultModuleProperties(); + @Rule + public final Expect mExpect = Expect.create(); + // Mocks @Mock private IBroadcastRadio mBroadcastRadioMock; @@ -77,13 +83,13 @@ public final class RadioModuleTest { @Test public void getService() { - assertWithMessage("Service of radio module") + mExpect.withMessage("Service of radio module") .that(mRadioModule.getService()).isEqualTo(mBroadcastRadioMock); } @Test public void getProperties() { - assertWithMessage("Module properties of radio module") + mExpect.withMessage("Module properties of radio module") .that(mRadioModule.getProperties()).isEqualTo(TEST_MODULE_PROPERTIES); } @@ -93,7 +99,7 @@ public final class RadioModuleTest { Bitmap imageTest = mRadioModule.getImage(imageId); - assertWithMessage("Image from radio module").that(imageTest).isNull(); + mExpect.withMessage("Image from radio module").that(imageTest).isNull(); } @Test @@ -104,7 +110,7 @@ public final class RadioModuleTest { mRadioModule.getImage(invalidImageId); }); - assertWithMessage("Exception for getting image with invalid ID") + mExpect.withMessage("Exception for getting image with invalid ID") .that(thrown).hasMessageThat().contains("Image ID is missing"); } @@ -117,6 +123,18 @@ public final class RadioModuleTest { } @Test + public void addAnnouncementListener_whenHalThrowsRemoteException() throws Exception { + doThrow(new RuntimeException("HAL service died")).when(mBroadcastRadioMock) + .registerAnnouncementListener(any(), any()); + + ParcelableException thrown = assertThrows(ParcelableException.class, () -> + mRadioModule.addAnnouncementListener(mListenerMock, new int[]{TEST_ENABLED_TYPE})); + + mExpect.withMessage("Exception for adding announcement listener when HAL service died") + .that(thrown).hasMessageThat().contains("unknown error"); + } + + @Test public void onListUpdate_forAnnouncementListener() throws Exception { android.hardware.broadcastradio.Announcement halAnnouncement = AidlTestUtils.makeAnnouncement(TEST_ENABLED_TYPE, /* selectorFreq= */ 96300); 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 755bcdb7df20..4ded91d03579 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 @@ -421,6 +421,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test + public void tune_withClosedTuner_fails() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + mTunerSessions[0].close(); + + IllegalStateException thrown = assertThrows(IllegalStateException.class, + () -> mTunerSessions[0].tune(sel)); + + expect.withMessage("Exception for tuning on closed tuner").that(thrown).hasMessageThat() + .contains("Tuner is closed"); + } + + @Test public void step_withDirectionUp() throws Exception { long initFreq = AM_FM_FREQUENCY_LIST[1]; ProgramSelector initialSel = AidlTestUtils.makeFmSelector(initFreq); @@ -1149,6 +1162,20 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test + public void onCurrentProgramInfoChanged_withLowerSdkVersion_doesNotInvokesCallback() + throws Exception { + doReturn(false).when(() -> CompatChanges.isChangeEnabled( + eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt())); + openAidlClients(/* numClients= */ 1); + + mHalTunerCallback.onCurrentProgramInfoChanged( + AidlTestUtils.programInfoToHalProgramInfo(TEST_DAB_INFO)); + + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).never()) + .onCurrentProgramInfoChanged(any()); + } + + @Test public void onTuneFailed_forTunerCallback() throws Exception { int numSessions = 3; openAidlClients(numSessions); @@ -1165,6 +1192,20 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test + public void onTuneFailed_withLowerSdkVersion_doesNotInvokesCallback() + throws Exception { + doReturn(false).when(() -> CompatChanges.isChangeEnabled( + eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt())); + openAidlClients(/* numClients= */ 1); + + mHalTunerCallback.onTuneFailed(Result.CANCELED, + ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR)); + + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).never()) + .onTuneFailed(anyInt(), any()); + } + + @Test public void onAntennaStateChange_forTunerCallback() throws Exception { int numSessions = 3; openAidlClients(numSessions); @@ -1231,6 +1272,36 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } } + @Test + public void openSession_withNonNullAntennaState() throws Exception { + boolean antennaConnected = false; + android.hardware.radio.ITunerCallback callback = + mock(android.hardware.radio.ITunerCallback.class); + openAidlClients(/* numClients= */ 1); + mHalTunerCallback.onAntennaStateChange(antennaConnected); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onAntennaState(antennaConnected); + + mRadioModule.openSession(callback); + + verify(callback, CALLBACK_TIMEOUT).onAntennaState(antennaConnected); + } + + @Test + public void openSession_withNonNullCurrentProgramInfo() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + RadioManager.ProgramInfo tuneInfo = AidlTestUtils.makeProgramInfo(initialSel, + SIGNAL_QUALITY); + mTunerSessions[0].tune(initialSel); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); + android.hardware.radio.ITunerCallback callback = + mock(android.hardware.radio.ITunerCallback.class); + + mRadioModule.openSession(callback); + + verify(callback, CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); + } + private void openAidlClients(int numClients) throws Exception { mAidlTunerCallbackMocks = new android.hardware.radio.ITunerCallback[numClients]; mTunerSessions = new TunerSession[numClients]; diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java index 123e02c0a054..4cb012ca27db 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java @@ -21,7 +21,6 @@ import android.hardware.broadcastradio.V2_0.AmFmRegionConfig; import android.hardware.broadcastradio.V2_0.DabTableEntry; import android.hardware.broadcastradio.V2_0.IdentifierType; import android.hardware.broadcastradio.V2_0.Properties; -import android.hardware.broadcastradio.V2_0.VendorKeyValue; import android.hardware.radio.Announcement; import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; @@ -149,6 +148,26 @@ public final class ConvertTest { } @Test + public void propertiesFromHalProperties_withInvalidBand() { + AmFmRegionConfig amFmRegionConfig = new AmFmRegionConfig(); + amFmRegionConfig.ranges = new ArrayList<>(Arrays.asList(createAmFmBandRange( + /* lowerBound= */ 50000, /* upperBound= */ 60000, /* spacing= */ 10), + createAmFmBandRange(FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING))); + + RadioManager.ModuleProperties properties = convertToModuleProperties(amFmRegionConfig, + new ArrayList<>()); + + RadioManager.BandDescriptor[] bands = properties.getBands(); + expect.withMessage("Band descriptors").that(bands).hasLength(1); + expect.withMessage("FM band frequency lower limit") + .that(bands[0].getLowerLimit()).isEqualTo(FM_LOWER_LIMIT); + expect.withMessage("FM band frequency upper limit") + .that(bands[0].getUpperLimit()).isEqualTo(FM_UPPER_LIMIT); + expect.withMessage("FM band frequency spacing") + .that(bands[0].getSpacing()).isEqualTo(FM_SPACING); + } + + @Test public void announcementFromHalAnnouncement_typesMatch() { expect.withMessage("Announcement type") .that(ANNOUNCEMENT.getType()).isEqualTo(TEST_ENABLED_TYPE); @@ -184,15 +203,20 @@ public final class ConvertTest { List<DabTableEntry> dabTableEntries = Arrays.asList( createDabTableEntry(DAB_ENTRY_LABEL_1, DAB_ENTRY_FREQUENCY_1), createDabTableEntry(DAB_ENTRY_LABEL_2, DAB_ENTRY_FREQUENCY_2)); - Properties properties = createHalProperties(); + return convertToModuleProperties(amFmConfig, dabTableEntries); + } + + private static RadioManager.ModuleProperties convertToModuleProperties( + AmFmRegionConfig amFmConfig, List<DabTableEntry> dabTableEntries) { + Properties properties = createHalProperties(); return Convert.propertiesFromHal(TEST_ID, TEST_SERVICE_NAME, properties, amFmConfig, dabTableEntries); } private static AmFmRegionConfig createAmFmRegionConfig() { AmFmRegionConfig amFmRegionConfig = new AmFmRegionConfig(); - amFmRegionConfig.ranges = new ArrayList<AmFmBandRange>(Arrays.asList( + amFmRegionConfig.ranges = new ArrayList<>(Arrays.asList( createAmFmBandRange(FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING), createAmFmBandRange(AM_LOWER_LIMIT, AM_UPPER_LIMIT, AM_SPACING))); return amFmRegionConfig; @@ -222,7 +246,7 @@ public final class ConvertTest { halProperties.product = TEST_PRODUCT; halProperties.version = TEST_VERSION; halProperties.serial = TEST_SERIAL; - halProperties.vendorInfo = new ArrayList<VendorKeyValue>(Arrays.asList( + halProperties.vendorInfo = new ArrayList<>(Arrays.asList( TestUtils.makeVendorKeyValue(VENDOR_INFO_KEY_1, VENDOR_INFO_VALUE_1), TestUtils.makeVendorKeyValue(VENDOR_INFO_KEY_2, VENDOR_INFO_VALUE_2))); return halProperties; 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 6edfa0294fdd..898ef577629c 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 @@ -29,8 +29,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.google.common.truth.Truth.assertWithMessage; - import static org.junit.Assert.assertThrows; import android.graphics.Bitmap; @@ -57,8 +55,11 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; import com.android.server.broadcastradio.RadioServiceUserController; +import com.google.common.truth.Expect; + import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -98,6 +99,9 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { private ProgramInfo mHalCurrentInfo; private TunerSession[] mTunerSessions; + @Rule + public final Expect mExpect = Expect.create(); + @Mock private UserHandle mUserHandleMock; @Mock @@ -206,7 +210,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(numSessions); for (int index = 0; index < numSessions; index++) { - assertWithMessage("Session of index %s close state", index) + mExpect.withMessage("Session of index %s close state", index) .that(mTunerSessions[index].isClosed()).isFalse(); } } @@ -238,7 +242,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { RadioManager.BandConfig config = mTunerSessions[0].getConfiguration(); - assertWithMessage("Session configuration").that(config) + mExpect.withMessage("Session configuration").that(config) .isEqualTo(FM_BAND_CONFIG); } @@ -248,7 +252,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setMuted(/* mute= */ false); - assertWithMessage("Session mute state after setting unmuted") + mExpect.withMessage("Session mute state after setting unmuted") .that(mTunerSessions[0].isMuted()).isFalse(); } @@ -258,7 +262,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setMuted(/* mute= */ true); - assertWithMessage("Session mute state after setting muted") + mExpect.withMessage("Session mute state after setting muted") .that(mTunerSessions[0].isMuted()).isTrue(); } @@ -268,7 +272,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].close(); - assertWithMessage("Close state of broadcast radio service session") + mExpect.withMessage("Close state of broadcast radio service session") .that(mTunerSessions[0].isClosed()).isTrue(); } @@ -282,11 +286,11 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { for (int index = 0; index < numSessions; index++) { if (index == closeIdx) { - assertWithMessage( + mExpect.withMessage( "Close state of broadcast radio service session of index %s", index) .that(mTunerSessions[index].isClosed()).isTrue(); } else { - assertWithMessage( + mExpect.withMessage( "Close state of broadcast radio service session of index %s", index) .that(mTunerSessions[index].isClosed()).isFalse(); } @@ -301,7 +305,21 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].close(errorCode); verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onError(errorCode); - assertWithMessage("Close state of broadcast radio service session") + mExpect.withMessage("Close state of broadcast radio service session") + .that(mTunerSessions[0].isClosed()).isTrue(); + } + + @Test + public void close_forMultipleTimes() throws Exception { + openAidlClients(/* numClients= */ 1); + int errorCode = RadioTuner.ERROR_SERVER_DIED; + mTunerSessions[0].close(errorCode); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onError(errorCode); + + mTunerSessions[0].close(errorCode); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onError(errorCode); + mExpect.withMessage("State of closing broadcast radio service session twice") .that(mTunerSessions[0].isClosed()).isTrue(); } @@ -315,7 +333,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { for (int index = 0; index < numSessions; index++) { verify(mAidlTunerCallbackMocks[index], CALLBACK_TIMEOUT).onError(errorCode); - assertWithMessage("Close state of broadcast radio service session of index %s", index) + mExpect.withMessage("Close state of broadcast radio service session of index %s", index) .that(mTunerSessions[index].isClosed()).isTrue(); } } @@ -365,7 +383,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { UnsupportedOperationException thrown = assertThrows(UnsupportedOperationException.class, () -> mTunerSessions[0].tune(unsupportedSelector)); - assertWithMessage("Exception for tuning on unsupported program selector") + mExpect.withMessage("Exception for tuning on unsupported program selector") .that(thrown).hasMessageThat().contains("tune: NOT_SUPPORTED"); } @@ -393,11 +411,24 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].tune(sel); }); - assertWithMessage("Unknown error HAL exception when tuning") + mExpect.withMessage("Unknown error HAL exception when tuning") .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR)); } @Test + public void tune_withClosedTuner_fails() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramSelector sel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + mTunerSessions[0].close(); + + IllegalStateException thrown = assertThrows(IllegalStateException.class, + () -> mTunerSessions[0].tune(sel)); + + mExpect.withMessage("Exception for tuning on closed tuner").that(thrown).hasMessageThat() + .contains("Tuner is closed"); + } + + @Test public void step_withDirectionUp() throws Exception { long initFreq = AM_FM_FREQUENCY_LIST[1]; ProgramSelector initialSel = TestUtils.makeFmSelector(initFreq); @@ -454,7 +485,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); }); - assertWithMessage("Exception for stepping when HAL is in invalid state") + mExpect.withMessage("Exception for stepping when HAL is in invalid state") .that(thrown).hasMessageThat().contains(Result.toString(Result.INVALID_STATE)); } @@ -533,7 +564,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); }); - assertWithMessage("Internal error HAL exception when seeking") + mExpect.withMessage("Internal error HAL exception when seeking") .that(thrown).hasMessageThat().contains(Result.toString(Result.INTERNAL_ERROR)); } @@ -566,7 +597,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].cancel(); }); - assertWithMessage("Exception for canceling when HAL throws remote exception") + mExpect.withMessage("Exception for canceling when HAL throws remote exception") .that(thrown).hasMessageThat().contains(exceptionMessage); } @@ -579,7 +610,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].getImage(imageId); }); - assertWithMessage("Get image exception") + mExpect.withMessage("Get image exception") .that(thrown).hasMessageThat().contains("Image ID is missing"); } @@ -590,7 +621,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { Bitmap imageTest = mTunerSessions[0].getImage(imageId); - assertWithMessage("Null image").that(imageTest).isEqualTo(null); + mExpect.withMessage("Null image").that(imageTest).isEqualTo(null); } @Test @@ -603,7 +634,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].getImage(/* id= */ 1); }); - assertWithMessage("Exception for getting image when HAL throws remote exception") + mExpect.withMessage("Exception for getting image when HAL throws remote exception") .that(thrown).hasMessageThat().contains(exceptionMessage); } @@ -649,7 +680,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].startProgramListUpdates(/* filter= */ null); }); - assertWithMessage("Unknown error HAL exception when updating program list") + mExpect.withMessage("Unknown error HAL exception when updating program list") .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR)); } @@ -686,7 +717,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { boolean isSupported = mTunerSessions[0].isConfigFlagSupported(flag); verify(mHalTunerSessionMock).isConfigFlagSet(eq(flag), any()); - assertWithMessage("Config flag %s is supported", flag).that(isSupported).isFalse(); + mExpect.withMessage("Config flag %s is supported", flag).that(isSupported).isFalse(); } @Test @@ -697,7 +728,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { boolean isSupported = mTunerSessions[0].isConfigFlagSupported(flag); verify(mHalTunerSessionMock).isConfigFlagSet(eq(flag), any()); - assertWithMessage("Config flag %s is supported", flag).that(isSupported).isTrue(); + mExpect.withMessage("Config flag %s is supported", flag).that(isSupported).isTrue(); } @Test @@ -709,7 +740,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setConfigFlag(flag, /* value= */ true); }); - assertWithMessage("Exception for setting unsupported flag %s", flag) + mExpect.withMessage("Exception for setting unsupported flag %s", flag) .that(thrown).hasMessageThat().contains("setConfigFlag: NOT_SUPPORTED"); } @@ -755,7 +786,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].isConfigFlagSet(flag); }); - assertWithMessage("Exception for checking if unsupported flag %s is set", flag) + mExpect.withMessage("Exception for checking if unsupported flag %s is set", flag) .that(thrown).hasMessageThat().contains("isConfigFlagSet: NOT_SUPPORTED"); } @@ -768,7 +799,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { boolean isSet = mTunerSessions[0].isConfigFlagSet(flag); - assertWithMessage("Config flag %s is set", flag) + mExpect.withMessage("Config flag %s is set", flag) .that(isSet).isEqualTo(expectedConfigFlagValue); } @@ -782,7 +813,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].isConfigFlagSet(flag); }); - assertWithMessage("Exception for checking config flag when HAL throws remote exception") + mExpect.withMessage("Exception for checking config flag when HAL throws remote exception") .that(thrown).hasMessageThat().contains("Failed to check flag"); } @@ -822,7 +853,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setParameters(parametersSet); }); - assertWithMessage("Exception for setting parameters when HAL throws remote exception") + mExpect.withMessage("Exception for setting parameters when HAL throws remote exception") .that(thrown).hasMessageThat().contains(exceptionMessage); } @@ -848,7 +879,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].getParameters(parameterKeys); }); - assertWithMessage("Exception for getting parameters when HAL throws remote exception") + mExpect.withMessage("Exception for getting parameters when HAL throws remote exception") .that(thrown).hasMessageThat().contains(exceptionMessage); } @@ -894,6 +925,36 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } } + @Test + public void openSession_withNonNullAntennaState() throws Exception { + boolean antennaConnected = false; + android.hardware.radio.ITunerCallback callback = + mock(android.hardware.radio.ITunerCallback.class); + openAidlClients(/* numClients= */ 1); + mHalTunerCallback.onAntennaStateChange(antennaConnected); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onAntennaState(antennaConnected); + + mRadioModule.openSession(callback); + + verify(callback, CALLBACK_TIMEOUT).onAntennaState(antennaConnected); + } + + @Test + public void openSession_withNonNullCurrentProgramInfo() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, + SIGNAL_QUALITY); + mTunerSessions[0].tune(initialSel); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); + android.hardware.radio.ITunerCallback callback = + mock(android.hardware.radio.ITunerCallback.class); + + mRadioModule.openSession(callback); + + verify(callback, CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); + } + private void openAidlClients(int numClients) throws Exception { mAidlTunerCallbackMocks = new android.hardware.radio.ITunerCallback[numClients]; mTunerSessions = new TunerSession[numClients]; diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java index 5b77c5214dd9..077e8eea485b 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java @@ -446,6 +446,7 @@ final class ConversionUtils { sel.secondaryIds[i]); if (id == null) { Slogf.e(TAG, "invalid secondary id: %s", sel.secondaryIds[i]); + continue; } secondaryIdList.add(id); } diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java index 34bfa6cb2d46..02a9f0963e5f 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java @@ -304,10 +304,7 @@ final class Convert { private static boolean isEmpty( @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) { - if (sel.primaryId.type != 0) return false; - if (sel.primaryId.value != 0) return false; - if (!sel.secondaryIds.isEmpty()) return false; - return true; + return sel.primaryId.type == 0 && sel.primaryId.value == 0 && sel.secondaryIds.isEmpty(); } static @Nullable ProgramSelector programSelectorFromHal( |