Merge "Set bcradio HAL tuner callback when sessions exist" into main
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
index a034653..10ac05d 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java
@@ -88,13 +88,6 @@
}
@Test
- public void setInternalHalCallback_callbackSetInHal() throws Exception {
- mRadioModule.setInternalHalCallback();
-
- verify(mBroadcastRadioMock).setTunerCallback(any());
- }
-
- @Test
public void getImage_withValidIdFromRadioModule() {
int imageId = 1;
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 262f167..755bcdb 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -192,66 +192,6 @@
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
return null;
}).when(mBroadcastRadioMock).setTunerCallback(any());
- mRadioModule.setInternalHalCallback();
-
- doAnswer(invocation -> {
- android.hardware.broadcastradio.ProgramSelector halSel =
- (android.hardware.broadcastradio.ProgramSelector) invocation.getArguments()[0];
- mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(halSel, SIGNAL_QUALITY);
- if (halSel.primaryId.type != IdentifierType.AMFM_FREQUENCY_KHZ) {
- throw new ServiceSpecificException(Result.NOT_SUPPORTED);
- }
- mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
- return Result.OK;
- }).when(mBroadcastRadioMock).tune(any());
-
- doAnswer(invocation -> {
- if ((boolean) invocation.getArguments()[0]) {
- mHalCurrentInfo.selector.primaryId.value += AM_FM_FREQUENCY_SPACING;
- } else {
- mHalCurrentInfo.selector.primaryId.value -= AM_FM_FREQUENCY_SPACING;
- }
- mHalCurrentInfo.logicallyTunedTo = mHalCurrentInfo.selector.primaryId;
- mHalCurrentInfo.physicallyTunedTo = mHalCurrentInfo.selector.primaryId;
- mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
- return Result.OK;
- }).when(mBroadcastRadioMock).step(anyBoolean());
-
- doAnswer(invocation -> {
- if (mHalCurrentInfo == null) {
- android.hardware.broadcastradio.ProgramSelector placeHolderSelector =
- AidlTestUtils.makeHalFmSelector(/* freq= */ 97300);
-
- mHalTunerCallback.onTuneFailed(Result.TIMEOUT, placeHolderSelector);
- return Result.OK;
- }
- mHalCurrentInfo.selector.primaryId.value = getSeekFrequency(
- mHalCurrentInfo.selector.primaryId.value,
- !(boolean) invocation.getArguments()[0]);
- mHalCurrentInfo.logicallyTunedTo = mHalCurrentInfo.selector.primaryId;
- mHalCurrentInfo.physicallyTunedTo = mHalCurrentInfo.selector.primaryId;
- mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
- return Result.OK;
- }).when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
-
- doReturn(null).when(mBroadcastRadioMock).getImage(anyInt());
-
- doAnswer(invocation -> {
- int configFlag = (int) invocation.getArguments()[0];
- if (configFlag == UNSUPPORTED_CONFIG_FLAG) {
- throw new ServiceSpecificException(Result.NOT_SUPPORTED);
- }
- return mHalConfigMap.getOrDefault(configFlag, false);
- }).when(mBroadcastRadioMock).isConfigFlagSet(anyInt());
-
- doAnswer(invocation -> {
- int configFlag = (int) invocation.getArguments()[0];
- if (configFlag == UNSUPPORTED_CONFIG_FLAG) {
- throw new ServiceSpecificException(Result.NOT_SUPPORTED);
- }
- mHalConfigMap.put(configFlag, (boolean) invocation.getArguments()[1]);
- return null;
- }).when(mBroadcastRadioMock).setConfigFlag(anyInt(), anyBoolean());
}
@After
@@ -330,6 +270,7 @@
expect.withMessage("Close state of broadcast radio service session")
.that(mTunerSessions[0].isClosed()).isTrue();
+ verify(mBroadcastRadioMock).unsetTunerCallback();
}
@Test
@@ -351,6 +292,7 @@
.that(mTunerSessions[index].isClosed()).isFalse();
}
}
+ verify(mBroadcastRadioMock, never()).unsetTunerCallback();
}
@Test
@@ -378,6 +320,7 @@
expect.withMessage("Close state of broadcast radio service session of index %s", index)
.that(mTunerSessions[index].isClosed()).isTrue();
}
+ verify(mBroadcastRadioMock).unsetTunerCallback();
}
@Test
@@ -1295,6 +1238,71 @@
mAidlTunerCallbackMocks[index] = mock(android.hardware.radio.ITunerCallback.class);
mTunerSessions[index] = mRadioModule.openSession(mAidlTunerCallbackMocks[index]);
}
+ setupMockedHalTunerSession();
+ }
+
+ private void setupMockedHalTunerSession() throws Exception {
+ expect.withMessage("Registered HAL tuner callback").that(mHalTunerCallback)
+ .isNotNull();
+
+ doAnswer(invocation -> {
+ android.hardware.broadcastradio.ProgramSelector halSel =
+ (android.hardware.broadcastradio.ProgramSelector) invocation.getArguments()[0];
+ mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo(halSel, SIGNAL_QUALITY);
+ if (halSel.primaryId.type != IdentifierType.AMFM_FREQUENCY_KHZ) {
+ throw new ServiceSpecificException(Result.NOT_SUPPORTED);
+ }
+ mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
+ return Result.OK;
+ }).when(mBroadcastRadioMock).tune(any());
+
+ doAnswer(invocation -> {
+ if ((boolean) invocation.getArguments()[0]) {
+ mHalCurrentInfo.selector.primaryId.value += AM_FM_FREQUENCY_SPACING;
+ } else {
+ mHalCurrentInfo.selector.primaryId.value -= AM_FM_FREQUENCY_SPACING;
+ }
+ mHalCurrentInfo.logicallyTunedTo = mHalCurrentInfo.selector.primaryId;
+ mHalCurrentInfo.physicallyTunedTo = mHalCurrentInfo.selector.primaryId;
+ mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
+ return Result.OK;
+ }).when(mBroadcastRadioMock).step(anyBoolean());
+
+ doAnswer(invocation -> {
+ if (mHalCurrentInfo == null) {
+ android.hardware.broadcastradio.ProgramSelector placeHolderSelector =
+ AidlTestUtils.makeHalFmSelector(/* freq= */ 97300);
+
+ mHalTunerCallback.onTuneFailed(Result.TIMEOUT, placeHolderSelector);
+ return Result.OK;
+ }
+ mHalCurrentInfo.selector.primaryId.value = getSeekFrequency(
+ mHalCurrentInfo.selector.primaryId.value,
+ !(boolean) invocation.getArguments()[0]);
+ mHalCurrentInfo.logicallyTunedTo = mHalCurrentInfo.selector.primaryId;
+ mHalCurrentInfo.physicallyTunedTo = mHalCurrentInfo.selector.primaryId;
+ mHalTunerCallback.onCurrentProgramInfoChanged(mHalCurrentInfo);
+ return Result.OK;
+ }).when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
+
+ doReturn(null).when(mBroadcastRadioMock).getImage(anyInt());
+
+ doAnswer(invocation -> {
+ int configFlag = (int) invocation.getArguments()[0];
+ if (configFlag == UNSUPPORTED_CONFIG_FLAG) {
+ throw new ServiceSpecificException(Result.NOT_SUPPORTED);
+ }
+ return mHalConfigMap.getOrDefault(configFlag, false);
+ }).when(mBroadcastRadioMock).isConfigFlagSet(anyInt());
+
+ doAnswer(invocation -> {
+ int configFlag = (int) invocation.getArguments()[0];
+ if (configFlag == UNSUPPORTED_CONFIG_FLAG) {
+ throw new ServiceSpecificException(Result.NOT_SUPPORTED);
+ }
+ mHalConfigMap.put(configFlag, (boolean) invocation.getArguments()[1]);
+ return null;
+ }).when(mBroadcastRadioMock).setConfigFlag(anyInt(), anyBoolean());
}
private long getSeekFrequency(long currentFrequency, boolean seekDown) {
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
index 03acf72..d93ff9d 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
@@ -82,13 +82,6 @@
Slogf.w(TAG, "No module %s with id %d (HAL AIDL)", name, moduleId);
return;
}
- try {
- radioModule.setInternalHalCallback();
- } catch (RemoteException ex) {
- Slogf.wtf(TAG, ex, "Broadcast radio module %s with id %d (HAL AIDL) "
- + "cannot register HAL callback", name, moduleId);
- return;
- }
if (DEBUG) {
Slogf.d(TAG, "Loaded broadcast radio module %s with id %d (HAL AIDL)",
name, moduleId);
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index 4b3444d..cd86510 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -246,10 +246,6 @@
return mProperties;
}
- void setInternalHalCallback() throws RemoteException {
- mService.setTunerCallback(mHalTunerCallback);
- }
-
TunerSession openSession(android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
mLogger.logRadioEvent("Open TunerSession");
@@ -257,10 +253,14 @@
Boolean antennaConnected;
RadioManager.ProgramInfo currentProgramInfo;
synchronized (mLock) {
+ boolean isFirstTunerSession = mAidlTunerSessions.isEmpty();
tunerSession = new TunerSession(this, mService, userCb);
mAidlTunerSessions.add(tunerSession);
antennaConnected = mAntennaConnected;
currentProgramInfo = mCurrentProgramInfo;
+ if (isFirstTunerSession) {
+ mService.setTunerCallback(mHalTunerCallback);
+ }
}
// Propagate state to new client.
// Note: These callbacks are invoked while holding mLock to prevent race conditions
@@ -284,7 +284,6 @@
synchronized (mLock) {
tunerSessions = new TunerSession[mAidlTunerSessions.size()];
mAidlTunerSessions.toArray(tunerSessions);
- mAidlTunerSessions.clear();
}
for (TunerSession tunerSession : tunerSessions) {
@@ -402,6 +401,14 @@
mAidlTunerSessions.remove(tunerSession);
}
onTunerSessionProgramListFilterChanged(null);
+ if (mAidlTunerSessions.isEmpty()) {
+ try {
+ mService.unsetTunerCallback();
+ } catch (RemoteException ex) {
+ Slogf.wtf(TAG, ex, "Failed to unregister HAL callback for module %d",
+ mProperties.getId());
+ }
+ }
}
// add to mHandler queue