Merge "Use CompatChanges to radio app version check" into udc-dev

This commit is contained in:
Weilin Xu
2023-03-16 22:20:54 +00:00
committed by Android (Google) Code Review
18 changed files with 113 additions and 103 deletions

View File

@@ -31,7 +31,7 @@ interface IRadioService {
List<RadioManager.ModuleProperties> listModules();
ITuner openTuner(int moduleId, in RadioManager.BandConfig bandConfig, boolean withAudio,
in ITunerCallback callback, int targetSdkVersion);
in ITunerCallback callback);
ICloseHandle addAnnouncementListener(in int[] enabledTypes,
in IAnnouncementListener listener);

View File

@@ -1796,7 +1796,7 @@ public class RadioManager {
ITuner tuner;
TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
try {
tuner = mService.openTuner(moduleId, config, withAudio, halCallback, mTargetSdkVersion);
tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
} catch (RemoteException | IllegalArgumentException | IllegalStateException ex) {
Log.e(TAG, "Failed to open tuner", ex);
return null;
@@ -1873,7 +1873,6 @@ public class RadioManager {
@NonNull private final Context mContext;
@NonNull private final IRadioService mService;
private final int mTargetSdkVersion;
/**
* @hide
@@ -1890,6 +1889,5 @@ public class RadioManager {
public RadioManager(Context context, IRadioService service) {
mContext = context;
mService = service;
mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
}
}

View File

@@ -18,6 +18,8 @@
package="com.android.frameworks.broadcastradiotests">
<uses-permission android:name="android.permission.ACCESS_BROADCAST_RADIO" />
<uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
<uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />

View File

@@ -580,7 +580,7 @@ public final class ProgramListTest {
doAnswer(invocation -> {
mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
return mTunerMock;
}).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());
}).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
mRadioTuner = radioManager.openTuner(/* moduleId= */ 0, band,
/* withAudio= */ true, mTunerCallbackMock, /* handler= */ null);

View File

@@ -30,7 +30,6 @@ import static org.mockito.Mockito.when;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -50,8 +49,6 @@ 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;
@@ -1043,14 +1040,13 @@ 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(),
anyInt());
verify(mRadioServiceMock).openTuner(eq(moduleId), eq(FM_BAND_CONFIG), eq(withAudio), any());
}
@Test
public void openTuner_whenServiceDied_returnsNull() throws Exception {
createRadioManager();
when(mRadioServiceMock.openTuner(anyInt(), any(), anyBoolean(), any(), anyInt()))
when(mRadioServiceMock.openTuner(anyInt(), any(), anyBoolean(), any()))
.thenThrow(new RemoteException());
RadioTuner nullTuner = mRadioManager.openTuner(/* moduleId= */ 0, FM_BAND_CONFIG,
@@ -1166,7 +1162,6 @@ 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);

View File

@@ -86,7 +86,7 @@ public final class TunerAdapterTest {
doAnswer(invocation -> {
mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
return mTunerMock;
}).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());
}).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
doAnswer(invocation -> {
ProgramSelector program = (ProgramSelector) invocation.getArguments()[0];

View File

@@ -24,7 +24,6 @@ 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.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -35,7 +34,6 @@ import android.hardware.radio.ICloseHandle;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.os.Build;
import android.os.IBinder;
import android.os.ServiceManager;
@@ -58,7 +56,6 @@ public final class IRadioServiceAidlImplTest extends ExtendedRadioMockitoTestCas
"android.hardware.broadcastradio.IBroadcastRadio/amfm";
private static final String DAB_SERVICE_NAME =
"android.hardware.broadcastradio.IBroadcastRadio/dab";
private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private IRadioServiceAidlImpl mAidlImpl;
@@ -86,7 +83,7 @@ public final class IRadioServiceAidlImplTest extends ExtendedRadioMockitoTestCas
doNothing().when(mServiceMock).enforcePolicyAccess();
when(mHalMock.listModules()).thenReturn(List.of(mModuleMock));
when(mHalMock.openSession(anyInt(), any(), anyBoolean(), any(), eq(TARGET_SDK_VERSION)))
when(mHalMock.openSession(anyInt(), any(), anyBoolean(), any()))
.thenReturn(mTunerMock);
when(mHalMock.addAnnouncementListener(any(), any())).thenReturn(mICloseHandle);
@@ -118,7 +115,7 @@ public final class IRadioServiceAidlImplTest extends ExtendedRadioMockitoTestCas
@Test
public void openTuner_forAidlImpl() throws Exception {
ITuner tuner = mAidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
/* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
/* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in AIDL HAL")
.that(tuner).isEqualTo(mTunerMock);
@@ -128,7 +125,7 @@ public final class IRadioServiceAidlImplTest extends ExtendedRadioMockitoTestCas
public void openTuner_withNullCallbackForAidlImpl_fails() throws Exception {
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mAidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
/* withAudio= */ true, /* callback= */ null, TARGET_SDK_VERSION));
/* withAudio= */ true, /* callback= */ null));
assertWithMessage("Exception for opening tuner with null callback")
.that(thrown).hasMessageThat().contains("Callback must not be null");

