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