• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }