Home | History | Annotate | Download | only in telephony
      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;
     18 
     19 import static com.android.internal.telephony.RILConstants.*;
     20 import static com.android.internal.util.Preconditions.checkNotNull;
     21 
     22 import android.content.Context;
     23 import android.hardware.radio.V1_0.Carrier;
     24 import android.hardware.radio.V1_0.CarrierRestrictions;
     25 import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
     26 import android.hardware.radio.V1_0.CdmaSmsAck;
     27 import android.hardware.radio.V1_0.CdmaSmsMessage;
     28 import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
     29 import android.hardware.radio.V1_0.CellInfoCdma;
     30 import android.hardware.radio.V1_0.CellInfoGsm;
     31 import android.hardware.radio.V1_0.CellInfoLte;
     32 import android.hardware.radio.V1_0.CellInfoType;
     33 import android.hardware.radio.V1_0.CellInfoWcdma;
     34 import android.hardware.radio.V1_0.DataProfileInfo;
     35 import android.hardware.radio.V1_0.Dial;
     36 import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
     37 import android.hardware.radio.V1_0.GsmSmsMessage;
     38 import android.hardware.radio.V1_0.HardwareConfigModem;
     39 import android.hardware.radio.V1_0.IRadio;
     40 import android.hardware.radio.V1_0.IccIo;
     41 import android.hardware.radio.V1_0.ImsSmsMessage;
     42 import android.hardware.radio.V1_0.IndicationFilter;
     43 import android.hardware.radio.V1_0.LceDataInfo;
     44 import android.hardware.radio.V1_0.MvnoType;
     45 import android.hardware.radio.V1_0.NvWriteItem;
     46 import android.hardware.radio.V1_0.RadioError;
     47 import android.hardware.radio.V1_0.RadioIndicationType;
     48 import android.hardware.radio.V1_0.RadioResponseInfo;
     49 import android.hardware.radio.V1_0.RadioResponseType;
     50 import android.hardware.radio.V1_0.ResetNvType;
     51 import android.hardware.radio.V1_0.SelectUiccSub;
     52 import android.hardware.radio.V1_0.SimApdu;
     53 import android.hardware.radio.V1_0.SmsWriteArgs;
     54 import android.hardware.radio.V1_0.UusInfo;
     55 import android.hardware.radio.V1_2.AccessNetwork;
     56 import android.hardware.radio.deprecated.V1_0.IOemHook;
     57 import android.net.ConnectivityManager;
     58 import android.net.KeepalivePacketData;
     59 import android.net.LinkProperties;
     60 import android.os.AsyncResult;
     61 import android.os.Build;
     62 import android.os.Handler;
     63 import android.os.HwBinder;
     64 import android.os.Message;
     65 import android.os.Parcel;
     66 import android.os.PowerManager;
     67 import android.os.PowerManager.WakeLock;
     68 import android.os.RemoteException;
     69 import android.os.SystemClock;
     70 import android.os.SystemProperties;
     71 import android.os.WorkSource;
     72 import android.service.carrier.CarrierIdentifier;
     73 import android.telephony.AccessNetworkConstants.AccessNetworkType;
     74 import android.telephony.CellIdentity;
     75 import android.telephony.CellIdentityCdma;
     76 import android.telephony.CellInfo;
     77 import android.telephony.CellSignalStrengthCdma;
     78 import android.telephony.ClientRequestStats;
     79 import android.telephony.ImsiEncryptionInfo;
     80 import android.telephony.ModemActivityInfo;
     81 import android.telephony.NeighboringCellInfo;
     82 import android.telephony.NetworkScanRequest;
     83 import android.telephony.PhoneNumberUtils;
     84 import android.telephony.RadioAccessFamily;
     85 import android.telephony.RadioAccessSpecifier;
     86 import android.telephony.Rlog;
     87 import android.telephony.ServiceState;
     88 import android.telephony.SignalStrength;
     89 import android.telephony.SmsManager;
     90 import android.telephony.TelephonyHistogram;
     91 import android.telephony.TelephonyManager;
     92 import android.telephony.data.DataProfile;
     93 import android.telephony.data.DataService;
     94 import android.text.TextUtils;
     95 import android.util.Log;
     96 import android.util.SparseArray;
     97 
     98 import com.android.internal.annotations.VisibleForTesting;
     99 import com.android.internal.telephony.cat.ComprehensionTlv;
    100 import com.android.internal.telephony.cat.ComprehensionTlvTag;
    101 import com.android.internal.telephony.cdma.CdmaInformationRecords;
    102 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
    103 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
    104 import com.android.internal.telephony.metrics.TelephonyMetrics;
    105 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
    106 import com.android.internal.telephony.uicc.IccUtils;
    107 
    108 import java.io.ByteArrayInputStream;
    109 import java.io.DataInputStream;
    110 import java.io.FileDescriptor;
    111 import java.io.IOException;
    112 import java.io.PrintWriter;
    113 import java.net.Inet4Address;
    114 import java.net.Inet6Address;
    115 import java.net.InetAddress;
    116 import java.util.ArrayList;
    117 import java.util.Arrays;
    118 import java.util.List;
    119 import java.util.concurrent.atomic.AtomicBoolean;
    120 import java.util.concurrent.atomic.AtomicLong;
    121 
    122 /**
    123  * RIL implementation of the CommandsInterface.
    124  *
    125  * {@hide}
    126  */
    127 public class RIL extends BaseCommands implements CommandsInterface {
    128     static final String RILJ_LOG_TAG = "RILJ";
    129     static final String RILJ_WAKELOCK_TAG = "*telephony-radio*";
    130     // Have a separate wakelock instance for Ack
    131     static final String RILJ_ACK_WAKELOCK_NAME = "RILJ_ACK_WL";
    132     static final boolean RILJ_LOGD = true;
    133     static final boolean RILJ_LOGV = false; // STOPSHIP if true
    134     static final int RIL_HISTOGRAM_BUCKET_COUNT = 5;
    135 
    136     /**
    137      * Wake lock timeout should be longer than the longest timeout in
    138      * the vendor ril.
    139      */
    140     private static final int DEFAULT_WAKE_LOCK_TIMEOUT_MS = 60000;
    141 
    142     // Wake lock default timeout associated with ack
    143     private static final int DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS = 200;
    144 
    145     private static final int DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS = 2000;
    146 
    147     // Variables used to differentiate ack messages from request while calling clearWakeLock()
    148     public static final int INVALID_WAKELOCK = -1;
    149     public static final int FOR_WAKELOCK = 0;
    150     public static final int FOR_ACK_WAKELOCK = 1;
    151     private final ClientWakelockTracker mClientWakelockTracker = new ClientWakelockTracker();
    152 
    153     //***** Instance Variables
    154 
    155     final WakeLock mWakeLock;           // Wake lock associated with request/response
    156     final WakeLock mAckWakeLock;        // Wake lock associated with ack sent
    157     final int mWakeLockTimeout;         // Timeout associated with request/response
    158     final int mAckWakeLockTimeout;      // Timeout associated with ack sent
    159     // The number of wakelock requests currently active.  Don't release the lock
    160     // until dec'd to 0
    161     int mWakeLockCount;
    162 
    163     // Variables used to identify releasing of WL on wakelock timeouts
    164     volatile int mWlSequenceNum = 0;
    165     volatile int mAckWlSequenceNum = 0;
    166 
    167     SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
    168     static SparseArray<TelephonyHistogram> mRilTimeHistograms = new
    169             SparseArray<TelephonyHistogram>();
    170 
    171     Object[]     mLastNITZTimeInfo;
    172 
    173     // When we are testing emergency calls
    174     AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
    175 
    176     final Integer mPhoneId;
    177 
    178     /* default work source which will blame phone process */
    179     private WorkSource mRILDefaultWorkSource;
    180 
    181     /* Worksource containing all applications causing wakelock to be held */
    182     private WorkSource mActiveWakelockWorkSource;
    183 
    184     /** Telephony metrics instance for logging metrics event */
    185     private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
    186 
    187     boolean mIsMobileNetworkSupported;
    188     RadioResponse mRadioResponse;
    189     RadioIndication mRadioIndication;
    190     volatile IRadio mRadioProxy = null;
    191     OemHookResponse mOemHookResponse;
    192     OemHookIndication mOemHookIndication;
    193     volatile IOemHook mOemHookProxy = null;
    194     final AtomicLong mRadioProxyCookie = new AtomicLong(0);
    195     final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
    196     final RilHandler mRilHandler;
    197 
    198     //***** Events
    199     static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
    200     static final int EVENT_ACK_WAKE_LOCK_TIMEOUT    = 4;
    201     static final int EVENT_BLOCKING_RESPONSE_TIMEOUT = 5;
    202     static final int EVENT_RADIO_PROXY_DEAD     = 6;
    203 
    204     //***** Constants
    205 
    206     static final String[] HIDL_SERVICE_NAME = {"slot1", "slot2", "slot3"};
    207 
    208     static final int IRADIO_GET_SERVICE_DELAY_MILLIS = 4 * 1000;
    209 
    210     static final String EMPTY_ALPHA_LONG = "";
    211     static final String EMPTY_ALPHA_SHORT = "";
    212 
    213     public static List<TelephonyHistogram> getTelephonyRILTimingHistograms() {
    214         List<TelephonyHistogram> list;
    215         synchronized (mRilTimeHistograms) {
    216             list = new ArrayList<>(mRilTimeHistograms.size());
    217             for (int i = 0; i < mRilTimeHistograms.size(); i++) {
    218                 TelephonyHistogram entry = new TelephonyHistogram(mRilTimeHistograms.valueAt(i));
    219                 list.add(entry);
    220             }
    221         }
    222         return list;
    223     }
    224 
    225     /** The handler used to handle the internal event of RIL. */
    226     @VisibleForTesting
    227     public class RilHandler extends Handler {
    228 
    229         //***** Handler implementation
    230         @Override
    231         public void handleMessage(Message msg) {
    232             RILRequest rr;
    233 
    234             switch (msg.what) {
    235                 case EVENT_WAKE_LOCK_TIMEOUT:
    236                     // Haven't heard back from the last request.  Assume we're
    237                     // not getting a response and  release the wake lock.
    238 
    239                     // The timer of WAKE_LOCK_TIMEOUT is reset with each
    240                     // new send request. So when WAKE_LOCK_TIMEOUT occurs
    241                     // all requests in mRequestList already waited at
    242                     // least DEFAULT_WAKE_LOCK_TIMEOUT_MS but no response.
    243                     //
    244                     // Note: Keep mRequestList so that delayed response
    245                     // can still be handled when response finally comes.
    246 
    247                     synchronized (mRequestList) {
    248                         if (msg.arg1 == mWlSequenceNum && clearWakeLock(FOR_WAKELOCK)) {
    249                             if (RILJ_LOGD) {
    250                                 int count = mRequestList.size();
    251                                 Rlog.d(RILJ_LOG_TAG, "WAKE_LOCK_TIMEOUT " +
    252                                         " mRequestList=" + count);
    253                                 for (int i = 0; i < count; i++) {
    254                                     rr = mRequestList.valueAt(i);
    255                                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
    256                                             + requestToString(rr.mRequest));
    257                                 }
    258                             }
    259                         }
    260                     }
    261                     break;
    262 
    263                 case EVENT_ACK_WAKE_LOCK_TIMEOUT:
    264                     if (msg.arg1 == mAckWlSequenceNum && clearWakeLock(FOR_ACK_WAKELOCK)) {
    265                         if (RILJ_LOGV) {
    266                             Rlog.d(RILJ_LOG_TAG, "ACK_WAKE_LOCK_TIMEOUT");
    267                         }
    268                     }
    269                     break;
    270 
    271                 case EVENT_BLOCKING_RESPONSE_TIMEOUT:
    272                     int serial = msg.arg1;
    273                     rr = findAndRemoveRequestFromList(serial);
    274                     // If the request has already been processed, do nothing
    275                     if(rr == null) {
    276                         break;
    277                     }
    278 
    279                     //build a response if expected
    280                     if (rr.mResult != null) {
    281                         Object timeoutResponse = getResponseForTimedOutRILRequest(rr);
    282                         AsyncResult.forMessage( rr.mResult, timeoutResponse, null);
    283                         rr.mResult.sendToTarget();
    284                         mMetrics.writeOnRilTimeoutResponse(mPhoneId, rr.mSerial, rr.mRequest);
    285                     }
    286 
    287                     decrementWakeLock(rr);
    288                     rr.release();
    289                     break;
    290 
    291                 case EVENT_RADIO_PROXY_DEAD:
    292                     riljLog("handleMessage: EVENT_RADIO_PROXY_DEAD cookie = " + msg.obj +
    293                             " mRadioProxyCookie = " + mRadioProxyCookie.get());
    294                     if ((long) msg.obj == mRadioProxyCookie.get()) {
    295                         resetProxyAndRequestList();
    296                     }
    297                     break;
    298             }
    299         }
    300     }
    301 
    302     /**
    303      * In order to prevent calls to Telephony from waiting indefinitely
    304      * low-latency blocking calls will eventually time out. In the event of
    305      * a timeout, this function generates a response that is returned to the
    306      * higher layers to unblock the call. This is in lieu of a meaningful
    307      * response.
    308      * @param rr The RIL Request that has timed out.
    309      * @return A default object, such as the one generated by a normal response
    310      * that is returned to the higher layers.
    311      **/
    312     private static Object getResponseForTimedOutRILRequest(RILRequest rr) {
    313         if (rr == null ) return null;
    314 
    315         Object timeoutResponse = null;
    316         switch(rr.mRequest) {
    317             case RIL_REQUEST_GET_ACTIVITY_INFO:
    318                 timeoutResponse = new ModemActivityInfo(
    319                         0, 0, 0, new int [ModemActivityInfo.TX_POWER_LEVELS], 0, 0);
    320                 break;
    321         };
    322         return timeoutResponse;
    323     }
    324 
    325     final class RadioProxyDeathRecipient implements HwBinder.DeathRecipient {
    326         @Override
    327         public void serviceDied(long cookie) {
    328             // Deal with service going away
    329             riljLog("serviceDied");
    330             mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
    331         }
    332     }
    333 
    334     private void resetProxyAndRequestList() {
    335         mRadioProxy = null;
    336         mOemHookProxy = null;
    337 
    338         // increment the cookie so that death notification can be ignored
    339         mRadioProxyCookie.incrementAndGet();
    340 
    341         setRadioState(RadioState.RADIO_UNAVAILABLE);
    342 
    343         RILRequest.resetSerial();
    344         // Clear request list on close
    345         clearRequestList(RADIO_NOT_AVAILABLE, false);
    346 
    347         getRadioProxy(null);
    348         getOemHookProxy(null);
    349     }
    350 
    351     /** Returns a {@link IRadio} instance or null if the service is not available. */
    352     @VisibleForTesting
    353     public IRadio getRadioProxy(Message result) {
    354         if (!mIsMobileNetworkSupported) {
    355             if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
    356             if (result != null) {
    357                 AsyncResult.forMessage(result, null,
    358                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
    359                 result.sendToTarget();
    360             }
    361             return null;
    362         }
    363 
    364         if (mRadioProxy != null) {
    365             return mRadioProxy;
    366         }
    367 
    368         try {
    369             mRadioProxy = IRadio.getService(HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId],
    370                     true);
    371             if (mRadioProxy != null) {
    372                 mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
    373                         mRadioProxyCookie.incrementAndGet());
    374                 mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
    375             } else {
    376                 riljLoge("getRadioProxy: mRadioProxy == null");
    377             }
    378         } catch (RemoteException | RuntimeException e) {
    379             mRadioProxy = null;
    380             riljLoge("RadioProxy getService/setResponseFunctions: " + e);
    381         }
    382 
    383         if (mRadioProxy == null) {
    384             // getService() is a blocking call, so this should never happen
    385             riljLoge("getRadioProxy: mRadioProxy == null");
    386             if (result != null) {
    387                 AsyncResult.forMessage(result, null,
    388                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
    389                 result.sendToTarget();
    390             }
    391         }
    392 
    393         return mRadioProxy;
    394     }
    395 
    396     /** Returns an {@link IOemHook} instance or null if the service is not available. */
    397     @VisibleForTesting
    398     public IOemHook getOemHookProxy(Message result) {
    399         if (!mIsMobileNetworkSupported) {
    400             if (RILJ_LOGV) riljLog("getOemHookProxy: Not calling getService(): wifi-only");
    401             if (result != null) {
    402                 AsyncResult.forMessage(result, null,
    403                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
    404                 result.sendToTarget();
    405             }
    406             return null;
    407         }
    408 
    409         if (mOemHookProxy != null) {
    410             return mOemHookProxy;
    411         }
    412 
    413         try {
    414             mOemHookProxy = IOemHook.getService(
    415                     HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId], true);
    416             if (mOemHookProxy != null) {
    417                 // not calling linkToDeath() as ril service runs in the same process and death
    418                 // notification for that should be sufficient
    419                 mOemHookProxy.setResponseFunctions(mOemHookResponse, mOemHookIndication);
    420             } else {
    421                 riljLoge("getOemHookProxy: mOemHookProxy == null");
    422             }
    423         } catch (RemoteException | RuntimeException e) {
    424             mOemHookProxy = null;
    425             riljLoge("OemHookProxy getService/setResponseFunctions: " + e);
    426         }
    427 
    428         if (mOemHookProxy == null) {
    429             if (result != null) {
    430                 AsyncResult.forMessage(result, null,
    431                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
    432                 result.sendToTarget();
    433             }
    434         }
    435 
    436         return mOemHookProxy;
    437     }
    438 
    439     //***** Constructors
    440 
    441     public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
    442         this(context, preferredNetworkType, cdmaSubscription, null);
    443     }
    444 
    445     public RIL(Context context, int preferredNetworkType,
    446             int cdmaSubscription, Integer instanceId) {
    447         super(context);
    448         if (RILJ_LOGD) {
    449             riljLog("RIL: init preferredNetworkType=" + preferredNetworkType
    450                     + " cdmaSubscription=" + cdmaSubscription + ")");
    451         }
    452 
    453         mContext = context;
    454         mCdmaSubscription  = cdmaSubscription;
    455         mPreferredNetworkType = preferredNetworkType;
    456         mPhoneType = RILConstants.NO_PHONE;
    457         mPhoneId = instanceId;
    458 
    459         ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
    460                 Context.CONNECTIVITY_SERVICE);
    461         mIsMobileNetworkSupported = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
    462 
    463         mRadioResponse = new RadioResponse(this);
    464         mRadioIndication = new RadioIndication(this);
    465         mOemHookResponse = new OemHookResponse(this);
    466         mOemHookIndication = new OemHookIndication(this);
    467         mRilHandler = new RilHandler();
    468         mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
    469 
    470         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    471         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_WAKELOCK_TAG);
    472         mWakeLock.setReferenceCounted(false);
    473         mAckWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_ACK_WAKELOCK_NAME);
    474         mAckWakeLock.setReferenceCounted(false);
    475         mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
    476                 DEFAULT_WAKE_LOCK_TIMEOUT_MS);
    477         mAckWakeLockTimeout = SystemProperties.getInt(
    478                 TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT, DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS);
    479         mWakeLockCount = 0;
    480         mRILDefaultWorkSource = new WorkSource(context.getApplicationInfo().uid,
    481                 context.getPackageName());
    482 
    483         TelephonyDevController tdc = TelephonyDevController.getInstance();
    484         tdc.registerRIL(this);
    485 
    486         // set radio callback; needed to set RadioIndication callback (should be done after
    487         // wakelock stuff is initialized above as callbacks are received on separate binder threads)
    488         getRadioProxy(null);
    489         getOemHookProxy(null);
    490     }
    491 
    492     @Override
    493     public void setOnNITZTime(Handler h, int what, Object obj) {
    494         super.setOnNITZTime(h, what, obj);
    495 
    496         // Send the last NITZ time if we have it
    497         if (mLastNITZTimeInfo != null) {
    498             mNITZTimeRegistrant
    499                 .notifyRegistrant(
    500                     new AsyncResult (null, mLastNITZTimeInfo, null));
    501         }
    502     }
    503 
    504     private void addRequest(RILRequest rr) {
    505         acquireWakeLock(rr, FOR_WAKELOCK);
    506         synchronized (mRequestList) {
    507             rr.mStartTimeMs = SystemClock.elapsedRealtime();
    508             mRequestList.append(rr.mSerial, rr);
    509         }
    510     }
    511 
    512     private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
    513         RILRequest rr = RILRequest.obtain(request, result, workSource);
    514         addRequest(rr);
    515         return rr;
    516     }
    517 
    518     private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) {
    519         riljLoge(caller + ": " + e);
    520         resetProxyAndRequestList();
    521     }
    522 
    523     private String convertNullToEmptyString(String string) {
    524         return string != null ? string : "";
    525     }
    526 
    527     @Override
    528     public void getIccCardStatus(Message result) {
    529         IRadio radioProxy = getRadioProxy(result);
    530         if (radioProxy != null) {
    531             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_STATUS, result,
    532                     mRILDefaultWorkSource);
    533 
    534             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    535 
    536             try {
    537                 radioProxy.getIccCardStatus(rr.mSerial);
    538             } catch (RemoteException | RuntimeException e) {
    539                 handleRadioProxyExceptionForRR(rr, "getIccCardStatus", e);
    540             }
    541         }
    542     }
    543 
    544     @Override
    545     public void getIccSlotsStatus(Message result) {
    546         if (result != null) {
    547             AsyncResult.forMessage(result, null,
    548                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
    549             result.sendToTarget();
    550         }
    551     }
    552 
    553     @Override
    554     public void setLogicalToPhysicalSlotMapping(int[] physicalSlots, Message result) {
    555         if (result != null) {
    556             AsyncResult.forMessage(result, null,
    557                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
    558             result.sendToTarget();
    559         }
    560     }
    561 
    562     @Override
    563     public void supplyIccPin(String pin, Message result) {
    564         supplyIccPinForApp(pin, null, result);
    565     }
    566 
    567     @Override
    568     public void supplyIccPinForApp(String pin, String aid, Message result) {
    569         IRadio radioProxy = getRadioProxy(result);
    570         if (radioProxy != null) {
    571             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN, result,
    572                     mRILDefaultWorkSource);
    573 
    574             if (RILJ_LOGD) {
    575                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
    576                         + " aid = " + aid);
    577             }
    578 
    579             try {
    580                 radioProxy.supplyIccPinForApp(rr.mSerial,
    581                         convertNullToEmptyString(pin),
    582                         convertNullToEmptyString(aid));
    583             } catch (RemoteException | RuntimeException e) {
    584                 handleRadioProxyExceptionForRR(rr, "supplyIccPinForApp", e);
    585             }
    586         }
    587     }
    588 
    589     @Override
    590     public void supplyIccPuk(String puk, String newPin, Message result) {
    591         supplyIccPukForApp(puk, newPin, null, result);
    592     }
    593 
    594     @Override
    595     public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
    596         IRadio radioProxy = getRadioProxy(result);
    597         if (radioProxy != null) {
    598             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK, result,
    599                     mRILDefaultWorkSource);
    600 
    601             if (RILJ_LOGD) {
    602                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
    603                         + " aid = " + aid);
    604             }
    605 
    606             try {
    607                 radioProxy.supplyIccPukForApp(rr.mSerial,
    608                         convertNullToEmptyString(puk),
    609                         convertNullToEmptyString(newPin),
    610                         convertNullToEmptyString(aid));
    611             } catch (RemoteException | RuntimeException e) {
    612                 handleRadioProxyExceptionForRR(rr, "supplyIccPukForApp", e);
    613             }
    614         }
    615     }
    616 
    617     @Override
    618     public void supplyIccPin2(String pin, Message result) {
    619         supplyIccPin2ForApp(pin, null, result);
    620     }
    621 
    622     @Override
    623     public void supplyIccPin2ForApp(String pin, String aid, Message result) {
    624         IRadio radioProxy = getRadioProxy(result);
    625         if (radioProxy != null) {
    626             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN2, result,
    627                     mRILDefaultWorkSource);
    628 
    629             if (RILJ_LOGD) {
    630                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
    631                         + " aid = " + aid);
    632             }
    633 
    634             try {
    635                 radioProxy.supplyIccPin2ForApp(rr.mSerial,
    636                         convertNullToEmptyString(pin),
    637                         convertNullToEmptyString(aid));
    638             } catch (RemoteException | RuntimeException e) {
    639                 handleRadioProxyExceptionForRR(rr, "supplyIccPin2ForApp", e);
    640             }
    641         }
    642     }
    643 
    644     @Override
    645     public void supplyIccPuk2(String puk2, String newPin2, Message result) {
    646         supplyIccPuk2ForApp(puk2, newPin2, null, result);
    647     }
    648 
    649     @Override
    650     public void supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
    651         IRadio radioProxy = getRadioProxy(result);
    652         if (radioProxy != null) {
    653             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK2, result,
    654                     mRILDefaultWorkSource);
    655 
    656             if (RILJ_LOGD) {
    657                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
    658                         + " aid = " + aid);
    659             }
    660 
    661             try {
    662                 radioProxy.supplyIccPuk2ForApp(rr.mSerial,
    663                         convertNullToEmptyString(puk),
    664                         convertNullToEmptyString(newPin2),
    665                         convertNullToEmptyString(aid));
    666             } catch (RemoteException | RuntimeException e) {
    667                 handleRadioProxyExceptionForRR(rr, "supplyIccPuk2ForApp", e);
    668             }
    669         }
    670     }
    671 
    672     @Override
    673     public void changeIccPin(String oldPin, String newPin, Message result) {
    674         changeIccPinForApp(oldPin, newPin, null, result);
    675     }
    676 
    677     @Override
    678     public void changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
    679         IRadio radioProxy = getRadioProxy(result);
    680         if (radioProxy != null) {
    681             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN, result,
    682                     mRILDefaultWorkSource);
    683 
    684             if (RILJ_LOGD) {
    685                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
    686                         + oldPin + " newPin = " + newPin + " aid = " + aid);
    687             }
    688 
    689             try {
    690                 radioProxy.changeIccPinForApp(rr.mSerial,
    691                         convertNullToEmptyString(oldPin),
    692                         convertNullToEmptyString(newPin),
    693                         convertNullToEmptyString(aid));
    694             } catch (RemoteException | RuntimeException e) {
    695                 handleRadioProxyExceptionForRR(rr, "changeIccPinForApp", e);
    696             }
    697         }
    698     }
    699 
    700     @Override
    701     public void changeIccPin2(String oldPin2, String newPin2, Message result) {
    702         changeIccPin2ForApp(oldPin2, newPin2, null, result);
    703     }
    704 
    705     @Override
    706     public void changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
    707         IRadio radioProxy = getRadioProxy(result);
    708         if (radioProxy != null) {
    709             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN2, result,
    710                     mRILDefaultWorkSource);
    711 
    712             if (RILJ_LOGD) {
    713                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
    714                         + oldPin2 + " newPin = " + newPin2 + " aid = " + aid);
    715             }
    716 
    717             try {
    718                 radioProxy.changeIccPin2ForApp(rr.mSerial,
    719                         convertNullToEmptyString(oldPin2),
    720                         convertNullToEmptyString(newPin2),
    721                         convertNullToEmptyString(aid));
    722             } catch (RemoteException | RuntimeException e) {
    723                 handleRadioProxyExceptionForRR(rr, "changeIccPin2ForApp", e);
    724             }
    725         }
    726     }
    727 
    728     @Override
    729     public void supplyNetworkDepersonalization(String netpin, Message result) {
    730         IRadio radioProxy = getRadioProxy(result);
    731         if (radioProxy != null) {
    732             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result,
    733                     mRILDefaultWorkSource);
    734 
    735             if (RILJ_LOGD) {
    736                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " netpin = "
    737                         + netpin);
    738             }
    739 
    740             try {
    741                 radioProxy.supplyNetworkDepersonalization(rr.mSerial,
    742                         convertNullToEmptyString(netpin));
    743             } catch (RemoteException | RuntimeException e) {
    744                 handleRadioProxyExceptionForRR(rr, "supplyNetworkDepersonalization", e);
    745             }
    746         }
    747     }
    748 
    749     @Override
    750     public void getCurrentCalls(Message result) {
    751         IRadio radioProxy = getRadioProxy(result);
    752         if (radioProxy != null) {
    753             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
    754                     mRILDefaultWorkSource);
    755 
    756             if (RILJ_LOGD) {
    757                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    758             }
    759 
    760             try {
    761                 radioProxy.getCurrentCalls(rr.mSerial);
    762             } catch (RemoteException | RuntimeException e) {
    763                 handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
    764             }
    765         }
    766     }
    767 
    768     @Override
    769     public void dial(String address, int clirMode, Message result) {
    770         dial(address, clirMode, null, result);
    771     }
    772 
    773     @Override
    774     public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
    775         IRadio radioProxy = getRadioProxy(result);
    776         if (radioProxy != null) {
    777             RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result,
    778                     mRILDefaultWorkSource);
    779 
    780             Dial dialInfo = new Dial();
    781             dialInfo.address = convertNullToEmptyString(address);
    782             dialInfo.clir = clirMode;
    783             if (uusInfo != null) {
    784                 UusInfo info = new UusInfo();
    785                 info.uusType = uusInfo.getType();
    786                 info.uusDcs = uusInfo.getDcs();
    787                 info.uusData = new String(uusInfo.getUserData());
    788                 dialInfo.uusInfo.add(info);
    789             }
    790 
    791             if (RILJ_LOGD) {
    792                 // Do not log function arg for privacy
    793                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    794             }
    795 
    796             try {
    797                 radioProxy.dial(rr.mSerial, dialInfo);
    798             } catch (RemoteException | RuntimeException e) {
    799                 handleRadioProxyExceptionForRR(rr, "dial", e);
    800             }
    801         }
    802     }
    803 
    804     @Override
    805     public void getIMSI(Message result) {
    806         getIMSIForApp(null, result);
    807     }
    808 
    809     @Override
    810     public void getIMSIForApp(String aid, Message result) {
    811         IRadio radioProxy = getRadioProxy(result);
    812         if (radioProxy != null) {
    813             RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result,
    814                     mRILDefaultWorkSource);
    815 
    816             if (RILJ_LOGD) {
    817                 riljLog(rr.serialString()
    818                         + ">  " + requestToString(rr.mRequest) + " aid = " + aid);
    819             }
    820             try {
    821                 radioProxy.getImsiForApp(rr.mSerial, convertNullToEmptyString(aid));
    822             } catch (RemoteException | RuntimeException e) {
    823                 handleRadioProxyExceptionForRR(rr, "getIMSIForApp", e);
    824             }
    825         }
    826     }
    827 
    828     @Override
    829     public void hangupConnection(int gsmIndex, Message result) {
    830         IRadio radioProxy = getRadioProxy(result);
    831         if (radioProxy != null) {
    832             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP, result,
    833                     mRILDefaultWorkSource);
    834 
    835             if (RILJ_LOGD) {
    836                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " gsmIndex = "
    837                         + gsmIndex);
    838             }
    839 
    840             try {
    841                 radioProxy.hangup(rr.mSerial, gsmIndex);
    842             } catch (RemoteException | RuntimeException e) {
    843                 handleRadioProxyExceptionForRR(rr, "hangupConnection", e);
    844             }
    845         }
    846     }
    847 
    848     @Override
    849     public void hangupWaitingOrBackground(Message result) {
    850         IRadio radioProxy = getRadioProxy(result);
    851         if (radioProxy != null) {
    852             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, result,
    853                     mRILDefaultWorkSource);
    854 
    855             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    856 
    857             try {
    858                 radioProxy.hangupWaitingOrBackground(rr.mSerial);
    859             } catch (RemoteException | RuntimeException e) {
    860                 handleRadioProxyExceptionForRR(rr, "hangupWaitingOrBackground", e);
    861             }
    862         }
    863     }
    864 
    865     @Override
    866     public void hangupForegroundResumeBackground(Message result) {
    867         IRadio radioProxy = getRadioProxy(result);
    868         if (radioProxy != null) {
    869             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, result,
    870                     mRILDefaultWorkSource);
    871 
    872             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    873 
    874             try {
    875                 radioProxy.hangupForegroundResumeBackground(rr.mSerial);
    876             } catch (RemoteException | RuntimeException e) {
    877                 handleRadioProxyExceptionForRR(rr, "hangupForegroundResumeBackground", e);
    878             }
    879         }
    880     }
    881 
    882     @Override
    883     public void switchWaitingOrHoldingAndActive(Message result) {
    884         IRadio radioProxy = getRadioProxy(result);
    885         if (radioProxy != null) {
    886             RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, result,
    887                     mRILDefaultWorkSource);
    888 
    889             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    890 
    891             try {
    892                 radioProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
    893             } catch (RemoteException | RuntimeException e) {
    894                 handleRadioProxyExceptionForRR(rr, "switchWaitingOrHoldingAndActive", e);
    895             }
    896         }
    897     }
    898 
    899     @Override
    900     public void conference(Message result) {
    901         IRadio radioProxy = getRadioProxy(result);
    902         if (radioProxy != null) {
    903             RILRequest rr = obtainRequest(RIL_REQUEST_CONFERENCE, result,
    904                     mRILDefaultWorkSource);
    905 
    906             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    907 
    908             try {
    909                 radioProxy.conference(rr.mSerial);
    910             } catch (RemoteException | RuntimeException e) {
    911                 handleRadioProxyExceptionForRR(rr, "conference", e);
    912             }
    913         }
    914     }
    915 
    916     @Override
    917     public void rejectCall(Message result) {
    918         IRadio radioProxy = getRadioProxy(result);
    919         if (radioProxy != null) {
    920             RILRequest rr = obtainRequest(RIL_REQUEST_UDUB, result,
    921                     mRILDefaultWorkSource);
    922 
    923             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    924 
    925             try {
    926                 radioProxy.rejectCall(rr.mSerial);
    927             } catch (RemoteException | RuntimeException e) {
    928                 handleRadioProxyExceptionForRR(rr, "rejectCall", e);
    929             }
    930         }
    931     }
    932 
    933     @Override
    934     public void getLastCallFailCause(Message result) {
    935         IRadio radioProxy = getRadioProxy(result);
    936         if (radioProxy != null) {
    937             RILRequest rr = obtainRequest(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result,
    938                     mRILDefaultWorkSource);
    939 
    940             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    941 
    942             try {
    943                 radioProxy.getLastCallFailCause(rr.mSerial);
    944             } catch (RemoteException | RuntimeException e) {
    945                 handleRadioProxyExceptionForRR(rr, "getLastCallFailCause", e);
    946             }
    947         }
    948     }
    949 
    950     @Override
    951     public void getSignalStrength(Message result) {
    952         IRadio radioProxy = getRadioProxy(result);
    953         if (radioProxy != null) {
    954             RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
    955                     mRILDefaultWorkSource);
    956 
    957             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    958 
    959             try {
    960                 radioProxy.getSignalStrength(rr.mSerial);
    961             } catch (RemoteException | RuntimeException e) {
    962                 handleRadioProxyExceptionForRR(rr, "getSignalStrength", e);
    963             }
    964         }
    965     }
    966 
    967     @Override
    968     public void getVoiceRegistrationState(Message result) {
    969         IRadio radioProxy = getRadioProxy(result);
    970         if (radioProxy != null) {
    971             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE, result,
    972                     mRILDefaultWorkSource);
    973 
    974             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    975 
    976             try {
    977                 radioProxy.getVoiceRegistrationState(rr.mSerial);
    978             } catch (RemoteException | RuntimeException e) {
    979                 handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState", e);
    980             }
    981         }
    982     }
    983 
    984     @Override
    985     public void getDataRegistrationState(Message result) {
    986         IRadio radioProxy = getRadioProxy(result);
    987         if (radioProxy != null) {
    988             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_REGISTRATION_STATE, result,
    989                     mRILDefaultWorkSource);
    990 
    991             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    992 
    993             try {
    994                 radioProxy.getDataRegistrationState(rr.mSerial);
    995             } catch (RemoteException | RuntimeException e) {
    996                 handleRadioProxyExceptionForRR(rr, "getDataRegistrationState", e);
    997             }
    998         }
    999     }
   1000 
   1001     @Override
   1002     public void getOperator(Message result) {
   1003         IRadio radioProxy = getRadioProxy(result);
   1004         if (radioProxy != null) {
   1005             RILRequest rr = obtainRequest(RIL_REQUEST_OPERATOR, result,
   1006                     mRILDefaultWorkSource);
   1007 
   1008             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1009 
   1010             try {
   1011                 radioProxy.getOperator(rr.mSerial);
   1012             } catch (RemoteException | RuntimeException e) {
   1013                 handleRadioProxyExceptionForRR(rr, "getOperator", e);
   1014             }
   1015         }
   1016     }
   1017 
   1018     @Override
   1019     public void setRadioPower(boolean on, Message result) {
   1020         IRadio radioProxy = getRadioProxy(result);
   1021         if (radioProxy != null) {
   1022             RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result,
   1023                     mRILDefaultWorkSource);
   1024 
   1025             if (RILJ_LOGD) {
   1026                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1027                         + " on = " + on);
   1028             }
   1029 
   1030             try {
   1031                 radioProxy.setRadioPower(rr.mSerial, on);
   1032             } catch (RemoteException | RuntimeException e) {
   1033                 handleRadioProxyExceptionForRR(rr, "setRadioPower", e);
   1034             }
   1035         }
   1036     }
   1037 
   1038     @Override
   1039     public void sendDtmf(char c, Message result) {
   1040         IRadio radioProxy = getRadioProxy(result);
   1041         if (radioProxy != null) {
   1042             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF, result,
   1043                     mRILDefaultWorkSource);
   1044 
   1045             if (RILJ_LOGD) {
   1046                 // Do not log function arg for privacy
   1047                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1048             }
   1049 
   1050             try {
   1051                 radioProxy.sendDtmf(rr.mSerial, c + "");
   1052             } catch (RemoteException | RuntimeException e) {
   1053                 handleRadioProxyExceptionForRR(rr, "sendDtmf", e);
   1054             }
   1055         }
   1056     }
   1057 
   1058     private GsmSmsMessage constructGsmSendSmsRilRequest(String smscPdu, String pdu) {
   1059         GsmSmsMessage msg = new GsmSmsMessage();
   1060         msg.smscPdu = smscPdu == null ? "" : smscPdu;
   1061         msg.pdu = pdu == null ? "" : pdu;
   1062         return msg;
   1063     }
   1064 
   1065     @Override
   1066     public void sendSMS(String smscPdu, String pdu, Message result) {
   1067         IRadio radioProxy = getRadioProxy(result);
   1068         if (radioProxy != null) {
   1069             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS, result,
   1070                     mRILDefaultWorkSource);
   1071 
   1072             // Do not log function args for privacy
   1073             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1074 
   1075             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
   1076 
   1077             try {
   1078                 radioProxy.sendSms(rr.mSerial, msg);
   1079                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
   1080                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
   1081             } catch (RemoteException | RuntimeException e) {
   1082                 handleRadioProxyExceptionForRR(rr, "sendSMS", e);
   1083             }
   1084         }
   1085     }
   1086 
   1087     @Override
   1088     public void sendSMSExpectMore(String smscPdu, String pdu, Message result) {
   1089         IRadio radioProxy = getRadioProxy(result);
   1090         if (radioProxy != null) {
   1091             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS_EXPECT_MORE, result,
   1092                     mRILDefaultWorkSource);
   1093 
   1094             // Do not log function arg for privacy
   1095             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1096 
   1097             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
   1098 
   1099             try {
   1100                 radioProxy.sendSMSExpectMore(rr.mSerial, msg);
   1101                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
   1102                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
   1103             } catch (RemoteException | RuntimeException e) {
   1104                 handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
   1105             }
   1106         }
   1107     }
   1108 
   1109     /**
   1110      * Convert MVNO type string into MvnoType defined in types.hal.
   1111      * @param mvnoType MVNO type
   1112      * @return MVNO type in integer
   1113      */
   1114     private static int convertToHalMvnoType(String mvnoType) {
   1115         switch (mvnoType) {
   1116             case "imsi" : return MvnoType.IMSI;
   1117             case "gid" : return MvnoType.GID;
   1118             case "spn" : return MvnoType.SPN;
   1119             default: return MvnoType.NONE;
   1120         }
   1121     }
   1122 
   1123     /**
   1124      * Convert to DataProfileInfo defined in types.hal
   1125      * @param dp Data profile
   1126      * @return A converted data profile
   1127      */
   1128     private static DataProfileInfo convertToHalDataProfile(DataProfile dp) {
   1129         DataProfileInfo dpi = new DataProfileInfo();
   1130 
   1131         dpi.profileId = dp.getProfileId();
   1132         dpi.apn = dp.getApn();
   1133         dpi.protocol = dp.getProtocol();
   1134         dpi.roamingProtocol = dp.getRoamingProtocol();
   1135         dpi.authType = dp.getAuthType();
   1136         dpi.user = dp.getUserName();
   1137         dpi.password = dp.getPassword();
   1138         dpi.type = dp.getType();
   1139         dpi.maxConnsTime = dp.getMaxConnsTime();
   1140         dpi.maxConns = dp.getMaxConns();
   1141         dpi.waitTime = dp.getWaitTime();
   1142         dpi.enabled = dp.isEnabled();
   1143         dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmap();
   1144         dpi.bearerBitmap = dp.getBearerBitmap();
   1145         dpi.mtu = dp.getMtu();
   1146         dpi.mvnoType = convertToHalMvnoType(dp.getMvnoType());
   1147         dpi.mvnoMatchData = dp.getMvnoMatchData();
   1148 
   1149         return dpi;
   1150     }
   1151 
   1152     /**
   1153      * Convert NV reset type into ResetNvType defined in types.hal.
   1154      * @param resetType NV reset type.
   1155      * @return Converted reset type in integer or -1 if param is invalid.
   1156      */
   1157     private static int convertToHalResetNvType(int resetType) {
   1158         /**
   1159          * resetType values
   1160          * 1 - reload all NV items
   1161          * 2 - erase NV reset (SCRTN)
   1162          * 3 - factory reset (RTN)
   1163          */
   1164         switch (resetType) {
   1165             case 1: return ResetNvType.RELOAD;
   1166             case 2: return ResetNvType.ERASE;
   1167             case 3: return ResetNvType.FACTORY_RESET;
   1168         }
   1169         return -1;
   1170     }
   1171 
   1172     @Override
   1173     public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
   1174                               boolean allowRoaming, int reason, LinkProperties linkProperties,
   1175                               Message result) {
   1176 
   1177         IRadio radioProxy = getRadioProxy(result);
   1178 
   1179         if (radioProxy != null) {
   1180 
   1181             RILRequest rr = obtainRequest(RIL_REQUEST_SETUP_DATA_CALL, result,
   1182                     mRILDefaultWorkSource);
   1183 
   1184             // Convert to HAL data profile
   1185             DataProfileInfo dpi = convertToHalDataProfile(dataProfile);
   1186 
   1187             android.hardware.radio.V1_2.IRadio radioProxy12 =
   1188                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   1189             try {
   1190                 if (radioProxy12 == null) {
   1191                     // IRadio V1.0
   1192 
   1193                     // Getting data RAT here is just a workaround to support the older 1.0 vendor
   1194                     // RIL. The new data service interface passes access network type instead of
   1195                     // RAT for setup data request. It is impossible to convert access network
   1196                     // type back to RAT here, so we directly get the data RAT from phone.
   1197                     int dataRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
   1198                     Phone phone = PhoneFactory.getPhone(mPhoneId);
   1199                     if (phone != null) {
   1200                         ServiceState ss = phone.getServiceState();
   1201                         if (ss != null) {
   1202                             dataRat = ss.getRilDataRadioTechnology();
   1203                         }
   1204                     }
   1205                     if (RILJ_LOGD) {
   1206                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1207                                 + ",dataRat=" + dataRat + ",isRoaming=" + isRoaming
   1208                                 + ",allowRoaming=" + allowRoaming + "," + dataProfile);
   1209                     }
   1210 
   1211                     radioProxy.setupDataCall(rr.mSerial, dataRat, dpi,
   1212                             dataProfile.isModemCognitive(), allowRoaming, isRoaming);
   1213                 } else {
   1214                     // IRadio V1.2
   1215                     ArrayList<String> addresses = new ArrayList<>();
   1216                     ArrayList<String> dnses = new ArrayList<>();
   1217                     if (linkProperties != null) {
   1218                         for (InetAddress address : linkProperties.getAddresses()) {
   1219                             addresses.add(address.getHostAddress());
   1220                         }
   1221                         for (InetAddress dns : linkProperties.getDnsServers()) {
   1222                             dnses.add(dns.getHostAddress());
   1223                         }
   1224                     }
   1225 
   1226                     if (RILJ_LOGD) {
   1227                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1228                                 + ",accessNetworkType=" + accessNetworkType + ",isRoaming="
   1229                                 + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
   1230                                 + ",addresses=" + addresses + ",dnses=" + dnses);
   1231                     }
   1232 
   1233                     radioProxy12.setupDataCall_1_2(rr.mSerial, accessNetworkType, dpi,
   1234                             dataProfile.isModemCognitive(), allowRoaming, isRoaming, reason,
   1235                             addresses, dnses);
   1236                 }
   1237             } catch (RemoteException | RuntimeException e) {
   1238                 handleRadioProxyExceptionForRR(rr, "setupDataCall", e);
   1239             }
   1240         }
   1241     }
   1242 
   1243     @Override
   1244     public void iccIO(int command, int fileId, String path, int p1, int p2, int p3,
   1245                       String data, String pin2, Message result) {
   1246         iccIOForApp(command, fileId, path, p1, p2, p3, data, pin2, null, result);
   1247     }
   1248 
   1249     @Override
   1250     public void iccIOForApp(int command, int fileId, String path, int p1, int p2, int p3,
   1251                  String data, String pin2, String aid, Message result) {
   1252         IRadio radioProxy = getRadioProxy(result);
   1253         if (radioProxy != null) {
   1254             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_IO, result,
   1255                     mRILDefaultWorkSource);
   1256 
   1257             if (RILJ_LOGD) {
   1258                 if (Build.IS_DEBUGGABLE) {
   1259                     riljLog(rr.serialString() + "> iccIO: "
   1260                             + requestToString(rr.mRequest) + " command = 0x"
   1261                             + Integer.toHexString(command) + " fileId = 0x"
   1262                             + Integer.toHexString(fileId) + " path = " + path + " p1 = "
   1263                             + p1 + " p2 = " + p2 + " p3 = " + " data = " + data
   1264                             + " aid = " + aid);
   1265                 } else {
   1266                     riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest));
   1267                 }
   1268             }
   1269 
   1270             IccIo iccIo = new IccIo();
   1271             iccIo.command = command;
   1272             iccIo.fileId = fileId;
   1273             iccIo.path = convertNullToEmptyString(path);
   1274             iccIo.p1 = p1;
   1275             iccIo.p2 = p2;
   1276             iccIo.p3 = p3;
   1277             iccIo.data = convertNullToEmptyString(data);
   1278             iccIo.pin2 = convertNullToEmptyString(pin2);
   1279             iccIo.aid = convertNullToEmptyString(aid);
   1280 
   1281             try {
   1282                 radioProxy.iccIOForApp(rr.mSerial, iccIo);
   1283             } catch (RemoteException | RuntimeException e) {
   1284                 handleRadioProxyExceptionForRR(rr, "iccIOForApp", e);
   1285             }
   1286         }
   1287     }
   1288 
   1289     @Override
   1290     public void sendUSSD(String ussd, Message result) {
   1291         IRadio radioProxy = getRadioProxy(result);
   1292         if (radioProxy != null) {
   1293             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_USSD, result,
   1294                     mRILDefaultWorkSource);
   1295 
   1296             if (RILJ_LOGD) {
   1297                 String logUssd = "*******";
   1298                 if (RILJ_LOGV) logUssd = ussd;
   1299                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1300                         + " ussd = " + logUssd);
   1301             }
   1302 
   1303             try {
   1304                 radioProxy.sendUssd(rr.mSerial, convertNullToEmptyString(ussd));
   1305             } catch (RemoteException | RuntimeException e) {
   1306                 handleRadioProxyExceptionForRR(rr, "sendUSSD", e);
   1307             }
   1308         }
   1309     }
   1310 
   1311     @Override
   1312     public void cancelPendingUssd(Message result) {
   1313         IRadio radioProxy = getRadioProxy(result);
   1314         if (radioProxy != null) {
   1315             RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_USSD, result,
   1316                     mRILDefaultWorkSource);
   1317 
   1318             if (RILJ_LOGD) {
   1319                 riljLog(rr.serialString()
   1320                         + "> " + requestToString(rr.mRequest));
   1321             }
   1322 
   1323             try {
   1324                 radioProxy.cancelPendingUssd(rr.mSerial);
   1325             } catch (RemoteException | RuntimeException e) {
   1326                 handleRadioProxyExceptionForRR(rr, "cancelPendingUssd", e);
   1327             }
   1328         }
   1329     }
   1330 
   1331     @Override
   1332     public void getCLIR(Message result) {
   1333         IRadio radioProxy = getRadioProxy(result);
   1334         if (radioProxy != null) {
   1335             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CLIR, result,
   1336                     mRILDefaultWorkSource);
   1337 
   1338             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1339 
   1340             try {
   1341                 radioProxy.getClir(rr.mSerial);
   1342             } catch (RemoteException | RuntimeException e) {
   1343                 handleRadioProxyExceptionForRR(rr, "getCLIR", e);
   1344             }
   1345         }
   1346     }
   1347 
   1348     @Override
   1349     public void setCLIR(int clirMode, Message result) {
   1350         IRadio radioProxy = getRadioProxy(result);
   1351         if (radioProxy != null) {
   1352             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CLIR, result, mRILDefaultWorkSource);
   1353 
   1354             if (RILJ_LOGD) {
   1355                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1356                         + " clirMode = " + clirMode);
   1357             }
   1358 
   1359             try {
   1360                 radioProxy.setClir(rr.mSerial, clirMode);
   1361             } catch (RemoteException | RuntimeException e) {
   1362                 handleRadioProxyExceptionForRR(rr, "setCLIR", e);
   1363             }
   1364         }
   1365     }
   1366 
   1367     @Override
   1368     public void queryCallForwardStatus(int cfReason, int serviceClass,
   1369                            String number, Message result) {
   1370         IRadio radioProxy = getRadioProxy(result);
   1371         if (radioProxy != null) {
   1372             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
   1373                     mRILDefaultWorkSource);
   1374 
   1375             if (RILJ_LOGD) {
   1376                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1377                         + " cfreason = " + cfReason + " serviceClass = " + serviceClass);
   1378             }
   1379 
   1380             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
   1381                     new android.hardware.radio.V1_0.CallForwardInfo();
   1382             cfInfo.reason = cfReason;
   1383             cfInfo.serviceClass = serviceClass;
   1384             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
   1385             cfInfo.number = convertNullToEmptyString(number);
   1386             cfInfo.timeSeconds = 0;
   1387 
   1388             try {
   1389                 radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
   1390             } catch (RemoteException | RuntimeException e) {
   1391                 handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
   1392             }
   1393         }
   1394     }
   1395 
   1396     @Override
   1397     public void setCallForward(int action, int cfReason, int serviceClass,
   1398                    String number, int timeSeconds, Message result) {
   1399         IRadio radioProxy = getRadioProxy(result);
   1400         if (radioProxy != null) {
   1401             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_FORWARD, result,
   1402                     mRILDefaultWorkSource);
   1403 
   1404             if (RILJ_LOGD) {
   1405                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1406                         + " action = " + action + " cfReason = " + cfReason + " serviceClass = "
   1407                         + serviceClass + " timeSeconds = " + timeSeconds);
   1408             }
   1409 
   1410             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
   1411                     new android.hardware.radio.V1_0.CallForwardInfo();
   1412             cfInfo.status = action;
   1413             cfInfo.reason = cfReason;
   1414             cfInfo.serviceClass = serviceClass;
   1415             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
   1416             cfInfo.number = convertNullToEmptyString(number);
   1417             cfInfo.timeSeconds = timeSeconds;
   1418 
   1419             try {
   1420                 radioProxy.setCallForward(rr.mSerial, cfInfo);
   1421             } catch (RemoteException | RuntimeException e) {
   1422                 handleRadioProxyExceptionForRR(rr, "setCallForward", e);
   1423 
   1424             }
   1425         }
   1426     }
   1427 
   1428     @Override
   1429     public void queryCallWaiting(int serviceClass, Message result) {
   1430         IRadio radioProxy = getRadioProxy(result);
   1431         if (radioProxy != null) {
   1432             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_WAITING, result,
   1433                     mRILDefaultWorkSource);
   1434 
   1435             if (RILJ_LOGD) {
   1436                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1437                         + " serviceClass = " + serviceClass);
   1438             }
   1439 
   1440             try {
   1441                 radioProxy.getCallWaiting(rr.mSerial, serviceClass);
   1442             } catch (RemoteException | RuntimeException e) {
   1443                 handleRadioProxyExceptionForRR(rr, "queryCallWaiting", e);
   1444             }
   1445         }
   1446     }
   1447 
   1448     @Override
   1449     public void setCallWaiting(boolean enable, int serviceClass, Message result) {
   1450         IRadio radioProxy = getRadioProxy(result);
   1451         if (radioProxy != null) {
   1452             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_WAITING, result,
   1453                     mRILDefaultWorkSource);
   1454 
   1455             if (RILJ_LOGD) {
   1456                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1457                         + " enable = " + enable + " serviceClass = " + serviceClass);
   1458             }
   1459 
   1460             try {
   1461                 radioProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
   1462             } catch (RemoteException | RuntimeException e) {
   1463                 handleRadioProxyExceptionForRR(rr, "setCallWaiting", e);
   1464             }
   1465         }
   1466     }
   1467 
   1468     @Override
   1469     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
   1470         IRadio radioProxy = getRadioProxy(result);
   1471         if (radioProxy != null) {
   1472             RILRequest rr = obtainRequest(RIL_REQUEST_SMS_ACKNOWLEDGE, result,
   1473                     mRILDefaultWorkSource);
   1474 
   1475             if (RILJ_LOGD) {
   1476                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1477                         + " success = " + success + " cause = " + cause);
   1478             }
   1479 
   1480             try {
   1481                 radioProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
   1482             } catch (RemoteException | RuntimeException e) {
   1483                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingGsmSms", e);
   1484             }
   1485         }
   1486     }
   1487 
   1488     @Override
   1489     public void acceptCall(Message result) {
   1490         IRadio radioProxy = getRadioProxy(result);
   1491         if (radioProxy != null) {
   1492             RILRequest rr = obtainRequest(RIL_REQUEST_ANSWER, result,
   1493                     mRILDefaultWorkSource);
   1494 
   1495             if (RILJ_LOGD) {
   1496                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1497             }
   1498 
   1499             try {
   1500                 radioProxy.acceptCall(rr.mSerial);
   1501                 mMetrics.writeRilAnswer(mPhoneId, rr.mSerial);
   1502             } catch (RemoteException | RuntimeException e) {
   1503                 handleRadioProxyExceptionForRR(rr, "acceptCall", e);
   1504             }
   1505         }
   1506     }
   1507 
   1508     @Override
   1509     public void deactivateDataCall(int cid, int reason, Message result) {
   1510         IRadio radioProxy = getRadioProxy(result);
   1511         if (radioProxy != null) {
   1512             RILRequest rr = obtainRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, result,
   1513                     mRILDefaultWorkSource);
   1514 
   1515             if (RILJ_LOGD) {
   1516                 riljLog(rr.serialString() + "> "
   1517                         + requestToString(rr.mRequest) + " cid = " + cid + " reason = " + reason);
   1518             }
   1519 
   1520             android.hardware.radio.V1_2.IRadio radioProxy12 =
   1521                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   1522 
   1523             try {
   1524                 if (radioProxy12 == null) {
   1525                     radioProxy.deactivateDataCall(rr.mSerial, cid,
   1526                             (reason == DataService.REQUEST_REASON_SHUTDOWN));
   1527                 } else {
   1528                     radioProxy12.deactivateDataCall_1_2(rr.mSerial, cid, reason);
   1529                 }
   1530                 mMetrics.writeRilDeactivateDataCall(mPhoneId, rr.mSerial, cid, reason);
   1531             } catch (RemoteException | RuntimeException e) {
   1532                 handleRadioProxyExceptionForRR(rr, "deactivateDataCall", e);
   1533             }
   1534         }
   1535     }
   1536 
   1537     @Override
   1538     public void queryFacilityLock(String facility, String password, int serviceClass,
   1539                                   Message result) {
   1540         queryFacilityLockForApp(facility, password, serviceClass, null, result);
   1541     }
   1542 
   1543     @Override
   1544     public void queryFacilityLockForApp(String facility, String password, int serviceClass,
   1545                                         String appId, Message result) {
   1546         IRadio radioProxy = getRadioProxy(result);
   1547         if (radioProxy != null) {
   1548             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_FACILITY_LOCK, result,
   1549                     mRILDefaultWorkSource);
   1550 
   1551             if (RILJ_LOGD) {
   1552                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1553                         + " facility = " + facility + " serviceClass = " + serviceClass
   1554                         + " appId = " + appId);
   1555             }
   1556 
   1557             try {
   1558                 radioProxy.getFacilityLockForApp(rr.mSerial,
   1559                         convertNullToEmptyString(facility),
   1560                         convertNullToEmptyString(password),
   1561                         serviceClass,
   1562                         convertNullToEmptyString(appId));
   1563             } catch (RemoteException | RuntimeException e) {
   1564                 handleRadioProxyExceptionForRR(rr, "getFacilityLockForApp", e);
   1565             }
   1566         }
   1567     }
   1568 
   1569     @Override
   1570     public void setFacilityLock(String facility, boolean lockState, String password,
   1571                                 int serviceClass, Message result) {
   1572         setFacilityLockForApp(facility, lockState, password, serviceClass, null, result);
   1573     }
   1574 
   1575     @Override
   1576     public void setFacilityLockForApp(String facility, boolean lockState, String password,
   1577                                       int serviceClass, String appId, Message result) {
   1578         IRadio radioProxy = getRadioProxy(result);
   1579         if (radioProxy != null) {
   1580             RILRequest rr = obtainRequest(RIL_REQUEST_SET_FACILITY_LOCK, result,
   1581                     mRILDefaultWorkSource);
   1582 
   1583             if (RILJ_LOGD) {
   1584                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1585                         + " facility = " + facility + " lockstate = " + lockState
   1586                         + " serviceClass = " + serviceClass + " appId = " + appId);
   1587             }
   1588 
   1589             try {
   1590                 radioProxy.setFacilityLockForApp(rr.mSerial,
   1591                         convertNullToEmptyString(facility),
   1592                         lockState,
   1593                         convertNullToEmptyString(password),
   1594                         serviceClass,
   1595                         convertNullToEmptyString(appId));
   1596             } catch (RemoteException | RuntimeException e) {
   1597                 handleRadioProxyExceptionForRR(rr, "setFacilityLockForApp", e);
   1598             }
   1599         }
   1600     }
   1601 
   1602     @Override
   1603     public void changeBarringPassword(String facility, String oldPwd, String newPwd,
   1604                                       Message result) {
   1605         IRadio radioProxy = getRadioProxy(result);
   1606         if (radioProxy != null) {
   1607             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result,
   1608                     mRILDefaultWorkSource);
   1609 
   1610             // Do not log all function args for privacy
   1611             if (RILJ_LOGD) {
   1612                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1613                         + "facility = " + facility);
   1614             }
   1615 
   1616             try {
   1617                 radioProxy.setBarringPassword(rr.mSerial,
   1618                         convertNullToEmptyString(facility),
   1619                         convertNullToEmptyString(oldPwd),
   1620                         convertNullToEmptyString(newPwd));
   1621             } catch (RemoteException | RuntimeException e) {
   1622                 handleRadioProxyExceptionForRR(rr, "changeBarringPassword", e);
   1623             }
   1624         }
   1625     }
   1626 
   1627     @Override
   1628     public void getNetworkSelectionMode(Message result) {
   1629         IRadio radioProxy = getRadioProxy(result);
   1630         if (radioProxy != null) {
   1631             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, result,
   1632                     mRILDefaultWorkSource);
   1633 
   1634             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1635 
   1636             try {
   1637                 radioProxy.getNetworkSelectionMode(rr.mSerial);
   1638             } catch (RemoteException | RuntimeException e) {
   1639                 handleRadioProxyExceptionForRR(rr, "getNetworkSelectionMode", e);
   1640             }
   1641         }
   1642     }
   1643 
   1644     @Override
   1645     public void setNetworkSelectionModeAutomatic(Message result) {
   1646         IRadio radioProxy = getRadioProxy(result);
   1647         if (radioProxy != null) {
   1648             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, result,
   1649                     mRILDefaultWorkSource);
   1650 
   1651             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1652 
   1653             try {
   1654                 radioProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
   1655             } catch (RemoteException | RuntimeException e) {
   1656                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeAutomatic", e);
   1657             }
   1658         }
   1659     }
   1660 
   1661     @Override
   1662     public void setNetworkSelectionModeManual(String operatorNumeric, Message result) {
   1663         IRadio radioProxy = getRadioProxy(result);
   1664         if (radioProxy != null) {
   1665             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, result,
   1666                     mRILDefaultWorkSource);
   1667 
   1668             if (RILJ_LOGD) {
   1669                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1670                         + " operatorNumeric = " + operatorNumeric);
   1671             }
   1672 
   1673             try {
   1674                 radioProxy.setNetworkSelectionModeManual(rr.mSerial,
   1675                         convertNullToEmptyString(operatorNumeric));
   1676             } catch (RemoteException | RuntimeException e) {
   1677                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeManual", e);
   1678             }
   1679         }
   1680     }
   1681 
   1682     @Override
   1683     public void getAvailableNetworks(Message result) {
   1684         IRadio radioProxy = getRadioProxy(result);
   1685         if (radioProxy != null) {
   1686             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, result,
   1687                     mRILDefaultWorkSource);
   1688 
   1689             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1690 
   1691             try {
   1692                 radioProxy.getAvailableNetworks(rr.mSerial);
   1693             } catch (RemoteException | RuntimeException e) {
   1694                 handleRadioProxyExceptionForRR(rr, "getAvailableNetworks", e);
   1695             }
   1696         }
   1697     }
   1698 
   1699     private android.hardware.radio.V1_1.RadioAccessSpecifier convertRadioAccessSpecifierToRadioHAL(
   1700             RadioAccessSpecifier ras) {
   1701         android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
   1702                 new android.hardware.radio.V1_1.RadioAccessSpecifier();
   1703         rasInHalFormat.radioAccessNetwork = ras.getRadioAccessNetwork();
   1704         List<Integer> bands = null;
   1705         switch (ras.getRadioAccessNetwork()) {
   1706             case AccessNetworkType.GERAN:
   1707                 bands = rasInHalFormat.geranBands;
   1708                 break;
   1709             case AccessNetworkType.UTRAN:
   1710                 bands = rasInHalFormat.utranBands;
   1711                 break;
   1712             case AccessNetworkType.EUTRAN:
   1713                 bands = rasInHalFormat.eutranBands;
   1714                 break;
   1715             default:
   1716                 Log.wtf(RILJ_LOG_TAG, "radioAccessNetwork " + ras.getRadioAccessNetwork()
   1717                         + " not supported!");
   1718                 return null;
   1719         }
   1720 
   1721         if (ras.getBands() != null) {
   1722             for (int band : ras.getBands()) {
   1723                 bands.add(band);
   1724             }
   1725         }
   1726         if (ras.getChannels() != null) {
   1727             for (int channel : ras.getChannels()) {
   1728                 rasInHalFormat.channels.add(channel);
   1729             }
   1730         }
   1731 
   1732         return rasInHalFormat;
   1733     }
   1734 
   1735     @Override
   1736     public void startNetworkScan(NetworkScanRequest nsr, Message result) {
   1737         IRadio radioProxy = getRadioProxy(result);
   1738         if (radioProxy != null) {
   1739             android.hardware.radio.V1_2.IRadio radioProxy12 =
   1740                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   1741             if (radioProxy12 != null) {
   1742                 android.hardware.radio.V1_2.NetworkScanRequest request =
   1743                         new android.hardware.radio.V1_2.NetworkScanRequest();
   1744                 request.type = nsr.getScanType();
   1745                 request.interval = nsr.getSearchPeriodicity();
   1746                 request.maxSearchTime = nsr.getMaxSearchTime();
   1747                 request.incrementalResultsPeriodicity = nsr.getIncrementalResultsPeriodicity();
   1748                 request.incrementalResults = nsr.getIncrementalResults();
   1749 
   1750                 for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
   1751 
   1752                     android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
   1753                             convertRadioAccessSpecifierToRadioHAL(ras);
   1754                     if (rasInHalFormat == null) {
   1755                         return;
   1756                     }
   1757 
   1758                     request.specifiers.add(rasInHalFormat);
   1759                 }
   1760 
   1761                 request.mccMncs.addAll(nsr.getPlmns());
   1762                 RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
   1763                         mRILDefaultWorkSource);
   1764 
   1765                 if (RILJ_LOGD) {
   1766                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1767                 }
   1768 
   1769                 try {
   1770                     radioProxy12.startNetworkScan_1_2(rr.mSerial, request);
   1771                 } catch (RemoteException | RuntimeException e) {
   1772                     handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
   1773                 }
   1774             } else {
   1775                 android.hardware.radio.V1_1.IRadio radioProxy11 =
   1776                         android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   1777                 if (radioProxy11 == null) {
   1778                     if (result != null) {
   1779                         AsyncResult.forMessage(result, null,
   1780                                 CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   1781                         result.sendToTarget();
   1782                     }
   1783                 } else {
   1784                     android.hardware.radio.V1_1.NetworkScanRequest request =
   1785                             new android.hardware.radio.V1_1.NetworkScanRequest();
   1786                     request.type = nsr.getScanType();
   1787                     request.interval = nsr.getSearchPeriodicity();
   1788                     for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
   1789                         android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
   1790                                 convertRadioAccessSpecifierToRadioHAL(ras);
   1791                         if (rasInHalFormat == null) {
   1792                             return;
   1793                         }
   1794 
   1795                         request.specifiers.add(rasInHalFormat);
   1796                     }
   1797 
   1798                     RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
   1799                             mRILDefaultWorkSource);
   1800 
   1801                     if (RILJ_LOGD) {
   1802                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1803                     }
   1804 
   1805                     try {
   1806                         radioProxy11.startNetworkScan(rr.mSerial, request);
   1807                     } catch (RemoteException | RuntimeException e) {
   1808                         handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
   1809                     }
   1810                 }
   1811             }
   1812         }
   1813     }
   1814 
   1815     @Override
   1816     public void stopNetworkScan(Message result) {
   1817         IRadio radioProxy = getRadioProxy(result);
   1818         if (radioProxy != null) {
   1819             android.hardware.radio.V1_1.IRadio radioProxy11 =
   1820                     android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   1821             if (radioProxy11 == null) {
   1822                 if (result != null) {
   1823                     AsyncResult.forMessage(result, null,
   1824                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   1825                     result.sendToTarget();
   1826                 }
   1827             } else {
   1828                 RILRequest rr = obtainRequest(RIL_REQUEST_STOP_NETWORK_SCAN, result,
   1829                         mRILDefaultWorkSource);
   1830 
   1831                 if (RILJ_LOGD) {
   1832                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1833                 }
   1834 
   1835                 try {
   1836                     radioProxy11.stopNetworkScan(rr.mSerial);
   1837                 } catch (RemoteException | RuntimeException e) {
   1838                     handleRadioProxyExceptionForRR(rr, "stopNetworkScan", e);
   1839                 }
   1840             }
   1841         }
   1842     }
   1843 
   1844     @Override
   1845     public void startDtmf(char c, Message result) {
   1846         IRadio radioProxy = getRadioProxy(result);
   1847         if (radioProxy != null) {
   1848             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_START, result,
   1849                     mRILDefaultWorkSource);
   1850 
   1851             // Do not log function arg for privacy
   1852             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1853 
   1854             try {
   1855                 radioProxy.startDtmf(rr.mSerial, c + "");
   1856             } catch (RemoteException | RuntimeException e) {
   1857                 handleRadioProxyExceptionForRR(rr, "startDtmf", e);
   1858             }
   1859         }
   1860     }
   1861 
   1862     @Override
   1863     public void stopDtmf(Message result) {
   1864         IRadio radioProxy = getRadioProxy(result);
   1865         if (radioProxy != null) {
   1866             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_STOP, result,
   1867                     mRILDefaultWorkSource);
   1868 
   1869             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1870 
   1871             try {
   1872                 radioProxy.stopDtmf(rr.mSerial);
   1873             } catch (RemoteException | RuntimeException e) {
   1874                 handleRadioProxyExceptionForRR(rr, "stopDtmf", e);
   1875             }
   1876         }
   1877     }
   1878 
   1879     @Override
   1880     public void separateConnection(int gsmIndex, Message result) {
   1881         IRadio radioProxy = getRadioProxy(result);
   1882         if (radioProxy != null) {
   1883             RILRequest rr = obtainRequest(RIL_REQUEST_SEPARATE_CONNECTION, result,
   1884                     mRILDefaultWorkSource);
   1885 
   1886             if (RILJ_LOGD) {
   1887                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1888                         + " gsmIndex = " + gsmIndex);
   1889             }
   1890 
   1891             try {
   1892                 radioProxy.separateConnection(rr.mSerial, gsmIndex);
   1893             } catch (RemoteException | RuntimeException e) {
   1894                 handleRadioProxyExceptionForRR(rr, "separateConnection", e);
   1895             }
   1896         }
   1897     }
   1898 
   1899     @Override
   1900     public void getBasebandVersion(Message result) {
   1901         IRadio radioProxy = getRadioProxy(result);
   1902         if (radioProxy != null) {
   1903             RILRequest rr = obtainRequest(RIL_REQUEST_BASEBAND_VERSION, result,
   1904                     mRILDefaultWorkSource);
   1905 
   1906             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1907 
   1908             try {
   1909                 radioProxy.getBasebandVersion(rr.mSerial);
   1910             } catch (RemoteException | RuntimeException e) {
   1911                 handleRadioProxyExceptionForRR(rr, "getBasebandVersion", e);
   1912             }
   1913         }
   1914     }
   1915 
   1916     @Override
   1917     public void setMute(boolean enableMute, Message result) {
   1918         IRadio radioProxy = getRadioProxy(result);
   1919         if (radioProxy != null) {
   1920             RILRequest rr = obtainRequest(RIL_REQUEST_SET_MUTE, result,
   1921                     mRILDefaultWorkSource);
   1922 
   1923             if (RILJ_LOGD) {
   1924                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   1925                         + " enableMute = " + enableMute);
   1926             }
   1927 
   1928             try {
   1929                 radioProxy.setMute(rr.mSerial, enableMute);
   1930             } catch (RemoteException | RuntimeException e) {
   1931                 handleRadioProxyExceptionForRR(rr, "setMute", e);
   1932             }
   1933         }
   1934     }
   1935 
   1936     @Override
   1937     public void getMute(Message result) {
   1938         IRadio radioProxy = getRadioProxy(result);
   1939         if (radioProxy != null) {
   1940             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MUTE, result,
   1941                     mRILDefaultWorkSource);
   1942 
   1943             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1944 
   1945             try {
   1946                 radioProxy.getMute(rr.mSerial);
   1947             } catch (RemoteException | RuntimeException e) {
   1948                 handleRadioProxyExceptionForRR(rr, "getMute", e);
   1949             }
   1950         }
   1951     }
   1952 
   1953     @Override
   1954     public void queryCLIP(Message result) {
   1955         IRadio radioProxy = getRadioProxy(result);
   1956         if (radioProxy != null) {
   1957             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CLIP, result,
   1958                     mRILDefaultWorkSource);
   1959 
   1960             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1961 
   1962             try {
   1963                 radioProxy.getClip(rr.mSerial);
   1964             } catch (RemoteException | RuntimeException e) {
   1965                 handleRadioProxyExceptionForRR(rr, "queryCLIP", e);
   1966             }
   1967         }
   1968     }
   1969 
   1970     /**
   1971      * @deprecated
   1972      */
   1973     @Override
   1974     @Deprecated
   1975     public void getPDPContextList(Message result) {
   1976         getDataCallList(result);
   1977     }
   1978 
   1979     @Override
   1980     public void getDataCallList(Message result) {
   1981         IRadio radioProxy = getRadioProxy(result);
   1982         if (radioProxy != null) {
   1983             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_CALL_LIST, result,
   1984                     mRILDefaultWorkSource);
   1985 
   1986             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   1987 
   1988             try {
   1989                 radioProxy.getDataCallList(rr.mSerial);
   1990             } catch (RemoteException | RuntimeException e) {
   1991                 handleRadioProxyExceptionForRR(rr, "getDataCallList", e);
   1992             }
   1993         }
   1994     }
   1995 
   1996     @Override
   1997     public void invokeOemRilRequestRaw(byte[] data, Message response) {
   1998         IOemHook oemHookProxy = getOemHookProxy(response);
   1999         if (oemHookProxy != null) {
   2000             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_RAW, response,
   2001                     mRILDefaultWorkSource);
   2002 
   2003             if (RILJ_LOGD) {
   2004                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2005                         + "[" + IccUtils.bytesToHexString(data) + "]");
   2006             }
   2007 
   2008             try {
   2009                 oemHookProxy.sendRequestRaw(rr.mSerial, primitiveArrayToArrayList(data));
   2010             } catch (RemoteException | RuntimeException e) {
   2011                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestRaw", e);
   2012             }
   2013         } else {
   2014             // OEM Hook service is disabled for P and later devices.
   2015             // Deprecated OEM Hook APIs will perform dummy before being removed.
   2016             if (RILJ_LOGD) riljLog("Radio Oem Hook Service is disabled for P and later devices. ");
   2017         }
   2018     }
   2019 
   2020     @Override
   2021     public void invokeOemRilRequestStrings(String[] strings, Message result) {
   2022         IOemHook oemHookProxy = getOemHookProxy(result);
   2023         if (oemHookProxy != null) {
   2024             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_STRINGS, result,
   2025                     mRILDefaultWorkSource);
   2026 
   2027             String logStr = "";
   2028             for (int i = 0; i < strings.length; i++) {
   2029                 logStr = logStr + strings[i] + " ";
   2030             }
   2031             if (RILJ_LOGD) {
   2032                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " strings = "
   2033                         + logStr);
   2034             }
   2035 
   2036             try {
   2037                 oemHookProxy.sendRequestStrings(rr.mSerial,
   2038                         new ArrayList<String>(Arrays.asList(strings)));
   2039             } catch (RemoteException | RuntimeException e) {
   2040                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestStrings", e);
   2041             }
   2042         } else {
   2043             // OEM Hook service is disabled for P and later devices.
   2044             // Deprecated OEM Hook APIs will perform dummy before being removed.
   2045             if (RILJ_LOGD) riljLog("Radio Oem Hook Service is disabled for P and later devices. ");
   2046         }
   2047     }
   2048 
   2049     @Override
   2050     public void setSuppServiceNotifications(boolean enable, Message result) {
   2051         IRadio radioProxy = getRadioProxy(result);
   2052         if (radioProxy != null) {
   2053             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result,
   2054                     mRILDefaultWorkSource);
   2055 
   2056             if (RILJ_LOGD) {
   2057                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
   2058                         + enable);
   2059             }
   2060 
   2061             try {
   2062                 radioProxy.setSuppServiceNotifications(rr.mSerial, enable);
   2063             } catch (RemoteException | RuntimeException e) {
   2064                 handleRadioProxyExceptionForRR(rr, "setSuppServiceNotifications", e);
   2065             }
   2066         }
   2067     }
   2068 
   2069     @Override
   2070     public void writeSmsToSim(int status, String smsc, String pdu, Message result) {
   2071         status = translateStatus(status);
   2072         IRadio radioProxy = getRadioProxy(result);
   2073         if (radioProxy != null) {
   2074             RILRequest rr = obtainRequest(RIL_REQUEST_WRITE_SMS_TO_SIM, result,
   2075                     mRILDefaultWorkSource);
   2076 
   2077             if (RILJ_LOGV) {
   2078                 riljLog(rr.serialString() + "> "
   2079                         + requestToString(rr.mRequest)
   2080                         + " " + status);
   2081             }
   2082 
   2083             SmsWriteArgs args = new SmsWriteArgs();
   2084             args.status = status;
   2085             args.smsc = convertNullToEmptyString(smsc);
   2086             args.pdu = convertNullToEmptyString(pdu);
   2087 
   2088             try {
   2089                 radioProxy.writeSmsToSim(rr.mSerial, args);
   2090             } catch (RemoteException | RuntimeException e) {
   2091                 handleRadioProxyExceptionForRR(rr, "writeSmsToSim", e);
   2092             }
   2093         }
   2094     }
   2095 
   2096     @Override
   2097     public void deleteSmsOnSim(int index, Message result) {
   2098         IRadio radioProxy = getRadioProxy(result);
   2099         if (radioProxy != null) {
   2100             RILRequest rr = obtainRequest(RIL_REQUEST_DELETE_SMS_ON_SIM, result,
   2101                     mRILDefaultWorkSource);
   2102 
   2103             if (RILJ_LOGV) {
   2104                 riljLog(rr.serialString() + "> "
   2105                         + requestToString(rr.mRequest) + " index = " + index);
   2106             }
   2107 
   2108             try {
   2109                 radioProxy.deleteSmsOnSim(rr.mSerial, index);
   2110             } catch (RemoteException | RuntimeException e) {
   2111                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnSim", e);
   2112             }
   2113         }
   2114     }
   2115 
   2116     @Override
   2117     public void setBandMode(int bandMode, Message result) {
   2118         IRadio radioProxy = getRadioProxy(result);
   2119         if (radioProxy != null) {
   2120             RILRequest rr = obtainRequest(RIL_REQUEST_SET_BAND_MODE, result,
   2121                     mRILDefaultWorkSource);
   2122 
   2123             if (RILJ_LOGD) {
   2124                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2125                         + " bandMode = " + bandMode);
   2126             }
   2127 
   2128             try {
   2129                 radioProxy.setBandMode(rr.mSerial, bandMode);
   2130             } catch (RemoteException | RuntimeException e) {
   2131                 handleRadioProxyExceptionForRR(rr, "setBandMode", e);
   2132             }
   2133         }
   2134     }
   2135 
   2136     @Override
   2137     public void queryAvailableBandMode(Message result) {
   2138         IRadio radioProxy = getRadioProxy(result);
   2139         if (radioProxy != null) {
   2140             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, result,
   2141                     mRILDefaultWorkSource);
   2142 
   2143             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2144 
   2145             try {
   2146                 radioProxy.getAvailableBandModes(rr.mSerial);
   2147             } catch (RemoteException | RuntimeException e) {
   2148                 handleRadioProxyExceptionForRR(rr, "queryAvailableBandMode", e);
   2149             }
   2150         }
   2151     }
   2152 
   2153     @Override
   2154     public void sendEnvelope(String contents, Message result) {
   2155         IRadio radioProxy = getRadioProxy(result);
   2156         if (radioProxy != null) {
   2157             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, result,
   2158                     mRILDefaultWorkSource);
   2159 
   2160             if (RILJ_LOGD) {
   2161                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
   2162                         + contents);
   2163             }
   2164 
   2165             try {
   2166                 radioProxy.sendEnvelope(rr.mSerial, convertNullToEmptyString(contents));
   2167             } catch (RemoteException | RuntimeException e) {
   2168                 handleRadioProxyExceptionForRR(rr, "sendEnvelope", e);
   2169             }
   2170         }
   2171     }
   2172 
   2173     @Override
   2174     public void sendTerminalResponse(String contents, Message result) {
   2175         IRadio radioProxy = getRadioProxy(result);
   2176         if (radioProxy != null) {
   2177             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, result,
   2178                     mRILDefaultWorkSource);
   2179 
   2180             if (RILJ_LOGD) {
   2181                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
   2182                         + (Build.IS_DEBUGGABLE ? contents : censoredTerminalResponse(contents)));
   2183             }
   2184 
   2185             try {
   2186                 radioProxy.sendTerminalResponseToSim(rr.mSerial,
   2187                         convertNullToEmptyString(contents));
   2188             } catch (RemoteException | RuntimeException e) {
   2189                 handleRadioProxyExceptionForRR(rr, "sendTerminalResponse", e);
   2190             }
   2191         }
   2192     }
   2193 
   2194     private String censoredTerminalResponse(String terminalResponse) {
   2195         try {
   2196             byte[] bytes = IccUtils.hexStringToBytes(terminalResponse);
   2197             if (bytes != null) {
   2198                 List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(bytes, 0);
   2199                 int from = 0;
   2200                 for (ComprehensionTlv ctlv : ctlvs) {
   2201                     // Find text strings which might be personal information input by user,
   2202                     // then replace it with "********".
   2203                     if (ComprehensionTlvTag.TEXT_STRING.value() == ctlv.getTag()) {
   2204                         byte[] target = Arrays.copyOfRange(ctlv.getRawValue(), from,
   2205                                 ctlv.getValueIndex() + ctlv.getLength());
   2206                         terminalResponse = terminalResponse.toLowerCase().replace(
   2207                                 IccUtils.bytesToHexString(target), "********");
   2208                     }
   2209                     // The text string tag and the length field should also be hidden.
   2210                     from = ctlv.getValueIndex() + ctlv.getLength();
   2211                 }
   2212             }
   2213         } catch (Exception e) {
   2214             Rlog.e(RILJ_LOG_TAG, "Could not censor the terminal response: " + e);
   2215             terminalResponse = null;
   2216         }
   2217 
   2218         return terminalResponse;
   2219     }
   2220 
   2221     @Override
   2222     public void sendEnvelopeWithStatus(String contents, Message result) {
   2223         IRadio radioProxy = getRadioProxy(result);
   2224         if (radioProxy != null) {
   2225             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, result,
   2226                     mRILDefaultWorkSource);
   2227 
   2228             if (RILJ_LOGD) {
   2229                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
   2230                         + contents);
   2231             }
   2232 
   2233             try {
   2234                 radioProxy.sendEnvelopeWithStatus(rr.mSerial, convertNullToEmptyString(contents));
   2235             } catch (RemoteException | RuntimeException e) {
   2236                 handleRadioProxyExceptionForRR(rr, "sendEnvelopeWithStatus", e);
   2237             }
   2238         }
   2239     }
   2240 
   2241     @Override
   2242     public void explicitCallTransfer(Message result) {
   2243         IRadio radioProxy = getRadioProxy(result);
   2244         if (radioProxy != null) {
   2245             RILRequest rr = obtainRequest(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result,
   2246                     mRILDefaultWorkSource);
   2247 
   2248             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2249 
   2250             try {
   2251                 radioProxy.explicitCallTransfer(rr.mSerial);
   2252             } catch (RemoteException | RuntimeException e) {
   2253                 handleRadioProxyExceptionForRR(rr, "explicitCallTransfer", e);
   2254             }
   2255         }
   2256     }
   2257 
   2258     @Override
   2259     public void setPreferredNetworkType(int networkType , Message result) {
   2260         IRadio radioProxy = getRadioProxy(result);
   2261         if (radioProxy != null) {
   2262             RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
   2263                     mRILDefaultWorkSource);
   2264 
   2265             if (RILJ_LOGD) {
   2266                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2267                         + " networkType = " + networkType);
   2268             }
   2269             mPreferredNetworkType = networkType;
   2270             mMetrics.writeSetPreferredNetworkType(mPhoneId, networkType);
   2271 
   2272             try {
   2273                 radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
   2274             } catch (RemoteException | RuntimeException e) {
   2275                 handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
   2276             }
   2277         }
   2278     }
   2279 
   2280     @Override
   2281     public void getPreferredNetworkType(Message result) {
   2282         IRadio radioProxy = getRadioProxy(result);
   2283         if (radioProxy != null) {
   2284             RILRequest rr = obtainRequest(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, result,
   2285                     mRILDefaultWorkSource);
   2286 
   2287             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2288 
   2289             try {
   2290                 radioProxy.getPreferredNetworkType(rr.mSerial);
   2291             } catch (RemoteException | RuntimeException e) {
   2292                 handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
   2293             }
   2294         }
   2295     }
   2296 
   2297     @Override
   2298     public void getNeighboringCids(Message result, WorkSource workSource) {
   2299         workSource = getDeafultWorkSourceIfInvalid(workSource);
   2300         IRadio radioProxy = getRadioProxy(result);
   2301         if (radioProxy != null) {
   2302             RILRequest rr = obtainRequest(RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, result,
   2303                     workSource);
   2304 
   2305             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2306 
   2307             try {
   2308                 radioProxy.getNeighboringCids(rr.mSerial);
   2309             } catch (RemoteException | RuntimeException e) {
   2310                 handleRadioProxyExceptionForRR(rr, "getNeighboringCids", e);
   2311             }
   2312         }
   2313     }
   2314 
   2315     @Override
   2316     public void setLocationUpdates(boolean enable, Message result) {
   2317         IRadio radioProxy = getRadioProxy(result);
   2318         if (radioProxy != null) {
   2319             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOCATION_UPDATES, result,
   2320                     mRILDefaultWorkSource);
   2321 
   2322             if (RILJ_LOGD) {
   2323                 riljLog(rr.serialString() + "> "
   2324                         + requestToString(rr.mRequest) + " enable = " + enable);
   2325             }
   2326 
   2327             try {
   2328                 radioProxy.setLocationUpdates(rr.mSerial, enable);
   2329             } catch (RemoteException | RuntimeException e) {
   2330                 handleRadioProxyExceptionForRR(rr, "setLocationUpdates", e);
   2331             }
   2332         }
   2333     }
   2334 
   2335     @Override
   2336     public void setCdmaSubscriptionSource(int cdmaSubscription , Message result) {
   2337         IRadio radioProxy = getRadioProxy(result);
   2338         if (radioProxy != null) {
   2339             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, result,
   2340                     mRILDefaultWorkSource);
   2341 
   2342             if (RILJ_LOGD) {
   2343                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2344                         + " cdmaSubscription = " + cdmaSubscription);
   2345             }
   2346 
   2347             try {
   2348                 radioProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
   2349             } catch (RemoteException | RuntimeException e) {
   2350                 handleRadioProxyExceptionForRR(rr, "setCdmaSubscriptionSource", e);
   2351             }
   2352         }
   2353     }
   2354 
   2355     @Override
   2356     public void queryCdmaRoamingPreference(Message result) {
   2357         IRadio radioProxy = getRadioProxy(result);
   2358         if (radioProxy != null) {
   2359             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, result,
   2360                     mRILDefaultWorkSource);
   2361 
   2362             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2363 
   2364             try {
   2365                 radioProxy.getCdmaRoamingPreference(rr.mSerial);
   2366             } catch (RemoteException | RuntimeException e) {
   2367                 handleRadioProxyExceptionForRR(rr, "queryCdmaRoamingPreference", e);
   2368             }
   2369         }
   2370     }
   2371 
   2372     @Override
   2373     public void setCdmaRoamingPreference(int cdmaRoamingType, Message result) {
   2374         IRadio radioProxy = getRadioProxy(result);
   2375         if (radioProxy != null) {
   2376             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, result,
   2377                     mRILDefaultWorkSource);
   2378 
   2379             if (RILJ_LOGD) {
   2380                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2381                         + " cdmaRoamingType = " + cdmaRoamingType);
   2382             }
   2383 
   2384             try {
   2385                 radioProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
   2386             } catch (RemoteException | RuntimeException e) {
   2387                 handleRadioProxyExceptionForRR(rr, "setCdmaRoamingPreference", e);
   2388             }
   2389         }
   2390     }
   2391 
   2392     @Override
   2393     public void queryTTYMode(Message result) {
   2394         IRadio radioProxy = getRadioProxy(result);
   2395         if (radioProxy != null) {
   2396             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_TTY_MODE, result,
   2397                     mRILDefaultWorkSource);
   2398 
   2399             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2400 
   2401             try {
   2402                 radioProxy.getTTYMode(rr.mSerial);
   2403             } catch (RemoteException | RuntimeException e) {
   2404                 handleRadioProxyExceptionForRR(rr, "queryTTYMode", e);
   2405             }
   2406         }
   2407     }
   2408 
   2409     @Override
   2410     public void setTTYMode(int ttyMode, Message result) {
   2411         IRadio radioProxy = getRadioProxy(result);
   2412         if (radioProxy != null) {
   2413             RILRequest rr = obtainRequest(RIL_REQUEST_SET_TTY_MODE, result,
   2414                     mRILDefaultWorkSource);
   2415 
   2416             if (RILJ_LOGD) {
   2417                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2418                         + " ttyMode = " + ttyMode);
   2419             }
   2420 
   2421             try {
   2422                 radioProxy.setTTYMode(rr.mSerial, ttyMode);
   2423             } catch (RemoteException | RuntimeException e) {
   2424                 handleRadioProxyExceptionForRR(rr, "setTTYMode", e);
   2425             }
   2426         }
   2427     }
   2428 
   2429     @Override
   2430     public void setPreferredVoicePrivacy(boolean enable, Message result) {
   2431         IRadio radioProxy = getRadioProxy(result);
   2432         if (radioProxy != null) {
   2433             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, result,
   2434                     mRILDefaultWorkSource);
   2435 
   2436             if (RILJ_LOGD) {
   2437                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2438                         + " enable = " + enable);
   2439             }
   2440 
   2441             try {
   2442                 radioProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
   2443             } catch (RemoteException | RuntimeException e) {
   2444                 handleRadioProxyExceptionForRR(rr, "setPreferredVoicePrivacy", e);
   2445             }
   2446         }
   2447     }
   2448 
   2449     @Override
   2450     public void getPreferredVoicePrivacy(Message result) {
   2451         IRadio radioProxy = getRadioProxy(result);
   2452         if (radioProxy != null) {
   2453             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
   2454                     result, mRILDefaultWorkSource);
   2455 
   2456             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2457 
   2458             try {
   2459                 radioProxy.getPreferredVoicePrivacy(rr.mSerial);
   2460             } catch (RemoteException | RuntimeException e) {
   2461                 handleRadioProxyExceptionForRR(rr, "getPreferredVoicePrivacy", e);
   2462             }
   2463         }
   2464     }
   2465 
   2466     @Override
   2467     public void sendCDMAFeatureCode(String featureCode, Message result) {
   2468         IRadio radioProxy = getRadioProxy(result);
   2469         if (radioProxy != null) {
   2470             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_FLASH, result,
   2471                     mRILDefaultWorkSource);
   2472 
   2473             if (RILJ_LOGD) {
   2474                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2475                         + " featureCode = " + featureCode);
   2476             }
   2477 
   2478             try {
   2479                 radioProxy.sendCDMAFeatureCode(rr.mSerial, convertNullToEmptyString(featureCode));
   2480             } catch (RemoteException | RuntimeException e) {
   2481                 handleRadioProxyExceptionForRR(rr, "sendCDMAFeatureCode", e);
   2482             }
   2483         }
   2484     }
   2485 
   2486     @Override
   2487     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
   2488         IRadio radioProxy = getRadioProxy(result);
   2489         if (radioProxy != null) {
   2490             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BURST_DTMF, result,
   2491                     mRILDefaultWorkSource);
   2492 
   2493             if (RILJ_LOGD) {
   2494                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2495                         + " dtmfString = " + dtmfString + " on = " + on + " off = " + off);
   2496             }
   2497 
   2498             try {
   2499                 radioProxy.sendBurstDtmf(rr.mSerial, convertNullToEmptyString(dtmfString), on, off);
   2500             } catch (RemoteException | RuntimeException e) {
   2501                 handleRadioProxyExceptionForRR(rr, "sendBurstDtmf", e);
   2502             }
   2503         }
   2504     }
   2505 
   2506     private void constructCdmaSendSmsRilRequest(CdmaSmsMessage msg, byte[] pdu) {
   2507         int addrNbrOfDigits;
   2508         int subaddrNbrOfDigits;
   2509         int bearerDataLength;
   2510         ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
   2511         DataInputStream dis = new DataInputStream(bais);
   2512 
   2513         try {
   2514             msg.teleserviceId = dis.readInt(); // teleServiceId
   2515             msg.isServicePresent = (byte) dis.readInt() == 1 ? true : false; // servicePresent
   2516             msg.serviceCategory = dis.readInt(); // serviceCategory
   2517             msg.address.digitMode = dis.read();  // address digit mode
   2518             msg.address.numberMode = dis.read(); // address number mode
   2519             msg.address.numberType = dis.read(); // address number type
   2520             msg.address.numberPlan = dis.read(); // address number plan
   2521             addrNbrOfDigits = (byte) dis.read();
   2522             for (int i = 0; i < addrNbrOfDigits; i++) {
   2523                 msg.address.digits.add(dis.readByte()); // address_orig_bytes[i]
   2524             }
   2525             msg.subAddress.subaddressType = dis.read(); //subaddressType
   2526             msg.subAddress.odd = (byte) dis.read() == 1 ? true : false; //subaddr odd
   2527             subaddrNbrOfDigits = (byte) dis.read();
   2528             for (int i = 0; i < subaddrNbrOfDigits; i++) {
   2529                 msg.subAddress.digits.add(dis.readByte()); //subaddr_orig_bytes[i]
   2530             }
   2531 
   2532             bearerDataLength = dis.read();
   2533             for (int i = 0; i < bearerDataLength; i++) {
   2534                 msg.bearerData.add(dis.readByte()); //bearerData[i]
   2535             }
   2536         } catch (IOException ex) {
   2537             if (RILJ_LOGD) {
   2538                 riljLog("sendSmsCdma: conversion from input stream to object failed: "
   2539                         + ex);
   2540             }
   2541         }
   2542     }
   2543 
   2544     @Override
   2545     public void sendCdmaSms(byte[] pdu, Message result) {
   2546         IRadio radioProxy = getRadioProxy(result);
   2547         if (radioProxy != null) {
   2548             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS, result,
   2549                     mRILDefaultWorkSource);
   2550 
   2551             // Do not log function arg for privacy
   2552             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2553 
   2554             CdmaSmsMessage msg = new CdmaSmsMessage();
   2555             constructCdmaSendSmsRilRequest(msg, pdu);
   2556 
   2557             try {
   2558                 radioProxy.sendCdmaSms(rr.mSerial, msg);
   2559                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
   2560                         SmsSession.Event.Format.SMS_FORMAT_3GPP2);
   2561             } catch (RemoteException | RuntimeException e) {
   2562                 handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
   2563             }
   2564         }
   2565     }
   2566 
   2567     @Override
   2568     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
   2569         IRadio radioProxy = getRadioProxy(result);
   2570         if (radioProxy != null) {
   2571             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result,
   2572                     mRILDefaultWorkSource);
   2573 
   2574             if (RILJ_LOGD) {
   2575                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2576                         + " success = " + success + " cause = " + cause);
   2577             }
   2578 
   2579             CdmaSmsAck msg = new CdmaSmsAck();
   2580             msg.errorClass = success ? 0 : 1;
   2581             msg.smsCauseCode = cause;
   2582 
   2583             try {
   2584                 radioProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, msg);
   2585             } catch (RemoteException | RuntimeException e) {
   2586                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingCdmaSms", e);
   2587             }
   2588         }
   2589     }
   2590 
   2591     @Override
   2592     public void getGsmBroadcastConfig(Message result) {
   2593         IRadio radioProxy = getRadioProxy(result);
   2594         if (radioProxy != null) {
   2595             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, result,
   2596                     mRILDefaultWorkSource);
   2597 
   2598             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2599 
   2600             try {
   2601                 radioProxy.getGsmBroadcastConfig(rr.mSerial);
   2602             } catch (RemoteException | RuntimeException e) {
   2603                 handleRadioProxyExceptionForRR(rr, "getGsmBroadcastConfig", e);
   2604             }
   2605         }
   2606     }
   2607 
   2608     @Override
   2609     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message result) {
   2610         IRadio radioProxy = getRadioProxy(result);
   2611         if (radioProxy != null) {
   2612             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, result,
   2613                     mRILDefaultWorkSource);
   2614 
   2615             if (RILJ_LOGD) {
   2616                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2617                         + " with " + config.length + " configs : ");
   2618                 for (int i = 0; i < config.length; i++) {
   2619                     riljLog(config[i].toString());
   2620                 }
   2621             }
   2622 
   2623             ArrayList<GsmBroadcastSmsConfigInfo> configs = new ArrayList<>();
   2624 
   2625             int numOfConfig = config.length;
   2626             GsmBroadcastSmsConfigInfo info;
   2627 
   2628             for (int i = 0; i < numOfConfig; i++) {
   2629                 info = new GsmBroadcastSmsConfigInfo();
   2630                 info.fromServiceId = config[i].getFromServiceId();
   2631                 info.toServiceId = config[i].getToServiceId();
   2632                 info.fromCodeScheme = config[i].getFromCodeScheme();
   2633                 info.toCodeScheme = config[i].getToCodeScheme();
   2634                 info.selected = config[i].isSelected();
   2635                 configs.add(info);
   2636             }
   2637 
   2638             try {
   2639                 radioProxy.setGsmBroadcastConfig(rr.mSerial, configs);
   2640             } catch (RemoteException | RuntimeException e) {
   2641                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastConfig", e);
   2642             }
   2643         }
   2644     }
   2645 
   2646     @Override
   2647     public void setGsmBroadcastActivation(boolean activate, Message result) {
   2648         IRadio radioProxy = getRadioProxy(result);
   2649         if (radioProxy != null) {
   2650             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, result,
   2651                     mRILDefaultWorkSource);
   2652 
   2653             if (RILJ_LOGD) {
   2654                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2655                         + " activate = " + activate);
   2656             }
   2657 
   2658             try {
   2659                 radioProxy.setGsmBroadcastActivation(rr.mSerial, activate);
   2660             } catch (RemoteException | RuntimeException e) {
   2661                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastActivation", e);
   2662             }
   2663         }
   2664     }
   2665 
   2666     @Override
   2667     public void getCdmaBroadcastConfig(Message result) {
   2668         IRadio radioProxy = getRadioProxy(result);
   2669         if (radioProxy != null) {
   2670             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, result,
   2671                     mRILDefaultWorkSource);
   2672 
   2673             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2674 
   2675             try {
   2676                 radioProxy.getCdmaBroadcastConfig(rr.mSerial);
   2677             } catch (RemoteException | RuntimeException e) {
   2678                 handleRadioProxyExceptionForRR(rr, "getCdmaBroadcastConfig", e);
   2679             }
   2680         }
   2681     }
   2682 
   2683     @Override
   2684     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result) {
   2685         IRadio radioProxy = getRadioProxy(result);
   2686         if (radioProxy != null) {
   2687             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, result,
   2688                     mRILDefaultWorkSource);
   2689 
   2690             ArrayList<CdmaBroadcastSmsConfigInfo> halConfigs = new ArrayList<>();
   2691 
   2692             for (CdmaSmsBroadcastConfigInfo config: configs) {
   2693                 for (int i = config.getFromServiceCategory();
   2694                         i <= config.getToServiceCategory();
   2695                         i++) {
   2696                     CdmaBroadcastSmsConfigInfo info = new CdmaBroadcastSmsConfigInfo();
   2697                     info.serviceCategory = i;
   2698                     info.language = config.getLanguage();
   2699                     info.selected = config.isSelected();
   2700                     halConfigs.add(info);
   2701                 }
   2702             }
   2703 
   2704             if (RILJ_LOGD) {
   2705                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2706                         + " with " + halConfigs.size() + " configs : ");
   2707                 for (CdmaBroadcastSmsConfigInfo config : halConfigs) {
   2708                     riljLog(config.toString());
   2709                 }
   2710             }
   2711 
   2712             try {
   2713                 radioProxy.setCdmaBroadcastConfig(rr.mSerial, halConfigs);
   2714             } catch (RemoteException | RuntimeException e) {
   2715                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastConfig", e);
   2716             }
   2717         }
   2718     }
   2719 
   2720     @Override
   2721     public void setCdmaBroadcastActivation(boolean activate, Message result) {
   2722         IRadio radioProxy = getRadioProxy(result);
   2723         if (radioProxy != null) {
   2724             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, result,
   2725                     mRILDefaultWorkSource);
   2726 
   2727             if (RILJ_LOGD) {
   2728                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2729                         + " activate = " + activate);
   2730             }
   2731 
   2732             try {
   2733                 radioProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
   2734             } catch (RemoteException | RuntimeException e) {
   2735                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastActivation", e);
   2736             }
   2737         }
   2738     }
   2739 
   2740     @Override
   2741     public void getCDMASubscription(Message result) {
   2742         IRadio radioProxy = getRadioProxy(result);
   2743         if (radioProxy != null) {
   2744             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SUBSCRIPTION, result,
   2745                     mRILDefaultWorkSource);
   2746 
   2747             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2748 
   2749             try {
   2750                 radioProxy.getCDMASubscription(rr.mSerial);
   2751             } catch (RemoteException | RuntimeException e) {
   2752                 handleRadioProxyExceptionForRR(rr, "getCDMASubscription", e);
   2753             }
   2754         }
   2755     }
   2756 
   2757     @Override
   2758     public void writeSmsToRuim(int status, String pdu, Message result) {
   2759         status = translateStatus(status);
   2760         IRadio radioProxy = getRadioProxy(result);
   2761         if (radioProxy != null) {
   2762             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, result,
   2763                     mRILDefaultWorkSource);
   2764 
   2765             if (RILJ_LOGV) {
   2766                 riljLog(rr.serialString() + "> "
   2767                         + requestToString(rr.mRequest)
   2768                         + " status = " + status);
   2769             }
   2770 
   2771             CdmaSmsWriteArgs args = new CdmaSmsWriteArgs();
   2772             args.status = status;
   2773             constructCdmaSendSmsRilRequest(args.message, pdu.getBytes());
   2774 
   2775             try {
   2776                 radioProxy.writeSmsToRuim(rr.mSerial, args);
   2777             } catch (RemoteException | RuntimeException e) {
   2778                 handleRadioProxyExceptionForRR(rr, "writeSmsToRuim", e);
   2779             }
   2780         }
   2781     }
   2782 
   2783     @Override
   2784     public void deleteSmsOnRuim(int index, Message result) {
   2785         IRadio radioProxy = getRadioProxy(result);
   2786         if (radioProxy != null) {
   2787             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, result,
   2788                     mRILDefaultWorkSource);
   2789 
   2790             if (RILJ_LOGV) {
   2791                 riljLog(rr.serialString() + "> "
   2792                         + requestToString(rr.mRequest)
   2793                         + " index = " + index);
   2794             }
   2795 
   2796             try {
   2797                 radioProxy.deleteSmsOnRuim(rr.mSerial, index);
   2798             } catch (RemoteException | RuntimeException e) {
   2799                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnRuim", e);
   2800             }
   2801         }
   2802     }
   2803 
   2804     @Override
   2805     public void getDeviceIdentity(Message result) {
   2806         IRadio radioProxy = getRadioProxy(result);
   2807         if (radioProxy != null) {
   2808             RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
   2809                     mRILDefaultWorkSource);
   2810 
   2811             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2812 
   2813             try {
   2814                 radioProxy.getDeviceIdentity(rr.mSerial);
   2815             } catch (RemoteException | RuntimeException e) {
   2816                 handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
   2817             }
   2818         }
   2819     }
   2820 
   2821     @Override
   2822     public void exitEmergencyCallbackMode(Message result) {
   2823         IRadio radioProxy = getRadioProxy(result);
   2824         if (radioProxy != null) {
   2825             RILRequest rr = obtainRequest(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, result,
   2826                     mRILDefaultWorkSource);
   2827 
   2828             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2829 
   2830             try {
   2831                 radioProxy.exitEmergencyCallbackMode(rr.mSerial);
   2832             } catch (RemoteException | RuntimeException e) {
   2833                 handleRadioProxyExceptionForRR(rr, "exitEmergencyCallbackMode", e);
   2834             }
   2835         }
   2836     }
   2837 
   2838     @Override
   2839     public void getSmscAddress(Message result) {
   2840         IRadio radioProxy = getRadioProxy(result);
   2841         if (radioProxy != null) {
   2842             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SMSC_ADDRESS, result,
   2843                     mRILDefaultWorkSource);
   2844 
   2845             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2846 
   2847             try {
   2848                 radioProxy.getSmscAddress(rr.mSerial);
   2849             } catch (RemoteException | RuntimeException e) {
   2850                 handleRadioProxyExceptionForRR(rr, "getSmscAddress", e);
   2851             }
   2852         }
   2853     }
   2854 
   2855     @Override
   2856     public void setSmscAddress(String address, Message result) {
   2857         IRadio radioProxy = getRadioProxy(result);
   2858         if (radioProxy != null) {
   2859             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SMSC_ADDRESS, result,
   2860                     mRILDefaultWorkSource);
   2861 
   2862             if (RILJ_LOGD) {
   2863                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2864                         + " address = " + address);
   2865             }
   2866 
   2867             try {
   2868                 radioProxy.setSmscAddress(rr.mSerial, convertNullToEmptyString(address));
   2869             } catch (RemoteException | RuntimeException e) {
   2870                 handleRadioProxyExceptionForRR(rr, "setSmscAddress", e);
   2871             }
   2872         }
   2873     }
   2874 
   2875     @Override
   2876     public void reportSmsMemoryStatus(boolean available, Message result) {
   2877         IRadio radioProxy = getRadioProxy(result);
   2878         if (radioProxy != null) {
   2879             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result,
   2880                     mRILDefaultWorkSource);
   2881 
   2882             if (RILJ_LOGD) {
   2883                 riljLog(rr.serialString() + "> "
   2884                         + requestToString(rr.mRequest) + " available = " + available);
   2885             }
   2886 
   2887             try {
   2888                 radioProxy.reportSmsMemoryStatus(rr.mSerial, available);
   2889             } catch (RemoteException | RuntimeException e) {
   2890                 handleRadioProxyExceptionForRR(rr, "reportSmsMemoryStatus", e);
   2891             }
   2892         }
   2893     }
   2894 
   2895     @Override
   2896     public void reportStkServiceIsRunning(Message result) {
   2897         IRadio radioProxy = getRadioProxy(result);
   2898         if (radioProxy != null) {
   2899             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result,
   2900                     mRILDefaultWorkSource);
   2901 
   2902             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2903 
   2904             try {
   2905                 radioProxy.reportStkServiceIsRunning(rr.mSerial);
   2906             } catch (RemoteException | RuntimeException e) {
   2907                 handleRadioProxyExceptionForRR(rr, "reportStkServiceIsRunning", e);
   2908             }
   2909         }
   2910     }
   2911 
   2912     @Override
   2913     public void getCdmaSubscriptionSource(Message result) {
   2914         IRadio radioProxy = getRadioProxy(result);
   2915         if (radioProxy != null) {
   2916             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, result,
   2917                     mRILDefaultWorkSource);
   2918 
   2919             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2920 
   2921             try {
   2922                 radioProxy.getCdmaSubscriptionSource(rr.mSerial);
   2923             } catch (RemoteException | RuntimeException e) {
   2924                 handleRadioProxyExceptionForRR(rr, "getCdmaSubscriptionSource", e);
   2925             }
   2926         }
   2927     }
   2928 
   2929     @Override
   2930     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
   2931         IRadio radioProxy = getRadioProxy(result);
   2932         if (radioProxy != null) {
   2933             RILRequest rr = obtainRequest(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result,
   2934                     mRILDefaultWorkSource);
   2935 
   2936             if (RILJ_LOGD) {
   2937                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2938                         + " success = " + success);
   2939             }
   2940 
   2941             try {
   2942                 radioProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
   2943                         convertNullToEmptyString(ackPdu));
   2944             } catch (RemoteException | RuntimeException e) {
   2945                 handleRadioProxyExceptionForRR(rr, "acknowledgeIncomingGsmSmsWithPdu", e);
   2946             }
   2947         }
   2948     }
   2949 
   2950     @Override
   2951     public void getVoiceRadioTechnology(Message result) {
   2952         IRadio radioProxy = getRadioProxy(result);
   2953         if (radioProxy != null) {
   2954             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_RADIO_TECH, result,
   2955                     mRILDefaultWorkSource);
   2956 
   2957             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2958 
   2959             try {
   2960                 radioProxy.getVoiceRadioTechnology(rr.mSerial);
   2961             } catch (RemoteException | RuntimeException e) {
   2962                 handleRadioProxyExceptionForRR(rr, "getVoiceRadioTechnology", e);
   2963             }
   2964         }
   2965     }
   2966 
   2967     @Override
   2968     public void getCellInfoList(Message result, WorkSource workSource) {
   2969         workSource = getDeafultWorkSourceIfInvalid(workSource);
   2970         IRadio radioProxy = getRadioProxy(result);
   2971         if (radioProxy != null) {
   2972             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CELL_INFO_LIST, result,
   2973                     workSource);
   2974 
   2975             if (RILJ_LOGD) {
   2976                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   2977             }
   2978 
   2979             try {
   2980                 radioProxy.getCellInfoList(rr.mSerial);
   2981             } catch (RemoteException | RuntimeException e) {
   2982                 handleRadioProxyExceptionForRR(rr, "getCellInfoList", e);
   2983             }
   2984         }
   2985     }
   2986 
   2987     @Override
   2988     public void setCellInfoListRate(int rateInMillis, Message result, WorkSource workSource) {
   2989         workSource = getDeafultWorkSourceIfInvalid(workSource);
   2990         IRadio radioProxy = getRadioProxy(result);
   2991         if (radioProxy != null) {
   2992             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, result,
   2993                     workSource);
   2994 
   2995             if (RILJ_LOGD) {
   2996                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   2997                         + " rateInMillis = " + rateInMillis);
   2998             }
   2999 
   3000             try {
   3001                 radioProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
   3002             } catch (RemoteException | RuntimeException e) {
   3003                 handleRadioProxyExceptionForRR(rr, "setCellInfoListRate", e);
   3004             }
   3005         }
   3006     }
   3007 
   3008     void setCellInfoListRate() {
   3009         setCellInfoListRate(Integer.MAX_VALUE, null, mRILDefaultWorkSource);
   3010     }
   3011 
   3012     @Override
   3013     public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result) {
   3014 
   3015         IRadio radioProxy = getRadioProxy(result);
   3016         if (radioProxy != null) {
   3017             RILRequest rr = obtainRequest(RIL_REQUEST_SET_INITIAL_ATTACH_APN, result,
   3018                     mRILDefaultWorkSource);
   3019 
   3020             if (RILJ_LOGD) {
   3021                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + dataProfile);
   3022             }
   3023 
   3024             try {
   3025                 radioProxy.setInitialAttachApn(rr.mSerial, convertToHalDataProfile(dataProfile),
   3026                         dataProfile.isModemCognitive(), isRoaming);
   3027             } catch (RemoteException | RuntimeException e) {
   3028                 handleRadioProxyExceptionForRR(rr, "setInitialAttachApn", e);
   3029             }
   3030         }
   3031     }
   3032 
   3033     @Override
   3034     public void getImsRegistrationState(Message result) {
   3035         IRadio radioProxy = getRadioProxy(result);
   3036         if (radioProxy != null) {
   3037             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_REGISTRATION_STATE, result,
   3038                     mRILDefaultWorkSource);
   3039 
   3040             if (RILJ_LOGD) {
   3041                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3042             }
   3043 
   3044             try {
   3045                 radioProxy.getImsRegistrationState(rr.mSerial);
   3046             } catch (RemoteException | RuntimeException e) {
   3047                 handleRadioProxyExceptionForRR(rr, "getImsRegistrationState", e);
   3048             }
   3049         }
   3050     }
   3051 
   3052     @Override
   3053     public void sendImsGsmSms(String smscPdu, String pdu, int retry, int messageRef,
   3054                    Message result) {
   3055         IRadio radioProxy = getRadioProxy(result);
   3056         if (radioProxy != null) {
   3057             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
   3058                     mRILDefaultWorkSource);
   3059 
   3060             // Do not log function args for privacy
   3061             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3062 
   3063             ImsSmsMessage msg = new ImsSmsMessage();
   3064             msg.tech = RILConstants.GSM_PHONE;
   3065             msg.retry = (byte) retry >= 1 ? true : false;
   3066             msg.messageRef = messageRef;
   3067 
   3068             GsmSmsMessage gsmMsg = constructGsmSendSmsRilRequest(smscPdu, pdu);
   3069             msg.gsmMessage.add(gsmMsg);
   3070             try {
   3071                 radioProxy.sendImsSms(rr.mSerial, msg);
   3072                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
   3073                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
   3074             } catch (RemoteException | RuntimeException e) {
   3075                 handleRadioProxyExceptionForRR(rr, "sendImsGsmSms", e);
   3076             }
   3077         }
   3078     }
   3079 
   3080     @Override
   3081     public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message result) {
   3082         IRadio radioProxy = getRadioProxy(result);
   3083         if (radioProxy != null) {
   3084             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
   3085                     mRILDefaultWorkSource);
   3086 
   3087             // Do not log function args for privacy
   3088             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3089 
   3090             ImsSmsMessage msg = new ImsSmsMessage();
   3091             msg.tech = RILConstants.CDMA_PHONE;
   3092             msg.retry = (byte) retry >= 1 ? true : false;
   3093             msg.messageRef = messageRef;
   3094 
   3095             CdmaSmsMessage cdmaMsg = new CdmaSmsMessage();
   3096             constructCdmaSendSmsRilRequest(cdmaMsg, pdu);
   3097             msg.cdmaMessage.add(cdmaMsg);
   3098 
   3099             try {
   3100                 radioProxy.sendImsSms(rr.mSerial, msg);
   3101                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
   3102                         SmsSession.Event.Format.SMS_FORMAT_3GPP2);
   3103             } catch (RemoteException | RuntimeException e) {
   3104                 handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
   3105             }
   3106         }
   3107     }
   3108 
   3109     private SimApdu createSimApdu(int channel, int cla, int instruction, int p1, int p2, int p3,
   3110                                   String data) {
   3111         SimApdu msg = new SimApdu();
   3112         msg.sessionId = channel;
   3113         msg.cla = cla;
   3114         msg.instruction = instruction;
   3115         msg.p1 = p1;
   3116         msg.p2 = p2;
   3117         msg.p3 = p3;
   3118         msg.data = convertNullToEmptyString(data);
   3119         return msg;
   3120     }
   3121 
   3122     @Override
   3123     public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
   3124                                             int p3, String data, Message result) {
   3125         IRadio radioProxy = getRadioProxy(result);
   3126         if (radioProxy != null) {
   3127             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, result,
   3128                     mRILDefaultWorkSource);
   3129 
   3130             if (RILJ_LOGD) {
   3131                 if (Build.IS_DEBUGGABLE) {
   3132                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3133                             + " cla = " + cla + " instruction = " + instruction
   3134                             + " p1 = " + p1 + " p2 = " + " p3 = " + p3 + " data = " + data);
   3135                 } else {
   3136                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3137                 }
   3138             }
   3139 
   3140             SimApdu msg = createSimApdu(0, cla, instruction, p1, p2, p3, data);
   3141             try {
   3142                 radioProxy.iccTransmitApduBasicChannel(rr.mSerial, msg);
   3143             } catch (RemoteException | RuntimeException e) {
   3144                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduBasicChannel", e);
   3145             }
   3146         }
   3147     }
   3148 
   3149     @Override
   3150     public void iccOpenLogicalChannel(String aid, int p2, Message result) {
   3151         IRadio radioProxy = getRadioProxy(result);
   3152         if (radioProxy != null) {
   3153             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_OPEN_CHANNEL, result,
   3154                     mRILDefaultWorkSource);
   3155 
   3156             if (RILJ_LOGD) {
   3157                 if (Build.IS_DEBUGGABLE) {
   3158                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " aid = " + aid
   3159                             + " p2 = " + p2);
   3160                 } else {
   3161                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3162                 }
   3163             }
   3164 
   3165             try {
   3166                 radioProxy.iccOpenLogicalChannel(rr.mSerial, convertNullToEmptyString(aid), p2);
   3167             } catch (RemoteException | RuntimeException e) {
   3168                 handleRadioProxyExceptionForRR(rr, "iccOpenLogicalChannel", e);
   3169             }
   3170         }
   3171     }
   3172 
   3173     @Override
   3174     public void iccCloseLogicalChannel(int channel, Message result) {
   3175         IRadio radioProxy = getRadioProxy(result);
   3176         if (radioProxy != null) {
   3177             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_CLOSE_CHANNEL, result,
   3178                     mRILDefaultWorkSource);
   3179 
   3180             if (RILJ_LOGD) {
   3181                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
   3182                         + channel);
   3183             }
   3184 
   3185             try {
   3186                 radioProxy.iccCloseLogicalChannel(rr.mSerial, channel);
   3187             } catch (RemoteException | RuntimeException e) {
   3188                 handleRadioProxyExceptionForRR(rr, "iccCloseLogicalChannel", e);
   3189             }
   3190         }
   3191     }
   3192 
   3193     @Override
   3194     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
   3195                                               int p1, int p2, int p3, String data,
   3196                                               Message result) {
   3197         if (channel <= 0) {
   3198             throw new RuntimeException(
   3199                     "Invalid channel in iccTransmitApduLogicalChannel: " + channel);
   3200         }
   3201 
   3202         IRadio radioProxy = getRadioProxy(result);
   3203         if (radioProxy != null) {
   3204             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, result,
   3205                     mRILDefaultWorkSource);
   3206 
   3207             if (RILJ_LOGD) {
   3208                 if (Build.IS_DEBUGGABLE) {
   3209                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
   3210                             + channel + " cla = " + cla + " instruction = " + instruction
   3211                             + " p1 = " + p1 + " p2 = " + " p3 = " + p3 + " data = " + data);
   3212                 } else {
   3213                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3214                 }
   3215             }
   3216 
   3217             SimApdu msg = createSimApdu(channel, cla, instruction, p1, p2, p3, data);
   3218 
   3219             try {
   3220                 radioProxy.iccTransmitApduLogicalChannel(rr.mSerial, msg);
   3221             } catch (RemoteException | RuntimeException e) {
   3222                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduLogicalChannel", e);
   3223             }
   3224         }
   3225     }
   3226 
   3227     @Override
   3228     public void nvReadItem(int itemID, Message result) {
   3229         IRadio radioProxy = getRadioProxy(result);
   3230         if (radioProxy != null) {
   3231             RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result,
   3232                     mRILDefaultWorkSource);
   3233 
   3234             if (RILJ_LOGD) {
   3235                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3236                         + " itemId = " + itemID);
   3237             }
   3238 
   3239             try {
   3240                 radioProxy.nvReadItem(rr.mSerial, itemID);
   3241             } catch (RemoteException | RuntimeException e) {
   3242                 handleRadioProxyExceptionForRR(rr, "nvReadItem", e);
   3243             }
   3244         }
   3245     }
   3246 
   3247     @Override
   3248     public void nvWriteItem(int itemId, String itemValue, Message result) {
   3249         IRadio radioProxy = getRadioProxy(result);
   3250         if (radioProxy != null) {
   3251             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result,
   3252                     mRILDefaultWorkSource);
   3253 
   3254             if (RILJ_LOGD) {
   3255                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3256                         + " itemId = " + itemId + " itemValue = " + itemValue);
   3257             }
   3258 
   3259             NvWriteItem item = new NvWriteItem();
   3260             item.itemId = itemId;
   3261             item.value = convertNullToEmptyString(itemValue);
   3262 
   3263             try {
   3264                 radioProxy.nvWriteItem(rr.mSerial, item);
   3265             } catch (RemoteException | RuntimeException e) {
   3266                 handleRadioProxyExceptionForRR(rr, "nvWriteItem", e);
   3267             }
   3268         }
   3269     }
   3270 
   3271     @Override
   3272     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
   3273         IRadio radioProxy = getRadioProxy(result);
   3274         if (radioProxy != null) {
   3275             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_CDMA_PRL, result,
   3276                     mRILDefaultWorkSource);
   3277 
   3278             if (RILJ_LOGD) {
   3279                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3280                         + " PreferredRoamingList = 0x"
   3281                         + IccUtils.bytesToHexString(preferredRoamingList));
   3282             }
   3283 
   3284             ArrayList<Byte> arrList = new ArrayList<>();
   3285             for (int i = 0; i < preferredRoamingList.length; i++) {
   3286                 arrList.add(preferredRoamingList[i]);
   3287             }
   3288 
   3289             try {
   3290                 radioProxy.nvWriteCdmaPrl(rr.mSerial, arrList);
   3291             } catch (RemoteException | RuntimeException e) {
   3292                 handleRadioProxyExceptionForRR(rr, "nvWriteCdmaPrl", e);
   3293             }
   3294         }
   3295     }
   3296 
   3297     @Override
   3298     public void nvResetConfig(int resetType, Message result) {
   3299         IRadio radioProxy = getRadioProxy(result);
   3300         if (radioProxy != null) {
   3301             RILRequest rr = obtainRequest(RIL_REQUEST_NV_RESET_CONFIG, result,
   3302                     mRILDefaultWorkSource);
   3303 
   3304             if (RILJ_LOGD) {
   3305                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3306                         + " resetType = " + resetType);
   3307             }
   3308 
   3309             try {
   3310                 radioProxy.nvResetConfig(rr.mSerial, convertToHalResetNvType(resetType));
   3311             } catch (RemoteException | RuntimeException e) {
   3312                 handleRadioProxyExceptionForRR(rr, "nvResetConfig", e);
   3313             }
   3314         }
   3315     }
   3316 
   3317     @Override
   3318     public void setUiccSubscription(int slotId, int appIndex, int subId,
   3319                                     int subStatus, Message result) {
   3320         IRadio radioProxy = getRadioProxy(result);
   3321         if (radioProxy != null) {
   3322             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UICC_SUBSCRIPTION, result,
   3323                     mRILDefaultWorkSource);
   3324 
   3325             if (RILJ_LOGD) {
   3326                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3327                         + " slot = " + slotId + " appIndex = " + appIndex
   3328                         + " subId = " + subId + " subStatus = " + subStatus);
   3329             }
   3330 
   3331             SelectUiccSub info = new SelectUiccSub();
   3332             info.slot = slotId;
   3333             info.appIndex = appIndex;
   3334             info.subType = subId;
   3335             info.actStatus = subStatus;
   3336 
   3337             try {
   3338                 radioProxy.setUiccSubscription(rr.mSerial, info);
   3339             } catch (RemoteException | RuntimeException e) {
   3340                 handleRadioProxyExceptionForRR(rr, "setUiccSubscription", e);
   3341             }
   3342         }
   3343     }
   3344 
   3345     @Override
   3346     public void setDataAllowed(boolean allowed, Message result) {
   3347         IRadio radioProxy = getRadioProxy(result);
   3348         if (radioProxy != null) {
   3349             RILRequest rr = obtainRequest(RIL_REQUEST_ALLOW_DATA, result,
   3350                     mRILDefaultWorkSource);
   3351 
   3352             if (RILJ_LOGD) {
   3353                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3354                         + " allowed = " + allowed);
   3355             }
   3356 
   3357             try {
   3358                 radioProxy.setDataAllowed(rr.mSerial, allowed);
   3359             } catch (RemoteException | RuntimeException e) {
   3360                 handleRadioProxyExceptionForRR(rr, "setDataAllowed", e);
   3361             }
   3362         }
   3363     }
   3364 
   3365     @Override
   3366     public void getHardwareConfig(Message result) {
   3367         IRadio radioProxy = getRadioProxy(result);
   3368         if (radioProxy != null) {
   3369             RILRequest rr = obtainRequest(RIL_REQUEST_GET_HARDWARE_CONFIG, result,
   3370                     mRILDefaultWorkSource);
   3371 
   3372             // Do not log function args for privacy
   3373             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3374 
   3375             try {
   3376                 radioProxy.getHardwareConfig(rr.mSerial);
   3377             } catch (RemoteException | RuntimeException e) {
   3378                 handleRadioProxyExceptionForRR(rr, "getHardwareConfig", e);
   3379             }
   3380         }
   3381     }
   3382 
   3383     @Override
   3384     public void requestIccSimAuthentication(int authContext, String data, String aid,
   3385                                             Message result) {
   3386         IRadio radioProxy = getRadioProxy(result);
   3387         if (radioProxy != null) {
   3388             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_AUTHENTICATION, result,
   3389                     mRILDefaultWorkSource);
   3390 
   3391             // Do not log function args for privacy
   3392             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3393 
   3394             try {
   3395                 radioProxy.requestIccSimAuthentication(rr.mSerial,
   3396                         authContext,
   3397                         convertNullToEmptyString(data),
   3398                         convertNullToEmptyString(aid));
   3399             } catch (RemoteException | RuntimeException e) {
   3400                 handleRadioProxyExceptionForRR(rr, "requestIccSimAuthentication", e);
   3401             }
   3402         }
   3403     }
   3404 
   3405     @Override
   3406     public void setDataProfile(DataProfile[] dps, boolean isRoaming, Message result) {
   3407 
   3408         IRadio radioProxy = getRadioProxy(result);
   3409         if (radioProxy != null) {
   3410             RILRequest rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
   3411                     mRILDefaultWorkSource);
   3412 
   3413             if (RILJ_LOGD) {
   3414                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3415                         + " with data profiles : ");
   3416                 for (DataProfile profile : dps) {
   3417                     riljLog(profile.toString());
   3418                 }
   3419             }
   3420 
   3421             ArrayList<DataProfileInfo> dpis = new ArrayList<>();
   3422             for (DataProfile dp : dps) {
   3423                 dpis.add(convertToHalDataProfile(dp));
   3424             }
   3425 
   3426             try {
   3427                 radioProxy.setDataProfile(rr.mSerial, dpis, isRoaming);
   3428             } catch (RemoteException | RuntimeException e) {
   3429                 handleRadioProxyExceptionForRR(rr, "setDataProfile", e);
   3430             }
   3431         }
   3432     }
   3433 
   3434     @Override
   3435     public void requestShutdown(Message result) {
   3436         IRadio radioProxy = getRadioProxy(result);
   3437         if (radioProxy != null) {
   3438             RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result,
   3439                     mRILDefaultWorkSource);
   3440 
   3441             if (RILJ_LOGD) {
   3442                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3443             }
   3444 
   3445             try {
   3446                 radioProxy.requestShutdown(rr.mSerial);
   3447             } catch (RemoteException | RuntimeException e) {
   3448                 handleRadioProxyExceptionForRR(rr, "requestShutdown", e);
   3449             }
   3450         }
   3451     }
   3452 
   3453     @Override
   3454     public void getRadioCapability(Message response) {
   3455         IRadio radioProxy = getRadioProxy(response);
   3456         if (radioProxy != null) {
   3457             RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, response,
   3458                     mRILDefaultWorkSource);
   3459 
   3460             if (RILJ_LOGD) {
   3461                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3462             }
   3463 
   3464             try {
   3465                 radioProxy.getRadioCapability(rr.mSerial);
   3466             } catch (RemoteException | RuntimeException e) {
   3467                 handleRadioProxyExceptionForRR(rr, "getRadioCapability", e);
   3468             }
   3469         }
   3470     }
   3471 
   3472     @Override
   3473     public void setRadioCapability(RadioCapability rc, Message response) {
   3474         IRadio radioProxy = getRadioProxy(response);
   3475         if (radioProxy != null) {
   3476             RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, response,
   3477                     mRILDefaultWorkSource);
   3478 
   3479             if (RILJ_LOGD) {
   3480                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3481                         + " RadioCapability = " + rc.toString());
   3482             }
   3483 
   3484             android.hardware.radio.V1_0.RadioCapability halRc =
   3485                     new android.hardware.radio.V1_0.RadioCapability();
   3486 
   3487             halRc.session = rc.getSession();
   3488             halRc.phase = rc.getPhase();
   3489             halRc.raf = rc.getRadioAccessFamily();
   3490             halRc.logicalModemUuid = convertNullToEmptyString(rc.getLogicalModemUuid());
   3491             halRc.status = rc.getStatus();
   3492 
   3493             try {
   3494                 radioProxy.setRadioCapability(rr.mSerial, halRc);
   3495             } catch (Exception e) {
   3496                 handleRadioProxyExceptionForRR(rr, "setRadioCapability", e);
   3497             }
   3498         }
   3499     }
   3500 
   3501     @Override
   3502     public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
   3503         IRadio radioProxy = getRadioProxy(result);
   3504         android.hardware.radio.V1_2.IRadio radioProxy12 =
   3505                 android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   3506         if (radioProxy12 != null) {
   3507             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control path is unused.
   3508             // Instead the LCE functionality is always-on and provides unsolicited indications.
   3509             return;
   3510         }
   3511 
   3512         if (radioProxy != null) {
   3513             RILRequest rr = obtainRequest(RIL_REQUEST_START_LCE, result,
   3514                     mRILDefaultWorkSource);
   3515 
   3516             if (RILJ_LOGD) {
   3517                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
   3518                         + " reportIntervalMs = " + reportIntervalMs + " pullMode = " + pullMode);
   3519             }
   3520 
   3521             try {
   3522                 radioProxy.startLceService(rr.mSerial, reportIntervalMs, pullMode);
   3523             } catch (RemoteException | RuntimeException e) {
   3524                 handleRadioProxyExceptionForRR(rr, "startLceService", e);
   3525             }
   3526         }
   3527     }
   3528 
   3529     @Override
   3530     public void stopLceService(Message result) {
   3531         IRadio radioProxy = getRadioProxy(result);
   3532         android.hardware.radio.V1_2.IRadio radioProxy12 =
   3533                 android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   3534         if (radioProxy12 != null) {
   3535             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control is unused.
   3536             // Instead the LCE functionality is always-on and provides unsolicited indications.
   3537             return;
   3538         }
   3539 
   3540         if (radioProxy != null) {
   3541             RILRequest rr = obtainRequest(RIL_REQUEST_STOP_LCE, result,
   3542                     mRILDefaultWorkSource);
   3543 
   3544             if (RILJ_LOGD) {
   3545                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3546             }
   3547 
   3548             try {
   3549                 radioProxy.stopLceService(rr.mSerial);
   3550             } catch (RemoteException | RuntimeException e) {
   3551                 handleRadioProxyExceptionForRR(rr, "stopLceService", e);
   3552             }
   3553         }
   3554     }
   3555 
   3556     /**
   3557      * This will only be called if the LCE service is started in PULL mode, which is
   3558      * only enabled when using Radio HAL versions 1.1 and earlier.
   3559      *
   3560      * It is still possible for vendors to override this behavior and use the 1.1 version
   3561      * of LCE; however, this is strongly discouraged and this functionality will be removed
   3562      * when HAL 1.x support is dropped.
   3563      *
   3564      * @deprecated HAL 1.2 and later use an always-on LCE that relies on indications.
   3565      */
   3566     @Deprecated
   3567     @Override
   3568     public void pullLceData(Message response) {
   3569         IRadio radioProxy = getRadioProxy(response);
   3570         if (radioProxy != null) {
   3571             RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, response,
   3572                     mRILDefaultWorkSource);
   3573 
   3574             if (RILJ_LOGD) {
   3575                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3576             }
   3577 
   3578             try {
   3579                 radioProxy.pullLceData(rr.mSerial);
   3580             } catch (RemoteException | RuntimeException e) {
   3581                 handleRadioProxyExceptionForRR(rr, "pullLceData", e);
   3582             }
   3583         }
   3584     }
   3585 
   3586     @Override
   3587     public void getModemActivityInfo(Message result) {
   3588         IRadio radioProxy = getRadioProxy(result);
   3589         if (radioProxy != null) {
   3590             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
   3591                     mRILDefaultWorkSource);
   3592 
   3593             if (RILJ_LOGD) {
   3594                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3595             }
   3596 
   3597             try {
   3598                 radioProxy.getModemActivityInfo(rr.mSerial);
   3599 
   3600                 Message msg = mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT);
   3601                 msg.obj = null;
   3602                 msg.arg1 = rr.mSerial;
   3603                 mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
   3604             } catch (RemoteException | RuntimeException e) {
   3605                 handleRadioProxyExceptionForRR(rr, "getModemActivityInfo", e);
   3606             }
   3607         }
   3608 
   3609 
   3610     }
   3611 
   3612     @Override
   3613     public void setAllowedCarriers(List<CarrierIdentifier> carriers, Message result) {
   3614         checkNotNull(carriers, "Allowed carriers list cannot be null.");
   3615         IRadio radioProxy = getRadioProxy(result);
   3616         if (radioProxy != null) {
   3617             RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result,
   3618                     mRILDefaultWorkSource);
   3619 
   3620             if (RILJ_LOGD) {
   3621                 String logStr = "";
   3622                 for (int i = 0; i < carriers.size(); i++) {
   3623                     logStr = logStr + carriers.get(i) + " ";
   3624                 }
   3625                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " carriers = "
   3626                         + logStr);
   3627             }
   3628 
   3629             boolean allAllowed;
   3630             if (carriers.size() == 0) {
   3631                 allAllowed = true;
   3632             } else {
   3633                 allAllowed = false;
   3634             }
   3635             CarrierRestrictions carrierList = new CarrierRestrictions();
   3636 
   3637             for (CarrierIdentifier ci : carriers) { /* allowed carriers */
   3638                 Carrier c = new Carrier();
   3639                 c.mcc = convertNullToEmptyString(ci.getMcc());
   3640                 c.mnc = convertNullToEmptyString(ci.getMnc());
   3641                 int matchType = CarrierIdentifier.MatchType.ALL;
   3642                 String matchData = null;
   3643                 if (!TextUtils.isEmpty(ci.getSpn())) {
   3644                     matchType = CarrierIdentifier.MatchType.SPN;
   3645                     matchData = ci.getSpn();
   3646                 } else if (!TextUtils.isEmpty(ci.getImsi())) {
   3647                     matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
   3648                     matchData = ci.getImsi();
   3649                 } else if (!TextUtils.isEmpty(ci.getGid1())) {
   3650                     matchType = CarrierIdentifier.MatchType.GID1;
   3651                     matchData = ci.getGid1();
   3652                 } else if (!TextUtils.isEmpty(ci.getGid2())) {
   3653                     matchType = CarrierIdentifier.MatchType.GID2;
   3654                     matchData = ci.getGid2();
   3655                 }
   3656                 c.matchType = matchType;
   3657                 c.matchData = convertNullToEmptyString(matchData);
   3658                 carrierList.allowedCarriers.add(c);
   3659             }
   3660 
   3661             /* TODO: add excluded carriers */
   3662 
   3663             try {
   3664                 radioProxy.setAllowedCarriers(rr.mSerial, allAllowed, carrierList);
   3665             } catch (RemoteException | RuntimeException e) {
   3666                 handleRadioProxyExceptionForRR(rr, "setAllowedCarriers", e);
   3667             }
   3668         }
   3669     }
   3670 
   3671     @Override
   3672     public void getAllowedCarriers(Message result) {
   3673         IRadio radioProxy = getRadioProxy(result);
   3674         if (radioProxy != null) {
   3675             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result,
   3676                     mRILDefaultWorkSource);
   3677 
   3678             if (RILJ_LOGD) {
   3679                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3680             }
   3681 
   3682             try {
   3683                 radioProxy.getAllowedCarriers(rr.mSerial);
   3684             } catch (RemoteException | RuntimeException e) {
   3685                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
   3686             }
   3687         }
   3688     }
   3689 
   3690     @Override
   3691     public void sendDeviceState(int stateType, boolean state,
   3692                                 Message result) {
   3693         IRadio radioProxy = getRadioProxy(result);
   3694         if (radioProxy != null) {
   3695             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
   3696                     mRILDefaultWorkSource);
   3697 
   3698             if (RILJ_LOGD) {
   3699                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
   3700                         + stateType + ":" + state);
   3701             }
   3702 
   3703             try {
   3704                 radioProxy.sendDeviceState(rr.mSerial, stateType, state);
   3705             } catch (RemoteException | RuntimeException e) {
   3706                 handleRadioProxyExceptionForRR(rr, "sendDeviceState", e);
   3707             }
   3708         }
   3709     }
   3710 
   3711     @Override
   3712     public void setUnsolResponseFilter(int filter, Message result) {
   3713         IRadio radioProxy = getRadioProxy(result);
   3714         if (radioProxy != null) {
   3715             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, result,
   3716                     mRILDefaultWorkSource);
   3717 
   3718             if (RILJ_LOGD) {
   3719                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + filter);
   3720             }
   3721 
   3722             android.hardware.radio.V1_2.IRadio radioProxy12 =
   3723                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   3724 
   3725             if (radioProxy12 != null) {
   3726                 try {
   3727                     radioProxy12.setIndicationFilter_1_2(rr.mSerial, filter);
   3728                 } catch (RemoteException | RuntimeException e) {
   3729                     handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_2", e);
   3730                 }
   3731             } else {
   3732                 try {
   3733                     int filter10 = filter & IndicationFilter.ALL;
   3734                     radioProxy.setIndicationFilter(rr.mSerial, filter10);
   3735                 } catch (RemoteException | RuntimeException e) {
   3736                     handleRadioProxyExceptionForRR(rr, "setIndicationFilter", e);
   3737                 }
   3738             }
   3739         }
   3740     }
   3741 
   3742     @Override
   3743     public void setSignalStrengthReportingCriteria(int hysteresisMs, int hysteresisDb,
   3744             int[] thresholdsDbm, int ran, Message result) {
   3745         IRadio radioProxy = getRadioProxy(result);
   3746         if (radioProxy != null) {
   3747             android.hardware.radio.V1_2.IRadio radioProxy12 =
   3748                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   3749             if (radioProxy12 == null) {
   3750                 riljLoge("setSignalStrengthReportingCriteria ignored. RadioProxy 1.2 is null!");
   3751                 return;
   3752             }
   3753 
   3754             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
   3755                     result, mRILDefaultWorkSource);
   3756 
   3757             if (RILJ_LOGD) {
   3758                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3759             }
   3760 
   3761             try {
   3762                 radioProxy12.setSignalStrengthReportingCriteria(rr.mSerial, hysteresisMs,
   3763                         hysteresisDb, primitiveArrayToArrayList(thresholdsDbm),
   3764                         convertRanToHalRan(ran));
   3765             } catch (RemoteException | RuntimeException e) {
   3766                 handleRadioProxyExceptionForRR(rr, "setSignalStrengthReportingCriteria", e);
   3767             }
   3768         }
   3769     }
   3770 
   3771     @Override
   3772     public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
   3773             int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
   3774             Message result) {
   3775         IRadio radioProxy = getRadioProxy(result);
   3776         if (radioProxy != null) {
   3777             android.hardware.radio.V1_2.IRadio radioProxy12 =
   3778                     android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
   3779             if (radioProxy12 == null) {
   3780                 riljLoge("setLinkCapacityReportingCriteria ignored. RadioProxy 1.2 is null!");
   3781                 return;
   3782             }
   3783 
   3784             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA,
   3785                     result, mRILDefaultWorkSource);
   3786 
   3787             if (RILJ_LOGD) {
   3788                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3789             }
   3790 
   3791             try {
   3792                 radioProxy12.setLinkCapacityReportingCriteria(rr.mSerial, hysteresisMs,
   3793                         hysteresisDlKbps, hysteresisUlKbps,
   3794                         primitiveArrayToArrayList(thresholdsDlKbps),
   3795                         primitiveArrayToArrayList(thresholdsUlKbps), convertRanToHalRan(ran));
   3796             } catch (RemoteException | RuntimeException e) {
   3797                 handleRadioProxyExceptionForRR(rr, "setLinkCapacityReportingCriteria", e);
   3798             }
   3799         }
   3800     }
   3801 
   3802     private static int convertRanToHalRan(int radioAccessNetwork) {
   3803         switch (radioAccessNetwork) {
   3804             case AccessNetworkType.GERAN:
   3805                 return AccessNetwork.GERAN;
   3806             case AccessNetworkType.UTRAN:
   3807                 return AccessNetwork.UTRAN;
   3808             case AccessNetworkType.EUTRAN:
   3809                 return AccessNetwork.EUTRAN;
   3810             case AccessNetworkType.CDMA2000:
   3811                 return AccessNetwork.CDMA2000;
   3812             case AccessNetworkType.IWLAN:
   3813                 return AccessNetwork.IWLAN;
   3814             case AccessNetworkType.UNKNOWN:
   3815             default:
   3816                 return 0;
   3817         }
   3818     }
   3819 
   3820     @Override
   3821     public void setSimCardPower(int state, Message result) {
   3822         IRadio radioProxy = getRadioProxy(result);
   3823         if (radioProxy != null) {
   3824             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIM_CARD_POWER, result,
   3825                     mRILDefaultWorkSource);
   3826 
   3827             if (RILJ_LOGD) {
   3828                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + state);
   3829             }
   3830             android.hardware.radio.V1_1.IRadio radioProxy11 =
   3831                     android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   3832             if (radioProxy11 == null) {
   3833                 try {
   3834                     switch (state) {
   3835                         case TelephonyManager.CARD_POWER_DOWN: {
   3836                             radioProxy.setSimCardPower(rr.mSerial, false);
   3837                             break;
   3838                         }
   3839                         case TelephonyManager.CARD_POWER_UP: {
   3840                             radioProxy.setSimCardPower(rr.mSerial, true);
   3841                             break;
   3842                         }
   3843                         default: {
   3844                             if (result != null) {
   3845                                 AsyncResult.forMessage(result, null,
   3846                                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   3847                                 result.sendToTarget();
   3848                             }
   3849                         }
   3850                     }
   3851                 } catch (RemoteException | RuntimeException e) {
   3852                     handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
   3853                 }
   3854             } else {
   3855                 try {
   3856                     radioProxy11.setSimCardPower_1_1(rr.mSerial, state);
   3857                 } catch (RemoteException | RuntimeException e) {
   3858                     handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
   3859                 }
   3860             }
   3861         }
   3862     }
   3863 
   3864     @Override
   3865     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
   3866                                                 Message result) {
   3867         checkNotNull(imsiEncryptionInfo, "ImsiEncryptionInfo cannot be null.");
   3868         IRadio radioProxy = getRadioProxy(result);
   3869         if (radioProxy != null) {
   3870             android.hardware.radio.V1_1.IRadio radioProxy11 =
   3871                     android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   3872             if (radioProxy11 == null) {
   3873                 if (result != null) {
   3874                     AsyncResult.forMessage(result, null,
   3875                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   3876                     result.sendToTarget();
   3877                 }
   3878             } else {
   3879                 RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
   3880                         mRILDefaultWorkSource);
   3881                 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3882 
   3883                 try {
   3884                     android.hardware.radio.V1_1.ImsiEncryptionInfo halImsiInfo =
   3885                             new android.hardware.radio.V1_1.ImsiEncryptionInfo();
   3886                     halImsiInfo.mnc = imsiEncryptionInfo.getMnc();
   3887                     halImsiInfo.mcc = imsiEncryptionInfo.getMcc();
   3888                     halImsiInfo.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
   3889                     if (imsiEncryptionInfo.getExpirationTime() != null) {
   3890                         halImsiInfo.expirationTime =
   3891                                 imsiEncryptionInfo.getExpirationTime().getTime();
   3892                     }
   3893                     for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
   3894                         halImsiInfo.carrierKey.add(new Byte(b));
   3895                     }
   3896 
   3897                     radioProxy11.setCarrierInfoForImsiEncryption(
   3898                             rr.mSerial, halImsiInfo);
   3899                 } catch (RemoteException | RuntimeException e) {
   3900                     handleRadioProxyExceptionForRR(rr, "setCarrierInfoForImsiEncryption", e);
   3901                 }
   3902             }
   3903         }
   3904     }
   3905 
   3906     @Override
   3907     public void startNattKeepalive(
   3908             int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) {
   3909         checkNotNull(packetData, "KeepaliveRequest cannot be null.");
   3910         IRadio radioProxy = getRadioProxy(result);
   3911         if (radioProxy == null) {
   3912             riljLoge("Radio Proxy object is null!");
   3913             return;
   3914         }
   3915 
   3916         android.hardware.radio.V1_1.IRadio radioProxy11 =
   3917                 android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   3918         if (radioProxy11 == null) {
   3919             if (result != null) {
   3920                 AsyncResult.forMessage(result, null,
   3921                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   3922                 result.sendToTarget();
   3923             }
   3924             return;
   3925         }
   3926 
   3927         RILRequest rr = obtainRequest(
   3928                 RIL_REQUEST_START_KEEPALIVE, result, mRILDefaultWorkSource);
   3929 
   3930         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3931 
   3932         try {
   3933             android.hardware.radio.V1_1.KeepaliveRequest req =
   3934                     new android.hardware.radio.V1_1.KeepaliveRequest();
   3935 
   3936             req.cid = contextId;
   3937 
   3938             if (packetData.dstAddress instanceof Inet4Address) {
   3939                 req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV4;
   3940             } else if (packetData.dstAddress instanceof Inet6Address) {
   3941                 req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV6;
   3942             } else {
   3943                 AsyncResult.forMessage(result, null,
   3944                         CommandException.fromRilErrno(INVALID_ARGUMENTS));
   3945                 result.sendToTarget();
   3946                 return;
   3947             }
   3948 
   3949             appendPrimitiveArrayToArrayList(
   3950                     packetData.srcAddress.getAddress(), req.sourceAddress);
   3951             req.sourcePort = packetData.srcPort;
   3952             appendPrimitiveArrayToArrayList(
   3953                     packetData.dstAddress.getAddress(), req.destinationAddress);
   3954             req.destinationPort = packetData.dstPort;
   3955 
   3956             radioProxy11.startKeepalive(rr.mSerial, req);
   3957         } catch (RemoteException | RuntimeException e) {
   3958             handleRadioProxyExceptionForRR(rr, "startNattKeepalive", e);
   3959         }
   3960     }
   3961 
   3962     @Override
   3963     public void stopNattKeepalive(int sessionHandle, Message result) {
   3964         IRadio radioProxy = getRadioProxy(result);
   3965         if (radioProxy == null) {
   3966             Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!");
   3967             return;
   3968         }
   3969 
   3970         android.hardware.radio.V1_1.IRadio radioProxy11 =
   3971                 android.hardware.radio.V1_1.IRadio.castFrom(radioProxy);
   3972         if (radioProxy11 == null) {
   3973             if (result != null) {
   3974                 AsyncResult.forMessage(result, null,
   3975                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
   3976                 result.sendToTarget();
   3977             }
   3978             return;
   3979         }
   3980 
   3981         RILRequest rr = obtainRequest(
   3982                 RIL_REQUEST_STOP_KEEPALIVE, result, mRILDefaultWorkSource);
   3983 
   3984         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   3985 
   3986         try {
   3987             radioProxy11.stopKeepalive(rr.mSerial, sessionHandle);
   3988         } catch (RemoteException | RuntimeException e) {
   3989             handleRadioProxyExceptionForRR(rr, "stopNattKeepalive", e);
   3990         }
   3991     }
   3992 
   3993     @Override
   3994     public void getIMEI(Message result) {
   3995         throw new RuntimeException("getIMEI not expected to be called");
   3996     }
   3997 
   3998     @Override
   3999     public void getIMEISV(Message result) {
   4000         throw new RuntimeException("getIMEISV not expected to be called");
   4001     }
   4002 
   4003     /**
   4004      * @deprecated
   4005      */
   4006     @Deprecated
   4007     @Override
   4008     public void getLastPdpFailCause(Message result) {
   4009         throw new RuntimeException("getLastPdpFailCause not expected to be called");
   4010     }
   4011 
   4012     /**
   4013      * The preferred new alternative to getLastPdpFailCause
   4014      */
   4015     @Override
   4016     public void getLastDataCallFailCause(Message result) {
   4017         throw new RuntimeException("getLastDataCallFailCause not expected to be called");
   4018     }
   4019 
   4020     /**
   4021      *  Translates EF_SMS status bits to a status value compatible with
   4022      *  SMS AT commands.  See TS 27.005 3.1.
   4023      */
   4024     private int translateStatus(int status) {
   4025         switch(status & 0x7) {
   4026             case SmsManager.STATUS_ON_ICC_READ:
   4027                 return 1;
   4028             case SmsManager.STATUS_ON_ICC_UNREAD:
   4029                 return 0;
   4030             case SmsManager.STATUS_ON_ICC_SENT:
   4031                 return 3;
   4032             case SmsManager.STATUS_ON_ICC_UNSENT:
   4033                 return 2;
   4034         }
   4035 
   4036         // Default to READ.
   4037         return 1;
   4038     }
   4039 
   4040     @Override
   4041     public void resetRadio(Message result) {
   4042         throw new RuntimeException("resetRadio not expected to be called");
   4043     }
   4044 
   4045     /**
   4046      * {@inheritDoc}
   4047      */
   4048     @Override
   4049     public void handleCallSetupRequestFromSim(boolean accept, Message result) {
   4050         IRadio radioProxy = getRadioProxy(result);
   4051         if (radioProxy != null) {
   4052             RILRequest rr = obtainRequest(RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
   4053                     result, mRILDefaultWorkSource);
   4054 
   4055             if (RILJ_LOGD) {
   4056                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   4057             }
   4058 
   4059             try {
   4060                 radioProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
   4061             } catch (RemoteException | RuntimeException e) {
   4062                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
   4063             }
   4064         }
   4065     }
   4066 
   4067     //***** Private Methods
   4068 
   4069     /**
   4070      * This is a helper function to be called when a RadioIndication callback is called.
   4071      * It takes care of acquiring wakelock and sending ack if needed.
   4072      * @param indicationType RadioIndicationType received
   4073      */
   4074     void processIndication(int indicationType) {
   4075         if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
   4076             sendAck();
   4077             if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
   4078         } else {
   4079             // ack is not expected to be sent back. Nothing is required to be done here.
   4080         }
   4081     }
   4082 
   4083     void processRequestAck(int serial) {
   4084         RILRequest rr;
   4085         synchronized (mRequestList) {
   4086             rr = mRequestList.get(serial);
   4087         }
   4088         if (rr == null) {
   4089             Rlog.w(RIL.RILJ_LOG_TAG, "processRequestAck: Unexpected solicited ack response! "
   4090                     + "serial: " + serial);
   4091         } else {
   4092             decrementWakeLock(rr);
   4093             if (RIL.RILJ_LOGD) {
   4094                 riljLog(rr.serialString() + " Ack < " + RIL.requestToString(rr.mRequest));
   4095             }
   4096         }
   4097     }
   4098 
   4099     /**
   4100      * This is a helper function to be called when a RadioResponse callback is called.
   4101      * It takes care of acks, wakelocks, and finds and returns RILRequest corresponding to the
   4102      * response if one is found.
   4103      * @param responseInfo RadioResponseInfo received in response callback
   4104      * @return RILRequest corresponding to the response
   4105      */
   4106     @VisibleForTesting
   4107     public RILRequest processResponse(RadioResponseInfo responseInfo) {
   4108         int serial = responseInfo.serial;
   4109         int error = responseInfo.error;
   4110         int type = responseInfo.type;
   4111 
   4112         RILRequest rr = null;
   4113 
   4114         if (type == RadioResponseType.SOLICITED_ACK) {
   4115             synchronized (mRequestList) {
   4116                 rr = mRequestList.get(serial);
   4117             }
   4118             if (rr == null) {
   4119                 Rlog.w(RILJ_LOG_TAG, "Unexpected solicited ack response! sn: " + serial);
   4120             } else {
   4121                 decrementWakeLock(rr);
   4122                 if (RILJ_LOGD) {
   4123                     riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest));
   4124                 }
   4125             }
   4126             return rr;
   4127         }
   4128 
   4129         rr = findAndRemoveRequestFromList(serial);
   4130         if (rr == null) {
   4131             Rlog.e(RIL.RILJ_LOG_TAG, "processResponse: Unexpected response! serial: " + serial
   4132                     + " error: " + error);
   4133             return null;
   4134         }
   4135 
   4136         // Time logging for RIL command and storing it in TelephonyHistogram.
   4137         addToRilHistogram(rr);
   4138 
   4139         if (type == RadioResponseType.SOLICITED_ACK_EXP) {
   4140             sendAck();
   4141             if (RIL.RILJ_LOGD) {
   4142                 riljLog("Response received for " + rr.serialString() + " "
   4143                         + RIL.requestToString(rr.mRequest) + " Sending ack to ril.cpp");
   4144             }
   4145         } else {
   4146             // ack sent for SOLICITED_ACK_EXP above; nothing to do for SOLICITED response
   4147         }
   4148 
   4149         // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
   4150         // This is needed otherwise we don't automatically transition to the main lock
   4151         // screen when the pin or puk is entered incorrectly.
   4152         switch (rr.mRequest) {
   4153             case RIL_REQUEST_ENTER_SIM_PUK:
   4154             case RIL_REQUEST_ENTER_SIM_PUK2:
   4155                 if (mIccStatusChangedRegistrants != null) {
   4156                     if (RILJ_LOGD) {
   4157                         riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
   4158                                 + mIccStatusChangedRegistrants.size());
   4159                     }
   4160                     mIccStatusChangedRegistrants.notifyRegistrants();
   4161                 }
   4162                 break;
   4163             case RIL_REQUEST_SHUTDOWN:
   4164                 setRadioState(RadioState.RADIO_UNAVAILABLE);
   4165                 break;
   4166         }
   4167 
   4168         if (error != RadioError.NONE) {
   4169             switch (rr.mRequest) {
   4170                 case RIL_REQUEST_ENTER_SIM_PIN:
   4171                 case RIL_REQUEST_ENTER_SIM_PIN2:
   4172                 case RIL_REQUEST_CHANGE_SIM_PIN:
   4173                 case RIL_REQUEST_CHANGE_SIM_PIN2:
   4174                 case RIL_REQUEST_SET_FACILITY_LOCK:
   4175                     if (mIccStatusChangedRegistrants != null) {
   4176                         if (RILJ_LOGD) {
   4177                             riljLog("ON some errors fakeSimStatusChanged: reg count="
   4178                                     + mIccStatusChangedRegistrants.size());
   4179                         }
   4180                         mIccStatusChangedRegistrants.notifyRegistrants();
   4181                     }
   4182                     break;
   4183 
   4184             }
   4185         } else {
   4186             switch (rr.mRequest) {
   4187                 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
   4188                 if (mTestingEmergencyCall.getAndSet(false)) {
   4189                     if (mEmergencyCallbackModeRegistrant != null) {
   4190                         riljLog("testing emergency call, notify ECM Registrants");
   4191                         mEmergencyCallbackModeRegistrant.notifyRegistrant();
   4192                     }
   4193                 }
   4194             }
   4195         }
   4196         return rr;
   4197     }
   4198 
   4199     /**
   4200      * This is a helper function to be called at the end of all RadioResponse callbacks.
   4201      * It takes care of sending error response, logging, decrementing wakelock if needed, and
   4202      * releases the request from memory pool.
   4203      * @param rr RILRequest for which response callback was called
   4204      * @param responseInfo RadioResponseInfo received in the callback
   4205      * @param ret object to be returned to request sender
   4206      */
   4207     @VisibleForTesting
   4208     public void processResponseDone(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
   4209         if (responseInfo.error == 0) {
   4210             if (RILJ_LOGD) {
   4211                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
   4212                         + " " + retToString(rr.mRequest, ret));
   4213             }
   4214         } else {
   4215             if (RILJ_LOGD) {
   4216                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
   4217                         + " error " + responseInfo.error);
   4218             }
   4219             rr.onError(responseInfo.error, ret);
   4220         }
   4221         mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error,
   4222                 rr.mRequest, ret);
   4223         if (rr != null) {
   4224             if (responseInfo.type == RadioResponseType.SOLICITED) {
   4225                 decrementWakeLock(rr);
   4226             }
   4227             rr.release();
   4228         }
   4229     }
   4230 
   4231     /**
   4232      * Function to send ack and acquire related wakelock
   4233      */
   4234     private void sendAck() {
   4235         // TODO: Remove rr and clean up acquireWakelock for response and ack
   4236         RILRequest rr = RILRequest.obtain(RIL_RESPONSE_ACKNOWLEDGEMENT, null,
   4237                 mRILDefaultWorkSource);
   4238         acquireWakeLock(rr, RIL.FOR_ACK_WAKELOCK);
   4239         IRadio radioProxy = getRadioProxy(null);
   4240         if (radioProxy != null) {
   4241             try {
   4242                 radioProxy.responseAcknowledgement();
   4243             } catch (RemoteException | RuntimeException e) {
   4244                 handleRadioProxyExceptionForRR(rr, "sendAck", e);
   4245                 riljLoge("sendAck: " + e);
   4246             }
   4247         } else {
   4248             Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");
   4249         }
   4250         rr.release();
   4251     }
   4252 
   4253     private WorkSource getDeafultWorkSourceIfInvalid(WorkSource workSource) {
   4254         if (workSource == null) {
   4255             workSource = mRILDefaultWorkSource;
   4256         }
   4257 
   4258         return workSource;
   4259     }
   4260 
   4261 
   4262     /**
   4263      * Holds a PARTIAL_WAKE_LOCK whenever
   4264      * a) There is outstanding RIL request sent to RIL deamon and no replied
   4265      * b) There is a request pending to be sent out.
   4266      *
   4267      * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
   4268      * happen often.
   4269      */
   4270     private void acquireWakeLock(RILRequest rr, int wakeLockType) {
   4271         synchronized (rr) {
   4272             if (rr.mWakeLockType != INVALID_WAKELOCK) {
   4273                 Rlog.d(RILJ_LOG_TAG, "Failed to aquire wakelock for " + rr.serialString());
   4274                 return;
   4275             }
   4276 
   4277             switch(wakeLockType) {
   4278                 case FOR_WAKELOCK:
   4279                     synchronized (mWakeLock) {
   4280                         mWakeLock.acquire();
   4281                         mWakeLockCount++;
   4282                         mWlSequenceNum++;
   4283 
   4284                         String clientId = rr.getWorkSourceClientId();
   4285                         if (!mClientWakelockTracker.isClientActive(clientId)) {
   4286                             if (mActiveWakelockWorkSource != null) {
   4287                                 mActiveWakelockWorkSource.add(rr.mWorkSource);
   4288                             } else {
   4289                                 mActiveWakelockWorkSource = rr.mWorkSource;
   4290                             }
   4291                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
   4292                         }
   4293 
   4294                         mClientWakelockTracker.startTracking(rr.mClientId,
   4295                                 rr.mRequest, rr.mSerial, mWakeLockCount);
   4296 
   4297                         Message msg = mRilHandler.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
   4298                         msg.arg1 = mWlSequenceNum;
   4299                         mRilHandler.sendMessageDelayed(msg, mWakeLockTimeout);
   4300                     }
   4301                     break;
   4302                 case FOR_ACK_WAKELOCK:
   4303                     synchronized (mAckWakeLock) {
   4304                         mAckWakeLock.acquire();
   4305                         mAckWlSequenceNum++;
   4306 
   4307                         Message msg = mRilHandler.obtainMessage(EVENT_ACK_WAKE_LOCK_TIMEOUT);
   4308                         msg.arg1 = mAckWlSequenceNum;
   4309                         mRilHandler.sendMessageDelayed(msg, mAckWakeLockTimeout);
   4310                     }
   4311                     break;
   4312                 default: //WTF
   4313                     Rlog.w(RILJ_LOG_TAG, "Acquiring Invalid Wakelock type " + wakeLockType);
   4314                     return;
   4315             }
   4316             rr.mWakeLockType = wakeLockType;
   4317         }
   4318     }
   4319 
   4320     /** Returns the wake lock of the given type. */
   4321     @VisibleForTesting
   4322     public WakeLock getWakeLock(int wakeLockType) {
   4323         return wakeLockType == FOR_WAKELOCK ? mWakeLock : mAckWakeLock;
   4324     }
   4325 
   4326     /** Returns the {@link RilHandler} instance. */
   4327     @VisibleForTesting
   4328     public RilHandler getRilHandler() {
   4329         return mRilHandler;
   4330     }
   4331 
   4332     /** Returns the Ril request list. */
   4333     @VisibleForTesting
   4334     public SparseArray<RILRequest> getRilRequestList() {
   4335         return mRequestList;
   4336     }
   4337 
   4338     private void decrementWakeLock(RILRequest rr) {
   4339         synchronized (rr) {
   4340             switch(rr.mWakeLockType) {
   4341                 case FOR_WAKELOCK:
   4342                     synchronized (mWakeLock) {
   4343                         mClientWakelockTracker.stopTracking(rr.mClientId,
   4344                                 rr.mRequest, rr.mSerial,
   4345                                 (mWakeLockCount > 1) ? mWakeLockCount - 1 : 0);
   4346                         String clientId = rr.getWorkSourceClientId();
   4347                         if (!mClientWakelockTracker.isClientActive(clientId)
   4348                                 && (mActiveWakelockWorkSource != null)) {
   4349                             mActiveWakelockWorkSource.remove(rr.mWorkSource);
   4350                             if (mActiveWakelockWorkSource.size() == 0) {
   4351                                 mActiveWakelockWorkSource = null;
   4352                             }
   4353                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
   4354                         }
   4355 
   4356                         if (mWakeLockCount > 1) {
   4357                             mWakeLockCount--;
   4358                         } else {
   4359                             mWakeLockCount = 0;
   4360                             mWakeLock.release();
   4361                         }
   4362                     }
   4363                     break;
   4364                 case FOR_ACK_WAKELOCK:
   4365                     //We do not decrement the ACK wakelock
   4366                     break;
   4367                 case INVALID_WAKELOCK:
   4368                     break;
   4369                 default:
   4370                     Rlog.w(RILJ_LOG_TAG, "Decrementing Invalid Wakelock type " + rr.mWakeLockType);
   4371             }
   4372             rr.mWakeLockType = INVALID_WAKELOCK;
   4373         }
   4374     }
   4375 
   4376     private boolean clearWakeLock(int wakeLockType) {
   4377         if (wakeLockType == FOR_WAKELOCK) {
   4378             synchronized (mWakeLock) {
   4379                 if (mWakeLockCount == 0 && !mWakeLock.isHeld()) return false;
   4380                 Rlog.d(RILJ_LOG_TAG, "NOTE: mWakeLockCount is " + mWakeLockCount
   4381                         + "at time of clearing");
   4382                 mWakeLockCount = 0;
   4383                 mWakeLock.release();
   4384                 mClientWakelockTracker.stopTrackingAll();
   4385                 mActiveWakelockWorkSource = null;
   4386                 return true;
   4387             }
   4388         } else {
   4389             synchronized (mAckWakeLock) {
   4390                 if (!mAckWakeLock.isHeld()) return false;
   4391                 mAckWakeLock.release();
   4392                 return true;
   4393             }
   4394         }
   4395     }
   4396 
   4397     /**
   4398      * Release each request in mRequestList then clear the list
   4399      * @param error is the RIL_Errno sent back
   4400      * @param loggable true means to print all requests in mRequestList
   4401      */
   4402     private void clearRequestList(int error, boolean loggable) {
   4403         RILRequest rr;
   4404         synchronized (mRequestList) {
   4405             int count = mRequestList.size();
   4406             if (RILJ_LOGD && loggable) {
   4407                 Rlog.d(RILJ_LOG_TAG, "clearRequestList " + " mWakeLockCount="
   4408                         + mWakeLockCount + " mRequestList=" + count);
   4409             }
   4410 
   4411             for (int i = 0; i < count; i++) {
   4412                 rr = mRequestList.valueAt(i);
   4413                 if (RILJ_LOGD && loggable) {
   4414                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
   4415                             + requestToString(rr.mRequest));
   4416                 }
   4417                 rr.onError(error, null);
   4418                 decrementWakeLock(rr);
   4419                 rr.release();
   4420             }
   4421             mRequestList.clear();
   4422         }
   4423     }
   4424 
   4425     private RILRequest findAndRemoveRequestFromList(int serial) {
   4426         RILRequest rr = null;
   4427         synchronized (mRequestList) {
   4428             rr = mRequestList.get(serial);
   4429             if (rr != null) {
   4430                 mRequestList.remove(serial);
   4431             }
   4432         }
   4433 
   4434         return rr;
   4435     }
   4436 
   4437     private void addToRilHistogram(RILRequest rr) {
   4438         long endTime = SystemClock.elapsedRealtime();
   4439         int totalTime = (int) (endTime - rr.mStartTimeMs);
   4440 
   4441         synchronized (mRilTimeHistograms) {
   4442             TelephonyHistogram entry = mRilTimeHistograms.get(rr.mRequest);
   4443             if (entry == null) {
   4444                 // We would have total #RIL_HISTOGRAM_BUCKET_COUNT range buckets for RIL commands
   4445                 entry = new TelephonyHistogram(TelephonyHistogram.TELEPHONY_CATEGORY_RIL,
   4446                         rr.mRequest, RIL_HISTOGRAM_BUCKET_COUNT);
   4447                 mRilTimeHistograms.put(rr.mRequest, entry);
   4448             }
   4449             entry.addTimeTaken(totalTime);
   4450         }
   4451     }
   4452 
   4453     RadioCapability makeStaticRadioCapability() {
   4454         // default to UNKNOWN so we fail fast.
   4455         int raf = RadioAccessFamily.RAF_UNKNOWN;
   4456 
   4457         String rafString = mContext.getResources().getString(
   4458                 com.android.internal.R.string.config_radio_access_family);
   4459         if (!TextUtils.isEmpty(rafString)) {
   4460             raf = RadioAccessFamily.rafTypeFromString(rafString);
   4461         }
   4462         RadioCapability rc = new RadioCapability(mPhoneId.intValue(), 0, 0, raf,
   4463                 "", RadioCapability.RC_STATUS_SUCCESS);
   4464         if (RILJ_LOGD) riljLog("Faking RIL_REQUEST_GET_RADIO_CAPABILITY response using " + raf);
   4465         return rc;
   4466     }
   4467 
   4468     static String retToString(int req, Object ret) {
   4469         if (ret == null) return "";
   4470         switch (req) {
   4471             // Don't log these return values, for privacy's sake.
   4472             case RIL_REQUEST_GET_IMSI:
   4473             case RIL_REQUEST_GET_IMEI:
   4474             case RIL_REQUEST_GET_IMEISV:
   4475             case RIL_REQUEST_SIM_OPEN_CHANNEL:
   4476             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
   4477 
   4478                 if (!RILJ_LOGV) {
   4479                     // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
   4480                     return "";
   4481                 }
   4482         }
   4483 
   4484         StringBuilder sb;
   4485         String s;
   4486         int length;
   4487         if (ret instanceof int[]) {
   4488             int[] intArray = (int[]) ret;
   4489             length = intArray.length;
   4490             sb = new StringBuilder("{");
   4491             if (length > 0) {
   4492                 int i = 0;
   4493                 sb.append(intArray[i++]);
   4494                 while (i < length) {
   4495                     sb.append(", ").append(intArray[i++]);
   4496                 }
   4497             }
   4498             sb.append("}");
   4499             s = sb.toString();
   4500         } else if (ret instanceof String[]) {
   4501             String[] strings = (String[]) ret;
   4502             length = strings.length;
   4503             sb = new StringBuilder("{");
   4504             if (length > 0) {
   4505                 int i = 0;
   4506                 sb.append(strings[i++]);
   4507                 while (i < length) {
   4508                     sb.append(", ").append(strings[i++]);
   4509                 }
   4510             }
   4511             sb.append("}");
   4512             s = sb.toString();
   4513         } else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
   4514             ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
   4515             sb = new StringBuilder("{");
   4516             for (DriverCall dc : calls) {
   4517                 sb.append("[").append(dc).append("] ");
   4518             }
   4519             sb.append("}");
   4520             s = sb.toString();
   4521         } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
   4522             ArrayList<NeighboringCellInfo> cells = (ArrayList<NeighboringCellInfo>) ret;
   4523             sb = new StringBuilder("{");
   4524             for (NeighboringCellInfo cell : cells) {
   4525                 sb.append("[").append(cell).append("] ");
   4526             }
   4527             sb.append("}");
   4528             s = sb.toString();
   4529         } else if (req == RIL_REQUEST_QUERY_CALL_FORWARD_STATUS) {
   4530             CallForwardInfo[] cinfo = (CallForwardInfo[]) ret;
   4531             length = cinfo.length;
   4532             sb = new StringBuilder("{");
   4533             for (int i = 0; i < length; i++) {
   4534                 sb.append("[").append(cinfo[i]).append("] ");
   4535             }
   4536             sb.append("}");
   4537             s = sb.toString();
   4538         } else if (req == RIL_REQUEST_GET_HARDWARE_CONFIG) {
   4539             ArrayList<HardwareConfig> hwcfgs = (ArrayList<HardwareConfig>) ret;
   4540             sb = new StringBuilder(" ");
   4541             for (HardwareConfig hwcfg : hwcfgs) {
   4542                 sb.append("[").append(hwcfg).append("] ");
   4543             }
   4544             s = sb.toString();
   4545         } else {
   4546             s = ret.toString();
   4547         }
   4548         return s;
   4549     }
   4550 
   4551     void writeMetricsNewSms(int tech, int format) {
   4552         mMetrics.writeRilNewSms(mPhoneId, tech, format);
   4553     }
   4554 
   4555     void writeMetricsCallRing(char[] response) {
   4556         mMetrics.writeRilCallRing(mPhoneId, response);
   4557     }
   4558 
   4559     void writeMetricsSrvcc(int state) {
   4560         mMetrics.writeRilSrvcc(mPhoneId, state);
   4561     }
   4562 
   4563     void writeMetricsModemRestartEvent(String reason) {
   4564         mMetrics.writeModemRestartEvent(mPhoneId, reason);
   4565     }
   4566 
   4567     /**
   4568      * Notify all registrants that the ril has connected or disconnected.
   4569      *
   4570      * @param rilVer is the version of the ril or -1 if disconnected.
   4571      */
   4572     void notifyRegistrantsRilConnectionChanged(int rilVer) {
   4573         mRilVersion = rilVer;
   4574         if (mRilConnectedRegistrants != null) {
   4575             mRilConnectedRegistrants.notifyRegistrants(
   4576                     new AsyncResult(null, new Integer(rilVer), null));
   4577         }
   4578     }
   4579 
   4580     void
   4581     notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
   4582         int response = RIL_UNSOL_CDMA_INFO_REC;
   4583         if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
   4584             if (mDisplayInfoRegistrants != null) {
   4585                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4586                 mDisplayInfoRegistrants.notifyRegistrants(
   4587                         new AsyncResult(null, infoRec.record, null));
   4588             }
   4589         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
   4590             if (mSignalInfoRegistrants != null) {
   4591                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4592                 mSignalInfoRegistrants.notifyRegistrants(
   4593                         new AsyncResult(null, infoRec.record, null));
   4594             }
   4595         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
   4596             if (mNumberInfoRegistrants != null) {
   4597                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4598                 mNumberInfoRegistrants.notifyRegistrants(
   4599                         new AsyncResult(null, infoRec.record, null));
   4600             }
   4601         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
   4602             if (mRedirNumInfoRegistrants != null) {
   4603                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4604                 mRedirNumInfoRegistrants.notifyRegistrants(
   4605                         new AsyncResult(null, infoRec.record, null));
   4606             }
   4607         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
   4608             if (mLineControlInfoRegistrants != null) {
   4609                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4610                 mLineControlInfoRegistrants.notifyRegistrants(
   4611                         new AsyncResult(null, infoRec.record, null));
   4612             }
   4613         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
   4614             if (mT53ClirInfoRegistrants != null) {
   4615                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
   4616                 mT53ClirInfoRegistrants.notifyRegistrants(
   4617                         new AsyncResult(null, infoRec.record, null));
   4618             }
   4619         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
   4620             if (mT53AudCntrlInfoRegistrants != null) {
   4621                 if (RILJ_LOGD) {
   4622                     unsljLogRet(response, infoRec.record);
   4623                 }
   4624                 mT53AudCntrlInfoRegistrants.notifyRegistrants(
   4625                         new AsyncResult(null, infoRec.record, null));
   4626             }
   4627         }
   4628     }
   4629 
   4630     static String requestToString(int request) {
   4631         switch(request) {
   4632             case RIL_REQUEST_GET_SIM_STATUS:
   4633                 return "GET_SIM_STATUS";
   4634             case RIL_REQUEST_ENTER_SIM_PIN:
   4635                 return "ENTER_SIM_PIN";
   4636             case RIL_REQUEST_ENTER_SIM_PUK:
   4637                 return "ENTER_SIM_PUK";
   4638             case RIL_REQUEST_ENTER_SIM_PIN2:
   4639                 return "ENTER_SIM_PIN2";
   4640             case RIL_REQUEST_ENTER_SIM_PUK2:
   4641                 return "ENTER_SIM_PUK2";
   4642             case RIL_REQUEST_CHANGE_SIM_PIN:
   4643                 return "CHANGE_SIM_PIN";
   4644             case RIL_REQUEST_CHANGE_SIM_PIN2:
   4645                 return "CHANGE_SIM_PIN2";
   4646             case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
   4647                 return "ENTER_NETWORK_DEPERSONALIZATION";
   4648             case RIL_REQUEST_GET_CURRENT_CALLS:
   4649                 return "GET_CURRENT_CALLS";
   4650             case RIL_REQUEST_DIAL:
   4651                 return "DIAL";
   4652             case RIL_REQUEST_GET_IMSI:
   4653                 return "GET_IMSI";
   4654             case RIL_REQUEST_HANGUP:
   4655                 return "HANGUP";
   4656             case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
   4657                 return "HANGUP_WAITING_OR_BACKGROUND";
   4658             case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
   4659                 return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
   4660             case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
   4661                 return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
   4662             case RIL_REQUEST_CONFERENCE:
   4663                 return "CONFERENCE";
   4664             case RIL_REQUEST_UDUB:
   4665                 return "UDUB";
   4666             case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
   4667                 return "LAST_CALL_FAIL_CAUSE";
   4668             case RIL_REQUEST_SIGNAL_STRENGTH:
   4669                 return "SIGNAL_STRENGTH";
   4670             case RIL_REQUEST_VOICE_REGISTRATION_STATE:
   4671                 return "VOICE_REGISTRATION_STATE";
   4672             case RIL_REQUEST_DATA_REGISTRATION_STATE:
   4673                 return "DATA_REGISTRATION_STATE";
   4674             case RIL_REQUEST_OPERATOR:
   4675                 return "OPERATOR";
   4676             case RIL_REQUEST_RADIO_POWER:
   4677                 return "RADIO_POWER";
   4678             case RIL_REQUEST_DTMF:
   4679                 return "DTMF";
   4680             case RIL_REQUEST_SEND_SMS:
   4681                 return "SEND_SMS";
   4682             case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
   4683                 return "SEND_SMS_EXPECT_MORE";
   4684             case RIL_REQUEST_SETUP_DATA_CALL:
   4685                 return "SETUP_DATA_CALL";
   4686             case RIL_REQUEST_SIM_IO:
   4687                 return "SIM_IO";
   4688             case RIL_REQUEST_SEND_USSD:
   4689                 return "SEND_USSD";
   4690             case RIL_REQUEST_CANCEL_USSD:
   4691                 return "CANCEL_USSD";
   4692             case RIL_REQUEST_GET_CLIR:
   4693                 return "GET_CLIR";
   4694             case RIL_REQUEST_SET_CLIR:
   4695                 return "SET_CLIR";
   4696             case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
   4697                 return "QUERY_CALL_FORWARD_STATUS";
   4698             case RIL_REQUEST_SET_CALL_FORWARD:
   4699                 return "SET_CALL_FORWARD";
   4700             case RIL_REQUEST_QUERY_CALL_WAITING:
   4701                 return "QUERY_CALL_WAITING";
   4702             case RIL_REQUEST_SET_CALL_WAITING:
   4703                 return "SET_CALL_WAITING";
   4704             case RIL_REQUEST_SMS_ACKNOWLEDGE:
   4705                 return "SMS_ACKNOWLEDGE";
   4706             case RIL_REQUEST_GET_IMEI:
   4707                 return "GET_IMEI";
   4708             case RIL_REQUEST_GET_IMEISV:
   4709                 return "GET_IMEISV";
   4710             case RIL_REQUEST_ANSWER:
   4711                 return "ANSWER";
   4712             case RIL_REQUEST_DEACTIVATE_DATA_CALL:
   4713                 return "DEACTIVATE_DATA_CALL";
   4714             case RIL_REQUEST_QUERY_FACILITY_LOCK:
   4715                 return "QUERY_FACILITY_LOCK";
   4716             case RIL_REQUEST_SET_FACILITY_LOCK:
   4717                 return "SET_FACILITY_LOCK";
   4718             case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
   4719                 return "CHANGE_BARRING_PASSWORD";
   4720             case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
   4721                 return "QUERY_NETWORK_SELECTION_MODE";
   4722             case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
   4723                 return "SET_NETWORK_SELECTION_AUTOMATIC";
   4724             case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
   4725                 return "SET_NETWORK_SELECTION_MANUAL";
   4726             case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS :
   4727                 return "QUERY_AVAILABLE_NETWORKS ";
   4728             case RIL_REQUEST_DTMF_START:
   4729                 return "DTMF_START";
   4730             case RIL_REQUEST_DTMF_STOP:
   4731                 return "DTMF_STOP";
   4732             case RIL_REQUEST_BASEBAND_VERSION:
   4733                 return "BASEBAND_VERSION";
   4734             case RIL_REQUEST_SEPARATE_CONNECTION:
   4735                 return "SEPARATE_CONNECTION";
   4736             case RIL_REQUEST_SET_MUTE:
   4737                 return "SET_MUTE";
   4738             case RIL_REQUEST_GET_MUTE:
   4739                 return "GET_MUTE";
   4740             case RIL_REQUEST_QUERY_CLIP:
   4741                 return "QUERY_CLIP";
   4742             case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
   4743                 return "LAST_DATA_CALL_FAIL_CAUSE";
   4744             case RIL_REQUEST_DATA_CALL_LIST:
   4745                 return "DATA_CALL_LIST";
   4746             case RIL_REQUEST_RESET_RADIO:
   4747                 return "RESET_RADIO";
   4748             case RIL_REQUEST_OEM_HOOK_RAW:
   4749                 return "OEM_HOOK_RAW";
   4750             case RIL_REQUEST_OEM_HOOK_STRINGS:
   4751                 return "OEM_HOOK_STRINGS";
   4752             case RIL_REQUEST_SCREEN_STATE:
   4753                 return "SCREEN_STATE";
   4754             case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
   4755                 return "SET_SUPP_SVC_NOTIFICATION";
   4756             case RIL_REQUEST_WRITE_SMS_TO_SIM:
   4757                 return "WRITE_SMS_TO_SIM";
   4758             case RIL_REQUEST_DELETE_SMS_ON_SIM:
   4759                 return "DELETE_SMS_ON_SIM";
   4760             case RIL_REQUEST_SET_BAND_MODE:
   4761                 return "SET_BAND_MODE";
   4762             case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
   4763                 return "QUERY_AVAILABLE_BAND_MODE";
   4764             case RIL_REQUEST_STK_GET_PROFILE:
   4765                 return "REQUEST_STK_GET_PROFILE";
   4766             case RIL_REQUEST_STK_SET_PROFILE:
   4767                 return "REQUEST_STK_SET_PROFILE";
   4768             case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
   4769                 return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
   4770             case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
   4771                 return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
   4772             case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
   4773                 return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
   4774             case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
   4775             case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
   4776                 return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
   4777             case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
   4778                 return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
   4779             case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
   4780                 return "REQUEST_GET_NEIGHBORING_CELL_IDS";
   4781             case RIL_REQUEST_SET_LOCATION_UPDATES:
   4782                 return "REQUEST_SET_LOCATION_UPDATES";
   4783             case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
   4784                 return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
   4785             case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
   4786                 return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
   4787             case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
   4788                 return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
   4789             case RIL_REQUEST_SET_TTY_MODE:
   4790                 return "RIL_REQUEST_SET_TTY_MODE";
   4791             case RIL_REQUEST_QUERY_TTY_MODE:
   4792                 return "RIL_REQUEST_QUERY_TTY_MODE";
   4793             case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
   4794                 return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
   4795             case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
   4796                 return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
   4797             case RIL_REQUEST_CDMA_FLASH:
   4798                 return "RIL_REQUEST_CDMA_FLASH";
   4799             case RIL_REQUEST_CDMA_BURST_DTMF:
   4800                 return "RIL_REQUEST_CDMA_BURST_DTMF";
   4801             case RIL_REQUEST_CDMA_SEND_SMS:
   4802                 return "RIL_REQUEST_CDMA_SEND_SMS";
   4803             case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
   4804                 return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
   4805             case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG:
   4806                 return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
   4807             case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG:
   4808                 return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
   4809             case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:
   4810                 return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
   4811             case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:
   4812                 return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
   4813             case RIL_REQUEST_GSM_BROADCAST_ACTIVATION:
   4814                 return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
   4815             case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
   4816                 return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
   4817             case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION:
   4818                 return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
   4819             case RIL_REQUEST_CDMA_SUBSCRIPTION:
   4820                 return "RIL_REQUEST_CDMA_SUBSCRIPTION";
   4821             case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
   4822                 return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
   4823             case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
   4824                 return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
   4825             case RIL_REQUEST_DEVICE_IDENTITY:
   4826                 return "RIL_REQUEST_DEVICE_IDENTITY";
   4827             case RIL_REQUEST_GET_SMSC_ADDRESS:
   4828                 return "RIL_REQUEST_GET_SMSC_ADDRESS";
   4829             case RIL_REQUEST_SET_SMSC_ADDRESS:
   4830                 return "RIL_REQUEST_SET_SMSC_ADDRESS";
   4831             case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
   4832                 return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
   4833             case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
   4834                 return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
   4835             case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
   4836                 return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
   4837             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
   4838                 return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
   4839             case RIL_REQUEST_ISIM_AUTHENTICATION:
   4840                 return "RIL_REQUEST_ISIM_AUTHENTICATION";
   4841             case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
   4842                 return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
   4843             case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
   4844                 return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
   4845             case RIL_REQUEST_VOICE_RADIO_TECH:
   4846                 return "RIL_REQUEST_VOICE_RADIO_TECH";
   4847             case RIL_REQUEST_GET_CELL_INFO_LIST:
   4848                 return "RIL_REQUEST_GET_CELL_INFO_LIST";
   4849             case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
   4850                 return "RIL_REQUEST_SET_CELL_INFO_LIST_RATE";
   4851             case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
   4852                 return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
   4853             case RIL_REQUEST_SET_DATA_PROFILE:
   4854                 return "RIL_REQUEST_SET_DATA_PROFILE";
   4855             case RIL_REQUEST_IMS_REGISTRATION_STATE:
   4856                 return "RIL_REQUEST_IMS_REGISTRATION_STATE";
   4857             case RIL_REQUEST_IMS_SEND_SMS:
   4858                 return "RIL_REQUEST_IMS_SEND_SMS";
   4859             case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
   4860                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC";
   4861             case RIL_REQUEST_SIM_OPEN_CHANNEL:
   4862                 return "RIL_REQUEST_SIM_OPEN_CHANNEL";
   4863             case RIL_REQUEST_SIM_CLOSE_CHANNEL:
   4864                 return "RIL_REQUEST_SIM_CLOSE_CHANNEL";
   4865             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
   4866                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL";
   4867             case RIL_REQUEST_NV_READ_ITEM:
   4868                 return "RIL_REQUEST_NV_READ_ITEM";
   4869             case RIL_REQUEST_NV_WRITE_ITEM:
   4870                 return "RIL_REQUEST_NV_WRITE_ITEM";
   4871             case RIL_REQUEST_NV_WRITE_CDMA_PRL:
   4872                 return "RIL_REQUEST_NV_WRITE_CDMA_PRL";
   4873             case RIL_REQUEST_NV_RESET_CONFIG:
   4874                 return "RIL_REQUEST_NV_RESET_CONFIG";
   4875             case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
   4876                 return "RIL_REQUEST_SET_UICC_SUBSCRIPTION";
   4877             case RIL_REQUEST_ALLOW_DATA:
   4878                 return "RIL_REQUEST_ALLOW_DATA";
   4879             case RIL_REQUEST_GET_HARDWARE_CONFIG:
   4880                 return "GET_HARDWARE_CONFIG";
   4881             case RIL_REQUEST_SIM_AUTHENTICATION:
   4882                 return "RIL_REQUEST_SIM_AUTHENTICATION";
   4883             case RIL_REQUEST_SHUTDOWN:
   4884                 return "RIL_REQUEST_SHUTDOWN";
   4885             case RIL_REQUEST_SET_RADIO_CAPABILITY:
   4886                 return "RIL_REQUEST_SET_RADIO_CAPABILITY";
   4887             case RIL_REQUEST_GET_RADIO_CAPABILITY:
   4888                 return "RIL_REQUEST_GET_RADIO_CAPABILITY";
   4889             case RIL_REQUEST_START_LCE:
   4890                 return "RIL_REQUEST_START_LCE";
   4891             case RIL_REQUEST_STOP_LCE:
   4892                 return "RIL_REQUEST_STOP_LCE";
   4893             case RIL_REQUEST_PULL_LCEDATA:
   4894                 return "RIL_REQUEST_PULL_LCEDATA";
   4895             case RIL_REQUEST_GET_ACTIVITY_INFO:
   4896                 return "RIL_REQUEST_GET_ACTIVITY_INFO";
   4897             case RIL_REQUEST_SET_ALLOWED_CARRIERS:
   4898                 return "RIL_REQUEST_SET_ALLOWED_CARRIERS";
   4899             case RIL_REQUEST_GET_ALLOWED_CARRIERS:
   4900                 return "RIL_REQUEST_GET_ALLOWED_CARRIERS";
   4901             case RIL_REQUEST_SET_SIM_CARD_POWER:
   4902                 return "RIL_REQUEST_SET_SIM_CARD_POWER";
   4903             case RIL_REQUEST_SEND_DEVICE_STATE:
   4904                 return "RIL_REQUEST_SEND_DEVICE_STATE";
   4905             case RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER:
   4906                 return "RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER";
   4907             case RIL_RESPONSE_ACKNOWLEDGEMENT:
   4908                 return "RIL_RESPONSE_ACKNOWLEDGEMENT";
   4909             case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION:
   4910                 return "RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION";
   4911             case RIL_REQUEST_START_NETWORK_SCAN:
   4912                 return "RIL_REQUEST_START_NETWORK_SCAN";
   4913             case RIL_REQUEST_STOP_NETWORK_SCAN:
   4914                 return "RIL_REQUEST_STOP_NETWORK_SCAN";
   4915             case RIL_REQUEST_GET_SLOT_STATUS:
   4916                 return "RIL_REQUEST_GET_SLOT_STATUS";
   4917             case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
   4918                 return "RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
   4919             case RIL_REQUEST_START_KEEPALIVE:
   4920                 return "RIL_REQUEST_START_KEEPALIVE";
   4921             case RIL_REQUEST_STOP_KEEPALIVE:
   4922                 return "RIL_REQUEST_STOP_KEEPALIVE";
   4923             case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
   4924                 return "RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
   4925             case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
   4926                 return "RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA";
   4927             default: return "<unknown request>";
   4928         }
   4929     }
   4930 
   4931     static String responseToString(int request) {
   4932         switch(request) {
   4933             case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
   4934                 return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
   4935             case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
   4936                 return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
   4937             case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
   4938                 return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
   4939             case RIL_UNSOL_RESPONSE_NEW_SMS:
   4940                 return "UNSOL_RESPONSE_NEW_SMS";
   4941             case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
   4942                 return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
   4943             case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
   4944                 return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
   4945             case RIL_UNSOL_ON_USSD:
   4946                 return "UNSOL_ON_USSD";
   4947             case RIL_UNSOL_ON_USSD_REQUEST:
   4948                 return "UNSOL_ON_USSD_REQUEST";
   4949             case RIL_UNSOL_NITZ_TIME_RECEIVED:
   4950                 return "UNSOL_NITZ_TIME_RECEIVED";
   4951             case RIL_UNSOL_SIGNAL_STRENGTH:
   4952                 return "UNSOL_SIGNAL_STRENGTH";
   4953             case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
   4954                 return "UNSOL_DATA_CALL_LIST_CHANGED";
   4955             case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
   4956                 return "UNSOL_SUPP_SVC_NOTIFICATION";
   4957             case RIL_UNSOL_STK_SESSION_END:
   4958                 return "UNSOL_STK_SESSION_END";
   4959             case RIL_UNSOL_STK_PROACTIVE_COMMAND:
   4960                 return "UNSOL_STK_PROACTIVE_COMMAND";
   4961             case RIL_UNSOL_STK_EVENT_NOTIFY:
   4962                 return "UNSOL_STK_EVENT_NOTIFY";
   4963             case RIL_UNSOL_STK_CALL_SETUP:
   4964                 return "UNSOL_STK_CALL_SETUP";
   4965             case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
   4966                 return "UNSOL_SIM_SMS_STORAGE_FULL";
   4967             case RIL_UNSOL_SIM_REFRESH:
   4968                 return "UNSOL_SIM_REFRESH";
   4969             case RIL_UNSOL_CALL_RING:
   4970                 return "UNSOL_CALL_RING";
   4971             case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
   4972                 return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
   4973             case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
   4974                 return "UNSOL_RESPONSE_CDMA_NEW_SMS";
   4975             case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
   4976                 return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
   4977             case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
   4978                 return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
   4979             case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
   4980                 return "UNSOL_RESTRICTED_STATE_CHANGED";
   4981             case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
   4982                 return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
   4983             case RIL_UNSOL_CDMA_CALL_WAITING:
   4984                 return "UNSOL_CDMA_CALL_WAITING";
   4985             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
   4986                 return "UNSOL_CDMA_OTA_PROVISION_STATUS";
   4987             case RIL_UNSOL_CDMA_INFO_REC:
   4988                 return "UNSOL_CDMA_INFO_REC";
   4989             case RIL_UNSOL_OEM_HOOK_RAW:
   4990                 return "UNSOL_OEM_HOOK_RAW";
   4991             case RIL_UNSOL_RINGBACK_TONE:
   4992                 return "UNSOL_RINGBACK_TONE";
   4993             case RIL_UNSOL_RESEND_INCALL_MUTE:
   4994                 return "UNSOL_RESEND_INCALL_MUTE";
   4995             case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
   4996                 return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
   4997             case RIL_UNSOl_CDMA_PRL_CHANGED:
   4998                 return "UNSOL_CDMA_PRL_CHANGED";
   4999             case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
   5000                 return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
   5001             case RIL_UNSOL_RIL_CONNECTED:
   5002                 return "UNSOL_RIL_CONNECTED";
   5003             case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
   5004                 return "UNSOL_VOICE_RADIO_TECH_CHANGED";
   5005             case RIL_UNSOL_CELL_INFO_LIST:
   5006                 return "UNSOL_CELL_INFO_LIST";
   5007             case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
   5008                 return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
   5009             case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
   5010                 return "RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
   5011             case RIL_UNSOL_SRVCC_STATE_NOTIFY:
   5012                 return "UNSOL_SRVCC_STATE_NOTIFY";
   5013             case RIL_UNSOL_HARDWARE_CONFIG_CHANGED:
   5014                 return "RIL_UNSOL_HARDWARE_CONFIG_CHANGED";
   5015             case RIL_UNSOL_RADIO_CAPABILITY:
   5016                 return "RIL_UNSOL_RADIO_CAPABILITY";
   5017             case RIL_UNSOL_ON_SS:
   5018                 return "UNSOL_ON_SS";
   5019             case RIL_UNSOL_STK_CC_ALPHA_NOTIFY:
   5020                 return "UNSOL_STK_CC_ALPHA_NOTIFY";
   5021             case RIL_UNSOL_LCEDATA_RECV:
   5022                 return "UNSOL_LCE_INFO_RECV";
   5023             case RIL_UNSOL_PCO_DATA:
   5024                 return "UNSOL_PCO_DATA";
   5025             case RIL_UNSOL_MODEM_RESTART:
   5026                 return "UNSOL_MODEM_RESTART";
   5027             case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION:
   5028                 return "RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
   5029             case RIL_UNSOL_NETWORK_SCAN_RESULT:
   5030                 return "RIL_UNSOL_NETWORK_SCAN_RESULT";
   5031             case RIL_UNSOL_ICC_SLOT_STATUS:
   5032                 return "RIL_UNSOL_ICC_SLOT_STATUS";
   5033             case RIL_UNSOL_KEEPALIVE_STATUS:
   5034                 return "RIL_UNSOL_KEEPALIVE_STATUS";
   5035             case RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG:
   5036                 return "RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG";
   5037             default:
   5038                 return "<unknown response>";
   5039         }
   5040     }
   5041 
   5042     void riljLog(String msg) {
   5043         Rlog.d(RILJ_LOG_TAG, msg
   5044                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
   5045     }
   5046 
   5047     void riljLoge(String msg) {
   5048         Rlog.e(RILJ_LOG_TAG, msg
   5049                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
   5050     }
   5051 
   5052     void riljLoge(String msg, Exception e) {
   5053         Rlog.e(RILJ_LOG_TAG, msg
   5054                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""), e);
   5055     }
   5056 
   5057     void riljLogv(String msg) {
   5058         Rlog.v(RILJ_LOG_TAG, msg
   5059                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
   5060     }
   5061 
   5062     void unsljLog(int response) {
   5063         riljLog("[UNSL]< " + responseToString(response));
   5064     }
   5065 
   5066     void unsljLogMore(int response, String more) {
   5067         riljLog("[UNSL]< " + responseToString(response) + " " + more);
   5068     }
   5069 
   5070     void unsljLogRet(int response, Object ret) {
   5071         riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
   5072     }
   5073 
   5074     void unsljLogvRet(int response, Object ret) {
   5075         riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
   5076     }
   5077 
   5078     @Override
   5079     public void setPhoneType(int phoneType) { // Called by GsmCdmaPhone
   5080         if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
   5081         mPhoneType = phoneType;
   5082     }
   5083 
   5084     /* (non-Javadoc)
   5085      * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
   5086      */
   5087     @Override
   5088     public void testingEmergencyCall() {
   5089         if (RILJ_LOGD) riljLog("testingEmergencyCall");
   5090         mTestingEmergencyCall.set(true);
   5091     }
   5092 
   5093     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   5094         pw.println("RIL: " + this);
   5095         pw.println(" mWakeLock=" + mWakeLock);
   5096         pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
   5097         synchronized (mRequestList) {
   5098             synchronized (mWakeLock) {
   5099                 pw.println(" mWakeLockCount=" + mWakeLockCount);
   5100             }
   5101             int count = mRequestList.size();
   5102             pw.println(" mRequestList count=" + count);
   5103             for (int i = 0; i < count; i++) {
   5104                 RILRequest rr = mRequestList.valueAt(i);
   5105                 pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
   5106             }
   5107         }
   5108         pw.println(" mLastNITZTimeInfo=" + Arrays.toString(mLastNITZTimeInfo));
   5109         pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
   5110         mClientWakelockTracker.dumpClientRequestTracker(pw);
   5111     }
   5112 
   5113     public List<ClientRequestStats> getClientRequestStats() {
   5114         return mClientWakelockTracker.getClientRequestStats();
   5115     }
   5116 
   5117     /** Append the data to the end of an ArrayList */
   5118     public static void appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst) {
   5119         for (byte b : src) {
   5120             dst.add(b);
   5121         }
   5122     }
   5123 
   5124     public static ArrayList<Byte> primitiveArrayToArrayList(byte[] arr) {
   5125         ArrayList<Byte> arrayList = new ArrayList<>(arr.length);
   5126         for (byte b : arr) {
   5127             arrayList.add(b);
   5128         }
   5129         return arrayList;
   5130     }
   5131 
   5132     /** Convert a primitive int array to an ArrayList<Integer>. */
   5133     public static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
   5134         ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
   5135         for (int i : arr) {
   5136             arrayList.add(i);
   5137         }
   5138         return arrayList;
   5139     }
   5140 
   5141     /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
   5142     public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
   5143         byte[] ret = new byte[bytes.size()];
   5144         for (int i = 0; i < ret.length; i++) {
   5145             ret[i] = bytes.get(i);
   5146         }
   5147         return ret;
   5148     }
   5149 
   5150     static ArrayList<HardwareConfig> convertHalHwConfigList(
   5151             ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil,
   5152             RIL ril) {
   5153         int num;
   5154         ArrayList<HardwareConfig> response;
   5155         HardwareConfig hw;
   5156 
   5157         num = hwListRil.size();
   5158         response = new ArrayList<HardwareConfig>(num);
   5159 
   5160         if (RILJ_LOGV) {
   5161             ril.riljLog("convertHalHwConfigList: num=" + num);
   5162         }
   5163         for (android.hardware.radio.V1_0.HardwareConfig hwRil : hwListRil) {
   5164             int type = hwRil.type;
   5165             switch(type) {
   5166                 case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
   5167                     hw = new HardwareConfig(type);
   5168                     HardwareConfigModem hwModem = hwRil.modem.get(0);
   5169                     hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
   5170                             hwModem.maxVoice, hwModem.maxData, hwModem.maxStandby);
   5171                     break;
   5172                 }
   5173                 case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
   5174                     hw = new HardwareConfig(type);
   5175                     hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim.get(0).modemUuid);
   5176                     break;
   5177                 }
   5178                 default: {
   5179                     throw new RuntimeException(
   5180                             "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardward type:" + type);
   5181                 }
   5182             }
   5183 
   5184             response.add(hw);
   5185         }
   5186 
   5187         return response;
   5188     }
   5189 
   5190     static RadioCapability convertHalRadioCapability(
   5191             android.hardware.radio.V1_0.RadioCapability rcRil, RIL ril) {
   5192         int session = rcRil.session;
   5193         int phase = rcRil.phase;
   5194         int rat = rcRil.raf;
   5195         String logicModemUuid = rcRil.logicalModemUuid;
   5196         int status = rcRil.status;
   5197 
   5198         ril.riljLog("convertHalRadioCapability: session=" + session +
   5199                 ", phase=" + phase +
   5200                 ", rat=" + rat +
   5201                 ", logicModemUuid=" + logicModemUuid +
   5202                 ", status=" + status);
   5203         RadioCapability rc = new RadioCapability(
   5204                 ril.mPhoneId, session, phase, rat, logicModemUuid, status);
   5205         return rc;
   5206     }
   5207 
   5208     static LinkCapacityEstimate convertHalLceData(LceDataInfo halData, RIL ril) {
   5209         final LinkCapacityEstimate lce = new LinkCapacityEstimate(
   5210                 halData.lastHopCapacityKbps,
   5211                 Byte.toUnsignedInt(halData.confidenceLevel),
   5212                 halData.lceSuspended ? LinkCapacityEstimate.STATUS_SUSPENDED
   5213                         : LinkCapacityEstimate.STATUS_ACTIVE);
   5214 
   5215         ril.riljLog("LCE capacity information received:" + lce);
   5216         return lce;
   5217     }
   5218 
   5219     static LinkCapacityEstimate convertHalLceData(
   5220             android.hardware.radio.V1_2.LinkCapacityEstimate halData, RIL ril) {
   5221         final LinkCapacityEstimate lce = new LinkCapacityEstimate(
   5222                 halData.downlinkCapacityKbps,
   5223                 halData.uplinkCapacityKbps);
   5224         ril.riljLog("LCE capacity information received:" + lce);
   5225         return lce;
   5226     }
   5227 
   5228     private static void writeToParcelForGsm(
   5229             Parcel p, int lac, int cid, int arfcn, int bsic, String mcc, String mnc,
   5230             String al, String as, int ss, int ber, int ta) {
   5231         p.writeInt(CellIdentity.TYPE_GSM);
   5232         p.writeString(mcc);
   5233         p.writeString(mnc);
   5234         p.writeString(al);
   5235         p.writeString(as);
   5236         p.writeInt(lac);
   5237         p.writeInt(cid);
   5238         p.writeInt(arfcn);
   5239         p.writeInt(bsic);
   5240         p.writeInt(ss);
   5241         p.writeInt(ber);
   5242         p.writeInt(ta);
   5243     }
   5244 
   5245     private static void writeToParcelForCdma(
   5246             Parcel p, int ni, int si, int bsi, int lon, int lat, String al, String as,
   5247             int dbm, int ecio, int eDbm, int eEcio, int eSnr) {
   5248         new CellIdentityCdma(ni, si, bsi, lon, lat, al, as).writeToParcel(p, 0);
   5249         new CellSignalStrengthCdma(dbm, ecio, eDbm, eEcio, eSnr).writeToParcel(p, 0);
   5250     }
   5251 
   5252     private static void writeToParcelForLte(
   5253             Parcel p, int ci, int pci, int tac, int earfcn, int bandwidth, String mcc, String mnc,
   5254             String al, String as, int ss, int rsrp, int rsrq, int rssnr, int cqi, int ta) {
   5255         p.writeInt(CellIdentity.TYPE_LTE);
   5256         p.writeString(mcc);
   5257         p.writeString(mnc);
   5258         p.writeString(al);
   5259         p.writeString(as);
   5260         p.writeInt(ci);
   5261         p.writeInt(pci);
   5262         p.writeInt(tac);
   5263         p.writeInt(earfcn);
   5264         p.writeInt(bandwidth);
   5265         p.writeInt(ss);
   5266         p.writeInt(rsrp);
   5267         p.writeInt(rsrq);
   5268         p.writeInt(rssnr);
   5269         p.writeInt(cqi);
   5270         p.writeInt(ta);
   5271     }
   5272 
   5273     private static void writeToParcelForWcdma(
   5274             Parcel p, int lac, int cid, int psc, int uarfcn, String mcc, String mnc,
   5275             String al, String as, int ss, int ber) {
   5276         p.writeInt(CellIdentity.TYPE_WCDMA);
   5277         p.writeString(mcc);
   5278         p.writeString(mnc);
   5279         p.writeString(al);
   5280         p.writeString(as);
   5281         p.writeInt(lac);
   5282         p.writeInt(cid);
   5283         p.writeInt(psc);
   5284         p.writeInt(uarfcn);
   5285         p.writeInt(ss);
   5286         p.writeInt(ber);
   5287     }
   5288 
   5289     /**
   5290      * Convert CellInfo defined in 1.0/types.hal to CellInfo type.
   5291      * @param records List of CellInfo defined in 1.0/types.hal
   5292      * @return List of converted CellInfo object
   5293      */
   5294     @VisibleForTesting
   5295     public static ArrayList<CellInfo> convertHalCellInfoList(
   5296             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
   5297         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
   5298 
   5299         for (android.hardware.radio.V1_0.CellInfo record : records) {
   5300             // first convert RIL CellInfo to Parcel
   5301             Parcel p = Parcel.obtain();
   5302             p.writeInt(record.cellInfoType);
   5303             p.writeInt(record.registered ? 1 : 0);
   5304             p.writeInt(record.timeStampType);
   5305             p.writeLong(record.timeStamp);
   5306             p.writeInt(CellInfo.CONNECTION_UNKNOWN);
   5307             switch (record.cellInfoType) {
   5308                 case CellInfoType.GSM: {
   5309                     CellInfoGsm cellInfoGsm = record.gsm.get(0);
   5310                     writeToParcelForGsm(
   5311                             p,
   5312                             cellInfoGsm.cellIdentityGsm.lac,
   5313                             cellInfoGsm.cellIdentityGsm.cid,
   5314                             cellInfoGsm.cellIdentityGsm.arfcn,
   5315                             Byte.toUnsignedInt(cellInfoGsm.cellIdentityGsm.bsic),
   5316                             cellInfoGsm.cellIdentityGsm.mcc,
   5317                             cellInfoGsm.cellIdentityGsm.mnc,
   5318                             EMPTY_ALPHA_LONG,
   5319                             EMPTY_ALPHA_SHORT,
   5320                             cellInfoGsm.signalStrengthGsm.signalStrength,
   5321                             cellInfoGsm.signalStrengthGsm.bitErrorRate,
   5322                             cellInfoGsm.signalStrengthGsm.timingAdvance);
   5323                     break;
   5324                 }
   5325 
   5326                 case CellInfoType.CDMA: {
   5327                     CellInfoCdma cellInfoCdma = record.cdma.get(0);
   5328                     writeToParcelForCdma(
   5329                             p,
   5330                             cellInfoCdma.cellIdentityCdma.networkId,
   5331                             cellInfoCdma.cellIdentityCdma.systemId,
   5332                             cellInfoCdma.cellIdentityCdma.baseStationId,
   5333                             cellInfoCdma.cellIdentityCdma.longitude,
   5334                             cellInfoCdma.cellIdentityCdma.latitude,
   5335                             EMPTY_ALPHA_LONG,
   5336                             EMPTY_ALPHA_SHORT,
   5337                             cellInfoCdma.signalStrengthCdma.dbm,
   5338                             cellInfoCdma.signalStrengthCdma.ecio,
   5339                             cellInfoCdma.signalStrengthEvdo.dbm,
   5340                             cellInfoCdma.signalStrengthEvdo.ecio,
   5341                             cellInfoCdma.signalStrengthEvdo.signalNoiseRatio);
   5342                     break;
   5343                 }
   5344 
   5345                 case CellInfoType.LTE: {
   5346                     CellInfoLte cellInfoLte = record.lte.get(0);
   5347                     writeToParcelForLte(
   5348                             p,
   5349                             cellInfoLte.cellIdentityLte.ci,
   5350                             cellInfoLte.cellIdentityLte.pci,
   5351                             cellInfoLte.cellIdentityLte.tac,
   5352                             cellInfoLte.cellIdentityLte.earfcn,
   5353                             Integer.MAX_VALUE,
   5354                             cellInfoLte.cellIdentityLte.mcc,
   5355                             cellInfoLte.cellIdentityLte.mnc,
   5356                             EMPTY_ALPHA_LONG,
   5357                             EMPTY_ALPHA_SHORT,
   5358                             cellInfoLte.signalStrengthLte.signalStrength,
   5359                             cellInfoLte.signalStrengthLte.rsrp,
   5360                             cellInfoLte.signalStrengthLte.rsrq,
   5361                             cellInfoLte.signalStrengthLte.rssnr,
   5362                             cellInfoLte.signalStrengthLte.cqi,
   5363                             cellInfoLte.signalStrengthLte.timingAdvance);
   5364                     break;
   5365                 }
   5366 
   5367                 case CellInfoType.WCDMA: {
   5368                     CellInfoWcdma cellInfoWcdma = record.wcdma.get(0);
   5369                     writeToParcelForWcdma(
   5370                             p,
   5371                             cellInfoWcdma.cellIdentityWcdma.lac,
   5372                             cellInfoWcdma.cellIdentityWcdma.cid,
   5373                             cellInfoWcdma.cellIdentityWcdma.psc,
   5374                             cellInfoWcdma.cellIdentityWcdma.uarfcn,
   5375                             cellInfoWcdma.cellIdentityWcdma.mcc,
   5376                             cellInfoWcdma.cellIdentityWcdma.mnc,
   5377                             EMPTY_ALPHA_LONG,
   5378                             EMPTY_ALPHA_SHORT,
   5379                             cellInfoWcdma.signalStrengthWcdma.signalStrength,
   5380                             cellInfoWcdma.signalStrengthWcdma.bitErrorRate);
   5381                     break;
   5382                 }
   5383 
   5384                 default:
   5385                     throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
   5386             }
   5387 
   5388             p.setDataPosition(0);
   5389             CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p);
   5390             p.recycle();
   5391             response.add(InfoRec);
   5392         }
   5393 
   5394         return response;
   5395     }
   5396 
   5397     /**
   5398      * Convert CellInfo defined in 1.2/types.hal to CellInfo type.
   5399      * @param records List of CellInfo defined in 1.2/types.hal
   5400      * @return List of converted CellInfo object
   5401      */
   5402     @VisibleForTesting
   5403     public static ArrayList<CellInfo> convertHalCellInfoList_1_2(
   5404             ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
   5405         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
   5406 
   5407         for (android.hardware.radio.V1_2.CellInfo record : records) {
   5408             // first convert RIL CellInfo to Parcel
   5409             Parcel p = Parcel.obtain();
   5410             p.writeInt(record.cellInfoType);
   5411             p.writeInt(record.registered ? 1 : 0);
   5412             p.writeInt(record.timeStampType);
   5413             p.writeLong(record.timeStamp);
   5414             p.writeInt(record.connectionStatus);
   5415             switch (record.cellInfoType) {
   5416                 case CellInfoType.GSM: {
   5417                     android.hardware.radio.V1_2.CellInfoGsm cellInfoGsm = record.gsm.get(0);
   5418                     writeToParcelForGsm(
   5419                             p,
   5420                             cellInfoGsm.cellIdentityGsm.base.lac,
   5421                             cellInfoGsm.cellIdentityGsm.base.cid,
   5422                             cellInfoGsm.cellIdentityGsm.base.arfcn,
   5423                             Byte.toUnsignedInt(cellInfoGsm.cellIdentityGsm.base.bsic),
   5424                             cellInfoGsm.cellIdentityGsm.base.mcc,
   5425                             cellInfoGsm.cellIdentityGsm.base.mnc,
   5426                             cellInfoGsm.cellIdentityGsm.operatorNames.alphaLong,
   5427                             cellInfoGsm.cellIdentityGsm.operatorNames.alphaShort,
   5428                             cellInfoGsm.signalStrengthGsm.signalStrength,
   5429                             cellInfoGsm.signalStrengthGsm.bitErrorRate,
   5430                             cellInfoGsm.signalStrengthGsm.timingAdvance);
   5431                     break;
   5432                 }
   5433 
   5434                 case CellInfoType.CDMA: {
   5435                     android.hardware.radio.V1_2.CellInfoCdma cellInfoCdma = record.cdma.get(0);
   5436                     writeToParcelForCdma(
   5437                             p,
   5438                             cellInfoCdma.cellIdentityCdma.base.networkId,
   5439                             cellInfoCdma.cellIdentityCdma.base.systemId,
   5440                             cellInfoCdma.cellIdentityCdma.base.baseStationId,
   5441                             cellInfoCdma.cellIdentityCdma.base.longitude,
   5442                             cellInfoCdma.cellIdentityCdma.base.latitude,
   5443                             cellInfoCdma.cellIdentityCdma.operatorNames.alphaLong,
   5444                             cellInfoCdma.cellIdentityCdma.operatorNames.alphaShort,
   5445                             cellInfoCdma.signalStrengthCdma.dbm,
   5446                             cellInfoCdma.signalStrengthCdma.ecio,
   5447                             cellInfoCdma.signalStrengthEvdo.dbm,
   5448                             cellInfoCdma.signalStrengthEvdo.ecio,
   5449                             cellInfoCdma.signalStrengthEvdo.signalNoiseRatio);
   5450                     break;
   5451                 }
   5452 
   5453                 case CellInfoType.LTE: {
   5454                     android.hardware.radio.V1_2.CellInfoLte cellInfoLte = record.lte.get(0);
   5455                     writeToParcelForLte(
   5456                             p,
   5457                             cellInfoLte.cellIdentityLte.base.ci,
   5458                             cellInfoLte.cellIdentityLte.base.pci,
   5459                             cellInfoLte.cellIdentityLte.base.tac,
   5460                             cellInfoLte.cellIdentityLte.base.earfcn,
   5461                             cellInfoLte.cellIdentityLte.bandwidth,
   5462                             cellInfoLte.cellIdentityLte.base.mcc,
   5463                             cellInfoLte.cellIdentityLte.base.mnc,
   5464                             cellInfoLte.cellIdentityLte.operatorNames.alphaLong,
   5465                             cellInfoLte.cellIdentityLte.operatorNames.alphaShort,
   5466                             cellInfoLte.signalStrengthLte.signalStrength,
   5467                             cellInfoLte.signalStrengthLte.rsrp,
   5468                             cellInfoLte.signalStrengthLte.rsrq,
   5469                             cellInfoLte.signalStrengthLte.rssnr,
   5470                             cellInfoLte.signalStrengthLte.cqi,
   5471                             cellInfoLte.signalStrengthLte.timingAdvance);
   5472                     break;
   5473                 }
   5474 
   5475                 case CellInfoType.WCDMA: {
   5476                     android.hardware.radio.V1_2.CellInfoWcdma cellInfoWcdma = record.wcdma.get(0);
   5477                     writeToParcelForWcdma(
   5478                             p,
   5479                             cellInfoWcdma.cellIdentityWcdma.base.lac,
   5480                             cellInfoWcdma.cellIdentityWcdma.base.cid,
   5481                             cellInfoWcdma.cellIdentityWcdma.base.psc,
   5482                             cellInfoWcdma.cellIdentityWcdma.base.uarfcn,
   5483                             cellInfoWcdma.cellIdentityWcdma.base.mcc,
   5484                             cellInfoWcdma.cellIdentityWcdma.base.mnc,
   5485                             cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaLong,
   5486                             cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaShort,
   5487                             cellInfoWcdma.signalStrengthWcdma.base.signalStrength,
   5488                             cellInfoWcdma.signalStrengthWcdma.base.bitErrorRate);
   5489                     break;
   5490                 }
   5491 
   5492                 default:
   5493                     throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
   5494             }
   5495 
   5496             p.setDataPosition(0);
   5497             CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p);
   5498             p.recycle();
   5499             response.add(InfoRec);
   5500         }
   5501 
   5502         return response;
   5503     }
   5504 
   5505     /** Convert HAL 1.0 Signal Strength to android SignalStrength */
   5506     @VisibleForTesting
   5507     public static SignalStrength convertHalSignalStrength(
   5508             android.hardware.radio.V1_0.SignalStrength signalStrength) {
   5509         int tdscdmaRscp_1_2 = 255; // 255 is the value for unknown/unreported ASU.
   5510         // The HAL 1.0 range is 25..120; the ASU/ HAL 1.2 range is 0..96;
   5511         // yes, this means the range in 1.0 cannot express -24dBm = 96
   5512         if (signalStrength.tdScdma.rscp >= 25 && signalStrength.tdScdma.rscp <= 120) {
   5513             // First we flip the sign to convert from the HALs -rscp to the actual RSCP value.
   5514             int rscpDbm = -signalStrength.tdScdma.rscp;
   5515             // Then to convert from RSCP to ASU, we apply the offset which aligns 0 ASU to -120dBm.
   5516             tdscdmaRscp_1_2 = rscpDbm + 120;
   5517         }
   5518         return new SignalStrength(
   5519                 signalStrength.gw.signalStrength,
   5520                 signalStrength.gw.bitErrorRate,
   5521                 signalStrength.cdma.dbm,
   5522                 signalStrength.cdma.ecio,
   5523                 signalStrength.evdo.dbm,
   5524                 signalStrength.evdo.ecio,
   5525                 signalStrength.evdo.signalNoiseRatio,
   5526                 signalStrength.lte.signalStrength,
   5527                 signalStrength.lte.rsrp,
   5528                 signalStrength.lte.rsrq,
   5529                 signalStrength.lte.rssnr,
   5530                 signalStrength.lte.cqi,
   5531                 tdscdmaRscp_1_2);
   5532     }
   5533 
   5534     /** Convert HAL 1.2 Signal Strength to android SignalStrength */
   5535     @VisibleForTesting
   5536     public static SignalStrength convertHalSignalStrength_1_2(
   5537             android.hardware.radio.V1_2.SignalStrength signalStrength) {
   5538         return new SignalStrength(
   5539                 signalStrength.gsm.signalStrength,
   5540                 signalStrength.gsm.bitErrorRate,
   5541                 signalStrength.cdma.dbm,
   5542                 signalStrength.cdma.ecio,
   5543                 signalStrength.evdo.dbm,
   5544                 signalStrength.evdo.ecio,
   5545                 signalStrength.evdo.signalNoiseRatio,
   5546                 signalStrength.lte.signalStrength,
   5547                 signalStrength.lte.rsrp,
   5548                 signalStrength.lte.rsrq,
   5549                 signalStrength.lte.rssnr,
   5550                 signalStrength.lte.cqi,
   5551                 signalStrength.tdScdma.rscp,
   5552                 signalStrength.wcdma.base.signalStrength,
   5553                 signalStrength.wcdma.rscp);
   5554     }
   5555 }
   5556