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