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