diff options
| author | 2022-11-02 21:40:30 +0000 | |
|---|---|---|
| committer | 2022-11-03 18:24:09 +0000 | |
| commit | 1810a320c6fe7b74107d281f3d430d1c3a99ed09 (patch) | |
| tree | 2baf649f66d5b7df033a9bfe6c16a2e6d9f86a33 | |
| parent | bf06bafa98242071e6147ec5c2655567c66a6ac0 (diff) | |
Add unit tests for radio program list
Bug: 249602599
Test: atest android.hardware.radio.tests.unittests
Change-Id: Ia52d322ffc365be54096d3220a6b05f3fecbc207
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); |