summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Weilin Xu <xuweilin@google.com> 2022-11-30 23:00:38 +0000
committer Weilin Xu <xuweilin@google.com> 2022-12-01 19:07:20 +0000
commit6402193c32c258a76fe2991244d6e632b80724be (patch)
tree6338a7be9e690b4f637e03138accbe6149ed8e7a
parentc8b8b2986c8b165b8831e9dfd61fd4694bf59eb3 (diff)
Refactor locks in radio client for HIDL HAL
Seperate locks were used for radio service implementation, radio module, and tuner session in HIDL 2.0 and 1.x HAL clients to minimize performance issue. Potential dead lock issue in TunerSession#close was also fixed. Bug: 258688572 Test: atest com.android.server.broadcastradio.hal2 Test: atest android.broadcastradio.cts Change-Id: I63b1ee6b2d22c424133e7f208148e2863078cc40
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java8
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java3
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java3
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java3
-rw-r--r--services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java19
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java10
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java19
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java101
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java40
9 files changed, 108 insertions, 98 deletions
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
index 0b7bbeaab28e..c9224bfbe1c7 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
@@ -59,8 +59,6 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
new ArrayList<>(Arrays.asList("FmService", "DabService"));
private static final int[] TEST_ENABLED_TYPES = new int[]{Announcement.TYPE_TRAFFIC};
- private final Object mLock = new Object();
-
private BroadcastRadioService mBroadcastRadioService;
private DeathRecipient mFmDeathRecipient;
@@ -200,7 +198,7 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
mockServiceManager();
mBroadcastRadioService = new BroadcastRadioService(/* nextModuleId= */ FM_RADIO_MODULE_ID,
- mLock, mServiceManagerMock);
+ mServiceManagerMock);
}
private void mockServiceManager() throws RemoteException {
@@ -221,9 +219,9 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
}).thenReturn(true);
doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(FM_RADIO_MODULE_ID), anyString(), any(Object.class)));
+ eq(FM_RADIO_MODULE_ID), anyString()));
doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule(
- eq(DAB_RADIO_MODULE_ID), anyString(), any(Object.class)));
+ eq(DAB_RADIO_MODULE_ID), anyString()));
when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock);
when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
index 48f5a461d631..1f5e77038728 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java
@@ -62,13 +62,12 @@ public final class RadioModuleHidlTest {
@Mock
private android.hardware.broadcastradio.V2_0.ICloseHandle mHalCloseHandleMock;
- private final Object mLock = new Object();
private RadioModule mRadioModule;
private android.hardware.broadcastradio.V2_0.IAnnouncementListener mHalListener;
@Before
public void setup() throws RemoteException {
- mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES, mLock);
+ mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES);
when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0));
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index e3c9faa601e7..7d604d497984 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -64,7 +64,6 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
@Mock ITunerSession mHalTunerSessionMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
- private final Object mLock = new Object();
// RadioModule under test
private RadioModule mRadioModule;
@@ -100,7 +99,7 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
- TestUtils.makeDefaultModuleProperties(), mLock);
+ TestUtils.makeDefaultModuleProperties());
doAnswer((Answer) invocation -> {
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index b7da5d038f77..ff988a21473a 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -84,7 +84,6 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
new RadioManager.FmBandConfig(FM_BAND_DESCRIPTOR);
private static final int UNSUPPORTED_CONFIG_FLAG = 0;
- private final Object mLock = new Object();
private final ArrayMap<Integer, Boolean> mHalConfigMap = new ArrayMap<>();
private RadioModule mRadioModule;
private ITunerCallback mHalTunerCallback;
@@ -105,7 +104,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
- TestUtils.makeDefaultModuleProperties(), mLock);
+ TestUtils.makeDefaultModuleProperties());
doAnswer(invocation -> {
mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0];
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index a8e4034e3f86..408fba1bff3b 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -27,6 +27,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.broadcastradio.hal2.AnnouncementAggregator;
@@ -51,15 +52,17 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub {
private final Object mLock = new Object();
private final BroadcastRadioService mService;
+
+ @GuardedBy("mLock")
private final List<RadioManager.ModuleProperties> mV1Modules;
IRadioServiceHidlImpl(BroadcastRadioService service) {
mService = Objects.requireNonNull(service, "broadcast radio service cannot be null");
- mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService(mLock);
+ mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
mV1Modules = mHal1.loadModules();
OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
- max.isPresent() ? max.getAsInt() + 1 : 0, mLock);
+ max.isPresent() ? max.getAsInt() + 1 : 0);
}
@VisibleForTesting
@@ -78,9 +81,11 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub {
public List<RadioManager.ModuleProperties> listModules() {
mService.enforcePolicyAccess();
Collection<RadioManager.ModuleProperties> v2Modules = mHal2.listModules();
- List<RadioManager.ModuleProperties> modules = new ArrayList<>(
- mV1Modules.size() + v2Modules.size());
- modules.addAll(mV1Modules);
+ List<RadioManager.ModuleProperties> modules;
+ synchronized (mLock) {
+ modules = new ArrayList<>(mV1Modules.size() + v2Modules.size());
+ modules.addAll(mV1Modules);
+ }
modules.addAll(v2Modules);
return modules;
}
@@ -131,7 +136,9 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub {
radioPw.printf("HAL1: %s\n", mHal1);
radioPw.increaseIndent();
- radioPw.printf("Modules of HAL1: %s\n", mV1Modules);
+ synchronized (mLock) {
+ radioPw.printf("Modules of HAL1: %s\n", mV1Modules);
+ }
radioPw.decreaseIndent();
radioPw.printf("HAL2:\n");
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
index e50c6e8c21b8..fb42c94b56f4 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
@@ -36,7 +36,7 @@ public class BroadcastRadioService {
*/
private final long mNativeContext = nativeInit();
- private final Object mLock;
+ private final Object mLock = new Object();
@Override
protected void finalize() throws Throwable {
@@ -50,14 +50,6 @@ public class BroadcastRadioService {
private native Tuner nativeOpenTuner(long nativeContext, int moduleId,
RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback);
- /**
- * Constructor. should pass
- * {@code com.android.server.broadcastradio.BroadcastRadioService#mLock} for lock.
- */
- public BroadcastRadioService(Object lock) {
- mLock = lock;
- }
-
public @NonNull List<RadioManager.ModuleProperties> loadModules() {
synchronized (mLock) {
return Objects.requireNonNull(nativeLoadModules(mNativeContext));
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 3d6962783f4a..984bf5125582 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -43,13 +43,16 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
-public class BroadcastRadioService {
+/**
+ * Broadcast radio service using BroadcastRadio HIDL 2.0 HAL
+ */
+public final class BroadcastRadioService {
private static final String TAG = "BcRadio2Srv";
- private final Object mLock;
+ private final Object mLock = new Object();
@GuardedBy("mLock")
- private int mNextModuleId = 0;
+ private int mNextModuleId;
@GuardedBy("mLock")
private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>();
@@ -72,7 +75,7 @@ public class BroadcastRadioService {
moduleId = mNextModuleId;
}
- RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName, mLock);
+ RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName);
if (module == null) {
return;
}
@@ -120,9 +123,8 @@ public class BroadcastRadioService {
}
};
- public BroadcastRadioService(int nextModuleId, Object lock) {
+ public BroadcastRadioService(int nextModuleId) {
mNextModuleId = nextModuleId;
- mLock = lock;
try {
IServiceManager manager = IServiceManager.getService();
if (manager == null) {
@@ -136,9 +138,8 @@ public class BroadcastRadioService {
}
@VisibleForTesting
- BroadcastRadioService(int nextModuleId, Object lock, IServiceManager manager) {
+ BroadcastRadioService(int nextModuleId, IServiceManager manager) {
mNextModuleId = nextModuleId;
- mLock = lock;
Objects.requireNonNull(manager, "Service manager cannot be null");
try {
manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
@@ -180,7 +181,7 @@ public class BroadcastRadioService {
throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.0");
}
- RadioModule module = null;
+ RadioModule module;
synchronized (mLock) {
module = mModules.get(moduleId);
if (module == null) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index cf1b504037bc..0ea5f0fc1d6a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -60,7 +60,7 @@ final class RadioModule {
@NonNull private final IBroadcastRadio mService;
@NonNull private final RadioManager.ModuleProperties mProperties;
- private final Object mLock;
+ private final Object mLock = new Object();
@NonNull private final Handler mHandler;
@NonNull private final RadioEventLogger mEventLogger;
@@ -75,7 +75,7 @@ final class RadioModule {
private RadioManager.ProgramInfo mCurrentProgramInfo = null;
@GuardedBy("mLock")
- private final ProgramInfoCache mProgramInfoCache = new ProgramInfoCache(null);
+ private final ProgramInfoCache mProgramInfoCache = new ProgramInfoCache(/* filter= */ null);
@GuardedBy("mLock")
private android.hardware.radio.ProgramList.Filter mUnionOfAidlProgramFilters = null;
@@ -84,47 +84,59 @@ final class RadioModule {
private final ITunerCallback mHalTunerCallback = new ITunerCallback.Stub() {
@Override
public void onTuneFailed(int result, ProgramSelector programSelector) {
- lockAndFireLater(() -> {
+ fireLater(() -> {
android.hardware.radio.ProgramSelector csel =
Convert.programSelectorFromHal(programSelector);
- fanoutAidlCallbackLocked(cb -> cb.onTuneFailed(result, csel));
+ synchronized (mLock) {
+ fanoutAidlCallbackLocked(cb -> cb.onTuneFailed(result, csel));
+ }
});
}
@Override
public void onCurrentProgramInfoChanged(ProgramInfo halProgramInfo) {
- lockAndFireLater(() -> {
- mCurrentProgramInfo = Convert.programInfoFromHal(halProgramInfo);
- fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(mCurrentProgramInfo));
+ fireLater(() -> {
+ synchronized (mLock) {
+ mCurrentProgramInfo = Convert.programInfoFromHal(halProgramInfo);
+ RadioManager.ProgramInfo currentProgramInfo = mCurrentProgramInfo;
+ fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(
+ currentProgramInfo));
+ }
});
}
@Override
public void onProgramListUpdated(ProgramListChunk programListChunk) {
- lockAndFireLater(() -> {
+ fireLater(() -> {
android.hardware.radio.ProgramList.Chunk chunk =
Convert.programListChunkFromHal(programListChunk);
- mProgramInfoCache.filterAndApplyChunk(chunk);
+ synchronized (mLock) {
+ mProgramInfoCache.filterAndApplyChunk(chunk);
- for (TunerSession tunerSession : mAidlTunerSessions) {
- tunerSession.onMergedProgramListUpdateFromHal(chunk);
+ for (TunerSession tunerSession : mAidlTunerSessions) {
+ tunerSession.onMergedProgramListUpdateFromHal(chunk);
+ }
}
});
}
@Override
public void onAntennaStateChange(boolean connected) {
- lockAndFireLater(() -> {
- mAntennaConnected = connected;
- fanoutAidlCallbackLocked(cb -> cb.onAntennaState(connected));
+ fireLater(() -> {
+ synchronized (mLock) {
+ mAntennaConnected = connected;
+ fanoutAidlCallbackLocked(cb -> cb.onAntennaState(connected));
+ }
});
}
@Override
public void onParametersUpdated(ArrayList<VendorKeyValue> parameters) {
- lockAndFireLater(() -> {
+ fireLater(() -> {
Map<String, String> cparam = Convert.vendorInfoFromHal(parameters);
- fanoutAidlCallbackLocked(cb -> cb.onParametersUpdated(cparam));
+ synchronized (mLock) {
+ fanoutAidlCallbackLocked(cb -> cb.onParametersUpdated(cparam));
+ }
});
}
};
@@ -135,17 +147,15 @@ final class RadioModule {
@VisibleForTesting
RadioModule(@NonNull IBroadcastRadio service,
- @NonNull RadioManager.ModuleProperties properties, @NonNull Object lock) {
+ @NonNull RadioManager.ModuleProperties properties) {
mProperties = Objects.requireNonNull(properties);
mService = Objects.requireNonNull(service);
- mLock = Objects.requireNonNull(lock);
mHandler = new Handler(Looper.getMainLooper());
mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE);
}
@Nullable
- static RadioModule tryLoadingModule(int idx, @NonNull String fqName,
- Object lock) {
+ static RadioModule tryLoadingModule(int idx, @NonNull String fqName) {
try {
Slog.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName);
IBroadcastRadio service = IBroadcastRadio.getService(fqName);
@@ -167,7 +177,7 @@ final class RadioModule {
RadioManager.ModuleProperties prop = Convert.propertiesFromHal(idx, fqName,
service.getProperties(), amfmConfig.value, dabConfig.value);
- return new RadioModule(service, prop, lock);
+ return new RadioModule(service, prop);
} catch (RemoteException ex) {
Slog.e(TAG, "Failed to load module " + fqName, ex);
return null;
@@ -196,8 +206,7 @@ final class RadioModule {
});
mHalTunerSession = Objects.requireNonNull(hwSession.value);
}
- TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb,
- mLock);
+ TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb);
mAidlTunerSessions.add(tunerSession);
// Propagate state to new client. Note: These callbacks are invoked while holding mLock
@@ -229,6 +238,7 @@ final class RadioModule {
}
}
+ @GuardedBy("mLock")
@Nullable
private android.hardware.radio.ProgramList.Filter
buildUnionOfTunerSessionFiltersLocked() {
@@ -281,6 +291,7 @@ final class RadioModule {
}
}
+ @GuardedBy("mLock")
private void onTunerSessionProgramListFilterChangedLocked(@Nullable TunerSession session) {
android.hardware.radio.ProgramList.Filter newFilter =
buildUnionOfTunerSessionFiltersLocked();
@@ -325,6 +336,7 @@ final class RadioModule {
}
}
+ @GuardedBy("mLock")
private void onTunerSessionsClosedLocked(TunerSession... tunerSessions) {
for (TunerSession tunerSession : tunerSessions) {
mAidlTunerSessions.remove(tunerSession);
@@ -342,12 +354,8 @@ final class RadioModule {
}
// add to mHandler queue, but ensure the runnable holds mLock when it gets executed
- private void lockAndFireLater(Runnable r) {
- mHandler.post(() -> {
- synchronized (mLock) {
- r.run();
- }
- });
+ private void fireLater(Runnable r) {
+ mHandler.post(() -> r.run());
}
interface AidlCallbackRunnable {
@@ -356,9 +364,14 @@ final class RadioModule {
// Invokes runnable with each TunerSession currently open.
void fanoutAidlCallback(AidlCallbackRunnable runnable) {
- lockAndFireLater(() -> fanoutAidlCallbackLocked(runnable));
+ fireLater(() -> {
+ synchronized (mLock) {
+ fanoutAidlCallbackLocked(runnable);
+ }
+ });
}
+ @GuardedBy("mLock")
private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
List<TunerSession> deadSessions = null;
for (TunerSession tunerSession : mAidlTunerSessions) {
@@ -399,12 +412,10 @@ final class RadioModule {
}
};
- synchronized (mLock) {
- mService.registerAnnouncementListener(enabledList, hwListener, (result, closeHnd) -> {
- halResult.value = result;
- hwCloseHandle.value = closeHnd;
- });
- }
+ mService.registerAnnouncementListener(enabledList, hwListener, (result, closeHandle) -> {
+ halResult.value = result;
+ hwCloseHandle.value = closeHandle;
+ });
Convert.throwOnError("addAnnouncementListener", halResult.value);
return new android.hardware.radio.ICloseHandle.Stub() {
@@ -424,12 +435,10 @@ final class RadioModule {
if (id == 0) throw new IllegalArgumentException("Image ID is missing");
byte[] rawImage;
- synchronized (mLock) {
- List<Byte> rawList = Utils.maybeRethrow(() -> mService.getImage(id));
- rawImage = new byte[rawList.size()];
- for (int i = 0; i < rawList.size(); i++) {
- rawImage[i] = rawList.get(i);
- }
+ List<Byte> rawList = Utils.maybeRethrow(() -> mService.getImage(id));
+ rawImage = new byte[rawList.size()];
+ for (int i = 0; i < rawList.size(); i++) {
+ rawImage[i] = rawList.get(i);
}
if (rawImage == null || rawImage.length == 0) return null;
@@ -440,17 +449,17 @@ final class RadioModule {
void dumpInfo(IndentingPrintWriter pw) {
pw.printf("RadioModule\n");
pw.increaseIndent();
+ pw.printf("BroadcastRadioService: %s\n", mService);
+ pw.printf("Properties: %s\n", mProperties);
synchronized (mLock) {
- pw.printf("BroadcastRadioService: %s\n", mService);
- pw.printf("Properties: %s\n", mProperties);
- pw.printf("HIDL2.0 HAL TunerSession: %s\n", mHalTunerSession);
+ pw.printf("HIDL 2.0 HAL TunerSession: %s\n", mHalTunerSession);
pw.printf("Is antenna connected? ");
if (mAntennaConnected == null) {
pw.printf("null\n");
} else {
pw.printf("%s\n", mAntennaConnected ? "Yes" : "No");
}
- pw.printf("current ProgramInfo: %s\n", mCurrentProgramInfo);
+ pw.printf("Current ProgramInfo: %s\n", mCurrentProgramInfo);
pw.printf("ProgramInfoCache: %s\n", mProgramInfoCache);
pw.printf("Union of AIDL ProgramFilters: %s\n", mUnionOfAidlProgramFilters);
pw.printf("AIDL TunerSessions:\n");
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 12211eed47fd..7afee277fe1c 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -33,6 +33,7 @@ import android.util.MutableBoolean;
import android.util.MutableInt;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.broadcastradio.RadioServiceUserController;
import com.android.server.utils.Slogf;
@@ -46,26 +47,28 @@ class TunerSession extends ITuner.Stub {
private static final String kAudioDeviceName = "Radio tuner source";
private static final int TUNER_EVENT_LOGGER_QUEUE_SIZE = 25;
- private final Object mLock;
+ private final Object mLock = new Object();
@NonNull private final RadioEventLogger mEventLogger;
private final RadioModule mModule;
private final ITunerSession mHwSession;
final android.hardware.radio.ITunerCallback mCallback;
+
+ @GuardedBy("mLock")
private boolean mIsClosed = false;
+ @GuardedBy("mLock")
private boolean mIsMuted = false;
+ @GuardedBy("mLock")
private ProgramInfoCache mProgramInfoCache = null;
// necessary only for older APIs compatibility
private RadioManager.BandConfig mDummyConfig = null;
TunerSession(@NonNull RadioModule module, @NonNull ITunerSession hwSession,
- @NonNull android.hardware.radio.ITunerCallback callback,
- @NonNull Object lock) {
+ @NonNull android.hardware.radio.ITunerCallback callback) {
mModule = Objects.requireNonNull(module);
mHwSession = Objects.requireNonNull(hwSession);
mCallback = Objects.requireNonNull(callback);
- mLock = Objects.requireNonNull(lock);
mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}
@@ -86,23 +89,26 @@ class TunerSession extends ITuner.Stub {
mEventLogger.logRadioEvent("Close on error %d", error);
synchronized (mLock) {
if (mIsClosed) return;
- if (error != null) {
- try {
- mCallback.onError(error);
- } catch (RemoteException ex) {
- Slog.w(TAG, "mCallback.onError() failed: ", ex);
- }
- }
mIsClosed = true;
- mModule.onTunerSessionClosed(this);
}
+ if (error != null) {
+ try {
+ mCallback.onError(error);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "mCallback.onError() failed: ", ex);
+ }
+ }
+ mModule.onTunerSessionClosed(this);
}
@Override
public boolean isClosed() {
- return mIsClosed;
+ synchronized (mLock) {
+ return mIsClosed;
+ }
}
+ @GuardedBy("mLock")
private void checkNotClosedLocked() {
if (mIsClosed) {
throw new IllegalStateException("Tuner is closed, no further operations are allowed");
@@ -118,9 +124,9 @@ class TunerSession extends ITuner.Stub {
synchronized (mLock) {
checkNotClosedLocked();
mDummyConfig = Objects.requireNonNull(config);
- Slog.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL 2.0");
- mModule.fanoutAidlCallback(cb -> cb.onConfigurationChanged(config));
}
+ Slog.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL 2.0");
+ mModule.fanoutAidlCallback(cb -> cb.onConfigurationChanged(config));
}
@Override
@@ -137,8 +143,8 @@ class TunerSession extends ITuner.Stub {
checkNotClosedLocked();
if (mIsMuted == mute) return;
mIsMuted = mute;
- Slog.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
}
+ Slog.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
}
@Override
@@ -383,8 +389,8 @@ class TunerSession extends ITuner.Stub {
void dumpInfo(IndentingPrintWriter pw) {
pw.printf("TunerSession\n");
pw.increaseIndent();
+ pw.printf("HIDL HAL Session: %s\n", mHwSession);
synchronized (mLock) {
- pw.printf("HIDL HAL Session: %s\n", mHwSession);
pw.printf("Is session closed? %s\n", mIsClosed ? "Yes" : "No");
pw.printf("Is muted? %s\n", mIsMuted ? "Yes" : "No");
pw.printf("ProgramInfoCache: %s\n", mProgramInfoCache);