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

Commit 0f7dff24 authored by Weilin Xu's avatar Weilin Xu
Browse files

Add unit test for IRadioService implementation

Unit tests are added to test BrodacastRadioService implementation.
Mockito library and debuggable setting in manifest file are
modified to supoort mocking final classes and non-public methods.

Bug: 241118988
Test: atest com.android.server.broadcastradio
Change-Id: I2f664ded7ccbcb17e1de6363db6833ea7b3e7a53
parent 2d1f4371
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -23,23 +23,32 @@ package {

android_test {
    name: "BroadcastRadioTests",
    srcs: ["src/**/*.java"],
    privileged: true,
    certificate: "platform",
    // TODO(b/13282254): uncomment when b/13282254 is fixed
    // sdk_version: "current"
    platform_apis: true,
    static_libs: [
        "compatibility-device-util-axt",
        "androidx.test.rules",
        "testng",
        "services.core",
    ],
    libs: ["android.test.base"],
    srcs: ["src/**/*.java"],
    dex_preopt: {
        enabled: false,
    },
    optimize: {
        enabled: false,
    },
    static_libs: [
        "services.core",
        "androidx.test.rules",
        "truth-prebuilt",
        "testng",
        "mockito-target-extended",
    ],
    libs: ["android.test.base"],
    test_suites: [
        "general-tests",
    ],
    // mockito-target-inline dependency
    jni_libs: [
        "libcarservicejni",
        "libdexmakerjvmtiagent",
    ],
}
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@

    <uses-permission android:name="android.permission.ACCESS_BROADCAST_RADIO" />

    <application>
    <application android:debuggable="true">
        <uses-library android:name="android.test.runner" />
    </application>

+2 −4
Original line number Diff line number Diff line
@@ -33,11 +33,9 @@ import android.content.pm.PackageManager;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
@@ -47,6 +45,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.ArrayList;
import java.util.HashMap;
@@ -56,8 +55,7 @@ import java.util.Map;
/**
 * A test for broadcast radio API.
 */
@RunWith(AndroidJUnit4.class)
@MediumTest
@RunWith(MockitoJUnitRunner.class)
public class RadioTunerTest {
    private static final String TAG = "BroadcastRadioTests.RadioTuner";

+109 −0
Original line number Diff line number Diff line
/*
 * 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;

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

import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.hardware.radio.Announcement;
import android.hardware.radio.IAnnouncementListener;
import android.hardware.radio.ICloseHandle;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;

import com.android.server.broadcastradio.aidl.BroadcastRadioServiceImpl;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Arrays;

/**
 * Tests for {@link android.hardware.radio.IRadioService} with AIDL HAL implementation
 */
@RunWith(MockitoJUnitRunner.class)
public final class IRadioServiceAidlImplTest {

    private static final int[] ENABLE_TYPES = new int[]{Announcement.TYPE_TRAFFIC};

    private IRadioServiceAidlImpl mAidlImpl;

    @Mock
    private BroadcastRadioService mServiceMock;
    @Mock
    private BroadcastRadioServiceImpl mHalMock;
    @Mock
    private RadioManager.ModuleProperties mModuleMock;
    @Mock
    private RadioManager.BandConfig mBandConfigMock;
    @Mock
    private ITunerCallback mTunerCallbackMock;
    @Mock
    private IAnnouncementListener mListenerMock;
    @Mock
    private ICloseHandle mICloseHandle;
    @Mock
    private ITuner mTunerMock;

    @Before
    public void setUp() throws Exception {
        doNothing().when(mServiceMock).enforcePolicyAccess();

        when(mHalMock.listModules()).thenReturn(Arrays.asList(mModuleMock));
        when(mHalMock.openSession(anyInt(), any(), anyBoolean(), any()))
                .thenReturn(mTunerMock);
        when(mHalMock.addAnnouncementListener(any(), any())).thenReturn(mICloseHandle);

        mAidlImpl = new IRadioServiceAidlImpl(mServiceMock, mHalMock);
    }

    @Test
    public void loadModules_forAidlImpl() {
        assertWithMessage("Modules loaded in AIDL HAL")
                .that(mAidlImpl.listModules())
                .containsExactly(mModuleMock);
    }

    @Test
    public void openTuner_forAidlImpl() throws Exception {
        ITuner tuner = mAidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
                /* withAudio= */ true, mTunerCallbackMock);

        assertWithMessage("Tuner opened in AIDL HAL")
                .that(tuner).isEqualTo(mTunerMock);
    }

    @Test
    public void addAnnouncementListener_forAidlImpl() {
        ICloseHandle closeHandle = mAidlImpl.addAnnouncementListener(ENABLE_TYPES, mListenerMock);

        verify(mHalMock).addAnnouncementListener(ENABLE_TYPES, mListenerMock);
        assertWithMessage("Close handle of announcement listener for HAL 2")
                .that(closeHandle).isEqualTo(mICloseHandle);
    }

}
+131 −0
Original line number Diff line number Diff line
/*
 * 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;

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

import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.hardware.radio.Announcement;
import android.hardware.radio.IAnnouncementListener;
import android.hardware.radio.ICloseHandle;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Arrays;

/**
 * Tests for {@link android.hardware.radio.IRadioService} with HIDL HAL implementation
 */
@RunWith(MockitoJUnitRunner.class)
public final class IRadioServiceHidlImplTest {

    private static final int HAL1_MODULE_ID = 0;
    private static final int[] ENABLE_TYPES = new int[]{Announcement.TYPE_TRAFFIC};

    private IRadioServiceHidlImpl mHidlImpl;

    @Mock
    private BroadcastRadioService mServiceMock;
    @Mock
    private com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1Mock;
    @Mock
    private com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2Mock;
    @Mock
    private RadioManager.ModuleProperties mHal1ModuleMock;
    @Mock
    private RadioManager.ModuleProperties mHal2ModuleMock;
    @Mock
    private RadioManager.BandConfig mBandConfigMock;
    @Mock
    private ITunerCallback mTunerCallbackMock;
    @Mock
    private IAnnouncementListener mListenerMock;
    @Mock
    private ICloseHandle mICloseHandle;
    @Mock
    private ITuner mHal1TunerMock;
    @Mock
    private ITuner mHal2TunerMock;

    @Before
    public void setup() throws Exception {
        doNothing().when(mServiceMock).enforcePolicyAccess();
        when(mHal1Mock.loadModules()).thenReturn(Arrays.asList(mHal1ModuleMock));
        when(mHal1Mock.openTuner(anyInt(), any(), anyBoolean(), any())).thenReturn(mHal1TunerMock);

        when(mHal2Mock.listModules()).thenReturn(Arrays.asList(mHal2ModuleMock));
        doAnswer(invocation -> {
            int moduleId = (int) invocation.getArguments()[0];
            return moduleId != HAL1_MODULE_ID;
        }).when(mHal2Mock).hasModule(anyInt());
        when(mHal2Mock.openSession(anyInt(), any(), anyBoolean(), any()))
                .thenReturn(mHal2TunerMock);
        when(mHal2Mock.addAnnouncementListener(any(), any())).thenReturn(mICloseHandle);

        mHidlImpl = new IRadioServiceHidlImpl(mServiceMock, mHal1Mock, mHal2Mock);
    }

    @Test
    public void loadModules_forHidlImpl() {
        assertWithMessage("Modules loaded in HIDL HAL")
                .that(mHidlImpl.listModules())
                .containsExactly(mHal1ModuleMock, mHal2ModuleMock);
    }

    @Test
    public void openTuner_withHal1ModuleId_forHidlImpl() throws Exception {
        ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID, mBandConfigMock,
                /* withAudio= */ true, mTunerCallbackMock);

        assertWithMessage("Tuner opened in HAL 1")
                .that(tuner).isEqualTo(mHal1TunerMock);
    }

    @Test
    public void openTuner_withHal2ModuleId_forHidlImpl() throws Exception {
        ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID + 1, mBandConfigMock,
                /* withAudio= */ true, mTunerCallbackMock);

        assertWithMessage("Tuner opened in HAL 2")
                .that(tuner).isEqualTo(mHal2TunerMock);
    }

    @Test
    public void addAnnouncementListener_forHidlImpl() {
        when(mHal2Mock.hasAnyModules()).thenReturn(true);
        ICloseHandle closeHandle = mHidlImpl.addAnnouncementListener(ENABLE_TYPES, mListenerMock);

        verify(mHal2Mock).addAnnouncementListener(ENABLE_TYPES, mListenerMock);
        assertWithMessage("Close handle of announcement listener for HAL 2")
                .that(closeHandle).isEqualTo(mICloseHandle);
    }

}
Loading