diff options
| author | 2024-09-06 15:49:34 -0700 | |
|---|---|---|
| committer | 2024-09-09 17:14:15 -0700 | |
| commit | 7f30249a02c059800bb4eb4b71fd8b22ffe2ee2f (patch) | |
| tree | 5bfa983e86ab9f894ae4a799573c4a7008067a1a | |
| parent | 1390d4a456981103766c5212920d1c38b50aad09 (diff) | |
Add interface for radio service user controller
Refactored radio service user controller to interface to avoid
mocking static methods in unit tests, which causes test flakiness.
Bug: 363965571
Flag: EXEMPT refactor
Test: atest BroadcastRadioTests
Change-Id: I1c05ff684bc969c704cb1531ee1c7efb84465003
21 files changed, 234 insertions, 152 deletions
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java index 516253b0ebff..9c9dfe8174f2 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java @@ -41,6 +41,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe private static final int USER_ID_1 = 11; private static final int USER_ID_2 = 12; + private RadioServiceUserController mUserController; @Mock private UserHandle mUserHandleMock; @@ -55,6 +56,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe public void setUp() { doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); doReturn(USER_ID_1).when(() -> ActivityManager.getCurrentUser()); + mUserController = new RadioServiceUserControllerImpl(); } @Test @@ -62,7 +64,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); assertWithMessage("Current user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + .that(mUserController.isCurrentOrSystemUser()).isTrue(); } @Test @@ -70,7 +72,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2); assertWithMessage("Non-current user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse(); + .that(mUserController.isCurrentOrSystemUser()).isFalse(); } @Test @@ -79,7 +81,7 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM); assertWithMessage("System user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + .that(mUserController.isCurrentOrSystemUser()).isTrue(); } @Test @@ -88,13 +90,13 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser); assertWithMessage("User when activity manager fails") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse(); + .that(mUserController.isCurrentOrSystemUser()).isFalse(); } @Test public void getCurrentUser() { assertWithMessage("Current user") - .that(RadioServiceUserController.getCurrentUser()).isEqualTo(USER_ID_1); + .that(mUserController.getCurrentUser()).isEqualTo(USER_ID_1); } @Test @@ -103,6 +105,6 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser); assertWithMessage("Current user when activity manager fails") - .that(RadioServiceUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL); + .that(mUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL); } } diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java index 22f3bd4abe11..63f12d82b48a 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java @@ -91,12 +91,13 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes private IAnnouncementListener mAnnouncementListenerMock; @Mock private IBinder mListenerBinderMock; + @Mock + private RadioServiceUserController mUserControllerMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { builder.spyStatic(ServiceManager.class) - .spyStatic(RadioModule.class) - .spyStatic(RadioServiceUserController.class); + .spyStatic(RadioModule.class); } @Test @@ -156,7 +157,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes @Test public void openSession_forNonCurrentUser_throwsException() throws Exception { createBroadcastRadioService(); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, @@ -206,9 +207,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes } private void createBroadcastRadioService() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); mockServiceManager(); - mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST); + mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST, mUserControllerMock); } private void mockServiceManager() throws RemoteException { @@ -222,9 +223,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes any(IServiceCallback.class))); doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class))); + eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class), any())); doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class))); + eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class), any())); when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock); when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock); 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 a952bde956d8..368df090070b 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 @@ -34,6 +34,8 @@ import android.hardware.radio.RadioManager; import android.os.ParcelableException; import android.os.RemoteException; +import com.android.server.broadcastradio.RadioServiceUserController; + import com.google.common.truth.Expect; import org.junit.Before; @@ -63,6 +65,8 @@ public final class RadioModuleTest { private IAnnouncementListener mListenerMock; @Mock private android.hardware.broadcastradio.ICloseHandle mHalCloseHandleMock; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -70,7 +74,8 @@ public final class RadioModuleTest { @Before public void setup() throws RemoteException { - mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES); + mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES, + mUserControllerMock); // TODO(b/241118988): test non-null image for getImage method when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null); 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 92dfe38c31fe..e0b97dc3cb2a 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 @@ -152,6 +152,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Mock private IBroadcastRadio mBroadcastRadioMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -170,8 +172,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class) - .spyStatic(Binder.class); + builder.spyStatic(CompatChanges.class).spyStatic(Binder.class); } @Before @@ -184,11 +185,11 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt())); doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); + doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser(); mRadioModule = new RadioModule(mBroadcastRadioMock, - AidlTestUtils.makeDefaultModuleProperties()); + AidlTestUtils.makeDefaultModuleProperties(), mUserControllerMock); doAnswer(invocation -> { mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0]; @@ -237,7 +238,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); @@ -434,7 +435,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void tune_forNonCurrentUser_doesNotTune() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); RadioManager.ProgramInfo tuneInfo = AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); @@ -514,7 +515,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo( ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -593,7 +594,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo( ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -627,7 +628,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void cancel_forNonCurrentUser_doesNotCancel() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].cancel(); @@ -698,7 +699,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startBackgroundScan(); @@ -968,7 +969,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startProgramListUpdates(filter); @@ -1007,7 +1008,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); mTunerSessions[0].startProgramListUpdates(filter); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].stopProgramListUpdates(); @@ -1073,7 +1074,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception { openAidlClients(/* numClients= */ 1); int flag = UNSUPPORTED_CONFIG_FLAG + 1; - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfigFlag(flag, /* value= */ true); @@ -1138,7 +1139,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setParameters(parametersSet); @@ -1192,7 +1193,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); - doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser(); mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo( AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY)); 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 acf698bce33d..7c3f221f9bf5 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 @@ -88,11 +88,12 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes private IAnnouncementListener mAnnouncementListenerMock; @Mock private IBinder mBinderMock; + @Mock + private RadioServiceUserController mUserControllerMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioModule.class) - .spyStatic(RadioServiceUserController.class); + builder.spyStatic(RadioModule.class); } @Test @@ -156,7 +157,7 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes @Test public void openSession_forNonCurrentUser_throwsException() throws Exception { createBroadcastRadioService(); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(false); IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, @@ -206,11 +207,11 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes } private void createBroadcastRadioService() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(true); mockServiceManager(); mBroadcastRadioService = new BroadcastRadioService(/* nextModuleId= */ FM_RADIO_MODULE_ID, - mServiceManagerMock); + mServiceManagerMock, mUserControllerMock); } private void mockServiceManager() throws RemoteException { @@ -231,9 +232,9 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes }).thenReturn(true); doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(FM_RADIO_MODULE_ID), anyString())); + eq(FM_RADIO_MODULE_ID), anyString(), any())); doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(DAB_RADIO_MODULE_ID), anyString())); + eq(DAB_RADIO_MODULE_ID), anyString(), any())); 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 1f5e77038728..b53f7ca879aa 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 @@ -36,6 +36,8 @@ import android.hardware.radio.ICloseHandle; import android.hardware.radio.RadioManager; import android.os.RemoteException; +import com.android.server.broadcastradio.RadioServiceUserController; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -61,13 +63,16 @@ public final class RadioModuleHidlTest { private IAnnouncementListener mListenerMock; @Mock private android.hardware.broadcastradio.V2_0.ICloseHandle mHalCloseHandleMock; + @Mock + private RadioServiceUserController mUserControllerMock; private RadioModule mRadioModule; private android.hardware.broadcastradio.V2_0.IAnnouncementListener mHalListener; @Before public void setup() throws RemoteException { - mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES); + mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES, + mUserControllerMock); 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 8c16d79133ce..fa0744775f6d 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 @@ -38,13 +38,13 @@ import android.hardware.radio.RadioManager; import android.hardware.radio.UniqueProgramIdentifier; import android.os.RemoteException; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; -import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; import com.android.server.broadcastradio.RadioServiceUserController; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.mockito.verification.VerificationWithTimeout; @@ -55,7 +55,8 @@ import java.util.List; /** * Tests for v2 HAL RadioModule. */ -public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestCase { +@RunWith(MockitoJUnitRunner.class) +public class StartProgramListUpdatesFanoutTest { private static final String TAG = "BroadcastRadioTests.hal2.StartProgramListUpdatesFanout"; private static final VerificationWithTimeout CB_TIMEOUT = timeout(500); @@ -64,6 +65,8 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC @Mock IBroadcastRadio mBroadcastRadioMock; @Mock ITunerSession mHalTunerSessionMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -110,17 +113,12 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC private static final RadioManager.ProgramInfo TEST_DAB_INFO = TestUtils.makeProgramInfo( TEST_DAB_SELECTOR, TEST_QUALITY); - @Override - protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class); - } - @Before public void setup() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); - mRadioModule = new RadioModule(mBroadcastRadioMock, - TestUtils.makeDefaultModuleProperties()); + mRadioModule = new RadioModule(mBroadcastRadioMock, TestUtils.makeDefaultModuleProperties(), + mUserControllerMock); 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 55aae9d3396a..c18a6e31748d 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 @@ -110,21 +110,23 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Mock ITunerSession mHalTunerSessionMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; + @Mock + private RadioServiceUserController mUserControllerMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class).spyStatic(Binder.class); + builder.spyStatic(Binder.class); } @Before public void setup() throws Exception { doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); + doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser(); mRadioModule = new RadioModule(mBroadcastRadioMock, - TestUtils.makeDefaultModuleProperties()); + TestUtils.makeDefaultModuleProperties(), mUserControllerMock); doAnswer(invocation -> { mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0]; @@ -228,7 +230,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); @@ -403,7 +405,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void tune_forNonCurrentUser_doesNotTune() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); @@ -481,7 +483,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = TestUtils.makeHalProgramInfo( Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -559,7 +561,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = TestUtils.makeHalProgramInfo( Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -593,7 +595,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void cancel_forNonCurrentUser_doesNotCancel() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].cancel(); @@ -663,7 +665,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startBackgroundScan(); @@ -676,7 +678,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startProgramListUpdates(filter); @@ -715,7 +717,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); mTunerSessions[0].startProgramListUpdates(aidlFilter); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].stopProgramListUpdates(); @@ -781,7 +783,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception { openAidlClients(/* numClients= */ 1); int flag = UNSUPPORTED_CONFIG_FLAG + 1; - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfigFlag(flag, /* value= */ true); @@ -846,7 +848,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setParameters(parametersSet); @@ -900,7 +902,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); - doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser(); mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo( TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY)); diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java index 028b9b0bcbc0..fcbcb0262c95 100644 --- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java @@ -32,8 +32,9 @@ public final class BroadcastRadioService extends SystemService { public BroadcastRadioService(Context context) { super(context); ArrayList<String> serviceNameList = IRadioServiceAidlImpl.getServicesNames(); - mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this) - : new IRadioServiceAidlImpl(this, serviceNameList); + RadioServiceUserController userController = new RadioServiceUserControllerImpl(); + mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this, userController) + : new IRadioServiceAidlImpl(this, serviceNameList, userController); } @Override diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java index 16514fa813dc..332958d39a8c 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java @@ -69,8 +69,9 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub { return serviceList; } - IRadioServiceAidlImpl(BroadcastRadioService service, ArrayList<String> serviceList) { - this(service, new BroadcastRadioServiceImpl(serviceList)); + IRadioServiceAidlImpl(BroadcastRadioService service, List<String> serviceList, + RadioServiceUserController userController) { + this(service, new BroadcastRadioServiceImpl(serviceList, userController)); Slogf.i(TAG, "Initialize BroadcastRadioServiceAidl(%s)", service); } diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java index ab083429a200..67d3c95f3a23 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java @@ -59,13 +59,16 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub { @GuardedBy("mLock") private final List<RadioManager.ModuleProperties> mV1Modules; - IRadioServiceHidlImpl(BroadcastRadioService service) { + IRadioServiceHidlImpl(BroadcastRadioService service, + RadioServiceUserController userController) { mService = Objects.requireNonNull(service, "broadcast radio service cannot be null"); - mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService(); + Objects.requireNonNull(userController, "user controller cannot be null"); + mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService( + userController); mV1Modules = mHal1Client.loadModules(); OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max(); mHal2Client = new com.android.server.broadcastradio.hal2.BroadcastRadioService( - max.isPresent() ? max.getAsInt() + 1 : 0); + max.isPresent() ? max.getAsInt() + 1 : 0, userController); } @VisibleForTesting diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java index c705ebe686f2..2f8a2e623f95 100644 --- a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java +++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java @@ -16,19 +16,11 @@ package com.android.server.broadcastradio; -import android.app.ActivityManager; -import android.os.Binder; -import android.os.UserHandle; - /** - * Controller to handle users in {@link com.android.server.broadcastradio.BroadcastRadioService} + * Controller interface to handle users in + * {@link com.android.server.broadcastradio.BroadcastRadioService} */ -public final class RadioServiceUserController { - - private RadioServiceUserController() { - throw new UnsupportedOperationException( - "RadioServiceUserController class is noninstantiable"); - } +public interface RadioServiceUserController { /** * Check if the user calling the method in Broadcast Radio Service is the current user or the @@ -37,26 +29,12 @@ public final class RadioServiceUserController { * @return {@code true} if the user calling this method is the current user of system user, * {@code false} otherwise. */ - public static boolean isCurrentOrSystemUser() { - int callingUser = Binder.getCallingUserHandle().getIdentifier(); - return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM; - } + boolean isCurrentOrSystemUser(); /** * Get current foreground user for Broadcast Radio Service * * @return foreground user id. */ - public static int getCurrentUser() { - int userId = UserHandle.USER_NULL; - final long identity = Binder.clearCallingIdentity(); - try { - userId = ActivityManager.getCurrentUser(); - } catch (RuntimeException e) { - // Activity manager not running, nothing we can do assume user 0. - } finally { - Binder.restoreCallingIdentity(identity); - } - return userId; - } -} + int getCurrentUser(); +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java new file mode 100644 index 000000000000..740609f56d03 --- /dev/null +++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.broadcastradio; + +import android.app.ActivityManager; +import android.os.Binder; +import android.os.UserHandle; + +/** + * Implementation for the controller to handle users in + * {@link com.android.server.broadcastradio.BroadcastRadioService} + */ +public final class RadioServiceUserControllerImpl implements RadioServiceUserController { + + /** + * @see RadioServiceUserController#isCurrentOrSystemUser() + */ + @Override + public boolean isCurrentOrSystemUser() { + int callingUser = Binder.getCallingUserHandle().getIdentifier(); + return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM; + } + + /** + * @see RadioServiceUserController#getCurrentUser() + */ + @Override + public int getCurrentUser() { + int userId = UserHandle.USER_NULL; + final long identity = Binder.clearCallingIdentity(); + try { + userId = ActivityManager.getCurrentUser(); + } catch (RuntimeException e) { + // Activity manager not running, nothing we can do assume user 0. + } finally { + Binder.restoreCallingIdentity(identity); + } + return userId; + } +} 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 7b504659c197..06024b57e45f 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java @@ -51,6 +51,7 @@ public final class BroadcastRadioServiceImpl { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Object mLock = new Object(); + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private int mNextModuleId; @@ -77,7 +78,7 @@ public final class BroadcastRadioServiceImpl { } RadioModule radioModule = - RadioModule.tryLoadingModule(moduleId, name, newBinder); + RadioModule.tryLoadingModule(moduleId, name, newBinder, mUserController); if (radioModule == null) { Slogf.w(TAG, "No module %s with id %d (HAL AIDL)", name, moduleId); return; @@ -141,9 +142,12 @@ public final class BroadcastRadioServiceImpl { * BroadcastRadio HAL services * * @param serviceNameList list of names of AIDL BroadcastRadio HAL services + * @param userController User controller implementation */ - public BroadcastRadioServiceImpl(ArrayList<String> serviceNameList) { + public BroadcastRadioServiceImpl(List<String> serviceNameList, + RadioServiceUserController userController) { mNextModuleId = 0; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); if (DEBUG) { Slogf.d(TAG, "Initializing BroadcastRadioServiceImpl %s", IBroadcastRadio.DESCRIPTOR); } @@ -202,7 +206,7 @@ public final class BroadcastRadioServiceImpl { if (DEBUG) { Slogf.d(TAG, "Open AIDL radio session"); } - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on AIDL HAL client for non-current user"); throw new IllegalStateException("Cannot open session for non-current user"); } 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 a176a3275ee9..20ee49e25dc2 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java @@ -62,6 +62,7 @@ final class RadioModule { private final Handler mHandler; private final RadioEventLogger mLogger; private final RadioManager.ModuleProperties mProperties; + private final RadioServiceUserController mUserController; /** * Tracks antenna state reported by HAL (if any). @@ -194,15 +195,18 @@ final class RadioModule { }; @VisibleForTesting - RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties) { + RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties, + RadioServiceUserController userController) { mProperties = Objects.requireNonNull(properties, "properties cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); mHandler = new Handler(Looper.getMainLooper()); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable - static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder) { + static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder, + RadioServiceUserController userController) { try { Slogf.i(TAG, "Try loading module for module id = %d, module name = %s", moduleId, moduleName); @@ -232,7 +236,7 @@ final class RadioModule { RadioManager.ModuleProperties prop = ConversionUtils.propertiesFromHalProperties( moduleId, moduleName, service.getProperties(), amfmConfig, dabConfig); - return new RadioModule(service, prop); + return new RadioModule(service, prop, userController); } catch (RemoteException ex) { Slogf.e(TAG, ex, "Failed to load module %s", moduleName); return null; @@ -256,7 +260,7 @@ final class RadioModule { RadioManager.ProgramInfo currentProgramInfo; synchronized (mLock) { boolean isFirstTunerSession = mAidlTunerSessions.isEmpty(); - tunerSession = new TunerSession(this, mService, userCb); + tunerSession = new TunerSession(this, mService, userCb, mUserController); mAidlTunerSessions.add(tunerSession); antennaConnected = mAntennaConnected; currentProgramInfo = mCurrentProgramInfo; @@ -440,7 +444,7 @@ final class RadioModule { @GuardedBy("mLock") private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) { - int currentUserId = RadioServiceUserController.getCurrentUser(); + int currentUserId = mUserController.getCurrentUser(); List<TunerSession> deadSessions = null; for (int i = 0; i < mAidlTunerSessions.size(); i++) { if (mAidlTunerSessions.valueAt(i).mUserId != currentUserId diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java index e90a1dda6cf5..0152c08ad5cc 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java @@ -52,6 +52,7 @@ final class TunerSession extends ITuner.Stub { final android.hardware.radio.ITunerCallback mCallback; private final int mUid; private final IBroadcastRadio mService; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private boolean mIsClosed; @@ -65,11 +66,13 @@ final class TunerSession extends ITuner.Stub { private RadioManager.BandConfig mPlaceHolderConfig; TunerSession(RadioModule radioModule, IBroadcastRadio service, - android.hardware.radio.ITunerCallback callback) { + android.hardware.radio.ITunerCallback callback, + RadioServiceUserController userController) { mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback, "callback cannot be null"); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mUid = Binder.getCallingUid(); mLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @@ -126,7 +129,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for AIDL HAL client from non-current user"); return; } @@ -169,7 +172,7 @@ final class TunerSession extends ITuner.Stub { public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException { mLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on AIDL HAL client from non-current user"); return; } @@ -187,7 +190,7 @@ final class TunerSession extends ITuner.Stub { public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException { mLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot scan on AIDL HAL client from non-current user"); return; } @@ -204,7 +207,7 @@ final class TunerSession extends ITuner.Stub { @Override public void tune(ProgramSelector selector) throws RemoteException { mLogger.logRadioEvent("Tune with selector %s", selector); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on AIDL HAL client from non-current user"); return; } @@ -226,7 +229,7 @@ final class TunerSession extends ITuner.Stub { @Override public void cancel() { Slogf.i(TAG, "Cancel"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on AIDL HAL client from non-current user"); return; } @@ -255,7 +258,7 @@ final class TunerSession extends ITuner.Stub { @Override public boolean startBackgroundScan() { Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL AIDL"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user"); return false; } @@ -268,7 +271,7 @@ final class TunerSession extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException { mLogger.logRadioEvent("Start programList updates %s", filter); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on AIDL HAL client from non-current user"); return; @@ -344,7 +347,7 @@ final class TunerSession extends ITuner.Stub { @Override public void stopProgramListUpdates() throws RemoteException { mLogger.logRadioEvent("Stop programList updates"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on AIDL HAL client from non-current user"); return; @@ -389,7 +392,7 @@ final class TunerSession extends ITuner.Stub { public void setConfigFlag(int flag, boolean value) throws RemoteException { mLogger.logRadioEvent("set ConfigFlag %s to %b ", ConfigFlag.$.toString(flag), value); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for AIDL HAL client from non-current user"); return; } @@ -406,7 +409,7 @@ final class TunerSession extends ITuner.Stub { @Override public Map<String, String> setParameters(Map<String, String> parameters) { mLogger.logRadioEvent("Set parameters "); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set parameters for AIDL HAL client from non-current user"); return new ArrayMap<>(); } 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 fb42c94b56f4..6a6a3ae44c8b 100644 --- a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java @@ -35,6 +35,7 @@ public class BroadcastRadioService { * This field is used by native code, do not access or modify. */ private final long mNativeContext = nativeInit(); + private final RadioServiceUserController mUserController; private final Object mLock = new Object(); @@ -50,6 +51,10 @@ public class BroadcastRadioService { private native Tuner nativeOpenTuner(long nativeContext, int moduleId, RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback); + public BroadcastRadioService(RadioServiceUserController userController) { + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); + } + public @NonNull List<RadioManager.ModuleProperties> loadModules() { synchronized (mLock) { return Objects.requireNonNull(nativeLoadModules(mNativeContext)); @@ -58,7 +63,7 @@ public class BroadcastRadioService { public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig, boolean withAudio, ITunerCallback callback) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on HAL 1.x client for non-current user"); throw new IllegalStateException("Cannot open tuner for non-current user"); } diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java index 7cac4091c583..8e64600d2694 100644 --- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java +++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java @@ -28,6 +28,7 @@ import android.os.IBinder; import android.os.RemoteException; import com.android.server.broadcastradio.RadioServiceUserController; +import com.android.server.broadcastradio.RadioServiceUserControllerImpl; import com.android.server.utils.Slogf; import java.util.List; @@ -51,6 +52,7 @@ class Tuner extends ITuner.Stub { private boolean mIsMuted = false; private int mRegion; private final boolean mWithAudio; + private final RadioServiceUserController mUserController = new RadioServiceUserControllerImpl(); Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio, int band) { @@ -127,7 +129,7 @@ class Tuner extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for HAL 1.x client from non-current user"); return; } @@ -176,7 +178,7 @@ class Tuner extends ITuner.Stub { @Override public void step(boolean directionDown, boolean skipSubChannel) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on HAL 1.x client from non-current user"); return; } @@ -189,7 +191,7 @@ class Tuner extends ITuner.Stub { @Override public void seek(boolean directionDown, boolean skipSubChannel) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot seek on HAL 1.x client from non-current user"); return; } @@ -202,7 +204,7 @@ class Tuner extends ITuner.Stub { @Override public void tune(ProgramSelector selector) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on HAL 1.x client from non-current user"); return; } @@ -219,7 +221,7 @@ class Tuner extends ITuner.Stub { @Override public void cancel() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on HAL 1.x client from non-current user"); return; } @@ -231,7 +233,7 @@ class Tuner extends ITuner.Stub { @Override public void cancelAnnouncement() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel announcement on HAL 1.x client from non-current user"); return; } @@ -260,7 +262,7 @@ class Tuner extends ITuner.Stub { @Override public boolean startBackgroundScan() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on HAL 1.x client from non-current user"); return false; @@ -285,7 +287,7 @@ class Tuner extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on HAL 1.x client from non-current user"); return; @@ -295,7 +297,7 @@ class Tuner extends ITuner.Stub { @Override public void stopProgramListUpdates() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on HAL 1.x client from non-current user"); return; @@ -321,7 +323,7 @@ class Tuner extends ITuner.Stub { @Override public void setConfigFlag(int flag, boolean value) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for HAL 1.x client from non-current user"); return; } 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 a4efa2e330f8..3227afd82dbd 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -50,6 +50,8 @@ public final class BroadcastRadioService { private final Object mLock = new Object(); + private final RadioServiceUserController mUserController; + @GuardedBy("mLock") private int mNextModuleId; @@ -75,7 +77,8 @@ public final class BroadcastRadioService { moduleId = mNextModuleId; } - RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName); + RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName, + mUserController); if (radioModule == null) { return; } @@ -123,8 +126,9 @@ public final class BroadcastRadioService { } }; - public BroadcastRadioService(int nextModuleId) { + public BroadcastRadioService(int nextModuleId, RadioServiceUserController userController) { mNextModuleId = nextModuleId; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); try { IServiceManager manager = IServiceManager.getService(); if (manager == null) { @@ -138,8 +142,10 @@ public final class BroadcastRadioService { } @VisibleForTesting - BroadcastRadioService(int nextModuleId, IServiceManager manager) { + BroadcastRadioService(int nextModuleId, IServiceManager manager, + RadioServiceUserController userController) { mNextModuleId = nextModuleId; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); Objects.requireNonNull(manager, "Service manager cannot be null"); try { manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener); @@ -171,7 +177,7 @@ public final class BroadcastRadioService { public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig, boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException { Slogf.v(TAG, "Open HIDL 2.0 session with module id " + moduleId); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on HAL 2.0 client for non-current user"); throw new IllegalStateException("Cannot open session for non-current user"); } 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 d3b244886a64..a0d6cc2c75b0 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -66,6 +66,7 @@ final class RadioModule { private final Object mLock = new Object(); private final Handler mHandler; private final RadioEventLogger mEventLogger; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private ITunerSession mHalTunerSession; @@ -148,16 +149,18 @@ final class RadioModule { private final Set<TunerSession> mAidlTunerSessions = new ArraySet<>(); @VisibleForTesting - RadioModule(@NonNull IBroadcastRadio service, - @NonNull RadioManager.ModuleProperties properties) { + RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties, + RadioServiceUserController userController) { mProperties = Objects.requireNonNull(properties); mService = Objects.requireNonNull(service); mHandler = new Handler(Looper.getMainLooper()); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable - static RadioModule tryLoadingModule(int idx, @NonNull String fqName) { + static RadioModule tryLoadingModule(int idx, String fqName, + RadioServiceUserController controller) { try { Slogf.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName); IBroadcastRadio service = IBroadcastRadio.getService(fqName); @@ -179,7 +182,7 @@ final class RadioModule { RadioManager.ModuleProperties prop = Convert.propertiesFromHal(idx, fqName, service.getProperties(), amfmConfig.value, dabConfig.value); - return new RadioModule(service, prop); + return new RadioModule(service, prop, controller); } catch (RemoteException ex) { Slogf.e(TAG, "Failed to load module " + fqName, ex); return null; @@ -208,7 +211,8 @@ final class RadioModule { }); mHalTunerSession = Objects.requireNonNull(hwSession.value); } - TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb); + TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb, + mUserController); mAidlTunerSessions.add(tunerSession); // Propagate state to new client. Note: These callbacks are invoked while holding mLock @@ -375,7 +379,7 @@ final class RadioModule { @GuardedBy("mLock") private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) { - int currentUserId = RadioServiceUserController.getCurrentUser(); + int currentUserId = mUserController.getCurrentUser(); List<TunerSession> deadSessions = null; for (TunerSession tunerSession : mAidlTunerSessions) { if (tunerSession.mUserId != currentUserId && tunerSession.mUserId 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 80efacdb12ee..f7d7d2695f5b 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java @@ -16,7 +16,6 @@ package com.android.server.broadcastradio.hal2; -import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Bitmap; import android.hardware.broadcastradio.V2_0.ConfigFlag; @@ -55,6 +54,7 @@ final class TunerSession extends ITuner.Stub { private final ITunerSession mHwSession; final int mUserId; final android.hardware.radio.ITunerCallback mCallback; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private boolean mIsClosed = false; @@ -66,12 +66,14 @@ final class TunerSession extends ITuner.Stub { // necessary only for older APIs compatibility private RadioManager.BandConfig mDummyConfig = null; - TunerSession(@NonNull RadioModule module, @NonNull ITunerSession hwSession, - @NonNull android.hardware.radio.ITunerCallback callback) { + TunerSession(RadioModule module, ITunerSession hwSession, + android.hardware.radio.ITunerCallback callback, + RadioServiceUserController userController) { mModule = Objects.requireNonNull(module); mHwSession = Objects.requireNonNull(hwSession); mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @@ -120,7 +122,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for HAL 2.0 client from non-current user"); return; } @@ -162,7 +164,7 @@ final class TunerSession extends ITuner.Stub { public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException { mEventLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on HAL 2.0 client from non-current user"); return; } @@ -177,7 +179,7 @@ final class TunerSession extends ITuner.Stub { public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException { mEventLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot scan on HAL 2.0 client from non-current user"); return; } @@ -191,7 +193,7 @@ final class TunerSession extends ITuner.Stub { @Override public void tune(ProgramSelector selector) throws RemoteException { mEventLogger.logRadioEvent("Tune with selector %s", selector); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on HAL 2.0 client from non-current user"); return; } @@ -205,7 +207,7 @@ final class TunerSession extends ITuner.Stub { @Override public void cancel() { Slogf.i(TAG, "Cancel"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on HAL 2.0 client from non-current user"); return; } @@ -230,7 +232,7 @@ final class TunerSession extends ITuner.Stub { @Override public boolean startBackgroundScan() { Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL 2.0"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on HAL 2.0 client from non-current user"); return false; @@ -242,7 +244,7 @@ final class TunerSession extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) { mEventLogger.logRadioEvent("start programList updates %s", filter); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on HAL 2.0 client from non-current user"); return; @@ -306,7 +308,7 @@ final class TunerSession extends ITuner.Stub { @Override public void stopProgramListUpdates() throws RemoteException { mEventLogger.logRadioEvent("Stop programList updates"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on HAL 2.0 client from non-current user"); return; @@ -355,7 +357,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfigFlag(int flag, boolean value) throws RemoteException { mEventLogger.logRadioEvent("Set ConfigFlag %s = %b", ConfigFlag.toString(flag), value); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for HAL 2.0 client from non-current user"); return; } @@ -368,7 +370,7 @@ final class TunerSession extends ITuner.Stub { @Override public Map<String, String> setParameters(Map<String, String> parameters) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set parameters for HAL 2.0 client from non-current user"); return new ArrayMap<>(); } |