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

Commit c0b7cdc4 authored by Weilin Xu's avatar Weilin Xu
Browse files

Add SDK version checking in AIDL radio HAL client

The target SDK version checking was added in AIDL broadcast radio
HAL to guarantee that broadcast radio HAL can pass object including
new HAL features to the application only when the application has
a target SDK version at least the SDK version with the new features.
If the application SDK version is lower, the program selectors and
program infos will not be sent back to applications if they contain
features only existing in higher SDK version, and items only
existing in higher version will be removed from the chunk before
sending back to applications.

HIDL 1.x and 2.0 HAL clients were not updated with SDK version
since new broadcast radio HAL features are no longer landed in
them.

Bug: 257337458
Test: atest android.hardware.radio.tests.unittests
Test: atest com.android.server.broadcastradio
Change-Id: Ia716353d9c796c5dc5f5218d33fd20a129a5370a
parent 81f50685
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ interface IRadioService {
    List<RadioManager.ModuleProperties> listModules();

    ITuner openTuner(int moduleId, in RadioManager.BandConfig bandConfig, boolean withAudio,
            in ITunerCallback callback);
            in ITunerCallback callback, int targetSdkVersion);

    ICloseHandle addAnnouncementListener(in int[] enabledTypes,
            in IAnnouncementListener listener);
+3 −1
Original line number Diff line number Diff line
@@ -1796,7 +1796,7 @@ public class RadioManager {
        ITuner tuner;
        TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
        try {
            tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
            tuner = mService.openTuner(moduleId, config, withAudio, halCallback, mTargetSdkVersion);
        } catch (RemoteException | IllegalArgumentException | IllegalStateException ex) {
            Log.e(TAG, "Failed to open tuner", ex);
            return null;
@@ -1873,6 +1873,7 @@ public class RadioManager {

    @NonNull private final Context mContext;
    @NonNull private final IRadioService mService;
    private final int mTargetSdkVersion;

    /**
     * @hide
@@ -1889,5 +1890,6 @@ public class RadioManager {
    public RadioManager(Context context, IRadioService service) {
        mContext = context;
        mService = service;
        mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
    }
}
+6 −4
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ import android.os.Parcel;
import android.os.RemoteException;
import android.util.ArraySet;

import androidx.test.InstrumentationRegistry;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -54,6 +56,8 @@ import java.util.concurrent.Executor;
@RunWith(MockitoJUnitRunner.class)
public final class ProgramListTest {

    public final Context mContext = InstrumentationRegistry.getContext();

    private static final int CREATOR_ARRAY_SIZE = 3;
    private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(/* millis= */ 500);

@@ -109,8 +113,6 @@ public final class ProgramListTest {
    @Mock
    private IRadioService mRadioServiceMock;
    @Mock
    private Context mContextMock;
    @Mock
    private ITuner mTunerMock;
    @Mock
    private RadioTuner.Callback mTunerCallbackMock;
@@ -477,7 +479,7 @@ public final class ProgramListTest {
    }

    private void createRadioTuner() throws Exception {
        RadioManager radioManager = new RadioManager(mContextMock, mRadioServiceMock);
        RadioManager radioManager = new RadioManager(mContext, mRadioServiceMock);
        RadioManager.BandConfig band = new RadioManager.FmBandConfig(
                new RadioManager.FmBandDescriptor(RadioManager.REGION_ITU_1, RadioManager.BAND_FM,
                        /* lowerLimit= */ 87500, /* upperLimit= */ 108000, /* spacing= */ 200,
@@ -487,7 +489,7 @@ public final class ProgramListTest {
        doAnswer(invocation -> {
            mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
            return mTunerMock;
        }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
        }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());

        mRadioTuner = radioManager.openTuner(/* moduleId= */ 0, band,
                /* withAudio= */ true, mTunerCallbackMock, /* handler= */ null);
+12 −3
Original line number Diff line number Diff line
@@ -18,14 +18,16 @@ package android.hardware.radio.tests.unittests;

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

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.hardware.radio.Announcement;
import android.hardware.radio.IAnnouncementListener;
import android.hardware.radio.ICloseHandle;
@@ -34,6 +36,7 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
import android.hardware.radio.RadioTuner;
import android.os.Build;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -53,6 +56,8 @@ import java.util.Set;
@RunWith(MockitoJUnitRunner.class)
public final class RadioManagerTest {

    private static final int TEST_TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;

    private static final int REGION = RadioManager.REGION_ITU_2;
    private static final int FM_LOWER_LIMIT = 87500;
    private static final int FM_UPPER_LIMIT = 108000;
@@ -126,6 +131,7 @@ public final class RadioManagerTest {
                    /* vendorInfo= */ new ArrayMap<>()));

    private RadioManager mRadioManager;
    private final ApplicationInfo mApplicationInfo = new ApplicationInfo();

    @Mock
    private IRadioService mRadioServiceMock;
@@ -1008,7 +1014,8 @@ public final class RadioManagerTest {
        mRadioManager.openTuner(moduleId, FM_BAND_CONFIG, withAudio, mCallbackMock,
                /* handler= */ null);

        verify(mRadioServiceMock).openTuner(eq(moduleId), eq(FM_BAND_CONFIG), eq(withAudio), any());
        verify(mRadioServiceMock).openTuner(eq(moduleId), eq(FM_BAND_CONFIG), eq(withAudio), any(),
                anyInt());
    }

    @Test
@@ -1103,6 +1110,8 @@ public final class RadioManagerTest {
    }

    private void createRadioManager() throws RemoteException {
        mApplicationInfo.targetSdkVersion = TEST_TARGET_SDK_VERSION;
        when(mContextMock.getApplicationInfo()).thenReturn(mApplicationInfo);
        when(mRadioServiceMock.listModules()).thenReturn(Arrays.asList(AMFM_PROPERTIES));
        when(mRadioServiceMock.addAnnouncementListener(any(), any())).thenReturn(mCloseHandleMock);

+8 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.hardware.radio.IRadioService;
import android.hardware.radio.ITuner;
@@ -35,6 +36,7 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
import android.hardware.radio.RadioTuner;
import android.os.Build;

import org.junit.After;
import org.junit.Before;
@@ -51,6 +53,8 @@ import java.util.Map;
@RunWith(MockitoJUnitRunner.class)
public final class TunerAdapterTest {

    private static final int TEST_TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;

    private static final int CALLBACK_TIMEOUT_MS = 30_000;
    private static final int AM_LOWER_LIMIT_KHZ = 150;

@@ -65,6 +69,7 @@ public final class TunerAdapterTest {

    private RadioTuner mRadioTuner;
    private ITunerCallback mTunerCallback;
    private final ApplicationInfo mApplicationInfo = new ApplicationInfo();

    @Mock
    private IRadioService mRadioServiceMock;
@@ -77,12 +82,14 @@ public final class TunerAdapterTest {

    @Before
    public void setUp() throws Exception {
        mApplicationInfo.targetSdkVersion = TEST_TARGET_SDK_VERSION;
        when(mContextMock.getApplicationInfo()).thenReturn(mApplicationInfo);
        RadioManager radioManager = new RadioManager(mContextMock, mRadioServiceMock);

        doAnswer(invocation -> {
            mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
            return mTunerMock;
        }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
        }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());

        doAnswer(invocation -> {
            ProgramSelector program = (ProgramSelector) invocation.getArguments()[0];
Loading