View File

@@ -33,7 +33,6 @@ import android.hardware.radio.ICloseHandle;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +50,6 @@ public final class IRadioServiceHidlImplTest {
private static final int HAL1_MODULE_ID = 0;
private static final int[] ENABLE_TYPES = new int[]{Announcement.TYPE_TRAFFIC};
private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private IRadioServiceHidlImpl mHidlImpl;
@@ -106,7 +104,7 @@ public final class IRadioServiceHidlImplTest {
@Test
public void openTuner_withHal1ModuleId_forHidlImpl() throws Exception {
ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID, mBandConfigMock,
/* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
/* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in HAL 1")
.that(tuner).isEqualTo(mHal1TunerMock);
@@ -115,7 +113,7 @@ public final class IRadioServiceHidlImplTest {
@Test
public void openTuner_withHal2ModuleId_forHidlImpl() throws Exception {
ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID + 1, mBandConfigMock,
/* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
/* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in HAL 2")
.that(tuner).isEqualTo(mHal2TunerMock);
@@ -125,7 +123,7 @@ public final class IRadioServiceHidlImplTest {
public void openTuner_withNullCallbackForHidlImpl_fails() throws Exception {
NullPointerException thrown = assertThrows(NullPointerException.class,
() -> mHidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
/* withAudio= */ true, /* callback= */ null, TARGET_SDK_VERSION));
/* withAudio= */ true, /* callback= */ null));
assertWithMessage("Exception for opening tuner with null callback")
.that(thrown).hasMessageThat().contains("Callback must not be null");

View File

@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.compat.CompatChanges;
import android.os.Binder;
import android.os.UserHandle;
@@ -46,8 +47,8 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(ActivityManager.class)
.spyStatic(Binder.class);
builder.spyStatic(ActivityManager.class).spyStatic(Binder.class)
.spyStatic(CompatChanges.class);
}
@Before

View File

@@ -36,7 +36,6 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.os.Build;
import android.os.IBinder;
import android.os.IServiceCallback;
import android.os.RemoteException;
@@ -55,8 +54,6 @@ import java.util.Arrays;
public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTestCase {
private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private static final int FM_RADIO_MODULE_ID = 0;
private static final int DAB_RADIO_MODULE_ID = 1;
private static final ArrayList<String> SERVICE_LIST =
@@ -140,8 +137,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
createBroadcastRadioService();
ITuner session = mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
TARGET_SDK_VERSION);
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Session opened in FM radio module")
.that(session).isEqualTo(mFmTunerSessionMock);
@@ -152,8 +148,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
createBroadcastRadioService();
ITuner session = mBroadcastRadioService.openSession(DAB_RADIO_MODULE_ID + 1,
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
TARGET_SDK_VERSION);
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Session opened with id not found").that(session).isNull();
}
@@ -165,8 +160,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
IllegalStateException thrown = assertThrows(IllegalStateException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
TARGET_SDK_VERSION));
/* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock));
assertWithMessage("Exception for opening session by non-current user")
.that(thrown).hasMessageThat().contains("Cannot open session for non-current user");
@@ -178,8 +172,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
/* legacyConfig= */ null, /* withAudio= */ false, mTunerCallbackMock,
TARGET_SDK_VERSION));
/* legacyConfig= */ null, /* withAudio= */ false, mTunerCallbackMock));
assertWithMessage("Exception for opening session without audio")
.that(thrown).hasMessageThat().contains("not supported");
@@ -247,7 +240,6 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
return null;
}).when(mFmBinderMock).linkToDeath(any(), anyInt());
when(mFmRadioModuleMock.openSession(eq(mTunerCallbackMock), eq(TARGET_SDK_VERSION)))
.thenReturn(mFmTunerSessionMock);
when(mFmRadioModuleMock.openSession(mTunerCallbackMock)).thenReturn(mFmTunerSessionMock);
}
}

