Add exception and conversion tests for AIDL client

Unit tests when HAL throws exception and when non-current user calls
methods that modify HAL status were added for broadcast radio AIDL
HAL client. Also added tests for conversion utlis methods about
converting and checking SDK versions for program info and program
list chunk.

Bug: 241118988
Test: atest com.android.server.broadcastradio.aidl
Change-Id: I94c85f6bc4da374326530e46683c5375aa686c3b
This commit is contained in:
Weilin Xu
2022-12-16 23:42:19 +00:00
parent 43fccacbf3
commit 0555ea12e3
5 changed files with 432 additions and 58 deletions

View File

@@ -19,6 +19,7 @@ import android.hardware.broadcastradio.IdentifierType;
import android.hardware.broadcastradio.Metadata;
import android.hardware.broadcastradio.ProgramIdentifier;
import android.hardware.broadcastradio.ProgramInfo;
import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.VendorKeyValue;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
@@ -41,17 +42,18 @@ final class AidlTestUtils {
/* dabFrequencyTable= */ null, /* vendorInfo= */ null);
}
static RadioManager.ProgramInfo makeProgramInfo(ProgramSelector selector, int signalQuality) {
static RadioManager.ProgramInfo makeProgramInfo(ProgramSelector selector,
ProgramSelector.Identifier logicallyTunedTo,
ProgramSelector.Identifier physicallyTunedTo, int signalQuality) {
return new RadioManager.ProgramInfo(selector,
selector.getPrimaryId(), selector.getPrimaryId(), /* relatedContents= */ null,
logicallyTunedTo, physicallyTunedTo, /* relatedContents= */ null,
/* infoFlags= */ 0, signalQuality,
new RadioMetadata.Builder().build(), new ArrayMap<>());
}
static RadioManager.ProgramInfo makeProgramInfo(int programType,
ProgramSelector.Identifier identifier, int signalQuality) {
ProgramSelector selector = makeProgramSelector(programType, identifier);
return makeProgramInfo(selector, signalQuality);
static RadioManager.ProgramInfo makeProgramInfo(ProgramSelector selector, int signalQuality) {
return makeProgramInfo(selector, selector.getPrimaryId(), selector.getPrimaryId(),
signalQuality);
}
static ProgramIdentifier makeHalIdentifier(@IdentifierType int type, long value) {
@@ -87,21 +89,6 @@ final class AidlTestUtils {
return hwSelector;
}
static ProgramInfo programInfoToHalProgramInfo(RadioManager.ProgramInfo info) {
// Note that because ConversionUtils does not by design provide functions for all
// conversions, this function only copies fields that are set by makeProgramInfo().
ProgramInfo hwInfo = new ProgramInfo();
hwInfo.selector = ConversionUtils.programSelectorToHalProgramSelector(info.getSelector());
hwInfo.logicallyTunedTo =
ConversionUtils.identifierToHalProgramIdentifier(info.getLogicallyTunedTo());
hwInfo.physicallyTunedTo =
ConversionUtils.identifierToHalProgramIdentifier(info.getPhysicallyTunedTo());
hwInfo.signalQuality = info.getSignalStrength();
hwInfo.relatedContent = new ProgramIdentifier[]{};
hwInfo.metadata = new Metadata[]{};
return hwInfo;
}
static ProgramInfo makeHalProgramInfo(
android.hardware.broadcastradio.ProgramSelector hwSel, int hwSignalQuality) {
return makeHalProgramInfo(hwSel, hwSel.primaryId, hwSel.primaryId, hwSignalQuality);
@@ -121,6 +108,16 @@ final class AidlTestUtils {
return hwInfo;
}
static ProgramListChunk makeProgramListChunk(boolean purge, boolean complete,
ProgramInfo[] modified, ProgramIdentifier[] removed) {
ProgramListChunk halChunk = new ProgramListChunk();
halChunk.purge = purge;
halChunk.complete = complete;
halChunk.modified = modified;
halChunk.removed = removed;
return halChunk;
}
static VendorKeyValue makeVendorKeyValue(String vendorKey, String vendorValue) {
VendorKeyValue vendorKeyValue = new VendorKeyValue();
vendorKeyValue.key = vendorKey;

View File

@@ -172,6 +172,19 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
.that(thrown).hasMessageThat().contains("Cannot open session for non-current user");
}
@Test
public void openSession_withoutAudio_fails() throws Exception {
createBroadcastRadioService();
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
/* legacyConfig= */ null, /* withAudio= */ false, mTunerCallbackMock,
TARGET_SDK_VERSION));
assertWithMessage("Exception for opening session without audio")
.that(thrown).hasMessageThat().contains("not supported");
}
@Test
public void binderDied_forDeathRecipient() throws Exception {
createBroadcastRadioService();

View File

@@ -22,9 +22,11 @@ import android.hardware.broadcastradio.DabTableEntry;
import android.hardware.broadcastradio.IdentifierType;
import android.hardware.broadcastradio.ProgramIdentifier;
import android.hardware.broadcastradio.ProgramInfo;
import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.Properties;
import android.hardware.broadcastradio.VendorKeyValue;
import android.hardware.radio.Announcement;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.Build;
@@ -35,19 +37,20 @@ import org.junit.Rule;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
public final class ConversionUtilsTest {
private static final int FM_LOWER_LIMIT = 87500;
private static final int FM_UPPER_LIMIT = 108000;
private static final int FM_LOWER_LIMIT = 87_500;
private static final int FM_UPPER_LIMIT = 108_000;
private static final int FM_SPACING = 200;
private static final int AM_LOWER_LIMIT = 540;
private static final int AM_UPPER_LIMIT = 1700;
private static final int AM_UPPER_LIMIT = 1_700;
private static final int AM_SPACING = 10;
private static final String DAB_ENTRY_LABEL_1 = "5A";
private static final int DAB_ENTRY_FREQUENCY_1 = 174928;
private static final int DAB_ENTRY_FREQUENCY_1 = 174_928;
private static final String DAB_ENTRY_LABEL_2 = "12D";
private static final int DAB_ENTRY_FREQUENCY_2 = 229072;
private static final int DAB_ENTRY_FREQUENCY_2 = 229_072;
private static final String VENDOR_INFO_KEY_1 = "vendorKey1";
private static final String VENDOR_INFO_VALUE_1 = "vendorValue1";
private static final String VENDOR_INFO_KEY_2 = "vendorKey2";
@@ -62,7 +65,10 @@ public final class ConversionUtilsTest {
private static final int TEST_SIGNAL_QUALITY = 1;
private static final long TEST_DAB_DMB_SID_EXT_VALUE = 0xA000000111L;
private static final long TEST_DAB_ENSEMBLE_VALUE = 0x1001;
private static final long TEST_DAB_FREQUENCY_VALUE = 220352;
private static final long TEST_DAB_FREQUENCY_VALUE = 220_352;
private static final long TEST_FM_FREQUENCY_VALUE = 92_100;
private static final long TEST_VENDOR_ID_VALUE = 9_901;
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);
@@ -72,6 +78,13 @@ public final class ConversionUtilsTest {
private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
new ProgramSelector.Identifier(
ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY, TEST_DAB_FREQUENCY_VALUE);
private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
new ProgramSelector.Identifier(
ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, TEST_FM_FREQUENCY_VALUE);
private static final ProgramSelector.Identifier TEST_VENDOR_ID =
new ProgramSelector.Identifier(
ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, TEST_VENDOR_ID_VALUE);
private static final ProgramIdentifier TEST_HAL_DAB_SID_EXT_ID =
AidlTestUtils.makeHalIdentifier(IdentifierType.DAB_SID_EXT, TEST_DAB_DMB_SID_EXT_VALUE);
private static final ProgramIdentifier TEST_HAL_DAB_ENSEMBLE_ID =
@@ -79,6 +92,19 @@ public final class ConversionUtilsTest {
private static final ProgramIdentifier TEST_HAL_DAB_FREQUENCY_ID =
AidlTestUtils.makeHalIdentifier(IdentifierType.DAB_FREQUENCY_KHZ,
TEST_DAB_FREQUENCY_VALUE);
private static final ProgramIdentifier TEST_HAL_FM_FREQUENCY_ID =
AidlTestUtils.makeHalIdentifier(IdentifierType.AMFM_FREQUENCY_KHZ,
TEST_FM_FREQUENCY_VALUE);
private static final ProgramIdentifier TEST_HAL_VENDOR_ID =
AidlTestUtils.makeHalIdentifier(IdentifierType.VENDOR_START,
TEST_VENDOR_ID_VALUE);
private static final ProgramSelector TEST_DAB_SELECTOR = new ProgramSelector(
ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
/* vendorIds= */ null);
private static final ProgramSelector TEST_FM_SELECTOR =
AidlTestUtils.makeFmSelector(TEST_FM_FREQUENCY_VALUE);
private static final int TEST_ENABLED_TYPE = Announcement.TYPE_EMERGENCY;
private static final int TEST_ANNOUNCEMENT_FREQUENCY = FM_LOWER_LIMIT + FM_SPACING;
@@ -200,13 +226,8 @@ public final class ConversionUtilsTest {
@Test
public void programSelectorToHalProgramSelector_withValidSelector() {
ProgramSelector dabSelector = new ProgramSelector(
ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
new ProgramSelector.Identifier[]{TEST_DAB_ENSEMBLE_ID, TEST_DAB_FREQUENCY_ID},
new long[0]);
android.hardware.broadcastradio.ProgramSelector halDabSelector =
ConversionUtils.programSelectorToHalProgramSelector(dabSelector);
ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR);
expect.withMessage("Primary identifier of converted HAL DAB selector")
.that(halDabSelector.primaryId).isEqualTo(TEST_HAL_DAB_SID_EXT_ID);
@@ -297,26 +318,135 @@ public final class ConversionUtilsTest {
}
@Test
public void programSelectorMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
ProgramSelector dabSelector = new ProgramSelector(
ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
new ProgramSelector.Identifier[]{TEST_DAB_ENSEMBLE_ID, TEST_DAB_FREQUENCY_ID},
new long[0]);
public void chunkFromHalProgramListChunk_withValidChunk() {
boolean purge = false;
boolean complete = true;
android.hardware.broadcastradio.ProgramSelector halDabSelector =
AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
ProgramInfo halDabInfo = AidlTestUtils.makeHalProgramInfo(halDabSelector,
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,
new ProgramInfo[]{halDabInfo},
new ProgramIdentifier[]{TEST_HAL_VENDOR_ID, TEST_HAL_FM_FREQUENCY_ID});
expect.withMessage("Selector %s not meeting required SDK version", dabSelector)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(dabSelector,
ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk);
expect.withMessage("Purged state of the converted valid program list chunk")
.that(chunk.isPurge()).isEqualTo(purge);
expect.withMessage("Completion state of the converted valid program list chunk")
.that(chunk.isComplete()).isEqualTo(complete);
expect.withMessage("Modified program info in the converted valid program list chunk")
.that(chunk.getModified()).containsExactly(dabInfo);
expect.withMessage("Removed program ides in the converted valid program list chunk")
.that(chunk.getRemoved()).containsExactly(TEST_VENDOR_ID, TEST_FM_FREQUENCY_ID);
}
@Test
public void chunkFromHalProgramListChunk_withInvalidModifiedProgramInfo() {
boolean purge = true;
boolean complete = false;
android.hardware.broadcastradio.ProgramSelector halDabSelector =
AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
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,
new ProgramInfo[]{halDabInfo}, new ProgramIdentifier[]{TEST_HAL_FM_FREQUENCY_ID});
ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk);
expect.withMessage("Purged state of the converted invalid program list chunk")
.that(chunk.isPurge()).isEqualTo(purge);
expect.withMessage("Completion state of the converted invalid program list chunk")
.that(chunk.isComplete()).isEqualTo(complete);
expect.withMessage("Modified program info in the converted invalid program list chunk")
.that(chunk.getModified()).isEmpty();
expect.withMessage("Removed program ids in the converted invalid program list chunk")
.that(chunk.getRemoved()).containsExactly(TEST_FM_FREQUENCY_ID);
}
@Test
public void programSelectorMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
expect.withMessage("Selector %s without required SDK version", TEST_DAB_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_DAB_SELECTOR,
Build.VERSION_CODES.TIRAMISU)).isFalse();
}
@Test
public void programSelectorMeetsSdkVersionRequirement_withRequiredVersionId_returnsTrue() {
ProgramSelector fmSelector = AidlTestUtils.makeFmSelector(/* freq= */ 97100);
expect.withMessage("Selector %s meeting required SDK version", fmSelector)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(fmSelector,
expect.withMessage("Selector %s with required SDK version", TEST_FM_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_FM_SELECTOR,
Build.VERSION_CODES.TIRAMISU)).isTrue();
}
@Test
public void programInfoMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
RadioManager.ProgramInfo dabProgramInfo = AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR,
TEST_DAB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
expect.withMessage("Program info %s without required SDK version", dabProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(dabProgramInfo,
Build.VERSION_CODES.TIRAMISU)).isFalse();
}
@Test
public void programInfoMeetsSdkVersionRequirement_withRequiredVersionId_returnsTrue() {
RadioManager.ProgramInfo fmProgramInfo = AidlTestUtils.makeProgramInfo(TEST_FM_SELECTOR,
TEST_SIGNAL_QUALITY);
expect.withMessage("Program info %s with required SDK version", fmProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(fmProgramInfo,
Build.VERSION_CODES.TIRAMISU)).isTrue();
}
@Test
public void convertChunkToTargetSdkVersion_withLowerSdkVersion() {
RadioManager.ProgramInfo dabProgramInfo = AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR,
TEST_DAB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
RadioManager.ProgramInfo fmProgramInfo = AidlTestUtils.makeProgramInfo(TEST_FM_SELECTOR,
TEST_SIGNAL_QUALITY);
ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ true,
/* complete= */ true, Set.of(dabProgramInfo, fmProgramInfo),
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
Build.VERSION_CODES.TIRAMISU);
expect.withMessage(
"Purged state of the converted program list chunk with lower SDK version")
.that(convertedChunk.isPurge()).isEqualTo(chunk.isPurge());
expect.withMessage(
"Completion state of the converted program list chunk with lower SDK version")
.that(convertedChunk.isComplete()).isEqualTo(chunk.isComplete());
expect.withMessage(
"Modified program info in the converted program list chunk with lower SDK version")
.that(convertedChunk.getModified()).containsExactly(fmProgramInfo);
expect.withMessage(
"Removed program ids in the converted program list chunk with lower SDK version")
.that(convertedChunk.getRemoved())
.containsExactly(TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID);
}
@Test
public void convertChunkToTargetSdkVersion_withRequiredSdkVersion() {
RadioManager.ProgramInfo dabProgramInfo = AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR,
TEST_DAB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
RadioManager.ProgramInfo fmProgramInfo = AidlTestUtils.makeProgramInfo(TEST_FM_SELECTOR,
TEST_SIGNAL_QUALITY);
ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ true,
/* complete= */ true, Set.of(dabProgramInfo, fmProgramInfo),
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
Build.VERSION_CODES.CUR_DEVELOPMENT);
expect.withMessage("Converted program list chunk with required SDK version")
.that(convertedChunk).isEqualTo(chunk);
}
@Test
public void announcementFromHalAnnouncement_typesMatch() {
expect.withMessage("Announcement type")

View File

@@ -26,7 +26,9 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
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.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -43,6 +45,8 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.os.Build;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -57,7 +61,6 @@ 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;
@@ -71,10 +74,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
timeout(/* millis= */ 200);
private static final int SIGNAL_QUALITY = 1;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97500, 98100, 99100};
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
private static final RadioManager.FmBandDescriptor FM_BAND_DESCRIPTOR =
new RadioManager.FmBandDescriptor(RadioManager.REGION_ITU_1, RadioManager.BAND_FM,
/* lowerLimit= */ 87500, /* upperLimit= */ 108000, /* spacing= */ 100,
/* lowerLimit= */ 87_500, /* upperLimit= */ 108_000, /* spacing= */ 100,
/* stereo= */ false, /* rds= */ false, /* ta= */ false, /* af= */ false,
/* ea= */ false);
private static final RadioManager.BandConfig FM_BAND_CONFIG =
@@ -199,6 +202,17 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onConfigurationChanged(FM_BAND_CONFIG);
}
@Test
public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
.onConfigurationChanged(FM_BAND_CONFIG);
}
@Test
public void getConfiguration() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -365,7 +379,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
}
@Test
public void tune_forCurrentUser_doesNotTune() throws Exception {
public void tune_forNonCurrentUser_doesNotTune() throws Exception {
openAidlClients(/* numClients= */ 1);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
@@ -378,6 +392,21 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.onCurrentProgramInfoChanged(tuneInfo);
}
@Test
public void tune_withHalHasUnknownError_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
doThrow(new ServiceSpecificException(Result.UNKNOWN_ERROR))
.when(mBroadcastRadioMock).tune(any());
ParcelableException thrown = assertThrows(ParcelableException.class, () -> {
mTunerSessions[0].tune(sel);
});
assertWithMessage("Exception for tuning when HAL has unknown error")
.that(thrown).hasMessageThat().contains("UNKNOWN_ERROR");
}
@Test
public void step_withDirectionUp() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[1];
@@ -412,6 +441,35 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.onCurrentProgramInfoChanged(stepDownInfo);
}
@Test
public void step_forNonCurrentUser_doesNotStep() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[1];
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(initFreq);
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(
ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
.onCurrentProgramInfoChanged(any());
}
@Test
public void step_withHalInInvalidState_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
doThrow(new ServiceSpecificException(Result.INVALID_STATE))
.when(mBroadcastRadioMock).step(anyBoolean());
IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> {
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
});
assertWithMessage("Exception for stepping when HAL is in invalid state")
.that(thrown).hasMessageThat().contains("INVALID_STATE");
}
@Test
public void seek_withDirectionUp() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[2];
@@ -454,10 +512,43 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY);
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
.onCurrentProgramInfoChanged(seekUpInfo);
}
@Test
public void seek_forNonCurrentUser_doesNotSeek() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[2];
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(initFreq);
RadioManager.ProgramInfo seekUpInfo = AidlTestUtils.makeProgramInfo(
AidlTestUtils.makeFmSelector(getSeekFrequency(initFreq, /* seekDown= */ true)),
SIGNAL_QUALITY);
openAidlClients(/* numClients= */ 1);
mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(
ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
.onCurrentProgramInfoChanged(seekUpInfo);
}
@Test
public void seek_withHalHasInternalError_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
doThrow(new ServiceSpecificException(Result.INTERNAL_ERROR))
.when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
ParcelableException thrown = assertThrows(ParcelableException.class, () -> {
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
});
assertWithMessage("Exception for seeking when HAL has internal error")
.that(thrown).hasMessageThat().contains("INTERNAL_ERROR");
}
@Test
public void cancel() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -469,6 +560,32 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
verify(mBroadcastRadioMock).cancel();
}
@Test
public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
mTunerSessions[0].tune(initialSel);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].cancel();
verify(mBroadcastRadioMock, never()).cancel();
}
@Test
public void cancel_whenHalThrowsRemoteException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock).cancel();
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].cancel();
});
assertWithMessage("Exception for canceling when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test
public void getImage_withInvalidId_throwsIllegalArgumentException() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -492,6 +609,21 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
assertWithMessage("Null image").that(imageTest).isEqualTo(null);
}
@Test
public void getImage_whenHalThrowsException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
when(mBroadcastRadioMock.getImage(anyInt()))
.thenThrow(new RemoteException(exceptionMessage));
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getImage(/* id= */ 1);
});
assertWithMessage("Exception for getting image when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test
public void startBackgroundScan() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -501,6 +633,16 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onBackgroundScanComplete();
}
@Test
public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
openAidlClients(/* numClients= */ 1);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].startBackgroundScan();
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete();
}
@Test
public void stopProgramListUpdates() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -513,6 +655,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
verify(mBroadcastRadioMock).stopProgramListUpdates();
}
@Test
public void stopProgramListUpdates_forNonCurrentUser_doesNotStopUpdates() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
mTunerSessions[0].startProgramListUpdates(aidlFilter);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].stopProgramListUpdates();
verify(mBroadcastRadioMock, never()).stopProgramListUpdates();
}
@Test
public void isConfigFlagSupported_withUnsupportedFlag_returnsFalse() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -568,6 +723,17 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
verify(mBroadcastRadioMock).setConfigFlag(flag, /* value= */ false);
}
@Test
public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception {
openAidlClients(/* numClients= */ 1);
int flag = UNSUPPORTED_CONFIG_FLAG + 1;
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].setConfigFlag(flag, /* value= */ true);
verify(mBroadcastRadioMock, never()).setConfigFlag(flag, /* value= */ true);
}
@Test
public void isConfigFlagSet_withUnsupportedFlag_throwsRuntimeException()
throws Exception {
@@ -578,7 +744,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].isConfigFlagSet(flag);
});
assertWithMessage("Exception for check if unsupported flag %s is set", flag)
assertWithMessage("Exception for checking if unsupported flag %s is set", flag)
.that(thrown).hasMessageThat().contains("isConfigFlagSet: NOT_SUPPORTED");
}
@@ -595,6 +761,20 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.that(isSet).isEqualTo(expectedConfigFlagValue);
}
@Test
public void isConfigFlagSet_whenHalThrowsRemoteException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
int flag = UNSUPPORTED_CONFIG_FLAG + 1;
doThrow(new RemoteException()).when(mBroadcastRadioMock).isConfigFlagSet(anyInt());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].isConfigFlagSet(flag);
});
assertWithMessage("Exception for checking config flag when HAL throws remote exception")
.that(thrown).hasMessageThat().contains("Failed to check flag");
}
@Test
public void setParameters_withMockParameters() throws Exception {
openAidlClients(/* numClients= */ 1);
@@ -607,17 +787,59 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
ConversionUtils.vendorInfoToHalVendorKeyValues(parametersSet));
}
@Test
public void setParameters_forNonCurrentUser_doesNotSetParameters() throws Exception {
openAidlClients(/* numClients= */ 1);
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].setParameters(parametersSet);
verify(mBroadcastRadioMock, never()).setParameters(any());
}
@Test
public void setParameters_whenHalThrowsRemoteException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
String exceptionMessage = "HAL service died.";
when(mBroadcastRadioMock.setParameters(any()))
.thenThrow(new RemoteException(exceptionMessage));
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].setParameters(parametersSet);
});
assertWithMessage("Exception for setting parameters when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test
public void getParameters_withMockKeys() throws Exception {
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = new ArrayList<>(2);
parameterKeys.add("mockKey1");
parameterKeys.add("mockKey2");
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
mTunerSessions[0].getParameters(parameterKeys);
verify(mBroadcastRadioMock).getParameters(
parameterKeys.toArray(new String[0]));
verify(mBroadcastRadioMock).getParameters(parameterKeys.toArray(new String[0]));
}
@Test
public void getParameters_whenServiceThrowsRemoteException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
String exceptionMessage = "HAL service died.";
when(mBroadcastRadioMock.getParameters(any()))
.thenThrow(new RemoteException(exceptionMessage));
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getParameters(parameterKeys);
});
assertWithMessage("Exception for getting parameters when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@Test

View File

@@ -627,10 +627,22 @@ final class ConversionUtils {
if (isAtLeastU(targetSdkVersion)) {
return chunk;
}
Set<RadioManager.ProgramInfo> modified = chunk.getModified();
modified.removeIf(info -> !programInfoMeetsSdkVersionRequirement(info, targetSdkVersion));
Set<ProgramSelector.Identifier> removed = chunk.getRemoved();
removed.removeIf(id -> isNewIdentifierInU(id));
Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
Iterator<RadioManager.ProgramInfo> modifiedIterator = chunk.getModified().iterator();
while (modifiedIterator.hasNext()) {
RadioManager.ProgramInfo info = modifiedIterator.next();
if (programInfoMeetsSdkVersionRequirement(info, targetSdkVersion)) {
modified.add(info);
}
}
Set<ProgramSelector.Identifier> removed = new ArraySet<>();
Iterator<ProgramSelector.Identifier> removedIterator = chunk.getRemoved().iterator();
while (removedIterator.hasNext()) {
ProgramSelector.Identifier id = removedIterator.next();
if (!isNewIdentifierInU(id)) {
removed.add(id);
}
}
return new ProgramList.Chunk(chunk.isPurge(), chunk.isComplete(), modified, removed);
}