• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.phone.satellite.accesscontrol;
18 
19 import static android.location.LocationManager.MODE_CHANGED_ACTION;
20 import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
21 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ACCESS_CONFIGURATION;
22 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
23 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
24 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
25 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
26 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
27 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_DISABLED;
28 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_NOT_AVAILABLE;
29 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_ERROR;
30 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
31 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NO_RESOURCES;
32 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
33 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
34 
35 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.ALLOWED_STATE_CACHE_VALID_DURATION_NANOS;
36 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CMD_IS_SATELLITE_COMMUNICATION_ALLOWED;
37 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CONFIG_UPDATER_SATELLITE_VERSION_KEY;
38 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_DELAY_MINUTES_BEFORE_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
39 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
40 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
41 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_S2_LEVEL;
42 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES;
43 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CMD_UPDATE_CONFIG_DATA;
44 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_COUNTRY_CODE_CHANGED;
45 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT;
46 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT;
47 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.GOOGLE_US_SAN_SAT_S2_FILE_NAME;
48 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.SATELLITE_ACCESS_CONFIG_FILE_NAME;
49 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
50 
51 import static org.junit.Assert.assertArrayEquals;
52 import static org.junit.Assert.assertEquals;
53 import static org.junit.Assert.assertFalse;
54 import static org.junit.Assert.assertNull;
55 import static org.junit.Assert.assertSame;
56 import static org.junit.Assert.assertTrue;
57 import static org.junit.Assert.fail;
58 import static org.mockito.ArgumentMatchers.any;
59 import static org.mockito.ArgumentMatchers.anyBoolean;
60 import static org.mockito.ArgumentMatchers.anyInt;
61 import static org.mockito.ArgumentMatchers.anyList;
62 import static org.mockito.ArgumentMatchers.anyLong;
63 import static org.mockito.ArgumentMatchers.anyString;
64 import static org.mockito.ArgumentMatchers.eq;
65 import static org.mockito.ArgumentMatchers.nullable;
66 import static org.mockito.Mockito.clearInvocations;
67 import static org.mockito.Mockito.doAnswer;
68 import static org.mockito.Mockito.doNothing;
69 import static org.mockito.Mockito.doReturn;
70 import static org.mockito.Mockito.doThrow;
71 import static org.mockito.Mockito.mock;
72 import static org.mockito.Mockito.never;
73 import static org.mockito.Mockito.spy;
74 import static org.mockito.Mockito.times;
75 import static org.mockito.Mockito.verify;
76 import static org.mockito.Mockito.when;
77 
78 import android.annotation.Nullable;
79 import android.app.NotificationManager;
80 import android.content.BroadcastReceiver;
81 import android.content.Context;
82 import android.content.Intent;
83 import android.content.IntentFilter;
84 import android.content.SharedPreferences;
85 import android.content.pm.ApplicationInfo;
86 import android.content.pm.PackageManager;
87 import android.content.pm.ResolveInfo;
88 import android.content.res.Resources;
89 import android.location.Location;
90 import android.location.LocationManager;
91 import android.location.LocationRequest;
92 import android.os.AsyncResult;
93 import android.os.Build;
94 import android.os.Bundle;
95 import android.os.CancellationSignal;
96 import android.os.DropBoxManager;
97 import android.os.Handler;
98 import android.os.IBinder;
99 import android.os.Looper;
100 import android.os.Message;
101 import android.os.ResultReceiver;
102 import android.os.UserHandle;
103 import android.telecom.TelecomManager;
104 import android.telephony.SubscriptionManager;
105 import android.telephony.TelephonyManager;
106 import android.telephony.satellite.EarfcnRange;
107 import android.telephony.satellite.ISatelliteCommunicationAccessStateCallback;
108 import android.telephony.satellite.SatelliteAccessConfiguration;
109 import android.telephony.satellite.SatelliteInfo;
110 import android.telephony.satellite.SatelliteManager;
111 import android.telephony.satellite.SatellitePosition;
112 import android.telephony.satellite.SystemSelectionSpecifier;
113 import android.testing.AndroidTestingRunner;
114 import android.testing.TestableLooper;
115 import android.util.Log;
116 import android.util.Pair;
117 
118 import androidx.test.InstrumentationRegistry;
119 
120 import com.android.TelephonyTestBase;
121 import com.android.internal.telephony.Phone;
122 import com.android.internal.telephony.PhoneFactory;
123 import com.android.internal.telephony.TelephonyCountryDetector;
124 import com.android.internal.telephony.flags.FeatureFlags;
125 import com.android.internal.telephony.satellite.SatelliteConfig;
126 import com.android.internal.telephony.satellite.SatelliteConfigParser;
127 import com.android.internal.telephony.satellite.SatelliteController;
128 import com.android.internal.telephony.satellite.SatelliteModemInterface;
129 import com.android.internal.telephony.satellite.metrics.CarrierRoamingSatelliteControllerStats;
130 import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
131 import com.android.internal.telephony.subscription.SubscriptionManagerService;
132 
133 import org.junit.After;
134 import org.junit.Before;
135 import org.junit.Test;
136 import org.junit.runner.RunWith;
137 import org.mockito.ArgumentCaptor;
138 import org.mockito.Captor;
139 import org.mockito.Mock;
140 
141 import java.io.File;
142 import java.io.FileOutputStream;
143 import java.io.IOException;
144 import java.io.InputStream;
145 import java.util.ArrayList;
146 import java.util.Arrays;
147 import java.util.HashMap;
148 import java.util.Iterator;
149 import java.util.List;
150 import java.util.Map;
151 import java.util.Set;
152 import java.util.UUID;
153 import java.util.concurrent.ConcurrentHashMap;
154 import java.util.concurrent.Executor;
155 import java.util.concurrent.Semaphore;
156 import java.util.concurrent.TimeUnit;
157 import java.util.function.Consumer;
158 import java.util.stream.Collectors;
159 import java.util.stream.IntStream;
160 
161 /** Unit test for {@link SatelliteAccessController} */
162 @RunWith(AndroidTestingRunner.class)
163 @TestableLooper.RunWithLooper
164 public class SatelliteAccessControllerTest extends TelephonyTestBase {
165     private static final String TAG = "SatelliteAccessControllerTest";
166     private static final String[] TEST_SATELLITE_COUNTRY_CODES = {"US", "CA", "UK"};
167     private static final String[] TEST_SATELLITE_COUNTRY_CODES_EMPTY = {""};
168     private static final String TEST_SATELLITE_COUNTRY_CODE_US = "US";
169     private static final String TEST_SATELLITE_COUNTRY_CODE_KR = "KR";
170     private static final String TEST_SATELLITE_COUNTRY_CODE_JP = "JP";
171 
172     private static final String TEST_SATELLITE_S2_FILE = "sat_s2_file.dat";
173     private static final boolean TEST_SATELLITE_ALLOW = true;
174     private static final boolean TEST_SATELLITE_NOT_ALLOW = false;
175     private static final int TEST_LOCATION_FRESH_DURATION_SECONDS = 10;
176     private static final long TEST_LOCATION_FRESH_DURATION_NANOS =
177             TimeUnit.SECONDS.toNanos(TEST_LOCATION_FRESH_DURATION_SECONDS);
178     private static final long TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS =
179             TimeUnit.MINUTES.toNanos(10);  // DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES
180     private static final long TIMEOUT = 500;
181     private static final List<String> EMPTY_STRING_LIST = new ArrayList<>();
182     private static final List<String> LOCATION_PROVIDERS =
183             listOf(LocationManager.NETWORK_PROVIDER, LocationManager.FUSED_PROVIDER);
184     private static final int SUB_ID = 0;
185 
186     @Mock
187     private LocationManager mMockLocationManager;
188     @Mock
189     private TelecomManager mMockTelecomManager;
190     @Mock
191     private TelephonyCountryDetector mMockCountryDetector;
192     @Mock
193     private SatelliteController mMockSatelliteController;
194     @Mock
195     private SatelliteModemInterface mMockSatelliteModemInterface;
196     @Mock
197     private DropBoxManager mMockDropBoxManager;
198     private Context mMockContext;  // alias of mContext
199     @Mock
200     private Phone mMockPhone;
201     @Mock
202     private Phone mMockPhone2;
203     @Mock
204     private FeatureFlags mMockFeatureFlags;
205     @Mock
206     private Resources mMockResources;
207     @Mock
208     private SatelliteOnDeviceAccessController mMockSatelliteOnDeviceAccessController;
209     @Mock
210     Location mMockLocation0;
211     @Mock
212     Location mMockLocation1;
213     @Mock
214     File mMockSatS2File;
215     @Mock
216     SharedPreferences mMockSharedPreferences;
217     @Mock
218     private SharedPreferences.Editor mMockSharedPreferencesEditor;
219     @Mock
220     private Map<SatelliteOnDeviceAccessController.LocationToken, Integer>
221             mMockCachedAccessRestrictionMap;
222     @Mock
223     HashMap<Integer, SatelliteAccessConfiguration> mMockSatelliteAccessConfigMap;
224 
225     @Mock
226     private Intent mMockLocationIntent;
227     @Mock
228     private Set<ResultReceiver> mMockSatelliteAllowResultReceivers;
229     @Mock
230     private TelephonyManager mMockTelephonyManager;
231     @Mock
232     private PackageManager mMockPackageManager;
233     @Mock
234     private List<ResolveInfo> mMockResolveInfoList;
235     @Mock
236     private NotificationManager mMockNotificationManager;
237     @Mock
238     private ApplicationInfo mMockApplicationInfo;
239     @Mock
240     private ResultReceiver mMockResultReceiver;
241     @Mock
242     private ConcurrentHashMap<IBinder, ISatelliteCommunicationAccessStateCallback>
243             mSatelliteCommunicationAllowedStateCallbackMap;
244     @Mock
245     private ConcurrentHashMap<IBinder, ISatelliteCommunicationAccessStateCallback>
246             mMockSatelliteCommunicationAccessStateChangedListeners;
247     @Mock
248     private CarrierRoamingSatelliteControllerStats mCarrierRoamingSatelliteControllerStats;
249 
250     private SatelliteInfo mSatelliteInfo;
251 
252     private TestableLooper mTestableLooper;
253     private Phone[] mPhones;
254     private TestSatelliteAccessController mSatelliteAccessControllerUT;
255 
256     @Captor
257     private ArgumentCaptor<CancellationSignal> mLocationRequestCancellationSignalCaptor;
258     @Captor
259     private ArgumentCaptor<Consumer<Location>> mLocationRequestConsumerCaptor;
260     @Captor
261     private ArgumentCaptor<Handler> mConfigUpdateHandlerCaptor;
262     @Captor
263     private ArgumentCaptor<Integer> mConfigUpdateIntCaptor;
264     @Captor
265     private ArgumentCaptor<Object> mConfigUpdateObjectCaptor;
266     @Captor
267     private ArgumentCaptor<Handler> mCountryDetectorHandlerCaptor;
268     @Captor
269     private ArgumentCaptor<Integer> mCountryDetectorIntCaptor;
270     @Captor
271     private ArgumentCaptor<Object> mCountryDetectorObjCaptor;
272     @Captor
273     private ArgumentCaptor<BroadcastReceiver> mLocationBroadcastReceiverCaptor;
274     @Captor
275     private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
276     @Captor
277     private ArgumentCaptor<LocationRequest> mLocationRequestCaptor;
278     @Captor
279     private ArgumentCaptor<String> mLocationProviderStringCaptor;
280     @Captor
281     private ArgumentCaptor<Integer> mResultCodeIntCaptor;
282     @Captor
283     private ArgumentCaptor<Bundle> mResultDataBundleCaptor;
284     @Captor
285     private ArgumentCaptor<ISatelliteCommunicationAccessStateCallback> mAllowedStateCallbackCaptor;
286 
287     private boolean mQueriedSatelliteAllowed = false;
288     private int mQueriedSatelliteAllowedResultCode = SATELLITE_RESULT_SUCCESS;
289     private Semaphore mSatelliteAllowedSemaphore = new Semaphore(0);
290     private ResultReceiver mSatelliteAllowedReceiver = new ResultReceiver(null) {
291         @Override
292         protected void onReceiveResult(int resultCode, Bundle resultData) {
293             mQueriedSatelliteAllowedResultCode = resultCode;
294             if (resultCode == SATELLITE_RESULT_SUCCESS) {
295                 if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
296                     mQueriedSatelliteAllowed = resultData.getBoolean(
297                             KEY_SATELLITE_COMMUNICATION_ALLOWED);
298                 } else {
299                     logd("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
300                     mQueriedSatelliteAllowed = false;
301                 }
302             } else {
303                 logd("mSatelliteAllowedReceiver: resultCode=" + resultCode);
304                 mQueriedSatelliteAllowed = false;
305             }
306             try {
307                 mSatelliteAllowedSemaphore.release();
308             } catch (Exception ex) {
309                 fail("mSatelliteAllowedReceiver: Got exception in releasing semaphore, ex=" + ex);
310             }
311         }
312     };
313 
314     private int mQueriedSystemSelectionChannelUpdatedResultCode = SATELLITE_RESULT_SUCCESS;
315     private Semaphore mSystemSelectionChannelUpdatedSemaphore = new Semaphore(0);
316     private ResultReceiver mSystemSelectionChannelUpdatedReceiver = new ResultReceiver(null) {
317         @Override
318         protected void onReceiveResult(int resultCode, Bundle resultData) {
319             mQueriedSystemSelectionChannelUpdatedResultCode = resultCode;
320             try {
321                 mSystemSelectionChannelUpdatedSemaphore.release();
322             } catch (Exception ex) {
323                 fail("mSystemSelectionChannelUpdatedReceiver: Got exception in releasing "
324                         + "semaphore, ex="
325                         + ex);
326             }
327         }
328     };
329 
330     @Before
setUp()331     public void setUp() throws Exception {
332         logd("SatelliteAccessControllerTest setUp");
333         super.setUp();
334 
335         mMockContext = mContext;
336         mTestableLooper = TestableLooper.get(this);
337         when(mMockContext.getSystemServiceName(LocationManager.class)).thenReturn(
338                 Context.LOCATION_SERVICE);
339         when(mMockContext.getSystemServiceName(TelecomManager.class)).thenReturn(
340                 Context.TELECOM_SERVICE);
341         when(mMockContext.getSystemServiceName(DropBoxManager.class)).thenReturn(
342                 Context.DROPBOX_SERVICE);
343         when(mMockContext.getSystemService(LocationManager.class)).thenReturn(
344                 mMockLocationManager);
345         when(mMockContext.getSystemService(TelecomManager.class)).thenReturn(
346                 mMockTelecomManager);
347         when(mMockContext.getSystemService(DropBoxManager.class)).thenReturn(
348                 mMockDropBoxManager);
349         doAnswer(inv -> {
350             var args = inv.getArguments();
351             return InstrumentationRegistry.getTargetContext()
352                     .getDir((String) args[0], (Integer) args[1]);
353         }).when(mPhoneGlobals).getDir(anyString(), anyInt());
354         doAnswer(
355                         inv -> {
356                             return InstrumentationRegistry.getTargetContext().getAssets();
357                         })
358                 .when(mPhoneGlobals)
359                 .getAssets();
360         mPhones = new Phone[]{mMockPhone, mMockPhone2};
361         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
362         replaceInstance(SatelliteController.class, "sInstance", null,
363                 mMockSatelliteController);
364         replaceInstance(SatelliteModemInterface.class, "sInstance", null,
365                 mMockSatelliteModemInterface);
366         replaceInstance(SubscriptionManagerService.class, "sInstance", null,
367                 mock(SubscriptionManagerService.class));
368         replaceInstance(TelephonyCountryDetector.class, "sInstance", null,
369                 mMockCountryDetector);
370         replaceInstance(ControllerMetricsStats.class, "sInstance", null,
371                 mock(ControllerMetricsStats.class));
372         replaceInstance(CarrierRoamingSatelliteControllerStats.class, "sInstance", null,
373                 mCarrierRoamingSatelliteControllerStats);
374         when(mMockSatelliteController.getSatellitePhone()).thenReturn(mMockPhone);
375         when(mMockPhone.getSubId()).thenReturn(SubscriptionManager.getDefaultSubscriptionId());
376 
377         when(mMockContext.getResources()).thenReturn(mMockResources);
378         when(mMockResources.getStringArray(
379                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
380                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES);
381         when(mMockResources.getBoolean(
382                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
383                 .thenReturn(TEST_SATELLITE_ALLOW);
384         when(mMockResources.getString(
385                 com.android.internal.R.string.config_oem_enabled_satellite_s2cell_file))
386                 .thenReturn(TEST_SATELLITE_S2_FILE);
387         when(mMockResources.getInteger(com.android.internal.R.integer
388                 .config_oem_enabled_satellite_location_fresh_duration))
389                 .thenReturn(TEST_LOCATION_FRESH_DURATION_SECONDS);
390         when(mMockResources.getInteger(com.android.internal.R.integer
391                 .config_satellite_delay_minutes_before_retry_validating_possible_change_in_allowed_region))
392                 .thenReturn(
393                         DEFAULT_DELAY_MINUTES_BEFORE_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION);
394         when(mMockResources.getInteger(com.android.internal.R.integer
395                 .config_satellite_max_retry_count_for_validating_possible_change_in_allowed_region))
396                 .thenReturn(
397                         DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION);
398         when(mMockResources.getInteger(com.android.internal.R.integer
399                 .config_satellite_location_query_throttle_interval_minutes))
400                 .thenReturn(DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES);
401 
402         when(mMockLocationManager.getProviders(true)).thenReturn(LOCATION_PROVIDERS);
403         when(mMockLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
404                 .thenReturn(mMockLocation0);
405         when(mMockLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER))
406                 .thenReturn(mMockLocation1);
407         when(mMockLocation0.getLatitude()).thenReturn(0.0);
408         when(mMockLocation0.getLongitude()).thenReturn(0.0);
409         when(mMockLocation1.getLatitude()).thenReturn(1.0);
410         when(mMockLocation1.getLongitude()).thenReturn(1.0);
411         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
412                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
413                 .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
414 
415         doReturn(mMockSharedPreferences).when(mMockContext)
416                 .getSharedPreferences(anyString(), anyInt());
417         when(mMockSharedPreferences.getBoolean(anyString(), anyBoolean())).thenReturn(true);
418         when(mMockSharedPreferences.getStringSet(anyString(), any()))
419                 .thenReturn(Set.of(TEST_SATELLITE_COUNTRY_CODES));
420         when(mMockSharedPreferences.getInt(
421                 eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt())).thenReturn(0);
422         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit();
423         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
424                 .putBoolean(anyString(), anyBoolean());
425         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
426                 .putStringSet(anyString(), any());
427         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
428                 .putLong(anyString(), anyLong());
429         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
430                 .putInt(anyString(), anyInt());
431         doNothing().when(mMockSharedPreferencesEditor).apply();
432 
433         when(mMockFeatureFlags.geofenceEnhancementForBetterUx()).thenReturn(true);
434         when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
435 
436         when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
437                 .thenReturn(mMockTelephonyManager);
438         when(mMockTelephonyManager.isSmsCapable()).thenReturn(true);
439         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
440         mMockResolveInfoList = new ArrayList<>();
441         when(mMockPackageManager.queryBroadcastReceiversAsUser(any(Intent.class), anyInt(), any(
442                 UserHandle.class)))
443                 .thenReturn(mMockResolveInfoList);
444         when(mMockContext.getSystemServiceName(
445                 NotificationManager.class)).thenReturn(Context.NOTIFICATION_SERVICE);
446         when(mMockContext.getSystemService(Context.NOTIFICATION_SERVICE))
447                 .thenReturn(mMockNotificationManager);
448         doReturn(mMockApplicationInfo).when(mMockContext).getApplicationInfo();
449         mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
450         when(mMockPackageManager.getApplicationInfo(anyString(), anyInt()))
451                 .thenReturn(mMockApplicationInfo);
452         when(mCarrierRoamingSatelliteControllerStats.isMultiSim()).thenReturn(false);
453 
454         mSatelliteInfo = new SatelliteInfo(
455                 UUID.randomUUID(),
456                 new SatellitePosition(10, 15),
457                 new ArrayList<>(Arrays.asList(5, 30)),
458                 new ArrayList<>(Arrays.asList(new EarfcnRange(0, 250))));
459 
460         logd("setUp: Initializing mSatelliteAccessControllerUT:TestSatelliteAccessController");
461         mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
462                 mMockFeatureFlags, mTestableLooper.getLooper(), mMockLocationManager,
463                 mMockTelecomManager, mMockSatelliteOnDeviceAccessController, mMockSatS2File);
464         mTestableLooper.processAllMessages();
465     }
466 
467     @After
tearDown()468     public void tearDown() throws Exception {
469         super.tearDown();
470     }
471 
472     @Test
testGetInstance()473     public void testGetInstance() {
474         SatelliteAccessController inst1 =
475                 SatelliteAccessController.getOrCreateInstance(mMockContext, mMockFeatureFlags);
476         SatelliteAccessController inst2 =
477                 SatelliteAccessController.getOrCreateInstance(mMockContext, mMockFeatureFlags);
478         assertEquals(inst1, inst2);
479     }
480 
481     @Test
testOnCurrentLocationNotAvailable()482     public void testOnCurrentLocationNotAvailable() throws Exception {
483         // Verify the cache is used when the location is null and the cache is valid and true.
484         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
485                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS - 1;
486         mSatelliteAccessControllerUT
487                 .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_allowed");
488         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
489 
490         sendCurrentLocationTimeoutEvent();
491         assertTrue(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
492 
493         // Verify the cache is used when the location is null and the cache is valid and false.
494         mSatelliteAccessControllerUT
495                 .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_not_allowed");
496         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
497 
498         sendCurrentLocationTimeoutEvent();
499         assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
500 
501         // Verify the result code is SATELLITE_RESULT_LOCATION_NOT_AVAILABLE
502         // and allowedState is false when the location is null and the cache is expired
503         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
504                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS + 1;
505         Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
506         doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
507         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
508         doNothing().when(mMockSatelliteAllowResultReceivers).clear();
509         doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
510         replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
511                 mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
512         mSatelliteAccessControllerUT.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
513                 "cache_clear_and_not_allowed");
514         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
515 
516         sendCurrentLocationTimeoutEvent();
517         verify(mMockResultReceiver)
518                 .send(mResultCodeIntCaptor.capture(), any());
519         assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_NOT_AVAILABLE),
520                 mResultCodeIntCaptor.getValue());
521         assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
522     }
523 
524     @Test
testIsSatelliteAccessAllowedForLocation()525     public void testIsSatelliteAccessAllowedForLocation() {
526         // Test disallowList case
527         when(mMockResources.getBoolean(
528                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
529                 .thenReturn(TEST_SATELLITE_NOT_ALLOW);
530 
531         // configuration is EMPTY then we return true with any network country code.
532         when(mMockResources.getStringArray(
533                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
534                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES_EMPTY);
535         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
536         assertTrue(mSatelliteAccessControllerUT
537                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
538         assertTrue(mSatelliteAccessControllerUT
539                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_JP)));
540 
541         // configuration is ["US", "CA", "UK"]
542         // - if network country code is ["US"] or ["US","KR"] or [EMPTY] return false;
543         // - if network country code is ["KR"] return true;
544         when(mMockResources.getStringArray(
545                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
546                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES);
547         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
548         assertFalse(mSatelliteAccessControllerUT.isSatelliteAccessAllowedForLocation(List.of()));
549         assertFalse(mSatelliteAccessControllerUT
550                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
551         assertFalse(mSatelliteAccessControllerUT.isSatelliteAccessAllowedForLocation(
552                 List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_KR)));
553         assertTrue(mSatelliteAccessControllerUT
554                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_KR)));
555 
556         // Test allowList case
557         when(mMockResources.getBoolean(
558                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
559                 .thenReturn(TEST_SATELLITE_ALLOW);
560 
561         // configuration is [EMPTY] then return false in case of any network country code
562         when(mMockResources.getStringArray(
563                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
564                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES_EMPTY);
565         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
566         assertFalse(mSatelliteAccessControllerUT
567                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
568         assertFalse(mSatelliteAccessControllerUT
569                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_JP)));
570 
571         // configuration is ["US", "CA", "UK"]
572         // - if network country code is [EMPTY] or ["US","KR"] or [KR] return false;
573         // - if network country code is ["US"] return true;
574         when(mMockResources.getStringArray(
575                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
576                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES);
577         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
578         assertFalse(mSatelliteAccessControllerUT.isSatelliteAccessAllowedForLocation(List.of()));
579         assertFalse(mSatelliteAccessControllerUT
580                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_KR)));
581         assertFalse(mSatelliteAccessControllerUT.isSatelliteAccessAllowedForLocation(
582                 List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_KR)));
583         assertTrue(mSatelliteAccessControllerUT
584                 .isSatelliteAccessAllowedForLocation(List.of(TEST_SATELLITE_COUNTRY_CODE_US)));
585     }
586 
587 
setSatelliteCommunicationAllowed()588     private void setSatelliteCommunicationAllowed() throws Exception {
589         when(mMockContext.getResources()).thenReturn(mMockResources);
590         when(mMockResources.getBoolean(
591                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
592                 .thenReturn(TEST_SATELLITE_ALLOW);
593         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
594         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
595         doReturn(true).when(mMockLocationManager).isLocationEnabled();
596         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
597                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
598                 .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
599         replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
600                 mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
601         doReturn(true).when(mMockCachedAccessRestrictionMap).containsKey(any());
602         doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID)
603                 .when(mMockCachedAccessRestrictionMap).get(any());
604     }
605 
606     @Test
testRequestSatelliteAccessConfigurationForCurrentLocation()607     public void testRequestSatelliteAccessConfigurationForCurrentLocation() throws Exception {
608         // setup result receiver and satellite access configuration data
609         ResultReceiver mockResultReceiver = mock(ResultReceiver.class);
610         ArgumentCaptor<Integer> resultCodeCaptor = ArgumentCaptor.forClass(Integer.class);
611         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
612         SatelliteAccessConfiguration satelliteAccessConfig = getSatelliteAccessConfiguration();
613 
614         // setup satellite communication allowed state as true
615         setSatelliteCommunicationAllowed();
616 
617         // setup map data of location and configId.
618         replaceInstance(SatelliteAccessController.class, "mSatelliteAccessConfigMap",
619                 mSatelliteAccessControllerUT, mMockSatelliteAccessConfigMap);
620         doReturn(satelliteAccessConfig).when(mMockSatelliteAccessConfigMap).get(anyInt());
621         doReturn(null).when(mMockSatelliteAccessConfigMap).get(eq(null));
622         doReturn(null).when(mMockSatelliteAccessConfigMap)
623                 .get(eq(UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID));
624 
625         // setup callback
626         ISatelliteCommunicationAccessStateCallback mockSatelliteAllowedStateCallback = mock(
627                 ISatelliteCommunicationAccessStateCallback.class);
628         ArgumentCaptor<SatelliteAccessConfiguration> satelliteAccessConfigurationCaptor =
629                 ArgumentCaptor.forClass(SatelliteAccessConfiguration.class);
630 
631         when(mSatelliteCommunicationAllowedStateCallbackMap.values())
632                 .thenReturn(List.of(mockSatelliteAllowedStateCallback));
633         replaceInstance(SatelliteAccessController.class,
634                 "mSatelliteCommunicationAccessStateChangedListeners", mSatelliteAccessControllerUT,
635                 mSatelliteCommunicationAllowedStateCallbackMap);
636 
637         // Test when the featureFlags.carrierRoamingNbIotNtn() is false
638         doReturn(false).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
639 
640         clearInvocations(mockResultReceiver);
641         mSatelliteAccessControllerUT
642                 .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
643         mTestableLooper.processAllMessages();
644         verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
645                 bundleCaptor.capture());
646         assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, (int) resultCodeCaptor.getValue());
647         assertNull(bundleCaptor.getValue());
648         verify(mockSatelliteAllowedStateCallback, never())
649                 .onAccessConfigurationChanged(any());
650 
651         doReturn(true).when(mMockFeatureFlags).carrierRoamingNbIotNtn();
652 
653         // Verify if the map is maintained after the cleanup event
654         sendSatelliteDeviceAccessControllerResourcesTimeOutEvent();
655 
656         // satellite communication allowed state is enabled and
657         // regional config id is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID.
658         clearInvocations(mockResultReceiver);
659         clearInvocations(mockSatelliteAllowedStateCallback);
660         mSatelliteAccessControllerUT
661                 .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
662         mTestableLooper.processAllMessages();
663         verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
664                 bundleCaptor.capture());
665         assertEquals(SatelliteManager.SATELLITE_RESULT_SUCCESS, (int) resultCodeCaptor.getValue());
666         assertTrue(bundleCaptor.getValue().containsKey(KEY_SATELLITE_ACCESS_CONFIGURATION));
667         assertSame(bundleCaptor.getValue().getParcelable(KEY_SATELLITE_ACCESS_CONFIGURATION,
668                 SatelliteAccessConfiguration.class), satelliteAccessConfig);
669         verify(mockSatelliteAllowedStateCallback, times(1))
670                 .onAccessConfigurationChanged(
671                         satelliteAccessConfigurationCaptor.capture());
672         assertEquals(satelliteAccessConfigurationCaptor.getValue(), satelliteAccessConfig);
673 
674         // satellite communication allowed state is disabled and
675         // regional config id is null.
676         clearInvocations(mockResultReceiver);
677         clearInvocations(mockSatelliteAllowedStateCallback);
678         when(mMockCachedAccessRestrictionMap.get(any())).thenReturn(null);
679         mSatelliteAccessControllerUT
680                 .requestSatelliteAccessConfigurationForCurrentLocation(mockResultReceiver);
681         mTestableLooper.processAllMessages();
682 
683         verify(mockResultReceiver, times(1)).send(resultCodeCaptor.capture(),
684                 bundleCaptor.capture());
685         assertEquals(SATELLITE_RESULT_NO_RESOURCES, (int) resultCodeCaptor.getValue());
686         assertNull(bundleCaptor.getValue());
687 
688         verify(mockSatelliteAllowedStateCallback, times(1))
689                 .onAccessConfigurationChanged(
690                         satelliteAccessConfigurationCaptor.capture());
691         assertNull(satelliteAccessConfigurationCaptor.getValue());
692     }
693 
getSatelliteAccessConfiguration()694     private SatelliteAccessConfiguration getSatelliteAccessConfiguration() {
695         List<SatelliteInfo> satelliteInfoList = new ArrayList<>();
696         satelliteInfoList.add(mSatelliteInfo);
697         List<Integer> tagIds = new ArrayList<>(List.of(1, 2));
698         return new SatelliteAccessConfiguration(satelliteInfoList, tagIds);
699     }
700 
701     @Test
testRegisterForCommunicationAllowedStateChanged()702     public void testRegisterForCommunicationAllowedStateChanged() throws Exception {
703         ISatelliteCommunicationAccessStateCallback mockSatelliteAllowedStateCallback = mock(
704                 ISatelliteCommunicationAccessStateCallback.class);
705         doReturn(true).when(mSatelliteCommunicationAllowedStateCallbackMap)
706                 .put(any(IBinder.class), any(ISatelliteCommunicationAccessStateCallback.class));
707         replaceInstance(SatelliteAccessController.class,
708                 "mSatelliteCommunicationAccessStateChangedListeners", mSatelliteAccessControllerUT,
709                 mSatelliteCommunicationAllowedStateCallbackMap);
710 
711         int result = mSatelliteAccessControllerUT.registerForCommunicationAccessStateChanged(
712                 DEFAULT_SUBSCRIPTION_ID, mockSatelliteAllowedStateCallback);
713         mTestableLooper.processAllMessages();
714         assertEquals(SATELLITE_RESULT_SUCCESS, result);
715         verify(mockSatelliteAllowedStateCallback, times(1))
716                 .onAccessAllowedStateChanged(anyBoolean());
717         verify(mockSatelliteAllowedStateCallback, times(1))
718                 .onAccessConfigurationChanged(
719                         nullable(SatelliteAccessConfiguration.class));
720     }
721 
722     @Test
testNotifyRegionalSatelliteConfigurationChanged()723     public void testNotifyRegionalSatelliteConfigurationChanged() throws Exception {
724         // setup test
725         ISatelliteCommunicationAccessStateCallback mockSatelliteAllowedStateCallback = mock(
726                 ISatelliteCommunicationAccessStateCallback.class);
727         ArgumentCaptor<SatelliteAccessConfiguration> satelliteAccessConfigurationCaptor =
728                 ArgumentCaptor.forClass(SatelliteAccessConfiguration.class);
729 
730         when(mSatelliteCommunicationAllowedStateCallbackMap.values())
731                 .thenReturn(List.of(mockSatelliteAllowedStateCallback));
732         replaceInstance(SatelliteAccessController.class,
733                 "mSatelliteCommunicationAccessStateChangedListeners", mSatelliteAccessControllerUT,
734                 mSatelliteCommunicationAllowedStateCallbackMap);
735 
736         // register callback
737         mSatelliteAccessControllerUT.registerForCommunicationAccessStateChanged(
738                 DEFAULT_SUBSCRIPTION_ID, mockSatelliteAllowedStateCallback);
739 
740         // verify if the callback is
741         // the same instance from onmSatelliteCommunicationAllowedStateCallbackMap
742         verify(mSatelliteCommunicationAllowedStateCallbackMap).put(any(),
743                 mAllowedStateCallbackCaptor.capture());
744         assertSame(mockSatelliteAllowedStateCallback, mAllowedStateCallbackCaptor.getValue());
745 
746         // create SatelliteAccessConfiguration data for this test
747         SatelliteAccessConfiguration satelliteAccessConfig = getSatelliteAccessConfiguration();
748 
749         // trigger notifyRegionalSatelliteConfigurationChanged
750         mSatelliteAccessControllerUT
751                 .notifyRegionalSatelliteConfigurationChanged(satelliteAccessConfig);
752 
753         // verify if the satelliteAccessConfig is the same instance with the captured one.
754         verify(mockSatelliteAllowedStateCallback).onAccessConfigurationChanged(
755                 satelliteAccessConfigurationCaptor.capture());
756         assertSame(satelliteAccessConfig, satelliteAccessConfigurationCaptor.getValue());
757     }
758 
759     @Test
testCheckSatelliteAccessRestrictionForLocation()760     public void testCheckSatelliteAccessRestrictionForLocation() throws Exception {
761         // Setup
762         logd("testCheckSatelliteAccessRestrictionForLocation : setup");
763         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
764         ArgumentCaptor<Integer> regionalConfigIdCaptor = ArgumentCaptor.forClass(Integer.class);
765         replaceInstance(SatelliteAccessController.class, "mS2Level",
766                 mSatelliteAccessControllerUT, DEFAULT_S2_LEVEL);
767         Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
768         mSatelliteAccessControllerUT.setRegionalConfigId(null);
769 
770         doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
771         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
772         doNothing().when(mMockSatelliteAllowResultReceivers).clear();
773         doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
774         replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
775                 mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
776         replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
777                 mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
778 
779         // when mMockCachedAccessRestrictionMap is hit and has DEFAULT_REGIONAL_SATELLITE_CONFIG_ID,
780         // verify belows
781         // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is true
782         // - the newRegionalConfigId is the same as DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
783         // - the regionalConfigId is the same as DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
784         logd("testCheckSatelliteAccessRestrictionForLocation : case 1");
785         clearInvocations(mMockSatelliteOnDeviceAccessController);
786         clearInvocations(mMockCachedAccessRestrictionMap);
787 
788         doReturn(true).when(mMockCachedAccessRestrictionMap)
789                 .containsKey(any(SatelliteOnDeviceAccessController.LocationToken.class));
790         doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID).when(mMockCachedAccessRestrictionMap)
791                 .get(any(SatelliteOnDeviceAccessController.LocationToken.class));
792 
793         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
794         verify(mMockResultReceiver, times(1))
795                 .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
796         verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
797                 any(SatelliteOnDeviceAccessController.LocationToken.class));
798         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
799         assertTrue(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
800         assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
801                 mSatelliteAccessControllerUT.getNewRegionalConfigId());
802         assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
803                 mSatelliteAccessControllerUT.getRegionalConfigId());
804 
805         // when mMockCachedAccessRestrictionMap is not hit and regionalConfigId is null
806         // verify belows
807         // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is false
808         // - the regionalConfigId is null
809         logd("testCheckSatelliteAccessRestrictionForLocation : case 2");
810         clearInvocations(mMockCachedAccessRestrictionMap);
811         doReturn(false).when(mMockCachedAccessRestrictionMap)
812                 .containsKey(any(SatelliteOnDeviceAccessController.LocationToken.class));
813         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
814         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
815                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
816                 .thenReturn(null);
817 
818         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
819         verify(mMockResultReceiver, times(2))
820                 .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
821         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
822         assertFalse(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
823         verify(mMockCachedAccessRestrictionMap, times(1))
824                 .put(any(), regionalConfigIdCaptor.capture());
825         assertNull(regionalConfigIdCaptor.getValue());
826         assertNull(mSatelliteAccessControllerUT.getNewRegionalConfigId());
827         assertNull(mSatelliteAccessControllerUT.getRegionalConfigId());
828 
829         // when mMockCachedAccessRestrictionMap is not hit and
830         // regionalConfigId is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
831         // verify belows
832         // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is true
833         // - the regionalConfigId is DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
834         logd("testCheckSatelliteAccessRestrictionForLocation : case 3");
835         clearInvocations(mMockCachedAccessRestrictionMap);
836         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
837                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
838                 .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
839         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
840 
841         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
842         verify(mMockResultReceiver, times(3))
843                 .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
844         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
845         assertTrue(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
846         verify(mMockCachedAccessRestrictionMap, times(1))
847                 .put(any(), regionalConfigIdCaptor.capture());
848 
849         assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
850                 regionalConfigIdCaptor.getValue());
851         assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
852                 mSatelliteAccessControllerUT.getNewRegionalConfigId());
853         assertEquals(Integer.valueOf(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID),
854                 mSatelliteAccessControllerUT.getRegionalConfigId());
855 
856 
857         // when mMockCachedAccessRestrictionMap is not hit and regionalConfigId is null
858         // verify belows
859         // - the bundle data of KEY_SATELLITE_COMMUNICATION_ALLOWED is false
860         // - the regionalConfigId is null
861         logd("testCheckSatelliteAccessRestrictionForLocation : case 4");
862         clearInvocations(mMockCachedAccessRestrictionMap);
863         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
864                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
865                 .thenReturn(null);
866         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
867 
868         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(mMockLocation0);
869         verify(mMockResultReceiver, times(4))
870                 .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
871         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
872         assertFalse(bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
873         verify(mMockCachedAccessRestrictionMap, times(1))
874                 .put(any(), regionalConfigIdCaptor.capture());
875         assertNull(regionalConfigIdCaptor.getValue());
876         assertNull(mSatelliteAccessControllerUT.getNewRegionalConfigId());
877         assertNull(mSatelliteAccessControllerUT.getRegionalConfigId());
878     }
879 
880     @Test
testIsRegionDisallowed()881     public void testIsRegionDisallowed() throws Exception {
882         when(mMockContext.getResources()).thenReturn(mMockResources);
883         when(mMockResources.getBoolean(
884                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
885                 .thenReturn(TEST_SATELLITE_ALLOW);
886         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
887         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
888         doReturn(true).when(mMockLocationManager).isLocationEnabled();
889         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
890                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
891                 .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
892         replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
893                 mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
894         doReturn(true).when(mMockCachedAccessRestrictionMap).containsKey(any());
895         doReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID)
896                 .when(mMockCachedAccessRestrictionMap).get(any());
897 
898         // get allowed country codes EMPTY from resources
899         when(mMockResources.getStringArray(
900                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
901                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES_EMPTY);
902 
903         // allow case that network country codes [US] with [EMPTY] configuration
904         // location will not be compared and mQueriedSatelliteAllowed will be set false
905         clearInvocations(mMockCachedAccessRestrictionMap);
906         when(mMockCountryDetector.getCurrentNetworkCountryIso())
907                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
908         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
909         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
910                 mSatelliteAllowedReceiver, false);
911         mTestableLooper.processAllMessages();
912         verify(mMockCachedAccessRestrictionMap, times(0)).containsKey(any());
913         assertFalse(mQueriedSatelliteAllowed);
914 
915         // allow case that network country codes [EMPTY] with [EMPTY] configuration
916         // location will be compared and mQueriedSatelliteAllowed will be set true
917         clearInvocations(mMockCachedAccessRestrictionMap);
918         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(List.of());
919         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
920         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
921                 mSatelliteAllowedReceiver, false);
922         mTestableLooper.processAllMessages();
923         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
924         assertTrue(mQueriedSatelliteAllowed);
925 
926         // get allowed country codes [US, CA, UK] from resources
927         when(mMockResources.getStringArray(
928                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
929                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES);
930 
931         // allow case that network country codes [US, CA, UK] with [US, CA, UK] configuration
932         // location will be compared and mQueriedSatelliteAllowed will be set true
933         clearInvocations(mMockCachedAccessRestrictionMap);
934         when(mMockCountryDetector.getCurrentNetworkCountryIso())
935                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODES));
936         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
937         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
938                 mSatelliteAllowedReceiver, false);
939         mTestableLooper.processAllMessages();
940         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
941         assertTrue(mQueriedSatelliteAllowed);
942 
943         // allow case that network country codes [US] with [US, CA, UK] configuration
944         // location will be compared and mQueriedSatelliteAllowed will be set true
945         clearInvocations(mMockCachedAccessRestrictionMap);
946         when(mMockCountryDetector.getCurrentNetworkCountryIso())
947                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
948         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
949         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
950                 mSatelliteAllowedReceiver, false);
951         mTestableLooper.processAllMessages();
952         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
953         assertTrue(mQueriedSatelliteAllowed);
954 
955         // allow case that network country codes [US, KR] with [US, CA, UK] configuration
956         // location will be compared and mQueriedSatelliteAllowed will be set true
957         clearInvocations(mMockCachedAccessRestrictionMap);
958         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(
959                 List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_KR));
960         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
961         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
962                 mSatelliteAllowedReceiver, false);
963         mTestableLooper.processAllMessages();
964         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
965         assertTrue(mQueriedSatelliteAllowed);
966 
967         // allow case that network country codes [US] with [EMPTY] configuration
968         // location will be compared and mQueriedSatelliteAllowed will be set true
969         clearInvocations(mMockCachedAccessRestrictionMap);
970         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(List.of());
971         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
972         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
973                 mSatelliteAllowedReceiver, false);
974         mTestableLooper.processAllMessages();
975         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
976         assertTrue(mQueriedSatelliteAllowed);
977 
978         // allow case that network country codes [KR, JP] with [US, CA, UK] configuration
979         // location will not be compared and mQueriedSatelliteAllowed will be set false
980         clearInvocations(mMockCachedAccessRestrictionMap);
981         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(
982                 List.of(TEST_SATELLITE_COUNTRY_CODE_KR, TEST_SATELLITE_COUNTRY_CODE_JP));
983         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
984         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
985                 mSatelliteAllowedReceiver, false);
986         mTestableLooper.processAllMessages();
987         verify(mMockCachedAccessRestrictionMap, times(0)).containsKey(any());
988         assertFalse(mQueriedSatelliteAllowed);
989 
990         // allow case that network country codes [KR] with [US, CA, UK] configuration
991         // location will not be compared and mQueriedSatelliteAllowed will be set false
992         clearInvocations(mMockCachedAccessRestrictionMap);
993         when(mMockCountryDetector.getCurrentNetworkCountryIso())
994                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_KR));
995         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
996         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
997                 mSatelliteAllowedReceiver, false);
998         mTestableLooper.processAllMessages();
999         verify(mMockCachedAccessRestrictionMap, times(0)).containsKey(any());
1000         assertFalse(mQueriedSatelliteAllowed);
1001 
1002 
1003         // set disallowed list case
1004         when(mMockResources.getBoolean(
1005                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
1006                 .thenReturn(TEST_SATELLITE_NOT_ALLOW);
1007         // get disallowed country codes list [EMPTY] from resources
1008         when(mMockResources.getStringArray(
1009                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
1010                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES_EMPTY);
1011 
1012         // disallow case that network country codes [US] with [EMPTY] configuration
1013         // location will be compared and mQueriedSatelliteAllowed will be set true
1014         clearInvocations(mMockCachedAccessRestrictionMap);
1015         when(mMockCountryDetector.getCurrentNetworkCountryIso())
1016                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
1017         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1018         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1019                 mSatelliteAllowedReceiver, false);
1020         mTestableLooper.processAllMessages();
1021         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
1022         assertTrue(mQueriedSatelliteAllowed);
1023 
1024         // get disallowed country codes list ["US", "CA", "UK"] from resources
1025         when(mMockResources.getStringArray(
1026                 com.android.internal.R.array.config_oem_enabled_satellite_country_codes))
1027                 .thenReturn(TEST_SATELLITE_COUNTRY_CODES);
1028 
1029         // disallow case that network country codes [EMPTY] with [US, CA, UK] configuration
1030         // location will be compared and mQueriedSatelliteAllowed will be set true
1031         clearInvocations(mMockCachedAccessRestrictionMap);
1032         when(mMockCountryDetector.getCurrentNetworkCountryIso())
1033                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODES_EMPTY));
1034         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1035         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1036                 mSatelliteAllowedReceiver, false);
1037         mTestableLooper.processAllMessages();
1038         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
1039         assertTrue(mQueriedSatelliteAllowed);
1040 
1041         // disallow case that network country codes [US, JP] with [US, CA, UK] configuration
1042         // location will be compared and mQueriedSatelliteAllowed will be set true
1043         clearInvocations(mMockCachedAccessRestrictionMap);
1044         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(
1045                 List.of(TEST_SATELLITE_COUNTRY_CODE_US, TEST_SATELLITE_COUNTRY_CODE_JP));
1046         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1047         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1048                 mSatelliteAllowedReceiver, false);
1049         mTestableLooper.processAllMessages();
1050         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
1051         assertTrue(mQueriedSatelliteAllowed);
1052 
1053         // disallow case that network country codes [JP] with [US, CA, UK] configuration
1054         // location will be compared and mQueriedSatelliteAllowed will be set true
1055         clearInvocations(mMockCachedAccessRestrictionMap);
1056         when(mMockCountryDetector.getCurrentNetworkCountryIso())
1057                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_JP));
1058         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1059         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1060                 mSatelliteAllowedReceiver, false);
1061         mTestableLooper.processAllMessages();
1062         verify(mMockCachedAccessRestrictionMap, times(1)).containsKey(any());
1063         assertTrue(mQueriedSatelliteAllowed);
1064 
1065         // disallow case that network country codes [US] with [US, CA, UK] configuration
1066         // location will not be compared and mQueriedSatelliteAllowed will be set false
1067         clearInvocations(mMockCachedAccessRestrictionMap);
1068         when(mMockCountryDetector.getCurrentNetworkCountryIso())
1069                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
1070         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1071         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1072                 mSatelliteAllowedReceiver, false);
1073         mTestableLooper.processAllMessages();
1074         verify(mMockCachedAccessRestrictionMap, times(0)).containsKey(any());
1075         assertFalse(mQueriedSatelliteAllowed);
1076     }
1077 
1078     @Test
testRequestIsSatelliteCommunicationAllowedForCurrentLocation()1079     public void testRequestIsSatelliteCommunicationAllowedForCurrentLocation() throws Exception {
1080         // Satellite is not supported
1081         setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
1082         clearAllInvocations();
1083         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1084                 mSatelliteAllowedReceiver, false);
1085         mTestableLooper.processAllMessages();
1086         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1087                 mSatelliteAllowedSemaphore, 1));
1088         assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, mQueriedSatelliteAllowedResultCode);
1089         assertFalse(mQueriedSatelliteAllowed);
1090 
1091         // Failed to query whether satellite is supported or not
1092         setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_MODEM_ERROR);
1093         clearAllInvocations();
1094         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1095                 mSatelliteAllowedReceiver, false);
1096         mTestableLooper.processAllMessages();
1097         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1098                 mSatelliteAllowedSemaphore, 1));
1099         assertEquals(SATELLITE_RESULT_MODEM_ERROR, mQueriedSatelliteAllowedResultCode);
1100 
1101         // Network country codes are not available. TelecomManager.isInEmergencyCall() returns true.
1102         // On-device access controller will be used. Last known location is available and fresh.
1103         clearAllInvocations();
1104         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
1105         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
1106         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
1107         when(mMockTelecomManager.isInEmergencyCall()).thenReturn(true);
1108         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
1109         when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(2L);
1110         when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
1111         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1112                 mSatelliteAllowedReceiver, false);
1113         mTestableLooper.processAllMessages();
1114         assertTrue(
1115                 mSatelliteAccessControllerUT.isKeepOnDeviceAccessControllerResourcesTimerStarted());
1116         verify(mMockSatelliteOnDeviceAccessController).getRegionalConfigIdForLocation(
1117                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1118         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1119                 mSatelliteAllowedSemaphore, 1));
1120         assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
1121         assertTrue(mQueriedSatelliteAllowed);
1122 
1123         // Move time forward and verify resources are cleaned up
1124         clearAllInvocations();
1125         mTestableLooper.moveTimeForward(mSatelliteAccessControllerUT
1126                 .getKeepOnDeviceAccessControllerResourcesTimeoutMillis());
1127         mTestableLooper.processAllMessages();
1128         assertFalse(
1129                 mSatelliteAccessControllerUT.isKeepOnDeviceAccessControllerResourcesTimerStarted());
1130         assertTrue(mSatelliteAccessControllerUT.isSatelliteOnDeviceAccessControllerReset());
1131         verify(mMockSatelliteOnDeviceAccessController).close();
1132 
1133         // Restore SatelliteOnDeviceAccessController for next verification
1134         mSatelliteAccessControllerUT.setSatelliteOnDeviceAccessController(
1135                 mMockSatelliteOnDeviceAccessController);
1136 
1137         // Network country codes are not available. TelecomManager.isInEmergencyCall() returns
1138         // false. Phone0 is in ECM. On-device access controller will be used. Last known location is
1139         // not fresh.
1140         clearAllInvocations();
1141         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
1142         when(mMockTelecomManager.isInEmergencyCall()).thenReturn(false);
1143         when(mMockPhone.isInEcm()).thenReturn(true);
1144         when(mMockPhone.getContext()).thenReturn(mMockContext);
1145         when(mMockPhone2.getContext()).thenReturn(mMockContext);
1146         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
1147         when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(0L);
1148         when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
1149         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1150                 mSatelliteAllowedReceiver, false);
1151         mTestableLooper.processAllMessages();
1152         assertFalse(
1153                 mSatelliteAccessControllerUT.isKeepOnDeviceAccessControllerResourcesTimerStarted());
1154         verify(mMockLocationManager).getCurrentLocation(eq(LocationManager.FUSED_PROVIDER),
1155                 any(LocationRequest.class), mLocationRequestCancellationSignalCaptor.capture(),
1156                 any(Executor.class), mLocationRequestConsumerCaptor.capture());
1157         assertTrue(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
1158         sendLocationRequestResult(mMockLocation0);
1159         assertFalse(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
1160         // The LocationToken should be already in the cache
1161         verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
1162                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1163         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1164                 mSatelliteAllowedSemaphore, 1));
1165         assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSatelliteAllowedResultCode);
1166         assertTrue(mQueriedSatelliteAllowed);
1167 
1168         // Timed out to wait for current location. No cached allowed state.
1169         clearAllInvocations();
1170         mSatelliteAccessControllerUT.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
1171                 "cache_clear_and_not_allowed");
1172         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
1173         when(mMockTelecomManager.isInEmergencyCall()).thenReturn(false);
1174         when(mMockPhone.isInEcm()).thenReturn(true);
1175         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
1176         when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(0L);
1177         when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
1178         when(mMockCountryDetector.getCachedLocationCountryIsoInfo()).thenReturn(new Pair<>("", 0L));
1179         when(mMockCountryDetector.getCachedNetworkCountryIsoInfo()).thenReturn(new HashMap<>());
1180         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1181                 mSatelliteAllowedReceiver, false);
1182         mTestableLooper.processAllMessages();
1183         assertFalse(
1184                 mSatelliteAccessControllerUT.isKeepOnDeviceAccessControllerResourcesTimerStarted());
1185         verify(mMockLocationManager).getCurrentLocation(anyString(), any(LocationRequest.class),
1186                 any(CancellationSignal.class), any(Executor.class), any(Consumer.class));
1187         assertTrue(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
1188         // Timed out
1189         mTestableLooper.moveTimeForward(
1190                 mSatelliteAccessControllerUT.getWaitForCurrentLocationTimeoutMillis());
1191         mTestableLooper.processAllMessages();
1192         assertFalse(mSatelliteAccessControllerUT.isWaitForCurrentLocationTimerStarted());
1193         verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
1194                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1195         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1196                 mSatelliteAllowedSemaphore, 1));
1197         assertEquals(SATELLITE_RESULT_LOCATION_NOT_AVAILABLE, mQueriedSatelliteAllowedResultCode);
1198 
1199         // Network country codes are not available. TelecomManager.isInEmergencyCall() returns
1200         // false. No phone is in ECM. Last known location is not fresh. Cached country codes should
1201         // be used for verifying satellite allow. No cached country codes are available.
1202         clearAllInvocations();
1203         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
1204         when(mMockCountryDetector.getCachedLocationCountryIsoInfo()).thenReturn(new Pair<>("", 0L));
1205         when(mMockCountryDetector.getCachedNetworkCountryIsoInfo()).thenReturn(new HashMap<>());
1206         when(mMockTelecomManager.isInEmergencyCall()).thenReturn(false);
1207         when(mMockPhone.isInEcm()).thenReturn(false);
1208         when(mMockPhone2.isInEcm()).thenReturn(false);
1209         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
1210         when(mMockLocation0.getElapsedRealtimeNanos()).thenReturn(0L);
1211         when(mMockLocation1.getElapsedRealtimeNanos()).thenReturn(0L);
1212         doReturn(false).when(mMockLocationManager).isLocationEnabled();
1213         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
1214                 mSatelliteAllowedReceiver, false);
1215         mTestableLooper.processAllMessages();
1216         verify(mMockLocationManager, never()).getCurrentLocation(anyString(),
1217                 any(LocationRequest.class), any(CancellationSignal.class), any(Executor.class),
1218                 any(Consumer.class));
1219         verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
1220                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1221         assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(
1222                 mSatelliteAllowedSemaphore, 1));
1223         assertEquals(SATELLITE_RESULT_LOCATION_DISABLED, mQueriedSatelliteAllowedResultCode);
1224         assertFalse(mQueriedSatelliteAllowed);
1225     }
1226 
1227     @Test
testLocationQueryThrottleTimeUpdate()1228     public void testLocationQueryThrottleTimeUpdate() {
1229         long firstMccChangedTime = 1;
1230         long lastKnownLocationElapsedRealtime =
1231                 firstMccChangedTime + TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS;
1232 
1233         verify(mMockCountryDetector).registerForCountryCodeChanged(
1234                 mCountryDetectorHandlerCaptor.capture(), mCountryDetectorIntCaptor.capture(),
1235                 mCountryDetectorObjCaptor.capture());
1236 
1237         assertSame(mCountryDetectorHandlerCaptor.getValue(), mSatelliteAccessControllerUT);
1238         assertSame(EVENT_COUNTRY_CODE_CHANGED, mCountryDetectorIntCaptor.getValue());
1239         assertNull(mCountryDetectorObjCaptor.getValue());
1240 
1241         // Setup to invoke GPS query
1242         clearInvocations(mMockSatelliteOnDeviceAccessController);
1243         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
1244         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
1245         doReturn(true).when(mMockLocationManager).isLocationEnabled();
1246         when(mMockLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER))
1247                 .thenReturn(null);
1248         when(mMockLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
1249                 .thenReturn(null);
1250 
1251         // When mcc changed first, so queried a location with GPS,
1252         // verify if the mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos
1253         // is the same with firstMccChangedTime.
1254         // verify mMockLocationManager.getCurrentLocation() is invoked
1255         // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is
1256         // firstMccChangedTime
1257         clearInvocations(mMockLocationManager);
1258         mSatelliteAccessControllerUT.elapsedRealtimeNanos = firstMccChangedTime;
1259         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1260         verify(mMockLocationManager, times(1))
1261                 .getCurrentLocation(any(), any(), any(), any(), any());
1262         assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
1263                 .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
1264 
1265         // set current time less than throttle_interval
1266         // verify mMockLocationManager.getCurrentLocation() is not invoked
1267         // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is not updated
1268         clearInvocations(mMockLocationManager);
1269         doReturn(lastKnownLocationElapsedRealtime).when(mMockLocation1).getElapsedRealtimeNanos();
1270         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1271                 (firstMccChangedTime + TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS - 1);
1272         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1273         verify(mMockLocationManager, never())
1274                 .getCurrentLocation(any(), any(), any(), any(), any());
1275         assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
1276                 .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
1277 
1278         // Test the scenario when last know location is fresh and
1279         // current time is greater than the location query throttle interval
1280         // verify mMockLocationManager.getCurrentLocation() is not invoked
1281         // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is not updated
1282         clearInvocations(mMockLocationManager);
1283         doReturn(lastKnownLocationElapsedRealtime).when(mMockLocation1).getElapsedRealtimeNanos();
1284         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1285                 (lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS - 1);
1286         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1287         verify(mMockLocationManager, never())
1288                 .getCurrentLocation(any(), any(), any(), any(), any());
1289         assertEquals(firstMccChangedTime, mSatelliteAccessControllerUT
1290                 .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
1291 
1292         // Test the scenario when last know location is not fresh and
1293         // current time is greater than the location query throttle interval
1294         // verify mMockLocationManager.getCurrentLocation() is invoked
1295         // verify time(mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos) is updated
1296         clearInvocations(mMockLocationManager);
1297         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
1298         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1299                 (lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS + 1);
1300         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1301         verify(mMockLocationManager, times(1))
1302                 .getCurrentLocation(any(), any(), any(), any(), any());
1303         assertEquals(lastKnownLocationElapsedRealtime + TEST_LOCATION_FRESH_DURATION_NANOS + 1,
1304                 mSatelliteAccessControllerUT
1305                         .mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos);
1306     }
1307 
1308 
1309     @Test
testAllowLocationQueryForSatelliteAllowedCheck()1310     public void testAllowLocationQueryForSatelliteAllowedCheck() {
1311         mSatelliteAccessControllerUT.mLatestSatelliteCommunicationAllowedSetTime = 1;
1312 
1313         mSatelliteAccessControllerUT.setIsSatelliteAllowedRegionPossiblyChanged(false);
1314         // cash is invalid
1315         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1316                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS + 10;
1317         assertTrue(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1318 
1319         // cash is valid
1320         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1321                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS - 10;
1322         assertFalse(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1323 
1324         mSatelliteAccessControllerUT.setIsSatelliteAllowedRegionPossiblyChanged(true);
1325         // cash is invalid
1326         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1327                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS + 10;
1328         assertTrue(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1329 
1330         // cash is valid and throttled
1331         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1332                 ALLOWED_STATE_CACHE_VALID_DURATION_NANOS - 10;
1333 
1334         // cash is valid and never queried before
1335         mSatelliteAccessControllerUT.mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos =
1336                 0;
1337         assertTrue(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1338 
1339         // cash is valid and throttled
1340         mSatelliteAccessControllerUT.mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos =
1341                 mSatelliteAccessControllerUT.elapsedRealtimeNanos
1342                         - TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS + 100;
1343         assertFalse(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1344 
1345         // cash is valid and not throttled
1346         mSatelliteAccessControllerUT.mLastLocationQueryForPossibleChangeInAllowedRegionTimeNanos =
1347                 mSatelliteAccessControllerUT.elapsedRealtimeNanos
1348                         - TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS - 100;
1349         assertTrue(mSatelliteAccessControllerUT.allowLocationQueryForSatelliteAllowedCheck());
1350     }
1351 
1352     @Test
testValidatePossibleChangeInSatelliteAllowedRegion()1353     public void testValidatePossibleChangeInSatelliteAllowedRegion() throws Exception {
1354         verify(mMockCountryDetector).registerForCountryCodeChanged(
1355                 mCountryDetectorHandlerCaptor.capture(), mCountryDetectorIntCaptor.capture(),
1356                 mCountryDetectorObjCaptor.capture());
1357 
1358         assertSame(mCountryDetectorHandlerCaptor.getValue(), mSatelliteAccessControllerUT);
1359         assertSame(mCountryDetectorIntCaptor.getValue(), EVENT_COUNTRY_CODE_CHANGED);
1360         assertNull(mCountryDetectorObjCaptor.getValue());
1361 
1362         // Normal case that invokes
1363         // mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation
1364         clearInvocations(mMockSatelliteOnDeviceAccessController);
1365         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
1366         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
1367         doReturn(true).when(mMockLocationManager).isLocationEnabled();
1368         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS;
1369         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1370         verify(mMockSatelliteOnDeviceAccessController,
1371                 times(1)).getRegionalConfigIdForLocation(
1372                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1373 
1374         // Case that isCommunicationAllowedCacheValid is true
1375         clearInvocations(mMockSatelliteOnDeviceAccessController);
1376         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
1377         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1378         verify(mMockSatelliteOnDeviceAccessController, never()).getRegionalConfigIdForLocation(
1379                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1380 
1381         // Case that mLatestCacheEnforcedValidateTimeNanos is over
1382         // ALLOWED_STATE_CACHE_VALIDATE_INTERVAL_NANOS (1hours)
1383         clearInvocations(mMockSatelliteOnDeviceAccessController);
1384         mSatelliteAccessControllerUT.elapsedRealtimeNanos =
1385                 mSatelliteAccessControllerUT.elapsedRealtimeNanos
1386                         + TEST_LOCATION_QUERY_THROTTLE_INTERVAL_NANOS + 1;
1387         when(mMockLocation0.getElapsedRealtimeNanos())
1388                 .thenReturn(mSatelliteAccessControllerUT.elapsedRealtimeNanos + 1L);
1389         when(mMockLocation1.getElapsedRealtimeNanos())
1390                 .thenReturn(mSatelliteAccessControllerUT.elapsedRealtimeNanos + 1L);
1391         when(mMockLocation0.getLatitude()).thenReturn(2.0);
1392         when(mMockLocation0.getLongitude()).thenReturn(2.0);
1393         when(mMockLocation1.getLatitude()).thenReturn(3.0);
1394         when(mMockLocation1.getLongitude()).thenReturn(3.0);
1395         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
1396                 any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(null);
1397         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1398         verify(mMockSatelliteOnDeviceAccessController,
1399                 times(1)).getRegionalConfigIdForLocation(
1400                 any(SatelliteOnDeviceAccessController.LocationToken.class));
1401     }
1402 
1403     @Test
testRetryValidatePossibleChangeInSatelliteAllowedRegion()1404     public void testRetryValidatePossibleChangeInSatelliteAllowedRegion() throws Exception {
1405         verify(mMockCountryDetector).registerForCountryCodeChanged(
1406                 mCountryDetectorHandlerCaptor.capture(), mCountryDetectorIntCaptor.capture(),
1407                 mCountryDetectorObjCaptor.capture());
1408 
1409         assertSame(mCountryDetectorHandlerCaptor.getValue(), mSatelliteAccessControllerUT);
1410         assertSame(mCountryDetectorIntCaptor.getValue(), EVENT_COUNTRY_CODE_CHANGED);
1411         assertNull(mCountryDetectorObjCaptor.getValue());
1412 
1413         assertTrue(mSatelliteAccessControllerUT
1414                 .getRetryCountPossibleChangeInSatelliteAllowedRegion() == 0);
1415 
1416         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_LOCATION_NOT_AVAILABLE);
1417         sendCommandValidateCountryCodeChangeEvent(mMockContext);
1418 
1419         assertTrue(mSatelliteAccessControllerUT
1420                 .getRetryCountPossibleChangeInSatelliteAllowedRegion() == 1);
1421 
1422         mSatelliteAccessControllerUT.setRetryCountPossibleChangeInSatelliteAllowedRegion(
1423                 DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION);
1424         sendSatelliteCommunicationAllowedEvent();
1425         assertTrue(mSatelliteAccessControllerUT
1426                 .getRetryCountPossibleChangeInSatelliteAllowedRegion() == 0);
1427 
1428         mSatelliteAccessControllerUT.setRetryCountPossibleChangeInSatelliteAllowedRegion(2);
1429         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
1430         sendSatelliteCommunicationAllowedEvent();
1431         assertTrue(mSatelliteAccessControllerUT
1432                 .getRetryCountPossibleChangeInSatelliteAllowedRegion() == 0);
1433     }
1434 
1435     @Test
testLoadSatelliteAccessConfigurationFromDeviceConfig()1436     public void testLoadSatelliteAccessConfigurationFromDeviceConfig() {
1437         when(mMockContext.getResources()).thenReturn(mMockResources);
1438         when(mMockResources
1439                 .getString(eq(com.android.internal.R.string.satellite_access_config_file)))
1440                 .thenReturn("test_satellite_file.json");
1441         assertEquals("test_satellite_file.json", mSatelliteAccessControllerUT
1442                 .getSatelliteConfigurationFileNameFromOverlayConfig(mMockContext));
1443 
1444         when(mMockResources
1445                 .getString(eq(com.android.internal.R.string.satellite_access_config_file)))
1446                 .thenReturn(null);
1447         assertNull(mSatelliteAccessControllerUT
1448                 .getSatelliteConfigurationFileNameFromOverlayConfig(mMockContext));
1449         try {
1450             mSatelliteAccessControllerUT.loadSatelliteAccessConfiguration();
1451         } catch (Exception e) {
1452             fail("Unexpected exception thrown: " + e.getMessage());
1453         }
1454     }
1455 
1456 
1457     @Test
testUpdateSatelliteAccessDataWithConfigUpdaterData()1458     public void testUpdateSatelliteAccessDataWithConfigUpdaterData() throws Exception {
1459         logd("registering for config update changed");
1460         verify(mMockSatelliteController).registerForConfigUpdateChanged(
1461                 mConfigUpdateHandlerCaptor.capture(), mConfigUpdateIntCaptor.capture(),
1462                 mConfigUpdateObjectCaptor.capture());
1463 
1464         assertSame(mConfigUpdateHandlerCaptor.getValue(), mSatelliteAccessControllerUT);
1465         assertSame(mConfigUpdateIntCaptor.getValue(), CMD_UPDATE_CONFIG_DATA);
1466         assertSame(mConfigUpdateObjectCaptor.getValue(), mMockContext);
1467 
1468         logd("replacing instance for mCachedAccessRestrictionMap");
1469         replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
1470                 mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
1471 
1472         // These APIs are executed during loadRemoteConfigs
1473         logd("verify load remote configs shared preferences method calls");
1474         verify(mMockSharedPreferences, times(1)).getInt(anyString(), anyInt());
1475         verify(mMockSharedPreferences, times(0)).getStringSet(anyString(), any());
1476         verify(mMockSharedPreferences, times(4)).getBoolean(anyString(), anyBoolean());
1477 
1478         // satelliteConfig is null
1479         logd("test for satelliteConfig is null");
1480         SatelliteConfigParser spyConfigParser =
1481                 spy(new SatelliteConfigParser("test".getBytes()));
1482         doReturn(spyConfigParser).when(mMockSatelliteController).getSatelliteConfigParser();
1483         assertNull(spyConfigParser.getConfig());
1484 
1485         sendConfigUpdateChangedEvent(mMockContext);
1486         verify(mMockSharedPreferences, never()).edit();
1487         verify(mMockCachedAccessRestrictionMap, never()).clear();
1488         verify(mMockSatelliteController, times(1)).getSatelliteConfig();
1489 
1490         // satelliteConfig has satellite config data version(0) which is from device config.
1491         logd("test for satelliteConfig from device config version 0");
1492         SatelliteConfig mockConfig = mock(SatelliteConfig.class);
1493         doReturn(0).when(mockConfig).getSatelliteConfigDataVersion();
1494         doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
1495         doReturn(false).when(mockConfig).isSatelliteDataForAllowedRegion();
1496 
1497         sendConfigUpdateChangedEvent(mMockContext);
1498         verify(mMockSharedPreferences, never()).edit();
1499         verify(mMockCachedAccessRestrictionMap, never()).clear();
1500         verify(mMockSatelliteController, times(2)).getSatelliteConfig();
1501         verify(mockConfig, times(1)).getSatelliteConfigDataVersion();
1502         verify(mockConfig, times(0)).getDeviceSatelliteCountryCodes();
1503         verify(mockConfig, times(0)).isSatelliteDataForAllowedRegion();
1504         verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
1505         verify(mockConfig, times(0)).getSatelliteAccessConfigJsonFile(mMockContext);
1506 
1507         // satelliteConfig has invalid country codes
1508         logd("test for satelliteConfig with invalid country codes");
1509         doReturn(1).when(mockConfig).getSatelliteConfigDataVersion();
1510         doReturn(List.of("USA", "JAP")).when(mockConfig).getDeviceSatelliteCountryCodes();
1511         doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
1512         doReturn(false).when(mockConfig).isSatelliteDataForAllowedRegion();
1513 
1514         sendConfigUpdateChangedEvent(mMockContext);
1515         verify(mMockSharedPreferences, never()).edit();
1516         verify(mMockCachedAccessRestrictionMap, never()).clear();
1517         verify(mMockSatelliteController, times(3)).getSatelliteConfig();
1518         verify(mockConfig, times(2)).getSatelliteConfigDataVersion();
1519         verify(mockConfig, times(1)).getDeviceSatelliteCountryCodes();
1520         verify(mockConfig, times(0)).isSatelliteDataForAllowedRegion();
1521         verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
1522         verify(mockConfig, times(0)).getSatelliteAccessConfigJsonFile(mMockContext);
1523 
1524         // satelliteConfig does not have is_allow_access_control data
1525         logd("test for satelliteConfig does not have is_allow_access_control data");
1526         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
1527                 .when(mockConfig).getDeviceSatelliteCountryCodes();
1528         doReturn(null).when(mockConfig).isSatelliteDataForAllowedRegion();
1529 
1530         sendConfigUpdateChangedEvent(mMockContext);
1531         verify(mMockSharedPreferences, never()).edit();
1532         verify(mMockCachedAccessRestrictionMap, never()).clear();
1533         verify(mMockSatelliteController, times(4)).getSatelliteConfig();
1534         verify(mockConfig, times(3)).getSatelliteConfigDataVersion();
1535         verify(mockConfig, times(2)).getDeviceSatelliteCountryCodes();
1536         verify(mockConfig, times(1)).isSatelliteDataForAllowedRegion();
1537         verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
1538         verify(mockConfig, times(0)).getSatelliteAccessConfigJsonFile(mMockContext);
1539 
1540         // satelliteConfig doesn't have both S2CellFile and satellite access config json file
1541         logd(
1542                 "test for satelliteConfig doesn't have both S2CellFile and satellite access config"
1543                         + " json file");
1544         File mockS2File = mock(File.class);
1545         doReturn(false).when(mockS2File).exists();
1546         File mockSatelliteAccessConfigJsonFile = mock(File.class);
1547         doReturn(false).when(mockSatelliteAccessConfigJsonFile).exists();
1548         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
1549                 .when(mockConfig).getDeviceSatelliteCountryCodes();
1550         doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
1551         doReturn(mockS2File).when(mockConfig).getSatelliteS2CellFile(mMockContext);
1552         doReturn(mockSatelliteAccessConfigJsonFile)
1553                 .when(mockConfig)
1554                 .getSatelliteAccessConfigJsonFile(mMockContext);
1555 
1556         sendConfigUpdateChangedEvent(mMockContext);
1557         verify(mMockSharedPreferences, never()).edit();
1558         verify(mMockCachedAccessRestrictionMap, never()).clear();
1559         verify(mMockSatelliteController, times(5)).getSatelliteConfig();
1560         verify(mockConfig, times(4)).getSatelliteConfigDataVersion();
1561         verify(mockConfig, times(3)).getDeviceSatelliteCountryCodes();
1562         verify(mockConfig, times(2)).isSatelliteDataForAllowedRegion();
1563         verify(mockConfig, times(1)).getSatelliteS2CellFile(mMockContext);
1564         verify(mockConfig, times(0)).getSatelliteAccessConfigJsonFile(mMockContext);
1565 
1566         // satelliteConfig has s2CellFill, but doesn't have satellite access config json file
1567         logd(
1568                 "test for satelliteConfig having s2CellFill, but doesn't have satellite access"
1569                         + " config json file");
1570         doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
1571         File testS2File = mSatelliteAccessControllerUT
1572                 .getTestSatelliteS2File(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
1573         assertTrue("Test S2 file not created", testS2File != null && testS2File.exists());
1574         mockSatelliteAccessConfigJsonFile = mock(File.class);
1575         doReturn(false).when(mockSatelliteAccessConfigJsonFile).exists();
1576         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
1577                 .when(mockConfig).getDeviceSatelliteCountryCodes();
1578         doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
1579         doReturn(testS2File).when(mockConfig).getSatelliteS2CellFile(mMockContext);
1580         doReturn(mockSatelliteAccessConfigJsonFile)
1581                 .when(mockConfig)
1582                 .getSatelliteAccessConfigJsonFile(mMockContext);
1583 
1584         sendConfigUpdateChangedEvent(mMockContext);
1585         verify(mMockSharedPreferences, never()).edit();
1586         verify(mMockCachedAccessRestrictionMap, never()).clear();
1587         verify(mMockSatelliteController, times(6)).getSatelliteConfig();
1588         verify(mockConfig, times(5)).getSatelliteConfigDataVersion();
1589         verify(mockConfig, times(4)).getDeviceSatelliteCountryCodes();
1590         verify(mockConfig, times(3)).isSatelliteDataForAllowedRegion();
1591         verify(mockConfig, times(2)).getSatelliteS2CellFile(mMockContext);
1592         verify(mockConfig, times(1)).getSatelliteAccessConfigJsonFile(mMockContext);
1593 
1594         // satelliteConfig has valid data
1595         logd("test for satelliteConfig having valid data");
1596         doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
1597         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
1598                 .when(mockConfig)
1599                 .getDeviceSatelliteCountryCodes();
1600         testS2File =
1601                 mSatelliteAccessControllerUT.getTestSatelliteS2File(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
1602         assertTrue("Test S2 file not created", testS2File != null && testS2File.exists());
1603         doReturn(testS2File).when(mockConfig).getSatelliteS2CellFile(mMockContext);
1604         File testSatelliteAccessConfigFile =
1605                 mSatelliteAccessControllerUT.getTestSatelliteConfiguration(
1606                         SATELLITE_ACCESS_CONFIG_FILE_NAME);
1607         assertTrue(
1608                 "Test satellite access config file not created",
1609                 testSatelliteAccessConfigFile != null && testSatelliteAccessConfigFile.exists());
1610         doReturn(testSatelliteAccessConfigFile)
1611                 .when(mockConfig)
1612                 .getSatelliteAccessConfigJsonFile(mMockContext);
1613 
1614         sendConfigUpdateChangedEvent(mMockContext);
1615         verify(mMockSharedPreferences, times(3)).edit();
1616         verify(mMockCachedAccessRestrictionMap, times(1)).clear();
1617         verify(mMockSatelliteController, times(7)).getSatelliteConfig();
1618         verify(mockConfig, times(6)).getSatelliteConfigDataVersion();
1619         verify(mockConfig, times(5)).getDeviceSatelliteCountryCodes();
1620         verify(mockConfig, times(5)).isSatelliteDataForAllowedRegion();
1621         verify(mockConfig, times(3)).getSatelliteS2CellFile(mMockContext);
1622         verify(mockConfig, times(2)).getSatelliteAccessConfigJsonFile(mMockContext);
1623     }
1624 
setupTestFileFromRawResource(int resId, String targetFileName)1625     private String setupTestFileFromRawResource(int resId, String targetFileName)
1626             throws IOException {
1627         logd("setting up rest file for resId: " + resId + ", targetFileName: " + targetFileName);
1628         Context context = InstrumentationRegistry.getInstrumentation().getContext();
1629         InputStream is = context.getResources().openRawResource(resId);
1630         logd("Copying test file to temp_satellite_config_update");
1631         File tempDir =
1632                 InstrumentationRegistry.getInstrumentation()
1633                         .getTargetContext()
1634                         .getDir("temp_satellite_config_update", Context.MODE_PRIVATE);
1635         File tempFile = new File(tempDir, targetFileName);
1636         FileOutputStream fos = new FileOutputStream(tempFile);
1637         byte[] buffer = new byte[1024];
1638         int length;
1639         while ((length = is.read(buffer)) > 0) {
1640             fos.write(buffer, 0, length);
1641         }
1642         is.close();
1643         fos.close();
1644         return tempFile.getAbsolutePath();
1645     }
1646 
isLocationAllowed( ArgumentCaptor<Bundle> bundleCaptor, Iterator<ResultReceiver> mockResultReceiverIterator, Location location)1647     private boolean isLocationAllowed(
1648             ArgumentCaptor<Bundle> bundleCaptor,
1649             Iterator<ResultReceiver> mockResultReceiverIterator,
1650             Location location)
1651             throws Exception {
1652         clearInvocations(mMockResultReceiver);
1653         when(mMockLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
1654                 .thenReturn(location);
1655         when(mMockLocationManager.getLastKnownLocation(LocationManager.FUSED_PROVIDER))
1656                 .thenReturn(location);
1657         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
1658         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionForLocation(location);
1659         verify(mMockResultReceiver, times(1))
1660                 .send(mResultCodeIntCaptor.capture(), bundleCaptor.capture());
1661         if (mResultCodeIntCaptor.getValue() != SATELLITE_RESULT_SUCCESS) return false;
1662         return bundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
1663     }
1664 
setupOnDeviceGeofenceData( int sats2ResId, String targetSats2FileName, int satelliteAccessConfigResId, String targetSatelliteAccessConfigFileName)1665     private void setupOnDeviceGeofenceData(
1666             int sats2ResId,
1667             String targetSats2FileName,
1668             int satelliteAccessConfigResId,
1669             String targetSatelliteAccessConfigFileName)
1670             throws Exception {
1671         logd("setting up on device geofence data");
1672 
1673         logd("Clearing on device geofence data");
1674         sendSatelliteDeviceAccessControllerResourcesTimeOutEvent();
1675 
1676         logd("Creating sats2.dat and satellite_access_config.json files");
1677         // set given sats2.dat and satellite_access_config.json as device geofence files
1678         doReturn(0).when(mMockSharedPreferences)
1679                 .getInt(eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt());
1680         String sats2FilePath = setupTestFileFromRawResource(sats2ResId, targetSats2FileName);
1681         when(mMockResources.getString(
1682                         com.android.internal.R.string.config_oem_enabled_satellite_s2cell_file))
1683                 .thenReturn(sats2FilePath);
1684         String satelliteAccessConfigFilePath =
1685                 setupTestFileFromRawResource(
1686                         satelliteAccessConfigResId, targetSatelliteAccessConfigFileName);
1687         when(mMockResources.getString(com.android.internal.R.string.satellite_access_config_file))
1688                 .thenReturn(satelliteAccessConfigFilePath);
1689         mSatelliteAccessControllerUT.loadOverlayConfigs(mMockContext);
1690     }
1691 
setupOtaGeofenceData( int version, SatelliteConfig mockConfig, int sats2ResId, String targetSats2FileName, int satelliteAccessConfigResId, String targetSatelliteAccessConfigFileName, String[] countryCodes)1692     private void setupOtaGeofenceData(
1693             int version,
1694             SatelliteConfig mockConfig,
1695             int sats2ResId,
1696             String targetSats2FileName,
1697             int satelliteAccessConfigResId,
1698             String targetSatelliteAccessConfigFileName,
1699             String[] countryCodes)
1700             throws Exception {
1701         String sats2FilePath = setupTestFileFromRawResource(sats2ResId, targetSats2FileName);
1702         String satelliteAccessConfigFilePath =
1703                 setupTestFileFromRawResource(
1704                         satelliteAccessConfigResId, targetSatelliteAccessConfigFileName);
1705 
1706         File sats2File = new File(sats2FilePath);
1707         assertTrue("OTA geofence S2 file not created", sats2File != null && sats2File.exists());
1708         doReturn(sats2File).when(mockConfig).getSatelliteS2CellFile(mMockContext);
1709 
1710         File satelliteAccessConfigFile = new File(satelliteAccessConfigFilePath);
1711         assertTrue(
1712                 "OTA geofence satellite access config file not created",
1713                 satelliteAccessConfigFile != null && satelliteAccessConfigFile.exists());
1714         doReturn(satelliteAccessConfigFile)
1715                 .when(mockConfig)
1716                 .getSatelliteAccessConfigJsonFile(mMockContext);
1717 
1718         doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
1719         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
1720                 .when(mockConfig)
1721                 .getDeviceSatelliteCountryCodes();
1722         doReturn(version).when(mockConfig).getSatelliteConfigDataVersion();
1723         doReturn(version).when(mMockSharedPreferences)
1724                 .getInt(eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt());
1725     }
1726 
areOnDeviceAndOtaFilesValidAndDifferent( File onDeviceSats2File, File onDeviceSatelliteAccessConfigFile, File otaSats2File, File otaSatelliteAccessConfigFile)1727     private boolean areOnDeviceAndOtaFilesValidAndDifferent(
1728             File onDeviceSats2File,
1729             File onDeviceSatelliteAccessConfigFile,
1730             File otaSats2File,
1731             File otaSatelliteAccessConfigFile) {
1732         if (onDeviceSats2File == null
1733                 || onDeviceSatelliteAccessConfigFile == null
1734                 || otaSats2File == null
1735                 || otaSatelliteAccessConfigFile == null) {
1736             throw new AssertionError("Both on device and OTA files should NOT be null");
1737         }
1738         String onDeviceSats2FileAbsPath = onDeviceSats2File.getAbsolutePath();
1739         String onDeviceSatelliteAccessConfigFileAbsPath =
1740                 onDeviceSatelliteAccessConfigFile.getAbsolutePath();
1741         String otaSats2FileAbsPath = otaSats2File.getAbsolutePath();
1742         String otaSatelliteAccessConfigFileAbsPath = otaSatelliteAccessConfigFile.getAbsolutePath();
1743 
1744         logd("onDeviceSats2FileAbsPath: " + onDeviceSats2FileAbsPath);
1745         logd(
1746                 "onDeviceSatelliteAccessConfigFileAbsPath: "
1747                         + onDeviceSatelliteAccessConfigFileAbsPath);
1748         logd("otaSats2FileAbsPath: " + otaSats2FileAbsPath);
1749         logd("otaSatelliteAccessConfigFileAbsPath: " + otaSatelliteAccessConfigFileAbsPath);
1750 
1751         if (onDeviceSats2FileAbsPath.equals(otaSats2FileAbsPath)
1752                 || onDeviceSatelliteAccessConfigFileAbsPath.equals(
1753                         otaSatelliteAccessConfigFileAbsPath)) {
1754             return false;
1755         }
1756 
1757         logd("areOnDeviceAndOtaFilesValidAndDifferent: true");
1758         return true;
1759     }
1760 
1761     @Test
testConfigUpdateAndCorrespondingSatelliteAllowedAtLocationChecks()1762     public void testConfigUpdateAndCorrespondingSatelliteAllowedAtLocationChecks()
1763             throws Exception {
1764         replaceInstance(
1765                 SatelliteAccessController.class,
1766                 "mS2Level",
1767                 mSatelliteAccessControllerUT,
1768                 DEFAULT_S2_LEVEL);
1769         when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
1770         when(mMockContext.getResources()).thenReturn(mMockResources);
1771         when(mMockResources.getBoolean(
1772                         com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
1773                 .thenReturn(TEST_SATELLITE_ALLOW);
1774         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
1775         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
1776         doReturn(true).when(mMockLocationManager).isLocationEnabled();
1777 
1778         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
1779         Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
1780         doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
1781         doNothing().when(mMockSatelliteAllowResultReceivers).clear();
1782         doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
1783         replaceInstance(
1784                 SatelliteAccessController.class,
1785                 "mSatelliteAllowResultReceivers",
1786                 mSatelliteAccessControllerUT,
1787                 mMockSatelliteAllowResultReceivers);
1788         replaceInstance(
1789                 SatelliteAccessController.class,
1790                 "mCachedAccessRestrictionMap",
1791                 mSatelliteAccessControllerUT,
1792                 mMockCachedAccessRestrictionMap);
1793 
1794         ISatelliteCommunicationAccessStateCallback mockSatelliteAllowedStateCallback = mock(
1795                 ISatelliteCommunicationAccessStateCallback.class);
1796 
1797         when(mSatelliteCommunicationAllowedStateCallbackMap.values())
1798                 .thenReturn(List.of(mockSatelliteAllowedStateCallback));
1799         replaceInstance(SatelliteAccessController.class,
1800                 "mSatelliteCommunicationAccessStateChangedListeners", mSatelliteAccessControllerUT,
1801                 mSatelliteCommunicationAllowedStateCallbackMap);
1802 
1803         SatelliteConfig mockConfig = mock(SatelliteConfig.class);
1804         doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
1805 
1806         Location locationUS = mock(Location.class);
1807         when(locationUS.getLatitude()).thenReturn(37.7749);
1808         when(locationUS.getLongitude()).thenReturn(-122.4194);
1809         Location locationKR = mock(Location.class);
1810         when(locationKR.getLatitude()).thenReturn(37.5665);
1811         when(locationKR.getLongitude()).thenReturn(126.9780);
1812         Location locationTW = mock(Location.class);
1813         when(locationTW.getLatitude()).thenReturn(25.034);
1814         when(locationTW.getLongitude()).thenReturn(121.565);
1815 
1816         // Test v15 geofence data - supports US location
1817         // set v15's sats2.dat and satellite_access_config.json as device geofence files and
1818         // verify for below locations are allowed or not for satellite commiunication as expected.
1819         // location1 - US - allowed; location2 - KR - not allowed; location3 - TW - not allowed;
1820         logd(
1821                 "Step 1: Testing v15 (US) satellite config files. Expectation: locationUS -"
1822                         + " allowed; locationKR - not allowed; locationTW - not allowed");
1823         setupOnDeviceGeofenceData(
1824                 com.android.phone.tests.R.raw.v15_sats2,
1825                 "v15_sats2.dat",
1826                 com.android.phone.tests.R.raw.v15_satellite_access_config,
1827                 "v15_satellite_access_config.json");
1828         assertEquals(0, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
1829         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
1830         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
1831         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
1832         Map<Integer, SatelliteAccessConfiguration> satelliteAccessConfigurationMap =
1833                 mSatelliteAccessControllerUT.getSatelliteAccessConfigMap();
1834         logd("Obatined satelliteAccessConfigurationMap: " + satelliteAccessConfigurationMap);
1835         assertEquals(6, satelliteAccessConfigurationMap.size());
1836         assertEquals(
1837                 "62de127d-ead1-481f-8524-b58e2664103a",
1838                 satelliteAccessConfigurationMap
1839                         .get(5)
1840                         .getSatelliteInfos()
1841                         .get(0)
1842                         .getSatelliteId()
1843                         .toString());
1844         assertEquals(
1845                 -98.0,
1846                 satelliteAccessConfigurationMap
1847                         .get(5)
1848                         .getSatelliteInfos()
1849                         .get(0)
1850                         .getSatellitePosition()
1851                         .getLongitudeDegrees(),
1852                 0.001);
1853         assertEquals(
1854                 35775.1,
1855                 satelliteAccessConfigurationMap
1856                         .get(5)
1857                         .getSatelliteInfos()
1858                         .get(0)
1859                         .getSatellitePosition()
1860                         .getAltitudeKm(),
1861                 0.001);
1862         File onDeviceSats2File = mSatelliteAccessControllerUT.getSatelliteS2CellFile();
1863         File onDeviceSatelliteAccessConfigFile =
1864                 mSatelliteAccessControllerUT.getSatelliteAccessConfigFile();
1865 
1866         // Test v16 geofence data - supports US, KR, TW locations
1867         // Simulate config update to override v16's sats2.dat and satellite_access_config.json
1868         // as the geofence files.
1869         // And verify for below locations are allowed or not for satellite commiunication as
1870         // expected.
1871         // location1 - US - allowed; location2 - KR - allowed; location3 - TW - allowed;
1872         logd(
1873                 "Step 2: Testing v16 (US, KR, TW) satellite config files."
1874                         + " Simulate config update for v16 files. Expectation: locationUS -"
1875                         + " allowed; locationKR - allowed; locationTW - allowed");
1876         clearInvocations(mockSatelliteAllowedStateCallback);
1877         setupOtaGeofenceData(
1878                 16,
1879                 mockConfig,
1880                 com.android.phone.tests.R.raw.v16_sats2,
1881                 "v16_sats2.dat",
1882                 com.android.phone.tests.R.raw.v16_satellite_access_config,
1883                 "v16_satellite_access_config.json",
1884                 new String[] {"US", "CA", "UK", "KR", "TW"});
1885         sendConfigUpdateChangedEvent(mMockContext);
1886         verify(mockSatelliteAllowedStateCallback, times(1))
1887                 .onAccessConfigurationChanged(any());
1888         verify(mockSatelliteAllowedStateCallback, times(1))
1889                 .onAccessAllowedStateChanged(anyBoolean());
1890         assertEquals(16, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
1891         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
1892         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
1893         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
1894         satelliteAccessConfigurationMap =
1895                 mSatelliteAccessControllerUT.getSatelliteAccessConfigMap();
1896         logd("Obatined satelliteAccessConfigurationMap: " + satelliteAccessConfigurationMap);
1897         assertEquals(8, satelliteAccessConfigurationMap.size());
1898         assertEquals(
1899                 "c9d78ffa-ffa5-4d41-a81b-34693b33b496",
1900                 satelliteAccessConfigurationMap
1901                         .get(6)
1902                         .getSatelliteInfos()
1903                         .get(0)
1904                         .getSatelliteId()
1905                         .toString());
1906         assertEquals(
1907                 -101.3,
1908                 satelliteAccessConfigurationMap
1909                         .get(6)
1910                         .getSatelliteInfos()
1911                         .get(0)
1912                         .getSatellitePosition()
1913                         .getLongitudeDegrees(),
1914                 0.001);
1915         assertEquals(
1916                 35786.0,
1917                 satelliteAccessConfigurationMap
1918                         .get(6)
1919                         .getSatelliteInfos()
1920                         .get(0)
1921                         .getSatellitePosition()
1922                         .getAltitudeKm(),
1923                 0.001);
1924         File otaSats2File = mSatelliteAccessControllerUT.getSatelliteS2CellFile();
1925         File otaSatelliteAccessConfigFile =
1926                 mSatelliteAccessControllerUT.getSatelliteAccessConfigFile();
1927         assertTrue(
1928                 areOnDeviceAndOtaFilesValidAndDifferent(
1929                         onDeviceSats2File,
1930                         onDeviceSatelliteAccessConfigFile,
1931                         otaSats2File,
1932                         otaSatelliteAccessConfigFile));
1933 
1934         // Test v17 geofence data - supports US location
1935         // Simulate config update to override v17's sats2.dat and satellite_access_config.json
1936         // as the geofence files.
1937         // And verify for below locations are allowed or not for satellite commiunication as
1938         // expected.
1939         // location1 - US - allowed; location2 - KR - not allowed; location3 - TW - not allowed;
1940         logd(
1941                 "Step 3: Testing v17 (US) satellite config files."
1942                         + " Simulate config update for v17 files. Expectation: locationUS -"
1943                         + " allowed; locationKR - not allowed; locationTW - not allowed");
1944         clearInvocations(mockSatelliteAllowedStateCallback);
1945         setupOtaGeofenceData(
1946                 17,
1947                 mockConfig,
1948                 com.android.phone.tests.R.raw.v17_sats2,
1949                 "v17_sats2.dat",
1950                 com.android.phone.tests.R.raw.v17_satellite_access_config,
1951                 "v17_satellite_access_config.json",
1952                 new String[] {"US", "CA", "UK", "KR", "TW"});
1953         sendConfigUpdateChangedEvent(mMockContext);
1954         verify(mockSatelliteAllowedStateCallback, times(1))
1955                 .onAccessConfigurationChanged(any());
1956         verify(mockSatelliteAllowedStateCallback, times(1))
1957                 .onAccessAllowedStateChanged(anyBoolean());
1958         assertEquals(17, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
1959         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
1960         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
1961         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
1962         satelliteAccessConfigurationMap =
1963                 mSatelliteAccessControllerUT.getSatelliteAccessConfigMap();
1964         logd("Obatined satelliteAccessConfigurationMap: " + satelliteAccessConfigurationMap);
1965         assertEquals(6, satelliteAccessConfigurationMap.size());
1966         assertEquals(
1967                 "62de127d-ead1-481f-8524-b58e2664103a",
1968                 satelliteAccessConfigurationMap
1969                         .get(5)
1970                         .getSatelliteInfos()
1971                         .get(0)
1972                         .getSatelliteId()
1973                         .toString());
1974         assertEquals(
1975                 -98.0,
1976                 satelliteAccessConfigurationMap
1977                         .get(5)
1978                         .getSatelliteInfos()
1979                         .get(0)
1980                         .getSatellitePosition()
1981                         .getLongitudeDegrees(),
1982                 0.001);
1983         assertEquals(
1984                 35775.1,
1985                 satelliteAccessConfigurationMap
1986                         .get(5)
1987                         .getSatelliteInfos()
1988                         .get(0)
1989                         .getSatellitePosition()
1990                         .getAltitudeKm(),
1991                 0.001);
1992         otaSats2File = mSatelliteAccessControllerUT.getSatelliteS2CellFile();
1993         otaSatelliteAccessConfigFile = mSatelliteAccessControllerUT.getSatelliteAccessConfigFile();
1994         assertTrue(
1995                 areOnDeviceAndOtaFilesValidAndDifferent(
1996                         onDeviceSats2File,
1997                         onDeviceSatelliteAccessConfigFile,
1998                         otaSats2File,
1999                         otaSatelliteAccessConfigFile));
2000     }
2001 
2002     @Test
testLocationModeChanged()2003     public void testLocationModeChanged() throws Exception {
2004         logd("testLocationModeChanged: setup to query the current location");
2005         when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
2006         when(mMockContext.getResources()).thenReturn(mMockResources);
2007         when(mMockResources.getBoolean(
2008                 com.android.internal.R.bool.config_oem_enabled_satellite_access_allow))
2009                 .thenReturn(TEST_SATELLITE_ALLOW);
2010         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
2011         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
2012         when(mMockSatelliteOnDeviceAccessController.getRegionalConfigIdForLocation(
2013                 any(SatelliteOnDeviceAccessController.LocationToken.class)))
2014                 .thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
2015         replaceInstance(SatelliteAccessController.class, "mCachedAccessRestrictionMap",
2016                 mSatelliteAccessControllerUT, mMockCachedAccessRestrictionMap);
2017         doReturn(false).when(mMockCachedAccessRestrictionMap).containsKey(any());
2018         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
2019 
2020         logd("testLocationModeChanged: "
2021                 + "captor and verify if the mockReceiver and mockContext is registered well");
2022         verify(mMockContext, times(2)).registerReceiver(
2023                 mLocationBroadcastReceiverCaptor.capture(), mIntentFilterCaptor.capture());
2024 
2025         logd("testLocationModeChanged: verify if the location manager doesn't invoke "
2026                 + "isLocationEnabled(), when the intent action is not MODE_CHANGED_ACTION");
2027         doReturn("").when(mMockLocationIntent).getAction();
2028         mSatelliteAccessControllerUT.setIsSatelliteAllowedRegionPossiblyChanged(false);
2029         mSatelliteAccessControllerUT.getLocationBroadcastReceiver()
2030                 .onReceive(mMockContext, mMockLocationIntent);
2031         verify(mMockLocationManager, never()).isLocationEnabled();
2032 
2033         // When the intent action is MODE_CHANGED_ACTION and isLocationEnabled() is true,
2034         // verify if mIsSatelliteAllowedRegionPossiblyChanged is true
2035         logd("testLocationModeChanged: verify if mIsSatelliteAllowedRegionPossiblyChanged is true, "
2036                 + "when the intent action is MODE_CHANGED_ACTION and isLocationEnabled() is true");
2037         doReturn(MODE_CHANGED_ACTION).when(mMockLocationIntent).getAction();
2038         doReturn(true).when(mMockLocationManager).isLocationEnabled();
2039         clearInvocations(mMockLocationManager);
2040         mSatelliteAccessControllerUT.setIsSatelliteAllowedRegionPossiblyChanged(false);
2041         mSatelliteAccessControllerUT.getLocationBroadcastReceiver()
2042                 .onReceive(mMockContext, mMockLocationIntent);
2043         verify(mMockLocationManager, times(1)).isLocationEnabled();
2044         mTestableLooper.processAllMessages();
2045         assertEquals(true, mSatelliteAccessControllerUT.isSatelliteAllowedRegionPossiblyChanged());
2046 
2047         logd("testLocationModeChanged: "
2048                 + "verify if mIsSatelliteAllowedRegionPossiblyChanged is false, "
2049                 + "when the intent action is MODE_CHANGED_ACTION and isLocationEnabled() is false");
2050         mSatelliteAccessControllerUT
2051                 .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_allowed");
2052         replaceInstance(SatelliteAccessController.class,
2053                 "mSatelliteCommunicationAccessStateChangedListeners",
2054                 mSatelliteAccessControllerUT,
2055                 mMockSatelliteCommunicationAccessStateChangedListeners);
2056         doReturn(false).when(mMockLocationManager).isLocationEnabled();
2057         clearInvocations(mMockLocationManager);
2058         mSatelliteAccessControllerUT.setIsSatelliteAllowedRegionPossiblyChanged(false);
2059         mSatelliteAccessControllerUT.getLocationBroadcastReceiver()
2060                 .onReceive(mMockContext, mMockLocationIntent);
2061         verify(mMockLocationManager, times(1)).isLocationEnabled();
2062         mTestableLooper.processAllMessages();
2063         assertEquals(false,
2064                 mSatelliteAccessControllerUT.isSatelliteAllowedRegionPossiblyChanged());
2065         verify(mMockSatelliteCommunicationAccessStateChangedListeners, times(1)).values();
2066     }
2067 
2068     @Test
testCheckSatelliteAccessRestrictionUsingGPS()2069     public void testCheckSatelliteAccessRestrictionUsingGPS() {
2070         // In emergency case,
2071         // verify if the location manager get FUSED provider and ignore location settings
2072         doReturn(true).when(mMockTelecomManager).isInEmergencyCall();
2073         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
2074         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
2075         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
2076 
2077         verify(mMockLocationManager, times(1))
2078                 .getCurrentLocation(mLocationProviderStringCaptor.capture(),
2079                         mLocationRequestCaptor.capture(), any(), any(), any());
2080         assertEquals(LocationManager.FUSED_PROVIDER, mLocationProviderStringCaptor.getValue());
2081         assertTrue(mLocationRequestCaptor.getValue().isLocationSettingsIgnored());
2082 
2083         // In non-emergency case,
2084         // verify if the location manager get FUSED provider and not ignore location settings
2085         clearInvocations(mMockLocationManager);
2086         doReturn(false).when(mMockTelecomManager).isInEmergencyCall();
2087         doReturn(false).when(mMockPhone).isInEcm();
2088         doReturn(false).when(mMockPhone2).isInEcm();
2089         doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
2090         doReturn(true).when(mMockLocationManager).isLocationEnabled();
2091         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
2092         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
2093 
2094         verify(mMockLocationManager, times(1))
2095                 .getCurrentLocation(mLocationProviderStringCaptor.capture(),
2096                         mLocationRequestCaptor.capture(), any(), any(), any());
2097         assertEquals(LocationManager.FUSED_PROVIDER, mLocationProviderStringCaptor.getValue());
2098         assertFalse(mLocationRequestCaptor.getValue().isLocationSettingsIgnored());
2099     }
2100 
2101     @Test
testHandleIsSatelliteSupportedResult()2102     public void testHandleIsSatelliteSupportedResult() throws Exception {
2103         // Setup for this test case
2104         Iterator<ResultReceiver> mockResultReceiverIterator = mock(Iterator.class);
2105         doReturn(mockResultReceiverIterator).when(mMockSatelliteAllowResultReceivers).iterator();
2106         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2107         doReturn(mMockResultReceiver).when(mockResultReceiverIterator).next();
2108 
2109         replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
2110                 mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
2111         doNothing().when(mMockSatelliteAllowResultReceivers).clear();
2112 
2113         // case that resultCode is not SATELLITE_RESULT_SUCCESS
2114         int resultCode = SATELLITE_RESULT_ERROR;
2115         Bundle bundle = new Bundle();
2116         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2117         clearInvocations(mMockResultReceiver);
2118         mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
2119         verify(mMockResultReceiver)
2120                 .send(mResultCodeIntCaptor.capture(), any());
2121         assertEquals(Integer.valueOf(SATELLITE_RESULT_ERROR), mResultCodeIntCaptor.getValue());
2122 
2123         // case no KEY_SATELLITE_SUPPORTED in the bundle data.
2124         // verify that the resultCode is delivered as it were
2125         resultCode = SATELLITE_RESULT_SUCCESS;
2126         bundle.putBoolean(KEY_SATELLITE_PROVISIONED, false);
2127         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2128         clearInvocations(mMockResultReceiver);
2129         mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
2130         verify(mMockResultReceiver).send(mResultCodeIntCaptor.capture(), any());
2131         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS), mResultCodeIntCaptor.getValue());
2132 
2133         // case KEY_SATELLITE_SUPPORTED is false
2134         // verify SATELLITE_RESULT_NOT_SUPPORTED is captured
2135         bundle.putBoolean(KEY_SATELLITE_SUPPORTED, false);
2136         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2137         clearInvocations(mMockResultReceiver);
2138         mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
2139         verify(mMockResultReceiver)
2140                 .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
2141         assertEquals(Integer.valueOf(SATELLITE_RESULT_NOT_SUPPORTED),
2142                 mResultCodeIntCaptor.getValue());
2143         assertEquals(false,
2144                 mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
2145 
2146         // case KEY_SATELLITE_SUPPORTED is success and region is not allowed
2147         // verify SATELLITE_RESULT_SUCCESS is captured
2148         bundle.putBoolean(KEY_SATELLITE_SUPPORTED, true);
2149         when(mMockCountryDetector.getCurrentNetworkCountryIso())
2150                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_KR));
2151         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2152         clearInvocations(mMockResultReceiver);
2153         mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
2154         verify(mMockResultReceiver)
2155                 .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
2156         assertEquals(Integer.valueOf(SATELLITE_RESULT_SUCCESS),
2157                 mResultCodeIntCaptor.getValue());
2158         assertEquals(false,
2159                 mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
2160 
2161         // case KEY_SATELLITE_SUPPORTED is success and locationManager is disabled
2162         // verify SATELLITE_RESULT_LOCATION_DISABLED is captured
2163         when(mMockCountryDetector.getCurrentNetworkCountryIso())
2164                 .thenReturn(List.of(TEST_SATELLITE_COUNTRY_CODE_US));
2165         doReturn(false).when(mMockLocationManager).isLocationEnabled();
2166         doReturn(true, false).when(mockResultReceiverIterator).hasNext();
2167         clearInvocations(mMockResultReceiver);
2168         mSatelliteAccessControllerUT.handleIsSatelliteSupportedResult(resultCode, bundle);
2169         verify(mMockResultReceiver)
2170                 .send(mResultCodeIntCaptor.capture(), mResultDataBundleCaptor.capture());
2171         assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_DISABLED),
2172                 mResultCodeIntCaptor.getValue());
2173         assertEquals(false,
2174                 mResultDataBundleCaptor.getValue().getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED));
2175     }
2176 
2177     @Test
testRequestIsCommunicationAllowedForCurrentLocationWithEnablingSatellite()2178     public void testRequestIsCommunicationAllowedForCurrentLocationWithEnablingSatellite() {
2179         // Set non-emergency case
2180         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
2181         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
2182         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
2183         doReturn(false).when(mMockTelecomManager).isInEmergencyCall();
2184         doReturn(false).when(mMockPhone).isInEcm();
2185         doReturn(false).when(mMockPhone2).isInEcm();
2186         doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
2187         doReturn(true).when(mMockLocationManager).isLocationEnabled();
2188         mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
2189         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
2190 
2191         // Invoking requestIsCommunicationAllowedForCurrentLocation(resultReceiver, "false");
2192         // verify that mLocationManager.isLocationEnabled() is invoked
2193         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
2194                 mSatelliteAllowedReceiver, false);
2195         mTestableLooper.processAllMessages();
2196         verify(mMockLocationManager, times(1)).isLocationEnabled();
2197         verify(mMockLocationManager, times(1)).getCurrentLocation(anyString(),
2198                 any(LocationRequest.class), any(CancellationSignal.class), any(Executor.class),
2199                 any(Consumer.class));
2200 
2201         // Invoking requestIsCommunicationAllowedForCurrentLocation(resultReceiver, "true");
2202         // verify that mLocationManager.isLocationEnabled() is not invoked
2203         clearInvocations(mMockLocationManager);
2204         mSatelliteAccessControllerUT.requestIsCommunicationAllowedForCurrentLocation(
2205                 mSatelliteAllowedReceiver, true);
2206         mTestableLooper.processAllMessages();
2207         verify(mMockLocationManager, times(1)).isLocationEnabled();
2208         verify(mMockLocationManager, never()).getCurrentLocation(anyString(),
2209                 any(LocationRequest.class), any(CancellationSignal.class), any(Executor.class),
2210                 any(Consumer.class));
2211     }
2212 
2213     @Test
testUpdateSystemSelectionChannels()2214     public void testUpdateSystemSelectionChannels() {
2215         // Set non-emergency case
2216         when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
2217 
2218         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
2219         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
2220         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
2221 
2222         // Invoke when regional config ID is not set.
2223         mSatelliteAccessControllerUT.setRegionalConfigId(null);
2224         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2225                 mSystemSelectionChannelUpdatedReceiver);
2226         mTestableLooper.processAllMessages();
2227         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2228                 mSystemSelectionChannelUpdatedSemaphore, 1));
2229         assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
2230                 mQueriedSystemSelectionChannelUpdatedResultCode);
2231 
2232         // Invoke when mSatelliteAccessConfigMap does not have data for given regional config ID
2233         int satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
2234         mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
2235         mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
2236         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2237                 mSystemSelectionChannelUpdatedReceiver);
2238         mTestableLooper.processAllMessages();
2239         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2240                 mSystemSelectionChannelUpdatedSemaphore, 1));
2241         assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
2242                 mQueriedSystemSelectionChannelUpdatedResultCode);
2243 
2244         // Invoke when mSatelliteAccessConfigMap does not have data and given data is old format.
2245         satelliteRegionalConfigId = UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
2246         mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
2247         mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
2248         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2249                 mSystemSelectionChannelUpdatedReceiver);
2250         mTestableLooper.processAllMessages();
2251         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2252                 mSystemSelectionChannelUpdatedSemaphore, 1));
2253         assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
2254                 mQueriedSystemSelectionChannelUpdatedResultCode);
2255 
2256         satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
2257         // Return success when SatelliteController.updateSystemSelectionChannels was invoked
2258         setupResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
2259 
2260         // Invoke updateSystemSelectionChannels when there is corresponding satellite access config.
2261         // Create satellite info 1
2262         String seed1 = "test-seed-satellite1";
2263         UUID uuid1 = UUID.nameUUIDFromBytes(seed1.getBytes());
2264         SatellitePosition satellitePosition1 = new SatellitePosition(0, 35876);
2265         int[] bands1 = {200, 201, 202};
2266         EarfcnRange earfcnRange1 = new EarfcnRange(300, 301);
2267         EarfcnRange earfcnRange2 = new EarfcnRange(310, 311);
2268         List<EarfcnRange> earfcnRangeList1 = new ArrayList<>(
2269                 Arrays.asList(earfcnRange1, earfcnRange2));
2270         SatelliteInfo satelliteInfo1 = new SatelliteInfo(uuid1, satellitePosition1, Arrays.stream(
2271                 bands1).boxed().collect(Collectors.toList()), earfcnRangeList1);
2272         // Create satellite info 2
2273         String seed2 = "test-seed-satellite2";
2274         UUID uuid2 = UUID.nameUUIDFromBytes(seed2.getBytes());
2275         SatellitePosition satellitePosition2 = new SatellitePosition(120, 35876);
2276         int[] bands2 = {210, 211, 212};
2277         EarfcnRange earfcnRange3 = new EarfcnRange(320, 321);
2278         EarfcnRange earfcnRange4 = new EarfcnRange(330, 331);
2279         List<EarfcnRange> earfcnRangeList2 = new ArrayList<>(
2280                 Arrays.asList(earfcnRange3, earfcnRange4));
2281         SatelliteInfo satelliteInfo2 = new SatelliteInfo(uuid2, satellitePosition2, Arrays.stream(
2282                 bands2).boxed().collect(Collectors.toList()), earfcnRangeList2);
2283         // Create satellite info 3
2284         String seed3 = "test-seed-satellite3";
2285         UUID uuid3 = UUID.nameUUIDFromBytes(seed3.getBytes());
2286         SatellitePosition satellitePosition3 = new SatellitePosition(120, 35876);
2287         int[] bands3 = {220, 221, 222};
2288         EarfcnRange earfcnRange5 = new EarfcnRange(340, 341);
2289         EarfcnRange earfcnRange6 = new EarfcnRange(350, 351);
2290         List<EarfcnRange> earfcnRangeList3 = new ArrayList<>(
2291                 Arrays.asList(earfcnRange5, earfcnRange6));
2292         SatelliteInfo satelliteInfo3 = new SatelliteInfo(uuid3, satellitePosition3, Arrays.stream(
2293                 bands3).boxed().collect(Collectors.toList()), earfcnRangeList3);
2294 
2295         int[] tagIds = {1, 2, 3};
2296         SatelliteAccessConfiguration satelliteAccessConfiguration =
2297                 new SatelliteAccessConfiguration(new ArrayList<>(
2298                         Arrays.asList(satelliteInfo1, satelliteInfo2, satelliteInfo3)),
2299                         Arrays.stream(tagIds).boxed().collect(Collectors.toList()));
2300 
2301         // Add satellite access configuration to map
2302         mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(satelliteRegionalConfigId,
2303                 satelliteAccessConfiguration);
2304 
2305         // Invoke updateSystemSelectionChannel
2306         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2307                 mSystemSelectionChannelUpdatedReceiver);
2308         mTestableLooper.processAllMessages();
2309         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2310                 mSystemSelectionChannelUpdatedSemaphore, 1));
2311         assertEquals(SATELLITE_RESULT_SUCCESS,
2312                 mQueriedSystemSelectionChannelUpdatedResultCode);
2313         ArgumentCaptor<List<SystemSelectionSpecifier>> systemSelectionSpecifierListCaptor =
2314                 ArgumentCaptor.forClass(List.class);
2315         verify(mMockSatelliteController, times(1)).updateSystemSelectionChannels(
2316                 systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
2317         List<SystemSelectionSpecifier> capturedList = systemSelectionSpecifierListCaptor.getValue();
2318         SystemSelectionSpecifier systemSelectionSpecifier = capturedList.getFirst();
2319 
2320         // Verify the fields value of given systemSelectionSpecifier matched with expected.
2321         int[] expectedBandsArray = IntStream.concat(
2322                 IntStream.concat(Arrays.stream(bands1), Arrays.stream(bands2)),
2323                 Arrays.stream(bands3)).toArray();
2324         int[] actualBandsArray = systemSelectionSpecifier.getBands();
2325         assertArrayEquals(expectedBandsArray, actualBandsArray);
2326 
2327         int[] expectedEarfcnsArray = {300, 301, 310, 311, 320, 321, 330, 331, 340, 341, 350, 351};
2328         int[] actualEarfcnsArray = systemSelectionSpecifier.getEarfcns();
2329         assertArrayEquals(expectedEarfcnsArray, actualEarfcnsArray);
2330 
2331         SatelliteInfo[] expectedSatelliteInfos = {satelliteInfo1, satelliteInfo2, satelliteInfo3};
2332         assertArrayEquals(expectedSatelliteInfos,
2333                 systemSelectionSpecifier.getSatelliteInfos().toArray(new SatelliteInfo[0]));
2334 
2335         int[] actualTagIdArray = systemSelectionSpecifier.getTagIds();
2336         assertArrayEquals(tagIds, actualTagIdArray);
2337 
2338         // Verify backward compatibility when there is valid data for default regional config ID
2339         satelliteRegionalConfigId = UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
2340         mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
2341         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2342                 mSystemSelectionChannelUpdatedReceiver);
2343         mTestableLooper.processAllMessages();
2344 
2345         // updateSelectionChannelResult will be invoked with the data for default regional config ID
2346         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2347                 mSystemSelectionChannelUpdatedSemaphore, 1));
2348         systemSelectionSpecifierListCaptor = ArgumentCaptor.forClass(List.class);
2349         verify(mMockSatelliteController, times(2)).updateSystemSelectionChannels(
2350                 systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
2351         capturedList = systemSelectionSpecifierListCaptor.getValue();
2352         systemSelectionSpecifier = capturedList.getFirst();
2353 
2354         // Data will be same with default regional config ID
2355 
2356         // Verify the fields value of given systemSelectionSpecifier matched with expected.
2357         actualBandsArray = systemSelectionSpecifier.getBands();
2358         assertArrayEquals(expectedBandsArray, actualBandsArray);
2359 
2360         actualEarfcnsArray = systemSelectionSpecifier.getEarfcns();
2361         assertArrayEquals(expectedEarfcnsArray, actualEarfcnsArray);
2362 
2363         assertArrayEquals(expectedSatelliteInfos,
2364                 systemSelectionSpecifier.getSatelliteInfos().toArray(new SatelliteInfo[0]));
2365 
2366         actualTagIdArray = systemSelectionSpecifier.getTagIds();
2367         assertArrayEquals(tagIds, actualTagIdArray);
2368 
2369         mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
2370     }
2371 
2372     @Test
testUpdateSystemSelectionChannels_HandleInvalidInput()2373     public void testUpdateSystemSelectionChannels_HandleInvalidInput() {
2374         // Set non-emergency case
2375         when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
2376 
2377         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
2378         setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
2379         when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
2380         int satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
2381         mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
2382         // Set return success when SatelliteController.updateSystemSelectionChannels was invoked
2383         setupResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
2384 
2385         // Create satellite info in which satellite position is null.
2386         String seed1 = "test-seed-satellite1";
2387         UUID uuid1 = UUID.nameUUIDFromBytes(seed1.getBytes());
2388         SatellitePosition satellitePosition1 = null;
2389         List<Integer> bandList1 = new ArrayList<>(List.of(200, 201, 202));
2390         EarfcnRange earfcnRange1 = new EarfcnRange(300, 301);
2391         EarfcnRange earfcnRange2 = new EarfcnRange(310, 311);
2392         List<EarfcnRange> earfcnRangeList1 = new ArrayList<>(
2393                 Arrays.asList(earfcnRange1, earfcnRange2));
2394         SatelliteInfo satelliteInfo1 = new SatelliteInfo(uuid1, satellitePosition1, bandList1,
2395                 earfcnRangeList1);
2396 
2397         // Create satellite info in which band list is empty
2398         String seed2 = "test-seed-satellite2";
2399         UUID uuid2 = UUID.nameUUIDFromBytes(seed2.getBytes());
2400         SatellitePosition satellitePosition2 = new SatellitePosition(120, 35876);
2401         List<Integer> bandList2 = new ArrayList<>();
2402         EarfcnRange earfcnRange3 = new EarfcnRange(320, 321);
2403         EarfcnRange earfcnRange4 = new EarfcnRange(330, 331);
2404         List<EarfcnRange> earfcnRangeList2 = new ArrayList<>(
2405                 Arrays.asList(earfcnRange3, earfcnRange4));
2406         SatelliteInfo satelliteInfo2 = new SatelliteInfo(uuid2, satellitePosition2, bandList2,
2407                 earfcnRangeList2);
2408 
2409         // Create satellite info 3, every field is valid
2410         String seed3 = "test-seed-satellite3";
2411         UUID uuid3 = UUID.nameUUIDFromBytes(seed3.getBytes());
2412         SatellitePosition satellitePosition3 = new SatellitePosition(120, 35876);
2413         List<Integer> bandList3 = new ArrayList<>(List.of(220, 221, 222));
2414         EarfcnRange earfcnRange5 = new EarfcnRange(340, 341);
2415         EarfcnRange earfcnRange6 = new EarfcnRange(350, 351);
2416         List<EarfcnRange> earfcnRangeList3 = new ArrayList<>(
2417                 Arrays.asList(earfcnRange5, earfcnRange6));
2418         SatelliteInfo satelliteInfo3 = new SatelliteInfo(uuid3, satellitePosition3, bandList3,
2419                 earfcnRangeList3);
2420         // Add empty tagId list
2421         List<Integer> tagIdList = new ArrayList<>();
2422 
2423         // Create satelliteAccessConfiguration with some of files of added Satellite info are empty.
2424         SatelliteAccessConfiguration satelliteAccessConfiguration1 =
2425                 new SatelliteAccessConfiguration(new ArrayList<>(
2426                         Arrays.asList(satelliteInfo1, satelliteInfo2, satelliteInfo3)), tagIdList);
2427 
2428         // Add satellite access configuration to map
2429         mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(satelliteRegionalConfigId,
2430                 satelliteAccessConfiguration1);
2431 
2432         // Invoke updateSystemSelectionChannel
2433         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2434                 mSystemSelectionChannelUpdatedReceiver);
2435         mTestableLooper.processAllMessages();
2436         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2437                 mSystemSelectionChannelUpdatedSemaphore, 1));
2438         assertEquals(SATELLITE_RESULT_SUCCESS,
2439                 mQueriedSystemSelectionChannelUpdatedResultCode);
2440         ArgumentCaptor<List<SystemSelectionSpecifier>> systemSelectionSpecifierListCaptor =
2441                 ArgumentCaptor.forClass(List.class);
2442         verify(mMockSatelliteController, times(1)).updateSystemSelectionChannels(
2443                 systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
2444         List<SystemSelectionSpecifier> capturedList = systemSelectionSpecifierListCaptor.getValue();
2445         SystemSelectionSpecifier systemSelectionSpecifier = capturedList.getFirst();
2446 
2447         // Verify the fields value of given systemSelectionSpecifier matched with expected.
2448         List<Integer> expectedBandList = new ArrayList<>(bandList1);
2449         expectedBandList.addAll(bandList2);
2450         expectedBandList.addAll(bandList3);
2451 
2452         List<Integer> actualBandList = Arrays.stream(systemSelectionSpecifier.getBands()).boxed()
2453                 .collect(Collectors.toList());
2454         assertEquals(expectedBandList, actualBandList);
2455 
2456         List<Integer> expectedEarfcnList = new ArrayList<>(
2457                 List.of(300, 301, 310, 311, 320, 321, 330, 331, 340, 341, 350, 351));
2458         List<Integer> actualEarfcnList = Arrays.stream(systemSelectionSpecifier.getEarfcns())
2459                 .boxed().collect(Collectors.toList());
2460         assertEquals(expectedEarfcnList, actualEarfcnList);
2461 
2462         assertEquals(satelliteInfo1, systemSelectionSpecifier.getSatelliteInfos().get(0));
2463         assertEquals(satelliteInfo2, systemSelectionSpecifier.getSatelliteInfos().get(1));
2464         assertEquals(satelliteInfo3, systemSelectionSpecifier.getSatelliteInfos().get(2));
2465 
2466         List<Integer> actualTagIdList = Arrays.stream(systemSelectionSpecifier.getTagIds()).boxed()
2467                 .collect(Collectors.toList());
2468         assertEquals(tagIdList, actualTagIdList);
2469 
2470         // Create satelliteAccessConfiguration with empty list of SatelliteInfo.
2471         SatelliteAccessConfiguration satelliteAccessConfiguration2 =
2472                 new SatelliteAccessConfiguration(new ArrayList<>(), tagIdList);
2473         mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(
2474                 DEFAULT_REGIONAL_SATELLITE_CONFIG_ID, satelliteAccessConfiguration2);
2475 
2476         // Invoke updateSystemSelectionChannel
2477         mSatelliteAccessControllerUT.updateSystemSelectionChannels(
2478                 mSystemSelectionChannelUpdatedReceiver);
2479         mTestableLooper.processAllMessages();
2480         assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
2481                 mSystemSelectionChannelUpdatedSemaphore, 1));
2482         assertEquals(SATELLITE_RESULT_SUCCESS,
2483                 mQueriedSystemSelectionChannelUpdatedResultCode);
2484         systemSelectionSpecifierListCaptor = ArgumentCaptor.forClass(List.class);
2485         verify(mMockSatelliteController, times(2)).updateSystemSelectionChannels(
2486                 systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
2487         capturedList = systemSelectionSpecifierListCaptor.getValue();
2488         systemSelectionSpecifier = capturedList.getFirst();
2489 
2490         // Verify the fields value of given systemSelectionSpecifier matched with expected.
2491         assertEquals(0, systemSelectionSpecifier.getBands().length);
2492         assertEquals(0, systemSelectionSpecifier.getEarfcns().length);
2493 
2494         SatelliteInfo[] expectedSatelliteInfoArray = new SatelliteInfo[0];
2495         assertArrayEquals(expectedSatelliteInfoArray,
2496                 systemSelectionSpecifier.getSatelliteInfos().toArray(new SatelliteInfo[0]));
2497 
2498         actualTagIdList = Arrays.stream(systemSelectionSpecifier.getTagIds()).boxed().collect(
2499                 Collectors.toList());
2500         assertEquals(tagIdList, actualTagIdList);
2501 
2502         mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
2503     }
2504 
2505     @Test
testCheckSharedPreferenceException()2506     public void testCheckSharedPreferenceException() {
2507         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
2508                 .remove(anyString());
2509         doThrow(new ClassCastException()).when(mMockSharedPreferences)
2510                 .getBoolean(anyString(), eq(false));
2511 
2512         mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
2513                 mMockFeatureFlags, mTestableLooper.getLooper(), mMockLocationManager,
2514                 mMockTelecomManager, mMockSatelliteOnDeviceAccessController, mMockSatS2File);
2515 
2516         verify(mMockSharedPreferencesEditor, times(4)).remove(anyString());
2517     }
2518 
sendSatelliteCommunicationAllowedEvent()2519     private void sendSatelliteCommunicationAllowedEvent() {
2520         Pair<Integer, ResultReceiver> requestPair =
2521                 new Pair<>(DEFAULT_SUBSCRIPTION_ID,
2522                         mSatelliteAccessControllerUT.getResultReceiverCurrentLocation());
2523         Message msg = mSatelliteAccessControllerUT.obtainMessage(
2524                 CMD_IS_SATELLITE_COMMUNICATION_ALLOWED);
2525         msg.obj = requestPair;
2526         msg.sendToTarget();
2527         mTestableLooper.processAllMessages();
2528     }
2529 
sendSatelliteDeviceAccessControllerResourcesTimeOutEvent()2530     private void sendSatelliteDeviceAccessControllerResourcesTimeOutEvent() {
2531         logd("sendSatelliteDeviceAccessControllerResourcesTimeOutEvent");
2532         Message msg = mSatelliteAccessControllerUT
2533                 .obtainMessage(EVENT_KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT);
2534         msg.sendToTarget();
2535         mTestableLooper.processAllMessages();
2536     }
2537 
sendConfigUpdateChangedEvent(Context context)2538     private void sendConfigUpdateChangedEvent(Context context) {
2539         Message msg = mSatelliteAccessControllerUT.obtainMessage(CMD_UPDATE_CONFIG_DATA);
2540         msg.obj = new AsyncResult(context, SATELLITE_RESULT_SUCCESS, null);
2541         msg.sendToTarget();
2542         mTestableLooper.processAllMessages();
2543     }
2544 
sendCurrentLocationTimeoutEvent()2545     private void sendCurrentLocationTimeoutEvent() {
2546         Message msg = mSatelliteAccessControllerUT
2547                 .obtainMessage(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT);
2548         msg.sendToTarget();
2549         mTestableLooper.processAllMessages();
2550     }
2551 
sendCommandValidateCountryCodeChangeEvent(Context context)2552     private void sendCommandValidateCountryCodeChangeEvent(Context context) {
2553         Message msg = mSatelliteAccessControllerUT.obtainMessage(EVENT_COUNTRY_CODE_CHANGED);
2554         msg.obj = new AsyncResult(context, SATELLITE_RESULT_SUCCESS, null);
2555         msg.sendToTarget();
2556         mTestableLooper.processAllMessages();
2557     }
2558 
clearAllInvocations()2559     private void clearAllInvocations() {
2560         clearInvocations(mMockSatelliteController);
2561         clearInvocations(mMockSatelliteOnDeviceAccessController);
2562         clearInvocations(mMockLocationManager);
2563         clearInvocations(mMockCountryDetector);
2564     }
2565 
verifyCountryDetectorApisCalled()2566     private void verifyCountryDetectorApisCalled() {
2567         verify(mMockCountryDetector).getCurrentNetworkCountryIso();
2568         verify(mMockCountryDetector).getCachedLocationCountryIsoInfo();
2569         verify(mMockCountryDetector).getCachedLocationCountryIsoInfo();
2570     }
2571 
waitForRequestIsSatelliteAllowedForCurrentLocationResult(Semaphore semaphore, int expectedNumberOfEvents)2572     private boolean waitForRequestIsSatelliteAllowedForCurrentLocationResult(Semaphore semaphore,
2573             int expectedNumberOfEvents) {
2574         for (int i = 0; i < expectedNumberOfEvents; i++) {
2575             try {
2576                 if (!semaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
2577                     logd("Timeout to receive "
2578                             + "requestIsCommunicationAllowedForCurrentLocation()"
2579                             + " callback");
2580                     return false;
2581                 }
2582             } catch (Exception ex) {
2583                 logd("waitForRequestIsSatelliteSupportedResult: Got exception=" + ex);
2584                 return false;
2585             }
2586         }
2587         return true;
2588     }
2589 
waitForRequestUpdateSystemSelectionChannelResult(Semaphore semaphore, int expectedNumberOfEvents)2590     private boolean waitForRequestUpdateSystemSelectionChannelResult(Semaphore semaphore,
2591             int expectedNumberOfEvents) {
2592         for (int i = 0; i < expectedNumberOfEvents; i++) {
2593             try {
2594                 if (!semaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
2595                     logd("Timeout to receive "
2596                             + "updateSystemSelectionChannel()"
2597                             + " callback");
2598                     return false;
2599                 }
2600             } catch (Exception ex) {
2601                 logd("updateSystemSelectionChannel: Got exception=" + ex);
2602                 return false;
2603             }
2604         }
2605         return true;
2606     }
2607 
sendLocationRequestResult(Location location)2608     private void sendLocationRequestResult(Location location) {
2609         mLocationRequestConsumerCaptor.getValue().accept(location);
2610         mTestableLooper.processAllMessages();
2611     }
2612 
setUpResponseForRequestIsSatelliteSupported( boolean isSatelliteSupported, @SatelliteManager.SatelliteResult int error)2613     private void setUpResponseForRequestIsSatelliteSupported(
2614             boolean isSatelliteSupported, @SatelliteManager.SatelliteResult int error) {
2615         doAnswer(invocation -> {
2616             ResultReceiver resultReceiver = invocation.getArgument(0);
2617             if (error == SATELLITE_RESULT_SUCCESS) {
2618                 Bundle bundle = new Bundle();
2619                 bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, isSatelliteSupported);
2620                 resultReceiver.send(error, bundle);
2621             } else {
2622                 resultReceiver.send(error, Bundle.EMPTY);
2623             }
2624             return null;
2625         }).when(mMockSatelliteController).requestIsSatelliteSupported(any(ResultReceiver.class));
2626     }
2627 
setUpResponseForRequestIsSatelliteProvisioned( boolean isSatelliteProvisioned, @SatelliteManager.SatelliteResult int error)2628     private void setUpResponseForRequestIsSatelliteProvisioned(
2629             boolean isSatelliteProvisioned, @SatelliteManager.SatelliteResult int error) {
2630         doAnswer(invocation -> {
2631             ResultReceiver resultReceiver = invocation.getArgument(0);
2632             if (error == SATELLITE_RESULT_SUCCESS) {
2633                 Bundle bundle = new Bundle();
2634                 bundle.putBoolean(KEY_SATELLITE_PROVISIONED,
2635                         isSatelliteProvisioned);
2636                 resultReceiver.send(error, bundle);
2637             } else {
2638                 resultReceiver.send(error, Bundle.EMPTY);
2639             }
2640             return null;
2641         }).when(mMockSatelliteController).requestIsSatelliteProvisioned(any(ResultReceiver.class));
2642     }
2643 
setupResponseForUpdateSystemSelectionChannels( @atelliteManager.SatelliteResult int error)2644     private void setupResponseForUpdateSystemSelectionChannels(
2645             @SatelliteManager.SatelliteResult int error) {
2646         doAnswer(invocation -> {
2647             ResultReceiver resultReceiver = invocation.getArgument(1);
2648             resultReceiver.send(error, null);
2649             return null;
2650         }).when(mMockSatelliteController).updateSystemSelectionChannels(anyList(),
2651                 any(ResultReceiver.class));
2652     }
2653 
2654     @SafeVarargs
listOf(E... values)2655     private static <E> List<E> listOf(E... values) {
2656         return Arrays.asList(values);
2657     }
2658 
logd(String message)2659     private static void logd(String message) {
2660         Log.d(TAG, message);
2661     }
2662 
2663     private static class TestSatelliteAccessController extends SatelliteAccessController {
2664         public long elapsedRealtimeNanos = 0;
2665 
2666         /**
2667          * Create a SatelliteAccessController instance.
2668          *
2669          * @param context                           The context associated with the
2670          *                                          {@link SatelliteAccessController} instance.
2671          * @param featureFlags                      The FeatureFlags that are supported.
2672          * @param looper                            The Looper to run the SatelliteAccessController
2673          *                                          on.
2674          * @param locationManager                   The LocationManager for querying current
2675          *                                          location of the
2676          *                                          device.
2677          * @param satelliteOnDeviceAccessController The on-device satellite access controller
2678          *                                          instance.
2679          */
TestSatelliteAccessController(Context context, FeatureFlags featureFlags, Looper looper, LocationManager locationManager, TelecomManager telecomManager, SatelliteOnDeviceAccessController satelliteOnDeviceAccessController, File s2CellFile)2680         protected TestSatelliteAccessController(Context context, FeatureFlags featureFlags,
2681                 Looper looper, LocationManager locationManager, TelecomManager telecomManager,
2682                 SatelliteOnDeviceAccessController satelliteOnDeviceAccessController,
2683                 File s2CellFile) {
2684             super(context, featureFlags, looper, locationManager, telecomManager,
2685                     satelliteOnDeviceAccessController, s2CellFile);
2686         }
2687 
2688         @Override
getElapsedRealtimeNanos()2689         protected long getElapsedRealtimeNanos() {
2690             return elapsedRealtimeNanos;
2691         }
2692 
isKeepOnDeviceAccessControllerResourcesTimerStarted()2693         public boolean isKeepOnDeviceAccessControllerResourcesTimerStarted() {
2694             return hasMessages(EVENT_KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT);
2695         }
2696 
isSatelliteOnDeviceAccessControllerReset()2697         public boolean isSatelliteOnDeviceAccessControllerReset() {
2698             synchronized (mLock) {
2699                 return (mSatelliteOnDeviceAccessController == null);
2700             }
2701         }
2702 
setSatelliteOnDeviceAccessController( @ullable SatelliteOnDeviceAccessController accessController)2703         public void setSatelliteOnDeviceAccessController(
2704                 @Nullable SatelliteOnDeviceAccessController accessController) {
2705             synchronized (mLock) {
2706                 mSatelliteOnDeviceAccessController = accessController;
2707             }
2708         }
2709 
getKeepOnDeviceAccessControllerResourcesTimeoutMillis()2710         public long getKeepOnDeviceAccessControllerResourcesTimeoutMillis() {
2711             return KEEP_ON_DEVICE_ACCESS_CONTROLLER_RESOURCES_TIMEOUT_MILLIS;
2712         }
2713 
getWaitForCurrentLocationTimeoutMillis()2714         public long getWaitForCurrentLocationTimeoutMillis() {
2715             return WAIT_FOR_CURRENT_LOCATION_TIMEOUT_MILLIS;
2716         }
2717 
isWaitForCurrentLocationTimerStarted()2718         public boolean isWaitForCurrentLocationTimerStarted() {
2719             return hasMessages(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT);
2720         }
2721 
getRetryCountPossibleChangeInSatelliteAllowedRegion()2722         public int getRetryCountPossibleChangeInSatelliteAllowedRegion() {
2723             return mRetryCountForValidatingPossibleChangeInAllowedRegion;
2724         }
2725 
setRetryCountPossibleChangeInSatelliteAllowedRegion(int retryCount)2726         public void setRetryCountPossibleChangeInSatelliteAllowedRegion(int retryCount) {
2727             mRetryCountForValidatingPossibleChangeInAllowedRegion = retryCount;
2728         }
2729 
getResultReceiverCurrentLocation()2730         public ResultReceiver getResultReceiverCurrentLocation() {
2731             return mHandlerForSatelliteAllowedResult;
2732         }
2733 
getLocationBroadcastReceiver()2734         public BroadcastReceiver getLocationBroadcastReceiver() {
2735             return mLocationModeChangedBroadcastReceiver;
2736         }
2737 
setLocationRequestCancellationSignalAsNull(boolean isNull)2738         public void setLocationRequestCancellationSignalAsNull(boolean isNull) {
2739             synchronized (mLock) {
2740                 mLocationRequestCancellationSignal = isNull ? null : new CancellationSignal();
2741             }
2742         }
2743 
isCurrentSatelliteAllowedState()2744         public boolean isCurrentSatelliteAllowedState() {
2745             synchronized (mSatelliteCommunicationAllowStateLock) {
2746                 return mCurrentSatelliteAllowedState;
2747             }
2748         }
2749 
2750         @Nullable
getRegionalConfigId()2751         public Integer getRegionalConfigId() {
2752             synchronized (mLock) {
2753                 return mRegionalConfigId;
2754             }
2755         }
2756 
2757         @Nullable
getNewRegionalConfigId()2758         public Integer getNewRegionalConfigId() {
2759             synchronized (mLock) {
2760                 return mNewRegionalConfigId;
2761             }
2762         }
2763 
setRegionalConfigId(@ullable Integer regionalConfigId)2764         public void setRegionalConfigId(@Nullable Integer regionalConfigId) {
2765             synchronized (mLock) {
2766                 mRegionalConfigId = regionalConfigId;
2767             }
2768         }
2769 
setSatelliteAccessConfigMap(int regionalConfigId, SatelliteAccessConfiguration satelliteAccessConfiguration)2770         public void setSatelliteAccessConfigMap(int regionalConfigId,
2771                 SatelliteAccessConfiguration satelliteAccessConfiguration) {
2772             synchronized (mLock) {
2773                 if (mSatelliteAccessConfigMap == null) {
2774                     mSatelliteAccessConfigMap = new HashMap<>();
2775                 }
2776                 mSatelliteAccessConfigMap.put(regionalConfigId, satelliteAccessConfiguration);
2777             }
2778         }
2779 
resetSatelliteAccessConfigMap()2780         public void resetSatelliteAccessConfigMap() {
2781             synchronized (mLock) {
2782                 if (mSatelliteAccessConfigMap == null) {
2783                     mSatelliteAccessConfigMap = new HashMap<>();
2784                 } else {
2785                     mSatelliteAccessConfigMap.clear();
2786                 }
2787             }
2788         }
2789 
getSatelliteAccessConfigMap()2790         public Map<Integer, SatelliteAccessConfiguration> getSatelliteAccessConfigMap() {
2791             synchronized (mLock) {
2792                 return mSatelliteAccessConfigMap;
2793             }
2794         }
2795 
getSatelliteAccessConfigVersion()2796         public int getSatelliteAccessConfigVersion() {
2797             synchronized (mLock) {
2798                 return mSatelliteAccessConfigVersion;
2799             }
2800         }
2801     }
2802 }
2803