1 /* 2 * Copyright (C) 2021 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 17 package com.android.server.uwb; 18 19 import static com.android.server.uwb.UwbCountryCode.DEFAULT_COUNTRY_CODE; 20 import static com.android.server.uwb.data.UwbUciConstants.STATUS_CODE_FAILED; 21 import static com.android.server.uwb.data.UwbUciConstants.STATUS_CODE_OK; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.mockito.Mockito.any; 25 import static org.mockito.Mockito.anyDouble; 26 import static org.mockito.Mockito.anyFloat; 27 import static org.mockito.Mockito.anyInt; 28 import static org.mockito.Mockito.anyLong; 29 import static org.mockito.Mockito.anyString; 30 import static org.mockito.Mockito.clearInvocations; 31 import static org.mockito.Mockito.doThrow; 32 import static org.mockito.Mockito.eq; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.never; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.verifyNoMoreInteractions; 37 import static org.mockito.Mockito.when; 38 39 import android.app.AlarmManager; 40 import android.app.PendingIntent; 41 import android.content.BroadcastReceiver; 42 import android.content.Context; 43 import android.content.Intent; 44 import android.content.IntentFilter; 45 import android.content.pm.PackageManager; 46 import android.location.Address; 47 import android.location.Geocoder; 48 import android.location.Location; 49 import android.location.LocationListener; 50 import android.location.LocationManager; 51 import android.net.wifi.WifiManager; 52 import android.net.wifi.WifiManager.ActiveCountryCodeChangedCallback; 53 import android.os.Handler; 54 import android.os.Looper; 55 import android.os.UserHandle; 56 import android.os.test.TestLooper; 57 import android.provider.Settings; 58 import android.telephony.SubscriptionInfo; 59 import android.telephony.SubscriptionManager; 60 import android.telephony.TelephonyManager; 61 import android.util.Pair; 62 63 import androidx.test.filters.SmallTest; 64 65 import com.android.server.uwb.jni.NativeUwbManager; 66 import com.android.uwb.flags.FeatureFlags; 67 68 import org.junit.Before; 69 import org.junit.Test; 70 import org.mockito.ArgumentCaptor; 71 import org.mockito.Captor; 72 import org.mockito.Mock; 73 import org.mockito.MockitoAnnotations; 74 75 import java.nio.charset.StandardCharsets; 76 import java.util.List; 77 78 /** 79 * Unit tests for {@link com.android.server.uwb.UwbCountryCode}. 80 */ 81 @SmallTest 82 public class UwbCountryCodeTest { 83 private static final String TEST_COUNTRY_CODE = "US"; 84 private static final String TEST_COUNTRY_CODE_OTHER = "JP"; 85 private static final String ISO_COUNTRY_CODE = "UK"; 86 private static final int TEST_SUBSCRIPTION_ID = 0; 87 private static final int TEST_SLOT_IDX = 0; 88 private static final int TEST_SUBSCRIPTION_ID_OTHER = 1; 89 private static final int TEST_SLOT_IDX_OTHER = 1; 90 91 @Mock Context mContext; 92 @Mock TelephonyManager mTelephonyManager; 93 @Mock SubscriptionManager mSubscriptionManager; 94 @Mock LocationManager mLocationManager; 95 @Mock Geocoder mGeocoder; 96 @Mock WifiManager mWifiManager; 97 @Mock NativeUwbManager mNativeUwbManager; 98 @Mock UwbInjector mUwbInjector; 99 @Mock PackageManager mPackageManager; 100 @Mock Location mLocation; 101 @Mock UwbCountryCode.CountryCodeChangedListener mListener; 102 @Mock DeviceConfigFacade mDeviceConfigFacade; 103 @Mock FeatureFlags mFeatureFlags; 104 @Mock UwbSettingsStore mUwbSettingsStore; 105 @Mock AlarmManager mGeocodeRetryTimer; 106 @Mock IntentFilter mGeocoderRetryIntentFilter; 107 @Mock PendingIntent mGeocodeRetryPendingIntent; 108 @Mock LocationListener mFusedLocationListener; 109 @Mock Intent mLocalIntent; 110 @Mock UserHandle mUserHandle; 111 @Mock Looper mLooper; 112 113 private TestLooper mTestLooper; 114 private UwbCountryCode mUwbCountryCode; 115 116 @Captor 117 private ArgumentCaptor<BroadcastReceiver> mTelephonyCountryCodeReceiverCaptor; 118 @Captor 119 private ArgumentCaptor<ActiveCountryCodeChangedCallback> mWifiCountryCodeReceiverCaptor; 120 @Captor 121 private ArgumentCaptor<LocationListener> mLocationListenerCaptor; 122 @Captor 123 private ArgumentCaptor<LocationListener> mFusedLocationListenerCaptor; 124 @Captor 125 private ArgumentCaptor<Geocoder.GeocodeListener> mGeocodeListenerCaptor; 126 127 /** 128 * Setup test. 129 */ 130 @Before setUp()131 public void setUp() throws Exception { 132 MockitoAnnotations.initMocks(this); 133 mTestLooper = new TestLooper(); 134 135 // Setup the unit tests to have default behavior of using the getNetworkCountryIso(). This 136 // should not have any effect as below the TelephonyManager is setup to return some active 137 // subscription(s) (which should also be the typical behavior when phone has a SIM). 138 when(mUwbInjector.getFeatureFlags()).thenReturn(mFeatureFlags); 139 140 when(mContext.createContext(any())).thenReturn(mContext); 141 when(mContext.getSystemService(TelephonyManager.class)) 142 .thenReturn(mTelephonyManager); 143 when(mContext.getSystemService(SubscriptionManager.class)) 144 .thenReturn(mSubscriptionManager); 145 when(mContext.getSystemService(WifiManager.class)) 146 .thenReturn(mWifiManager); 147 when(mContext.getSystemService(LocationManager.class)) 148 .thenReturn(mLocationManager); 149 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(List.of( 150 new SubscriptionInfo( 151 TEST_SUBSCRIPTION_ID, "", TEST_SLOT_IDX, "", "", 0, 0, "", 0, null, "901", "345", 152 "", true /* isEmbedded */, null, "", 25, false, null, false, 0, 0, 0, null, 153 null, true, 0), 154 new SubscriptionInfo( 155 TEST_SUBSCRIPTION_ID_OTHER, "", TEST_SLOT_IDX_OTHER, "", "", 0, 0, "", 0, 156 null, "450", "08", "", true /* isEmbedded */, null, "", 25, false, null, 157 false, 0, 0, 0, null, null, true, 0) 158 )); 159 when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(List.of( 160 new SubscriptionInfo( 161 TEST_SUBSCRIPTION_ID, "", TEST_SLOT_IDX, "", "", 0, 0, "", 0, null, "901", "345", 162 "", true /* isEmbedded */, null, "", 25, false, null, false, 0, 0, 0, null, 163 null, true, 0), 164 new SubscriptionInfo( 165 TEST_SUBSCRIPTION_ID_OTHER, "", TEST_SLOT_IDX_OTHER, "", "", 0, 0, "", 0, 166 null, "450", "08", "", true /* isEmbedded */, null, "", 25, false, null, 167 false, 0, 0, 0, null, null, true, 0) 168 )); 169 when(mContext.getPackageManager()).thenReturn(mPackageManager); 170 when(mLocation.getLatitude()).thenReturn(0.0); 171 when(mLocation.getLongitude()).thenReturn(0.0); 172 when(mUwbInjector.makeGeocoder()).thenReturn(mGeocoder); 173 when(mUwbInjector.isGeocoderPresent()).thenReturn(true); 174 when(mDeviceConfigFacade.isLocationUseForCountryCodeEnabled()).thenReturn(true); 175 when(mUwbInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); 176 when(mUwbInjector.getUwbSettingsStore()).thenReturn(mUwbSettingsStore); 177 when(mUwbInjector.getUwbServiceLooper()).thenReturn(mLooper); 178 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true); 179 when(mNativeUwbManager.setCountryCode(any())).thenReturn( 180 (byte) STATUS_CODE_OK); 181 182 when(mLocalIntent.getAction()).thenReturn(UwbCountryCode.GEOCODER_RETRY_TIMEOUT_INTENT); 183 when(mContext.getSystemService(AlarmManager.class)).thenReturn(mGeocodeRetryTimer); 184 185 mUwbCountryCode = new UwbCountryCode( 186 mContext, mNativeUwbManager, new Handler(mTestLooper.getLooper()), mUwbInjector); 187 188 mUwbCountryCode.addListener(mListener); 189 } 190 191 @Test testSetDefaultCountryCodeWhenNoCountryCodeAvailable()192 public void testSetDefaultCountryCodeWhenNoCountryCodeAvailable() { 193 mUwbCountryCode.initialize(); 194 verify(mNativeUwbManager).setCountryCode( 195 DEFAULT_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 196 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, DEFAULT_COUNTRY_CODE); 197 } 198 199 @Test testInitializeCountryCodeFromTelephony()200 public void testInitializeCountryCodeFromTelephony() { 201 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 202 mUwbCountryCode.initialize(); 203 verify(mNativeUwbManager).setCountryCode( 204 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 205 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 206 } 207 208 // Test that a country code is configured, when the list of active subscriptions is empty, 209 // the flag to use the NetworkCountryIso() is enabled, and it returns a valid country code. 210 @Test testInitializeCountryCodeFromTelephonyWhenSubscriptionListEmptyAndFlagEnabled()211 public void testInitializeCountryCodeFromTelephonyWhenSubscriptionListEmptyAndFlagEnabled() { 212 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(List.of()); 213 when(mTelephonyManager.getNetworkCountryIso()).thenReturn(ISO_COUNTRY_CODE); 214 215 mUwbCountryCode.initialize(); 216 217 verify(mTelephonyManager).getNetworkCountryIso(); 218 verify(mTelephonyManager, never()).getNetworkCountryIso(anyInt()); 219 verify(mNativeUwbManager).setCountryCode( 220 ISO_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 221 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, ISO_COUNTRY_CODE); 222 } 223 224 // Test that a country code is configured, when the list of active subscriptions is null, 225 // the flag to use the NetworkCountryIso() is enabled, and it returns a valid country code. 226 @Test testInitializeCountryCodeFromTelephonyWhenSubscriptionListNullAndFlagEnabled()227 public void testInitializeCountryCodeFromTelephonyWhenSubscriptionListNullAndFlagEnabled() { 228 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null); 229 when(mTelephonyManager.getNetworkCountryIso()).thenReturn(ISO_COUNTRY_CODE); 230 231 mUwbCountryCode.initialize(); 232 233 verify(mTelephonyManager).getNetworkCountryIso(); 234 verify(mTelephonyManager, never()).getNetworkCountryIso(anyInt()); 235 verify(mNativeUwbManager).setCountryCode( 236 ISO_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 237 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, ISO_COUNTRY_CODE); 238 } 239 240 // Test that a country code is not configured, when the list of active subscriptions is empty, 241 // the flag to use the NetworkCountryIso() is enabled, and it returns an empty country code. 242 @Test testInitializeCountryCodeFromTelephonyWhenSubscriptionListAndNetworkCountryEmpty()243 public void testInitializeCountryCodeFromTelephonyWhenSubscriptionListAndNetworkCountryEmpty() { 244 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(List.of()); 245 when(mTelephonyManager.getNetworkCountryIso()).thenReturn(""); 246 247 mUwbCountryCode.initialize(); 248 249 verify(mTelephonyManager).getNetworkCountryIso(); 250 verify(mTelephonyManager, never()).getNetworkCountryIso(anyInt()); 251 verifyNoMoreInteractions(mNativeUwbManager, mListener); 252 } 253 254 @Test testSkipWhenExceptionThrownInInitializeCountryCodeFromTelephony()255 public void testSkipWhenExceptionThrownInInitializeCountryCodeFromTelephony() { 256 doThrow(new IllegalArgumentException()).when(mTelephonyManager).getNetworkCountryIso( 257 anyInt()); 258 mUwbCountryCode.initialize(); 259 verify(mNativeUwbManager, never()).setCountryCode(any()); 260 verify(mListener, never()).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 261 } 262 263 @Test testInitializeCountryCodeFromTelephonyVerifyListener()264 public void testInitializeCountryCodeFromTelephonyVerifyListener() { 265 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 266 mUwbCountryCode.initialize(); 267 verify(mNativeUwbManager).setCountryCode( 268 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 269 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 270 } 271 272 @Test testSetCountryCodeFromTelephony()273 public void testSetCountryCodeFromTelephony() { 274 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 275 mUwbCountryCode.initialize(); 276 verify(mNativeUwbManager).setCountryCode( 277 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 278 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 279 clearInvocations(mNativeUwbManager, mListener); 280 281 assertEquals(Pair.create(STATUS_CODE_OK, TEST_COUNTRY_CODE), 282 mUwbCountryCode.setCountryCode(false)); 283 // already set. 284 verify(mNativeUwbManager, never()).setCountryCode( 285 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 286 verify(mListener, never()).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 287 } 288 289 @Test testSetCountryCodeFromLocation()290 public void testSetCountryCodeFromLocation() { 291 when(mLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER)) 292 .thenReturn(mLocation); 293 mUwbCountryCode.initialize(); 294 verify(mGeocoder).getFromLocation( 295 anyDouble(), anyDouble(), anyInt(), mGeocodeListenerCaptor.capture()); 296 Address mockAddress = mock(Address.class); 297 when(mockAddress.getCountryCode()).thenReturn(TEST_COUNTRY_CODE); 298 List<Address> addresses = List.of(mockAddress); 299 mGeocodeListenerCaptor.getValue().onGeocode(addresses); 300 mTestLooper.dispatchAll(); 301 verify(mNativeUwbManager).setCountryCode( 302 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 303 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 304 clearInvocations(mNativeUwbManager, mListener); 305 306 assertEquals(Pair.create(STATUS_CODE_OK, TEST_COUNTRY_CODE), 307 mUwbCountryCode.setCountryCode(false)); 308 // already set. 309 verify(mNativeUwbManager, never()).setCountryCode( 310 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 311 verify(mListener, never()).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 312 } 313 314 @Test testSetCountryCodeWhenLocationUseIsDisabled()315 public void testSetCountryCodeWhenLocationUseIsDisabled() { 316 when(mDeviceConfigFacade.isLocationUseForCountryCodeEnabled()).thenReturn(false); 317 when(mLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER)) 318 .thenReturn(mLocation); 319 mUwbCountryCode.initialize(); 320 verifyNoMoreInteractions(mGeocoder); 321 } 322 323 @Test testSetCountryCodeWithForceUpdateFromTelephony()324 public void testSetCountryCodeWithForceUpdateFromTelephony() { 325 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 326 mUwbCountryCode.initialize(); 327 clearInvocations(mNativeUwbManager, mListener); 328 329 assertEquals(Pair.create(STATUS_CODE_OK, TEST_COUNTRY_CODE), 330 mUwbCountryCode.setCountryCode(true)); 331 // set again 332 verify(mNativeUwbManager).setCountryCode( 333 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 334 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 335 } 336 337 @Test testSetCountryCodeFromOemWhenTelephonyAndWifiNotAvailable()338 public void testSetCountryCodeFromOemWhenTelephonyAndWifiNotAvailable() { 339 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 340 mUwbCountryCode.initialize(); 341 clearInvocations(mNativeUwbManager, mListener); 342 343 assertEquals(Pair.create(STATUS_CODE_OK, TEST_COUNTRY_CODE), 344 mUwbCountryCode.setCountryCode(false)); 345 // already set. 346 verify(mNativeUwbManager, never()).setCountryCode( 347 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 348 verify(mListener, never()).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 349 } 350 351 @Test testSetCountryCode_statusError()352 public void testSetCountryCode_statusError() { 353 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 354 mUwbCountryCode.initialize(); 355 clearInvocations(mNativeUwbManager); 356 357 when(mNativeUwbManager.setCountryCode(any())).thenReturn((byte) STATUS_CODE_FAILED); 358 assertEquals(Pair.create(STATUS_CODE_FAILED, TEST_COUNTRY_CODE), 359 mUwbCountryCode.setCountryCode(true)); 360 verify(mNativeUwbManager).setCountryCode( 361 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 362 verify(mListener).onCountryCodeChanged(STATUS_CODE_FAILED, TEST_COUNTRY_CODE); 363 } 364 365 @Test testChangeInTelephonyCountryCode()366 public void testChangeInTelephonyCountryCode() { 367 mUwbCountryCode.initialize(); 368 verify(mContext).registerReceiver( 369 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 370 Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 371 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, TEST_COUNTRY_CODE) 372 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 373 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 374 verify(mNativeUwbManager).setCountryCode( 375 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 376 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 377 } 378 379 @Test testChangeInWifiCountryCode()380 public void testChangeInWifiCountryCode() { 381 mUwbCountryCode.initialize(); 382 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 383 any(), mWifiCountryCodeReceiverCaptor.capture()); 384 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 385 verify(mNativeUwbManager).setCountryCode( 386 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 387 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 388 } 389 390 @Test testWifiECallback_error()391 public void testWifiECallback_error() { 392 // Disable other sources (Geocoder) for the Wifi location error test. 393 when(mUwbInjector.isGeocoderPresent()).thenReturn(false); 394 when(mDeviceConfigFacade.isLocationUseForCountryCodeEnabled()).thenReturn(false); 395 396 doThrow(new SecurityException()).when(mWifiManager) 397 .registerActiveCountryCodeChangedCallback(any(), any()); 398 mUwbCountryCode.initialize(); 399 400 verify(mWifiManager).registerActiveCountryCodeChangedCallback(any(), any()); 401 verify(mNativeUwbManager).setCountryCode( 402 DEFAULT_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 403 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, DEFAULT_COUNTRY_CODE); 404 } 405 406 @Test testGeocodingLocation_error()407 public void testGeocodingLocation_error() { 408 doThrow(new IllegalArgumentException()).when(mLocation).getLatitude(); 409 when(mLocation.getLongitude()).thenReturn(0.0); 410 mUwbCountryCode.initialize(); 411 412 verify(mLocationManager).requestLocationUpdates( 413 anyString(), anyLong(), anyFloat(), mLocationListenerCaptor.capture()); 414 mLocationListenerCaptor.getValue().onLocationChanged(mLocation); 415 verify(mNativeUwbManager).setCountryCode( 416 DEFAULT_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 417 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, DEFAULT_COUNTRY_CODE); 418 } 419 420 @Test testChangeInLocationCountryCode()421 public void testChangeInLocationCountryCode() { 422 mUwbCountryCode.initialize(); 423 verify(mLocationManager).requestLocationUpdates( 424 anyString(), anyLong(), anyFloat(), mLocationListenerCaptor.capture()); 425 mLocationListenerCaptor.getValue().onLocationChanged(mLocation); 426 verify(mGeocoder).getFromLocation( 427 anyDouble(), anyDouble(), anyInt(), mGeocodeListenerCaptor.capture()); 428 Address mockAddress = mock(Address.class); 429 when(mockAddress.getCountryCode()).thenReturn(TEST_COUNTRY_CODE); 430 List<Address> addresses = List.of(mockAddress); 431 mGeocodeListenerCaptor.getValue().onGeocode(addresses); 432 mTestLooper.dispatchAll(); 433 verify(mNativeUwbManager).setCountryCode( 434 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 435 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 436 } 437 438 @Test testChangeInTelephonyCountryCodeWhenWifiAndLocationCountryCodeAvailable()439 public void testChangeInTelephonyCountryCodeWhenWifiAndLocationCountryCodeAvailable() { 440 mUwbCountryCode.initialize(); 441 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 442 any(), mWifiCountryCodeReceiverCaptor.capture()); 443 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 444 verify(mContext).registerReceiver( 445 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 446 verify(mNativeUwbManager).setCountryCode( 447 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 448 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 449 verify(mLocationManager).requestLocationUpdates( 450 anyString(), anyLong(), anyFloat(), mLocationListenerCaptor.capture()); 451 mLocationListenerCaptor.getValue().onLocationChanged(mLocation); 452 verify(mGeocoder).getFromLocation( 453 anyDouble(), anyDouble(), anyInt(), mGeocodeListenerCaptor.capture()); 454 Address mockAddress = mock(Address.class); 455 when(mockAddress.getCountryCode()).thenReturn(TEST_COUNTRY_CODE); 456 List<Address> addresses = List.of(mockAddress); 457 mGeocodeListenerCaptor.getValue().onGeocode(addresses); 458 mTestLooper.dispatchAll(); 459 460 Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 461 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, TEST_COUNTRY_CODE_OTHER) 462 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 463 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 464 verify(mNativeUwbManager).setCountryCode( 465 TEST_COUNTRY_CODE_OTHER.getBytes(StandardCharsets.UTF_8)); 466 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE_OTHER); 467 } 468 469 @Test testUseLastKnownTelephonyCountryCodeWhenWifiAndTelephonyCountryCodeNotAvailable()470 public void testUseLastKnownTelephonyCountryCodeWhenWifiAndTelephonyCountryCodeNotAvailable() { 471 mUwbCountryCode.initialize(); 472 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 473 any(), mWifiCountryCodeReceiverCaptor.capture()); 474 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(""); 475 verify(mContext).registerReceiver( 476 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 477 verify(mNativeUwbManager).setCountryCode( 478 DEFAULT_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 479 480 Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 481 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, "") 482 .putExtra(UwbCountryCode.EXTRA_LAST_KNOWN_NETWORK_COUNTRY, TEST_COUNTRY_CODE) 483 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 484 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 485 verify(mNativeUwbManager).setCountryCode( 486 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 487 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 488 } 489 490 @Test testChangeInTelephonyCountryCodeWhenMoreThanOneSimWifiCountryCodeAvailable()491 public void testChangeInTelephonyCountryCodeWhenMoreThanOneSimWifiCountryCodeAvailable() { 492 mUwbCountryCode.initialize(); 493 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 494 any(), mWifiCountryCodeReceiverCaptor.capture()); 495 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 496 verify(mContext).registerReceiver( 497 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 498 verify(mNativeUwbManager).setCountryCode( 499 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 500 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 501 502 Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 503 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, TEST_COUNTRY_CODE_OTHER) 504 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 505 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 506 verify(mNativeUwbManager).setCountryCode( 507 TEST_COUNTRY_CODE_OTHER.getBytes(StandardCharsets.UTF_8)); 508 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE_OTHER); 509 510 intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 511 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, TEST_COUNTRY_CODE_OTHER) 512 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX_OTHER); 513 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 514 verify(mNativeUwbManager).setCountryCode( 515 TEST_COUNTRY_CODE_OTHER.getBytes(StandardCharsets.UTF_8)); 516 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE_OTHER); 517 } 518 519 @Test testForceOverrideCodeWhenTelephonyAndWifiAvailable()520 public void testForceOverrideCodeWhenTelephonyAndWifiAvailable() { 521 when(mTelephonyManager.getNetworkCountryIso(anyInt())).thenReturn(TEST_COUNTRY_CODE); 522 mUwbCountryCode.initialize(); 523 524 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 525 any(), mWifiCountryCodeReceiverCaptor.capture()); 526 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 527 clearInvocations(mNativeUwbManager, mListener); 528 529 mUwbCountryCode.setOverrideCountryCode(TEST_COUNTRY_CODE_OTHER); 530 verify(mNativeUwbManager).setCountryCode( 531 TEST_COUNTRY_CODE_OTHER.getBytes(StandardCharsets.UTF_8)); 532 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE_OTHER); 533 clearInvocations(mNativeUwbManager, mListener); 534 535 mUwbCountryCode.clearOverrideCountryCode(); 536 verify(mNativeUwbManager).setCountryCode( 537 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 538 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 539 } 540 541 @Test testUseCacheWhenTelephonyAndWifiNotAvailable()542 public void testUseCacheWhenTelephonyAndWifiNotAvailable() { 543 when(mDeviceConfigFacade.isPersistentCacheUseForCountryCodeEnabled()).thenReturn(true); 544 mUwbCountryCode.initialize(); 545 verify(mContext).registerReceiver( 546 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 547 verify(mWifiManager).registerActiveCountryCodeChangedCallback( 548 any(), mWifiCountryCodeReceiverCaptor.capture()); 549 clearInvocations(mNativeUwbManager, mListener); 550 551 // Set other country code sources 552 Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 553 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, TEST_COUNTRY_CODE) 554 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 555 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 556 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 557 verify(mNativeUwbManager).setCountryCode( 558 TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 559 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 560 verify(mUwbSettingsStore).put( 561 UwbSettingsStore.SETTINGS_CACHED_COUNTRY_CODE, TEST_COUNTRY_CODE); 562 clearInvocations(mNativeUwbManager, mListener); 563 564 // Clear all other country code sources and ensure we use the cache. 565 intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED) 566 .putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, DEFAULT_COUNTRY_CODE) 567 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, TEST_SLOT_IDX); 568 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 569 mWifiCountryCodeReceiverCaptor.getValue().onActiveCountryCodeChanged(DEFAULT_COUNTRY_CODE); 570 verifyNoMoreInteractions(mNativeUwbManager, mListener); 571 572 // Now clear the cache and ensure we reset the country code. 573 mUwbCountryCode.clearCachedCountryCode(); 574 mUwbCountryCode.setCountryCode(true); 575 verify(mNativeUwbManager).setCountryCode( 576 DEFAULT_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 577 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, DEFAULT_COUNTRY_CODE); 578 } 579 580 @Test testUsePersistentCacheAtBootupWhenTelephonyAndWifiNotAvailable()581 public void testUsePersistentCacheAtBootupWhenTelephonyAndWifiNotAvailable() { 582 when(mDeviceConfigFacade.isPersistentCacheUseForCountryCodeEnabled()).thenReturn(true); 583 when(mUwbSettingsStore.get(UwbSettingsStore.SETTINGS_CACHED_COUNTRY_CODE)) 584 .thenReturn(TEST_COUNTRY_CODE); 585 mUwbCountryCode.initialize(); 586 verify(mUwbSettingsStore).get(UwbSettingsStore.SETTINGS_CACHED_COUNTRY_CODE); 587 verify(mNativeUwbManager) 588 .setCountryCode(TEST_COUNTRY_CODE.getBytes(StandardCharsets.UTF_8)); 589 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE); 590 } 591 592 @Test testAirplaneModeDisableTriggeredFusedProviderResolving()593 public void testAirplaneModeDisableTriggeredFusedProviderResolving() { 594 when(mLocation.getLongitude()).thenReturn(0.0); 595 when(mDeviceConfigFacade.isFusedCountryCodeProviderEnabled()).thenReturn(true); 596 when(mUwbInjector.getGlobalSettingsInt(Settings.Global.AIRPLANE_MODE_ON, 0)) 597 .thenReturn(0); 598 mUwbCountryCode.initialize(); 599 600 // Now clear the cache and ensure we reset the country code. 601 mUwbCountryCode.clearCachedCountryCode(); 602 603 verify(mLocationManager).requestLocationUpdates(eq(LocationManager.FUSED_PROVIDER), 604 anyLong(), anyFloat(), mFusedLocationListenerCaptor.capture(), 605 eq(mLooper)); 606 607 //TODO: b/350063314: Update with behaviour upon receiving Location Update 608 } 609 610 @Test testAirplaneModeEnableTriggeredFusedProviderStop()611 public void testAirplaneModeEnableTriggeredFusedProviderStop() { 612 when(mDeviceConfigFacade.isFusedCountryCodeProviderEnabled()).thenReturn(true); 613 when(mUwbInjector.getGlobalSettingsInt(Settings.Global.AIRPLANE_MODE_ON, 0)) 614 .thenReturn(0); 615 616 mUwbCountryCode.initialize(); 617 mUwbCountryCode.clearCachedCountryCode(); 618 619 // Simulate user disabled APM 620 when(mUwbInjector.getGlobalSettingsInt(Settings.Global.AIRPLANE_MODE_ON, 0)) 621 .thenReturn(1); 622 623 // Now clear the cache and ensure we reset the country code. 624 mUwbCountryCode.clearCachedCountryCode(); 625 626 verify(mLocationManager).removeUpdates(mLocationListenerCaptor.capture()); 627 } 628 629 @Test testMccMncOemOverrideCountryCode()630 public void testMccMncOemOverrideCountryCode() { 631 String[] mccMncList = new String[]{ "901", "45008", "45006" }; 632 when(mUwbInjector.getOemDefaultCountryCode()).thenReturn(TEST_COUNTRY_CODE_OTHER); 633 when(mDeviceConfigFacade.getMccMncOemOverrideList()).thenReturn(mccMncList); 634 mUwbCountryCode.initialize(); 635 clearInvocations(mNativeUwbManager, mListener); 636 verify(mContext).registerReceiver( 637 mTelephonyCountryCodeReceiverCaptor.capture(), any(), any(), any()); 638 Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED); 639 mTelephonyCountryCodeReceiverCaptor.getValue().onReceive(mock(Context.class), intent); 640 verify(mNativeUwbManager).setCountryCode( 641 TEST_COUNTRY_CODE_OTHER.getBytes(StandardCharsets.UTF_8)); 642 verify(mListener).onCountryCodeChanged(STATUS_CODE_OK, TEST_COUNTRY_CODE_OTHER); 643 } 644 }