View File

@@ -16,6 +16,9 @@
package com.android.server.broadcastradio.aidl;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import android.app.compat.CompatChanges;
import android.hardware.broadcastradio.AmFmBandRange;
import android.hardware.broadcastradio.AmFmRegionConfig;
import android.hardware.broadcastradio.DabTableEntry;
@@ -29,17 +32,23 @@ import android.hardware.radio.Announcement;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.Build;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
import com.google.common.truth.Expect;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
public final class ConversionUtilsTest {
public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
private static final int U_APP_UID = 1001;
private static final int T_APP_UID = 1002;
private static final int FM_LOWER_LIMIT = 87_500;
private static final int FM_UPPER_LIMIT = 108_000;
@@ -118,16 +127,29 @@ public final class ConversionUtilsTest {
@Rule
public final Expect expect = Expect.create();
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(CompatChanges.class);
}
@Before
public void setUp() {
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
ConversionUtils.RADIO_U_VERSION_REQUIRED, U_APP_UID));
doReturn(false).when(() -> CompatChanges.isChangeEnabled(
ConversionUtils.RADIO_U_VERSION_REQUIRED, T_APP_UID));
}
@Test
public void isAtLeastU_withTSdkVersion_returnsFalse() {
expect.withMessage("Target SDK version of T")
.that(ConversionUtils.isAtLeastU(Build.VERSION_CODES.TIRAMISU)).isFalse();
.that(ConversionUtils.isAtLeastU(T_APP_UID)).isFalse();
}
@Test
public void isAtLeastU_withCurrentSdkVersion_returnsTrue() {
expect.withMessage("Target SDK version of U")
.that(ConversionUtils.isAtLeastU(Build.VERSION_CODES.CUR_DEVELOPMENT)).isTrue();
.that(ConversionUtils.isAtLeastU(U_APP_UID)).isTrue();
}
@Test
@@ -372,14 +394,14 @@ public final class ConversionUtilsTest {
public void programSelectorMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
expect.withMessage("Selector %s without required SDK version", TEST_DAB_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_DAB_SELECTOR,
Build.VERSION_CODES.TIRAMISU)).isFalse();
T_APP_UID)).isFalse();
}
@Test
public void programSelectorMeetsSdkVersionRequirement_withRequiredVersionId_returnsTrue() {
expect.withMessage("Selector %s with required SDK version", TEST_FM_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_FM_SELECTOR,
Build.VERSION_CODES.TIRAMISU)).isTrue();
T_APP_UID)).isTrue();
}
@Test
@@ -389,7 +411,7 @@ public final class ConversionUtilsTest {
expect.withMessage("Program info %s without required SDK version", dabProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(dabProgramInfo,
Build.VERSION_CODES.TIRAMISU)).isFalse();
T_APP_UID)).isFalse();
}
@Test
@@ -399,7 +421,7 @@ public final class ConversionUtilsTest {
expect.withMessage("Program info %s with required SDK version", fmProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(fmProgramInfo,
Build.VERSION_CODES.TIRAMISU)).isTrue();
T_APP_UID)).isTrue();
}
@Test
@@ -413,7 +435,7 @@ public final class ConversionUtilsTest {
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
Build.VERSION_CODES.TIRAMISU);
T_APP_UID);
expect.withMessage(
"Purged state of the converted program list chunk with lower SDK version")
@@ -441,7 +463,7 @@ public final class ConversionUtilsTest {
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
Build.VERSION_CODES.CUR_DEVELOPMENT);
U_APP_UID);
expect.withMessage("Converted program list chunk with required SDK version")
.that(convertedChunk).isEqualTo(chunk);

View File

