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