Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8644138d authored by Weilin Xu's avatar Weilin Xu
Browse files

Improve code coverage for broadcast radio

Added missing unit tests for radio manager, AnnouncementAggregator,
and ProgramInfoCache in broadcast radio service. Also fixed the wrong
returned result for isConfigFlagSupported during illegal state for
HAL 2 broadcast radio client, and refactored the broadcast radio
service to improve code coverage.

Bug: 282031772
Test: atest BroadcastRadioTests
Flag: TEST_ONLY
Change-Id: Ibff9586844f5fa2babec4a43e044332a1cb157c9
parent ac798271
Loading
Loading
Loading
Loading
+153 −136

File changed.

Preview size limit exceeded, changes collapsed.

+22 −4
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@

package com.android.server.broadcastradio.aidl;

import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -33,7 +33,10 @@ import android.hardware.radio.ICloseHandle;
import android.os.IBinder;
import android.os.RemoteException;

import com.google.common.truth.Expect;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -54,6 +57,9 @@ public final class AnnouncementAggregatorTest {
    private AnnouncementAggregator mAnnouncementAggregator;
    private IBinder.DeathRecipient mDeathRecipient;

    @Rule
    public final Expect mExpect = Expect.create();

    @Mock
    private IAnnouncementListener mListenerMock;
    @Mock
@@ -74,6 +80,18 @@ public final class AnnouncementAggregatorTest {
        mDeathRecipient = deathRecipientCaptor.getValue();
    }

    @Test
    public void constructor_withBinderDied() throws Exception {
        RemoteException remoteException = new RemoteException("Binder is died");
        doThrow(remoteException).when(mBinderMock).linkToDeath(any(), anyInt());

        RuntimeException thrown = assertThrows(RuntimeException.class, () ->
                new AnnouncementAggregator(mListenerMock, mLock));

        mExpect.withMessage("Exception for dead binder").that(thrown).hasMessageThat()
                .contains(remoteException.getMessage());
    }

    @Test
    public void onListUpdated_withOneModuleWatcher() throws Exception {
        ArgumentCaptor<IAnnouncementListener> moduleWatcherCaptor =
@@ -103,7 +121,7 @@ public final class AnnouncementAggregatorTest {
            moduleWatcherCaptor.getValue().onListUpdated(Arrays.asList(mAnnouncementMocks[index]));

            verify(mListenerMock, times(index + 1)).onListUpdated(announcementsCaptor.capture());
            assertWithMessage("Number of announcements %s after %s announcements were updated",
            mExpect.withMessage("Number of announcements %s after %s announcements were updated",
                    announcementsCaptor.getValue(), index + 1)
                    .that(announcementsCaptor.getValue().size()).isEqualTo(index + 1);
        }
@@ -131,7 +149,7 @@ public final class AnnouncementAggregatorTest {
                () -> mAnnouncementAggregator.watchModule(mRadioModuleMocks[0],
                        TEST_ENABLED_TYPES));

        assertWithMessage("Exception for watching module after aggregator has been closed")
        mExpect.withMessage("Exception for watching module after aggregator has been closed")
                .that(thrown).hasMessageThat()
                .contains("announcement aggregator has already been closed");
    }
+6 −0
Original line number Diff line number Diff line
@@ -622,6 +622,12 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
                .isEqualTo(TEST_ALBUM_ART);
    }

    @Test
    public void getBands_withInvalidFrequency() {
        expect.withMessage("Band for invalid frequency")
                .that(Utils.getBand(/* freq= */ 110000)).isEqualTo(Utils.FrequencyBand.UNKNOWN);
    }

    private static RadioManager.ModuleProperties convertToModuleProperties() {
        AmFmRegionConfig amFmConfig = createAmFmRegionConfig();
        DabTableEntry[] dabTableEntries = new DabTableEntry[]{
+23 −0
Original line number Diff line number Diff line
@@ -440,6 +440,29 @@ public class ProgramInfoCacheTest {
                TEST_DAB_UNIQUE_ID_ALTERNATIVE);
    }

    @Test
    public void filterAndApplyChunkInternal_withInvalidProgramInfoAndIdentifiers()
            throws RemoteException {
        ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
                /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
        ProgramInfo[] halModified = new android.hardware.broadcastradio.ProgramInfo[1];
        halModified[0] = AidlTestUtils.makeHalProgramInfo(
                ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR_ALTERNATIVE),
                ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
                ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
                TEST_SIGNAL_QUALITY);
        ProgramIdentifier[] halRemoved = new android.hardware.broadcastradio.ProgramIdentifier[1];
        halRemoved[0] = new android.hardware.broadcastradio.ProgramIdentifier();
        ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
                /* complete= */ true, halModified, halRemoved);

        List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
                TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);

        expect.withMessage("Program list chunk applied with invalid program and identifiers")
                .that(programListChunks).isEmpty();
    }

    private void verifyChunkListPurge(List<ProgramList.Chunk> chunks, boolean purge) {
        if (chunks.isEmpty()) {
            return;
+23 −4
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@

package com.android.server.broadcastradio.hal2;

import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -33,7 +33,10 @@ import android.hardware.radio.ICloseHandle;
import android.os.IBinder;
import android.os.RemoteException;

import com.google.common.truth.Expect;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -55,6 +58,9 @@ public final class AnnouncementAggregatorHidlTest {
    private AnnouncementAggregator mAnnouncementAggregator;
    private IBinder.DeathRecipient mDeathRecipient;

    @Rule
    public final Expect mExpect = Expect.create();

    @Mock
    private IAnnouncementListener mListenerMock;
    @Mock
@@ -75,6 +81,19 @@ public final class AnnouncementAggregatorHidlTest {
        mDeathRecipient = deathRecipientCaptor.getValue();
    }

    @Test
    public void constructor_withBinderDied() throws Exception {
        RemoteException remoteException = new RemoteException("Binder is died");
        doThrow(remoteException).when(mBinderMock).linkToDeath(any(), anyInt());

        RuntimeException thrown = assertThrows(RuntimeException.class,
                () -> new com.android.server.broadcastradio.aidl.AnnouncementAggregator(
                        mListenerMock, mLock));

        mExpect.withMessage("Exception for dead binder").that(thrown).hasMessageThat()
                .contains(remoteException.getMessage());
    }

    @Test
    public void onListUpdated_withOneModuleWatcher() throws Exception {
        ArgumentCaptor<IAnnouncementListener> moduleWatcherCaptor =
@@ -104,7 +123,7 @@ public final class AnnouncementAggregatorHidlTest {
            moduleWatcherCaptor.getValue().onListUpdated(Arrays.asList(mAnnouncementMocks[index]));

            verify(mListenerMock, times(index + 1)).onListUpdated(announcementsCaptor.capture());
            assertWithMessage("Number of announcements %s after %s announcements were updated",
            mExpect.withMessage("Number of announcements %s after %s announcements were updated",
                    announcementsCaptor.getValue(), index + 1)
                    .that(announcementsCaptor.getValue().size()).isEqualTo(index + 1);
        }
@@ -132,7 +151,7 @@ public final class AnnouncementAggregatorHidlTest {
                () -> mAnnouncementAggregator.watchModule(mRadioModuleMocks[0],
                        TEST_ENABLED_TYPES));

        assertWithMessage("Exception for watching module after aggregator has been closed")
        mExpect.withMessage("Exception for watching module after aggregator has been closed")
                .that(thrown).hasMessageThat()
                .contains("announcement aggregator has already been closed");
    }
Loading