@@ -33,6 +33,7 @@ import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.compat.CompatChanges;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.IBroadcastRadio;
import android.hardware.broadcastradio.ITunerCallback;
@@ -46,7 +47,6 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
import android.os.Build;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -73,7 +73,6 @@ import java.util.Set;
*/
public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
private static final int SIGNAL_QUALITY = 90;
@@ -125,11 +124,13 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(RadioServiceUserController.class);
builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class);
}
@Before
public void setup() throws Exception {
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
@@ -341,7 +342,9 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void tune_withLowerSdkVersion() throws Exception {
openAidlClients(/* numClients= */ 1, Build.VERSION_CODES.TIRAMISU);
doReturn(false).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo =
AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
@@ -1175,17 +1178,13 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
.onParametersUpdated(parametersExpected);
}
}
private void openAidlClients(int numClients) throws Exception {
openAidlClients(numClients, TARGET_SDK_VERSION);
}
private void openAidlClients(int numClients, int targetSdkVersion) throws Exception {
private void openAidlClients(int numClients) throws Exception {
mAidlTunerCallbackMocks = new android.hardware.radio.ITunerCallback[numClients];
mTunerSessions = new TunerSession[numClients];
for (int index = 0; index < numClients; index++) {
mAidlTunerCallbackMocks[index] = mock(android.hardware.radio.ITunerCallback.class);
mTunerSessions[index] = mRadioModule.openSession(mAidlTunerCallbackMocks[index],
targetSdkVersion);
mTunerSessions[index] = mRadioModule.openSession(mAidlTunerCallbackMocks[index]);
}
}

View File

@@ -86,8 +86,7 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub {
@Override
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
boolean withAudio, ITunerCallback callback, int targetSdkVersion)
throws RemoteException {
boolean withAudio, ITunerCallback callback) throws RemoteException {
if (isDebugEnabled()) {
Slogf.d(TAG, "Opening module %d", moduleId);
}
@@ -95,7 +94,7 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub {
if (callback == null) {
throw new IllegalArgumentException("Callback must not be null");
}
return mHalAidl.openSession(moduleId, bandConfig, withAudio, callback, targetSdkVersion);
return mHalAidl.openSession(moduleId, bandConfig, withAudio, callback);
}
@Override

View File

@@ -92,8 +92,7 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub {
@Override
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
boolean withAudio, ITunerCallback callback, int targetSdkVersion)
throws RemoteException {
boolean withAudio, ITunerCallback callback) throws RemoteException {
if (isDebugEnabled()) {
Slog.d(TAG, "Opening module " + moduleId);
}

View File

@@ -199,8 +199,7 @@ public final class BroadcastRadioServiceImpl {
*/
@Nullable
public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
boolean withAudio, ITunerCallback callback, int targetSdkVersion)
throws RemoteException {
boolean withAudio, ITunerCallback callback) throws RemoteException {
if (DEBUG) {
Slogf.d(TAG, "Open AIDL radio session");
}
@@ -223,7 +222,7 @@ public final class BroadcastRadioServiceImpl {
}
}
TunerSession tunerSession = radioModule.openSession(callback, targetSdkVersion);
TunerSession tunerSession = radioModule.openSession(callback);
if (legacyConfig != null) {
tunerSession.setConfiguration(legacyConfig);
}

View File

@@ -17,6 +17,10 @@
package com.android.server.broadcastradio.aidl;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.hardware.broadcastradio.AmFmRegionConfig;
import android.hardware.broadcastradio.Announcement;
import android.hardware.broadcastradio.DabTableEntry;
@@ -57,16 +61,24 @@ import java.util.Set;
* {@link android.hardware.radio}
*/
final class ConversionUtils {
// TODO(b/241118988): Add unit test for ConversionUtils class
private static final String TAG = "BcRadioAidlSrv.convert";
/**
* With RADIO_U_VERSION_REQUIRED enabled, 44-bit DAB identifier
* {@link IdentifierType#DAB_SID_EXT} from broadcast radio HAL can be passed as
* {@link ProgramSelector#IDENTIFIER_TYPE_DAB_DMB_SID_EXT} to {@link RadioTuner}.
*/
@ChangeId
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final long RADIO_U_VERSION_REQUIRED = 261770108L;
private ConversionUtils() {
throw new UnsupportedOperationException("ConversionUtils class is noninstantiable");
}
static boolean isAtLeastU(int targetSdkVersion) {
// TODO(b/261770108): Use version code for U.
return targetSdkVersion >= Build.VERSION_CODES.CUR_DEVELOPMENT;
@SuppressLint("AndroidFrameworkRequiresPermission")
static boolean isAtLeastU(int uid) {
return CompatChanges.isChangeEnabled(RADIO_U_VERSION_REQUIRED, uid);
}
static RuntimeException throwOnError(RuntimeException halException, String action) {
@@ -584,9 +596,8 @@ final class ConversionUtils {
return id.getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT;
}
static boolean programSelectorMeetsSdkVersionRequirement(ProgramSelector sel,
int targetSdkVersion) {
if (isAtLeastU(targetSdkVersion)) {
static boolean programSelectorMeetsSdkVersionRequirement(ProgramSelector sel, int uid) {
if (isAtLeastU(uid)) {
return true;
}
if (sel.getPrimaryId().getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT) {
@@ -601,12 +612,11 @@ final class ConversionUtils {
return true;
}
static boolean programInfoMeetsSdkVersionRequirement(RadioManager.ProgramInfo info,
int targetSdkVersion) {
if (isAtLeastU(targetSdkVersion)) {
static boolean programInfoMeetsSdkVersionRequirement(RadioManager.ProgramInfo info, int uid) {
if (isAtLeastU(uid)) {
return true;
}
if (!programSelectorMeetsSdkVersionRequirement(info.getSelector(), targetSdkVersion)) {
if (!programSelectorMeetsSdkVersionRequirement(info.getSelector(), uid)) {
return false;
}
if (isNewIdentifierInU(info.getLogicallyTunedTo())
@@ -622,16 +632,15 @@ final class ConversionUtils {
return true;
}
static ProgramList.Chunk convertChunkToTargetSdkVersion(ProgramList.Chunk chunk,
int targetSdkVersion) {
if (isAtLeastU(targetSdkVersion)) {
static ProgramList.Chunk convertChunkToTargetSdkVersion(ProgramList.Chunk chunk, int uid) {
if (isAtLeastU(uid)) {
return chunk;
}
Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
Iterator<RadioManager.ProgramInfo> modifiedIterator = chunk.getModified().iterator();
while (modifiedIterator.hasNext()) {
RadioManager.ProgramInfo info = modifiedIterator.next();
if (programInfoMeetsSdkVersionRequirement(info, targetSdkVersion)) {
if (programInfoMeetsSdkVersionRequirement(info, uid)) {
modified.add(info);
}
}

View File

@@ -101,9 +101,9 @@ final class RadioModule {
ConversionUtils.programSelectorFromHalProgramSelector(programSelector);
int tunerResult = ConversionUtils.halResultToTunerResult(result);
synchronized (mLock) {
fanoutAidlCallbackLocked((cb, sdkVersion) -> {
fanoutAidlCallbackLocked((cb, uid) -> {
if (csel != null && !ConversionUtils
.programSelectorMeetsSdkVersionRequirement(csel, sdkVersion)) {
.programSelectorMeetsSdkVersionRequirement(csel, uid)) {
Slogf.e(TAG, "onTuneFailed: cannot send program selector "
+ "requiring higher target SDK version");
return;
@@ -123,9 +123,9 @@ final class RadioModule {
"Program info from AIDL HAL is invalid");
synchronized (mLock) {
mCurrentProgramInfo = currentProgramInfo;
fanoutAidlCallbackLocked((cb, sdkVersion) -> {
fanoutAidlCallbackLocked((cb, uid) -> {
if (!ConversionUtils.programInfoMeetsSdkVersionRequirement(
currentProgramInfo, sdkVersion)) {
currentProgramInfo, uid)) {
Slogf.e(TAG, "onCurrentProgramInfoChanged: cannot send "
+ "program info requiring higher target SDK version");
return;
@@ -156,7 +156,7 @@ final class RadioModule {
fireLater(() -> {
synchronized (mLock) {
mAntennaConnected = connected;
fanoutAidlCallbackLocked((cb, sdkVersion) -> cb.onAntennaState(connected));
fanoutAidlCallbackLocked((cb, uid) -> cb.onAntennaState(connected));
}
});
}
@@ -165,7 +165,7 @@ final class RadioModule {
public void onConfigFlagUpdated(int flag, boolean value) {
fireLater(() -> {
synchronized (mLock) {
fanoutAidlCallbackLocked((cb, sdkVersion) -> {
fanoutAidlCallbackLocked((cb, uid) -> {
cb.onConfigFlagUpdated(flag, value);
});
}
@@ -178,7 +178,7 @@ final class RadioModule {
synchronized (mLock) {
Map<String, String> cparam =
ConversionUtils.vendorInfoFromHalVendorKeyValues(parameters);
fanoutAidlCallbackLocked((cb, sdkVersion) -> {
fanoutAidlCallbackLocked((cb, uid) -> {
cb.onParametersUpdated(cparam);
});
}
@@ -244,14 +244,14 @@ final class RadioModule {
mService.setTunerCallback(mHalTunerCallback);
}
TunerSession openSession(android.hardware.radio.ITunerCallback userCb, int targetSdkVersion)
TunerSession openSession(android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
mLogger.logRadioEvent("Open TunerSession");
TunerSession tunerSession;
Boolean antennaConnected;
RadioManager.ProgramInfo currentProgramInfo;
synchronized (mLock) {
tunerSession = new TunerSession(this, mService, userCb, targetSdkVersion);
tunerSession = new TunerSession(this, mService, userCb);
mAidlTunerSessions.add(tunerSession);
antennaConnected = mAntennaConnected;
currentProgramInfo = mCurrentProgramInfo;
@@ -404,7 +404,7 @@ final class RadioModule {
}
interface AidlCallbackRunnable {
void run(android.hardware.radio.ITunerCallback callback, int targetSdkVersion)
void run(android.hardware.radio.ITunerCallback callback, int uid)
throws RemoteException;
}
@@ -423,7 +423,7 @@ final class RadioModule {
for (int i = 0; i < mAidlTunerSessions.size(); i++) {
try {
runnable.run(mAidlTunerSessions.valueAt(i).mCallback,
mAidlTunerSessions.valueAt(i).getTargetSdkVersion());
mAidlTunerSessions.valueAt(i).getUid());
} catch (DeadObjectException ex) {
// The other side died without calling close(), so just purge it from our records.
Slogf.e(TAG, "Removing dead TunerSession");

View File

@@ -24,6 +24,7 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.Binder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -46,7 +47,7 @@ final class TunerSession extends ITuner.Stub {
private final RadioLogger mLogger;
private final RadioModule mModule;
final android.hardware.radio.ITunerCallback mCallback;
private final int mTargetSdkVersion;
private final int mUid;
private final IBroadcastRadio mService;
@GuardedBy("mLock")
@@ -61,11 +62,11 @@ final class TunerSession extends ITuner.Stub {
private RadioManager.BandConfig mPlaceHolderConfig;
TunerSession(RadioModule radioModule, IBroadcastRadio service,
android.hardware.radio.ITunerCallback callback, int targetSdkVersion) {
android.hardware.radio.ITunerCallback callback) {
mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null");
mService = Objects.requireNonNull(service, "service cannot be null");
mCallback = Objects.requireNonNull(callback, "callback cannot be null");
mTargetSdkVersion = targetSdkVersion;
mUid = Binder.getCallingUid();
mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}
@@ -130,7 +131,7 @@ final class TunerSession extends ITuner.Stub {
mPlaceHolderConfig = Objects.requireNonNull(config, "config cannot be null");
}
Slogf.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL AIDL");
mModule.fanoutAidlCallback((cb, sdkVersion) -> cb.onConfigurationChanged(config));
mModule.fanoutAidlCallback((cb, mUid) -> cb.onConfigurationChanged(config));
}
@Override
@@ -254,7 +255,7 @@ final class TunerSession extends ITuner.Stub {
Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user");
return false;
}
mModule.fanoutAidlCallback((cb, sdkVersion) -> {
mModule.fanoutAidlCallback((cb, mUid) -> {
cb.onBackgroundScanComplete();
});
return true;
@@ -284,8 +285,8 @@ final class TunerSession extends ITuner.Stub {
mModule.onTunerSessionProgramListFilterChanged(this);
}
int getTargetSdkVersion() {
return mTargetSdkVersion;
int getUid() {
return mUid;
}
ProgramList.Filter getProgramListFilter() {
@@ -323,10 +324,9 @@ final class TunerSession extends ITuner.Stub {
}
for (int i = 0; i < chunks.size(); i++) {
try {
if (!ConversionUtils.isAtLeastU(getTargetSdkVersion())) {
if (!ConversionUtils.isAtLeastU(getUid())) {
ProgramList.Chunk downgradedChunk =
ConversionUtils.convertChunkToTargetSdkVersion(chunks.get(i),
getTargetSdkVersion());
ConversionUtils.convertChunkToTargetSdkVersion(chunks.get(i), getUid());
mCallback.onProgramListUpdated(downgradedChunk);
} else {
mCallback.onProgramListUpdated(chunks.get(i));