1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.test;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.hardware.radio.RadioError;
21 import android.hardware.radio.V1_2.VoiceRegStateResult;
22 import android.hardware.radio.V1_4.DataRegStateResult;
23 import android.hardware.radio.V1_4.PdpProtocolType;
24 import android.hardware.radio.V1_4.SetupDataCallResult;
25 import android.hardware.radio.modem.ImeiInfo;
26 import android.net.KeepalivePacketData;
27 import android.net.LinkProperties;
28 import android.os.AsyncResult;
29 import android.os.Handler;
30 import android.os.HandlerThread;
31 import android.os.Looper;
32 import android.os.Message;
33 import android.os.Parcel;
34 import android.os.SystemClock;
35 import android.os.WorkSource;
36 import android.telephony.CarrierRestrictionRules;
37 import android.telephony.CellInfo;
38 import android.telephony.CellInfoGsm;
39 import android.telephony.CellSignalStrengthCdma;
40 import android.telephony.CellSignalStrengthGsm;
41 import android.telephony.CellSignalStrengthLte;
42 import android.telephony.CellSignalStrengthNr;
43 import android.telephony.CellSignalStrengthTdscdma;
44 import android.telephony.CellSignalStrengthWcdma;
45 import android.telephony.IccOpenLogicalChannelResponse;
46 import android.telephony.ImsiEncryptionInfo;
47 import android.telephony.NetworkRegistrationInfo;
48 import android.telephony.NetworkScanRequest;
49 import android.telephony.PcoData;
50 import android.telephony.ServiceState;
51 import android.telephony.SignalStrength;
52 import android.telephony.SignalThresholdInfo;
53 import android.telephony.TelephonyManager;
54 import android.telephony.data.DataCallResponse;
55 import android.telephony.data.DataProfile;
56 import android.telephony.data.NetworkSliceInfo;
57 import android.telephony.data.TrafficDescriptor;
58 import android.telephony.emergency.EmergencyNumber;
59 
60 import com.android.internal.annotations.VisibleForTesting;
61 import com.android.internal.telephony.BaseCommands;
62 import com.android.internal.telephony.CallFailCause;
63 import com.android.internal.telephony.CommandException;
64 import com.android.internal.telephony.CommandsInterface;
65 import com.android.internal.telephony.LastCallFailCause;
66 import com.android.internal.telephony.Phone;
67 import com.android.internal.telephony.PhoneConstants;
68 import com.android.internal.telephony.RILUtils;
69 import com.android.internal.telephony.RadioCapability;
70 import com.android.internal.telephony.SmsResponse;
71 import com.android.internal.telephony.SrvccConnection;
72 import com.android.internal.telephony.UUSInfo;
73 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
74 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
75 import com.android.internal.telephony.gsm.SuppServiceNotification;
76 import com.android.internal.telephony.uicc.AdnCapacity;
77 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
78 import com.android.internal.telephony.uicc.IccCardStatus;
79 import com.android.internal.telephony.uicc.IccIoResult;
80 import com.android.internal.telephony.uicc.ReceivedPhonebookRecords;
81 import com.android.internal.telephony.uicc.SimPhonebookRecord;
82 import com.android.telephony.Rlog;
83 
84 import java.util.ArrayList;
85 import java.util.List;
86 import java.util.concurrent.atomic.AtomicBoolean;
87 import java.util.concurrent.atomic.AtomicInteger;
88 
89 public class SimulatedCommands extends BaseCommands
90         implements CommandsInterface, SimulatedRadioControl {
91     private static final String LOG_TAG = "SimulatedCommands";
92 
93     private enum SimLockState {
94         NONE,
95         REQUIRE_PIN,
96         REQUIRE_PUK,
97         SIM_PERM_LOCKED
98     }
99 
100     private enum SimFdnState {
101         NONE,
102         REQUIRE_PIN2,
103         REQUIRE_PUK2,
104         SIM_PERM_LOCKED
105     }
106 
107     private static final SimLockState INITIAL_LOCK_STATE = SimLockState.NONE;
108     public static final String DEFAULT_SIM_PIN_CODE = "1234";
109     private static final String SIM_PUK_CODE = "12345678";
110     private static final SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE;
111     public static final String DEFAULT_SIM_PIN2_CODE = "5678";
112     private static final String SIM_PUK2_CODE = "87654321";
113     public static final String FAKE_LONG_NAME = "Fake long name";
114     public static final String FAKE_SHORT_NAME = "Fake short name";
115     public static final String FAKE_MCC_MNC = "310260";
116     public static final String FAKE_IMEI = "012345678901234";
117     public static final String FAKE_IMEISV = "99";
118     public static final String FAKE_ESN = "1234";
119     public static final String FAKE_MEID = "1234";
120     public static final int DEFAULT_PIN1_ATTEMPT = 5;
121     public static final int DEFAULT_PIN2_ATTEMPT = 5;
122     public static final int ICC_AUTHENTICATION_MODE_DEFAULT = 0;
123     public static final int ICC_AUTHENTICATION_MODE_NULL = 1;
124     public static final int ICC_AUTHENTICATION_MODE_TIMEOUT = 2;
125     // Maximum time in millisecond to wait for a IccSim Challenge before assuming it will not
126     // arrive and returning null to the callers.
127     public static final  long ICC_SIM_CHALLENGE_TIMEOUT_MILLIS = 2500;
128 
129     //***** Instance Variables
130 
131     @UnsupportedAppUsage
132     SimulatedGsmCallState simulatedCallState;
133     HandlerThread mHandlerThread;
134     SimLockState mSimLockedState;
135     boolean mSimLockEnabled;
136     int mPinUnlockAttempts;
137     int mPukUnlockAttempts;
138     String mPinCode;
139     int mPin1attemptsRemaining = DEFAULT_PIN1_ATTEMPT;
140     SimFdnState mSimFdnEnabledState;
141     boolean mSimFdnEnabled;
142     int mPin2UnlockAttempts;
143     int mPuk2UnlockAttempts;
144     int mPreferredNetworkType;
145     int mAllowedNetworkType;
146     String mPin2Code;
147     boolean mSsnNotifyOn = false;
148     private int mVoiceRegState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
149     private int mVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
150     private int mDataRegState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
151     private int mDataRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
152     public boolean mCssSupported;
153     public int mRoamingIndicator;
154     public int mSystemIsInPrl;
155     public int mDefaultRoamingIndicator;
156     public int mReasonForDenial;
157     public int mMaxDataCalls;
158     public boolean mSendSetGsmBroadcastConfigResponse = true;
159     public boolean mSendGetSmscAddressResponse = true;
160 
161     private SignalStrength mSignalStrength;
162     private List<CellInfo> mCellInfoList = null;
163     private boolean mShouldReturnCellInfo = true;
164     private int[] mImsRegState;
165     private IccCardStatus mIccCardStatus;
166     private IccIoResult mIccIoResultForApduLogicalChannel;
167     private int mChannelId = IccOpenLogicalChannelResponse.INVALID_CHANNEL;
168 
169     private Object mDataRegStateResult;
170     private Object mVoiceRegStateResult;
171 
172     int mPausedResponseCount;
173     ArrayList<Message> mPausedResponses = new ArrayList<>();
174 
175     int mNextCallFailCause = CallFailCause.NORMAL_CLEARING;
176 
177     @UnsupportedAppUsage
178     private boolean mDcSuccess = true;
179     private SetupDataCallResult mSetupDataCallResult;
180     private boolean mIsRadioPowerFailResponse = false;
181     private boolean mIsReportSmsMemoryStatusFailResponse = false;
182 
183     public boolean mSetRadioPowerForEmergencyCall;
184     public boolean mSetRadioPowerAsSelectedPhoneForEmergencyCall;
185 
186     public boolean mCallWaitActivated = false;
187     private SrvccConnection[] mSrvccConnections;
188 
189     // mode for Icc Sim Authentication
190     private int mAuthenticationMode;
191 
192     private int[] mImsRegistrationInfo = new int[4];
193 
194     private boolean mN1ModeEnabled = false;
195     private boolean mVonrEnabled = false;
196 
197     //***** Constructor
198     public
SimulatedCommands()199     SimulatedCommands() {
200         super(null);  // Don't log statistics
201         mHandlerThread = new HandlerThread("SimulatedCommands");
202         mHandlerThread.start();
203         Looper looper = mHandlerThread.getLooper();
204 
205         simulatedCallState = new SimulatedGsmCallState(looper);
206 
207         setRadioState(TelephonyManager.RADIO_POWER_ON, false /* forceNotifyRegistrants */);
208         mSimLockedState = INITIAL_LOCK_STATE;
209         mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
210         mPinCode = DEFAULT_SIM_PIN_CODE;
211         mSimFdnEnabledState = INITIAL_FDN_STATE;
212         mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE);
213         mPin2Code = DEFAULT_SIM_PIN2_CODE;
214         mAuthenticationMode = ICC_AUTHENTICATION_MODE_DEFAULT;
215     }
216 
dispose()217     public void dispose() throws Exception {
218         if (mHandlerThread != null) {
219             mHandlerThread.quit();
220             mHandlerThread.join();
221         }
222     }
223 
log(String str)224     private void log(String str) {
225         Rlog.d(LOG_TAG, str);
226     }
227 
228     //***** CommandsInterface implementation
229 
230     @Override
getIccCardStatus(Message result)231     public void getIccCardStatus(Message result) {
232         SimulatedCommandsVerifier.getInstance().getIccCardStatus(result);
233         if (mIccCardStatus != null) {
234             resultSuccess(result, mIccCardStatus);
235         } else {
236             resultFail(result, null, new RuntimeException("IccCardStatus not set"));
237         }
238     }
239 
240     @Override
supplyIccPin(String pin, Message result)241     public void supplyIccPin(String pin, Message result)  {
242         if (mSimLockedState != SimLockState.REQUIRE_PIN) {
243             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: wrong state, state=" +
244                     mSimLockedState);
245             CommandException ex = new CommandException(
246                     CommandException.Error.PASSWORD_INCORRECT);
247             resultFail(result, null, ex);
248             return;
249         }
250 
251         if (pin != null && pin.equals(mPinCode)) {
252             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: success!");
253             mPinUnlockAttempts = 0;
254             mSimLockedState = SimLockState.NONE;
255             mIccStatusChangedRegistrants.notifyRegistrants();
256 
257             resultSuccess(result, null);
258 
259             return;
260         }
261 
262         if (result != null) {
263             mPinUnlockAttempts ++;
264 
265             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: failed! attempt=" +
266                     mPinUnlockAttempts);
267             if (mPinUnlockAttempts >= DEFAULT_PIN1_ATTEMPT) {
268                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: set state to REQUIRE_PUK");
269                 mSimLockedState = SimLockState.REQUIRE_PUK;
270             }
271 
272             CommandException ex = new CommandException(
273                     CommandException.Error.PASSWORD_INCORRECT);
274             resultFail(result, null, ex);
275         }
276     }
277 
278     @Override
supplyIccPuk(String puk, String newPin, Message result)279     public void supplyIccPuk(String puk, String newPin, Message result)  {
280         if (mSimLockedState != SimLockState.REQUIRE_PUK) {
281             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: wrong state, state=" +
282                     mSimLockedState);
283             CommandException ex = new CommandException(
284                     CommandException.Error.PASSWORD_INCORRECT);
285             resultFail(result, null, ex);
286             return;
287         }
288 
289         if (puk != null && puk.equals(SIM_PUK_CODE)) {
290             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!");
291             mSimLockedState = SimLockState.NONE;
292             mPukUnlockAttempts = 0;
293             mIccStatusChangedRegistrants.notifyRegistrants();
294 
295             resultSuccess(result, null);
296             return;
297         }
298 
299         if (result != null) {
300             mPukUnlockAttempts ++;
301 
302             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: failed! attempt=" +
303                     mPukUnlockAttempts);
304             if (mPukUnlockAttempts >= 10) {
305                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: set state to SIM_PERM_LOCKED");
306                 mSimLockedState = SimLockState.SIM_PERM_LOCKED;
307             }
308 
309             CommandException ex = new CommandException(
310                     CommandException.Error.PASSWORD_INCORRECT);
311             resultFail(result, null, ex);
312         }
313     }
314 
315     @Override
supplyIccPin2(String pin2, Message result)316     public void supplyIccPin2(String pin2, Message result)  {
317         if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) {
318             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: wrong state, state=" +
319                     mSimFdnEnabledState);
320             CommandException ex = new CommandException(
321                     CommandException.Error.PASSWORD_INCORRECT);
322             resultFail(result, null, ex);
323             return;
324         }
325 
326         if (pin2 != null && pin2.equals(mPin2Code)) {
327             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: success!");
328             mPin2UnlockAttempts = 0;
329             mSimFdnEnabledState = SimFdnState.NONE;
330 
331             resultSuccess(result, null);
332             return;
333         }
334 
335         if (result != null) {
336             mPin2UnlockAttempts ++;
337 
338             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: failed! attempt=" +
339                     mPin2UnlockAttempts);
340             if (mPin2UnlockAttempts >= DEFAULT_PIN2_ATTEMPT) {
341                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: set state to REQUIRE_PUK2");
342                 mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2;
343             }
344 
345             CommandException ex = new CommandException(
346                     CommandException.Error.PASSWORD_INCORRECT);
347             resultFail(result, null, ex);
348         }
349     }
350 
351     @Override
supplyIccPuk2(String puk2, String newPin2, Message result)352     public void supplyIccPuk2(String puk2, String newPin2, Message result)  {
353         if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) {
354             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: wrong state, state=" +
355                     mSimLockedState);
356             CommandException ex = new CommandException(
357                     CommandException.Error.PASSWORD_INCORRECT);
358             resultFail(result, null, ex);
359             return;
360         }
361 
362         if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) {
363             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: success!");
364             mSimFdnEnabledState = SimFdnState.NONE;
365             mPuk2UnlockAttempts = 0;
366 
367             resultSuccess(result, null);
368             return;
369         }
370 
371         if (result != null) {
372             mPuk2UnlockAttempts ++;
373 
374             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: failed! attempt=" +
375                     mPuk2UnlockAttempts);
376             if (mPuk2UnlockAttempts >= 10) {
377                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: set state to SIM_PERM_LOCKED");
378                 mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED;
379             }
380 
381             CommandException ex = new CommandException(
382                     CommandException.Error.PASSWORD_INCORRECT);
383             resultFail(result, null, ex);
384         }
385     }
386 
387     @Override
changeIccPin(String oldPin, String newPin, Message result)388     public void changeIccPin(String oldPin, String newPin, Message result)  {
389         if (oldPin != null && oldPin.equals(mPinCode)) {
390             mPinCode = newPin;
391             resultSuccess(result, null);
392 
393             return;
394         }
395 
396         Rlog.i(LOG_TAG, "[SimCmd] changeIccPin: pin failed!");
397 
398         CommandException ex = new CommandException(
399                 CommandException.Error.PASSWORD_INCORRECT);
400         resultFail(result, null, ex);
401     }
402 
403     @Override
changeIccPin2(String oldPin2, String newPin2, Message result)404     public void changeIccPin2(String oldPin2, String newPin2, Message result) {
405         if (oldPin2 != null && oldPin2.equals(mPin2Code)) {
406             mPin2Code = newPin2;
407             resultSuccess(result, null);
408 
409             return;
410         }
411 
412         Rlog.i(LOG_TAG, "[SimCmd] changeIccPin2: pin2 failed!");
413 
414         CommandException ex = new CommandException(
415                 CommandException.Error.PASSWORD_INCORRECT);
416         resultFail(result, null, ex);
417     }
418 
419     @Override
420     public void
changeBarringPassword(String facility, String oldPwd, String newPwd, Message result)421     changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
422         unimplemented(result);
423     }
424 
425     @Override
426     public void
setSuppServiceNotifications(boolean enable, Message result)427     setSuppServiceNotifications(boolean enable, Message result) {
428         resultSuccess(result, null);
429 
430         if (enable && mSsnNotifyOn) {
431             Rlog.w(LOG_TAG, "Supp Service Notifications already enabled!");
432         }
433 
434         mSsnNotifyOn = enable;
435     }
436 
437     @Override
queryFacilityLock(String facility, String pin, int serviceClass, Message result)438     public void queryFacilityLock(String facility, String pin,
439                                    int serviceClass, Message result) {
440         queryFacilityLockForApp(facility, pin, serviceClass, null, result);
441     }
442 
443     @Override
queryFacilityLockForApp(String facility, String pin, int serviceClass, String appId, Message result)444     public void queryFacilityLockForApp(String facility, String pin, int serviceClass,
445             String appId, Message result) {
446         if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
447             if (result != null) {
448                 int[] r = new int[1];
449                 r[0] = (mSimLockEnabled ? 1 : 0);
450                 Rlog.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is "
451                         + (r[0] == 0 ? "unlocked" : "locked"));
452                 resultSuccess(result, r);
453             }
454             return;
455         } else if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
456             if (result != null) {
457                 int[] r = new int[1];
458                 r[0] = (mSimFdnEnabled ? 1 : 0);
459                 Rlog.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is "
460                         + (r[0] == 0 ? "disabled" : "enabled"));
461                 resultSuccess(result, r);
462             }
463             return;
464         }
465 
466         unimplemented(result);
467     }
468 
469     @Override
setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass, Message result)470     public void setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass,
471             Message result) {
472         setFacilityLockForApp(facility, lockEnabled, pin, serviceClass, null, result);
473     }
474 
475     @Override
setFacilityLockForApp(String facility, boolean lockEnabled, String pin, int serviceClass, String appId, Message result)476     public void setFacilityLockForApp(String facility, boolean lockEnabled,
477                                  String pin, int serviceClass, String appId,
478                                  Message result) {
479         if (facility != null &&
480                 facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
481             if (pin != null && pin.equals(mPinCode)) {
482                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid");
483                 mSimLockEnabled = lockEnabled;
484 
485                 resultSuccess(result, null);
486 
487                 return;
488             }
489 
490             Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!");
491 
492             CommandException ex = new CommandException(
493                     CommandException.Error.GENERIC_FAILURE);
494             resultFail(result, null, ex);
495 
496             return;
497         }  else if (facility != null &&
498                 facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
499             if (pin != null && pin.equals(mPin2Code)) {
500                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid");
501                 mSimFdnEnabled = lockEnabled;
502 
503                 resultSuccess(result, null);
504 
505                 return;
506             }
507 
508             Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!");
509 
510             CommandException ex = new CommandException(
511                     CommandException.Error.GENERIC_FAILURE);
512             resultFail(result, null, ex);
513 
514             return;
515         }
516 
517         unimplemented(result);
518     }
519 
520     @Override
supplyNetworkDepersonalization(String netpin, Message result)521     public void supplyNetworkDepersonalization(String netpin, Message result) {
522         unimplemented(result);
523     }
524 
525     @Override
supplySimDepersonalization(PersoSubState persoType, String conrolKey, Message result)526     public void supplySimDepersonalization(PersoSubState persoType,
527             String conrolKey, Message result) {
528         unimplemented(result);
529     }
530 
531     /**
532      *  returned message
533      *  retMsg.obj = AsyncResult ar
534      *  ar.exception carries exception on failure
535      *  ar.userObject contains the original value of result.obj
536      *  ar.result contains a List of DriverCall
537      *      The ar.result List is sorted by DriverCall.index
538      */
539     @Override
getCurrentCalls(Message result)540     public void getCurrentCalls (Message result) {
541         SimulatedCommandsVerifier.getInstance().getCurrentCalls(result);
542         if ((mState == TelephonyManager.RADIO_POWER_ON) && !isSimLocked()) {
543             //Rlog.i("GSM", "[SimCmds] getCurrentCalls");
544             resultSuccess(result, simulatedCallState.getDriverCalls());
545         } else {
546             //Rlog.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!");
547             resultFail(result, null,
548                 new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE));
549         }
550     }
551 
552     /**
553      *  returned message
554      *  retMsg.obj = AsyncResult ar
555      *  ar.exception carries exception on failure
556      *  ar.userObject contains the original value of result.obj
557      *  ar.result contains a List of DataCallResponse
558      */
559     @Override
getDataCallList(Message result)560     public void getDataCallList(Message result) {
561         ArrayList<SetupDataCallResult> dcCallList = new ArrayList<>(0);
562         SimulatedCommandsVerifier.getInstance().getDataCallList(result);
563         if (mSetupDataCallResult != null) {
564             dcCallList.add(mSetupDataCallResult);
565         }
566         resultSuccess(result, dcCallList);
567     }
568 
569     /**
570      *  returned message
571      *  retMsg.obj = AsyncResult ar
572      *  ar.exception carries exception on failure
573      *  ar.userObject contains the original value of result.obj
574      *  ar.result is null on success and failure
575      *
576      * CLIR_DEFAULT     == on "use subscription default value"
577      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
578      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
579      */
580     @Override
dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, Message result)581     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
582                      boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
583         SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
584                 emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, result);
585         simulatedCallState.onDial(address);
586 
587         resultSuccess(result, null);
588     }
589 
590     /**
591      *  returned message
592      *  retMsg.obj = AsyncResult ar
593      *  ar.exception carries exception on failure
594      *  ar.userObject contains the original value of result.obj
595      *  ar.result is null on success and failure
596      *
597      * CLIR_DEFAULT     == on "use subscription default value"
598      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
599      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
600      */
601     @Override
dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result)602     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
603                      boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
604                      Message result) {
605         SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
606                 emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, uusInfo, result);
607         simulatedCallState.onDial(address);
608 
609         resultSuccess(result, null);
610     }
611 
612     @Override
getIMSI(Message result)613     public void getIMSI(Message result) {
614         getIMSIForApp(null, result);
615     }
616     /**
617      *  returned message
618      *  retMsg.obj = AsyncResult ar
619      *  ar.exception carries exception on failure
620      *  ar.userObject contains the original value of result.obj
621      *  ar.result is String containing IMSI on success
622      */
623     @Override
getIMSIForApp(String aid, Message result)624     public void getIMSIForApp(String aid, Message result) {
625         resultSuccess(result, "012345678901234");
626     }
627 
628     /**
629      * Hang up one individual connection.
630      *  returned message
631      *  retMsg.obj = AsyncResult ar
632      *  ar.exception carries exception on failure
633      *  ar.userObject contains the original value of result.obj
634      *  ar.result is null on success and failure
635      *
636      *  3GPP 22.030 6.5.5
637      *  "Releases a specific active call X"
638      */
639     @Override
hangupConnection(int gsmIndex, Message result)640     public void hangupConnection (int gsmIndex, Message result) {
641         boolean success;
642 
643         success = simulatedCallState.onChld('1', (char)('0'+gsmIndex));
644 
645         if (!success){
646             Rlog.i("GSM", "[SimCmd] hangupConnection: resultFail");
647             resultFail(result, null, new RuntimeException("Hangup Error"));
648         } else {
649             Rlog.i("GSM", "[SimCmd] hangupConnection: resultSuccess");
650             resultSuccess(result, null);
651         }
652     }
653 
654     /**
655      * 3GPP 22.030 6.5.5
656      *  "Releases all held calls or sets User Determined User Busy (UDUB)
657      *   for a waiting call."
658      *  ar.exception carries exception on failure
659      *  ar.userObject contains the original value of result.obj
660      *  ar.result is null on success and failure
661      */
662     @Override
hangupWaitingOrBackground(Message result)663     public void hangupWaitingOrBackground (Message result) {
664         boolean success;
665 
666         success = simulatedCallState.onChld('0', '\0');
667 
668         if (!success){
669             resultFail(result, null, new RuntimeException("Hangup Error"));
670         } else {
671             resultSuccess(result, null);
672         }
673     }
674 
675     /**
676      * 3GPP 22.030 6.5.5
677      * "Releases all active calls (if any exist) and accepts
678      *  the other (held or waiting) call."
679      *
680      *  ar.exception carries exception on failure
681      *  ar.userObject contains the original value of result.obj
682      *  ar.result is null on success and failure
683      */
684     @Override
hangupForegroundResumeBackground(Message result)685     public void hangupForegroundResumeBackground (Message result) {
686         boolean success;
687 
688         success = simulatedCallState.onChld('1', '\0');
689 
690         if (!success){
691             resultFail(result, null, new RuntimeException("Hangup Error"));
692         } else {
693             resultSuccess(result, null);
694         }
695     }
696 
697     /**
698      * 3GPP 22.030 6.5.5
699      * "Places all active calls (if any exist) on hold and accepts
700      *  the other (held or waiting) call."
701      *
702      *  ar.exception carries exception on failure
703      *  ar.userObject contains the original value of result.obj
704      *  ar.result is null on success and failure
705      */
706     @Override
switchWaitingOrHoldingAndActive(Message result)707     public void switchWaitingOrHoldingAndActive (Message result) {
708         boolean success;
709 
710         success = simulatedCallState.onChld('2', '\0');
711 
712         if (!success){
713             resultFail(result, null, new RuntimeException("Hangup Error"));
714         } else {
715             resultSuccess(result, null);
716         }
717     }
718 
719     /**
720      * 3GPP 22.030 6.5.5
721      * "Adds a held call to the conversation"
722      *
723      *  ar.exception carries exception on failure
724      *  ar.userObject contains the original value of result.obj
725      *  ar.result is null on success and failure
726      */
727     @Override
conference(Message result)728     public void conference (Message result) {
729         boolean success;
730 
731         success = simulatedCallState.onChld('3', '\0');
732 
733         if (!success){
734             resultFail(result, null, new RuntimeException("Hangup Error"));
735         } else {
736             resultSuccess(result, null);
737         }
738     }
739 
740     /**
741      * 3GPP 22.030 6.5.5
742      * "Connects the two calls and disconnects the subscriber from both calls"
743      *
744      *  ar.exception carries exception on failure
745      *  ar.userObject contains the original value of result.obj
746      *  ar.result is null on success and failure
747      */
748     @Override
explicitCallTransfer(Message result)749     public void explicitCallTransfer (Message result) {
750         boolean success;
751 
752         success = simulatedCallState.onChld('4', '\0');
753 
754         if (!success){
755             resultFail(result, null, new RuntimeException("Hangup Error"));
756         } else {
757             resultSuccess(result, null);
758         }
759     }
760 
761     /**
762      * 3GPP 22.030 6.5.5
763      * "Places all active calls on hold except call X with which
764      *  communication shall be supported."
765      */
766     @Override
separateConnection(int gsmIndex, Message result)767     public void separateConnection (int gsmIndex, Message result) {
768         boolean success;
769 
770         char ch = (char)(gsmIndex + '0');
771         success = simulatedCallState.onChld('2', ch);
772 
773         if (!success){
774             resultFail(result, null, new RuntimeException("Hangup Error"));
775         } else {
776             resultSuccess(result, null);
777         }
778     }
779 
780     /**
781      *
782      *  ar.exception carries exception on failure
783      *  ar.userObject contains the original value of result.obj
784      *  ar.result is null on success and failure
785      */
786     @UnsupportedAppUsage
787     @Override
acceptCall(Message result)788     public void acceptCall (Message result) {
789         boolean success;
790 
791         SimulatedCommandsVerifier.getInstance().acceptCall(result);
792         success = simulatedCallState.onAnswer();
793 
794         if (!success){
795             resultFail(result, null, new RuntimeException("Hangup Error"));
796         } else {
797             resultSuccess(result, null);
798         }
799     }
800 
801     /**
802      *  also known as UDUB
803      *  ar.exception carries exception on failure
804      *  ar.userObject contains the original value of result.obj
805      *  ar.result is null on success and failure
806      */
807     @Override
rejectCall(Message result)808     public void rejectCall (Message result) {
809         boolean success;
810 
811         success = simulatedCallState.onChld('0', '\0');
812 
813         if (!success){
814             resultFail(result, null, new RuntimeException("Hangup Error"));
815         } else {
816             resultSuccess(result, null);
817         }
818     }
819 
820     /**
821      * cause code returned as Integer in Message.obj.response
822      * Returns integer cause code defined in TS 24.008
823      * Annex H or closest approximation.
824      * Most significant codes:
825      * - Any defined in 22.001 F.4 (for generating busy/congestion)
826      * - Cause 68: ACM >= ACMMax
827      */
828     @Override
getLastCallFailCause(Message result)829     public void getLastCallFailCause (Message result) {
830         LastCallFailCause mFailCause = new LastCallFailCause();
831         mFailCause.causeCode = mNextCallFailCause;
832         resultSuccess(result, mFailCause);
833     }
834 
835     @Override
setMute(boolean enableMute, Message result)836     public void setMute (boolean enableMute, Message result) {unimplemented(result);}
837 
838     @Override
getMute(Message result)839     public void getMute (Message result) {unimplemented(result);}
840 
setSignalStrength(SignalStrength signalStrength)841     public void setSignalStrength(SignalStrength signalStrength) {
842         mSignalStrength = signalStrength;
843     }
844 
845     @Override
getSignalStrength(Message result)846     public void getSignalStrength (Message result) {
847         if (mSignalStrength == null) {
848             mSignalStrength = new SignalStrength(
849                     new CellSignalStrengthCdma(),
850                     new CellSignalStrengthGsm(20, 0, CellInfo.UNAVAILABLE),
851                     new CellSignalStrengthWcdma(),
852                     new CellSignalStrengthTdscdma(),
853                     new CellSignalStrengthLte(),
854                     new CellSignalStrengthNr());
855         }
856         resultSuccess(result, mSignalStrength);
857     }
858 
859      /**
860      * Assign a specified band for RF configuration.
861      *
862      * @param bandMode one of BM_*_BAND
863      * @param result is callback message
864      */
865     @Override
setBandMode(int bandMode, Message result)866     public void setBandMode (int bandMode, Message result) {
867         resultSuccess(result, null);
868     }
869 
870     /**
871      * Query the list of band mode supported by RF.
872      *
873      * @param result is callback message
874      *        ((AsyncResult)response.obj).result  is an int[] where int[0] is
875      *        the size of the array and the rest of each element representing
876      *        one available BM_*_BAND
877      */
878     @Override
queryAvailableBandMode(Message result)879     public void queryAvailableBandMode (Message result) {
880         int ret[] = new int [4];
881 
882         ret[0] = 4;
883         ret[1] = Phone.BM_US_BAND;
884         ret[2] = Phone.BM_JPN_BAND;
885         ret[3] = Phone.BM_AUS_BAND;
886 
887         resultSuccess(result, ret);
888     }
889 
890     /**
891      * {@inheritDoc}
892      */
893     @Override
sendTerminalResponse(String contents, Message response)894     public void sendTerminalResponse(String contents, Message response) {
895         resultSuccess(response, null);
896     }
897 
898     /**
899      * {@inheritDoc}
900      */
901     @Override
sendEnvelope(String contents, Message response)902     public void sendEnvelope(String contents, Message response) {
903         resultSuccess(response, null);
904     }
905 
906     /**
907      * {@inheritDoc}
908      */
909     @Override
sendEnvelopeWithStatus(String contents, Message response)910     public void sendEnvelopeWithStatus(String contents, Message response) {
911         resultSuccess(response, null);
912     }
913 
914     /**
915      * {@inheritDoc}
916      */
917     @Override
handleCallSetupRequestFromSim( boolean accept, Message response)918     public void handleCallSetupRequestFromSim(
919             boolean accept, Message response) {
920         resultSuccess(response, null);
921     }
922 
setVoiceRadioTech(int voiceRadioTech)923     public void setVoiceRadioTech(int voiceRadioTech) {
924         mVoiceRadioTech = voiceRadioTech;
925     }
926 
setVoiceRegState(int voiceRegState)927     public void setVoiceRegState(int voiceRegState) {
928         mVoiceRegState = voiceRegState;
929     }
930 
931     /**
932      * response.obj.result is an String[14]
933      * See ril.h for details
934      *
935      * Please note that registration state 4 ("unknown") is treated
936      * as "out of service" above
937      */
938     @Override
getVoiceRegistrationState(Message result)939     public void getVoiceRegistrationState(Message result) {
940         mGetVoiceRegistrationStateCallCount.incrementAndGet();
941 
942         Object ret = mVoiceRegStateResult;
943         if (ret == null) {
944             ret = new VoiceRegStateResult();
945             ((VoiceRegStateResult) ret).regState = mVoiceRegState;
946             ((VoiceRegStateResult) ret).rat = mVoiceRadioTech;
947             ((VoiceRegStateResult) ret).cssSupported = mCssSupported;
948             ((VoiceRegStateResult) ret).roamingIndicator = mRoamingIndicator;
949             ((VoiceRegStateResult) ret).systemIsInPrl = mSystemIsInPrl;
950             ((VoiceRegStateResult) ret).defaultRoamingIndicator = mDefaultRoamingIndicator;
951             ((VoiceRegStateResult) ret).reasonForDenial = mReasonForDenial;
952         }
953 
954         resultSuccess(result, ret);
955     }
956 
957     private final AtomicInteger mGetVoiceRegistrationStateCallCount = new AtomicInteger(0);
958 
959     @VisibleForTesting
getGetVoiceRegistrationStateCallCount()960     public int getGetVoiceRegistrationStateCallCount() {
961         return mGetVoiceRegistrationStateCallCount.get();
962     }
963 
setDataRadioTech(int radioTech)964     public void setDataRadioTech(int radioTech) {
965         mDataRadioTech = radioTech;
966     }
967 
setDataRegState(int dataRegState)968     public void setDataRegState(int dataRegState) {
969         mDataRegState = dataRegState;
970     }
971 
972     @Override
getDataRegistrationState(Message result)973     public void getDataRegistrationState(Message result) {
974         mGetDataRegistrationStateCallCount.incrementAndGet();
975 
976         Object ret = mDataRegStateResult;
977         if (ret == null) {
978             ret = new DataRegStateResult();
979             ((DataRegStateResult) ret).base.regState = mDataRegState;
980             ((DataRegStateResult) ret).base.rat = mDataRadioTech;
981             ((DataRegStateResult) ret).base.maxDataCalls = mMaxDataCalls;
982             ((DataRegStateResult) ret).base.reasonDataDenied = mReasonForDenial;
983         }
984 
985         resultSuccess(result, ret);
986     }
987 
988     private final AtomicInteger mGetDataRegistrationStateCallCount = new AtomicInteger(0);
989 
990     @VisibleForTesting
getGetDataRegistrationStateCallCount()991     public int getGetDataRegistrationStateCallCount() {
992         return mGetDataRegistrationStateCallCount.get();
993     }
994 
995     /**
996      * response.obj.result is a String[3]
997      * response.obj.result[0] is long alpha or null if unregistered
998      * response.obj.result[1] is short alpha or null if unregistered
999      * response.obj.result[2] is numeric or null if unregistered
1000      */
1001     @Override
getOperator(Message result)1002     public void getOperator(Message result) {
1003         mGetOperatorCallCount.incrementAndGet();
1004         String[] ret = new String[3];
1005 
1006         ret[0] = FAKE_LONG_NAME;
1007         ret[1] = FAKE_SHORT_NAME;
1008         ret[2] = FAKE_MCC_MNC;
1009 
1010         resultSuccess(result, ret);
1011     }
1012 
1013     private final AtomicInteger mGetOperatorCallCount = new AtomicInteger(0);
1014 
1015     @VisibleForTesting
getGetOperatorCallCount()1016     public int getGetOperatorCallCount() {
1017         return mGetOperatorCallCount.get();
1018     }
1019 
1020     /**
1021      *  ar.exception carries exception on failure
1022      *  ar.userObject contains the original value of result.obj
1023      *  ar.result is null on success and failure
1024      */
1025     @Override
sendDtmf(char c, Message result)1026     public void sendDtmf(char c, Message result) {
1027         resultSuccess(result, null);
1028     }
1029 
1030     /**
1031      *  ar.exception carries exception on failure
1032      *  ar.userObject contains the original value of result.obj
1033      *  ar.result is null on success and failure
1034      */
1035     @Override
startDtmf(char c, Message result)1036     public void startDtmf(char c, Message result) {
1037         resultSuccess(result, null);
1038     }
1039 
1040     /**
1041      *  ar.exception carries exception on failure
1042      *  ar.userObject contains the original value of result.obj
1043      *  ar.result is null on success and failure
1044      */
1045     @Override
stopDtmf(Message result)1046     public void stopDtmf(Message result) {
1047         resultSuccess(result, null);
1048     }
1049 
1050     /**
1051      *  ar.exception carries exception on failure
1052      *  ar.userObject contains the original value of result.obj
1053      *  ar.result is null on success and failure
1054      */
1055     @Override
sendBurstDtmf(String dtmfString, int on, int off, Message result)1056     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
1057         SimulatedCommandsVerifier.getInstance().sendBurstDtmf(dtmfString, on, off, result);
1058         resultSuccess(result, null);
1059     }
1060 
1061     /**
1062      * smscPDU is smsc address in PDU form GSM BCD format prefixed
1063      *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
1064      * pdu is SMS in PDU format as an ASCII hex string
1065      *      less the SMSC address
1066      */
1067     @Override
sendSMS(String smscPDU, String pdu, Message result)1068     public void sendSMS (String smscPDU, String pdu, Message result) {
1069         SimulatedCommandsVerifier.getInstance().sendSMS(smscPDU, pdu, result);
1070         resultSuccess(result, new SmsResponse(0 /*messageRef*/, null, SmsResponse.NO_ERROR_CODE));
1071     }
1072 
1073     /**
1074      * Send an SMS message, Identical to sendSMS,
1075      * except that more messages are expected to be sent soon
1076      * smscPDU is smsc address in PDU form GSM BCD format prefixed
1077      *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
1078      * pdu is SMS in PDU format as an ASCII hex string
1079      *      less the SMSC address
1080      */
1081     @Override
sendSMSExpectMore(String smscPDU, String pdu, Message result)1082     public void sendSMSExpectMore (String smscPDU, String pdu, Message result) {
1083         SimulatedCommandsVerifier.getInstance().sendSMSExpectMore(smscPDU, pdu, result);
1084         resultSuccess(result, new SmsResponse(0 /*messageRef*/, null, SmsResponse.NO_ERROR_CODE));
1085     }
1086 
1087     @Override
deleteSmsOnSim(int index, Message response)1088     public void deleteSmsOnSim(int index, Message response) {
1089         Rlog.d(LOG_TAG, "Delete message at index " + index);
1090         unimplemented(response);
1091     }
1092 
1093     @Override
deleteSmsOnRuim(int index, Message response)1094     public void deleteSmsOnRuim(int index, Message response) {
1095         Rlog.d(LOG_TAG, "Delete RUIM message at index " + index);
1096         unimplemented(response);
1097     }
1098 
1099     @Override
writeSmsToSim(int status, String smsc, String pdu, Message response)1100     public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
1101         Rlog.d(LOG_TAG, "Write SMS to SIM with status " + status);
1102         unimplemented(response);
1103     }
1104 
1105     @Override
writeSmsToRuim(int status, byte[] pdu, Message response)1106     public void writeSmsToRuim(int status, byte[] pdu, Message response) {
1107         Rlog.d(LOG_TAG, "Write SMS to RUIM with status " + status);
1108         unimplemented(response);
1109     }
1110 
setDataCallResult(final boolean success, final SetupDataCallResult dcResult)1111     public void setDataCallResult(final boolean success, final SetupDataCallResult dcResult) {
1112         mSetupDataCallResult = dcResult;
1113         mDcSuccess = success;
1114     }
1115 
triggerNITZupdate(String NITZStr)1116     public void triggerNITZupdate(String NITZStr) {
1117         if (NITZStr != null) {
1118             mNITZTimeRegistrant.notifyRegistrant(new AsyncResult (null, new Object[]{NITZStr,
1119                     SystemClock.elapsedRealtime()}, null));
1120         }
1121     }
1122 
triggerNITZupdate(String NITZStr, long ageMs)1123     public void triggerNITZupdate(String NITZStr, long ageMs) {
1124         if (NITZStr != null) {
1125             mNITZTimeRegistrant.notifyRegistrant(new AsyncResult (null, new Object[]{NITZStr,
1126                     SystemClock.elapsedRealtime(), ageMs}, null));
1127         }
1128     }
1129 
1130     @Override
setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId, NetworkSliceInfo sliceInfo, TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, Message result)1131     public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean allowRoaming,
1132             int reason, LinkProperties linkProperties, int pduSessionId, NetworkSliceInfo sliceInfo,
1133             TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, Message result) {
1134 
1135         SimulatedCommandsVerifier.getInstance().setupDataCall(accessNetworkType, dataProfile,
1136                 allowRoaming, reason, linkProperties, pduSessionId, sliceInfo, trafficDescriptor,
1137                 matchAllRuleAllowed, result);
1138 
1139         if (mSetupDataCallResult == null) {
1140             try {
1141                 mSetupDataCallResult = new SetupDataCallResult();
1142                 mSetupDataCallResult.cause = 0;
1143                 mSetupDataCallResult.suggestedRetryTime = -1;
1144                 mSetupDataCallResult.cid = 1;
1145                 mSetupDataCallResult.active = 2;
1146                 mSetupDataCallResult.type = PdpProtocolType.IP;
1147                 mSetupDataCallResult.ifname = "rmnet_data7";
1148                 mSetupDataCallResult.addresses = new ArrayList<>(List.of("12.34.56.78"));
1149                 mSetupDataCallResult.dnses = new ArrayList<>(List.of("98.76.54.32"));
1150                 mSetupDataCallResult.gateways = new ArrayList<>(List.of("11.22.33.44"));
1151                 mSetupDataCallResult.pcscf = new ArrayList<>(List.of(
1152                         "fd00:976a:c305:1d::8 fd00:976a:c202:1d::7 fd00:976a:c305:1d::5"));
1153                 mSetupDataCallResult.mtu = 1440;
1154             } catch (Exception e) {
1155                 Rlog.e(LOG_TAG, "setupDataCall: e=" + e);
1156             }
1157         }
1158 
1159         DataCallResponse response = RILUtils.convertHalDataCallResult(mSetupDataCallResult);
1160         if (mDcSuccess) {
1161             resultSuccess(result, response);
1162         } else {
1163             resultFail(result, response, new RuntimeException("Setup data call failed!"));
1164         }
1165     }
1166 
1167     @Override
deactivateDataCall(int cid, int reason, Message result)1168     public void deactivateDataCall(int cid, int reason, Message result) {
1169         SimulatedCommandsVerifier.getInstance().deactivateDataCall(cid, reason, result);
1170         resultSuccess(result, RadioError.NONE);
1171     }
1172 
1173     @Override
setPreferredNetworkType(int networkType , Message result)1174     public void setPreferredNetworkType(int networkType , Message result) {
1175         SimulatedCommandsVerifier.getInstance().setPreferredNetworkType(networkType, result);
1176         mPreferredNetworkType = networkType;
1177         resultSuccess(result, null);
1178     }
1179 
1180     @Override
getPreferredNetworkType(Message result)1181     public void getPreferredNetworkType(Message result) {
1182         SimulatedCommandsVerifier.getInstance().getPreferredNetworkType(result);
1183         int ret[] = new int[1];
1184 
1185         ret[0] = mPreferredNetworkType;
1186         resultSuccess(result, ret);
1187     }
1188 
1189     @Override
setAllowedNetworkTypesBitmap( @elephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message response)1190     public void setAllowedNetworkTypesBitmap(
1191             @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message response) {
1192         SimulatedCommandsVerifier.getInstance()
1193             .setAllowedNetworkTypesBitmap(networkTypeBitmask, response);
1194         mAllowedNetworkType = networkTypeBitmask;
1195         resultSuccess(response, null);
1196     }
1197 
1198     @Override
getAllowedNetworkTypesBitmap(Message response)1199     public void getAllowedNetworkTypesBitmap(Message response) {
1200         SimulatedCommandsVerifier.getInstance().getAllowedNetworkTypesBitmap(response);
1201         int[] ret = new int[1];
1202 
1203         ret[0] = mAllowedNetworkType;
1204         resultSuccess(response, ret);
1205     }
1206 
1207     @Override
setLocationUpdates(boolean enable, Message response)1208     public void setLocationUpdates(boolean enable, Message response) {
1209         SimulatedCommandsVerifier.getInstance().setLocationUpdates(enable, response);
1210         resultSuccess(response, null);
1211     }
1212 
1213     @Override
getSmscAddress(Message result)1214     public void getSmscAddress(Message result) {
1215         SimulatedCommandsVerifier.getInstance().getSmscAddress(result);
1216         if (mSendGetSmscAddressResponse) {
1217             unimplemented(result);
1218         }
1219     }
1220 
1221     @Override
setSmscAddress(String address, Message result)1222     public void setSmscAddress(String address, Message result) {
1223         unimplemented(result);
1224     }
1225 
1226     @Override
reportSmsMemoryStatus(boolean available, Message result)1227     public void reportSmsMemoryStatus(boolean available, Message result) {
1228         if (!mIsReportSmsMemoryStatusFailResponse) {
1229             resultSuccess(result, null);
1230         } else {
1231             CommandException ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
1232             resultFail(result, null, ex);
1233         }
1234         SimulatedCommandsVerifier.getInstance().reportSmsMemoryStatus(available, result);
1235     }
1236 
setReportSmsMemoryStatusFailResponse(boolean fail)1237     public void setReportSmsMemoryStatusFailResponse(boolean fail) {
1238         mIsReportSmsMemoryStatusFailResponse = fail;
1239     }
1240 
1241     @Override
reportStkServiceIsRunning(Message result)1242     public void reportStkServiceIsRunning(Message result) {
1243         resultSuccess(result, null);
1244     }
1245 
1246     @Override
getCdmaSubscriptionSource(Message result)1247     public void getCdmaSubscriptionSource(Message result) {
1248         unimplemented(result);
1249     }
1250 
isSimLocked()1251     private boolean isSimLocked() {
1252         if (mSimLockedState != SimLockState.NONE) {
1253             return true;
1254         }
1255         return false;
1256     }
1257 
1258     @Override
setRadioPower(boolean on, boolean forEmergencyCall, boolean preferredForEmergencyCall, Message result)1259     public void setRadioPower(boolean on, boolean forEmergencyCall,
1260             boolean preferredForEmergencyCall, Message result) {
1261         if (mIsRadioPowerFailResponse) {
1262             resultFail(result, null, new RuntimeException("setRadioPower failed!"));
1263             return;
1264         }
1265 
1266         mSetRadioPowerForEmergencyCall = forEmergencyCall;
1267         mSetRadioPowerAsSelectedPhoneForEmergencyCall = preferredForEmergencyCall;
1268 
1269         if(on) {
1270             setRadioState(TelephonyManager.RADIO_POWER_ON, false /* forceNotifyRegistrants */);
1271         } else {
1272             setRadioState(TelephonyManager.RADIO_POWER_OFF, false /* forceNotifyRegistrants */);
1273         }
1274         resultSuccess(result, null);
1275     }
1276 
1277 
1278     @Override
acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result)1279     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
1280         unimplemented(result);
1281         SimulatedCommandsVerifier.getInstance().
1282                 acknowledgeLastIncomingGsmSms(success, cause, result);
1283     }
1284 
1285     @Override
acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result)1286     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
1287         unimplemented(result);
1288     }
1289 
1290     @Override
acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result)1291     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
1292             Message result) {
1293         unimplemented(result);
1294     }
1295 
1296     @Override
iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, Message response)1297     public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
1298             String pin2, Message response) {
1299         iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, null, response);
1300     }
1301 
1302     /**
1303      * parameters equivalent to 27.007 AT+CRSM command
1304      * response.obj will be an AsyncResult
1305      * response.obj.userObj will be a SimIoResult on success
1306      */
1307     @Override
iccIOForApp(int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, String aid, Message result)1308     public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
1309                        int p3, String data, String pin2, String aid, Message result) {
1310         unimplemented(result);
1311     }
1312 
1313     /**
1314      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1315      * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
1316      *
1317      * @param response is callback message
1318      */
1319     @Override
queryCLIP(Message response)1320     public void queryCLIP(Message response) { unimplemented(response); }
1321 
1322 
1323     /**
1324      * response.obj will be a an int[2]
1325      *
1326      * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
1327      *  0 presentation indicator is used according to the subscription of the CLIR service
1328      *  1 CLIR invocation
1329      *  2 CLIR suppression
1330      *
1331      * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
1332      *  0 CLIR not provisioned
1333      *  1 CLIR provisioned in permanent mode
1334      *  2 unknown (e.g. no network, etc.)
1335      *  3 CLIR temporary mode presentation restricted
1336      *  4 CLIR temporary mode presentation allowed
1337      */
1338 
1339     @Override
getCLIR(Message result)1340     public void getCLIR(Message result) {unimplemented(result);}
1341 
1342     /**
1343      * clirMode is one of the CLIR_* constants above
1344      *
1345      * response.obj is null
1346      */
1347 
1348     @Override
setCLIR(int clirMode, Message result)1349     public void setCLIR(int clirMode, Message result) {unimplemented(result);}
1350 
1351     /**
1352      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1353      * 0 for disabled, 1 for enabled.
1354      *
1355      * @param serviceClass is a sum of SERVICE_CLASS_*
1356      * @param response is callback message
1357      */
1358 
1359     @Override
queryCallWaiting(int serviceClass, Message response)1360     public void queryCallWaiting(int serviceClass, Message response) {
1361         if (response != null && serviceClass == SERVICE_CLASS_NONE) {
1362             int[] r = new int[2];
1363             r[0] = (mCallWaitActivated ? 1 : 0);
1364             r[1] = (mCallWaitActivated ? SERVICE_CLASS_VOICE : SERVICE_CLASS_NONE);
1365             resultSuccess(response, r);
1366             return;
1367         }
1368 
1369         unimplemented(response);
1370     }
1371 
1372     /**
1373      * @param enable is true to enable, false to disable
1374      * @param serviceClass is a sum of SERVICE_CLASS_*
1375      * @param response is callback message
1376      */
1377     @Override
setCallWaiting(boolean enable, int serviceClass, Message response)1378     public void setCallWaiting(boolean enable, int serviceClass,
1379             Message response) {
1380         if ((serviceClass & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE) {
1381             mCallWaitActivated = enable;
1382         }
1383         if (response != null) {
1384             resultSuccess(response, null);
1385         }
1386     }
1387 
1388     /**
1389      * @param action is one of CF_ACTION_*
1390      * @param cfReason is one of CF_REASON_*
1391      * @param serviceClass is a sum of SERVICE_CLASSS_*
1392      */
1393     @Override
setCallForward(int action, int cfReason, int serviceClass, String number, int timeSeconds, Message result)1394     public void setCallForward(int action, int cfReason, int serviceClass,
1395             String number, int timeSeconds, Message result) {
1396         SimulatedCommandsVerifier.getInstance().setCallForward(action, cfReason, serviceClass,
1397                 number, timeSeconds, result);
1398         resultSuccess(result, null);
1399     }
1400 
1401     /**
1402      * cfReason is one of CF_REASON_*
1403      *
1404      * ((AsyncResult)response.obj).result will be an array of
1405      * CallForwardInfo's
1406      *
1407      * An array of length 0 means "disabled for all codes"
1408      */
1409     @Override
queryCallForwardStatus(int cfReason, int serviceClass, String number, Message result)1410     public void queryCallForwardStatus(int cfReason, int serviceClass,
1411             String number, Message result) {
1412         SimulatedCommandsVerifier.getInstance().queryCallForwardStatus(cfReason, serviceClass,
1413                 number, result);
1414         resultSuccess(result, null);
1415     }
1416 
1417     @Override
setNetworkSelectionModeAutomatic(Message result)1418     public void setNetworkSelectionModeAutomatic(Message result) {
1419         SimulatedCommandsVerifier.getInstance().setNetworkSelectionModeAutomatic(result);
1420         mMockNetworkSelectionMode = 0;
1421     }
1422     @Override
exitEmergencyCallbackMode(Message result)1423     public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
1424     @Override
setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result)1425     public void setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result) {
1426         SimulatedCommandsVerifier.getInstance().setNetworkSelectionModeManual(
1427                 operatorNumeric, ran, result);
1428         mMockNetworkSelectionMode = 1;
1429     }
1430 
1431     /**
1432      * Queries whether the current network selection mode is automatic
1433      * or manual
1434      *
1435      * ((AsyncResult)response.obj).result  is an int[] with element [0] being
1436      * a 0 for automatic selection and a 1 for manual selection
1437      */
1438 
1439     @Override
getNetworkSelectionMode(Message result)1440     public void getNetworkSelectionMode(Message result) {
1441         SimulatedCommandsVerifier.getInstance().getNetworkSelectionMode(result);
1442         getNetworkSelectionModeCallCount.incrementAndGet();
1443         int ret[] = new int[1];
1444 
1445         ret[0] = mMockNetworkSelectionMode;
1446         resultSuccess(result, ret);
1447     }
1448 
1449     /** 0 for automatic selection and a 1 for manual selection. */
1450     private int mMockNetworkSelectionMode = 0;
1451 
1452     private final AtomicInteger getNetworkSelectionModeCallCount = new AtomicInteger(0);
1453 
1454     @VisibleForTesting
getGetNetworkSelectionModeCallCount()1455     public int getGetNetworkSelectionModeCallCount() {
1456         return getNetworkSelectionModeCallCount.get();
1457     }
1458 
1459     /**
1460      * Queries the currently available networks
1461      *
1462      * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
1463      */
1464     @Override
getAvailableNetworks(Message result)1465     public void getAvailableNetworks(Message result) {
1466         unimplemented(result);
1467     }
1468 
1469     /**
1470      * Starts a network scan
1471      */
1472     @Override
startNetworkScan(NetworkScanRequest nsr, Message result)1473     public void startNetworkScan(NetworkScanRequest nsr, Message result) {
1474         unimplemented(result);
1475     }
1476 
1477     /**
1478      * Stops an ongoing network scan
1479      */
1480     @Override
stopNetworkScan(Message result)1481     public void stopNetworkScan(Message result) {
1482         unimplemented(result);
1483     }
1484 
1485     @Override
getBasebandVersion(Message result)1486     public void getBasebandVersion (Message result) {
1487         SimulatedCommandsVerifier.getInstance().getBasebandVersion(result);
1488         resultSuccess(result, "SimulatedCommands");
1489     }
1490 
1491     /**
1492      * Simulates an Stk Call Control Alpha message
1493      * @param alphaString Alpha string to send.
1494      */
triggerIncomingStkCcAlpha(String alphaString)1495     public void triggerIncomingStkCcAlpha(String alphaString) {
1496         if (mCatCcAlphaRegistrant != null) {
1497             mCatCcAlphaRegistrant.notifyResult(alphaString);
1498         }
1499     }
1500 
sendStkCcAplha(String alphaString)1501     public void sendStkCcAplha(String alphaString) {
1502         triggerIncomingStkCcAlpha(alphaString);
1503     }
1504 
1505     /**
1506      * Simulates an incoming USSD message
1507      * @param statusCode  Status code string. See <code>setOnUSSD</code>
1508      * in CommandsInterface.java
1509      * @param message Message text to send or null if none
1510      */
1511     @Override
triggerIncomingUssd(String statusCode, String message)1512     public void triggerIncomingUssd(String statusCode, String message) {
1513         if (mUSSDRegistrant != null) {
1514             String[] result = {statusCode, message};
1515             mUSSDRegistrant.notifyResult(result);
1516         }
1517     }
1518 
1519 
1520     @Override
sendUSSD(String ussdString, Message result)1521     public void sendUSSD (String ussdString, Message result) {
1522 
1523         // We simulate this particular sequence
1524         if (ussdString.equals("#646#")) {
1525             resultSuccess(result, null);
1526 
1527             // 0 == USSD-Notify
1528             triggerIncomingUssd("0", "You have NNN minutes remaining.");
1529         } else {
1530             resultSuccess(result, null);
1531 
1532             triggerIncomingUssd("0", "All Done");
1533         }
1534     }
1535 
1536     // inherited javadoc suffices
1537     @Override
cancelPendingUssd(Message response)1538     public void cancelPendingUssd (Message response) {
1539         resultSuccess(response, null);
1540     }
1541 
1542     @Override
setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo, Message response)1543     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
1544                                                 Message response) {
1545         // Just echo back data
1546         if (response != null) {
1547             AsyncResult.forMessage(response).result = imsiEncryptionInfo;
1548             response.sendToTarget();
1549         }
1550     }
1551 
1552     //***** SimulatedRadioControl
1553 
1554 
1555     /** Start the simulated phone ringing */
1556     @Override
1557     public void
triggerRing(String number)1558     triggerRing(String number) {
1559         simulatedCallState.triggerRing(number);
1560         mCallStateRegistrants.notifyRegistrants();
1561     }
1562 
1563     @Override
1564     public void
progressConnectingCallState()1565     progressConnectingCallState() {
1566         simulatedCallState.progressConnectingCallState();
1567         mCallStateRegistrants.notifyRegistrants();
1568     }
1569 
1570     /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
1571     @Override
1572     public void
progressConnectingToActive()1573     progressConnectingToActive() {
1574         simulatedCallState.progressConnectingToActive();
1575         mCallStateRegistrants.notifyRegistrants();
1576     }
1577 
1578     /** automatically progress mobile originated calls to ACTIVE.
1579      *  default to true
1580      */
1581     @Override
1582     public void
setAutoProgressConnectingCall(boolean b)1583     setAutoProgressConnectingCall(boolean b) {
1584         simulatedCallState.setAutoProgressConnectingCall(b);
1585     }
1586 
1587     @Override
1588     public void
setNextDialFailImmediately(boolean b)1589     setNextDialFailImmediately(boolean b) {
1590         simulatedCallState.setNextDialFailImmediately(b);
1591     }
1592 
1593     @Override
1594     public void
setNextCallFailCause(int gsmCause)1595     setNextCallFailCause(int gsmCause) {
1596         mNextCallFailCause = gsmCause;
1597     }
1598 
1599     @Override
1600     public void
triggerHangupForeground()1601     triggerHangupForeground() {
1602         simulatedCallState.triggerHangupForeground();
1603         mCallStateRegistrants.notifyRegistrants();
1604     }
1605 
1606     /** hangup holding calls */
1607     @Override
1608     public void
triggerHangupBackground()1609     triggerHangupBackground() {
1610         simulatedCallState.triggerHangupBackground();
1611         mCallStateRegistrants.notifyRegistrants();
1612     }
1613 
1614     @Override
triggerSsn(int type, int code)1615     public void triggerSsn(int type, int code) {
1616         SuppServiceNotification not = new SuppServiceNotification();
1617         not.notificationType = type;
1618         not.code = code;
1619         mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null));
1620     }
1621 
1622     @Override
1623     public void
shutdown()1624     shutdown() {
1625         setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, false /* forceNotifyRegistrants */);
1626         Looper looper = mHandlerThread.getLooper();
1627         if (looper != null) {
1628             looper.quit();
1629         }
1630     }
1631 
1632     /** hangup all */
1633 
1634     @Override
1635     public void
triggerHangupAll()1636     triggerHangupAll() {
1637         simulatedCallState.triggerHangupAll();
1638         mCallStateRegistrants.notifyRegistrants();
1639     }
1640 
1641     @Override
1642     public void
triggerIncomingSMS(String message)1643     triggerIncomingSMS(String message) {
1644         //TODO
1645     }
1646 
1647     @Override
1648     public void
pauseResponses()1649     pauseResponses() {
1650         mPausedResponseCount++;
1651     }
1652 
1653     @Override
1654     public void
resumeResponses()1655     resumeResponses() {
1656         mPausedResponseCount--;
1657 
1658         if (mPausedResponseCount == 0) {
1659             for (int i = 0, s = mPausedResponses.size(); i < s ; i++) {
1660                 mPausedResponses.get(i).sendToTarget();
1661             }
1662             mPausedResponses.clear();
1663         } else {
1664             Rlog.e("GSM", "SimulatedCommands.resumeResponses < 0");
1665         }
1666     }
1667 
1668     //***** Private Methods
1669 
1670     @UnsupportedAppUsage
unimplemented(Message result)1671     private void unimplemented(Message result) {
1672         if (result != null) {
1673             AsyncResult.forMessage(result).exception
1674                 = new RuntimeException("Unimplemented");
1675 
1676             if (mPausedResponseCount > 0) {
1677                 mPausedResponses.add(result);
1678             } else {
1679                 result.sendToTarget();
1680             }
1681         }
1682     }
1683 
1684     @UnsupportedAppUsage
resultSuccess(Message result, Object ret)1685     protected void resultSuccess(Message result, Object ret) {
1686         if (result != null) {
1687             AsyncResult.forMessage(result).result = ret;
1688             if (mPausedResponseCount > 0) {
1689                 mPausedResponses.add(result);
1690             } else {
1691                 result.sendToTarget();
1692             }
1693         }
1694     }
1695 
1696     @UnsupportedAppUsage
resultFail(Message result, Object ret, Throwable tr)1697     private void resultFail(Message result, Object ret, Throwable tr) {
1698         if (result != null) {
1699             AsyncResult.forMessage(result, ret, tr);
1700             if (mPausedResponseCount > 0) {
1701                 mPausedResponses.add(result);
1702             } else {
1703                 result.sendToTarget();
1704             }
1705         }
1706     }
1707 
1708     // ***** Methods for CDMA support
1709     @Override
1710     public void
getDeviceIdentity(Message response)1711     getDeviceIdentity(Message response) {
1712         SimulatedCommandsVerifier.getInstance().getDeviceIdentity(response);
1713         resultSuccess(response, new String[] {FAKE_IMEI, FAKE_IMEISV, FAKE_ESN, FAKE_MEID});
1714     }
1715 
1716     @Override
getImei(Message response)1717     public void getImei(Message response) {
1718         SimulatedCommandsVerifier.getInstance().getImei(response);
1719         ImeiInfo imeiInfo = new ImeiInfo();
1720         imeiInfo.imei = FAKE_IMEI;
1721         imeiInfo.svn = FAKE_IMEISV;
1722         imeiInfo.type = ImeiInfo.ImeiType.SECONDARY;
1723         resultSuccess(response, imeiInfo);
1724     }
1725 
1726     @Override
1727     public void
getCDMASubscription(Message result)1728     getCDMASubscription(Message result) {
1729         String ret[] = new String[5];
1730         ret[0] = "123";
1731         ret[1] = "456";
1732         ret[2] = "789";
1733         ret[3] = "234";
1734         ret[4] = "345";
1735         resultSuccess(result, ret);
1736     }
1737 
1738     @Override
1739     public void
setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response)1740     setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
1741         unimplemented(response);
1742     }
1743 
1744     @Override
queryCdmaRoamingPreference(Message response)1745     public void queryCdmaRoamingPreference(Message response) {
1746         unimplemented(response);
1747     }
1748 
1749     @Override
setCdmaRoamingPreference(int cdmaRoamingType, Message response)1750     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
1751         unimplemented(response);
1752     }
1753 
1754     @Override
1755     public void
setPhoneType(int phoneType)1756     setPhoneType(int phoneType) {
1757     }
1758 
1759     @Override
getPreferredVoicePrivacy(Message result)1760     public void getPreferredVoicePrivacy(Message result) {
1761         unimplemented(result);
1762     }
1763 
1764     @Override
setPreferredVoicePrivacy(boolean enable, Message result)1765     public void setPreferredVoicePrivacy(boolean enable, Message result) {
1766         unimplemented(result);
1767     }
1768 
1769     /**
1770      *  Set the TTY mode
1771      *
1772      * @param ttyMode is one of the following:
1773      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1774      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1775      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1776      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1777      * @param response is callback message
1778      */
1779     @Override
setTTYMode(int ttyMode, Message response)1780     public void setTTYMode(int ttyMode, Message response) {
1781         Rlog.w(LOG_TAG, "Not implemented in SimulatedCommands");
1782         unimplemented(response);
1783     }
1784 
1785     /**
1786      *  Query the TTY mode
1787      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1788      * tty mode:
1789      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1790      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1791      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1792      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1793      * @param response is callback message
1794      */
1795     @Override
queryTTYMode(Message response)1796     public void queryTTYMode(Message response) {
1797         unimplemented(response);
1798     }
1799 
1800     /**
1801      * {@inheritDoc}
1802      */
1803     @Override
sendCDMAFeatureCode(String FeatureCode, Message response)1804     public void sendCDMAFeatureCode(String FeatureCode, Message response) {
1805         unimplemented(response);
1806     }
1807 
1808     /**
1809      * {@inheritDoc}
1810      */
1811     @Override
sendCdmaSms(byte[] pdu, Message response)1812     public void sendCdmaSms(byte[] pdu, Message response){
1813         SimulatedCommandsVerifier.getInstance().sendCdmaSms(pdu, response);
1814         resultSuccess(response, null);
1815     }
1816 
1817     /**
1818      * {@inheritDoc}
1819      */
1820     @Override
sendCdmaSMSExpectMore(byte[] pdu, Message response)1821     public void sendCdmaSMSExpectMore(byte[] pdu, Message response){
1822     }
1823 
1824     @Override
setCdmaBroadcastActivation(boolean activate, Message response)1825     public void setCdmaBroadcastActivation(boolean activate, Message response) {
1826         SimulatedCommandsVerifier.getInstance().setCdmaBroadcastActivation(activate, response);
1827         resultSuccess(response, null);
1828     }
1829 
1830     @Override
getCdmaBroadcastConfig(Message response)1831     public void getCdmaBroadcastConfig(Message response) {
1832         unimplemented(response);
1833 
1834     }
1835 
1836     @Override
setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response)1837     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) {
1838         SimulatedCommandsVerifier.getInstance().setCdmaBroadcastConfig(configs, response);
1839         resultSuccess(response, null);
1840     }
1841 
forceDataDormancy(Message response)1842     public void forceDataDormancy(Message response) {
1843         unimplemented(response);
1844     }
1845 
1846 
1847     @Override
setGsmBroadcastActivation(boolean activate, Message response)1848     public void setGsmBroadcastActivation(boolean activate, Message response) {
1849         SimulatedCommandsVerifier.getInstance().setGsmBroadcastActivation(activate, response);
1850         resultSuccess(response, null);
1851     }
1852 
1853 
1854     @Override
setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response)1855     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
1856         SimulatedCommandsVerifier.getInstance().setGsmBroadcastConfig(config, response);
1857         if (mSendSetGsmBroadcastConfigResponse) {
1858             resultSuccess(response, null);
1859         }
1860     }
1861 
1862     @Override
getGsmBroadcastConfig(Message response)1863     public void getGsmBroadcastConfig(Message response) {
1864         unimplemented(response);
1865     }
1866 
1867     @Override
supplyIccPinForApp(String pin, String aid, Message response)1868     public void supplyIccPinForApp(String pin, String aid, Message response) {
1869         SimulatedCommandsVerifier.getInstance().supplyIccPinForApp(pin, aid, response);
1870         if (mPinCode != null && mPinCode.equals(pin)) {
1871             resultSuccess(response, null);
1872             return;
1873         }
1874 
1875         Rlog.i(LOG_TAG, "[SimCmd] supplyIccPinForApp: pin failed!");
1876         CommandException ex = new CommandException(
1877                 CommandException.Error.PASSWORD_INCORRECT);
1878         resultFail(response, new int[]{
1879                 (--mPin1attemptsRemaining < 0) ? 0 : mPin1attemptsRemaining}, ex);
1880     }
1881 
1882     @Override
supplyIccPukForApp(String puk, String newPin, String aid, Message response)1883     public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
1884         unimplemented(response);
1885     }
1886 
1887     @Override
supplyIccPin2ForApp(String pin2, String aid, Message response)1888     public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
1889         unimplemented(response);
1890     }
1891 
1892     @Override
supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response)1893     public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
1894         unimplemented(response);
1895     }
1896 
1897     @Override
changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response)1898     public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
1899         SimulatedCommandsVerifier.getInstance().changeIccPinForApp(oldPin, newPin, aidPtr,
1900                 response);
1901         changeIccPin(oldPin, newPin, response);
1902     }
1903 
1904     @Override
changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message response)1905     public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
1906             Message response) {
1907         unimplemented(response);
1908     }
1909 
1910     @Override
requestIccSimAuthentication(int authContext, String data, String aid, Message response)1911     public void requestIccSimAuthentication(int authContext, String data, String aid, Message response) {
1912         switch (mAuthenticationMode) {
1913             case ICC_AUTHENTICATION_MODE_TIMEOUT:
1914                 break;
1915 
1916             case ICC_AUTHENTICATION_MODE_NULL:
1917                 sendMessageResponse(response, null);
1918                 break;
1919 
1920             default:
1921                 if (data == null || data.length() == 0) {
1922                     sendMessageResponse(response,  null);
1923                 } else {
1924                     sendMessageResponse(response, new IccIoResult(0, 0, (byte[]) data.getBytes()));
1925                 }
1926                 break;
1927         }
1928     }
1929 
1930     /**
1931      * Helper function to send response msg
1932      * @param msg Response message to be sent
1933      * @param ret Return object to be included in the response message
1934      */
sendMessageResponse(Message msg, Object ret)1935     private void sendMessageResponse(Message msg, Object ret) {
1936         if (msg != null) {
1937             AsyncResult.forMessage(msg, ret, null);
1938             msg.sendToTarget();
1939         }
1940     }
1941 
setAuthenticationMode(int authenticationMode)1942     public void setAuthenticationMode(int authenticationMode) {
1943         mAuthenticationMode = authenticationMode;
1944     }
1945 
1946     @Override
getVoiceRadioTechnology(Message response)1947     public void getVoiceRadioTechnology(Message response) {
1948         SimulatedCommandsVerifier.getInstance().getVoiceRadioTechnology(response);
1949         int ret[] = new int[1];
1950         ret[0] = mVoiceRadioTech;
1951         resultSuccess(response, ret);
1952     }
1953 
setCellInfoList(List<CellInfo> list)1954     public void setCellInfoList(List<CellInfo> list) {
1955         mCellInfoList = list;
1956     }
1957 
getCellInfoGsm()1958     private CellInfoGsm getCellInfoGsm() {
1959         Parcel p = Parcel.obtain();
1960         // CellInfo
1961         p.writeInt(1);
1962         p.writeInt(1);
1963         p.writeInt(2);
1964         p.writeLong(1453510289108L);
1965         p.writeInt(0);
1966         // CellIdentity
1967         p.writeInt(1);
1968         p.writeString("310");
1969         p.writeString("260");
1970         p.writeString("long");
1971         p.writeString("short");
1972         // CellIdentityGsm
1973         p.writeInt(123);
1974         p.writeInt(456);
1975         p.writeInt(950);
1976         p.writeInt(27);
1977         // CellSignalStrength
1978         p.writeInt(99);
1979         p.writeInt(0);
1980         p.writeInt(3);
1981         p.setDataPosition(0);
1982 
1983         return CellInfoGsm.CREATOR.createFromParcel(p);
1984     }
1985 
setCellInfoListBehavior(boolean shouldReturn)1986     public synchronized void setCellInfoListBehavior(boolean shouldReturn) {
1987         mShouldReturnCellInfo = shouldReturn;
1988     }
1989 
1990     @Override
getCellInfoList(Message response, WorkSource workSource)1991     public synchronized void getCellInfoList(Message response, WorkSource workSource) {
1992         if (!mShouldReturnCellInfo) return;
1993 
1994         if (mCellInfoList == null) {
1995             mCellInfoList = new ArrayList();
1996             mCellInfoList.add(getCellInfoGsm());
1997         }
1998 
1999         resultSuccess(response, mCellInfoList);
2000     }
2001 
2002     @Override
getRilVersion()2003     public int getRilVersion() {
2004         return 11;
2005     }
2006 
2007     @Override
setCellInfoListRate(int rateInMillis, Message response, WorkSource workSource)2008     public void setCellInfoListRate(int rateInMillis, Message response, WorkSource workSource) {
2009         unimplemented(response);
2010     }
2011 
2012     @Override
setInitialAttachApn(DataProfile dataProfile, Message result)2013     public void setInitialAttachApn(DataProfile dataProfile, Message result) {
2014         SimulatedCommandsVerifier.getInstance().setInitialAttachApn(dataProfile, result);
2015         resultSuccess(result, null);
2016     }
2017 
2018     @Override
setDataProfile(DataProfile[] dps, Message result)2019     public void setDataProfile(DataProfile[] dps, Message result) {
2020         SimulatedCommandsVerifier.getInstance().setDataProfile(dps, result);
2021         resultSuccess(result, null);
2022     }
2023 
2024     @Override
startHandover(Message result, int callId)2025     public void startHandover(Message result, int callId) {
2026         SimulatedCommandsVerifier.getInstance().startHandover(result, callId);
2027         resultSuccess(result, null);
2028     };
2029 
2030     @Override
cancelHandover(Message result, int callId)2031     public void cancelHandover(Message result, int callId) {
2032         SimulatedCommandsVerifier.getInstance().cancelHandover(result, callId);
2033         resultSuccess(result, null);
2034     };
2035 
setImsRegistrationState(int[] regState)2036     public void setImsRegistrationState(int[] regState) {
2037         mImsRegState = regState;
2038     }
2039 
2040     @Override
getImsRegistrationState(Message response)2041     public void getImsRegistrationState(Message response) {
2042         if (mImsRegState == null) {
2043             mImsRegState = new int[]{1, PhoneConstants.PHONE_TYPE_NONE};
2044         }
2045 
2046         resultSuccess(response, mImsRegState);
2047     }
2048 
2049     @Override
sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message response)2050     public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef,
2051             Message response){
2052         SimulatedCommandsVerifier.getInstance().sendImsCdmaSms(pdu, retry, messageRef, response);
2053         resultSuccess(response, new SmsResponse(0 /*messageRef*/, null, SmsResponse.NO_ERROR_CODE));
2054     }
2055 
2056     @Override
sendImsGsmSms(String smscPDU, String pdu, int retry, int messageRef, Message response)2057     public void sendImsGsmSms(String smscPDU, String pdu,
2058             int retry, int messageRef, Message response){
2059         SimulatedCommandsVerifier.getInstance().sendImsGsmSms(smscPDU, pdu, retry, messageRef,
2060                 response);
2061         resultSuccess(response, new SmsResponse(0 /*messageRef*/, null, SmsResponse.NO_ERROR_CODE));
2062     }
2063 
2064     @Override
iccOpenLogicalChannel(String AID, int p2, Message response)2065     public void iccOpenLogicalChannel(String AID, int p2, Message response) {
2066         SimulatedCommandsVerifier.getInstance().iccOpenLogicalChannel(AID, p2, response);
2067         Object result = new int[]{mChannelId};
2068         resultSuccess(response, result);
2069     }
2070 
2071     @Override
iccCloseLogicalChannel(int channel, boolean isEs10, Message response)2072     public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response) {
2073         unimplemented(response);
2074     }
2075 
2076     @Override
iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2, int p3, String data, boolean isEs10Command, Message response)2077     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
2078             int p1, int p2, int p3, String data, boolean isEs10Command, Message response) {
2079         SimulatedCommandsVerifier.getInstance().iccTransmitApduLogicalChannel(channel, cla,
2080                 instruction, p1, p2, p3, data, isEs10Command, response);
2081         if (mIccIoResultForApduLogicalChannel != null) {
2082             resultSuccess(response, mIccIoResultForApduLogicalChannel);
2083         } else {
2084             resultFail(response, null, new RuntimeException("IccIoResult not set"));
2085         }
2086     }
2087 
2088     @Override
iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3, String data, Message response)2089     public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
2090             int p3, String data, Message response) {
2091         unimplemented(response);
2092     }
2093 
2094     @Override
nvReadItem(int itemID, Message response, WorkSource workSource)2095     public void nvReadItem(int itemID, Message response, WorkSource workSource) {
2096         unimplemented(response);
2097     }
2098 
2099     @Override
nvWriteItem(int itemID, String itemValue, Message response, WorkSource workSource)2100     public void nvWriteItem(int itemID, String itemValue, Message response, WorkSource workSource) {
2101         unimplemented(response);
2102     }
2103 
2104     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2105     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
2106         unimplemented(response);
2107     }
2108 
2109     @Override
nvResetConfig(int resetType, Message response)2110     public void nvResetConfig(int resetType, Message response) {
2111         unimplemented(response);
2112     }
2113 
2114     @Override
getHardwareConfig(Message result)2115     public void getHardwareConfig(Message result) {
2116         unimplemented(result);
2117     }
2118 
2119     @Override
requestShutdown(Message result)2120     public void requestShutdown(Message result) {
2121         setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, false /* forceNotifyRegistrants */);
2122     }
2123 
2124     @Override
registerForLceInfo(Handler h, int what, Object obj)2125     public void registerForLceInfo(Handler h, int what, Object obj) {
2126         SimulatedCommandsVerifier.getInstance().registerForLceInfo(h, what, obj);
2127     }
2128 
2129     @Override
unregisterForLceInfo(Handler h)2130     public void unregisterForLceInfo(Handler h) {
2131         SimulatedCommandsVerifier.getInstance().unregisterForLceInfo(h);
2132     }
2133 
2134     @Override
getModemActivityInfo(Message result, WorkSource workSource)2135     public void getModemActivityInfo(Message result, WorkSource workSource) {
2136         unimplemented(result);
2137     }
2138 
2139     @Override
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules, Message result, WorkSource workSource)2140     public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
2141             Message result, WorkSource workSource) {
2142         unimplemented(result);
2143     }
2144 
2145     @Override
getAllowedCarriers(Message result, WorkSource workSource)2146     public void getAllowedCarriers(Message result, WorkSource workSource) {
2147         unimplemented(result);
2148     }
2149 
2150     @Override
getRadioCapability(Message result)2151     public void getRadioCapability(Message result) {
2152         SimulatedCommandsVerifier.getInstance().getRadioCapability(result);
2153         resultSuccess(result, new RadioCapability(0, 0, 0, 0xFFFF, null, 0));
2154     }
notifySmsStatus(Object result)2155     public void notifySmsStatus(Object result) {
2156         if (mSmsStatusRegistrant != null) {
2157             mSmsStatusRegistrant.notifyRegistrant(new AsyncResult(null, result, null));
2158         }
2159     }
2160 
notifyGsmBroadcastSms(Object result)2161     public void notifyGsmBroadcastSms(Object result) {
2162         if (mGsmBroadcastSmsRegistrant != null) {
2163             mGsmBroadcastSmsRegistrant.notifyRegistrant(new AsyncResult(null, result, null));
2164         }
2165     }
2166 
notifyIccSmsFull()2167     public void notifyIccSmsFull() {
2168         if (mIccSmsFullRegistrant != null) {
2169             mIccSmsFullRegistrant.notifyRegistrant();
2170         }
2171     }
2172 
notifyEmergencyCallbackMode()2173     public void notifyEmergencyCallbackMode() {
2174         if (mEmergencyCallbackModeRegistrant != null) {
2175             mEmergencyCallbackModeRegistrant.notifyRegistrant();
2176         }
2177     }
2178 
2179     @Override
setEmergencyCallbackMode(Handler h, int what, Object obj)2180     public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
2181         SimulatedCommandsVerifier.getInstance().setEmergencyCallbackMode(h, what, obj);
2182         super.setEmergencyCallbackMode(h, what, obj);
2183     }
2184 
notifyExitEmergencyCallbackMode()2185     public void notifyExitEmergencyCallbackMode() {
2186         if (mExitEmergencyCallbackModeRegistrants != null) {
2187             mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
2188                     new AsyncResult (null, null, null));
2189         }
2190     }
2191 
notifyImsNetworkStateChanged()2192     public void notifyImsNetworkStateChanged() {
2193         if(mImsNetworkStateChangedRegistrants != null) {
2194             mImsNetworkStateChangedRegistrants.notifyRegistrants();
2195         }
2196     }
2197 
notifyModemReset()2198     public void notifyModemReset() {
2199         if (mModemResetRegistrants != null) {
2200             mModemResetRegistrants.notifyRegistrants(new AsyncResult(null, "Test", null));
2201         }
2202     }
2203 
2204     @Override
registerForExitEmergencyCallbackMode(Handler h, int what, Object obj)2205     public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
2206         SimulatedCommandsVerifier.getInstance().registerForExitEmergencyCallbackMode(h, what, obj);
2207         super.registerForExitEmergencyCallbackMode(h, what, obj);
2208     }
2209 
2210     @Override
registerForSrvccStateChanged(Handler h, int what, Object obj)2211     public void registerForSrvccStateChanged(Handler h, int what, Object obj) {
2212         SimulatedCommandsVerifier.getInstance().registerForSrvccStateChanged(h, what, obj);
2213         super.registerForSrvccStateChanged(h, what, obj);
2214     }
2215 
notifyRadioOn()2216     public void notifyRadioOn() {
2217         mOnRegistrants.notifyRegistrants();
2218     }
2219 
2220     @VisibleForTesting
notifyNetworkStateChanged()2221     public void notifyNetworkStateChanged() {
2222         mNetworkStateRegistrants.notifyRegistrants();
2223     }
2224 
2225     @VisibleForTesting
notifyOtaProvisionStatusChanged()2226     public void notifyOtaProvisionStatusChanged() {
2227         if (mOtaProvisionRegistrants != null) {
2228             int ret[] = new int[1];
2229             ret[0] = Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED;
2230             mOtaProvisionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
2231         }
2232     }
2233 
notifySignalStrength()2234     public void notifySignalStrength() {
2235         if (mSignalStrength == null) {
2236             mSignalStrength = new SignalStrength(
2237                     new CellSignalStrengthCdma(),
2238                     new CellSignalStrengthGsm(20, 0, CellInfo.UNAVAILABLE),
2239                     new CellSignalStrengthWcdma(),
2240                     new CellSignalStrengthTdscdma(),
2241                     new CellSignalStrengthLte(),
2242                     new CellSignalStrengthNr());
2243         }
2244 
2245         if (mSignalStrengthRegistrant != null) {
2246             mSignalStrengthRegistrant.notifyRegistrant(
2247                     new AsyncResult (null, mSignalStrength, null));
2248         }
2249     }
2250 
setIccCardStatus(IccCardStatus iccCardStatus)2251     public void setIccCardStatus(IccCardStatus iccCardStatus){
2252         mIccCardStatus = iccCardStatus;
2253     }
2254 
setIccIoResultForApduLogicalChannel(IccIoResult iccIoResult)2255     public void setIccIoResultForApduLogicalChannel(IccIoResult iccIoResult) {
2256         mIccIoResultForApduLogicalChannel = iccIoResult;
2257     }
2258 
setOpenChannelId(int channelId)2259     public void setOpenChannelId(int channelId) {
2260         mChannelId = channelId;
2261     }
2262 
setPin1RemainingAttempt(int pin1attemptsRemaining)2263     public void setPin1RemainingAttempt(int pin1attemptsRemaining) {
2264         mPin1attemptsRemaining = pin1attemptsRemaining;
2265     }
2266 
2267     private AtomicBoolean mAllowed = new AtomicBoolean(false);
2268 
2269     @Override
setDataAllowed(boolean allowed, Message result)2270     public void setDataAllowed(boolean allowed, Message result) {
2271         log("setDataAllowed = " + allowed);
2272         mAllowed.set(allowed);
2273         resultSuccess(result, null);
2274     }
2275 
2276     @VisibleForTesting
isDataAllowed()2277     public boolean isDataAllowed() {
2278         return mAllowed.get();
2279     }
2280 
2281     @Override
registerForPcoData(Handler h, int what, Object obj)2282     public void registerForPcoData(Handler h, int what, Object obj) {
2283         SimulatedCommandsVerifier.getInstance().registerForPcoData(h, what, obj);
2284         mPcoDataRegistrants.addUnique(h, what, obj);
2285     }
2286 
2287     @Override
unregisterForPcoData(Handler h)2288     public void unregisterForPcoData(Handler h) {
2289         SimulatedCommandsVerifier.getInstance().unregisterForPcoData(h);
2290         mPcoDataRegistrants.remove(h);
2291     }
2292 
2293     @Override
registerForNotAvailable(Handler h, int what, Object obj)2294     public void registerForNotAvailable(Handler h, int what, Object obj) {
2295         SimulatedCommandsVerifier.getInstance().registerForNotAvailable(h, what, obj);
2296         super.registerForNotAvailable(h, what, obj);
2297     }
2298 
2299     @Override
unregisterForNotAvailable(Handler h)2300     public void unregisterForNotAvailable(Handler h) {
2301         SimulatedCommandsVerifier.getInstance().unregisterForNotAvailable(h);
2302         super.unregisterForNotAvailable(h);
2303     }
2304 
2305     @Override
registerForModemReset(Handler h, int what, Object obj)2306     public void registerForModemReset(Handler h, int what, Object obj) {
2307         SimulatedCommandsVerifier.getInstance().registerForModemReset(h, what, obj);
2308         super.registerForModemReset(h, what, obj);
2309     }
2310 
2311     @Override
sendDeviceState(int stateType, boolean state, Message result)2312     public void sendDeviceState(int stateType, boolean state, Message result) {
2313         SimulatedCommandsVerifier.getInstance().sendDeviceState(stateType, state, result);
2314         resultSuccess(result, null);
2315     }
2316 
2317     @Override
setUnsolResponseFilter(int filter, Message result)2318     public void setUnsolResponseFilter(int filter, Message result) {
2319         SimulatedCommandsVerifier.getInstance().setUnsolResponseFilter(filter, result);
2320         resultSuccess(result, null);
2321     }
2322 
2323     @Override
setSignalStrengthReportingCriteria(List<SignalThresholdInfo> signalThresholdInfos, Message result)2324     public void setSignalStrengthReportingCriteria(List<SignalThresholdInfo> signalThresholdInfos,
2325             Message result) {
2326         SimulatedCommandsVerifier.getInstance().setSignalStrengthReportingCriteria(
2327                 signalThresholdInfos, result);
2328         resultSuccess(result, null);
2329     }
2330 
2331     @Override
setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps, int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran, Message result)2332     public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
2333             int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
2334             Message result) {
2335     }
2336 
2337     @Override
setSimCardPower(int state, Message result, WorkSource workSource)2338     public void setSimCardPower(int state, Message result, WorkSource workSource) {
2339     }
2340 
2341     @VisibleForTesting
triggerRestrictedStateChanged(int restrictedState)2342     public void triggerRestrictedStateChanged(int restrictedState) {
2343         if (mRestrictedStateRegistrant != null) {
2344             mRestrictedStateRegistrant.notifyRegistrant(
2345                     new AsyncResult(null, restrictedState, null));
2346         }
2347     }
2348 
2349     @Override
setOnRestrictedStateChanged(Handler h, int what, Object obj)2350     public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
2351         super.setOnRestrictedStateChanged(h, what, obj);
2352         SimulatedCommandsVerifier.getInstance().setOnRestrictedStateChanged(h, what, obj);
2353     }
2354 
setRadioPowerFailResponse(boolean fail)2355     public void setRadioPowerFailResponse(boolean fail) {
2356         mIsRadioPowerFailResponse = fail;
2357     }
2358 
2359     @Override
registerForIccRefresh(Handler h, int what, Object obj)2360     public void registerForIccRefresh(Handler h, int what, Object obj) {
2361         super.registerForIccRefresh(h, what, obj);
2362         SimulatedCommandsVerifier.getInstance().registerForIccRefresh(h, what, obj);
2363     }
2364 
2365     @Override
unregisterForIccRefresh(Handler h)2366     public void unregisterForIccRefresh(Handler h) {
2367         super.unregisterForIccRefresh(h);
2368         SimulatedCommandsVerifier.getInstance().unregisterForIccRefresh(h);
2369     }
2370 
2371     @Override
registerForNattKeepaliveStatus(Handler h, int what, Object obj)2372     public void registerForNattKeepaliveStatus(Handler h, int what, Object obj) {
2373         SimulatedCommandsVerifier.getInstance().registerForNattKeepaliveStatus(h, what, obj);
2374     }
2375 
2376     @Override
unregisterForNattKeepaliveStatus(Handler h)2377     public void unregisterForNattKeepaliveStatus(Handler h) {
2378         SimulatedCommandsVerifier.getInstance().unregisterForNattKeepaliveStatus(h);
2379     }
2380 
2381     @Override
startNattKeepalive( int contextId, KeepalivePacketData packetData, int intervalMillis, Message result)2382     public void startNattKeepalive(
2383             int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) {
2384         SimulatedCommandsVerifier.getInstance().startNattKeepalive(
2385                 contextId, packetData, intervalMillis, result);
2386     }
2387 
2388     @Override
stopNattKeepalive(int sessionHandle, Message result)2389     public void stopNattKeepalive(int sessionHandle, Message result) {
2390         SimulatedCommandsVerifier.getInstance().stopNattKeepalive(sessionHandle, result);
2391     }
2392 
getHandler()2393     public Handler getHandler() {
2394         return mHandlerThread.getThreadHandler();
2395     }
2396 
2397     @Override
getBarringInfo(Message result)2398     public void getBarringInfo(Message result) {
2399         SimulatedCommandsVerifier.getInstance().getBarringInfo(result);
2400         resultSuccess(result, null);
2401     }
2402 
2403     @Override
allocatePduSessionId(Message message)2404     public void allocatePduSessionId(Message message) {
2405         SimulatedCommandsVerifier.getInstance().allocatePduSessionId(message);
2406         resultSuccess(message, 1);
2407     }
2408 
2409     @Override
releasePduSessionId(Message message, int pduSessionId)2410     public void releasePduSessionId(Message message, int pduSessionId) {
2411         SimulatedCommandsVerifier.getInstance().releasePduSessionId(message, pduSessionId);
2412         resultSuccess(message, null);
2413     }
2414 
2415     @Override
getSlicingConfig(Message result)2416     public void getSlicingConfig(Message result) {
2417         SimulatedCommandsVerifier.getInstance().getSlicingConfig(result);
2418         resultSuccess(result, null);
2419     }
2420 
2421     @VisibleForTesting
setDataRegStateResult(Object regStateResult)2422     public void setDataRegStateResult(Object regStateResult) {
2423         mDataRegStateResult = regStateResult;
2424     }
2425 
2426     @VisibleForTesting
setVoiceRegStateResult(Object regStateResult)2427     public void setVoiceRegStateResult(Object regStateResult) {
2428         mVoiceRegStateResult = regStateResult;
2429     }
2430 
2431     @Override
getSimPhonebookRecords(Message result)2432     public void getSimPhonebookRecords(Message result) {
2433         resultSuccess(result, null);
2434 
2435         // send a fake result
2436         List<SimPhonebookRecord> phonebookRecordInfoGroup = new ArrayList<SimPhonebookRecord>();
2437         mSimPhonebookRecordsReceivedRegistrants.notifyRegistrants(
2438                 new AsyncResult(null,
2439                 new ReceivedPhonebookRecords(4, phonebookRecordInfoGroup), null));
2440     }
2441 
2442     @Override
getSimPhonebookCapacity(Message result)2443     public void getSimPhonebookCapacity(Message result) {
2444         resultSuccess(result, new AdnCapacity(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
2445     }
2446 
2447     @Override
updateSimPhonebookRecord(SimPhonebookRecord phonebookRecord, Message result)2448     public void updateSimPhonebookRecord(SimPhonebookRecord phonebookRecord, Message result) {
2449         int recordId = phonebookRecord.getRecordId();
2450         // Based on design, the record ID starts from 1.
2451         // So if the record ID passed from upper layer is 0, it indicates to insert one new record
2452         // without record ID specific.
2453         if (recordId == 0) {
2454             recordId = 1; // hack code for unit test
2455         }
2456         resultSuccess(result, new int[]{recordId});
2457         notifySimPhonebookChanged();
2458     }
2459 
2460     @VisibleForTesting
notifySimPhonebookChanged()2461     public void notifySimPhonebookChanged() {
2462         mSimPhonebookChangedRegistrants.notifyRegistrants();
2463     }
2464 
triggerPcoData(int cid, String bearerProto, int pcoId, byte[] contents)2465     public void triggerPcoData(int cid, String bearerProto, int pcoId, byte[] contents) {
2466         PcoData response = new PcoData(cid, bearerProto, pcoId, contents);
2467         mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
2468     }
2469 
2470     @Override
setSrvccCallInfo(SrvccConnection[] srvccConnections, Message result)2471     public void setSrvccCallInfo(SrvccConnection[] srvccConnections, Message result) {
2472         mSrvccConnections = srvccConnections;
2473     }
2474 
getSrvccConnections()2475     public SrvccConnection[] getSrvccConnections() {
2476         return mSrvccConnections;
2477     }
2478 
2479     @Override
updateImsRegistrationInfo(int regState, int imsRadioTech, int suggestedAction, int capabilities, Message result)2480     public void updateImsRegistrationInfo(int regState,
2481             int imsRadioTech, int suggestedAction, int capabilities, Message result) {
2482         mImsRegistrationInfo[0] = regState;
2483         mImsRegistrationInfo[1] = imsRadioTech;
2484         mImsRegistrationInfo[2] = suggestedAction;
2485         mImsRegistrationInfo[3] = capabilities;
2486     }
2487 
getImsRegistrationInfo()2488     public int[] getImsRegistrationInfo() {
2489         return mImsRegistrationInfo;
2490     }
2491 
2492     @Override
setN1ModeEnabled(boolean enable, Message result)2493     public void setN1ModeEnabled(boolean enable, Message result) {
2494         mN1ModeEnabled = enable;
2495     }
2496 
isN1ModeEnabled()2497     public boolean isN1ModeEnabled() {
2498         return mN1ModeEnabled;
2499     }
2500 
2501     @Override
isVoNrEnabled(Message message, WorkSource workSource)2502     public void isVoNrEnabled(Message message, WorkSource workSource) {
2503         resultSuccess(message, (Object) mVonrEnabled);
2504     }
2505 
setVonrEnabled(boolean vonrEnable)2506     public void setVonrEnabled(boolean vonrEnable) {
2507         mVonrEnabled = vonrEnable;
2508     }
2509 }
2510