Add test for AIDL radio service program info cache
Added unit tests for program info cache of AIDL broadcast radio HAL client. Bug: 241118988 Test: com.android.server.broadcastradio.aidl Change-Id: I6796917f95644e4e606ef8bfeefdb9d6e7c05437
This commit is contained in:
@@ -121,8 +121,8 @@ final class AidlTestUtils {
|
||||
return hwInfo;
|
||||
}
|
||||
|
||||
static ProgramListChunk makeHalChunk(boolean purge, List<RadioManager.ProgramInfo> modified,
|
||||
List<ProgramSelector.Identifier> removed) {
|
||||
static ProgramListChunk makeHalChunk(boolean purge, boolean complete,
|
||||
List<RadioManager.ProgramInfo> modified, List<ProgramSelector.Identifier> removed) {
|
||||
ProgramInfo[] halModified =
|
||||
new android.hardware.broadcastradio.ProgramInfo[modified.size()];
|
||||
for (int i = 0; i < modified.size(); i++) {
|
||||
@@ -134,7 +134,7 @@ final class AidlTestUtils {
|
||||
for (int i = 0; i < removed.size(); i++) {
|
||||
halRemoved[i] = ConversionUtils.identifierToHalProgramIdentifier(removed.get(i));
|
||||
}
|
||||
return makeHalChunk(purge, /* complete= */ true, halModified, halRemoved);
|
||||
return makeHalChunk(purge, complete, halModified, halRemoved);
|
||||
}
|
||||
|
||||
static ProgramListChunk makeHalChunk(boolean purge, boolean complete,
|
||||
@@ -147,7 +147,7 @@ final class AidlTestUtils {
|
||||
return halChunk;
|
||||
}
|
||||
|
||||
static ProgramList.Chunk makeChunk(boolean purge,
|
||||
static ProgramList.Chunk makeChunk(boolean purge, boolean complete,
|
||||
List<RadioManager.ProgramInfo> modified,
|
||||
List<ProgramSelector.Identifier> removed) throws RemoteException {
|
||||
ArraySet<RadioManager.ProgramInfo> modifiedSet = new ArraySet<>();
|
||||
@@ -158,8 +158,7 @@ final class AidlTestUtils {
|
||||
if (removed != null) {
|
||||
removedSet.addAll(removed);
|
||||
}
|
||||
ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ purge, /* complete= */true,
|
||||
modifiedSet, removedSet);
|
||||
ProgramList.Chunk chunk = new ProgramList.Chunk(purge, complete, modifiedSet, removedSet);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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 com.android.server.broadcastradio.aidl;
|
||||
|
||||
import android.hardware.broadcastradio.ProgramIdentifier;
|
||||
import android.hardware.broadcastradio.ProgramInfo;
|
||||
import android.hardware.broadcastradio.ProgramListChunk;
|
||||
import android.hardware.radio.ProgramList;
|
||||
import android.hardware.radio.ProgramSelector;
|
||||
import android.hardware.radio.RadioManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.google.common.truth.Expect;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Unit tests for AIDL ProgramInfoCache
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ProgramInfoCacheTest {
|
||||
|
||||
private static final int TEST_SIGNAL_QUALITY = 90;
|
||||
|
||||
private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
|
||||
/* value= */ 88_500);
|
||||
private static final RadioManager.ProgramInfo TEST_FM_INFO = AidlTestUtils.makeProgramInfo(
|
||||
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
|
||||
TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, TEST_FM_FREQUENCY_ID,
|
||||
TEST_SIGNAL_QUALITY);
|
||||
private static final RadioManager.ProgramInfo TEST_FM_INFO_MODIFIED =
|
||||
AidlTestUtils.makeProgramInfo(AidlTestUtils.makeProgramSelector(
|
||||
ProgramSelector.PROGRAM_TYPE_FM, TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID,
|
||||
TEST_FM_FREQUENCY_ID, /* signalQuality= */ 99);
|
||||
|
||||
private static final ProgramSelector.Identifier TEST_AM_FREQUENCY_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
|
||||
/* value= */ 1_700);
|
||||
private static final RadioManager.ProgramInfo TEST_AM_INFO = AidlTestUtils.makeProgramInfo(
|
||||
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
|
||||
TEST_AM_FREQUENCY_ID), TEST_AM_FREQUENCY_ID, TEST_AM_FREQUENCY_ID,
|
||||
TEST_SIGNAL_QUALITY);
|
||||
|
||||
private static final ProgramSelector.Identifier TEST_RDS_PI_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
|
||||
/* value= */ 15_019);
|
||||
private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo(
|
||||
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID),
|
||||
TEST_RDS_PI_ID, new ProgramSelector.Identifier(
|
||||
ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 89_500),
|
||||
TEST_SIGNAL_QUALITY);
|
||||
|
||||
private static final ProgramSelector.Identifier TEST_DAB_DMB_SID_EXT_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
|
||||
/* value= */ 0xA000000111L);
|
||||
private static final ProgramSelector.Identifier TEST_DAB_ENSEMBLE_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
|
||||
/* value= */ 0x1001);
|
||||
private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
|
||||
/* value= */ 220_352);
|
||||
private static final RadioManager.ProgramInfo TEST_DAB_INFO = AidlTestUtils.makeProgramInfo(
|
||||
new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_DMB_SID_EXT_ID,
|
||||
new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
|
||||
/* vendorIds= */ null), TEST_DAB_DMB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID,
|
||||
TEST_SIGNAL_QUALITY);
|
||||
|
||||
private static final ProgramSelector.Identifier TEST_VENDOR_ID =
|
||||
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_VENDOR_START,
|
||||
/* value= */ 9_001);
|
||||
private static final RadioManager.ProgramInfo TEST_VENDOR_INFO = AidlTestUtils.makeProgramInfo(
|
||||
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_VENDOR_START,
|
||||
TEST_VENDOR_ID), TEST_VENDOR_ID, TEST_VENDOR_ID, TEST_SIGNAL_QUALITY);
|
||||
|
||||
private static final ProgramInfoCache FULL_PROGRAM_INFO_CACHE = new ProgramInfoCache(
|
||||
/* filter= */ null, /* complete= */ true,
|
||||
TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_VENDOR_INFO);
|
||||
|
||||
@Rule
|
||||
public final Expect expect = Expect.create();
|
||||
|
||||
@Test
|
||||
public void isComplete_forCompleteProgramInfoCache_returnsTrue() {
|
||||
expect.withMessage("Complete program info cache")
|
||||
.that(FULL_PROGRAM_INFO_CACHE.isComplete()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isComplete_forIncompleteProgramInfoCache_returnsFalse() {
|
||||
ProgramInfoCache programInfoCache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ false);
|
||||
expect.withMessage("Incomplete program info cache")
|
||||
.that(programInfoCache.isComplete()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFilter_forProgramInfoCache() {
|
||||
ProgramList.Filter fmFilter = new ProgramList.Filter(
|
||||
Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false);
|
||||
ProgramInfoCache fmProgramInfoCache = new ProgramInfoCache(fmFilter);
|
||||
|
||||
expect.withMessage("Program info cache filter")
|
||||
.that(fmProgramInfoCache.getFilter()).isEqualTo(fmFilter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateFromHalProgramListChunk_withPurgingCompleteChunk() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ false, TEST_FM_INFO);
|
||||
ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ true, /* complete= */ true,
|
||||
new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(TEST_RDS_INFO),
|
||||
AidlTestUtils.programInfoToHalProgramInfo(TEST_VENDOR_INFO)},
|
||||
new ProgramIdentifier[]{});
|
||||
|
||||
cache.updateFromHalProgramListChunk(chunk);
|
||||
|
||||
expect.withMessage("Program cache updated with purge-enabled and complete chunk")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_RDS_INFO, TEST_VENDOR_INFO);
|
||||
expect.withMessage("Complete program cache").that(cache.isComplete()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateFromHalProgramListChunk_withNonPurgingIncompleteChunk() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO);
|
||||
ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
/* complete= */ false,
|
||||
new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(TEST_FM_INFO_MODIFIED),
|
||||
AidlTestUtils.programInfoToHalProgramInfo(TEST_VENDOR_INFO)},
|
||||
new ProgramIdentifier[]{ConversionUtils.identifierToHalProgramIdentifier(
|
||||
TEST_RDS_PI_ID)});
|
||||
|
||||
cache.updateFromHalProgramListChunk(chunk);
|
||||
|
||||
expect.withMessage("Program cache updated with non-purging and incomplete chunk")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO, TEST_AM_INFO);
|
||||
expect.withMessage("Incomplete program cache").that(cache.isComplete()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withNullFilter() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ true);
|
||||
|
||||
cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
|
||||
|
||||
expect.withMessage("Program cache filtered by null filter")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
|
||||
TEST_VENDOR_INFO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withEmptyFilter() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
|
||||
new ArraySet<>(),
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false));
|
||||
|
||||
cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
|
||||
|
||||
expect.withMessage("Program cache filtered by empty filter")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
|
||||
TEST_VENDOR_INFO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withFilterByIdentifierType() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(
|
||||
new ProgramList.Filter(Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
|
||||
ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false));
|
||||
|
||||
cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
|
||||
|
||||
expect.withMessage("Program cache filtered by identifier type")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withFilterByIdentifier() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(
|
||||
new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID),
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false));
|
||||
int maxNumModifiedPerChunk = 2;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
|
||||
FULL_PROGRAM_INFO_CACHE, /* purge= */ true, maxNumModifiedPerChunk,
|
||||
maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Program cache filtered by identifier")
|
||||
.that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_DAB_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ true);
|
||||
verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
|
||||
TEST_DAB_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withFilterExcludingCategories() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
|
||||
new ArraySet<>(), /* includeCategories= */ false,
|
||||
/* excludeModifications= */ false));
|
||||
int maxNumModifiedPerChunk = 3;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
|
||||
FULL_PROGRAM_INFO_CACHE, /* purge= */ false, maxNumModifiedPerChunk,
|
||||
maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Program cache filtered by excluding categories")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ true);
|
||||
verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
|
||||
TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withFilterExcludingModifications() {
|
||||
ProgramList.Filter filterExcludingModifications = new ProgramList.Filter(new ArraySet<>(),
|
||||
new ArraySet<>(), /* includeCategories= */ true,
|
||||
/* excludeModifications= */ true);
|
||||
ProgramInfoCache cache = new ProgramInfoCache(filterExcludingModifications,
|
||||
/* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
|
||||
ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
|
||||
TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
|
||||
int maxNumModifiedPerChunk = 2;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
|
||||
/* purge= */ false, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Program cache filtered by excluding modifications")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO, TEST_VENDOR_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ false);
|
||||
verifyChunkListComplete(programListChunks, halCache.isComplete());
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_VENDOR_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
|
||||
TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndUpdateFromInternal_withPurge() {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
|
||||
new ArraySet<>(), /* includeCategories= */ true,
|
||||
/* excludeModifications= */ false),
|
||||
/* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO);
|
||||
ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
|
||||
TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
|
||||
int maxNumModifiedPerChunk = 2;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
|
||||
/* purge= */ true, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Purged program cache").that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ true);
|
||||
verifyChunkListComplete(programListChunks, halCache.isComplete());
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
|
||||
TEST_DAB_INFO, TEST_VENDOR_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndApplyChunkInternal_withPurgingIncompleteChunk() throws RemoteException {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ false, TEST_FM_INFO, TEST_DAB_INFO);
|
||||
ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO),
|
||||
List.of(TEST_DAB_DMB_SID_EXT_ID));
|
||||
int maxNumModifiedPerChunk = 2;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
|
||||
maxNumModifiedPerChunk, maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Program cache applied with non-purging and complete chunk")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ true);
|
||||
verifyChunkListComplete(programListChunks, /* complete= */ false);
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
|
||||
TEST_RDS_INFO, TEST_VENDOR_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterAndApplyChunk_withNonPurgingCompleteChunk() throws RemoteException {
|
||||
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
|
||||
/* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
|
||||
ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO),
|
||||
List.of(TEST_RDS_PI_ID, TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID));
|
||||
int maxNumModifiedPerChunk = 2;
|
||||
int maxNumRemovedPerChunk = 2;
|
||||
|
||||
List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
|
||||
maxNumModifiedPerChunk, maxNumRemovedPerChunk);
|
||||
|
||||
expect.withMessage("Program cache applied with purge-enabled complete chunk")
|
||||
.that(cache.toProgramInfoList())
|
||||
.containsExactly(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
|
||||
verifyChunkListPurge(programListChunks, /* purge= */ false);
|
||||
verifyChunkListComplete(programListChunks, /* complete= */ true);
|
||||
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
|
||||
TEST_VENDOR_INFO);
|
||||
verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
|
||||
TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
|
||||
}
|
||||
|
||||
private void verifyChunkListPurge(List<ProgramList.Chunk> chunks, boolean purge) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
ProgramList.Chunk chunk = chunks.get(i);
|
||||
boolean expectedPurge = (i == 0 && purge);
|
||||
|
||||
expect.withMessage("Purge for chunk %s", i)
|
||||
.that(chunk.isPurge()).isEqualTo(expectedPurge);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyChunkListComplete(List<ProgramList.Chunk> chunks, boolean complete) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
ProgramList.Chunk chunk = chunks.get(i);
|
||||
boolean expectedComplete = (i == chunks.size() - 1 && complete);
|
||||
|
||||
expect.withMessage("Purge for chunk %s", i)
|
||||
.that(chunk.isComplete()).isEqualTo(expectedComplete);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyChunkListModified(List<ProgramList.Chunk> chunks,
|
||||
int maxModifiedPerChunk, RadioManager.ProgramInfo... expectedProgramInfos) {
|
||||
if (chunks.isEmpty()) {
|
||||
expect.withMessage("Empty program info list")
|
||||
.that(expectedProgramInfos.length).isEqualTo(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ArraySet<RadioManager.ProgramInfo> actualSet = new ArraySet<>();
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
Set<RadioManager.ProgramInfo> chunkModified = chunks.get(i).getModified();
|
||||
actualSet.addAll(chunkModified);
|
||||
|
||||
expect.withMessage("Chunk %s modified program info array size", i)
|
||||
.that(chunkModified.size()).isAtMost(maxModifiedPerChunk);
|
||||
}
|
||||
expect.withMessage("Program info items")
|
||||
.that(actualSet).containsExactlyElementsIn(expectedProgramInfos);
|
||||
}
|
||||
|
||||
private void verifyChunkListRemoved(List<ProgramList.Chunk> chunks,
|
||||
int maxRemovedPerChunk, ProgramSelector.Identifier... expectedIdentifiers) {
|
||||
if (chunks.isEmpty()) {
|
||||
expect.withMessage("Empty program info list")
|
||||
.that(expectedIdentifiers.length).isEqualTo(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ArraySet<ProgramSelector.Identifier> actualSet = new ArraySet<>();
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
Set<ProgramSelector.Identifier> chunkRemoved = chunks.get(i).getRemoved();
|
||||
actualSet.addAll(chunkRemoved);
|
||||
|
||||
expect.withMessage("Chunk %s removed identifier array size ", i)
|
||||
.that(chunkRemoved.size()).isAtMost(maxRemovedPerChunk);
|
||||
}
|
||||
expect.withMessage("Removed identifier items")
|
||||
.that(actualSet).containsExactlyElementsIn(expectedIdentifiers);
|
||||
}
|
||||
}
|
||||
@@ -676,10 +676,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(filter);
|
||||
List<RadioManager.ProgramInfo> modified = List.of(TEST_FM_INFO, TEST_RDS_INFO);
|
||||
List<ProgramSelector.Identifier> removed = new ArrayList<>();
|
||||
ProgramListChunk halProgramList =
|
||||
AidlTestUtils.makeHalChunk(/* purge= */ true, modified, removed);
|
||||
ProgramListChunk halProgramList = AidlTestUtils.makeHalChunk(/* purge= */ true,
|
||||
/* complete= */ true, modified, removed);
|
||||
ProgramList.Chunk expectedProgramList =
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, modified, removed);
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modified, removed);
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(filter);
|
||||
mHalTunerCallback.onProgramListUpdated(halProgramList);
|
||||
@@ -696,17 +696,17 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false);
|
||||
mTunerSessions[0].startProgramListUpdates(filter);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED),
|
||||
List.of(TEST_RDS_PI_ID)));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -716,22 +716,22 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
/* includeCategories= */ true, /* excludeModifications= */ false);
|
||||
mTunerSessions[0].startProgramListUpdates(filter);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED),
|
||||
List.of(TEST_RDS_PI_ID)));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(filter);
|
||||
|
||||
verify(mBroadcastRadioMock).startProgramListUpdates(any());
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO_MODIFIED),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -740,19 +740,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mBroadcastRadioMock).startProgramListUpdates(any());
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED),
|
||||
List.of(TEST_RDS_PI_ID)));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -765,15 +765,15 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(idFilter);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_RDS_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any());
|
||||
}
|
||||
@@ -789,15 +789,15 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(filterExcludingModifications);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any());
|
||||
}
|
||||
@@ -813,19 +813,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
|
||||
mTunerSessions[0].startProgramListUpdates(filterIncludingModifications);
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, List.of(TEST_FM_INFO_MODIFIED),
|
||||
new ArrayList<>()));
|
||||
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
|
||||
List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -840,7 +840,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
verify(mBroadcastRadioMock).stopProgramListUpdates();
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any());
|
||||
}
|
||||
@@ -893,17 +893,18 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
|
||||
}
|
||||
|
||||
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
|
||||
|
||||
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
|
||||
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
|
||||
List.of(TEST_RDS_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
|
||||
verify(mAidlTunerCallbackMocks[1], CALLBACK_TIMEOUT)
|
||||
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
|
||||
List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
|
||||
verify(mAidlTunerCallbackMocks[2], CALLBACK_TIMEOUT)
|
||||
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
|
||||
List.of(TEST_RDS_INFO, TEST_FM_INFO), new ArrayList<>()));
|
||||
/* complete= */ true, List.of(TEST_RDS_INFO, TEST_FM_INFO),
|
||||
new ArrayList<>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -86,12 +86,8 @@ final class ProgramInfoCache {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean programInfosAreExactly(RadioManager.ProgramInfo... programInfos) {
|
||||
Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> expectedMap = new ArrayMap<>();
|
||||
for (int i = 0; i < programInfos.length; i++) {
|
||||
expectedMap.put(programInfos[i].getSelector().getPrimaryId(), programInfos[i]);
|
||||
}
|
||||
return expectedMap.equals(mProgramInfoMap);
|
||||
List<RadioManager.ProgramInfo> toProgramInfoList() {
|
||||
return new ArrayList<>(mProgramInfoMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user