• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.mockmodem;
18 
19 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT;
20 
21 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER;
22 
23 import android.annotation.Nullable;
24 import android.content.Context;
25 import android.hardware.radio.RadioError;
26 import android.hardware.radio.sim.Carrier;
27 import android.hardware.radio.sim.CarrierRestrictions;
28 import android.hardware.radio.voice.CdmaSignalInfoRecord;
29 import android.hardware.radio.voice.UusInfo;
30 import android.os.Build;
31 import android.os.Looper;
32 import android.os.SystemProperties;
33 import android.telephony.Annotation;
34 import android.telephony.BarringInfo;
35 import android.telephony.CellularIdentifierDisclosure;
36 import android.telephony.SecurityAlgorithmUpdate;
37 import android.telephony.SubscriptionManager;
38 import android.telephony.TelephonyManager;
39 import android.telephony.cts.util.TelephonyUtils;
40 import android.telephony.ims.feature.ConnectionFailureInfo;
41 import android.telephony.ims.feature.MmTelFeature;
42 import android.telephony.ims.stub.ImsRegistrationImplBase;
43 import android.util.Log;
44 import android.util.SparseArray;
45 
46 import androidx.test.InstrumentationRegistry;
47 
48 import com.android.compatibility.common.util.TestThread;
49 
50 import java.util.Arrays;
51 import java.util.List;
52 import java.util.Set;
53 import java.util.concurrent.TimeUnit;
54 import java.util.function.BooleanSupplier;
55 
56 public class MockModemManager {
57     private static final String TAG = "MockModemManager";
58     private static final boolean DEBUG = !"user".equals(Build.TYPE);
59 
60     private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
61     private static final String BOOT_ALLOW_MOCK_MODEM_PROPERTY = "ro.boot.radio.allow_mock_modem";
62 
63     private static Context sContext;
64     private static MockModemServiceConnector sServiceConnector;
65     private static final long TIMEOUT_IN_MSEC_FOR_SIM_STATUS_CHANGED = 10000;
66     private static final int WAIT_UPDATE_TIMEOUT_MS = 1000;  // 1sec delay
67     private MockModemService mMockModemService;
68 
enforceMockModemDeveloperSetting()69     public static void enforceMockModemDeveloperSetting() throws Exception {
70         boolean isAllowed = SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false);
71         boolean isAllowedForBoot =
72                 SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false);
73         // Check for developer settings for user build. Always allow for debug builds
74         if (!(isAllowed || isAllowedForBoot) && !DEBUG) {
75             throw new IllegalStateException(
76                 "!! Enable Mock Modem before running this test !! "
77                     + "Developer options => Allow Mock Modem");
78         }
79     }
80 
MockModemManager()81     public MockModemManager() {
82         sContext = InstrumentationRegistry.getInstrumentation().getContext();
83     }
84 
waitForTelephonyFrameworkDone(int delayInSec)85     private void waitForTelephonyFrameworkDone(int delayInSec) throws Exception {
86         TimeUnit.SECONDS.sleep(delayInSec);
87     }
88 
waitForSubscriptionCondition(BooleanSupplier condition, long maxWaitMillis)89     private void waitForSubscriptionCondition(BooleanSupplier condition, long maxWaitMillis)
90             throws Exception {
91         final Object lock = new Object();
92         SubscriptionManager sm =
93                 (SubscriptionManager)
94                         sContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
95 
96         TestThread t =
97                 new TestThread(
98                         () -> {
99                             Looper.prepare();
100 
101                             SubscriptionManager.OnSubscriptionsChangedListener listener =
102                                     new SubscriptionManager.OnSubscriptionsChangedListener() {
103                                         @Override
104                                         public void onSubscriptionsChanged() {
105                                             synchronized (lock) {
106                                                 if (condition.getAsBoolean()) {
107                                                     lock.notifyAll();
108                                                     Looper.myLooper().quitSafely();
109                                                 }
110                                             }
111                                         }
112                                     };
113 
114                             sm.addOnSubscriptionsChangedListener(listener);
115                             try {
116                                 synchronized (lock) {
117                                     if (condition.getAsBoolean()) lock.notifyAll();
118                                 }
119                                 Log.d(TAG, "before loop()....");
120                                 if (!condition.getAsBoolean()) Looper.loop();
121                                 Log.d(TAG, "after loop()....");
122                             } finally {
123                                 sm.removeOnSubscriptionsChangedListener(listener);
124                             }
125                         });
126 
127         synchronized (lock) {
128             if (condition.getAsBoolean()) return;
129             t.start();
130             lock.wait(maxWaitMillis);
131         }
132     }
133 
134     /* Public APIs */
135 
136     /**
137      * Bring up Mock Modem Service and connect to it.
138      *
139      * @return boolean true if the operation is successful, otherwise false.
140      */
connectMockModemService()141     public boolean connectMockModemService() throws Exception {
142         return connectMockModemService(MOCK_SIM_PROFILE_ID_DEFAULT);
143     }
144 
145     /**
146      * Bring up Mock Modem Service and connect to it.
147      *
148      * @pararm simprofile for initial Sim profile
149      * @return boolean true if the operation is successful, otherwise false.
150      */
connectMockModemService(int simprofile)151     public boolean connectMockModemService(int simprofile) throws Exception {
152         int[] simprofiles = new int[1];
153         simprofiles[0] = Integer.valueOf(simprofile);
154 
155         return connectMockModemService(simprofiles);
156     }
157 
158     /**
159      * Bring up Mock Modem Service and connect to it.
160      *
161      * @param simprofiles for initial Sim profile of multiple Sim slots
162      * @return boolean true if the operation is successful, otherwise false.
163      */
connectMockModemService(int[] simprofiles)164     public boolean connectMockModemService(int[] simprofiles) throws Exception {
165         boolean result = true;
166 
167         if (simprofiles == null) {
168             Log.e(TAG, "The parameter is invalid.");
169             result = false;
170         }
171 
172         if (result && sServiceConnector == null) {
173             sServiceConnector =
174                     new MockModemServiceConnector(InstrumentationRegistry.getInstrumentation());
175         }
176 
177         if (result && sServiceConnector != null) {
178             result = sServiceConnector.connectMockModemService(simprofiles);
179 
180             if (result) {
181                 mMockModemService = sServiceConnector.getMockModemService();
182 
183                 if (mMockModemService != null) {
184                     /*
185                      It needs to have a delay to wait for Telephony Framework to bind with
186                      MockModemService and set radio power as a desired state for initial condition
187                      even get SIM card state. Currently, 1 sec is enough for now.
188                     */
189                     waitForTelephonyFrameworkDone(1);
190                 } else {
191                     Log.e(TAG, "MockModemService get failed!");
192                     result = false;
193                 }
194             }
195         } else {
196             Log.e(TAG, "Create MockModemServiceConnector failed!");
197         }
198 
199         return result;
200     }
201 
202     /**
203      * Disconnect from Mock Modem Service.
204      *
205      * @return boolean true if the operation is successful, otherwise false.
206      */
disconnectMockModemService()207     public boolean disconnectMockModemService() throws Exception {
208         boolean result = false;
209 
210         if (sServiceConnector != null) {
211             result = sServiceConnector.disconnectMockModemService();
212 
213             if (result) {
214                 mMockModemService = null;
215             } else {
216                 Log.e(TAG, "MockModemService disconnected failed!");
217             }
218         } else {
219             Log.e(TAG, "No MockModemServiceConnector exist!");
220         }
221 
222         return result;
223     }
224 
225     /**
226      * Query whether an active SIM card is present on this slot or not.
227      *
228      * @param slotId which slot would be checked.
229      * @return boolean true if any sim card inserted, otherwise false.
230      */
isSimCardPresent(int slotId)231     public boolean isSimCardPresent(int slotId) throws Exception {
232         Log.d(TAG, "isSimCardPresent[" + slotId + "]");
233 
234         MockModemConfigInterface configInterface = mMockModemService.getMockModemConfigInterface();
235         return (configInterface != null) ? configInterface.isSimCardPresent(slotId, TAG) : false;
236     }
237 
238     /**
239      * Insert a SIM card.
240      *
241      * @param slotId which slot would insert.
242      * @param simProfileId which carrier sim card is inserted.
243      * @return boolean true if the operation is successful, otherwise false.
244      */
insertSimCard(int slotId, int simProfileId)245     public boolean insertSimCard(int slotId, int simProfileId) throws Exception {
246         Log.d(TAG, "insertSimCard[" + slotId + "] with profile Id(" + simProfileId + ")");
247         boolean result = true;
248 
249         if (!isSimCardPresent(slotId)) {
250             MockModemConfigInterface configInterface =
251                     mMockModemService.getMockModemConfigInterface();
252             if (configInterface != null) {
253                 TelephonyManager tm = sContext.getSystemService(TelephonyManager.class);
254 
255                 result = configInterface.changeSimProfile(slotId, simProfileId, TAG);
256                 if (result) {
257                     try {
258                         waitForSubscriptionCondition(
259                                 () -> (TelephonyManager.SIM_STATE_PRESENT == tm.getSimCardState()),
260                                 TIMEOUT_IN_MSEC_FOR_SIM_STATUS_CHANGED);
261                     } finally {
262                         Log.d(TAG, "Insert Sim - subscription changed.");
263                     }
264                 }
265             }
266         } else {
267             Log.d(TAG, "There is a SIM inserted. Need to remove first.");
268             result = false;
269         }
270         return result;
271     }
272 
273     /**
274      * Remove a SIM card.
275      *
276      * @param slotId which slot would remove the SIM.
277      * @return boolean true if the operation is successful, otherwise false.
278      */
removeSimCard(int slotId)279     public boolean removeSimCard(int slotId) throws Exception {
280         Log.d(TAG, "removeSimCard[" + slotId + "]");
281         boolean result = true;
282 
283         if (isSimCardPresent(slotId)) {
284             MockModemConfigInterface configInterface =
285                     mMockModemService.getMockModemConfigInterface();
286             if (configInterface != null) {
287                 TelephonyManager tm = sContext.getSystemService(TelephonyManager.class);
288 
289                 result = configInterface.changeSimProfile(slotId, MOCK_SIM_PROFILE_ID_DEFAULT, TAG);
290                 if (result) {
291                     try {
292                         waitForSubscriptionCondition(
293                                 () -> (TelephonyManager.SIM_STATE_ABSENT == tm.getSimCardState()),
294                                 TIMEOUT_IN_MSEC_FOR_SIM_STATUS_CHANGED);
295                     } finally {
296                         Log.d(TAG, "Remove Sim - subscription changed.");
297                     }
298                 }
299             }
300         } else {
301             Log.d(TAG, "There is no SIM inserted.");
302             result = false;
303         }
304         return result;
305     }
306 
307     /**
308      * Modify SIM info of the SIM such as MCC/MNC, IMSI, etc.
309      *
310      * @param slotId for modifying.
311      * @param type the type of SIM info to modify.
312      * @param data to modify for the type of SIM info.
313      * @return boolean true if the operation is successful, otherwise false.
314      */
setSimInfo(int slotId, int type, String[] data)315     public boolean setSimInfo(int slotId, int type, String[] data) throws Exception {
316         Log.d(TAG, "setSimInfo[" + slotId + "]");
317         boolean result = true;
318 
319         if (isSimCardPresent(slotId)) {
320             MockModemConfigInterface configInterface =
321                     mMockModemService.getMockModemConfigInterface();
322             if (configInterface != null) {
323                 configInterface.setSimInfo(slotId, type, data, TAG);
324 
325                 // Wait for telephony framework refresh data and carrier config
326                 waitForTelephonyFrameworkDone(3);
327             } else {
328                 Log.e(TAG, "MockModemConfigInterface == null!");
329                 result = false;
330             }
331         } else {
332             Log.d(TAG, "There is no SIM inserted.");
333             result = false;
334         }
335         return result;
336     }
337 
338     /**
339      * Get SIM info of the SIM slot, e.g. MCC/MNC, IMSI.
340      *
341      * @param slotId for the query.
342      * @param type the type of SIM info.
343      * @return String the SIM info of the queried type.
344      */
getSimInfo(int slotId, int type)345     public String getSimInfo(int slotId, int type) throws Exception {
346         Log.d(TAG, "getSimInfo[" + slotId + "]");
347         String result = "";
348 
349         if (isSimCardPresent(slotId)) {
350             MockModemConfigInterface configInterface =
351                     mMockModemService.getMockModemConfigInterface();
352             if (configInterface != null) {
353                 result = configInterface.getSimInfo(slotId, type, TAG);
354             }
355         } else {
356             Log.d(TAG, "There is no SIM inserted.");
357         }
358         return result;
359     }
360 
361 
362     /**
363      * Sets the logical slots that are currently capable of performing cellular simultaneous
364      * calling.
365      * @param slotId The logical slot ID where the simultaneous calling state has changed
366      * @param enabledLogicalSlots The other logical slots that will have simultaneous calling
367      *     enabled for this slot.
368      * @return true if the operation succeeded, false if it failed
369      */
setSimulCallingEnabledLogicalSlots(int slotId, int[] enabledLogicalSlots)370     public boolean setSimulCallingEnabledLogicalSlots(int slotId,
371             int[] enabledLogicalSlots) throws Exception {
372         Log.d(TAG, "setSimulCallingEnabledLogicalSlots[" + slotId + "]");
373         boolean result = true;
374 
375         if (isSimCardPresent(slotId)) {
376             MockModemConfigInterface configInterface =
377                     mMockModemService.getMockModemConfigInterface();
378             if (configInterface != null) {
379                 configInterface.setSimulCallingEnabledLogicalSlots(slotId, enabledLogicalSlots,
380                         TAG);
381 
382                 // Wait for telephony framework refresh data and carrier config
383                 waitForTelephonyFrameworkDone(3);
384             } else {
385                 Log.e(TAG, "setSimulCallingEnabledLogicalSlots: MockModemConfigInterface"
386                         + " == null!");
387                 result = false;
388             }
389         } else {
390             Log.d(TAG, "setSimulCallingEnabledLogicalSlots: There is no SIM inserted.");
391             result = false;
392         }
393         return result;
394     }
395 
396     /**
397      * Force the response error return for a specific RIL request
398      *
399      * @param slotId which slot needs to be set.
400      * @param requestId the request/response message ID
401      * @param error RIL_Errno and -1 means to disable the modified mechanism, back to original mock
402      *     modem behavior
403      * @return boolean true if the operation is successful, otherwise false.
404      */
forceErrorResponse(int slotId, int requestId, int error)405     public boolean forceErrorResponse(int slotId, int requestId, int error) throws Exception {
406         Log.d(
407                 TAG,
408                 "forceErrorResponse[" + slotId + "] for request:" + requestId + " ,error:" + error);
409         boolean result = true;
410 
411         switch (requestId) {
412             case RIL_REQUEST_RADIO_POWER:
413                 mMockModemService
414                         .getIRadioModem((byte) slotId)
415                         .forceErrorResponse(requestId, error);
416                 break;
417             default:
418                 Log.e(TAG, "request:" + requestId + " not support to change the response error");
419                 result = false;
420                 break;
421         }
422         return result;
423     }
424 
425     /**
426      * Make the modem is in service or not.
427      *
428      * @param slotId which SIM slot is under the carrierId network.
429      * @param carrierId which carrier network is used.
430      * @param registration boolean true if the modem is in service, otherwise false.
431      * @return boolean true if the operation is successful, otherwise false.
432      */
changeNetworkService(int slotId, int carrierId, boolean registration)433     public boolean changeNetworkService(int slotId, int carrierId, boolean registration)
434             throws Exception {
435         Log.d(
436                 TAG,
437                 "changeNetworkService["
438                         + slotId
439                         + "] in carrier ("
440                         + carrierId
441                         + ") "
442                         + registration);
443 
444         boolean result;
445         result =
446                 mMockModemService
447                         .getIRadioNetwork((byte) slotId)
448                         .changeNetworkService(carrierId, registration);
449 
450         waitForTelephonyFrameworkDone(1);
451         return result;
452     }
453 
454     /**
455      * Make the modem is in service or not for CS or PS registration
456      *
457      * @param slotId which SIM slot is under the carrierId network.
458      * @param carrierId which carrier network is used.
459      * @param registration boolean true if the modem is in service, otherwise false.
460      * @param domainBitmask int specify domains (CS only, PS only, or both).
461      * @return boolean true if the operation is successful, otherwise false.
462      */
changeNetworkService( int slotId, int carrierId, boolean registration, int domainBitmask)463     public boolean changeNetworkService(
464             int slotId, int carrierId,
465             boolean registration, int domainBitmask) throws Exception {
466         return changeNetworkService(
467                 slotId, carrierId, registration, domainBitmask, 0 /* regFailCause */);
468     }
469 
470     /**
471      * Make the modem is in service or not for CS or PS registration
472      *
473      * @param slotId which SIM slot is under the carrierId network.
474      * @param carrierId which carrier network is used.
475      * @param registration boolean true if the modem is in service, otherwise false.
476      * @param domainBitmask int specify domains (CS only, PS only, or both).
477      * @param regFailCause int reason code for registration failure.
478      * @return boolean true if the operation is successful, otherwise false.
479      */
changeNetworkService( int slotId, int carrierId, boolean registration, int domainBitmask, int regFailCause)480     public boolean changeNetworkService(
481             int slotId, int carrierId,
482             boolean registration, int domainBitmask,
483             int regFailCause) throws Exception {
484         Log.d(
485                 TAG,
486                 "changeNetworkService["
487                         + slotId
488                         + "] in carrier ("
489                         + carrierId
490                         + ") "
491                         + registration
492                         + " with domainBitmask = "
493                         + domainBitmask
494                         + " with failCause = "
495                         + regFailCause);
496 
497         boolean result;
498         result =
499                 mMockModemService
500                         .getIRadioNetwork((byte) slotId)
501                         .changeNetworkService(
502                                 carrierId, registration, domainBitmask, regFailCause);
503 
504         waitForTelephonyFrameworkDone(1);
505         return result;
506     }
507 
508     /**
509      * get GSM CellBroadcastConfig outputs from IRadioMessagingImpl
510      *
511      * @param slotId which slot would insert
512      * @return Set of broadcast configs
513      */
getGsmBroadcastConfig(int slotId)514     public Set<Integer> getGsmBroadcastConfig(int slotId) {
515         return mMockModemService.getIRadioMessaging((byte) slotId).getGsmBroadcastConfigSet();
516     }
517 
518     /**
519      * get CDMA CellBroadcastConfig outputs from IRadioMessagingImpl
520      *
521      * @param slotId which slot would insert
522      * @return Set of broadcast configs
523      */
getCdmaBroadcastConfig(int slotId)524     public Set<Integer> getCdmaBroadcastConfig(int slotId) {
525         return mMockModemService.getIRadioMessaging((byte) slotId).getCdmaBroadcastConfigSet();
526     }
527 
528     /**
529      * receive new broadcast sms message
530      *
531      * @param slotId which slot would insert
532      * @param data data of broadcast messages to be received
533      */
newBroadcastSms(int slotId, byte[] data)534     public void newBroadcastSms(int slotId, byte[] data) {
535         mMockModemService.getIRadioMessaging((byte) slotId).newBroadcastSms(data);
536     }
537 
538     /**
539      * register callback for monitoring broadcast activation
540      *
541      * @param slotId which slot would insert
542      * @param callback callback to register
543      */
registerBroadcastCallback(int slotId, IRadioMessagingImpl.CallBackWithExecutor callback)544     public void registerBroadcastCallback(int slotId,
545             IRadioMessagingImpl.CallBackWithExecutor callback) {
546         mMockModemService.getIRadioMessaging((byte) slotId).registerBroadcastCallback(callback);
547     }
548 
549     /**
550      * unregister callback for monitoring broadcast activation
551      *
552      * @param slotId which slot would insert
553      * @param callback callback to unregister
554      */
unregisterBroadcastCallback(int slotId, IRadioMessagingImpl.CallBackWithExecutor callback)555     public void unregisterBroadcastCallback(int slotId,
556             IRadioMessagingImpl.CallBackWithExecutor callback) {
557         mMockModemService.getIRadioMessaging((byte) slotId).unregisterBroadcastCallback(callback);
558     }
559 
560     /**
561      * Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed.
562      *
563      * @param slotId which slot would insert.
564      * @param state New SRVCC State
565      * @return boolean true if the operation is successful, otherwise false.
566      */
srvccStateNotify(int slotId, int state)567     public boolean srvccStateNotify(int slotId, int state) {
568         Log.d(TAG, "notifySrvccState[" + slotId + "] with state(" + state + ")");
569 
570         boolean result = false;
571         try {
572             IRadioVoiceImpl radioVoice = mMockModemService.getIRadioVoice((byte) slotId);
573             if (radioVoice != null) {
574                 radioVoice.srvccStateNotify(state);
575 
576                 waitForTelephonyFrameworkDone(1);
577                 result = true;
578             }
579         } catch (Exception e) {
580         }
581         return result;
582     }
583 
584     /**
585      * Returns the list of MockSrvccCall
586      *
587      * @param slotId for which slot to get the list
588      * @return the list of {@link MockSrvccCall}
589      */
getSrvccCalls(int slotId)590     public List<MockSrvccCall> getSrvccCalls(int slotId) {
591         Log.d(TAG, "getSrvccCalls[" + slotId + "]");
592 
593         IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
594         if (radioIms == null) return null;
595         return radioIms.getSrvccCalls();
596     }
597 
598     /**
599      * Triggers IMS deregistration.
600      *
601      * @param slotId which slot would insert.
602      * @param reason the reason why the deregistration is triggered.
603      * @return {@code true} if the operation is successful, otherwise {@code false}.
604      */
triggerImsDeregistration(int slotId, @ImsRegistrationImplBase.ImsDeregistrationReason int reason)605     public boolean triggerImsDeregistration(int slotId,
606             @ImsRegistrationImplBase.ImsDeregistrationReason int reason) {
607         Log.d(TAG, "triggerImsDeregistration[" + slotId + "] reason=" + reason);
608 
609         boolean result = false;
610         try {
611             mMockModemService.getIRadioIms().triggerImsDeregistration(reason);
612 
613             waitForTelephonyFrameworkDone(1);
614             result = true;
615         } catch (Exception e) {
616         }
617         return result;
618     }
619 
620     /**
621      * Clears the Anbr values.
622      *
623      * @param slotId for which slot to get the reason.
624      */
resetAnbrValues(int slotId)625     public void resetAnbrValues(int slotId) {
626         Log.d(TAG, "resetAnbrValues[" + slotId + "]");
627 
628         try {
629             IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
630             if (radioIms == null) return;
631             radioIms.resetAnbrValues();
632         } catch (Exception e) {
633             Log.e(TAG, "resetAnbrValues - failed");
634         }
635     }
636 
637     /**
638      * Returns the Anbr values.
639      *
640      * @param slotId for which slot to get the reason.
641      * @return the Anbr values triggered by Anbr Query.
642      */
getAnbrValues(int slotId)643     public int[] getAnbrValues(int slotId) {
644         Log.d(TAG, "getAnbrValues[" + slotId + "]");
645 
646         IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
647         if (radioIms == null) return null;
648         return radioIms.getAnbrValues();
649     }
650 
651     /**
652      * Triggers NotifyAnbr.
653      *
654      * @param slotId which slot would insert.
655      * @param qosSessionId is used to identify media stream such as audio or video.
656      * @param direction Direction of this packet stream (e.g. uplink or downlink).
657      * @param bitsPerSecond is the bitrate received from the NW through the Recommended
658      *        bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
659      *        to audio/video codec bitrate (defined in TS26.114).
660      * @return {@code true} if the operation is successful, otherwise {@code false}.
661      */
notifyAnbr(int slotId, int qosSessionId, int direction, int bitsPerSecond)662     public boolean notifyAnbr(int slotId, int qosSessionId, int direction, int bitsPerSecond) {
663         Log.d(TAG, "mockmodem - notifyAnbr[" + slotId + "] qosSessionId=" + qosSessionId
664                 + ", direction=" + direction + ", bitsPerSecond" + bitsPerSecond);
665 
666         boolean result = false;
667         try {
668 
669             IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
670             if (radioIms == null) return false;
671             radioIms.notifyAnbr(qosSessionId, direction, bitsPerSecond);
672 
673             waitForTelephonyFrameworkDone(1);
674             result = true;
675         } catch (Exception e) {
676             Log.e(TAG, "Create notifyAnbr - failed");
677         }
678         return result;
679     }
680 
681     /**
682      * Returns the reason that caused EPS fallback.
683      *
684      * @param slotId for which slot to get the reason
685      * @return the reason that caused EPS fallback.
686      */
getEpsFallbackReason(int slotId)687     public @MmTelFeature.EpsFallbackReason int getEpsFallbackReason(int slotId) {
688         Log.d(TAG, "getEpsFallbackReason[" + slotId + "]");
689 
690         IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
691         if (radioIms == null) return -1;
692         return radioIms.getEpsFallbackReason();
693     }
694 
695     /**
696      * Clears the EPS fallback reason.
697      *
698      * @param slotId for which slot to get the reason
699      */
resetEpsFallbackReason(int slotId)700     public void resetEpsFallbackReason(int slotId) {
701         Log.d(TAG, "resetEpsFallbackReason[" + slotId + "]");
702 
703         IRadioImsImpl radioIms = mMockModemService.getIRadioIms((byte) slotId);
704         if (radioIms == null) return;
705         radioIms.resetEpsFallbackReason();
706     }
707 
708     /**
709      * Updates the emergency registration state.
710      *
711      * @param slotId the Id of logical sim slot.
712      * @param regResult the emergency registration state.
713      */
setEmergencyRegResult(int slotId, MockEmergencyRegResult regResult)714     public void setEmergencyRegResult(int slotId, MockEmergencyRegResult regResult) {
715         Log.d(TAG, "setEmergencyRegResult[" + slotId + "]");
716         mMockModemService.getIRadioNetwork((byte) slotId).setEmergencyRegResult(regResult);
717     }
718 
719     /**
720      * Notifies the barring information change.
721      *
722      * @param slotId the Id of logical sim slot.
723      * @param barringServiceInfos the barring information.
724      */
unsolBarringInfoChanged(int slotId, SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos)725     public boolean unsolBarringInfoChanged(int slotId,
726             SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos) {
727         Log.d(TAG, "unsolBarringInfoChanged[" + slotId + "]");
728         return mMockModemService.getIRadioNetwork((byte) slotId)
729                 .unsolBarringInfoChanged(barringServiceInfos);
730     }
731 
732     /**
733      * Triggers RIL_UNSOL_EMERGENCY_NETWORK_SCAN_RESULT unsol message.
734      *
735      * @param slotId the Id of logical sim slot.
736      * @param regResult the registration result.
737      */
unsolEmergencyNetworkScanResult(int slotId, MockEmergencyRegResult regResult)738     public boolean unsolEmergencyNetworkScanResult(int slotId, MockEmergencyRegResult regResult) {
739         Log.d(TAG, "unsolEmergencyNetworkScanResult[" + slotId + "]");
740         return mMockModemService.getIRadioNetwork((byte) slotId)
741                 .unsolEmergencyNetworkScanResult(regResult);
742     }
743 
744     /**
745      * Notifies of the SecurityAlgorithmUpdate change.
746      *
747      * @param slotId the Id of logical sim slot.
748      * @param update the security algorithm update information.
749      */
unsolSecurityAlgorithmsUpdated(int slotId, SecurityAlgorithmUpdate update)750     public boolean unsolSecurityAlgorithmsUpdated(int slotId,
751             SecurityAlgorithmUpdate update) {
752         Log.d(TAG, "unsolSecurityAlgorithmsUpdated[" + slotId + "]");
753         return mMockModemService.getIRadioNetwork((byte) slotId)
754                 .unsolSecurityAlgorithmsUpdated(update);
755     }
756 
757     /**
758      * Notifies of the CellularIdentifierDisclosure change.
759      *
760      * @param slotId the Id of logical sim slot.
761      * @param disclosure the cellular identifier disclosure information.
762      */
unsolCellularIdentifierDisclosed(int slotId, CellularIdentifierDisclosure disclosure)763     public boolean unsolCellularIdentifierDisclosed(int slotId,
764             CellularIdentifierDisclosure disclosure) {
765         Log.d(TAG, "unsolCellularIdentifierDisclosed[" + slotId + "]");
766         return mMockModemService.getIRadioNetwork((byte) slotId)
767                 .unsolCellularIdentifierDisclosed(disclosure);
768     }
769 
770     /**
771      * Resets the current emergency mode.
772      *
773      * @param slotId the Id of logical sim slot.
774      */
resetEmergencyMode(int slotId)775     public void resetEmergencyMode(int slotId) {
776         Log.d(TAG, "resetEmergencyMode[" + slotId + "]");
777         mMockModemService.getIRadioNetwork((byte) slotId).resetEmergencyMode();
778     }
779 
780     /**
781      * @return the current emergency mode.
782      *
783      * @param slotId the Id of logical sim slot.
784      */
getEmergencyMode(int slotId)785     public int getEmergencyMode(int slotId) {
786         Log.d(TAG, "getEmergencyMode[" + slotId + "]");
787         return mMockModemService.getIRadioNetwork((byte) slotId).getEmergencyMode();
788     }
789 
790     /**
791      * Returns whether emergency network scan is triggered.
792      *
793      * @param slotId the Id of logical sim slot.
794      * @return {@code true} if emergency network scan is triggered.
795      */
isEmergencyNetworkScanTriggered(int slotId)796     public boolean isEmergencyNetworkScanTriggered(int slotId) {
797         Log.d(TAG, "isEmergencyNetworkScanTriggered[" + slotId + "]");
798         return mMockModemService.getIRadioNetwork((byte) slotId).isEmergencyNetworkScanTriggered();
799     }
800 
801     /**
802      * Returns whether emergency network scan is canceled.
803      *
804      * @param slotId the Id of logical sim slot.
805      * @return {@code true} if emergency network scan is canceled.
806      */
isEmergencyNetworkScanCanceled(int slotId)807     public boolean isEmergencyNetworkScanCanceled(int slotId) {
808         Log.d(TAG, "isEmergencyNetworkScanCanceled[" + slotId + "]");
809         return mMockModemService.getIRadioNetwork((byte) slotId).isEmergencyNetworkScanCanceled();
810     }
811 
812     /**
813      * Returns the list of preferred network type.
814      *
815      * @param slotId the Id of logical sim slot.
816      * @return the list of preferred network type.
817      */
getEmergencyNetworkScanAccessNetwork(int slotId)818     public int[] getEmergencyNetworkScanAccessNetwork(int slotId) {
819         Log.d(TAG, "getEmergencyNetworkScanAccessNetwork[" + slotId + "]");
820         return mMockModemService.getIRadioNetwork((byte) slotId)
821                 .getEmergencyNetworkScanAccessNetwork();
822     }
823 
824     /**
825      * Returns the preferred scan type.
826      *
827      * @param slotId the Id of logical sim slot.
828      * @return the preferred scan type.
829      */
getEmergencyNetworkScanType(int slotId)830     public int getEmergencyNetworkScanType(int slotId) {
831         Log.d(TAG, "getEmergencyNetworkScanType[" + slotId + "]");
832         return mMockModemService.getIRadioNetwork((byte) slotId).getEmergencyNetworkScanType();
833     }
834 
835     /**
836      * Resets the emergency network scan attributes.
837      *
838      * @param slotId the Id of logical sim slot.
839      */
resetEmergencyNetworkScan(int slotId)840     public void resetEmergencyNetworkScan(int slotId) {
841         Log.d(TAG, "resetEmergencyNetworkScan[" + slotId + "]");
842         mMockModemService.getIRadioNetwork((byte) slotId).resetEmergencyNetworkScan();
843     }
844 
845     /**
846      * Waits for the event of network service.
847      *
848      * @param slotId the Id of logical sim slot.
849      * @param latchIndex The index of the event.
850      * @param waitMs The timeout in milliseconds.
851      */
waitForNetworkLatchCountdown(int slotId, int latchIndex, int waitMs)852     public boolean waitForNetworkLatchCountdown(int slotId, int latchIndex, int waitMs) {
853         Log.d(TAG, "waitForNetworkLatchCountdown[" + slotId + "]");
854         return mMockModemService.getIRadioNetwork((byte) slotId)
855                 .waitForLatchCountdown(latchIndex, waitMs);
856     }
857 
858     /**
859      * Resets the CountDownLatches of network service.
860      *
861      * @param slotId the Id of logical sim slot.
862      */
resetNetworkAllLatchCountdown(int slotId)863     public void resetNetworkAllLatchCountdown(int slotId) {
864         Log.d(TAG, "resetNetworkAllLatchCountdown[" + slotId + "]");
865         mMockModemService.getIRadioNetwork((byte) slotId).resetAllLatchCountdown();
866     }
867 
868     /**
869      * Waits for the event of voice service.
870      *
871      * @param slotId the Id of logical sim slot.
872      * @param latchIndex The index of the event.
873      * @param waitMs The timeout in milliseconds.
874      */
waitForVoiceLatchCountdown(int slotId, int latchIndex, int waitMs)875     public boolean waitForVoiceLatchCountdown(int slotId, int latchIndex, int waitMs) {
876         Log.d(TAG, "waitForVoiceLatchCountdown[" + slotId + "]");
877         return mMockModemService.getIRadioVoice((byte) slotId)
878                 .waitForLatchCountdown(latchIndex, waitMs);
879     }
880 
881     /**
882      * Resets the CountDownLatches of voice service.
883      *
884      * @param slotId the Id of logical sim slot.
885      */
resetVoiceAllLatchCountdown(int slotId)886     public void resetVoiceAllLatchCountdown(int slotId) {
887         Log.d(TAG, "resetVoiceAllLatchCountdown[" + slotId + "]");
888         mMockModemService.getIRadioVoice((byte) slotId).resetAllLatchCountdown();
889     }
890 
891     /**
892      * Stops sending default response to startImsTraffic.
893      *
894      * @param slotId which slot would insert.
895      * @param blocked indicates whether sending response is allowed or not.
896      */
blockStartImsTrafficResponse(int slotId, boolean blocked)897     public void blockStartImsTrafficResponse(int slotId, boolean blocked) {
898         Log.d(TAG, "blockStartImsTrafficResponse[" + slotId + "] blocked(" + blocked + ")");
899 
900         mMockModemService.getIRadioIms((byte) slotId).blockStartImsTrafficResponse(blocked);
901     }
902 
903     /**
904      * Returns whether the given IMS traffic type is started or not.
905      *
906      * @param slotId which slot would insert.
907      * @param trafficType the IMS traffic type
908      * @return boolean true if the given IMS traffic type is started
909      */
isImsTrafficStarted(int slotId, @MmTelFeature.ImsTrafficType int trafficType)910     public boolean isImsTrafficStarted(int slotId,
911             @MmTelFeature.ImsTrafficType int trafficType) {
912         Log.d(TAG, "isImsTrafficStarted[" + slotId + "] trafficType(" + trafficType + ")");
913 
914         return mMockModemService.getIRadioIms((byte) slotId).isImsTrafficStarted(trafficType);
915     }
916 
917     /**
918      * Sends the response with the given information.
919      *
920      * @param slotId which slot would insert.
921      * @param trafficType the IMS traffic type
922      * @param reason The reason of failure.
923      * @param causeCode Failure cause code from network or modem specific to the failure.
924      * @param waitTimeMillis Retry wait time provided by network in milliseconds.
925      * @return boolean true if there is no error
926      */
sendStartImsTrafficResponse(int slotId, @MmTelFeature.ImsTrafficType int trafficType, @ConnectionFailureInfo.FailureReason int reason, int causeCode, int waitTimeMillis)927     public boolean sendStartImsTrafficResponse(int slotId,
928             @MmTelFeature.ImsTrafficType int trafficType,
929             @ConnectionFailureInfo.FailureReason int reason,
930             int causeCode, int waitTimeMillis) {
931         Log.d(TAG, "sendStartImsTrafficResponse[" + slotId
932                 + "] trafficType(" + trafficType + ")"
933                 + " reason(" + reason + ")"
934                 + " cause(" + causeCode + ")"
935                 + " wait(" + waitTimeMillis + ")");
936 
937         boolean result = false;
938         try {
939             mMockModemService.getIRadioIms((byte) slotId).sendStartImsTrafficResponse(
940                     trafficType, reason, causeCode, waitTimeMillis);
941 
942             waitForTelephonyFrameworkDone(1);
943             result = true;
944         } catch (Exception e) {
945             Log.e(TAG, "sendStartImsTrafficResponse e=" + e);
946         }
947         return result;
948     }
949 
950     /**
951      * Notifies the connection failure info
952      *
953      * @param slotId which slot would insert.
954      * @param trafficType the IMS traffic type
955      * @param reason The reason of failure.
956      * @param causeCode Failure cause code from network or modem specific to the failure.
957      * @param waitTimeMillis Retry wait time provided by network in milliseconds.
958      * @return boolean true if there is no error
959      */
sendConnectionFailureInfo(int slotId, @MmTelFeature.ImsTrafficType int trafficType, @ConnectionFailureInfo.FailureReason int reason, int causeCode, int waitTimeMillis)960     public boolean sendConnectionFailureInfo(int slotId,
961             @MmTelFeature.ImsTrafficType int trafficType,
962             @ConnectionFailureInfo.FailureReason int reason,
963             int causeCode, int waitTimeMillis) {
964         Log.d(TAG, "sendConnectionFailureInfo[" + slotId
965                 + "] trafficType(" + trafficType + ")"
966                 + " reason(" + reason + ")"
967                 + " cause(" + causeCode + ")"
968                 + " wait(" + waitTimeMillis + ")");
969 
970         boolean result = false;
971         try {
972             mMockModemService.getIRadioIms((byte) slotId).sendConnectionFailureInfo(
973                     trafficType, reason, causeCode, waitTimeMillis);
974 
975             waitForTelephonyFrameworkDone(1);
976             result = true;
977         } catch (Exception e) {
978             Log.e(TAG, "sendConnectionFailureInfo e=" + e);
979         }
980         return result;
981     }
982 
983     /**
984      * Clears the IMS traffic state.
985      */
clearImsTrafficState()986     public void clearImsTrafficState() {
987         mMockModemService.getIRadioIms().clearImsTrafficState();
988     }
989 
990     /**
991      * Waits for the event of mock IMS state.
992      *
993      * @param latchIndex The index of the event.
994      * @param waitMs The timeout in milliseconds.
995      */
waitForImsLatchCountdown(int latchIndex, int waitMs)996     public boolean waitForImsLatchCountdown(int latchIndex, int waitMs) {
997         return mMockModemService.getIRadioIms().waitForLatchCountdown(latchIndex, waitMs);
998     }
999 
1000     /** Resets the CountDownLatches of IMS state. */
resetImsAllLatchCountdown()1001     public void resetImsAllLatchCountdown() {
1002         mMockModemService.getIRadioIms().resetAllLatchCountdown();
1003     }
1004 
1005     /**
1006      * Set/override default call control configuration.
1007      *
1008      * @param slotId the Id of logical sim slot.
1009      * @param callControlInfo the configuration of call control would like to override.
1010      * @return boolean true if the operation succeeds, otherwise false.
1011      */
setCallControlInfo(int slotId, MockCallControlInfo callControlInfo)1012     public boolean setCallControlInfo(int slotId, MockCallControlInfo callControlInfo) {
1013         Log.d(TAG, "setCallControlInfo[" + slotId + "]");
1014         return mMockModemService
1015                 .getMockModemConfigInterface()
1016                 .setCallControlInfo(slotId, callControlInfo, TAG);
1017     }
1018 
1019     /**
1020      * Get call control configuration.
1021      *
1022      * @param slotId the Id of logical sim slot.
1023      * @return MockCallControlInfo which was set/overridden before.
1024      */
getCallControlInfo(int slotId)1025     public MockCallControlInfo getCallControlInfo(int slotId) {
1026         Log.d(TAG, "getCallControlInfo[" + slotId + "]");
1027         return mMockModemService.getMockModemConfigInterface().getCallControlInfo(slotId, TAG);
1028     }
1029 
1030     /**
1031      * Trigger an incoming voice call.
1032      *
1033      * @param slotId the Id of logical sim slot.
1034      * @param address phone number of the incoming call
1035      * @param uusInfo user to user signaling information.
1036      * @param cdmaSignalInfoRecord CDMA Signal Information Record.
1037      * @return boolean true if the operation succeeds, otherwise false.
1038      */
triggerIncomingVoiceCall( int slotId, String address, UusInfo[] uusInfo, CdmaSignalInfoRecord cdmaSignalInfoRecord)1039     public boolean triggerIncomingVoiceCall(
1040             int slotId,
1041             String address,
1042             UusInfo[] uusInfo,
1043             CdmaSignalInfoRecord cdmaSignalInfoRecord)
1044             throws Exception {
1045         return triggerIncomingVoiceCall(slotId, address, uusInfo, cdmaSignalInfoRecord, null);
1046     }
1047 
1048     /**
1049      * Trigger an incoming voice call with a call control configuration.
1050      *
1051      * @param slotId the Id of logical sim slot.
1052      * @param address phone number of the incoming call
1053      * @param uusInfo user to user signaling information.
1054      * @param cdmaSignalInfoRecord CDMA Signal Information Record.
1055      * @param callControlInfo the configuration of call control would like to override.
1056      * @return boolean true if the operation succeeds, otherwise false.
1057      */
triggerIncomingVoiceCall( int slotId, String address, UusInfo[] uusInfo, CdmaSignalInfoRecord cdmaSignalInfoRecord, MockCallControlInfo callControlInfo)1058     public boolean triggerIncomingVoiceCall(
1059             int slotId,
1060             String address,
1061             UusInfo[] uusInfo,
1062             CdmaSignalInfoRecord cdmaSignalInfoRecord,
1063             MockCallControlInfo callControlInfo)
1064             throws Exception {
1065         Log.d(TAG, "triggerIncomingVoiceCall[" + slotId + "] address: " + address);
1066         boolean result;
1067 
1068         result =
1069                 mMockModemService
1070                         .getMockModemConfigInterface()
1071                         .triggerIncomingVoiceCall(
1072                                 slotId,
1073                                 address,
1074                                 uusInfo,
1075                                 cdmaSignalInfoRecord,
1076                                 callControlInfo,
1077                                 TAG);
1078 
1079         waitForTelephonyFrameworkDone(1);
1080         return result;
1081     }
1082 
1083     /**
1084      * Get number of on going CS calls.
1085      *
1086      * @param slotId the Id of logical sim slot.
1087      * @return int the number of CS calls.
1088      */
getNumberOfOngoingCSCalls(int slotId)1089     public int getNumberOfOngoingCSCalls(int slotId) {
1090         Log.d(TAG, "getNumberOfOngoingCSCalls[" + slotId + "]");
1091         return mMockModemService.getMockModemConfigInterface().getNumberOfCalls(slotId, TAG);
1092     }
1093 
1094     /**
1095      * Sets the last call fail cause.
1096      *
1097      * @param slotId the Id of logical sim slot.
1098      * @param cause The disconnect cause.
1099      */
setLastCallFailCause(int slotId, int cause)1100     public void setLastCallFailCause(int slotId, int cause) {
1101         Log.d(TAG, "setLastCallFailCause[" + slotId + "] cause = " + cause);
1102         mMockModemService.getMockModemConfigInterface().setLastCallFailCause(slotId, cause, TAG);
1103     }
1104 
1105     /**
1106      * Clears all calls with the given cause.
1107      *
1108      * @param slotId the Id of logical sim slot.
1109      * @param cause The disconnect cause.
1110      */
clearAllCalls(int slotId, @Annotation.DisconnectCauses int cause)1111     public void clearAllCalls(int slotId, @Annotation.DisconnectCauses int cause) {
1112         Log.d(TAG, "clearAllCalls[" + slotId + "] cause = " + cause);
1113         mMockModemService.getMockModemConfigInterface().clearAllCalls(slotId, cause, TAG);
1114     }
1115 
1116     /**
1117      * Reports the list of emergency numbers.
1118      *
1119      * @param numbers The list of emergency numbers.
1120      */
notifyEmergencyNumberList(int slotId, String[] numbers)1121     public void notifyEmergencyNumberList(int slotId, String[] numbers) {
1122         Log.d(TAG, "notifyEmergencyNumberList[" + slotId + "]");
1123         mMockModemService.getIRadioVoice((byte) slotId).notifyEmergencyNumberList(numbers);
1124     }
1125 
1126     /**
1127      * Sets the new carrierId and CarrierRestriction status values in IRadioSimImpl.java
1128      * @param carrierList
1129      * @param carrierRestrictionStatus
1130      */
updateCarrierRestrictionInfo(Carrier[] carrierList, int carrierRestrictionStatus)1131     public void updateCarrierRestrictionInfo(Carrier[] carrierList, int carrierRestrictionStatus) {
1132         mMockModemService.getIRadioSim().updateCarrierRestrictionStatusInfo(carrierList,
1133                 carrierRestrictionStatus);
1134     }
1135 
1136     /**
1137      * Helper method that can be called from the test suite to change the primary IMEi mapping
1138      * with respect to sim slot.
1139      */
changeImeiMapping()1140     public boolean changeImeiMapping() {
1141         int modemCount = mMockModemService.getActiveMockModemCount();
1142         if (modemCount == 1) {
1143             return false;
1144         }
1145         // In case there are more than 2 modems, it is enough to shuffle the primary IMEI with
1146         // another one slot, so enough to run the loop for 2 times.
1147         if (modemCount > 2) {
1148             modemCount = 2;
1149         }
1150         for (int slotId = 0; slotId < modemCount; slotId++) {
1151             mMockModemService.getIRadioModem((byte) slotId).resetAllLatchCountdown();
1152             mMockModemService.getIRadioModem((byte) slotId).changeImeiMapping();
1153             if (waitForModemLatchCountdown(slotId, WAIT_UPDATE_TIMEOUT_MS)) {
1154                 Log.e(TAG, "Error in waitForModemLatchCountdown");
1155             }
1156         }
1157         return true;
1158     }
1159 
1160     /**
1161      * Wait latch for WAIT_UPDATE_TIMEOUT_MS or latch to countdown.
1162      * @param slotId : slotId of the device.
1163      * @param waitMs : Wait in milliseconds for the latch-wait timeout.
1164      * @return true if latch is success else fail.
1165      */
waitForModemLatchCountdown(int slotId, int waitMs)1166     public boolean waitForModemLatchCountdown(int slotId, int waitMs) {
1167         Log.d(TAG, "waitForVoiceLatchCountdown[" + slotId + "]");
1168         return mMockModemService.getIRadioModem((byte) slotId)
1169                 .waitForLatchCountdown(slotId, waitMs);
1170     }
1171 
setCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules, int multiSimPolicy)1172     public void setCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules,
1173             int multiSimPolicy) {
1174         mMockModemService.getIRadioSim().updateCarrierRestrictionRules(
1175                 carrierRestrictionRules, multiSimPolicy);
1176     }
1177 
1178     /**
1179      * Triggers an incoming SMS.
1180      *
1181      * @param slotId the Id of logical sim slot.
1182      * @return {@code true} if the operation succeeds otherwise false.
1183      */
triggerIncomingSms(int slotId)1184     public boolean triggerIncomingSms(int slotId) {
1185         Log.d(TAG, "triggerIncomingSms[" + slotId + "]");
1186 
1187         boolean result = false;
1188         try {
1189             String pdu = "07916164260220F0040B914151245584F600006060605130308A04D4F29C0E";
1190             mMockModemService.getIRadioMessaging((byte) slotId)
1191                     .newSms(TelephonyUtils.hexStringToByteArray(pdu));
1192 
1193             waitForTelephonyFrameworkDone(1);
1194             result = true;
1195         } catch (Exception e) {
1196             Log.e(TAG, "triggerIncomingSms e=" + e);
1197         }
1198         return result;
1199     }
1200 
1201     /** Set error code to be returned by mock modem. */
setSatelliteErrorCode(int slotId, @RadioError int errorCode)1202     public void setSatelliteErrorCode(int slotId, @RadioError int errorCode) {
1203         Log.d(TAG, "setSatelliteErrorCode: slotId=" + slotId + "errorCode=" + errorCode);
1204         if (mMockModemService == null) {
1205             Log.e(TAG, "setSatelliteErrorCode: mMockModemService is null");
1206             return;
1207         }
1208         mMockModemService.getIRadioNetwork((byte) slotId).setSatelliteErrorCode(errorCode);
1209     }
1210 
1211     /** Wait until setSatellitePlmn() is called. */
waitForEventOnSetSatellitePlmn(int expectedNumberOfEvents)1212     public boolean waitForEventOnSetSatellitePlmn(int expectedNumberOfEvents) {
1213         Log.d(TAG, "waitForEventOnSetSatellitePlmn");
1214         if (mMockModemService == null) {
1215             Log.e(TAG, "waitForEventOnSetSatellitePlmn: mMockModemService is null");
1216             return false;
1217         }
1218 
1219         return mMockModemService.waitForEventOnSetSatellitePlmn(expectedNumberOfEvents);
1220     }
1221 
1222     /** Get whether satellite is enabled for carrier. */
getIsSatelliteEnabledForCarrier(int slotId)1223     public boolean getIsSatelliteEnabledForCarrier(int slotId) {
1224         Log.d(TAG, "getIsSatelliteEnabledForCarrier: slotId=" + slotId);
1225         if (mMockModemService == null) {
1226             Log.e(TAG, "getIsSatelliteEnabledForCarrier: mMockModemService is null");
1227             return false;
1228         }
1229         return mMockModemService.getIRadioNetwork((byte) slotId).getIsSatelliteEnabledForCarrier();
1230     }
1231 
1232     /** Return carrier PLMN list. */
1233     @Nullable
getCarrierPlmnList(int slotId)1234     public List<String> getCarrierPlmnList(int slotId) {
1235         Log.d(TAG, "getCarrierPlmnList: slotId=" + slotId);
1236         if (mMockModemService == null) {
1237             Log.e(TAG, "getIsSatelliteEnabledForCarrier: mMockModemService is null");
1238             return null;
1239         }
1240 
1241         String[] carrierPlmnArray =
1242                 mMockModemService.getIRadioNetwork((byte) slotId).getCarrierPlmnArray();
1243         return Arrays.asList(carrierPlmnArray);
1244     }
1245 
1246     /** Return all satellite PLMN list. */
1247     @Nullable
getAllSatellitePlmnList(int slotId)1248     public List<String> getAllSatellitePlmnList(int slotId) {
1249         Log.d(TAG, "getAllSatellitePlmnList: slotId=" + slotId);
1250         if (mMockModemService == null) {
1251             Log.e(TAG, "getAllSatellitePlmnList: mMockModemService is null");
1252             return null;
1253         }
1254 
1255         String[] allSatellitePlmnArray =
1256                 mMockModemService.getIRadioNetwork((byte) slotId).getAllSatellitePlmnArray();
1257         return Arrays.asList(allSatellitePlmnArray);
1258     }
1259 
1260     /** Clear satellite enabled for carrier. */
clearSatelliteEnabledForCarrier(int slotId)1261     public void clearSatelliteEnabledForCarrier(int slotId) {
1262         Log.d(TAG, "clearSatelliteEnabledForCarrier: slotId=" + slotId);
1263         if (mMockModemService == null) {
1264             Log.e(TAG, "clearSatelliteEnabledForCarrier: mMockModemService is null");
1265         }
1266 
1267         mMockModemService.getIRadioNetwork((byte) slotId).clearSatelliteEnabledForCarrier();
1268     }
1269 }
1270