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