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

Commit 6402193c authored by Weilin Xu's avatar Weilin Xu
Browse files

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
parent c8b8b298
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -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);
+1 −2
Original line number Diff line number Diff line
@@ -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));

+1 −2
Original line number Diff line number Diff line
@@ -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];
+1 −2
Original line number Diff line number Diff line
@@ -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];
+13 −6
Original line number Diff line number Diff line
@@ -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());
        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();
        synchronized (mLock) {
            radioPw.printf("Modules of HAL1: %s\n", mV1Modules);
        }
        radioPw.decreaseIndent();

        radioPw.printf("HAL2:\n");
Loading