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
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7f30249a02c059800bb4eb4b71fd8b22ffe2ee2f)
Merged-In: I1c05ff684bc969c704cb1531ee1c7efb84465003
Change-Id: I1c05ff684bc969c704cb1531ee1c7efb84465003
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 516253b..9c9dfe8 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 @@
 
     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 void setUp() {
         doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
         doReturn(USER_ID_1).when(() -> ActivityManager.getCurrentUser());
+        mUserController = new RadioServiceUserControllerImpl();
     }
 
     @Test
@@ -62,7 +64,7 @@
         when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
 
         assertWithMessage("Current user")
-                .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue();
+                .that(mUserController.isCurrentOrSystemUser()).isTrue();
     }
 
     @Test
@@ -70,7 +72,7 @@
         when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2);
 
         assertWithMessage("Non-current user")
-                .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse();
+                .that(mUserController.isCurrentOrSystemUser()).isFalse();
     }
 
     @Test
@@ -79,7 +81,7 @@
         when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
 
         assertWithMessage("System user")
-                .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue();
+                .that(mUserController.isCurrentOrSystemUser()).isTrue();
     }
 
     @Test
@@ -88,13 +90,13 @@
         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 @@
         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 22f3bd4..63f12d8 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 @@
     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 @@
     @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 @@
     }
 
     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 @@
                 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 a952bde..368df09 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.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 @@
     private IAnnouncementListener mListenerMock;
     @Mock
     private android.hardware.broadcastradio.ICloseHandle mHalCloseHandleMock;
+    @Mock
+    private RadioServiceUserController mUserControllerMock;
 
     // RadioModule under test
     private RadioModule mRadioModule;
@@ -70,7 +74,8 @@
 
     @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 e963caf..6a6231e 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
@@ -151,6 +151,8 @@
     @Mock
     private IBroadcastRadio mBroadcastRadioMock;
     private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
+    @Mock
+    private RadioServiceUserController mUserControllerMock;
 
     // RadioModule under test
     private RadioModule mRadioModule;
@@ -169,8 +171,7 @@
 
     @Override
     protected void initializeSession(StaticMockitoSessionBuilder builder) {
-        builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class)
-                .spyStatic(Binder.class);
+        builder.spyStatic(CompatChanges.class).spyStatic(Binder.class);
     }
 
     @Before
@@ -183,11 +184,11 @@
                 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];
@@ -224,7 +225,7 @@
     @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);
 
@@ -421,7 +422,7 @@
     @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);
@@ -501,7 +502,7 @@
         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);
 
@@ -580,7 +581,7 @@
         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);
 
@@ -614,7 +615,7 @@
     @Test
     public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
         openAidlClients(/* numClients= */ 1);
-        doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
 
         mTunerSessions[0].cancel();
 
@@ -685,7 +686,7 @@
     @Test
     public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception {
         openAidlClients(/* numClients= */ 1);
-        doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser();
 
         mTunerSessions[0].startBackgroundScan();
 
@@ -955,7 +956,7 @@
         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);
 
@@ -994,7 +995,7 @@
         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();
 
@@ -1060,7 +1061,7 @@
     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);
 
@@ -1125,7 +1126,7 @@
         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);
 
@@ -1179,7 +1180,7 @@
     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 acf698b..7c3f221 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 @@
     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 @@
     @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 @@
     }
 
     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 @@
                 }).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 1f5e770..b53f7ca 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.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 @@
     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 8c16d79..fa07447 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.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 @@
 /**
  * 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 @@
     @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 @@
     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 55aae9d..c18a6e3 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 @@
     @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 @@
     @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 @@
     @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 @@
         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 @@
         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 @@
     @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 @@
     @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 @@
         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 @@
         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 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 @@
         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 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 028b9b0..fcbcb02 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 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 16514fa..332958d 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 @@
         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 ab08342..67d3c95 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 @@
     @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 c705ebe..2f8a2e6 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 @@
      * @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 0000000..740609f
--- /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 d9f8588..bf9d1a3 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 @@
     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 @@
                 }
 
                 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 @@
      * 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 @@
         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 03e347a..928fa29 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 @@
     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 @@
     };
 
     @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 @@
             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;
@@ -255,7 +259,7 @@
         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;
@@ -433,7 +437,7 @@
 
     @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 e90a1dd..0152c08 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 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 @@
     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 @@
 
     @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 @@
     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 @@
     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 @@
     @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 @@
     @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 @@
     @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 @@
     @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 @@
     @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 @@
     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 @@
     @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 fb42c94..6a6a3ae 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 @@
      * 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 @@
     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 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 7cac409..8e64600d2 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.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 @@
     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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 a4efa2e..3227afd 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 @@
 
     private final Object mLock = new Object();
 
+    private final RadioServiceUserController mUserController;
+
     @GuardedBy("mLock")
     private int mNextModuleId;
 
@@ -75,7 +77,8 @@
                     moduleId = mNextModuleId;
                 }
 
-                RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName);
+                RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName,
+                        mUserController);
                 if (radioModule == null) {
                     return;
                 }
@@ -123,8 +126,9 @@
         }
     };
 
-    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 @@
     }
 
     @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 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 d3b2448..a0d6cc2 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 @@
     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 @@
     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 @@
             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 @@
                 });
                 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 @@
 
     @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 80efacd..f7d7d26 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 @@
     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 @@
     // 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 @@
 
     @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 @@
     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 @@
     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 @@
     @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 @@
     @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 @@
     @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 @@
     @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 @@
     @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 @@
     @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 @@
 
     @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<>();
         }