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