1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.connectivity 17 18 import android.Manifest 19 import android.app.role.OnRoleHoldersChangedListener 20 import android.app.role.RoleManager 21 import android.content.BroadcastReceiver 22 import android.content.Context 23 import android.content.Intent 24 import android.content.IntentFilter 25 import android.content.pm.ApplicationInfo 26 import android.content.pm.PackageManager 27 import android.os.Build 28 import android.os.Handler 29 import android.os.Looper 30 import android.os.UserHandle 31 import android.os.UserManager 32 import android.util.ArraySet 33 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 34 import com.android.testutils.DevSdkIgnoreRunner 35 import java.util.concurrent.Executor 36 import java.util.function.Consumer 37 import org.junit.Before 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import org.mockito.ArgumentCaptor 41 import org.mockito.ArgumentMatchers.any 42 import org.mockito.ArgumentMatchers.anyInt 43 import org.mockito.ArgumentMatchers.eq 44 import org.mockito.ArgumentMatchers.isNull 45 import org.mockito.Mockito.doReturn 46 import org.mockito.Mockito.mock 47 import org.mockito.Mockito.never 48 import org.mockito.Mockito.timeout 49 import org.mockito.Mockito.times 50 import org.mockito.Mockito.verify 51 52 private const val PRIMARY_USER = 0 53 private const val SECONDARY_USER = 10 54 private val PRIMARY_USER_HANDLE = UserHandle.of(PRIMARY_USER) 55 private val SECONDARY_USER_HANDLE = UserHandle.of(SECONDARY_USER) 56 57 // sms app names 58 private const val SMS_APP1 = "sms_app_1" 59 private const val SMS_APP2 = "sms_app_2" 60 61 // sms app ids 62 private const val SMS_APP_ID1 = 100 63 private const val SMS_APP_ID2 = 101 64 65 // UID for app1 and app2 on primary user 66 // These app could become default sms app for user1 67 private val PRIMARY_USER_SMS_APP_UID1 = UserHandle.getUid(PRIMARY_USER, SMS_APP_ID1) 68 private val PRIMARY_USER_SMS_APP_UID2 = UserHandle.getUid(PRIMARY_USER, SMS_APP_ID2) 69 70 // UID for app1 and app2 on secondary user 71 // These app could become default sms app for user2 72 private val SECONDARY_USER_SMS_APP_UID1 = UserHandle.getUid(SECONDARY_USER, SMS_APP_ID1) 73 private val SECONDARY_USER_SMS_APP_UID2 = UserHandle.getUid(SECONDARY_USER, SMS_APP_ID2) 74 75 @RunWith(DevSdkIgnoreRunner::class) 76 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 77 class SatelliteAccessControllerTest { 78 private val context = mock(Context::class.java) 79 private val primaryUserContext = mock(Context::class.java) 80 private val secondaryUserContext = mock(Context::class.java) 81 private val mPackageManagerPrimaryUser = mock(PackageManager::class.java) 82 private val mPackageManagerSecondaryUser = mock(PackageManager::class.java) 83 private val mDeps = mock(SatelliteAccessController.Dependencies::class.java) 84 private val mCallback = mock(Consumer::class.java) as Consumer<Set<Int>> 85 private val userManager = mock(UserManager::class.java) 86 private val mHandler = Handler(Looper.getMainLooper()) 87 private var mSatelliteAccessController = 88 SatelliteAccessController(context, mDeps, mCallback, mHandler) 89 private lateinit var mRoleHolderChangedListener: OnRoleHoldersChangedListener 90 private lateinit var mUserRemovedReceiver: BroadcastReceiver 91 mockServicenull92 private fun <T> mockService(name: String, clazz: Class<T>, service: T) { 93 doReturn(name).`when`(context).getSystemServiceName(clazz) 94 doReturn(service).`when`(context).getSystemService(name) 95 if (context.getSystemService(clazz) == null) { 96 // Test is using mockito-extended 97 doReturn(service).`when`(context).getSystemService(clazz) 98 } 99 } 100 101 @Before 102 @Throws(PackageManager.NameNotFoundException::class) setupnull103 fun setup() { 104 doReturn(emptyList<UserHandle>()).`when`(userManager).getUserHandles(true) 105 mockService(Context.USER_SERVICE, UserManager::class.java, userManager) 106 107 doReturn(primaryUserContext).`when`(context).createContextAsUser(PRIMARY_USER_HANDLE, 0) 108 doReturn(mPackageManagerPrimaryUser).`when`(primaryUserContext).packageManager 109 110 doReturn(secondaryUserContext).`when`(context).createContextAsUser(SECONDARY_USER_HANDLE, 0) 111 doReturn(mPackageManagerSecondaryUser).`when`(secondaryUserContext).packageManager 112 113 for (app in listOf(SMS_APP1, SMS_APP2)) { 114 doReturn(PackageManager.PERMISSION_GRANTED) 115 .`when`(mPackageManagerPrimaryUser) 116 .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, app) 117 doReturn(PackageManager.PERMISSION_GRANTED) 118 .`when`(mPackageManagerSecondaryUser) 119 .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, app) 120 } 121 122 // Initialise message application primary user package1 123 val applicationInfo1 = ApplicationInfo() 124 applicationInfo1.uid = PRIMARY_USER_SMS_APP_UID1 125 doReturn(applicationInfo1) 126 .`when`(mPackageManagerPrimaryUser) 127 .getApplicationInfo(eq(SMS_APP1), anyInt()) 128 129 // Initialise message application primary user package2 130 val applicationInfo2 = ApplicationInfo() 131 applicationInfo2.uid = PRIMARY_USER_SMS_APP_UID2 132 doReturn(applicationInfo2) 133 .`when`(mPackageManagerPrimaryUser) 134 .getApplicationInfo(eq(SMS_APP2), anyInt()) 135 136 // Initialise message application secondary user package1 137 val applicationInfo3 = ApplicationInfo() 138 applicationInfo3.uid = SECONDARY_USER_SMS_APP_UID1 139 doReturn(applicationInfo3) 140 .`when`(mPackageManagerSecondaryUser) 141 .getApplicationInfo(eq(SMS_APP1), anyInt()) 142 143 // Initialise message application secondary user package2 144 val applicationInfo4 = ApplicationInfo() 145 applicationInfo4.uid = SECONDARY_USER_SMS_APP_UID2 146 doReturn(applicationInfo4) 147 .`when`(mPackageManagerSecondaryUser) 148 .getApplicationInfo(eq(SMS_APP2), anyInt()) 149 } 150 151 @Test test_onRoleHoldersChanged_SatelliteFallbackUid_Changed_SingleUsernull152 fun test_onRoleHoldersChanged_SatelliteFallbackUid_Changed_SingleUser() { 153 startSatelliteAccessController() 154 doReturn(listOf<String>()).`when`(mDeps).getRoleHoldersAsUser( 155 RoleManager.ROLE_SMS, 156 PRIMARY_USER_HANDLE 157 ) 158 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 159 verify(mCallback, never()).accept(any()) 160 161 // check DEFAULT_MESSAGING_APP1 is available as satellite network fallback uid 162 doReturn(listOf(SMS_APP1)) 163 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 164 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 165 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) 166 167 // check SMS_APP2 is available as satellite network Fallback uid 168 doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( 169 RoleManager.ROLE_SMS, 170 PRIMARY_USER_HANDLE 171 ) 172 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 173 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) 174 175 // check no uid is available as satellite network fallback uid 176 doReturn(listOf<String>()).`when`(mDeps).getRoleHoldersAsUser( 177 RoleManager.ROLE_SMS, 178 PRIMARY_USER_HANDLE 179 ) 180 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 181 verify(mCallback).accept(ArraySet()) 182 } 183 184 @Test test_onRoleHoldersChanged_NoSatelliteCommunicationPermissionnull185 fun test_onRoleHoldersChanged_NoSatelliteCommunicationPermission() { 186 startSatelliteAccessController() 187 doReturn(listOf<Any>()).`when`(mDeps).getRoleHoldersAsUser( 188 RoleManager.ROLE_SMS, 189 PRIMARY_USER_HANDLE 190 ) 191 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 192 verify(mCallback, never()).accept(any()) 193 194 // check DEFAULT_MESSAGING_APP1 is not available as satellite network fallback uid 195 // since satellite communication permission not available. 196 doReturn(PackageManager.PERMISSION_DENIED) 197 .`when`(mPackageManagerPrimaryUser) 198 .checkPermission(Manifest.permission.SATELLITE_COMMUNICATION, SMS_APP1) 199 doReturn(listOf(SMS_APP1)) 200 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 201 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 202 verify(mCallback, never()).accept(any()) 203 } 204 205 @Test test_onRoleHoldersChanged_RoleSms_NotAvailablenull206 fun test_onRoleHoldersChanged_RoleSms_NotAvailable() { 207 startSatelliteAccessController() 208 doReturn(listOf(SMS_APP1)) 209 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 210 mRoleHolderChangedListener.onRoleHoldersChanged( 211 RoleManager.ROLE_BROWSER, 212 PRIMARY_USER_HANDLE 213 ) 214 verify(mCallback, never()).accept(any()) 215 } 216 217 @Test test_onRoleHoldersChanged_SatelliteNetworkFallbackUid_Changed_multiUsernull218 fun test_onRoleHoldersChanged_SatelliteNetworkFallbackUid_Changed_multiUser() { 219 startSatelliteAccessController() 220 doReturn(listOf<String>()).`when`(mDeps).getRoleHoldersAsUser( 221 RoleManager.ROLE_SMS, 222 PRIMARY_USER_HANDLE 223 ) 224 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 225 verify(mCallback, never()).accept(any()) 226 227 // check SMS_APP1 is available as satellite network fallback uid at primary user 228 doReturn(listOf(SMS_APP1)) 229 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 230 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 231 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) 232 233 // check SMS_APP2 is available as satellite network fallback uid at primary user 234 doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( 235 RoleManager.ROLE_SMS, 236 PRIMARY_USER_HANDLE 237 ) 238 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 239 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) 240 241 // check SMS_APP1 is available as satellite network fallback uid at secondary user 242 doReturn(listOf(SMS_APP1)).`when`(mDeps).getRoleHoldersAsUser( 243 RoleManager.ROLE_SMS, 244 SECONDARY_USER_HANDLE 245 ) 246 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) 247 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2, SECONDARY_USER_SMS_APP_UID1)) 248 249 // check no uid is available as satellite network fallback uid at primary user 250 doReturn(listOf<String>()).`when`(mDeps).getRoleHoldersAsUser( 251 RoleManager.ROLE_SMS, 252 PRIMARY_USER_HANDLE 253 ) 254 mRoleHolderChangedListener.onRoleHoldersChanged( 255 RoleManager.ROLE_SMS, 256 PRIMARY_USER_HANDLE 257 ) 258 verify(mCallback).accept(setOf(SECONDARY_USER_SMS_APP_UID1)) 259 260 // check SMS_APP2 is available as satellite network fallback uid at secondary user 261 doReturn(listOf(SMS_APP2)) 262 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) 263 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) 264 verify(mCallback).accept(setOf(SECONDARY_USER_SMS_APP_UID2)) 265 266 // check no uid is available as satellite network fallback uid at secondary user 267 doReturn(listOf<String>()).`when`(mDeps).getRoleHoldersAsUser( 268 RoleManager.ROLE_SMS, 269 SECONDARY_USER_HANDLE 270 ) 271 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) 272 verify(mCallback).accept(ArraySet()) 273 } 274 275 @Test test_SatelliteFallbackUidCallback_OnUserRemovalnull276 fun test_SatelliteFallbackUidCallback_OnUserRemoval() { 277 startSatelliteAccessController() 278 // check SMS_APP2 is available as satellite network fallback uid at primary user 279 doReturn(listOf(SMS_APP2)).`when`(mDeps).getRoleHoldersAsUser( 280 RoleManager.ROLE_SMS, 281 PRIMARY_USER_HANDLE 282 ) 283 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 284 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) 285 286 // check SMS_APP1 is available as satellite network fallback uid at secondary user 287 doReturn(listOf(SMS_APP1)).`when`(mDeps).getRoleHoldersAsUser( 288 RoleManager.ROLE_SMS, 289 SECONDARY_USER_HANDLE 290 ) 291 mRoleHolderChangedListener.onRoleHoldersChanged(RoleManager.ROLE_SMS, SECONDARY_USER_HANDLE) 292 verify(mCallback).accept(setOf(PRIMARY_USER_SMS_APP_UID2, SECONDARY_USER_SMS_APP_UID1)) 293 294 val userRemovalIntent = Intent(Intent.ACTION_USER_REMOVED) 295 userRemovalIntent.putExtra(Intent.EXTRA_USER, SECONDARY_USER_HANDLE) 296 mUserRemovedReceiver.onReceive(context, userRemovalIntent) 297 verify(mCallback, times(2)).accept(setOf(PRIMARY_USER_SMS_APP_UID2)) 298 } 299 300 @Test testOnStartUpCallbackSatelliteFallbackUidWithExistingUsersnull301 fun testOnStartUpCallbackSatelliteFallbackUidWithExistingUsers() { 302 doReturn( 303 listOf(PRIMARY_USER_HANDLE) 304 ).`when`(userManager).getUserHandles(true) 305 doReturn(listOf(SMS_APP1)) 306 .`when`(mDeps).getRoleHoldersAsUser(RoleManager.ROLE_SMS, PRIMARY_USER_HANDLE) 307 // At start up, SatelliteAccessController must call CS callback with existing users' 308 // default messaging apps uids. 309 startSatelliteAccessController() 310 verify(mCallback, timeout(500)).accept(setOf(PRIMARY_USER_SMS_APP_UID1)) 311 } 312 startSatelliteAccessControllernull313 private fun startSatelliteAccessController() { 314 mSatelliteAccessController.start() 315 // Get registered listener using captor 316 val listenerCaptor = ArgumentCaptor.forClass(OnRoleHoldersChangedListener::class.java) 317 verify(mDeps).addOnRoleHoldersChangedListenerAsUser( 318 any(Executor::class.java), 319 listenerCaptor.capture(), 320 any(UserHandle::class.java) 321 ) 322 mRoleHolderChangedListener = listenerCaptor.value 323 324 // Get registered receiver using captor 325 val userRemovedReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver::class.java) 326 verify(context).registerReceiver( 327 userRemovedReceiverCaptor.capture(), 328 any(IntentFilter::class.java), 329 isNull(), 330 any(Handler::class.java) 331 ) 332 mUserRemovedReceiver = userRemovedReceiverCaptor.value 333 } 334 } 335