summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Weilin Xu <xuweilin@google.com> 2022-11-02 21:40:30 +0000
committer Weilin Xu <xuweilin@google.com> 2022-11-03 18:24:09 +0000
commit1810a320c6fe7b74107d281f3d430d1c3a99ed09 (patch)
tree2baf649f66d5b7df033a9bfe6c16a2e6d9f86a33
parentbf06bafa98242071e6147ec5c2655567c66a6ac0 (diff)
Add unit tests for radio program list
Bug: 249602599 Test: atest android.hardware.radio.tests.unittests Change-Id: Ia52d322ffc365be54096d3220a6b05f3fecbc207
-rw-r--r--core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/ProgramListTest.java494
-rw-r--r--core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/TunerAdapterTest.java10
2 files changed, 504 insertions, 0 deletions
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/ProgramListTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/ProgramListTest.java
new file mode 100644
index 000000000000..27111004ae60
--- /dev/null
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/ProgramListTest.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.tests.unittests;
+
+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.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.hardware.radio.IRadioService;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.ProgramList;
+import android.hardware.radio.ProgramSelector;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioMetadata;
+import android.hardware.radio.RadioTuner;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.util.ArraySet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.verification.VerificationWithTimeout;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class ProgramListTest {
+
+ private static final int CREATOR_ARRAY_SIZE = 3;
+ private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(/* millis= */ 500);
+
+ private static final boolean IS_PURGE = false;
+ private static final boolean IS_COMPLETE = true;
+
+ private static final boolean INCLUDE_CATEGORIES = true;
+ private static final boolean EXCLUDE_MODIFICATIONS = false;
+
+ private static final ProgramSelector.Identifier FM_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ /* value= */ 94300);
+ private static final ProgramSelector.Identifier RDS_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI, 15019);
+ private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
+ /* value= */ 0x10000111);
+ private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1013);
+ private static final RadioManager.ProgramInfo FM_PROGRAM_INFO = createFmProgramInfo(
+ createProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, FM_IDENTIFIER));
+ private static final RadioManager.ProgramInfo RDS_PROGRAM_INFO = createFmProgramInfo(
+ createProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, RDS_IDENTIFIER));
+
+ private static final Set<Integer> FILTER_IDENTIFIER_TYPES = Set.of(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, ProgramSelector.IDENTIFIER_TYPE_RDS_PI);
+ private static final Set<ProgramSelector.Identifier> FILTER_IDENTIFIERS = Set.of(FM_IDENTIFIER);
+
+ private static final ProgramList.Chunk FM_RDS_ADD_CHUNK = new ProgramList.Chunk(IS_PURGE,
+ IS_COMPLETE, Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
+ Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+ private static final ProgramList.Chunk FM_ADD_INCOMPLETE_CHUNK = new ProgramList.Chunk(IS_PURGE,
+ /* complete= */ false, Set.of(FM_PROGRAM_INFO), new ArraySet<>());
+ private static final ProgramList.Filter TEST_FILTER = new ProgramList.Filter(
+ FILTER_IDENTIFIER_TYPES, FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+ private static final Map<String, String> VENDOR_FILTER = Map.of("testVendorKey1",
+ "testVendorValue1", "testVendorKey2", "testVendorValue2");
+
+ private final Executor mExecutor = new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ };
+
+ private RadioTuner mRadioTuner;
+ private ITunerCallback mTunerCallback;
+ private ProgramList mProgramList;
+
+ private ProgramList.ListCallback[] mListCallbackMocks;
+ private ProgramList.OnCompleteListener[] mOnCompleteListenerMocks;
+ @Mock
+ private IRadioService mRadioServiceMock;
+ @Mock
+ private Context mContextMock;
+ @Mock
+ private ITuner mTunerMock;
+ @Mock
+ private RadioTuner.Callback mTunerCallbackMock;
+
+ @Test
+ public void getIdentifierTypes_forFilter() {
+ ProgramList.Filter filter = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Filtered identifier types").that(filter.getIdentifierTypes())
+ .containsExactlyElementsIn(FILTER_IDENTIFIER_TYPES);
+ }
+
+ @Test
+ public void getIdentifiers_forFilter() {
+ ProgramList.Filter filter = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Filtered identifiers").that(filter.getIdentifiers())
+ .containsExactlyElementsIn(FILTER_IDENTIFIERS);
+ }
+
+ @Test
+ public void areCategoriesIncluded_forFilter() {
+ ProgramList.Filter filter = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Filter including categories")
+ .that(filter.areCategoriesIncluded()).isEqualTo(INCLUDE_CATEGORIES);
+ }
+
+ @Test
+ public void areModificationsExcluded_forFilter() {
+ ProgramList.Filter filter = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Filter excluding modifications")
+ .that(filter.areModificationsExcluded()).isEqualTo(EXCLUDE_MODIFICATIONS);
+ }
+
+ @Test
+ public void getVendorFilter_forFilterWithoutVendorFilter_returnsNull() {
+ ProgramList.Filter filter = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Filter vendor obtained from filter without vendor filter")
+ .that(filter.getVendorFilter()).isNull();
+ }
+
+ @Test
+ public void getVendorFilter_forFilterWithVendorFilter() {
+ ProgramList.Filter vendorFilter = new ProgramList.Filter(VENDOR_FILTER);
+
+ assertWithMessage("Filter vendor obtained from filter with vendor filter")
+ .that(vendorFilter.getVendorFilter()).isEqualTo(VENDOR_FILTER);
+ }
+
+ @Test
+ public void describeContents_forFilter() {
+ assertWithMessage("Filter contents").that(TEST_FILTER.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void hashCode_withTheSameFilters_equals() {
+ ProgramList.Filter filterCompared = new ProgramList.Filter(FILTER_IDENTIFIER_TYPES,
+ FILTER_IDENTIFIERS, INCLUDE_CATEGORIES, EXCLUDE_MODIFICATIONS);
+
+ assertWithMessage("Hash code of the same filter")
+ .that(filterCompared.hashCode()).isEqualTo(TEST_FILTER.hashCode());
+ }
+
+ @Test
+ public void hashCode_withDifferentFilters_notEquals() {
+ ProgramList.Filter filterCompared = new ProgramList.Filter();
+
+ assertWithMessage("Hash code of the different filter")
+ .that(filterCompared.hashCode()).isNotEqualTo(TEST_FILTER.hashCode());
+ }
+
+ @Test
+ public void writeToParcel_forFilter() {
+ Parcel parcel = Parcel.obtain();
+
+ TEST_FILTER.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+
+ ProgramList.Filter filterFromParcel =
+ ProgramList.Filter.CREATOR.createFromParcel(parcel);
+ assertWithMessage("Filter created from parcel")
+ .that(filterFromParcel).isEqualTo(TEST_FILTER);
+ }
+
+ @Test
+ public void newArray_forFilterCreator() {
+ ProgramList.Filter[] filters = ProgramList.Filter.CREATOR.newArray(CREATOR_ARRAY_SIZE);
+
+ assertWithMessage("Program filters").that(filters).hasLength(CREATOR_ARRAY_SIZE);
+ }
+
+ @Test
+ public void isPurge_forChunk() {
+ ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
+ Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
+ Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+
+ assertWithMessage("Puring chunk").that(chunk.isPurge()).isEqualTo(IS_PURGE);
+ }
+
+ @Test
+ public void isComplete_forChunk() {
+ ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
+ Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
+ Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+
+ assertWithMessage("Complete chunk").that(chunk.isComplete()).isEqualTo(IS_COMPLETE);
+ }
+
+ @Test
+ public void getModified_forChunk() {
+ ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
+ Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
+ Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+
+ assertWithMessage("Modified program info in chunk")
+ .that(chunk.getModified()).containsExactly(FM_PROGRAM_INFO, RDS_PROGRAM_INFO);
+ }
+
+ @Test
+ public void getRemoved_forChunk() {
+ ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
+ Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
+ Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+
+ assertWithMessage("Removed program identifiers in chunk").that(chunk.getRemoved())
+ .containsExactly(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER);
+ }
+
+ @Test
+ public void describeContents_forChunk() {
+ assertWithMessage("Chunk contents").that(FM_RDS_ADD_CHUNK.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void writeToParcel_forChunk() {
+ Parcel parcel = Parcel.obtain();
+
+ FM_RDS_ADD_CHUNK.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+
+ ProgramList.Chunk chunkFromParcel =
+ ProgramList.Chunk.CREATOR.createFromParcel(parcel);
+ assertWithMessage("Chunk created from parcel")
+ .that(chunkFromParcel).isEqualTo(FM_RDS_ADD_CHUNK);
+ }
+
+ @Test
+ public void newArray_forChunkCreator() {
+ ProgramList.Chunk[] chunks = ProgramList.Chunk.CREATOR.newArray(CREATOR_ARRAY_SIZE);
+
+ assertWithMessage("Chunks").that(chunks).hasLength(CREATOR_ARRAY_SIZE);
+ }
+
+ @Test
+ public void getDynamicProgramList_forTunerAdapter() throws Exception {
+ createRadioTuner();
+
+ mRadioTuner.getDynamicProgramList(TEST_FILTER);
+
+ verify(mTunerMock).startProgramListUpdates(TEST_FILTER);
+ }
+
+ @Test
+ public void getDynamicProgramList_forTunerAdapterWithServiceDied_throwsException()
+ throws Exception {
+ createRadioTuner();
+ doThrow(new RemoteException()).when(mTunerMock).startProgramListUpdates(any());
+
+ RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
+ mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ });
+
+ assertWithMessage("Exception for radio HAL client service died")
+ .that(thrown).hasMessageThat().contains("Service died");
+ }
+
+ @Test
+ public void onProgramListUpdated_withNewIdsAdded_invokesMockedCallbacks() throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+ addOnCompleteListeners(/* numListeners= */ 1);
+
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemChanged(FM_IDENTIFIER);
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemChanged(RDS_IDENTIFIER);
+ verify(mOnCompleteListenerMocks[0], CALLBACK_TIMEOUT).onComplete();
+ assertWithMessage("Program info in program list after adding FM and RDS info")
+ .that(mProgramList.toList()).containsExactly(FM_PROGRAM_INFO, RDS_PROGRAM_INFO);
+ }
+
+ @Test
+ public void onProgramListUpdated_withIdsRemoved_invokesMockedCallbacks() throws Exception {
+ ProgramList.Chunk fmRemovedChunk = new ProgramList.Chunk(/* purge= */ false,
+ /* complete= */ false, new ArraySet<>(), Set.of(FM_IDENTIFIER));
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ mTunerCallback.onProgramListUpdated(fmRemovedChunk);
+
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(FM_IDENTIFIER);
+ assertWithMessage("Program info in program list after removing FM id")
+ .that(mProgramList.toList()).containsExactly(RDS_PROGRAM_INFO);
+ assertWithMessage("Program info FM identifier")
+ .that(mProgramList.get(RDS_IDENTIFIER)).isEqualTo(RDS_PROGRAM_INFO);
+ }
+
+ @Test
+ public void onProgramListUpdated_withIncompleteChunk_notInvokesOnCompleteListener()
+ throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ addOnCompleteListeners(/* numListeners= */ 1);
+
+ mTunerCallback.onProgramListUpdated(FM_ADD_INCOMPLETE_CHUNK);
+
+ verify(mOnCompleteListenerMocks[0], CALLBACK_TIMEOUT.times(0)).onComplete();
+ }
+
+ @Test
+ public void onProgramListUpdated_withPurgeChunk() throws Exception {
+ ProgramList.Chunk purgeChunk = new ProgramList.Chunk(/* purge= */ true,
+ /* complete= */ true, new ArraySet<>(), new ArraySet<>());
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ mTunerCallback.onProgramListUpdated(purgeChunk);
+
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(FM_IDENTIFIER);
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(RDS_IDENTIFIER);
+ assertWithMessage("Program list after purge chunk applied")
+ .that(mProgramList.toList()).isEmpty();
+ }
+
+ @Test
+ public void registerListCallback_withExecutor() throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ ProgramList.ListCallback listCallbackMock = mock(ProgramList.ListCallback.class);
+
+ mProgramList.registerListCallback(mExecutor, listCallbackMock);
+ mTunerCallback.onProgramListUpdated(FM_ADD_INCOMPLETE_CHUNK);
+
+ verify(listCallbackMock, CALLBACK_TIMEOUT).onItemChanged(FM_IDENTIFIER);
+ }
+
+ @Test
+ public void onProgramListUpdated_withMultipleListCallBacks() throws Exception {
+ int numCallbacks = 3;
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(numCallbacks);
+
+ mTunerCallback.onProgramListUpdated(FM_ADD_INCOMPLETE_CHUNK);
+
+ for (int index = 0; index < numCallbacks; index++) {
+ verify(mListCallbackMocks[index], CALLBACK_TIMEOUT).onItemChanged(FM_IDENTIFIER);
+ }
+ }
+
+ @Test
+ public void unregisterListCallback_withProgramUpdated_notInvokesCallback() throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+
+ mProgramList.unregisterListCallback(mListCallbackMocks[0]);
+ mTunerCallback.onProgramListUpdated(FM_ADD_INCOMPLETE_CHUNK);
+
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onItemChanged(any());
+ }
+
+ @Test
+ public void addOnCompleteListener_withExecutor() throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ ProgramList.OnCompleteListener onCompleteListenerMock =
+ mock(ProgramList.OnCompleteListener.class);
+
+ mProgramList.addOnCompleteListener(mExecutor, onCompleteListenerMock);
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ verify(onCompleteListenerMock, CALLBACK_TIMEOUT).onComplete();
+ }
+
+ @Test
+ public void onProgramListUpdated_withMultipleOnCompleteListeners() throws Exception {
+ int numListeners = 3;
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ addOnCompleteListeners(numListeners);
+
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ for (int index = 0; index < numListeners; index++) {
+ verify(mOnCompleteListenerMocks[index], CALLBACK_TIMEOUT).onComplete();
+ }
+ }
+
+ @Test
+ public void removeOnCompleteListener_withProgramUpdated_notInvokesListener() throws Exception {
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ addOnCompleteListeners(/* numListeners= */ 1);
+
+ mProgramList.removeOnCompleteListener(mOnCompleteListenerMocks[0]);
+ mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+
+ verify(mOnCompleteListenerMocks[0], CALLBACK_TIMEOUT.times(0)).onComplete();
+ }
+
+ @Test
+ public void close_forProgramList_invokesStopProgramListUpdates() throws Exception {
+ createRadioTuner();
+ ProgramList programList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+
+ programList.close();
+
+ verify(mTunerMock, CALLBACK_TIMEOUT).stopProgramListUpdates();
+ }
+
+ private static ProgramSelector createProgramSelector(int programType,
+ ProgramSelector.Identifier identifier) {
+ return new ProgramSelector(programType, identifier, /* secondaryIds= */ null,
+ /* vendorIds= */ null);
+ }
+
+ private static RadioManager.ProgramInfo createFmProgramInfo(ProgramSelector selector) {
+ return new RadioManager.ProgramInfo(selector, selector.getPrimaryId(),
+ selector.getPrimaryId(), /* relatedContents= */ null, /* infoFlags= */ 0,
+ /* signalQuality= */ 1, new RadioMetadata.Builder().build(),
+ /* vendorInfo= */ null);
+ }
+
+ private void createRadioTuner() throws Exception {
+ RadioManager radioManager = new RadioManager(mContextMock, mRadioServiceMock);
+ RadioManager.BandConfig band = new RadioManager.FmBandConfig(
+ new RadioManager.FmBandDescriptor(RadioManager.REGION_ITU_1, RadioManager.BAND_FM,
+ /* lowerLimit= */ 87500, /* upperLimit= */ 108000, /* spacing= */ 200,
+ /* stereo= */ true, /* rds= */ false, /* ta= */ false, /* af= */ false,
+ /* es= */ false));
+
+ doAnswer(invocation -> {
+ mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
+ return mTunerMock;
+ }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
+
+ mRadioTuner = radioManager.openTuner(/* moduleId= */ 0, band,
+ /* withAudio= */ true, mTunerCallbackMock, /* handler= */ null);
+ }
+
+ private void registerListCallbacks(int numCallbacks) {
+ mListCallbackMocks = new ProgramList.ListCallback[numCallbacks];
+ for (int index = 0; index < numCallbacks; index++) {
+ mListCallbackMocks[index] = mock(ProgramList.ListCallback.class);
+ mProgramList.registerListCallback(mListCallbackMocks[index]);
+ }
+ }
+
+ private void addOnCompleteListeners(int numListeners) {
+ mOnCompleteListenerMocks = new ProgramList.OnCompleteListener[numListeners];
+ for (int index = 0; index < numListeners; index++) {
+ mOnCompleteListenerMocks[index] = mock(ProgramList.OnCompleteListener.class);
+ mProgramList.addOnCompleteListener(mOnCompleteListenerMocks[index]);
+ }
+ }
+}
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/TunerAdapterTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/TunerAdapterTest.java
index fe3ab625bacc..bdba6a1c5402 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/TunerAdapterTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/TunerAdapterTest.java
@@ -280,6 +280,16 @@ public final class TunerAdapterTest {
}
@Test
+ public void startBackgroundScan_forTunerAdapter() throws Exception {
+ when(mTunerMock.startBackgroundScan()).thenReturn(false);
+
+ boolean scanStatus = mRadioTuner.startBackgroundScan();
+
+ verify(mTunerMock).startBackgroundScan();
+ assertWithMessage("Status for starting background scan").that(scanStatus).isFalse();
+ }
+
+ @Test
public void isAnalogForced_forTunerAdapter() throws Exception {
when(mTunerMock.isConfigFlagSet(RadioManager.CONFIG_FORCE_ANALOG)).thenReturn(true);