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 android.telephony.satellite.cts;
18 
19 
20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
21 
22 import android.annotation.ArrayRes;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.app.ActivityManager;
26 import android.app.Instrumentation;
27 import android.content.BroadcastReceiver;
28 import android.content.ComponentName;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.content.ServiceConnection;
33 import android.content.pm.PackageManager;
34 import android.content.res.Resources;
35 import android.os.IBinder;
36 import android.os.RemoteException;
37 import android.telephony.Rlog;
38 import android.telephony.cts.externalpointingui.ExternalMockPointingUi;
39 import android.telephony.cts.externalsatellitegatewayservice.ExternalMockSatelliteGatewayService;
40 import android.telephony.cts.externalsatellitegatewayservice.IExternalMockSatelliteGatewayService;
41 import android.telephony.cts.externalsatellitegatewayservice.IExternalSatelliteGatewayListener;
42 import android.telephony.cts.externalsatelliteservice.ExternalMockSatelliteService;
43 import android.telephony.cts.externalsatelliteservice.IExternalMockSatelliteService;
44 import android.telephony.cts.externalsatelliteservice.IExternalSatelliteListener;
45 import android.telephony.cts.util.TelephonyUtils;
46 import android.telephony.satellite.stub.PointingInfo;
47 import android.telephony.satellite.stub.SatelliteDatagram;
48 import android.text.TextUtils;
49 
50 import com.android.internal.R;
51 
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.List;
55 import java.util.concurrent.CountDownLatch;
56 import java.util.concurrent.Semaphore;
57 import java.util.concurrent.TimeUnit;
58 
59 /**
60  * This class is responsible for connecting Telephony framework and CTS to the MockSatelliteService.
61  */
62 class MockSatelliteServiceManager {
63     private static final String TAG = "MockSatelliteServiceManager";
64     private static final String PACKAGE = "android.telephony.cts";
65     private static final String EXTERNAL_SATELLITE_GATEWAY_PACKAGE =
66             ExternalMockSatelliteGatewayService.class.getPackage().getName();
67     private static final String EXTERNAL_SATELLITE_PACKAGE =
68             ExternalMockSatelliteService.class.getPackage().getName();
69     private static final String EXTERNAL_POINTING_UI_PACKAGE =
70             ExternalMockPointingUi.class.getPackage().getName();
71     private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME_CMD =
72             "cmd phone set-satellite-service-package-name -s ";
73     private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME_CMD =
74             "cmd phone set-satellite-gateway-service-package-name -s ";
75     private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION_CMD =
76             "cmd phone set-satellite-listening-timeout-duration -t ";
77     private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME_CMD =
78             "cmd phone set-satellite-pointing-ui-class-name";
79     private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION_CMD =
80             "cmd phone set-datagram-controller-timeout-duration ";
81 
82     private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG_CMD =
83             "cmd phone set-datagram-controller-boolean-config ";
84 
85     private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION_CMD =
86             "cmd phone set-satellite-controller-timeout-duration ";
87     private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
88             "cmd phone set-should-send-datagram-to-modem-in-demo-mode ";
89     private static final String SET_COUNTRY_CODES = "cmd phone set-country-codes";
90     private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
91             "cmd phone set-satellite-access-control-overlay-configs";
92     private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
93             "cmd phone set-is-satellite-communication-allowed-for-current-location-cache ";
94 
95     private static final long TIMEOUT = 5000;
96     @NonNull private ActivityManager mActivityManager;
97     @NonNull private UidImportanceListener mUidImportanceListener = new UidImportanceListener();
98 
99     private MockSatelliteService mSatelliteService;
100     private TestSatelliteServiceConnection mSatelliteServiceConn;
101     private IExternalMockSatelliteService mExternalSatelliteService;
102     private ExternalSatelliteServiceConnection mExternalSatelliteServiceConn;
103     private final Semaphore mRemoteServiceConnectedSemaphore = new Semaphore(0);
104     private final Semaphore mExternalServiceDisconnectedSemaphore = new Semaphore(0);
105     private MockSatelliteGatewayService mSatelliteGatewayService;
106     private TestSatelliteGatewayServiceConnection mSatelliteGatewayServiceConn;
107     private IExternalMockSatelliteGatewayService mExternalSatelliteGatewayService;
108     private ExternalSatelliteGatewayServiceConnection mExternalSatelliteGatewayServiceConn;
109     private final Semaphore mRemoteGatewayServiceConnectedSemaphore = new Semaphore(0);
110     private final Semaphore mRemoteGatewayServiceDisconnectedSemaphore = new Semaphore(0);
111     private final Semaphore mExternalGatewayServiceDisconnectedSemaphore = new Semaphore(0);
112     private Instrumentation mInstrumentation;
113     private final Semaphore mStartSendingPointingInfoSemaphore = new Semaphore(0);
114     private final Semaphore mStopSendingPointingInfoSemaphore = new Semaphore(0);
115     private final Semaphore mPollPendingDatagramsSemaphore = new Semaphore(0);
116     private final Semaphore mStopPointingUiSemaphore = new Semaphore(0);
117     private final Semaphore mSendDatagramsSemaphore = new Semaphore(0);
118     private final Semaphore mRequestSatelliteEnabledSemaphore = new Semaphore(0);
119     private final Object mRequestSatelliteEnabledLock = new Object();
120     private List<SatelliteDatagram> mSentSatelliteDatagrams = new ArrayList<>();
121     private List<Boolean> mSentIsEmergencyList = new ArrayList<>();
122     private final Object mSendDatagramLock = new Object();
123     private final Semaphore mListeningEnabledSemaphore = new Semaphore(0);
124     private List<Boolean> mListeningEnabledList = new ArrayList<>();
125     private final Object mListeningEnabledLock = new Object();
126     private final Semaphore mMockPointingUiActivitySemaphore = new Semaphore(0);
127     private final MockPointingUiActivityStatusReceiver mMockPointingUiActivityStatusReceiver =
128             new MockPointingUiActivityStatusReceiver(mMockPointingUiActivitySemaphore);
129     private final boolean mIsSatelliteServicePackageConfigured;
130     boolean mIsPointingUiOverridden = false;
131     private final Semaphore mSetSatellitePlmnSemaphore = new Semaphore(0);
132 
133     @NonNull
134     private final ILocalSatelliteListener mSatelliteListener =
135             new ILocalSatelliteListener.Stub() {
136                 @Override
137                 public void onRemoteServiceConnected() {
138                     logd("onRemoteServiceConnected");
139                     mRemoteServiceConnectedSemaphore.release();
140                 }
141 
142                 @Override
143                 public void onStartSendingSatellitePointingInfo() {
144                     logd("onStartSendingSatellitePointingInfo");
145                     try {
146                         mStartSendingPointingInfoSemaphore.release();
147                     } catch (Exception ex) {
148                         logd("onStartSendingSatellitePointingInfo: Got exception, ex=" + ex);
149                     }
150                 }
151 
152                 @Override
153                 public void onStopSendingSatellitePointingInfo() {
154                     logd("onStopSendingSatellitePointingInfo");
155                     try {
156                         mStopSendingPointingInfoSemaphore.release();
157                     } catch (Exception ex) {
158                         logd("onStopSendingSatellitePointingInfo: Got exception, ex=" + ex);
159                     }
160                 }
161 
162                 @Override
163                 public void onPollPendingSatelliteDatagrams() {
164                     logd("onPollPendingSatelliteDatagrams");
165                     try {
166                         mPollPendingDatagramsSemaphore.release();
167                     } catch (Exception ex) {
168                         logd("onPollPendingSatelliteDatagrams: Got exception, ex=" + ex);
169                     }
170                 }
171 
172                 @Override
173                 public void onSendSatelliteDatagram(
174                         SatelliteDatagram datagram, boolean isEmergency) {
175                     logd("onSendSatelliteDatagram");
176                     synchronized (mSendDatagramLock) {
177                         mSentSatelliteDatagrams.add(datagram);
178                         mSentIsEmergencyList.add(isEmergency);
179                     }
180                     try {
181                         mSendDatagramsSemaphore.release();
182                     } catch (Exception ex) {
183                         logd("onSendSatelliteDatagram: Got exception, ex=" + ex);
184                     }
185                 }
186 
187                 @Override
188                 public void onSatelliteListeningEnabled(boolean enabled) {
189                     logd("onSatelliteListeningEnabled: enabled=" + enabled);
190                     synchronized (mListeningEnabledLock) {
191                         mListeningEnabledList.add(enabled);
192                     }
193                     try {
194                         mListeningEnabledSemaphore.release();
195                     } catch (Exception ex) {
196                         logd("onSatelliteListeningEnabled: Got exception, ex=" + ex);
197                     }
198                 }
199 
200                 @Override
201                 public void onSetSatellitePlmn() {
202                     logd("onSetSatellitePlmn()");
203                     try {
204                         mSetSatellitePlmnSemaphore.release();
205                     } catch (Exception ex) {
206                         logd("onSetSatellitePlmn: Got exception, ex=" + ex);
207                     }
208                 }
209 
210                 @Override
211                 public void onRequestSatelliteEnabled(boolean enableSatellite) {
212                     logd("onRequestSatelliteEnabled: enableSatellite=" + enableSatellite);
213                     try {
214                         mRequestSatelliteEnabledSemaphore.release();
215                     } catch (Exception ex) {
216                         logd("onRequestSatelliteEnabled: Got exception, ex=" + ex);
217                     }
218                 }
219             };
220 
221     @NonNull
222     private final ILocalSatelliteGatewayListener mSatelliteGatewayListener =
223             new ILocalSatelliteGatewayListener.Stub() {
224                 @Override
225                 public void onRemoteServiceConnected() {
226                     logd("ILocalSatelliteGatewayListener: onRemoteServiceConnected");
227                     mRemoteGatewayServiceConnectedSemaphore.release();
228                 }
229 
230                 @Override
231                 public void onRemoteServiceDisconnected() {
232                     logd("ILocalSatelliteGatewayListener: onRemoteServiceDisconnected");
233                     mRemoteGatewayServiceDisconnectedSemaphore.release();
234                 }
235             };
236 
237     private class TestSatelliteServiceConnection implements ServiceConnection {
238         private final CountDownLatch mLatch;
239 
TestSatelliteServiceConnection(CountDownLatch latch)240         TestSatelliteServiceConnection(CountDownLatch latch) {
241             mLatch = latch;
242         }
243 
244         @Override
onServiceConnected(ComponentName name, IBinder service)245         public void onServiceConnected(ComponentName name, IBinder service) {
246             logd("onServiceConnected");
247             mSatelliteService = ((MockSatelliteService.LocalBinder) service).getService();
248             mSatelliteService.setLocalSatelliteListener(mSatelliteListener);
249             mLatch.countDown();
250         }
251 
252         @Override
onServiceDisconnected(ComponentName name)253         public void onServiceDisconnected(ComponentName name) {
254             logd("onServiceDisconnected");
255             mSatelliteService = null;
256         }
257     }
258 
259     private class ExternalSatelliteServiceConnection implements ServiceConnection {
260         private final CountDownLatch mLatch;
261 
ExternalSatelliteServiceConnection(CountDownLatch latch)262         ExternalSatelliteServiceConnection(CountDownLatch latch) {
263             mLatch = latch;
264         }
265 
266         @Override
onServiceConnected(ComponentName name, IBinder service)267         public void onServiceConnected(ComponentName name, IBinder service) {
268             logd("ExternalSatelliteService: onServiceConnected");
269             mExternalSatelliteService =
270                     IExternalMockSatelliteService.Stub.asInterface(service);
271             try {
272                 mExternalSatelliteService.setExternalSatelliteListener(
273                         mExternalSatelliteListener);
274                 mLatch.countDown();
275             } catch (RemoteException ex) {
276                 loge("ExternalSatelliteService: setExternalSatelliteListener ex=" + ex);
277             }
278         }
279 
280         @Override
onServiceDisconnected(ComponentName name)281         public void onServiceDisconnected(ComponentName name) {
282             logd("ExternalSatelliteService: onServiceDisconnected");
283             mExternalSatelliteService = null;
284             try {
285                 mExternalServiceDisconnectedSemaphore.release();
286             } catch (Exception ex) {
287                 loge("ExternalSatelliteService: ex=" + ex);
288             }
289         }
290     }
291 
292     private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
293         @Override
onUidImportance(int uid, int importance)294         public void onUidImportance(int uid, int importance) {
295             if (importance != IMPORTANCE_GONE) return;
296             final PackageManager pm = mInstrumentation.getContext().getPackageManager();
297             final String[] callerPackages = pm.getPackagesForUid(uid);
298             if (callerPackages != null) {
299                 if (Arrays.stream(callerPackages)
300                         .anyMatch(EXTERNAL_POINTING_UI_PACKAGE::contains)) {
301                     mStopPointingUiSemaphore.release();
302                 }
303             }
304         }
305     }
306 
307     @NonNull
308     private final IExternalSatelliteListener mExternalSatelliteListener =
309             new IExternalSatelliteListener.Stub() {
310                 @Override
311                 public void onRemoteServiceConnected() {
312                     logd("IExternalSatelliteListener: onRemoteServiceConnected");
313                     mRemoteServiceConnectedSemaphore.release();
314                 }
315             };
316 
317     private class TestSatelliteGatewayServiceConnection implements ServiceConnection {
318         private final CountDownLatch mLatch;
319 
TestSatelliteGatewayServiceConnection(CountDownLatch latch)320         TestSatelliteGatewayServiceConnection(CountDownLatch latch) {
321             mLatch = latch;
322         }
323 
324         @Override
onServiceConnected(ComponentName name, IBinder service)325         public void onServiceConnected(ComponentName name, IBinder service) {
326             logd("GatewayService: onServiceConnected");
327             mSatelliteGatewayService =
328                     ((MockSatelliteGatewayService.LocalBinder) service).getService();
329             mSatelliteGatewayService.setLocalSatelliteListener(mSatelliteGatewayListener);
330             mLatch.countDown();
331         }
332 
333         @Override
onServiceDisconnected(ComponentName name)334         public void onServiceDisconnected(ComponentName name) {
335             logd("GatewayService: onServiceDisconnected");
336             mSatelliteGatewayService = null;
337         }
338     }
339 
340     @NonNull
341     private final IExternalSatelliteGatewayListener mExternalSatelliteGatewayListener =
342             new IExternalSatelliteGatewayListener.Stub() {
343                 @Override
344                 public void onRemoteServiceConnected() {
345                     logd("IExternalSatelliteGatewayListener: onRemoteServiceConnected");
346                     mRemoteGatewayServiceConnectedSemaphore.release();
347                 }
348             };
349 
350     private class ExternalSatelliteGatewayServiceConnection implements ServiceConnection {
351         private final CountDownLatch mLatch;
352 
ExternalSatelliteGatewayServiceConnection(CountDownLatch latch)353         ExternalSatelliteGatewayServiceConnection(CountDownLatch latch) {
354             mLatch = latch;
355         }
356 
357         @Override
onServiceConnected(ComponentName name, IBinder service)358         public void onServiceConnected(ComponentName name, IBinder service) {
359             logd("ExternalGatewayService: onServiceConnected");
360             mExternalSatelliteGatewayService =
361                     IExternalMockSatelliteGatewayService.Stub.asInterface(service);
362             try {
363                 mExternalSatelliteGatewayService.setExternalSatelliteGatewayListener(
364                         mExternalSatelliteGatewayListener);
365                 mLatch.countDown();
366             } catch (RemoteException ex) {
367                 loge("ExternalGatewayService: setExternalSatelliteGatewayListener ex=" + ex);
368             }
369         }
370 
371         @Override
onServiceDisconnected(ComponentName name)372         public void onServiceDisconnected(ComponentName name) {
373             logd("ExternalGatewayService: onServiceDisconnected");
374             mExternalSatelliteGatewayService = null;
375             try {
376                 mExternalGatewayServiceDisconnectedSemaphore.release();
377             } catch (Exception ex) {
378                 loge("ExternalGatewayService: ex=" + ex);
379             }
380         }
381     }
382 
MockSatelliteServiceManager(Instrumentation instrumentation)383     MockSatelliteServiceManager(Instrumentation instrumentation) {
384         mInstrumentation = instrumentation;
385         mIsSatelliteServicePackageConfigured = !TextUtils.isEmpty(getSatelliteServicePackageName());
386     }
387 
connectSatelliteService()388     boolean connectSatelliteService() {
389         logd("connectSatelliteService starting ...");
390         if (!setupLocalSatelliteService()) {
391             loge("Failed to set up local satellite service");
392             return false;
393         }
394 
395         try {
396             if (!setSatelliteServicePackageName(PACKAGE)) {
397                 loge("Failed to set satellite service package name");
398                 return false;
399             }
400         } catch (Exception ex) {
401             loge("connectSatelliteService: Got exception with setSatelliteServicePackageName "
402                     + "ex=" + ex);
403             return false;
404         }
405 
406         // Wait for SatelliteModemInterface connecting to MockSatelliteService.
407         return waitForRemoteSatelliteServiceConnected(1);
408     }
409 
connectExternalSatelliteService()410     boolean connectExternalSatelliteService() {
411         logd("connectExternalSatelliteService starting ...");
412         if (!setupExternalSatelliteService()) {
413             loge("Failed to set up external satellite service");
414             return false;
415         }
416 
417         try {
418             if (!setSatelliteServicePackageName(EXTERNAL_SATELLITE_PACKAGE)) {
419                 loge("Failed to set satellite service package name");
420                 return false;
421             }
422         } catch (Exception ex) {
423             loge("connectExternalSatelliteService: Got exception with "
424                     + "setSatelliteServicePackageName, ex=" + ex);
425             return false;
426         }
427         return true;
428     }
429 
setupExternalSatelliteService()430     boolean setupExternalSatelliteService() {
431         logd("setupExternalSatelliteService start");
432         if (mExternalSatelliteService != null) {
433             logd("setupExternalSatelliteService: external service is already set up");
434             return true;
435         }
436         CountDownLatch latch = new CountDownLatch(1);
437         mExternalSatelliteServiceConn = new ExternalSatelliteServiceConnection(latch);
438         Intent intent = new Intent();
439         intent.setComponent(new ComponentName(EXTERNAL_SATELLITE_PACKAGE,
440                 ExternalMockSatelliteService.class.getName()));
441         mInstrumentation.getContext().bindService(intent, mExternalSatelliteServiceConn,
442                 Context.BIND_AUTO_CREATE);
443         try {
444             return latch.await(TIMEOUT, TimeUnit.MILLISECONDS);
445         } catch (InterruptedException e) {
446             loge("setupExternalSatelliteService: Got InterruptedException e=" + e);
447             return false;
448         }
449     }
450 
connectSatelliteGatewayService()451     boolean connectSatelliteGatewayService() {
452         logd("connectSatelliteGatewayService starting ...");
453         if (!setupLocalSatelliteGatewayService()) {
454             loge("Failed to set up local satellite gateway service");
455             return false;
456         }
457 
458         try {
459             if (!setSatelliteGatewayServicePackageName(PACKAGE)) {
460                 loge("Failed to set satellite gateway service package name");
461                 return false;
462             }
463         } catch (Exception ex) {
464             loge("connectSatelliteGatewayService: Got exception with "
465                     + "setSatelliteGatewayServicePackageName, ex=" + ex);
466             return false;
467         }
468         return true;
469     }
470 
connectExternalSatelliteGatewayService()471     boolean connectExternalSatelliteGatewayService() {
472         logd("connectExternalSatelliteGatewayService starting ...");
473         if (!setupExternalSatelliteGatewayService()) {
474             loge("Failed to set up external satellite gateway service");
475             return false;
476         }
477 
478         try {
479             if (!setSatelliteGatewayServicePackageName(EXTERNAL_SATELLITE_GATEWAY_PACKAGE)) {
480                 loge("Failed to set satellite gateway service package name");
481                 return false;
482             }
483         } catch (Exception ex) {
484             loge("connectExternalSatelliteGatewayService: Got exception with "
485                     + "setSatelliteGatewayServicePackageName, ex=" + ex);
486             return false;
487         }
488         return true;
489     }
490 
setupExternalSatelliteGatewayService()491     boolean setupExternalSatelliteGatewayService() {
492         logd("setupExternalSatelliteGatewayService start");
493         if (mExternalSatelliteGatewayService != null) {
494             logd("setupExternalSatelliteGatewayService: external service is already set up");
495             return true;
496         }
497         CountDownLatch latch = new CountDownLatch(1);
498         mExternalSatelliteGatewayServiceConn = new ExternalSatelliteGatewayServiceConnection(latch);
499         Intent intent = new Intent();
500         intent.setComponent(new ComponentName(EXTERNAL_SATELLITE_GATEWAY_PACKAGE,
501                 ExternalMockSatelliteGatewayService.class.getName()));
502         mInstrumentation.getContext().bindService(intent, mExternalSatelliteGatewayServiceConn,
503                 Context.BIND_AUTO_CREATE);
504         try {
505             return latch.await(TIMEOUT, TimeUnit.MILLISECONDS);
506         } catch (InterruptedException e) {
507             loge("setupExternalSatelliteGatewayService: Got InterruptedException e=" + e);
508             return false;
509         }
510     }
511 
restoreSatelliteServicePackageName()512     boolean restoreSatelliteServicePackageName() {
513         logd("restoreSatelliteServicePackageName");
514         try {
515             if (!setSatelliteServicePackageName(null)) {
516                 loge("Failed to restore satellite service package name");
517                 return false;
518             }
519         } catch (Exception ex) {
520             loge("restoreSatelliteServicePackageName: Got exception with "
521                     + "setSatelliteServicePackageName ex=" + ex);
522             return false;
523         }
524         return true;
525     }
526 
restoreSatelliteGatewayServicePackageName()527     boolean restoreSatelliteGatewayServicePackageName() {
528         logd("restoreSatelliteGatewayServicePackageName");
529         if (mSatelliteGatewayServiceConn != null) {
530             mInstrumentation.getContext().unbindService(mSatelliteGatewayServiceConn);
531         }
532         mSatelliteGatewayServiceConn = null;
533         mSatelliteGatewayService = null;
534         try {
535             if (!setSatelliteGatewayServicePackageName(null)) {
536                 loge("Failed to restore satellite gateway service package name");
537                 return false;
538             }
539         } catch (Exception ex) {
540             loge("restoreSatelliteGatewayServicePackageName: Got exception with "
541                     + "setSatelliteGatewayServicePackageName ex=" + ex);
542             return false;
543         }
544         return true;
545     }
546 
overrideSatellitePointingUiClassName()547     boolean overrideSatellitePointingUiClassName() {
548         logd("overrideSatellitePointingUiClassName");
549         try {
550             if (!setSatellitePointingUiClassName(
551                     PACKAGE, MockPointingUiActivity.class.getName())) {
552                 loge("Failed to override satellite pointing UI package and class names");
553                 return false;
554             }
555         } catch (Exception ex) {
556             loge("overrideSatellitePointingUiClassName: Got exception with "
557                     + "setSatellitePointingUiClassName ex=" + ex);
558             return false;
559         }
560         registerForMockPointingUiActivityStatus();
561         mIsPointingUiOverridden = true;
562         return true;
563     }
564 
overrideExternalSatellitePointingUiClassName()565     boolean overrideExternalSatellitePointingUiClassName() {
566         logd("overrideExternalSatellitePointingUiClassName");
567         try {
568             mActivityManager = mInstrumentation.getContext()
569                     .getSystemService(ActivityManager.class);
570             mActivityManager.addOnUidImportanceListener(mUidImportanceListener, IMPORTANCE_GONE);
571             if (!setSatellitePointingUiClassName(
572                     EXTERNAL_POINTING_UI_PACKAGE, ExternalMockPointingUi.class.getName())) {
573                 loge("Failed to override external satellite pointing UI package and class names");
574                 return false;
575             }
576         } catch (Exception ex) {
577             loge("overrideExternalSatellitePointingUiClassName: Got exception with "
578                     + "setSatellitePointingUiClassName ex=" + ex);
579             return false;
580         }
581         registerForExternalMockPointingUiActivityStatus();
582         mIsPointingUiOverridden = true;
583         return true;
584     }
restoreSatellitePointingUiClassName()585     boolean restoreSatellitePointingUiClassName() {
586         logd("restoreSatellitePointingUiClassName");
587         if (!mIsPointingUiOverridden) {
588             return true;
589         }
590         try {
591             if (!setSatellitePointingUiClassName(null, null)) {
592                 loge("Failed to restore satellite pointing UI package and class names");
593                 return false;
594             }
595         } catch (Exception ex) {
596             loge("restoreSatellitePointingUiClassName: Got exception with "
597                     + "setSatellitePointingUiClassName ex=" + ex);
598             return false;
599         }
600         unregisterForMockPointingUiActivityStatus();
601         mIsPointingUiOverridden = false;
602         return true;
603     }
604 
isSatelliteServicePackageConfigured()605     boolean isSatelliteServicePackageConfigured() {
606         return mIsSatelliteServicePackageConfigured;
607     }
608 
getSentIsEmergency(int index)609     Boolean getSentIsEmergency(int index) {
610         synchronized (mSendDatagramLock) {
611             if (index >= mSentIsEmergencyList.size()) return null;
612             return mSentIsEmergencyList.get(index);
613         }
614     }
615 
getSentSatelliteDatagram(int index)616     SatelliteDatagram getSentSatelliteDatagram(int index) {
617         synchronized (mSendDatagramLock) {
618             if (index >= mSentSatelliteDatagrams.size()) return null;
619             return mSentSatelliteDatagrams.get(index);
620         }
621     }
622 
clearSentSatelliteDatagramInfo()623     void clearSentSatelliteDatagramInfo() {
624         synchronized (mSendDatagramLock) {
625             mSentSatelliteDatagrams.clear();
626             mSentIsEmergencyList.clear();
627             mSendDatagramsSemaphore.drainPermits();
628         }
629     }
630 
clearRequestSatelliteEnabledInfo()631     void clearRequestSatelliteEnabledInfo() {
632         synchronized (mRequestSatelliteEnabledLock) {
633             mRequestSatelliteEnabledSemaphore.drainPermits();
634         }
635     }
636 
getTotalCountOfSentSatelliteDatagrams()637     int getTotalCountOfSentSatelliteDatagrams() {
638         synchronized (mSendDatagramLock) {
639             return mSentSatelliteDatagrams.size();
640         }
641     }
642 
getListeningEnabled(int index)643     Boolean getListeningEnabled(int index) {
644         synchronized (mListeningEnabledLock) {
645             if (index >= mListeningEnabledList.size()) return null;
646             return mListeningEnabledList.get(index);
647         }
648     }
649 
getTotalCountOfListeningEnabledList()650     int getTotalCountOfListeningEnabledList() {
651         synchronized (mListeningEnabledLock) {
652             return mListeningEnabledList.size();
653         }
654     }
655 
clearListeningEnabledList()656     void clearListeningEnabledList() {
657         synchronized (mListeningEnabledLock) {
658             mListeningEnabledList.clear();
659             mListeningEnabledSemaphore.drainPermits();
660         }
661     }
662 
clearMockPointingUiActivityStatusChanges()663     void clearMockPointingUiActivityStatusChanges() {
664         mMockPointingUiActivitySemaphore.drainPermits();
665     }
666 
clearRemoteGatewayServiceConnectedStatusChanges()667     void clearRemoteGatewayServiceConnectedStatusChanges() {
668         mRemoteGatewayServiceConnectedSemaphore.drainPermits();
669     }
670 
clearRemoteGatewayServiceDisconnectedStatusChanges()671     void clearRemoteGatewayServiceDisconnectedStatusChanges() {
672         mRemoteGatewayServiceDisconnectedSemaphore.drainPermits();
673     }
674 
clearStopPointingUiActivity()675     void clearStopPointingUiActivity() {
676         mStopPointingUiSemaphore.drainPermits();
677     }
678 
waitForEventOnStartSendingSatellitePointingInfo(int expectedNumberOfEvents)679     boolean waitForEventOnStartSendingSatellitePointingInfo(int expectedNumberOfEvents) {
680         for (int i = 0; i < expectedNumberOfEvents; i++) {
681             try {
682                 if (!mStartSendingPointingInfoSemaphore.tryAcquire(
683                         TIMEOUT, TimeUnit.MILLISECONDS)) {
684                     loge("Timeout to receive onStartSendingSatellitePointingInfo");
685                     return false;
686                 }
687             } catch (Exception ex) {
688                 loge("onStartSendingSatellitePointingInfo: Got exception=" + ex);
689                 return false;
690             }
691         }
692         return true;
693     }
694 
waitForEventOnStopSendingSatellitePointingInfo(int expectedNumberOfEvents)695     boolean waitForEventOnStopSendingSatellitePointingInfo(int expectedNumberOfEvents) {
696         for (int i = 0; i < expectedNumberOfEvents; i++) {
697             try {
698                 if (!mStopSendingPointingInfoSemaphore.tryAcquire(
699                         TIMEOUT, TimeUnit.MILLISECONDS)) {
700                     loge("Timeout to receive onStopSendingSatellitePointingInfo");
701                     return false;
702                 }
703             } catch (Exception ex) {
704                 loge("onStopSendingSatellitePointingInfo: Got exception=" + ex);
705                 return false;
706             }
707         }
708         return true;
709     }
710 
waitForEventOnPollPendingSatelliteDatagrams(int expectedNumberOfEvents)711     boolean waitForEventOnPollPendingSatelliteDatagrams(int expectedNumberOfEvents) {
712         for (int i = 0; i < expectedNumberOfEvents; i++) {
713             try {
714                 if (!mPollPendingDatagramsSemaphore.tryAcquire(
715                         TIMEOUT, TimeUnit.MILLISECONDS)) {
716                     loge("Timeout to receive onPollPendingSatelliteDatagrams");
717                     return false;
718                 }
719             } catch (Exception ex) {
720                 loge("onPollPendingSatelliteDatagrams: Got exception=" + ex);
721                 return false;
722             }
723         }
724         return true;
725     }
726 
clearPollPendingDatagramPermits()727     void clearPollPendingDatagramPermits() {
728         mPollPendingDatagramsSemaphore.drainPermits();
729     }
730 
waitForEventOnSendSatelliteDatagram(int expectedNumberOfEvents)731     boolean waitForEventOnSendSatelliteDatagram(int expectedNumberOfEvents) {
732         for (int i = 0; i < expectedNumberOfEvents; i++) {
733             try {
734                 if (!mSendDatagramsSemaphore.tryAcquire(
735                         TIMEOUT, TimeUnit.MILLISECONDS)) {
736                     loge("Timeout to receive onSendSatelliteDatagram");
737                     return false;
738                 }
739             } catch (Exception ex) {
740                 loge("onSendSatelliteDatagram: Got exception=" + ex);
741                 return false;
742             }
743         }
744         return true;
745     }
746 
waitForEventOnRequestSatelliteEnabled(int expectedNumberOfEvents)747     boolean waitForEventOnRequestSatelliteEnabled(int expectedNumberOfEvents) {
748         for (int i = 0; i < expectedNumberOfEvents; i++) {
749             try {
750                 if (!mRequestSatelliteEnabledSemaphore.tryAcquire(
751                         TIMEOUT, TimeUnit.MILLISECONDS)) {
752                     loge("Timeout to receive OnRequestSatelliteEnabled");
753                     return false;
754                 }
755             } catch (Exception ex) {
756                 loge("OnRequestSatelliteEnabled: Got exception=" + ex);
757                 return false;
758             }
759         }
760         return true;
761     }
762 
waitForEventOnSatelliteListeningEnabled(int expectedNumberOfEvents)763     boolean waitForEventOnSatelliteListeningEnabled(int expectedNumberOfEvents) {
764         for (int i = 0; i < expectedNumberOfEvents; i++) {
765             try {
766                 if (!mListeningEnabledSemaphore.tryAcquire(
767                         TIMEOUT, TimeUnit.MILLISECONDS)) {
768                     loge("Timeout to receive onSatelliteListeningEnabled");
769                     return false;
770                 }
771             } catch (Exception ex) {
772                 loge("onSatelliteListeningEnabled: Got exception=" + ex);
773                 return false;
774             }
775         }
776         return true;
777     }
778 
waitForRemoteSatelliteServiceConnected(int expectedNumberOfEvents)779     boolean waitForRemoteSatelliteServiceConnected(int expectedNumberOfEvents) {
780         for (int i = 0; i < expectedNumberOfEvents; i++) {
781             try {
782                 if (!mRemoteServiceConnectedSemaphore.tryAcquire(
783                         TIMEOUT, TimeUnit.MILLISECONDS)) {
784                     loge("Timeout to receive RemoteSatelliteServiceConnected");
785                     return false;
786                 }
787             } catch (Exception ex) {
788                 loge("RemoteSatelliteServiceConnected: Got exception=" + ex);
789                 return false;
790             }
791         }
792         return true;
793     }
794 
waitForRemoteSatelliteGatewayServiceConnected(int expectedNumberOfEvents)795     boolean waitForRemoteSatelliteGatewayServiceConnected(int expectedNumberOfEvents) {
796         for (int i = 0; i < expectedNumberOfEvents; i++) {
797             try {
798                 if (!mRemoteGatewayServiceConnectedSemaphore.tryAcquire(
799                         TIMEOUT, TimeUnit.MILLISECONDS)) {
800                     loge("Timeout to receive RemoteSatelliteGatewayServiceConnected");
801                     return false;
802                 }
803             } catch (Exception ex) {
804                 loge("RemoteSatelliteGatewayServiceConnected: Got exception=" + ex);
805                 return false;
806             }
807         }
808         return true;
809     }
810 
waitForRemoteSatelliteGatewayServiceDisconnected(int expectedNumberOfEvents)811     boolean waitForRemoteSatelliteGatewayServiceDisconnected(int expectedNumberOfEvents) {
812         for (int i = 0; i < expectedNumberOfEvents; i++) {
813             try {
814                 if (!mRemoteGatewayServiceDisconnectedSemaphore.tryAcquire(
815                         TIMEOUT, TimeUnit.MILLISECONDS)) {
816                     loge("Timeout to receive RemoteGatewayServiceDisconnected");
817                     return false;
818                 }
819             } catch (Exception ex) {
820                 loge("RemoteGatewayServiceDisconnected: Got exception=" + ex);
821                 return false;
822             }
823         }
824         return true;
825     }
826 
waitForExternalSatelliteServiceDisconnected(int expectedNumberOfEvents)827     boolean waitForExternalSatelliteServiceDisconnected(int expectedNumberOfEvents) {
828         for (int i = 0; i < expectedNumberOfEvents; i++) {
829             try {
830                 if (!mExternalServiceDisconnectedSemaphore.tryAcquire(
831                         TIMEOUT, TimeUnit.MILLISECONDS)) {
832                     loge("Timeout to receive ExternalServiceDisconnected");
833                     return false;
834                 }
835             } catch (Exception ex) {
836                 loge("ExternalServiceDisconnected: Got exception=" + ex);
837                 return false;
838             }
839         }
840         return true;
841     }
842 
waitForExternalSatelliteGatewayServiceDisconnected(int expectedNumberOfEvents)843     boolean waitForExternalSatelliteGatewayServiceDisconnected(int expectedNumberOfEvents) {
844         for (int i = 0; i < expectedNumberOfEvents; i++) {
845             try {
846                 if (!mExternalGatewayServiceDisconnectedSemaphore.tryAcquire(
847                         TIMEOUT, TimeUnit.MILLISECONDS)) {
848                     loge("Timeout to receive ExternalGatewayServiceDisconnected");
849                     return false;
850                 }
851             } catch (Exception ex) {
852                 loge("ExternalGatewayServiceDisconnected: Got exception=" + ex);
853                 return false;
854             }
855         }
856         return true;
857     }
858 
waitForEventMockPointingUiActivityStarted(int expectedNumberOfEvents)859     boolean waitForEventMockPointingUiActivityStarted(int expectedNumberOfEvents) {
860         for (int i = 0; i < expectedNumberOfEvents; i++) {
861             try {
862                 if (!mMockPointingUiActivitySemaphore.tryAcquire(
863                         TIMEOUT, TimeUnit.MILLISECONDS)) {
864                     loge("Timeout to receive MockPointingUiActivityStarted");
865                     return false;
866                 }
867             } catch (Exception ex) {
868                 loge("MockPointingUiActivityStarted: Got exception=" + ex);
869                 return false;
870             }
871         }
872         return true;
873     }
874 
waitForEventMockPointingUiActivityStopped(int expectedNumberOfEvents)875     boolean waitForEventMockPointingUiActivityStopped(int expectedNumberOfEvents) {
876         for (int i = 0; i < expectedNumberOfEvents; i++) {
877             try {
878                 if (!mStopPointingUiSemaphore.tryAcquire(
879                         TIMEOUT, TimeUnit.MILLISECONDS)) {
880                     loge("Timeout to receive StopPointingUiSemaphore");
881                     return false;
882                 }
883             } catch (Exception ex) {
884                 loge("StopPointingUiSemaphore: Got exception=" + ex);
885                 return false;
886             }
887         }
888         return true;
889     }
890 
waitForEventOnSetSatellitePlmn(int expectedNumberOfEvents)891     boolean waitForEventOnSetSatellitePlmn(int expectedNumberOfEvents) {
892         for (int i = 0; i < expectedNumberOfEvents; i++) {
893             try {
894                 if (!mSetSatellitePlmnSemaphore.tryAcquire(
895                         TIMEOUT, TimeUnit.MILLISECONDS)) {
896                     loge("Timeout to receive onSetSatellitePlmn");
897                     return false;
898                 }
899             } catch (Exception ex) {
900                 loge("onSetSatellitePlmn: Got exception=" + ex);
901                 return false;
902             }
903         }
904         return true;
905     }
906 
setErrorCode(int errorCode)907     void setErrorCode(int errorCode) {
908         logd("setErrorCode: errorCode=" + errorCode);
909         if (mSatelliteService == null) {
910             loge("setErrorCode: mSatelliteService is null");
911             return;
912         }
913         mSatelliteService.setErrorCode(errorCode);
914     }
915 
setEnableCellularScanningErrorCode(int errorCode)916     void setEnableCellularScanningErrorCode(int errorCode) {
917         logd("setEnableCellularScanningErrorCode: errorCode=" + errorCode);
918         if (mSatelliteService == null) {
919             loge("setEnableCellularScanningErrorCode: mSatelliteService is null");
920             return;
921         }
922         mSatelliteService.setEnableCellularScanningErrorCode(errorCode);
923     }
924 
setSupportedRadioTechnologies(@onNull int[] supportedRadioTechnologies)925     void setSupportedRadioTechnologies(@NonNull int[] supportedRadioTechnologies) {
926         logd("setSupportedRadioTechnologies: " + supportedRadioTechnologies[0]);
927         if (mSatelliteService == null) {
928             loge("setSupportedRadioTechnologies: mSatelliteService is null");
929             return;
930         }
931         mSatelliteService.setSupportedRadioTechnologies(supportedRadioTechnologies);
932     }
933 
setSatelliteSupport(boolean supported)934     void setSatelliteSupport(boolean supported) {
935         logd("setSatelliteSupport: supported=" + supported);
936         if (mSatelliteService == null) {
937             loge("setErrorCode: mSatelliteService is null");
938             return;
939         }
940         mSatelliteService.setSatelliteSupport(supported);
941     }
942 
setShouldRespondTelephony(boolean shouldRespondTelephony)943     public void setShouldRespondTelephony(boolean shouldRespondTelephony) {
944         logd("setShouldRespondTelephony: shouldRespondTelephony=" + shouldRespondTelephony);
945         if (mSatelliteService == null) {
946             loge("setShouldRespondTelephony: mSatelliteService is null");
947             return;
948         }
949         mSatelliteService.setShouldRespondTelephony(shouldRespondTelephony);
950     }
951 
setNtnSignalStrength( android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength)952     void setNtnSignalStrength(
953             android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength) {
954         if (mSatelliteService == null) {
955             loge("setNtnSignalStrength: mSatelliteService is null");
956             return;
957         }
958         mSatelliteService.setNtnSignalStrength(ntnSignalStrength);
959     }
960 
sendOnSatelliteDatagramReceived(SatelliteDatagram datagram, int pendingCount)961     void sendOnSatelliteDatagramReceived(SatelliteDatagram datagram, int pendingCount) {
962         logd("sendOnSatelliteDatagramReceived");
963         if (mSatelliteService == null) {
964             loge("setErrorCode: mSatelliteService is null");
965             return;
966         }
967         mSatelliteService.sendOnSatelliteDatagramReceived(datagram, pendingCount);
968     }
969 
sendOnPendingDatagrams()970     void sendOnPendingDatagrams() {
971         logd("sendOnPendingDatagrams");
972         if (mSatelliteService == null) {
973             loge("setErrorCode: mSatelliteService is null");
974             return;
975         }
976         mSatelliteService.sendOnPendingDatagrams();
977     }
978 
sendOnSatellitePositionChanged(PointingInfo pointingInfo)979     void sendOnSatellitePositionChanged(PointingInfo pointingInfo) {
980         logd("sendOnSatellitePositionChanged");
981         mSatelliteService.sendOnSatellitePositionChanged(pointingInfo);
982     }
983 
sendOnSatelliteModemStateChanged(int modemState)984     void sendOnSatelliteModemStateChanged(int modemState) {
985         logd("sendOnSatelliteModemStateChanged: " + modemState);
986         if (mSatelliteService == null) {
987             loge("sendOnSatelliteModemStateChanged: mSatelliteService is null");
988             return;
989         }
990         mSatelliteService.sendOnSatelliteModemStateChanged(modemState);
991     }
992 
sendOnNtnSignalStrengthChanged( android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength)993     void sendOnNtnSignalStrengthChanged(
994             android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength) {
995         logd("sendOnNtnSignalStrengthChanged: " + ntnSignalStrength.signalStrengthLevel);
996         if (mSatelliteService == null) {
997             loge("sendOnNtnSignalStrengthChanged: mSatelliteService is null");
998             return;
999         }
1000         mSatelliteService.sendOnNtnSignalStrengthChanged(ntnSignalStrength);
1001     }
1002 
sendOnSatelliteCapabilitiesChanged( android.telephony.satellite.stub.SatelliteCapabilities satelliteCapabilities)1003     void sendOnSatelliteCapabilitiesChanged(
1004             android.telephony.satellite.stub.SatelliteCapabilities satelliteCapabilities) {
1005         logd("sendOnSatelliteCapabilitiesChanged: " + satelliteCapabilities);
1006         if (mSatelliteService == null) {
1007             loge("sendOnSatelliteCapabilitiesChanged: mSatelliteService is null");
1008             return;
1009         }
1010         mSatelliteService.sendOnSatelliteCapabilitiesChanged(satelliteCapabilities);
1011     }
1012 
sendOnSatelliteSupportedStateChanged(boolean supported)1013     void sendOnSatelliteSupportedStateChanged(boolean supported) {
1014         logd("sendOnSatelliteSupportedStateChanged: " + supported);
1015         if (mSatelliteService == null) {
1016             loge("sendOnSatelliteSupportedStateChanged: mSatelliteService is null");
1017             return;
1018         }
1019         mSatelliteService.sendOnSatelliteSupportedStateChanged(supported);
1020     }
1021 
setSatelliteListeningTimeoutDuration(long timeoutMillis)1022     boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
1023         try {
1024             String result =
1025                     TelephonyUtils.executeShellCommand(mInstrumentation,
1026                             SET_SATELLITE_LISTENING_TIMEOUT_DURATION_CMD + timeoutMillis);
1027             logd("setSatelliteListeningTimeoutDuration: result = " + result);
1028             return "true".equals(result);
1029         } catch (Exception e) {
1030             loge("setSatelliteListeningTimeoutDuration: e=" + e);
1031             return false;
1032         }
1033     }
1034 
setDatagramControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)1035     boolean setDatagramControllerTimeoutDuration(
1036             boolean reset, int timeoutType, long timeoutMillis) {
1037         StringBuilder command = new StringBuilder();
1038         command.append(SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION_CMD);
1039         if (reset) {
1040             command.append("-r");
1041         }
1042         command.append(" -t " + timeoutType);
1043         command.append(" -d " + timeoutMillis);
1044 
1045         try {
1046             String result =
1047                     TelephonyUtils.executeShellCommand(mInstrumentation, command.toString());
1048             logd("setDatagramControllerTimeoutDuration: result = " + result);
1049             return "true".equals(result);
1050         } catch (Exception e) {
1051             loge("setDatagramControllerTimeoutDuration: e=" + e);
1052             return false;
1053         }
1054     }
1055 
setDatagramControllerBooleanConfig( boolean reset, int booleanType, boolean enable)1056     boolean setDatagramControllerBooleanConfig(
1057             boolean reset, int booleanType, boolean enable) {
1058         StringBuilder command = new StringBuilder();
1059         command.append(SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG_CMD);
1060         if (reset) {
1061             command.append("-r");
1062         }
1063         command.append(" -t " + booleanType);
1064         command.append(" -d " + enable);
1065 
1066         try {
1067             String result =
1068                     TelephonyUtils.executeShellCommand(mInstrumentation, command.toString());
1069             logd("setDatagramControllerBooleanConfig: result = " + result);
1070             return "true".equals(result);
1071         } catch (Exception e) {
1072             loge("setDatagramControllerBooleanConfig: e=" + e);
1073             return false;
1074         }
1075     }
1076 
setSatelliteControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)1077     boolean setSatelliteControllerTimeoutDuration(
1078             boolean reset, int timeoutType, long timeoutMillis) {
1079         StringBuilder command = new StringBuilder();
1080         command.append(SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION_CMD);
1081         if (reset) {
1082             command.append("-r");
1083         }
1084         command.append(" -t " + timeoutType);
1085         command.append(" -d " + timeoutMillis);
1086 
1087         try {
1088             String result =
1089                     TelephonyUtils.executeShellCommand(mInstrumentation, command.toString());
1090             logd("setSatelliteControllerTimeoutDuration: result = " + result);
1091             return "true".equals(result);
1092         } catch (Exception e) {
1093             loge("setSatelliteControllerTimeoutDuration: e=" + e);
1094             return false;
1095         }
1096     }
1097 
setShouldSendDatagramToModemInDemoMode(boolean shouldSendToDemoMode)1098     boolean setShouldSendDatagramToModemInDemoMode(boolean shouldSendToDemoMode) {
1099         try {
1100             String result = TelephonyUtils.executeShellCommand(mInstrumentation,
1101                     SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE
1102                             + (shouldSendToDemoMode ? "true" : "false"));
1103             logd("setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + "): result = "
1104                     + result);
1105             return true;
1106         } catch (Exception e) {
1107             loge("setShouldSendDatagramToModemInDemoMode: e=" + e);
1108             return false;
1109         }
1110     }
1111 
setWaitToSend(boolean wait)1112     void setWaitToSend(boolean wait) {
1113         logd("setWaitToSend: wait= " + wait);
1114         if (mSatelliteService == null) {
1115             loge("setWaitToSend: mSatelliteService is null");
1116             return;
1117         }
1118         mSatelliteService.setWaitToSend(wait);
1119     }
1120 
sendSavedDatagram()1121     boolean sendSavedDatagram() {
1122         logd("sendSavedDatagram");
1123         if (mSatelliteService == null) {
1124             loge("sendSavedDatagram: mSatelliteService is null");
1125             return false;
1126         }
1127         return mSatelliteService.sendSavedDatagram();
1128     }
1129 
respondToRequestSatelliteEnabled(boolean isEnabled)1130     boolean respondToRequestSatelliteEnabled(boolean isEnabled) {
1131         logd("respondToRequestSatelliteEnabled, isEnabled=" + isEnabled);
1132         if (mSatelliteService == null) {
1133             loge("respondToRequestSatelliteEnabled: mSatelliteService is null");
1134             return false;
1135         }
1136         return mSatelliteService.respondToRequestSatelliteEnabled(isEnabled);
1137     }
1138 
stopExternalSatelliteService()1139     boolean stopExternalSatelliteService() {
1140         logd("stopExternalSatelliteService");
1141         try {
1142             TelephonyUtils.executeShellCommand(mInstrumentation,
1143                     "am force-stop " + EXTERNAL_SATELLITE_PACKAGE);
1144             return true;
1145         } catch (Exception ex) {
1146             loge("stopExternalSatelliteService: ex=" + ex);
1147             return false;
1148         }
1149     }
1150 
stopExternalSatelliteGatewayService()1151     boolean stopExternalSatelliteGatewayService() {
1152         logd("stopExternalSatelliteGatewayService");
1153         try {
1154             TelephonyUtils.executeShellCommand(mInstrumentation,
1155                     "am force-stop " + EXTERNAL_SATELLITE_GATEWAY_PACKAGE);
1156             return true;
1157         } catch (Exception ex) {
1158             loge("stopExternalSatelliteGatewayService: ex=" + ex);
1159             return false;
1160         }
1161     }
1162 
resetSatelliteService()1163     void resetSatelliteService() {
1164         mSatelliteService = null;
1165     }
1166 
stopExternalMockPointingUi()1167     boolean stopExternalMockPointingUi() {
1168         logd("stopExternalMockPointingUi");
1169         try {
1170             TelephonyUtils.executeShellCommand(mInstrumentation,
1171                     "am force-stop " + EXTERNAL_POINTING_UI_PACKAGE);
1172             return true;
1173         } catch (Exception ex) {
1174             loge("stopExternalMockPointingUi: ex=" + ex);
1175             return false;
1176         }
1177     }
1178 
getCarrierPlmnList()1179     @Nullable List<String> getCarrierPlmnList() {
1180         if (mSatelliteService == null) {
1181             loge("getCarrierPlmnList: mSatelliteService is null");
1182             return null;
1183         }
1184         return mSatelliteService.getCarrierPlmnList();
1185     }
1186 
getAllSatellitePlmnList()1187     @Nullable List<String> getAllSatellitePlmnList() {
1188         if (mSatelliteService == null) {
1189             loge("getAllSatellitePlmnList: mSatelliteService is null");
1190             return null;
1191         }
1192         return mSatelliteService.getAllSatellitePlmnList();
1193     }
1194 
getIsSatelliteEnabledForCarrier()1195     @Nullable Boolean getIsSatelliteEnabledForCarrier() {
1196         if (mSatelliteService == null) {
1197             loge("getIsSatelliteEnabledForCarrier: mSatelliteService is null");
1198             return null;
1199         }
1200         return mSatelliteService.getIsSatelliteEnabledForCarrier();
1201     }
1202 
clearSatelliteEnabledForCarrier()1203     void clearSatelliteEnabledForCarrier() {
1204         if (mSatelliteService == null) {
1205             loge("clearSatelliteEnabledForCarrier: mSatelliteService is null");
1206             return;
1207         }
1208         mSatelliteService.clearSatelliteEnabledForCarrier();
1209     }
1210 
1211     /**
1212      * Set whether provisioning API should be supported
1213      */
setProvisioningApiSupported(boolean provisioningApiSupported)1214     void setProvisioningApiSupported(boolean provisioningApiSupported) {
1215         if (mSatelliteService == null) {
1216             loge("setProvisioningApiSupported: mSatelliteService is null");
1217             return;
1218         }
1219         mSatelliteService.setProvisioningApiSupported(provisioningApiSupported);
1220     }
1221 
getPlmnListFromOverlayConfig()1222     @NonNull List<String> getPlmnListFromOverlayConfig() {
1223         String[] plmnArr = readStringArrayFromOverlayConfig(
1224                 R.array.config_satellite_providers);
1225         return Arrays.stream(plmnArr).toList();
1226     }
1227 
getIsEmergency()1228     @Nullable Boolean getIsEmergency() {
1229         if (mSatelliteService == null) {
1230             loge("getIsEmergency: mSatelliteService is null");
1231             return null;
1232         }
1233         return mSatelliteService.getIsEmergency();
1234     }
1235 
1236     /** Set telephony country codes */
setCountryCodes(boolean reset, @Nullable String currentNetworkCountryCodes, @Nullable String cachedNetworkCountryCodes, @Nullable String locationCountryCode, long locationCountryCodeTimestampNanos)1237     boolean setCountryCodes(boolean reset, @Nullable String currentNetworkCountryCodes,
1238             @Nullable String cachedNetworkCountryCodes, @Nullable String locationCountryCode,
1239             long locationCountryCodeTimestampNanos) {
1240         logd("setCountryCodes: reset= " + reset + ", currentNetworkCountryCodes="
1241                 + currentNetworkCountryCodes + ", cachedNetworkCountryCodes="
1242                 + cachedNetworkCountryCodes + ", locationCountryCode=" + locationCountryCode
1243                 + ", locationCountryCodeTimestampNanos=" + locationCountryCodeTimestampNanos);
1244         try {
1245             StringBuilder command = new StringBuilder();
1246             command.append(SET_COUNTRY_CODES);
1247             if (reset) {
1248                 command.append(" -r");
1249             }
1250             if (!TextUtils.isEmpty(currentNetworkCountryCodes)) {
1251                 command.append(" -n ");
1252                 command.append(currentNetworkCountryCodes);
1253             }
1254             if (!TextUtils.isEmpty(cachedNetworkCountryCodes)) {
1255                 command.append(" -c ");
1256                 command.append(cachedNetworkCountryCodes);
1257             }
1258             if (!TextUtils.isEmpty(locationCountryCode)) {
1259                 command.append(" -l ");
1260                 command.append(locationCountryCode);
1261                 command.append(" -t ");
1262                 command.append(locationCountryCodeTimestampNanos);
1263             }
1264             TelephonyUtils.executeShellCommand(mInstrumentation, command.toString());
1265             return true;
1266         } catch (Exception ex) {
1267             loge("setCountryCodes: ex= " + ex);
1268             return false;
1269         }
1270     }
1271 
1272     /** Set overlay configs for satellite access controller */
setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed, @Nullable String s2CellFile, long locationFreshDurationNanos, @Nullable String satelliteCountryCodes)1273     boolean setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed,
1274             @Nullable String s2CellFile, long locationFreshDurationNanos,
1275             @Nullable String satelliteCountryCodes) {
1276         logd("setSatelliteAccessControlOverlayConfigs");
1277         try {
1278             StringBuilder command = new StringBuilder();
1279             command.append(SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS);
1280             if (reset) {
1281                 command.append(" -r");
1282             } else {
1283                 if (isAllowed) {
1284                     command.append(" -a");
1285                 }
1286                 if (!TextUtils.isEmpty(s2CellFile)) {
1287                     command.append(" -f ");
1288                     command.append(s2CellFile);
1289                 }
1290                 command.append(" -d ");
1291                 command.append(locationFreshDurationNanos);
1292                 if (!TextUtils.isEmpty(satelliteCountryCodes)) {
1293                     command.append(" -c ");
1294                     command.append(satelliteCountryCodes);
1295                 }
1296             }
1297             logd("command=" + command);
1298             TelephonyUtils.executeShellCommand(mInstrumentation, command.toString());
1299             return true;
1300         } catch (Exception ex) {
1301             loge("setSatelliteAccessControlOverlayConfigs: ex= " + ex);
1302             return false;
1303         }
1304     }
1305 
readStringArrayFromOverlayConfig(@rrayRes int id)1306     @NonNull private String[] readStringArrayFromOverlayConfig(@ArrayRes int id) {
1307         String[] strArray = null;
1308         try {
1309             strArray = mInstrumentation.getContext().getResources().getStringArray(id);
1310         } catch (Resources.NotFoundException ex) {
1311             loge("readStringArrayFromOverlayConfig: id= " + id + ", ex=" + ex);
1312         }
1313         if (strArray == null) {
1314             strArray = new String[0];
1315         }
1316         return strArray;
1317     }
1318 
setupLocalSatelliteService()1319     private boolean setupLocalSatelliteService() {
1320         if (mSatelliteService != null) {
1321             logd("setupLocalSatelliteService: local service is already set up");
1322             return true;
1323         }
1324         CountDownLatch latch = new CountDownLatch(1);
1325         mSatelliteServiceConn = new TestSatelliteServiceConnection(latch);
1326         mInstrumentation.getContext().bindService(new Intent(mInstrumentation.getContext(),
1327                 MockSatelliteService.class), mSatelliteServiceConn, Context.BIND_AUTO_CREATE);
1328         try {
1329             return latch.await(TIMEOUT, TimeUnit.MILLISECONDS);
1330         } catch (InterruptedException e) {
1331             loge("setupLocalSatelliteService: Got InterruptedException e=" + e);
1332             return false;
1333         }
1334     }
1335 
setupLocalSatelliteGatewayService()1336     private boolean setupLocalSatelliteGatewayService() {
1337         if (mSatelliteGatewayService != null) {
1338             logd("setupLocalSatelliteGatewayService: local service is already set up");
1339             return true;
1340         }
1341         CountDownLatch latch = new CountDownLatch(1);
1342         mSatelliteGatewayServiceConn = new TestSatelliteGatewayServiceConnection(latch);
1343         mInstrumentation.getContext().bindService(new Intent(mInstrumentation.getContext(),
1344                 MockSatelliteGatewayService.class), mSatelliteGatewayServiceConn,
1345                 Context.BIND_AUTO_CREATE);
1346         try {
1347             return latch.await(TIMEOUT, TimeUnit.MILLISECONDS);
1348         } catch (InterruptedException e) {
1349             loge("setupLocalSatelliteGatewayService: Got InterruptedException e=" + e);
1350             return false;
1351         }
1352     }
1353 
setSatelliteServicePackageName(@ullable String packageName)1354     private boolean setSatelliteServicePackageName(@Nullable String packageName) {
1355         try {
1356             TelephonyUtils.executeShellCommand(
1357                     mInstrumentation, SET_SATELLITE_SERVICE_PACKAGE_NAME_CMD + packageName);
1358             return true;
1359         } catch (Exception ex) {
1360             loge("setSatelliteServicePackageName: ex= " + ex);
1361             return false;
1362         }
1363     }
1364 
setSatelliteGatewayServicePackageName( @ullable String packageName)1365     private boolean setSatelliteGatewayServicePackageName(
1366             @Nullable String packageName) throws Exception {
1367         try {
1368             TelephonyUtils.executeShellCommand(mInstrumentation,
1369                     SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME_CMD + packageName);
1370             return true;
1371         } catch (Exception ex) {
1372             loge("setSatelliteGatewayServicePackageName: ex=" + ex);
1373             return false;
1374         }
1375     }
1376 
setSatellitePointingUiClassName( @ullable String packageName, @Nullable String className)1377     private boolean setSatellitePointingUiClassName(
1378             @Nullable String packageName, @Nullable String className)  {
1379         try {
1380             TelephonyUtils.executeShellCommand(mInstrumentation,
1381                     SET_SATELLITE_POINTING_UI_CLASS_NAME_CMD + " -p " + packageName
1382                             + " -c " + className);
1383             return true;
1384         } catch (Exception ex) {
1385             loge("setSatellitePointingUiClassName: ex = " + ex);
1386             return false;
1387         }
1388     }
1389 
setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state)1390     boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state) {
1391         String option;
1392         if ("cache_allowed".equalsIgnoreCase(state)) {
1393             option = "-a";
1394         } else if ("cache_clear_and_not_allowed".equalsIgnoreCase(state)) {
1395             option = "-n";
1396         } else if ("clear_cache_only".equalsIgnoreCase(state)) {
1397             option = "-c";
1398         } else {
1399             return false;
1400         }
1401 
1402         try {
1403             String result = TelephonyUtils.executeShellCommand(mInstrumentation,
1404                     SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE
1405                             + option);
1406             logd("setIsSatelliteCommunicationAllowedForCurrentLocationCache(" + option
1407                     + "): result = " + result);
1408             return true;
1409         } catch (Exception e) {
1410             loge("setIsSatelliteCommunicationAllowedForCurrentLocationCache: e=" + e);
1411             return false;
1412         }
1413     }
1414 
registerForMockPointingUiActivityStatus()1415     private void registerForMockPointingUiActivityStatus() {
1416         IntentFilter intentFilter = new IntentFilter(
1417                 MockPointingUiActivity.ACTION_MOCK_POINTING_UI_ACTIVITY_STARTED);
1418         mInstrumentation.getContext().registerReceiver(
1419                 mMockPointingUiActivityStatusReceiver, intentFilter, Context.RECEIVER_EXPORTED);
1420     }
1421 
registerForExternalMockPointingUiActivityStatus()1422     private void registerForExternalMockPointingUiActivityStatus() {
1423         logd("registerForExternalMockPointingUiActivityStatus");
1424         IntentFilter intentFilter = new IntentFilter(
1425                 ExternalMockPointingUi.ACTION_MOCK_POINTING_UI_ACTIVITY_STARTED);
1426         mInstrumentation.getContext().registerReceiver(
1427                 mMockPointingUiActivityStatusReceiver, intentFilter, Context.RECEIVER_EXPORTED);
1428     }
1429 
unregisterForMockPointingUiActivityStatus()1430     private void unregisterForMockPointingUiActivityStatus() {
1431         mInstrumentation.getContext().unregisterReceiver(mMockPointingUiActivityStatusReceiver);
1432     }
1433 
logd(@onNull String log)1434     private static void logd(@NonNull String log) {
1435         Rlog.d(TAG, log);
1436     }
1437 
loge(@onNull String log)1438     private static void loge(@NonNull String log) {
1439         Rlog.e(TAG, log);
1440     }
1441 
1442     private static class MockPointingUiActivityStatusReceiver extends BroadcastReceiver {
1443         private Semaphore mSemaphore;
1444 
MockPointingUiActivityStatusReceiver(Semaphore semaphore)1445         MockPointingUiActivityStatusReceiver(Semaphore semaphore) {
1446             mSemaphore = semaphore;
1447         }
1448 
1449         @Override
onReceive(Context context, Intent intent)1450         public void onReceive(Context context, Intent intent) {
1451             logd("MockPointingUiActivityStatusReceiver: onReceive " + intent.getAction());
1452             if ((MockPointingUiActivity.ACTION_MOCK_POINTING_UI_ACTIVITY_STARTED.equals(
1453                     intent.getAction()))
1454                     || (ExternalMockPointingUi.ACTION_MOCK_POINTING_UI_ACTIVITY_STARTED.equals(
1455                     intent.getAction()))) {
1456                 logd("MockPointingUiActivityStatusReceiver: onReceive");
1457                 try {
1458                     mSemaphore.release();
1459                 } catch (Exception ex) {
1460                     loge("MockPointingUiActivityStatusReceiver: Got exception, ex=" + ex);
1461                 }
1462             }
1463         }
1464     }
1465 
getSatelliteServicePackageName()1466     private String getSatelliteServicePackageName() {
1467         return TextUtils.emptyIfNull(mInstrumentation.getContext().getResources().getString(
1468                 R.string.config_satellite_service_package));
1469     }
1470 }
1471