diff --git a/service/src/com/android/server/connectivity/SatelliteAccessController.java b/service/src/com/android/server/connectivity/SatelliteAccessController.java index b53abce8fe..2cdc932a12 100644 --- a/service/src/com/android/server/connectivity/SatelliteAccessController.java +++ b/service/src/com/android/server/connectivity/SatelliteAccessController.java @@ -20,7 +20,10 @@ import android.Manifest; import android.annotation.NonNull; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Handler; @@ -49,7 +52,6 @@ public class SatelliteAccessController { private final Context mContext; private final Dependencies mDeps; private final DefaultMessageRoleListener mDefaultMessageRoleListener; - private final UserManager mUserManager; private final Consumer> mCallback; private final Handler mConnectivityServiceHandler; @@ -114,7 +116,6 @@ public class SatelliteAccessController { @NonNull final Handler connectivityServiceInternalHandler) { mContext = c; mDeps = deps; - mUserManager = mContext.getSystemService(UserManager.class); mDefaultMessageRoleListener = new DefaultMessageRoleListener(); mCallback = callback; mConnectivityServiceHandler = connectivityServiceInternalHandler; @@ -165,9 +166,6 @@ public class SatelliteAccessController { } // on Role sms change triggered by OnRoleHoldersChangedListener() - // TODO(b/326373613): using UserLifecycleListener, callback to be received when user removed for - // user delete scenario. This to be used to update uid list and ML Layer request can also be - // updated. private void onRoleSmsChanged(@NonNull UserHandle userHandle) { int userId = userHandle.getIdentifier(); if (userId == Process.INVALID_UID) { @@ -184,9 +182,8 @@ public class SatelliteAccessController { mAllUsersSatelliteNetworkFallbackUidCache.get(userId, new ArraySet<>()); Log.i(TAG, "currentUser : role_sms_packages: " + userId + " : " + packageNames); - final Set newUidsForUser = !packageNames.isEmpty() - ? updateSatelliteNetworkFallbackUidListCache(packageNames, userHandle) - : new ArraySet<>(); + final Set newUidsForUser = + updateSatelliteNetworkFallbackUidListCache(packageNames, userHandle); Log.i(TAG, "satellite_fallback_uid: " + newUidsForUser); // on Role change, update the multilayer request at ConnectivityService with updated @@ -197,6 +194,11 @@ public class SatelliteAccessController { mAllUsersSatelliteNetworkFallbackUidCache.put(userId, newUidsForUser); + // Update all users fallback cache for user, send cs fallback to update ML request + reportSatelliteNetworkFallbackUids(); + } + + private void reportSatelliteNetworkFallbackUids() { // Merge all uids of multiple users available Set mergedSatelliteNetworkFallbackUidCache = new ArraySet<>(); for (int i = 0; i < mAllUsersSatelliteNetworkFallbackUidCache.size(); i++) { @@ -210,27 +212,48 @@ public class SatelliteAccessController { mCallback.accept(mergedSatelliteNetworkFallbackUidCache); } - private List getRoleSmsChangedPackageName(UserHandle userHandle) { - try { - return mDeps.getRoleHoldersAsUser(RoleManager.ROLE_SMS, userHandle); - } catch (RuntimeException e) { - Log.wtf(TAG, "Could not get package name at role sms change update due to: " + e); - return null; - } - } - - /** Register OnRoleHoldersChangedListener */ public void start() { mConnectivityServiceHandler.post(this::updateAllUserRoleSmsUids); + + // register sms OnRoleHoldersChangedListener mDefaultMessageRoleListener.register(); + + // Monitor for User removal intent, to update satellite fallback uids. + IntentFilter userRemovedFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (Intent.ACTION_USER_REMOVED.equals(action)) { + final UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER); + if (userHandle == null) return; + updateSatelliteFallbackUidListOnUserRemoval(userHandle.getIdentifier()); + } else { + Log.wtf(TAG, "received unexpected intent: " + action); + } + } + }, userRemovedFilter, null, mConnectivityServiceHandler); + } private void updateAllUserRoleSmsUids() { - List existingUsers = mUserManager.getUserHandles(true /* excludeDying */); + UserManager userManager = mContext.getSystemService(UserManager.class); + // get existing user handles of available users + List existingUsers = userManager.getUserHandles(true /*excludeDying*/); + // Iterate through the user handles and obtain their uids with role sms and satellite // communication permission + Log.i(TAG, "existing users: " + existingUsers); for (UserHandle userHandle : existingUsers) { onRoleSmsChanged(userHandle); } } + + private void updateSatelliteFallbackUidListOnUserRemoval(int userIdRemoved) { + Log.i(TAG, "user id removed:" + userIdRemoved); + if (mAllUsersSatelliteNetworkFallbackUidCache.contains(userIdRemoved)) { + mAllUsersSatelliteNetworkFallbackUidCache.remove(userIdRemoved); + reportSatelliteNetworkFallbackUids(); + } + } } diff --git a/tests/unit/java/com/android/server/connectivity/SatelliteAccessControllerTest.kt b/tests/unit/java/com/android/server/connectivity/SatelliteAccessControllerTest.kt index 193078b57d..788532565f 100644 --- a/tests/unit/java/com/android/server/connectivity/SatelliteAccessControllerTest.kt +++ b/tests/unit/java/com/android/server/connectivity/SatelliteAccessControllerTest.kt @@ -18,17 +18,22 @@ package com.android.server.connectivity import android.Manifest import android.app.role.OnRoleHoldersChangedListener import android.app.role.RoleManager +import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.content.pm.ApplicationInfo import android.content.pm.PackageManager -import android.content.pm.UserInfo import android.os.Build import android.os.Handler +import android.os.Looper import android.os.UserHandle +import android.os.UserManager import android.util.ArraySet -import com.android.server.makeMockUserManager import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo import com.android.testutils.DevSdkIgnoreRunner +import java.util.concurrent.Executor +import java.util.function.Consumer import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -36,30 +41,32 @@ import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.eq +import org.mockito.ArgumentMatchers.isNull import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock import org.mockito.Mockito.never +import org.mockito.Mockito.timeout +import org.mockito.Mockito.times import org.mockito.Mockito.verify -import java.util.concurrent.Executor -import java.util.function.Consumer -private const val USER = 0 -val USER_INFO = UserInfo(USER, "" /* name */, UserInfo.FLAG_PRIMARY) -val USER_HANDLE = UserHandle(USER) private const val PRIMARY_USER = 0 private const val SECONDARY_USER = 10 private val PRIMARY_USER_HANDLE = UserHandle.of(PRIMARY_USER) private val SECONDARY_USER_HANDLE = UserHandle.of(SECONDARY_USER) + // sms app names private const val SMS_APP1 = "sms_app_1" private const val SMS_APP2 = "sms_app_2" + // sms app ids private const val SMS_APP_ID1 = 100 private const val SMS_APP_ID2 = 101 + // UID for app1 and app2 on primary user // These app could become default sms app for user1 private val PRIMARY_USER_SMS_APP_UID1 = UserHandle.getUid(PRIMARY_USER, SMS_APP_ID1) private val PRIMARY_USER_SMS_APP_UID2 = UserHandle.getUid(PRIMARY_USER, SMS_APP_ID2) + // UID for app1 and app2 on secondary user // These app could become default sms app for user2 private val SECONDARY_USER_SMS_APP_UID1 = UserHandle.getUid(SECONDARY_USER, SMS_APP_ID1) @@ -69,154 +76,259 @@ private val SECONDARY_USER_SMS_APP_UID2 = UserHandle.getUid(SECONDARY_USER, SMS_ @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) class SatelliteAccessControllerTest { private val context = mock(Context::class.java) - private val mPackageManager = mock(PackageManager::class.java) - private val mHandler = mock(Handler::class.java) - private val mRoleManager = - mock(SatelliteAccessController.Dependencies::class.java) + private val primaryUserContext = mock(Context::class.java) + private val secondaryUserContext = mock(Context::class.java) + private val mPackageManagerPrimaryUser = mock(PackageManager::class.java) + private val mPackageManagerSecondaryUser = mock(PackageManager::class.java) + private val mDeps = mock(SatelliteAccessController.Dependencies::class.java) private val mCallback = mock(Consumer::class.java) as Consumer> - private val mSatelliteAccessController = - SatelliteAccessController(context, mRoleManager, mCallback, mHandler) + private val userManager = mock(UserManager::class.java) + private val mHandler = Handler(Looper.getMainLooper()) + private var mSatelliteAccessController = + SatelliteAccessController(context, mDeps, mCallback, mHandler) private lateinit var mRoleHolderChangedListener: OnRoleHoldersChangedListener + private lateinit var mUserRemovedReceiver: BroadcastReceiver + + private fun mockService(name: String, clazz: Class, service: T) { + doReturn(name).`when`(context).getSystemServiceName(clazz) + doReturn(service).`when`(context).getSystemService(name) + if (context.getSystemService(clazz) == null) { + // Test is using mockito-extended + doReturn(service).`when`(context).getSystemService(clazz) + } + } + @Before @Throws(PackageManager.NameNotFoundException::class) fun setup() { - makeMockUserManager(USER_INFO, USER_HANDLE) - doReturn(context).`when`(context).createContextAsUser(any(), anyInt()) - doReturn(mPackageManager).`when`(context).packageManager + doReturn(emptyList()).`when`(userManager).getUserHandles(true) + mockService(Context.USER_SERVICE, UserManager::class.java, userManager) - doReturn(PackageManager.PERMISSION_GRANTED) - .`when`(mPackageManager) - .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, SMS_APP1) - doReturn(PackageManager.PERMISSION_GRANTED) - .`when`(mPackageManager) - .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, SMS_APP2) + doReturn(primaryUserContext).`when`(context).createContextAsUser(PRIMARY_USER_HANDLE, 0) + doReturn(mPackageManagerPrimaryUser).`when`(primaryUserContext).packageManager - // Initialise default message application primary user package1 + doReturn(secondaryUserContext).`when`(context).createContextAsUser(SECONDARY_USER_HANDLE, 0) + doReturn(mPackageManagerSecondaryUser).`when`(secondaryUserContext).packageManager + + for (app in listOf(SMS_APP1, SMS_APP2)) { + doReturn(PackageManager.PERMISSION_GRANTED) + .`when`(mPackageManagerPrimaryUser) + .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, app) + doReturn(PackageManager.PERMISSION_GRANTED) + .`when`(mPackageManagerSecondaryUser) + .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, app) + } + + // Initialise message application primary user package1 val applicationInfo1 = ApplicationInfo() applicationInfo1.uid = PRIMARY_USER_SMS_APP_UID1 doReturn(applicationInfo1) - .`when`(mPackageManager) + .`when`(mPackageManagerPrimaryUser) .getApplicationInfo(eq(SMS_APP1), anyInt()) - // Initialise default message application primary user package2 + // Initialise message application primary user package2 val applicationInfo2 = ApplicationInfo() applicationInfo2.uid = PRIMARY_USER_SMS_APP_UID2 doReturn(applicationInfo2) - .`when`(mPackageManager) + .`when`(mPackageManagerPrimaryUser) .getApplicationInfo(eq(SMS_APP2), anyInt()) - // Get registered listener using captor - val listenerCaptor = ArgumentCaptor.forClass( - OnRoleHoldersChangedListener::class.java - ) - mSatelliteAccessController.start() - verify(mRoleManager).addOnRoleHoldersChangedListenerAsUser( - any(Executor::class.java), listenerCaptor.capture(), any(UserHandle::class.java)) - mRoleHolderChangedListener = listenerCaptor.value + // Initialise message application secondary user package1 + val applicationInfo3 = ApplicationInfo() + applicationInfo3.uid = SECONDARY_USER_SMS_APP_UID1 + doReturn(applicationInfo3) + .`when`(mPackageManagerSecondaryUser) + .getApplicationInfo(eq(SMS_APP1), anyInt()) + + // Initialise message application secondary user package2 + val applicationInfo4 = ApplicationInfo() + applicationInfo4.uid = SECONDARY_USER_SMS_APP_UID2 + doReturn(applicationInfo4) + .`when`(mPackageManagerSecondaryUser) + .getApplicationInfo(eq(SMS_APP2), anyInt()) } @Test fun test_onRoleHoldersChanged_SatelliteFallbackUid_Changed_SingleUser() { - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + startSatelliteAccessController() + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback, never()).accept(any()) // check DEFAULT_MESSAGING_APP1 is available as satellite network fallback uid doReturn(listOf(SMS_APP1)) - .`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) // check SMS_APP2 is available as satellite network Fallback uid - doReturn(listOf(SMS_APP2)).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) // check no uid is available as satellite network fallback uid - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback).accept(ArraySet()) } @Test fun test_onRoleHoldersChanged_NoSatelliteCommunicationPermission() { - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + startSatelliteAccessController() + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback, never()).accept(any()) // check DEFAULT_MESSAGING_APP1 is not available as satellite network fallback uid // since satellite communication permission not available. doReturn(PackageManager.PERMISSION_DENIED) - .`when`(mPackageManager) + .`when`(mPackageManagerPrimaryUser) .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, SMS_APP1) doReturn(listOf(SMS_APP1)) - .`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback, never()).accept(any()) } @Test fun test_onRoleHoldersChanged_RoleSms_NotAvailable() { + startSatelliteAccessController() doReturn(listOf(SMS_APP1)) - .`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) - mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_BROWSER, - PRIMARY_USER_HANDLE) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + mRoleHolderChangedListener.onRoleHoldersChanged( + RoleManager.ROLE_BROWSER, + PRIMARY_USER_HANDLE + ) verify(mCallback, never()).accept(any()) } @Test fun test_onRoleHoldersChanged_SatelliteNetworkFallbackUid_Changed_multiUser() { - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + startSatelliteAccessController() + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback, never()).accept(any()) // check SMS_APP1 is available as satellite network fallback uid at primary user doReturn(listOf(SMS_APP1)) - .`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) // check SMS_APP2 is available as satellite network fallback uid at primary user - doReturn(listOf(SMS_APP2)).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) // check SMS_APP1 is available as satellite network fallback uid at secondary user - val applicationInfo1 = ApplicationInfo() - applicationInfo1.uid = SECONDARY_USER_SMS_APP_UID1 - doReturn(applicationInfo1).`when`(mPackageManager) - .getApplicationInfo(eq(SMS_APP1), anyInt()) - doReturn(listOf(SMS_APP1)).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - SECONDARY_USER_HANDLE) + doReturn(listOf(SMS_APP1)).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + SECONDARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2, SECONDARY_USER_SMS_APP_UID1)) // check no uid is available as satellite network fallback uid at primary user - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) - mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, - PRIMARY_USER_HANDLE) + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) + mRoleHolderChangedListener.onRoleHoldersChanged( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) verify(mCallback).accept(setOf(SECONDARY_USER_SMS_APP_UID1)) // check SMS_APP2 is available as satellite network fallback uid at secondary user - applicationInfo1.uid = SECONDARY_USER_SMS_APP_UID2 - doReturn(applicationInfo1).`when`(mPackageManager) - .getApplicationInfo(eq(SMS_APP2), anyInt()) doReturn(listOf(SMS_APP2)) - .`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) verify(mCallback).accept(setOf(SECONDARY_USER_SMS_APP_UID2)) // check no uid is available as satellite network fallback uid at secondary user - doReturn(listOf()).`when`(mRoleManager).getRoleHoldersAsUser(RoleManager.ROLE_SMS, - SECONDARY_USER_HANDLE) + doReturn(listOf()).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + SECONDARY_USER_HANDLE + ) mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) verify(mCallback).accept(ArraySet()) } + + @Test + fun test_SatelliteFallbackUidCallback_OnUserRemoval() { + startSatelliteAccessController() + // check SMS_APP2 is available as satellite network fallback uid at primary user + doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + PRIMARY_USER_HANDLE + ) + mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) + + // check SMS_APP1 is available as satellite network fallback uid at secondary user + doReturn(listOf(SMS_APP1)).`when`(mDeps).getRoleHoldersAsUser( + RoleManager.ROLE_SMS, + SECONDARY_USER_HANDLE + ) + mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) + verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2, SECONDARY_USER_SMS_APP_UID1)) + + val userRemovalIntent = Intent(Intent.ACTION_USER_REMOVED) + userRemovalIntent.putExtra(Intent.EXTRA_USER, SECONDARY_USER_HANDLE) + mUserRemovedReceiver.onReceive(context, userRemovalIntent) + verify(mCallback, times(2)).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) + } + + @Test + fun testOnStartUpCallbackSatelliteFallbackUidWithExistingUsers() { + doReturn( + listOf(PRIMARY_USER_HANDLE) + ).`when`(userManager).getUserHandles(true) + doReturn(listOf(SMS_APP1)) + .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) + // At start up, SatelliteAccessController must call CS callback with existing users' + // default messaging apps uids. + startSatelliteAccessController() + verify(mCallback, timeout(500)).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) + } + + private fun startSatelliteAccessController() { + mSatelliteAccessController.start() + // Get registered listener using captor + val listenerCaptor = ArgumentCaptor.forClass(OnRoleHoldersChangedListener::class.java) + verify(mDeps).addOnRoleHoldersChangedListenerAsUser( + any(Executor::class.java), + listenerCaptor.capture(), + any(UserHandle::class.java) + ) + mRoleHolderChangedListener = listenerCaptor.value + + // Get registered receiver using captor + val userRemovedReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver::class.java) + verify(context).registerReceiver( + userRemovedReceiverCaptor.capture(), + any(IntentFilter::class.java), + isNull(), + any(Handler::class.java) + ) + mUserRemovedReceiver = userRemovedReceiverCaptor.value + } }