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.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.content.Context;
26 import android.hardware.radio.V1_0.Carrier;
27 import android.hardware.radio.V1_0.CarrierRestrictions;
28 import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
29 import android.hardware.radio.V1_0.CdmaSmsAck;
30 import android.hardware.radio.V1_0.CdmaSmsMessage;
31 import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
32 import android.hardware.radio.V1_0.DataProfileId;
33 import android.hardware.radio.V1_0.Dial;
34 import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
35 import android.hardware.radio.V1_0.GsmSmsMessage;
36 import android.hardware.radio.V1_0.HardwareConfigModem;
37 import android.hardware.radio.V1_0.IRadio;
38 import android.hardware.radio.V1_0.IccIo;
39 import android.hardware.radio.V1_0.ImsSmsMessage;
40 import android.hardware.radio.V1_0.LceDataInfo;
41 import android.hardware.radio.V1_0.MvnoType;
42 import android.hardware.radio.V1_0.NvWriteItem;
43 import android.hardware.radio.V1_0.RadioError;
44 import android.hardware.radio.V1_0.RadioIndicationType;
45 import android.hardware.radio.V1_0.RadioResponseInfo;
46 import android.hardware.radio.V1_0.RadioResponseType;
47 import android.hardware.radio.V1_0.ResetNvType;
48 import android.hardware.radio.V1_0.SelectUiccSub;
49 import android.hardware.radio.V1_0.SimApdu;
50 import android.hardware.radio.V1_0.SmsWriteArgs;
51 import android.hardware.radio.V1_0.UusInfo;
52 import android.hardware.radio.V1_4.CarrierRestrictionsWithPriority;
53 import android.hardware.radio.V1_4.SimLockMultiSimPolicy;
54 import android.hardware.radio.V1_5.AccessNetwork;
55 import android.hardware.radio.V1_5.IndicationFilter;
56 import android.hardware.radio.V1_5.PersoSubstate;
57 import android.hardware.radio.V1_5.RadioAccessNetworks;
58 import android.hardware.radio.deprecated.V1_0.IOemHook;
59 import android.net.InetAddresses;
60 import android.net.KeepalivePacketData;
61 import android.net.LinkAddress;
62 import android.net.LinkProperties;
63 import android.os.AsyncResult;
64 import android.os.Handler;
65 import android.os.HwBinder;
66 import android.os.Message;
67 import android.os.PowerManager;
68 import android.os.PowerManager.WakeLock;
69 import android.os.RemoteException;
70 import android.os.SystemClock;
71 import android.os.WorkSource;
72 import android.provider.Settings;
73 import android.service.carrier.CarrierIdentifier;
74 import android.sysprop.TelephonyProperties;
75 import android.telephony.AccessNetworkConstants.AccessNetworkType;
76 import android.telephony.CarrierRestrictionRules;
77 import android.telephony.CellInfo;
78 import android.telephony.CellSignalStrengthCdma;
79 import android.telephony.CellSignalStrengthGsm;
80 import android.telephony.CellSignalStrengthLte;
81 import android.telephony.CellSignalStrengthNr;
82 import android.telephony.CellSignalStrengthTdscdma;
83 import android.telephony.CellSignalStrengthWcdma;
84 import android.telephony.ClientRequestStats;
85 import android.telephony.ImsiEncryptionInfo;
86 import android.telephony.ModemActivityInfo;
87 import android.telephony.NeighboringCellInfo;
88 import android.telephony.NetworkScanRequest;
89 import android.telephony.PhoneNumberUtils;
90 import android.telephony.RadioAccessFamily;
91 import android.telephony.RadioAccessSpecifier;
92 import android.telephony.ServiceState;
93 import android.telephony.SignalStrength;
94 import android.telephony.SignalThresholdInfo;
95 import android.telephony.SmsManager;
96 import android.telephony.SubscriptionManager;
97 import android.telephony.TelephonyHistogram;
98 import android.telephony.TelephonyManager;
99 import android.telephony.TelephonyManager.PrefNetworkMode;
100 import android.telephony.data.ApnSetting;
101 import android.telephony.data.DataCallResponse;
102 import android.telephony.data.DataProfile;
103 import android.telephony.data.DataService;
104 import android.telephony.emergency.EmergencyNumber;
105 import android.text.TextUtils;
106 import android.util.Log;
107 import android.util.SparseArray;
108 
109 import com.android.internal.annotations.VisibleForTesting;
110 import com.android.internal.telephony.cat.ComprehensionTlv;
111 import com.android.internal.telephony.cat.ComprehensionTlvTag;
112 import com.android.internal.telephony.cdma.CdmaInformationRecords;
113 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
114 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
115 import com.android.internal.telephony.metrics.TelephonyMetrics;
116 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
117 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
118 import com.android.internal.telephony.uicc.IccUtils;
119 import com.android.internal.telephony.util.TelephonyUtils;
120 import com.android.telephony.Rlog;
121 
122 import java.io.ByteArrayInputStream;
123 import java.io.DataInputStream;
124 import java.io.FileDescriptor;
125 import java.io.IOException;
126 import java.io.PrintWriter;
127 import java.net.Inet4Address;
128 import java.net.Inet6Address;
129 import java.net.InetAddress;
130 import java.util.ArrayList;
131 import java.util.Arrays;
132 import java.util.HashSet;
133 import java.util.List;
134 import java.util.NoSuchElementException;
135 import java.util.Set;
136 import java.util.concurrent.ConcurrentHashMap;
137 import java.util.concurrent.atomic.AtomicBoolean;
138 import java.util.concurrent.atomic.AtomicLong;
139 import java.util.stream.Collectors;
140 
141 /**
142  * RIL implementation of the CommandsInterface.
143  *
144  * {@hide}
145  */
146 public class RIL extends BaseCommands implements CommandsInterface {
147     static final String RILJ_LOG_TAG = "RILJ";
148     static final String RILJ_WAKELOCK_TAG = "*telephony-radio*";
149     // Have a separate wakelock instance for Ack
150     static final String RILJ_ACK_WAKELOCK_NAME = "RILJ_ACK_WL";
151     static final boolean RILJ_LOGD = true;
152     static final boolean RILJ_LOGV = false; // STOPSHIP if true
153     static final int RIL_HISTOGRAM_BUCKET_COUNT = 5;
154 
155     /**
156      * Wake lock timeout should be longer than the longest timeout in
157      * the vendor ril.
158      */
159     private static final int DEFAULT_WAKE_LOCK_TIMEOUT_MS = 60000;
160 
161     // Wake lock default timeout associated with ack
162     private static final int DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS = 200;
163 
164     private static final int DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS = 2000;
165 
166     // Variables used to differentiate ack messages from request while calling clearWakeLock()
167     public static final int INVALID_WAKELOCK = -1;
168     public static final int FOR_WAKELOCK = 0;
169     public static final int FOR_ACK_WAKELOCK = 1;
170     private final ClientWakelockTracker mClientWakelockTracker = new ClientWakelockTracker();
171 
172     /** @hide */
173     public static final HalVersion RADIO_HAL_VERSION_UNKNOWN = HalVersion.UNKNOWN;
174 
175     /** @hide */
176     public static final HalVersion RADIO_HAL_VERSION_1_0 = new HalVersion(1, 0);
177 
178     /** @hide */
179     public static final HalVersion RADIO_HAL_VERSION_1_1 = new HalVersion(1, 1);
180 
181     /** @hide */
182     public static final HalVersion RADIO_HAL_VERSION_1_2 = new HalVersion(1, 2);
183 
184     /** @hide */
185     public static final HalVersion RADIO_HAL_VERSION_1_3 = new HalVersion(1, 3);
186 
187     /** @hide */
188     public static final HalVersion RADIO_HAL_VERSION_1_4 = new HalVersion(1, 4);
189 
190     /** @hide */
191     public static final HalVersion RADIO_HAL_VERSION_1_5 = new HalVersion(1, 5);
192 
193     // IRadio version
194     private HalVersion mRadioVersion = RADIO_HAL_VERSION_UNKNOWN;
195 
196     private static final int INDICATION_FILTERS_ALL_V1_0 =
197             IndicationFilter.SIGNAL_STRENGTH
198             | IndicationFilter.FULL_NETWORK_STATE
199             | IndicationFilter.DATA_CALL_DORMANCY_CHANGED;
200     private static final int INDICATION_FILTERS_ALL_V1_2 =
201             INDICATION_FILTERS_ALL_V1_0
202             | IndicationFilter.LINK_CAPACITY_ESTIMATE
203             | IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
204     private static final  int INDICATION_FILTERS_ALL_V1_5 =
205             INDICATION_FILTERS_ALL_V1_2
206             | IndicationFilter.REGISTRATION_FAILURE
207             | IndicationFilter.BARRING_INFO;
208 
209     //***** Instance Variables
210 
211     @UnsupportedAppUsage
212     @VisibleForTesting
213     public final WakeLock mWakeLock;           // Wake lock associated with request/response
214     @VisibleForTesting
215     public final WakeLock mAckWakeLock;        // Wake lock associated with ack sent
216     final int mWakeLockTimeout;         // Timeout associated with request/response
217     final int mAckWakeLockTimeout;      // Timeout associated with ack sent
218     // The number of wakelock requests currently active.  Don't release the lock
219     // until dec'd to 0
220     int mWakeLockCount;
221 
222     // Variables used to identify releasing of WL on wakelock timeouts
223     volatile int mWlSequenceNum = 0;
224     volatile int mAckWlSequenceNum = 0;
225 
226     @UnsupportedAppUsage
227     SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
228     static SparseArray<TelephonyHistogram> mRilTimeHistograms = new
229             SparseArray<TelephonyHistogram>();
230 
231     Object[] mLastNITZTimeInfo;
232 
233     // When we are testing emergency calls using ril.test.emergencynumber, this will trigger test
234     // ECbM when the call is ended.
235     @UnsupportedAppUsage
236     AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
237 
238     final Integer mPhoneId;
239 
240     /**
241      * A set that records if radio service is disabled in hal for
242      * a specific phone id slot to avoid further getService request.
243      */
244     Set<Integer> mDisabledRadioServices = new HashSet();
245 
246     /**
247      * A set that records if oem hook service is disabled in hal for
248      * a specific phone id slot to avoid further getService request.
249      */
250     Set<Integer> mDisabledOemHookServices = new HashSet();
251 
252     /* default work source which will blame phone process */
253     private WorkSource mRILDefaultWorkSource;
254 
255     /* Worksource containing all applications causing wakelock to be held */
256     private WorkSource mActiveWakelockWorkSource;
257 
258     /** Telephony metrics instance for logging metrics event */
259     private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
260     /** Radio bug detector instance */
261     private RadioBugDetector mRadioBugDetector = null;
262 
263     boolean mIsCellularSupported;
264     RadioResponse mRadioResponse;
265     RadioIndication mRadioIndication;
266     volatile IRadio mRadioProxy = null;
267     OemHookResponse mOemHookResponse;
268     OemHookIndication mOemHookIndication;
269     volatile IOemHook mOemHookProxy = null;
270     final AtomicLong mRadioProxyCookie = new AtomicLong(0);
271     final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
272     final RilHandler mRilHandler;
273 
274     // Thread-safe HashMap to map from RIL_REQUEST_XXX constant to HalVersion.
275     // This is for Radio HAL Fallback Compatibility feature. When a RIL request
276     // is received, the HAL method from the mapping HalVersion here (if present),
277     // instead of the latest HalVersion, will be invoked.
278     private ConcurrentHashMap<Integer, HalVersion> mCompatOverrides =
279             new ConcurrentHashMap<>();
280 
281     //***** Events
282     static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
283     static final int EVENT_ACK_WAKE_LOCK_TIMEOUT    = 4;
284     static final int EVENT_BLOCKING_RESPONSE_TIMEOUT = 5;
285     static final int EVENT_RADIO_PROXY_DEAD     = 6;
286 
287     //***** Constants
288 
289     static final String[] HIDL_SERVICE_NAME = {"slot1", "slot2", "slot3"};
290 
291     static final int IRADIO_GET_SERVICE_DELAY_MILLIS = 4 * 1000;
292 
293     static final String EMPTY_ALPHA_LONG = "";
294     static final String EMPTY_ALPHA_SHORT = "";
295 
getTelephonyRILTimingHistograms()296     public static List<TelephonyHistogram> getTelephonyRILTimingHistograms() {
297         List<TelephonyHistogram> list;
298         synchronized (mRilTimeHistograms) {
299             list = new ArrayList<>(mRilTimeHistograms.size());
300             for (int i = 0; i < mRilTimeHistograms.size(); i++) {
301                 TelephonyHistogram entry = new TelephonyHistogram(mRilTimeHistograms.valueAt(i));
302                 list.add(entry);
303             }
304         }
305         return list;
306     }
307 
308     /** The handler used to handle the internal event of RIL. */
309     @VisibleForTesting
310     public class RilHandler extends Handler {
311 
312         //***** Handler implementation
313         @Override
handleMessage(Message msg)314         public void handleMessage(Message msg) {
315             RILRequest rr;
316 
317             switch (msg.what) {
318                 case EVENT_WAKE_LOCK_TIMEOUT:
319                     // Haven't heard back from the last request.  Assume we're
320                     // not getting a response and  release the wake lock.
321 
322                     // The timer of WAKE_LOCK_TIMEOUT is reset with each
323                     // new send request. So when WAKE_LOCK_TIMEOUT occurs
324                     // all requests in mRequestList already waited at
325                     // least DEFAULT_WAKE_LOCK_TIMEOUT_MS but no response.
326                     //
327                     // Note: Keep mRequestList so that delayed response
328                     // can still be handled when response finally comes.
329 
330                     synchronized (mRequestList) {
331                         if (msg.arg1 == mWlSequenceNum && clearWakeLock(FOR_WAKELOCK)) {
332                             if (mRadioBugDetector != null) {
333                                 mRadioBugDetector.processWakelockTimeout();
334                             }
335                             if (RILJ_LOGD) {
336                                 int count = mRequestList.size();
337                                 Rlog.d(RILJ_LOG_TAG, "WAKE_LOCK_TIMEOUT " +
338                                         " mRequestList=" + count);
339                                 for (int i = 0; i < count; i++) {
340                                     rr = mRequestList.valueAt(i);
341                                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
342                                             + requestToString(rr.mRequest));
343                                 }
344                             }
345                         }
346                     }
347                     break;
348 
349                 case EVENT_ACK_WAKE_LOCK_TIMEOUT:
350                     if (msg.arg1 == mAckWlSequenceNum && clearWakeLock(FOR_ACK_WAKELOCK)) {
351                         if (RILJ_LOGV) {
352                             Rlog.d(RILJ_LOG_TAG, "ACK_WAKE_LOCK_TIMEOUT");
353                         }
354                     }
355                     break;
356 
357                 case EVENT_BLOCKING_RESPONSE_TIMEOUT:
358                     int serial = msg.arg1;
359                     rr = findAndRemoveRequestFromList(serial);
360                     // If the request has already been processed, do nothing
361                     if(rr == null) {
362                         break;
363                     }
364 
365                     //build a response if expected
366                     if (rr.mResult != null) {
367                         Object timeoutResponse = getResponseForTimedOutRILRequest(rr);
368                         AsyncResult.forMessage( rr.mResult, timeoutResponse, null);
369                         rr.mResult.sendToTarget();
370                         mMetrics.writeOnRilTimeoutResponse(mPhoneId, rr.mSerial, rr.mRequest);
371                     }
372 
373                     decrementWakeLock(rr);
374                     rr.release();
375                     break;
376 
377                 case EVENT_RADIO_PROXY_DEAD:
378                     riljLog("handleMessage: EVENT_RADIO_PROXY_DEAD cookie = " + msg.obj +
379                             " mRadioProxyCookie = " + mRadioProxyCookie.get());
380                     if ((long) msg.obj == mRadioProxyCookie.get()) {
381                         resetProxyAndRequestList();
382                     }
383                     break;
384             }
385         }
386     }
387 
388     /** Return RadioBugDetector instance for testing. */
389     @VisibleForTesting
getRadioBugDetector()390     public RadioBugDetector getRadioBugDetector() {
391         if (mRadioBugDetector == null) {
392             mRadioBugDetector = new RadioBugDetector(mContext, mPhoneId);
393         }
394         return mRadioBugDetector;
395     }
396 
397     /**
398      * In order to prevent calls to Telephony from waiting indefinitely
399      * low-latency blocking calls will eventually time out. In the event of
400      * a timeout, this function generates a response that is returned to the
401      * higher layers to unblock the call. This is in lieu of a meaningful
402      * response.
403      * @param rr The RIL Request that has timed out.
404      * @return A default object, such as the one generated by a normal response
405      * that is returned to the higher layers.
406      **/
407     @UnsupportedAppUsage
getResponseForTimedOutRILRequest(RILRequest rr)408     private static Object getResponseForTimedOutRILRequest(RILRequest rr) {
409         if (rr == null ) return null;
410 
411         Object timeoutResponse = null;
412         switch(rr.mRequest) {
413             case RIL_REQUEST_GET_ACTIVITY_INFO:
414                 timeoutResponse = new ModemActivityInfo(
415                         0, 0, 0, new int [ModemActivityInfo.TX_POWER_LEVELS], 0);
416                 break;
417         };
418         return timeoutResponse;
419     }
420 
421     final class RadioProxyDeathRecipient implements HwBinder.DeathRecipient {
422         @Override
serviceDied(long cookie)423         public void serviceDied(long cookie) {
424             // Deal with service going away
425             riljLog("serviceDied");
426             mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
427         }
428     }
429 
resetProxyAndRequestList()430     private synchronized void resetProxyAndRequestList() {
431         mRadioProxy = null;
432         mOemHookProxy = null;
433 
434         // increment the cookie so that death notification can be ignored
435         mRadioProxyCookie.incrementAndGet();
436 
437         setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, true /* forceNotifyRegistrants */);
438 
439         RILRequest.resetSerial();
440         // Clear request list on close
441         clearRequestList(RADIO_NOT_AVAILABLE, false);
442 
443         getRadioProxy(null);
444         getOemHookProxy(null);
445     }
446 
447     /** Set a radio HAL fallback compatibility override. */
448     @VisibleForTesting
setCompatVersion(int rilRequest, @NonNull HalVersion halVersion)449     public void setCompatVersion(int rilRequest, @NonNull HalVersion halVersion) {
450         HalVersion oldVersion = getCompatVersion(rilRequest);
451         // Do not allow to set same or greater verions
452         if (oldVersion != null && halVersion.greaterOrEqual(oldVersion)) {
453             riljLoge("setCompatVersion with equal or greater one, ignored, halVerion=" + halVersion
454                     + ", oldVerion=" + oldVersion);
455             return;
456         }
457         mCompatOverrides.put(rilRequest, halVersion);
458     }
459 
460     /** Get a radio HAL fallback compatibility override, or null if not exist. */
461     @VisibleForTesting
getCompatVersion(int rilRequest)462     public @Nullable HalVersion getCompatVersion(int rilRequest) {
463         return mCompatOverrides.getOrDefault(rilRequest, null);
464     }
465 
466     /** Returns a {@link IRadio} instance or null if the service is not available. */
467     @VisibleForTesting
getRadioProxy(Message result)468     public synchronized IRadio getRadioProxy(Message result) {
469         if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return null;
470         if (!mIsCellularSupported) {
471             if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
472             if (result != null) {
473                 AsyncResult.forMessage(result, null,
474                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
475                 result.sendToTarget();
476             }
477             return null;
478         }
479 
480         if (mRadioProxy != null) {
481             return mRadioProxy;
482         }
483 
484         try {
485             if (mDisabledRadioServices.contains(mPhoneId)) {
486                 riljLoge("getRadioProxy: mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId]
487                         + " is disabled");
488             } else {
489                 try {
490                     mRadioProxy = android.hardware.radio.V1_5.IRadio.getService(
491                             HIDL_SERVICE_NAME[mPhoneId], true);
492                     mRadioVersion = RADIO_HAL_VERSION_1_5;
493                 } catch (NoSuchElementException e) {
494                 }
495 
496                 if (mRadioProxy == null) {
497                     try {
498                         mRadioProxy = android.hardware.radio.V1_4.IRadio.getService(
499                                 HIDL_SERVICE_NAME[mPhoneId], true);
500                         mRadioVersion = RADIO_HAL_VERSION_1_4;
501                     } catch (NoSuchElementException e) {
502                     }
503                 }
504 
505                 if (mRadioProxy == null) {
506                     try {
507                         mRadioProxy = android.hardware.radio.V1_3.IRadio.getService(
508                                 HIDL_SERVICE_NAME[mPhoneId], true);
509                         mRadioVersion = RADIO_HAL_VERSION_1_3;
510                     } catch (NoSuchElementException e) {
511                     }
512                 }
513 
514                 if (mRadioProxy == null) {
515                     try {
516                         mRadioProxy = android.hardware.radio.V1_2.IRadio.getService(
517                                 HIDL_SERVICE_NAME[mPhoneId], true);
518                         mRadioVersion = RADIO_HAL_VERSION_1_2;
519                     } catch (NoSuchElementException e) {
520                     }
521                 }
522 
523                 if (mRadioProxy == null) {
524                     try {
525                         mRadioProxy = android.hardware.radio.V1_1.IRadio.getService(
526                                 HIDL_SERVICE_NAME[mPhoneId], true);
527                         mRadioVersion = RADIO_HAL_VERSION_1_1;
528                     } catch (NoSuchElementException e) {
529                     }
530                 }
531 
532                 if (mRadioProxy == null) {
533                     try {
534                         mRadioProxy = android.hardware.radio.V1_0.IRadio.getService(
535                                 HIDL_SERVICE_NAME[mPhoneId], true);
536                         mRadioVersion = RADIO_HAL_VERSION_1_0;
537                     } catch (NoSuchElementException e) {
538                     }
539                 }
540 
541                 if (mRadioProxy != null) {
542                     mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
543                             mRadioProxyCookie.incrementAndGet());
544                     mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
545                 } else {
546                     mDisabledRadioServices.add(mPhoneId);
547                     riljLoge("getRadioProxy: mRadioProxy for "
548                             + HIDL_SERVICE_NAME[mPhoneId] + " is disabled");
549                 }
550             }
551         } catch (RemoteException e) {
552             mRadioProxy = null;
553             riljLoge("RadioProxy getService/setResponseFunctions: " + e);
554         }
555 
556         if (mRadioProxy == null) {
557             // getService() is a blocking call, so this should never happen
558             riljLoge("getRadioProxy: mRadioProxy == null");
559             if (result != null) {
560                 AsyncResult.forMessage(result, null,
561                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
562                 result.sendToTarget();
563             }
564         }
565 
566         return mRadioProxy;
567     }
568 
569     @Override
onSlotActiveStatusChange(boolean active)570     public synchronized void onSlotActiveStatusChange(boolean active) {
571         if (active) {
572             // Try to connect to RIL services and set response functions.
573             getRadioProxy(null);
574             getOemHookProxy(null);
575         } else {
576             resetProxyAndRequestList();
577         }
578     }
579 
580     /** Returns an {@link IOemHook} instance or null if the service is not available. */
581     @VisibleForTesting
getOemHookProxy(Message result)582     public synchronized IOemHook getOemHookProxy(Message result) {
583         if (!SubscriptionManager.isValidPhoneId((mPhoneId))) return null;
584         if (!mIsCellularSupported) {
585             if (RILJ_LOGV) riljLog("getOemHookProxy: Not calling getService(): wifi-only");
586             if (result != null) {
587                 AsyncResult.forMessage(result, null,
588                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
589                 result.sendToTarget();
590             }
591             return null;
592         }
593 
594         if (mOemHookProxy != null) {
595             return mOemHookProxy;
596         }
597 
598         try {
599             if (mDisabledOemHookServices.contains(mPhoneId)) {
600                 riljLoge("getOemHookProxy: mOemHookProxy for " + HIDL_SERVICE_NAME[mPhoneId]
601                         + " is disabled");
602             } else {
603                 mOemHookProxy = IOemHook.getService(HIDL_SERVICE_NAME[mPhoneId], true);
604                 if (mOemHookProxy != null) {
605                     // not calling linkToDeath() as ril service runs in the same process and death
606                     // notification for that should be sufficient
607                     mOemHookProxy.setResponseFunctions(mOemHookResponse, mOemHookIndication);
608                 } else {
609                     mDisabledOemHookServices.add(mPhoneId);
610                     riljLoge("getOemHookProxy: mOemHookProxy for " + HIDL_SERVICE_NAME[mPhoneId]
611                             + " is disabled");
612                 }
613             }
614         } catch (NoSuchElementException e) {
615             mOemHookProxy = null;
616             riljLoge("IOemHook service is not on the device HAL: " + e);
617         }  catch (RemoteException e) {
618             mOemHookProxy = null;
619             riljLoge("OemHookProxy getService/setResponseFunctions: " + e);
620         }
621 
622         if (mOemHookProxy == null) {
623             if (result != null) {
624                 AsyncResult.forMessage(result, null,
625                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
626                 result.sendToTarget();
627             }
628         }
629 
630         return mOemHookProxy;
631     }
632 
633     //***** Constructors
634 
635     @UnsupportedAppUsage
RIL(Context context, int preferredNetworkType, int cdmaSubscription)636     public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
637         this(context, preferredNetworkType, cdmaSubscription, null);
638     }
639 
640     @UnsupportedAppUsage
RIL(Context context, int preferredNetworkType, int cdmaSubscription, Integer instanceId)641     public RIL(Context context, int preferredNetworkType,
642             int cdmaSubscription, Integer instanceId) {
643         super(context);
644         if (RILJ_LOGD) {
645             riljLog("RIL: init preferredNetworkType=" + preferredNetworkType
646                     + " cdmaSubscription=" + cdmaSubscription + ")");
647         }
648 
649         mContext = context;
650         mCdmaSubscription  = cdmaSubscription;
651         mPreferredNetworkType = preferredNetworkType;
652         mPhoneType = RILConstants.NO_PHONE;
653         mPhoneId = instanceId == null ? 0 : instanceId;
654         if (isRadioBugDetectionEnabled()) {
655             mRadioBugDetector = new RadioBugDetector(context, mPhoneId);
656         }
657 
658         TelephonyManager tm = (TelephonyManager) context.getSystemService(
659                 Context.TELEPHONY_SERVICE);
660         mIsCellularSupported = tm.isVoiceCapable() || tm.isSmsCapable() || tm.isDataCapable();
661 
662         mRadioResponse = new RadioResponse(this);
663         mRadioIndication = new RadioIndication(this);
664         mOemHookResponse = new OemHookResponse(this);
665         mOemHookIndication = new OemHookIndication(this);
666         mRilHandler = new RilHandler();
667         mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
668 
669         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
670         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_WAKELOCK_TAG);
671         mWakeLock.setReferenceCounted(false);
672         mAckWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_ACK_WAKELOCK_NAME);
673         mAckWakeLock.setReferenceCounted(false);
674         mWakeLockTimeout = TelephonyProperties.wake_lock_timeout()
675                 .orElse(DEFAULT_WAKE_LOCK_TIMEOUT_MS);
676         mAckWakeLockTimeout = TelephonyProperties.wake_lock_timeout()
677                 .orElse(DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS);
678         mWakeLockCount = 0;
679         mRILDefaultWorkSource = new WorkSource(context.getApplicationInfo().uid,
680                 context.getPackageName());
681         mActiveWakelockWorkSource = new WorkSource();
682 
683         TelephonyDevController tdc = TelephonyDevController.getInstance();
684         tdc.registerRIL(this);
685 
686         // set radio callback; needed to set RadioIndication callback (should be done after
687         // wakelock stuff is initialized above as callbacks are received on separate binder threads)
688         getRadioProxy(null);
689         getOemHookProxy(null);
690 
691         if (RILJ_LOGD) {
692             riljLog("Radio HAL version: " + mRadioVersion);
693         }
694     }
695 
isRadioBugDetectionEnabled()696     private boolean isRadioBugDetectionEnabled() {
697         return Settings.Global.getInt(
698                 mContext.getContentResolver(),
699                 Settings.Global.ENABLE_RADIO_BUG_DETECTION,
700                 1) != 0;
701     }
702 
703     @Override
setOnNITZTime(Handler h, int what, Object obj)704     public void setOnNITZTime(Handler h, int what, Object obj) {
705         super.setOnNITZTime(h, what, obj);
706 
707         // Send the last NITZ time if we have it
708         if (mLastNITZTimeInfo != null) {
709             mNITZTimeRegistrant
710                 .notifyRegistrant(
711                     new AsyncResult (null, mLastNITZTimeInfo, null));
712         }
713     }
714 
addRequest(RILRequest rr)715     private void addRequest(RILRequest rr) {
716         acquireWakeLock(rr, FOR_WAKELOCK);
717         synchronized (mRequestList) {
718             rr.mStartTimeMs = SystemClock.elapsedRealtime();
719             mRequestList.append(rr.mSerial, rr);
720         }
721     }
722 
obtainRequest(int request, Message result, WorkSource workSource)723     private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
724         RILRequest rr = RILRequest.obtain(request, result, workSource);
725         addRequest(rr);
726         return rr;
727     }
728 
obtainRequest(int request, Message result, WorkSource workSource, Object... args)729     private RILRequest obtainRequest(int request, Message result, WorkSource workSource,
730             Object... args) {
731         RILRequest rr = RILRequest.obtain(request, result, workSource, args);
732         addRequest(rr);
733         return rr;
734     }
735 
handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e)736     private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) {
737         riljLoge(caller + ": " + e);
738         resetProxyAndRequestList();
739     }
740 
convertNullToEmptyString(String string)741     private static String convertNullToEmptyString(String string) {
742         return string != null ? string : "";
743     }
744 
745     @Override
getIccCardStatus(Message result)746     public void getIccCardStatus(Message result) {
747         IRadio radioProxy = getRadioProxy(result);
748         if (radioProxy != null) {
749             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_STATUS, result,
750                     mRILDefaultWorkSource);
751 
752             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
753 
754             try {
755                 radioProxy.getIccCardStatus(rr.mSerial);
756             } catch (RemoteException | RuntimeException e) {
757                 handleRadioProxyExceptionForRR(rr, "getIccCardStatus", e);
758             }
759         }
760     }
761 
762     @Override
getIccSlotsStatus(Message result)763     public void getIccSlotsStatus(Message result) {
764         if (result != null) {
765             AsyncResult.forMessage(result, null,
766                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
767             result.sendToTarget();
768         }
769     }
770 
771     @Override
setLogicalToPhysicalSlotMapping(int[] physicalSlots, Message result)772     public void setLogicalToPhysicalSlotMapping(int[] physicalSlots, Message result) {
773         if (result != null) {
774             AsyncResult.forMessage(result, null,
775                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
776             result.sendToTarget();
777         }
778     }
779 
780     @Override
supplyIccPin(String pin, Message result)781     public void supplyIccPin(String pin, Message result) {
782         supplyIccPinForApp(pin, null, result);
783     }
784 
785     @Override
supplyIccPinForApp(String pin, String aid, Message result)786     public void supplyIccPinForApp(String pin, String aid, Message result) {
787         IRadio radioProxy = getRadioProxy(result);
788         if (radioProxy != null) {
789             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN, result,
790                     mRILDefaultWorkSource);
791 
792             if (RILJ_LOGD) {
793                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
794                         + " aid = " + aid);
795             }
796 
797             try {
798                 radioProxy.supplyIccPinForApp(rr.mSerial,
799                         convertNullToEmptyString(pin),
800                         convertNullToEmptyString(aid));
801             } catch (RemoteException | RuntimeException e) {
802                 handleRadioProxyExceptionForRR(rr, "supplyIccPinForApp", e);
803             }
804         }
805     }
806 
807     @Override
supplyIccPuk(String puk, String newPin, Message result)808     public void supplyIccPuk(String puk, String newPin, Message result) {
809         supplyIccPukForApp(puk, newPin, null, result);
810     }
811 
812     @Override
supplyIccPukForApp(String puk, String newPin, String aid, Message result)813     public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
814         IRadio radioProxy = getRadioProxy(result);
815         if (radioProxy != null) {
816             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK, result,
817                     mRILDefaultWorkSource);
818 
819             if (RILJ_LOGD) {
820                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
821                         + " aid = " + aid);
822             }
823 
824             try {
825                 radioProxy.supplyIccPukForApp(rr.mSerial,
826                         convertNullToEmptyString(puk),
827                         convertNullToEmptyString(newPin),
828                         convertNullToEmptyString(aid));
829             } catch (RemoteException | RuntimeException e) {
830                 handleRadioProxyExceptionForRR(rr, "supplyIccPukForApp", e);
831             }
832         }
833     }
834 
835     @Override
supplyIccPin2(String pin, Message result)836     public void supplyIccPin2(String pin, Message result) {
837         supplyIccPin2ForApp(pin, null, result);
838     }
839 
840     @Override
supplyIccPin2ForApp(String pin, String aid, Message result)841     public void supplyIccPin2ForApp(String pin, String aid, Message result) {
842         IRadio radioProxy = getRadioProxy(result);
843         if (radioProxy != null) {
844             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN2, result,
845                     mRILDefaultWorkSource);
846 
847             if (RILJ_LOGD) {
848                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
849                         + " aid = " + aid);
850             }
851 
852             try {
853                 radioProxy.supplyIccPin2ForApp(rr.mSerial,
854                         convertNullToEmptyString(pin),
855                         convertNullToEmptyString(aid));
856             } catch (RemoteException | RuntimeException e) {
857                 handleRadioProxyExceptionForRR(rr, "supplyIccPin2ForApp", e);
858             }
859         }
860     }
861 
862     @Override
supplyIccPuk2(String puk2, String newPin2, Message result)863     public void supplyIccPuk2(String puk2, String newPin2, Message result) {
864         supplyIccPuk2ForApp(puk2, newPin2, null, result);
865     }
866 
867     @Override
supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result)868     public void supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
869         IRadio radioProxy = getRadioProxy(result);
870         if (radioProxy != null) {
871             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK2, result,
872                     mRILDefaultWorkSource);
873 
874             if (RILJ_LOGD) {
875                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
876                         + " aid = " + aid);
877             }
878 
879             try {
880                 radioProxy.supplyIccPuk2ForApp(rr.mSerial,
881                         convertNullToEmptyString(puk),
882                         convertNullToEmptyString(newPin2),
883                         convertNullToEmptyString(aid));
884             } catch (RemoteException | RuntimeException e) {
885                 handleRadioProxyExceptionForRR(rr, "supplyIccPuk2ForApp", e);
886             }
887         }
888     }
889 
890     @Override
changeIccPin(String oldPin, String newPin, Message result)891     public void changeIccPin(String oldPin, String newPin, Message result) {
892         changeIccPinForApp(oldPin, newPin, null, result);
893     }
894 
895     @Override
changeIccPinForApp(String oldPin, String newPin, String aid, Message result)896     public void changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
897         IRadio radioProxy = getRadioProxy(result);
898         if (radioProxy != null) {
899             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN, result,
900                     mRILDefaultWorkSource);
901 
902             if (RILJ_LOGD) {
903                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
904                         + oldPin + " newPin = " + newPin + " aid = " + aid);
905             }
906 
907             try {
908                 radioProxy.changeIccPinForApp(rr.mSerial,
909                         convertNullToEmptyString(oldPin),
910                         convertNullToEmptyString(newPin),
911                         convertNullToEmptyString(aid));
912             } catch (RemoteException | RuntimeException e) {
913                 handleRadioProxyExceptionForRR(rr, "changeIccPinForApp", e);
914             }
915         }
916     }
917 
918     @Override
changeIccPin2(String oldPin2, String newPin2, Message result)919     public void changeIccPin2(String oldPin2, String newPin2, Message result) {
920         changeIccPin2ForApp(oldPin2, newPin2, null, result);
921     }
922 
923     @Override
changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result)924     public void changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
925         IRadio radioProxy = getRadioProxy(result);
926         if (radioProxy != null) {
927             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN2, result,
928                     mRILDefaultWorkSource);
929 
930             if (RILJ_LOGD) {
931                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
932                         + oldPin2 + " newPin = " + newPin2 + " aid = " + aid);
933             }
934 
935             try {
936                 radioProxy.changeIccPin2ForApp(rr.mSerial,
937                         convertNullToEmptyString(oldPin2),
938                         convertNullToEmptyString(newPin2),
939                         convertNullToEmptyString(aid));
940             } catch (RemoteException | RuntimeException e) {
941                 handleRadioProxyExceptionForRR(rr, "changeIccPin2ForApp", e);
942             }
943         }
944     }
945 
946     @Override
supplyNetworkDepersonalization(String netpin, Message result)947     public void supplyNetworkDepersonalization(String netpin, Message result) {
948         IRadio radioProxy = getRadioProxy(result);
949         if (radioProxy != null) {
950             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result,
951                     mRILDefaultWorkSource);
952 
953             if (RILJ_LOGD) {
954                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " netpin = "
955                         + netpin);
956             }
957 
958             try {
959                 radioProxy.supplyNetworkDepersonalization(rr.mSerial,
960                         convertNullToEmptyString(netpin));
961             } catch (RemoteException | RuntimeException e) {
962                 handleRadioProxyExceptionForRR(rr, "supplyNetworkDepersonalization", e);
963             }
964         }
965     }
966 
967     @Override
supplySimDepersonalization(PersoSubState persoType, String controlKey, Message result)968     public void supplySimDepersonalization(PersoSubState persoType,
969             String controlKey, Message result) {
970         IRadio radioProxy = getRadioProxy(result);
971         // IRadio V1.5
972         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
973             android.hardware.radio.V1_5.IRadio radioProxy15 =
974                 (android.hardware.radio.V1_5.IRadio) radioProxy;
975             if (radioProxy15 != null) {
976                 RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, result,
977                         mRILDefaultWorkSource);
978                 if (RILJ_LOGD) {
979                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " controlKey = "
980                         + controlKey + " persoType" + persoType);
981                 }
982                 try {
983                     radioProxy15.supplySimDepersonalization(rr.mSerial,
984                             convertPersoTypeToHalPersoType(persoType),
985                             convertNullToEmptyString(controlKey));
986                 } catch (RemoteException | RuntimeException e) {
987                     handleRadioProxyExceptionForRR(rr, "supplySimDepersonalization", e);
988                 }
989             }
990         } else {
991             if (result != null) {
992                 AsyncResult.forMessage(result, null,
993                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
994                 result.sendToTarget();
995             }
996         }
997     }
998 
convertPersoTypeToHalPersoType(PersoSubState persoType)999     private static int convertPersoTypeToHalPersoType(PersoSubState persoType) {
1000 
1001         switch(persoType) {
1002 
1003             case PERSOSUBSTATE_IN_PROGRESS:
1004                 return PersoSubstate.IN_PROGRESS;
1005             case  PERSOSUBSTATE_READY:
1006                 return PersoSubstate.READY;
1007             case PERSOSUBSTATE_SIM_NETWORK:
1008                 return PersoSubstate.SIM_NETWORK;
1009             case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
1010                 return PersoSubstate.SIM_NETWORK_SUBSET;
1011             case PERSOSUBSTATE_SIM_CORPORATE:
1012                 return PersoSubstate.SIM_CORPORATE;
1013             case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
1014                 return PersoSubstate.SIM_SERVICE_PROVIDER;
1015             case PERSOSUBSTATE_SIM_SIM:
1016                 return PersoSubstate.SIM_SIM;
1017             case PERSOSUBSTATE_SIM_NETWORK_PUK:
1018                 return PersoSubstate.SIM_NETWORK_PUK;
1019             case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
1020                 return PersoSubstate.SIM_NETWORK_SUBSET_PUK;
1021             case PERSOSUBSTATE_SIM_CORPORATE_PUK:
1022                 return PersoSubstate.SIM_CORPORATE_PUK;
1023             case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
1024                 return PersoSubstate.SIM_SERVICE_PROVIDER_PUK;
1025             case PERSOSUBSTATE_SIM_SIM_PUK:
1026                 return PersoSubstate.SIM_SIM_PUK;
1027             case PERSOSUBSTATE_RUIM_NETWORK1:
1028                 return PersoSubstate.RUIM_NETWORK1;
1029             case PERSOSUBSTATE_RUIM_NETWORK2:
1030                 return PersoSubstate.RUIM_NETWORK2;
1031             case PERSOSUBSTATE_RUIM_HRPD:
1032                 return PersoSubstate.RUIM_HRPD;
1033             case PERSOSUBSTATE_RUIM_CORPORATE:
1034                 return PersoSubstate.RUIM_CORPORATE;
1035             case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER:
1036                 return PersoSubstate.RUIM_SERVICE_PROVIDER;
1037             case PERSOSUBSTATE_RUIM_RUIM:
1038                 return PersoSubstate.RUIM_RUIM;
1039             case PERSOSUBSTATE_RUIM_NETWORK1_PUK:
1040                 return PersoSubstate.RUIM_NETWORK1_PUK;
1041             case PERSOSUBSTATE_RUIM_NETWORK2_PUK:
1042                 return PersoSubstate.RUIM_NETWORK2_PUK;
1043             case PERSOSUBSTATE_RUIM_HRPD_PUK:
1044                 return PersoSubstate.RUIM_HRPD_PUK;
1045             case PERSOSUBSTATE_RUIM_CORPORATE_PUK:
1046                 return PersoSubstate.RUIM_CORPORATE_PUK;
1047             case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK:
1048                 return PersoSubstate.RUIM_SERVICE_PROVIDER_PUK;
1049             case PERSOSUBSTATE_RUIM_RUIM_PUK:
1050                 return PersoSubstate.RUIM_RUIM_PUK;
1051             case PERSOSUBSTATE_SIM_SPN:
1052                 return PersoSubstate.SIM_SPN;
1053             case PERSOSUBSTATE_SIM_SPN_PUK:
1054                 return PersoSubstate.SIM_SPN_PUK;
1055             case PERSOSUBSTATE_SIM_SP_EHPLMN:
1056                 return PersoSubstate.SIM_SP_EHPLMN;
1057             case PERSOSUBSTATE_SIM_SP_EHPLMN_PUK:
1058                 return PersoSubstate.SIM_SP_EHPLMN_PUK;
1059             case PERSOSUBSTATE_SIM_ICCID:
1060                 return PersoSubstate.SIM_ICCID;
1061             case PERSOSUBSTATE_SIM_ICCID_PUK:
1062                 return PersoSubstate.SIM_ICCID_PUK;
1063             case PERSOSUBSTATE_SIM_IMPI:
1064                 return PersoSubstate.SIM_IMPI;
1065             case PERSOSUBSTATE_SIM_IMPI_PUK:
1066                 return PersoSubstate.SIM_IMPI_PUK;
1067             case PERSOSUBSTATE_SIM_NS_SP:
1068                 return PersoSubstate.SIM_NS_SP;
1069             case PERSOSUBSTATE_SIM_NS_SP_PUK:
1070                 return PersoSubstate.SIM_NS_SP_PUK;
1071             default:
1072                 return PersoSubstate.UNKNOWN;
1073         }
1074     }
1075 
1076     @Override
getCurrentCalls(Message result)1077     public void getCurrentCalls(Message result) {
1078         IRadio radioProxy = getRadioProxy(result);
1079         if (radioProxy != null) {
1080             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
1081                     mRILDefaultWorkSource);
1082 
1083             if (RILJ_LOGD) {
1084                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1085             }
1086 
1087             try {
1088                 radioProxy.getCurrentCalls(rr.mSerial);
1089             } catch (RemoteException | RuntimeException e) {
1090                 handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
1091             }
1092         }
1093     }
1094 
1095     @Override
dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, Message result)1096     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
1097                      boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
1098         dial(address, isEmergencyCall, emergencyNumberInfo, hasKnownUserIntentEmergency,
1099                 clirMode, null, result);
1100     }
1101 
1102     @Override
enableModem(boolean enable, Message result)1103     public void enableModem(boolean enable, Message result) {
1104         IRadio radioProxy = getRadioProxy(result);
1105         if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
1106             if (RILJ_LOGV) riljLog("enableModem: not supported.");
1107             if (result != null) {
1108                 AsyncResult.forMessage(result, null,
1109                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
1110                 result.sendToTarget();
1111             }
1112             return;
1113         }
1114 
1115         android.hardware.radio.V1_3.IRadio radioProxy13 =
1116                 (android.hardware.radio.V1_3.IRadio) radioProxy;
1117         if (radioProxy13 != null) {
1118             RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result,
1119                     mRILDefaultWorkSource);
1120 
1121             if (RILJ_LOGD) {
1122                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
1123                         + enable);
1124             }
1125 
1126             try {
1127                 radioProxy13.enableModem(rr.mSerial, enable);
1128             } catch (RemoteException | RuntimeException e) {
1129                 handleRadioProxyExceptionForRR(rr, "enableModem", e);
1130             }
1131         }
1132     }
1133 
1134     @Override
setSystemSelectionChannels(@onNull List<RadioAccessSpecifier> specifiers, Message onComplete)1135     public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
1136             Message onComplete) {
1137         IRadio radioProxy = getRadioProxy(onComplete);
1138         if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
1139             if (RILJ_LOGV) riljLog("setSystemSelectionChannels: not supported.");
1140             if (onComplete != null) {
1141                 AsyncResult.forMessage(onComplete, null,
1142                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
1143                 onComplete.sendToTarget();
1144             }
1145             return;
1146         }
1147 
1148         RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, onComplete,
1149                 mRILDefaultWorkSource);
1150 
1151         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
1152             android.hardware.radio.V1_3.IRadio radioProxy13 =
1153                     (android.hardware.radio.V1_3.IRadio) radioProxy;
1154             if (radioProxy13 != null) {
1155                 if (RILJ_LOGD) {
1156                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1157                             + " setSystemSelectionChannels_1.3= "
1158                             + specifiers);
1159                 }
1160 
1161                 ArrayList<android.hardware.radio.V1_1.RadioAccessSpecifier> halSpecifiers =
1162                         specifiers.stream()
1163                                 .map(this::convertRadioAccessSpecifierToRadioHAL)
1164                                 .collect(Collectors.toCollection(ArrayList::new));
1165 
1166                 try {
1167                     radioProxy13.setSystemSelectionChannels(rr.mSerial,
1168                             !halSpecifiers.isEmpty(),
1169                             halSpecifiers);
1170                 } catch (RemoteException | RuntimeException e) {
1171                     handleRadioProxyExceptionForRR(rr, "setSystemSelectionChannels", e);
1172                 }
1173             }
1174         }
1175 
1176         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
1177             android.hardware.radio.V1_5.IRadio radioProxy15 =
1178                     (android.hardware.radio.V1_5.IRadio) radioProxy;
1179 
1180             if (radioProxy15 != null) {
1181                 if (RILJ_LOGD) {
1182                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1183                             + " setSystemSelectionChannels_1.5= "
1184                             + specifiers);
1185                 }
1186 
1187                 ArrayList<android.hardware.radio.V1_5.RadioAccessSpecifier> halSpecifiers =
1188                         specifiers.stream()
1189                                 .map(this::convertRadioAccessSpecifierToRadioHAL_1_5)
1190                                 .collect(Collectors.toCollection(ArrayList::new));
1191 
1192                 try {
1193                     radioProxy15.setSystemSelectionChannels_1_5(rr.mSerial,
1194                             !halSpecifiers.isEmpty(),
1195                             halSpecifiers);
1196                 } catch (RemoteException | RuntimeException e) {
1197                     handleRadioProxyExceptionForRR(rr, "setSystemSelectionChannels", e);
1198                 }
1199             }
1200         }
1201     }
1202 
1203     @Override
getModemStatus(Message result)1204     public void getModemStatus(Message result) {
1205         IRadio radioProxy = getRadioProxy(result);
1206         if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
1207             if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
1208             if (result != null) {
1209                 AsyncResult.forMessage(result, null,
1210                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
1211                 result.sendToTarget();
1212             }
1213             return;
1214         }
1215 
1216         android.hardware.radio.V1_3.IRadio radioProxy13 =
1217                 (android.hardware.radio.V1_3.IRadio) radioProxy;
1218         if (radioProxy13 != null) {
1219             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
1220                     mRILDefaultWorkSource);
1221 
1222             if (RILJ_LOGD) {
1223                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1224             }
1225 
1226             try {
1227                 radioProxy13.getModemStackStatus(rr.mSerial);
1228             } catch (RemoteException | RuntimeException e) {
1229                 handleRadioProxyExceptionForRR(rr, "getModemStatus", e);
1230             }
1231         }
1232     }
1233 
1234     @Override
dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result)1235     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
1236                      boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
1237                      Message result) {
1238         if (isEmergencyCall && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)
1239                 && emergencyNumberInfo != null) {
1240             emergencyDial(address, emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode,
1241                     uusInfo, result);
1242             return;
1243         }
1244         IRadio radioProxy = getRadioProxy(result);
1245         if (radioProxy != null) {
1246             RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result,
1247                     mRILDefaultWorkSource);
1248 
1249             Dial dialInfo = new Dial();
1250             dialInfo.address = convertNullToEmptyString(address);
1251             dialInfo.clir = clirMode;
1252             if (uusInfo != null) {
1253                 UusInfo info = new UusInfo();
1254                 info.uusType = uusInfo.getType();
1255                 info.uusDcs = uusInfo.getDcs();
1256                 info.uusData = new String(uusInfo.getUserData());
1257                 dialInfo.uusInfo.add(info);
1258             }
1259 
1260             if (RILJ_LOGD) {
1261                 // Do not log function arg for privacy
1262                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1263             }
1264 
1265             try {
1266                 radioProxy.dial(rr.mSerial, dialInfo);
1267             } catch (RemoteException | RuntimeException e) {
1268                 handleRadioProxyExceptionForRR(rr, "dial", e);
1269             }
1270         }
1271     }
1272 
emergencyDial(String address, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result)1273     private void emergencyDial(String address, EmergencyNumber emergencyNumberInfo,
1274                                boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
1275                                Message result) {
1276         IRadio radioProxy = getRadioProxy(result);
1277         // IRadio V1.4
1278         android.hardware.radio.V1_4.IRadio radioProxy14 =
1279                 (android.hardware.radio.V1_4.IRadio) radioProxy;
1280         if (radioProxy != null) {
1281             RILRequest rr = obtainRequest(RIL_REQUEST_EMERGENCY_DIAL, result,
1282                     mRILDefaultWorkSource);
1283             Dial dialInfo = new Dial();
1284             dialInfo.address = convertNullToEmptyString(address);
1285             dialInfo.clir = clirMode;
1286             if (uusInfo != null) {
1287                 UusInfo info = new UusInfo();
1288                 info.uusType = uusInfo.getType();
1289                 info.uusDcs = uusInfo.getDcs();
1290                 info.uusData = new String(uusInfo.getUserData());
1291                 dialInfo.uusInfo.add(info);
1292             }
1293 
1294             if (RILJ_LOGD) {
1295                 // Do not log function arg for privacy
1296                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1297             }
1298 
1299             try {
1300                 radioProxy14.emergencyDial(rr.mSerial, dialInfo,
1301                         emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
1302                         emergencyNumberInfo.getEmergencyUrns() != null
1303                                 ? new ArrayList(emergencyNumberInfo.getEmergencyUrns())
1304                                 : new ArrayList<>(),
1305                         emergencyNumberInfo.getEmergencyCallRouting(),
1306                         hasKnownUserIntentEmergency,
1307                         emergencyNumberInfo.getEmergencyNumberSourceBitmask()
1308                                 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
1309             } catch (RemoteException | RuntimeException e) {
1310                 handleRadioProxyExceptionForRR(rr, "emergencyDial", e);
1311             }
1312         }
1313     }
1314 
1315     @Override
getIMSI(Message result)1316     public void getIMSI(Message result) {
1317         getIMSIForApp(null, result);
1318     }
1319 
1320     @Override
getIMSIForApp(String aid, Message result)1321     public void getIMSIForApp(String aid, Message result) {
1322         IRadio radioProxy = getRadioProxy(result);
1323         if (radioProxy != null) {
1324             RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result,
1325                     mRILDefaultWorkSource);
1326 
1327             if (RILJ_LOGD) {
1328                 riljLog(rr.serialString()
1329                         + ">  " + requestToString(rr.mRequest) + " aid = " + aid);
1330             }
1331             try {
1332                 radioProxy.getImsiForApp(rr.mSerial, convertNullToEmptyString(aid));
1333             } catch (RemoteException | RuntimeException e) {
1334                 handleRadioProxyExceptionForRR(rr, "getIMSIForApp", e);
1335             }
1336         }
1337     }
1338 
1339     @Override
hangupConnection(int gsmIndex, Message result)1340     public void hangupConnection(int gsmIndex, Message result) {
1341         IRadio radioProxy = getRadioProxy(result);
1342         if (radioProxy != null) {
1343             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP, result,
1344                     mRILDefaultWorkSource);
1345 
1346             if (RILJ_LOGD) {
1347                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " gsmIndex = "
1348                         + gsmIndex);
1349             }
1350 
1351             try {
1352                 radioProxy.hangup(rr.mSerial, gsmIndex);
1353             } catch (RemoteException | RuntimeException e) {
1354                 handleRadioProxyExceptionForRR(rr, "hangupConnection", e);
1355             }
1356         }
1357     }
1358 
1359     @UnsupportedAppUsage
1360     @Override
hangupWaitingOrBackground(Message result)1361     public void hangupWaitingOrBackground(Message result) {
1362         IRadio radioProxy = getRadioProxy(result);
1363         if (radioProxy != null) {
1364             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, result,
1365                     mRILDefaultWorkSource);
1366 
1367             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1368 
1369             try {
1370                 radioProxy.hangupWaitingOrBackground(rr.mSerial);
1371             } catch (RemoteException | RuntimeException e) {
1372                 handleRadioProxyExceptionForRR(rr, "hangupWaitingOrBackground", e);
1373             }
1374         }
1375     }
1376 
1377     @UnsupportedAppUsage
1378     @Override
hangupForegroundResumeBackground(Message result)1379     public void hangupForegroundResumeBackground(Message result) {
1380         IRadio radioProxy = getRadioProxy(result);
1381         if (radioProxy != null) {
1382             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, result,
1383                     mRILDefaultWorkSource);
1384 
1385             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1386 
1387             try {
1388                 radioProxy.hangupForegroundResumeBackground(rr.mSerial);
1389             } catch (RemoteException | RuntimeException e) {
1390                 handleRadioProxyExceptionForRR(rr, "hangupForegroundResumeBackground", e);
1391             }
1392         }
1393     }
1394 
1395     @Override
switchWaitingOrHoldingAndActive(Message result)1396     public void switchWaitingOrHoldingAndActive(Message result) {
1397         IRadio radioProxy = getRadioProxy(result);
1398         if (radioProxy != null) {
1399             RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, result,
1400                     mRILDefaultWorkSource);
1401 
1402             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1403 
1404             try {
1405                 radioProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
1406             } catch (RemoteException | RuntimeException e) {
1407                 handleRadioProxyExceptionForRR(rr, "switchWaitingOrHoldingAndActive", e);
1408             }
1409         }
1410     }
1411 
1412     @Override
conference(Message result)1413     public void conference(Message result) {
1414         IRadio radioProxy = getRadioProxy(result);
1415         if (radioProxy != null) {
1416             RILRequest rr = obtainRequest(RIL_REQUEST_CONFERENCE, result,
1417                     mRILDefaultWorkSource);
1418 
1419             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1420 
1421             try {
1422                 radioProxy.conference(rr.mSerial);
1423             } catch (RemoteException | RuntimeException e) {
1424                 handleRadioProxyExceptionForRR(rr, "conference", e);
1425             }
1426         }
1427     }
1428 
1429     @Override
rejectCall(Message result)1430     public void rejectCall(Message result) {
1431         IRadio radioProxy = getRadioProxy(result);
1432         if (radioProxy != null) {
1433             RILRequest rr = obtainRequest(RIL_REQUEST_UDUB, result,
1434                     mRILDefaultWorkSource);
1435 
1436             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1437 
1438             try {
1439                 radioProxy.rejectCall(rr.mSerial);
1440             } catch (RemoteException | RuntimeException e) {
1441                 handleRadioProxyExceptionForRR(rr, "rejectCall", e);
1442             }
1443         }
1444     }
1445 
1446     @Override
getLastCallFailCause(Message result)1447     public void getLastCallFailCause(Message result) {
1448         IRadio radioProxy = getRadioProxy(result);
1449         if (radioProxy != null) {
1450             RILRequest rr = obtainRequest(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result,
1451                     mRILDefaultWorkSource);
1452 
1453             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1454 
1455             try {
1456                 radioProxy.getLastCallFailCause(rr.mSerial);
1457             } catch (RemoteException | RuntimeException e) {
1458                 handleRadioProxyExceptionForRR(rr, "getLastCallFailCause", e);
1459             }
1460         }
1461     }
1462 
1463     @Override
getSignalStrength(Message result)1464     public void getSignalStrength(Message result) {
1465         IRadio radioProxy = getRadioProxy(result);
1466         if (radioProxy != null) {
1467             RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
1468                     mRILDefaultWorkSource);
1469 
1470             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1471 
1472             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
1473                 android.hardware.radio.V1_4.IRadio radioProxy14 =
1474                         (android.hardware.radio.V1_4.IRadio) radioProxy;
1475                 try {
1476                     radioProxy14.getSignalStrength_1_4(rr.mSerial);
1477                 } catch (RemoteException | RuntimeException e) {
1478                     handleRadioProxyExceptionForRR(rr, "getSignalStrength_1_4", e);
1479                 }
1480             } else {
1481                 try {
1482                     radioProxy.getSignalStrength(rr.mSerial);
1483                 } catch (RemoteException | RuntimeException e) {
1484                     handleRadioProxyExceptionForRR(rr, "getSignalStrength", e);
1485                 }
1486             }
1487         }
1488     }
1489 
1490     @Override
getVoiceRegistrationState(Message result)1491     public void getVoiceRegistrationState(Message result) {
1492         IRadio radioProxy = getRadioProxy(result);
1493         if (radioProxy != null) {
1494             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE, result,
1495                     mRILDefaultWorkSource);
1496 
1497             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1498 
1499             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_VOICE_REGISTRATION_STATE);
1500             if (RILJ_LOGD) {
1501                 riljLog("getVoiceRegistrationState: overrideHalVersion=" + overrideHalVersion);
1502             }
1503             if ((overrideHalVersion == null
1504                         || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
1505                     && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
1506                 final android.hardware.radio.V1_5.IRadio radioProxy15 =
1507                         (android.hardware.radio.V1_5.IRadio) radioProxy;
1508                 try {
1509                     radioProxy15.getVoiceRegistrationState_1_5(rr.mSerial);
1510                 } catch (RemoteException | RuntimeException e) {
1511                     handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState_1_5", e);
1512                 }
1513             } else {
1514                 try {
1515                     radioProxy.getVoiceRegistrationState(rr.mSerial);
1516                 } catch (RemoteException | RuntimeException e) {
1517                     handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState", e);
1518                 }
1519             }
1520         }
1521     }
1522 
1523     @Override
getDataRegistrationState(Message result)1524     public void getDataRegistrationState(Message result) {
1525         IRadio radioProxy = getRadioProxy(result);
1526         if (radioProxy != null) {
1527             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_REGISTRATION_STATE, result,
1528                     mRILDefaultWorkSource);
1529 
1530             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1531 
1532             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_DATA_REGISTRATION_STATE);
1533             if (RILJ_LOGD) {
1534                 riljLog("getDataRegistrationState: overrideHalVersion=" + overrideHalVersion);
1535             }
1536             if ((overrideHalVersion == null
1537                         || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
1538                     && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
1539                 final android.hardware.radio.V1_5.IRadio radioProxy15 =
1540                         (android.hardware.radio.V1_5.IRadio) radioProxy;
1541                 try {
1542                     radioProxy15.getDataRegistrationState_1_5(rr.mSerial);
1543                 } catch (RemoteException | RuntimeException e) {
1544                     handleRadioProxyExceptionForRR(rr, "getDataRegistrationState_1_5", e);
1545                 }
1546             } else {
1547                 try {
1548                     radioProxy.getDataRegistrationState(rr.mSerial);
1549                 } catch (RemoteException | RuntimeException e) {
1550                     handleRadioProxyExceptionForRR(rr, "getDataRegistrationState", e);
1551                 }
1552             }
1553         }
1554     }
1555 
1556     @Override
getOperator(Message result)1557     public void getOperator(Message result) {
1558         IRadio radioProxy = getRadioProxy(result);
1559         if (radioProxy != null) {
1560             RILRequest rr = obtainRequest(RIL_REQUEST_OPERATOR, result,
1561                     mRILDefaultWorkSource);
1562 
1563             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1564 
1565             try {
1566                 radioProxy.getOperator(rr.mSerial);
1567             } catch (RemoteException | RuntimeException e) {
1568                 handleRadioProxyExceptionForRR(rr, "getOperator", e);
1569             }
1570         }
1571     }
1572 
1573     @UnsupportedAppUsage
1574     @Override
setRadioPower(boolean on, boolean forEmergencyCall, boolean preferredForEmergencyCall, Message result)1575     public void setRadioPower(boolean on, boolean forEmergencyCall,
1576             boolean preferredForEmergencyCall, Message result) {
1577         IRadio radioProxy = getRadioProxy(result);
1578         if (radioProxy != null) {
1579             RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result,
1580                     mRILDefaultWorkSource);
1581 
1582             if (RILJ_LOGD) {
1583                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1584                         + " on = " + on + " forEmergencyCall= " + forEmergencyCall
1585                         + " preferredForEmergencyCall="  + preferredForEmergencyCall);
1586             }
1587 
1588             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
1589                 android.hardware.radio.V1_5.IRadio radioProxy15 =
1590                         (android.hardware.radio.V1_5.IRadio) radioProxy;
1591                 try {
1592                     radioProxy15.setRadioPower_1_5(rr.mSerial, on, forEmergencyCall,
1593                             preferredForEmergencyCall);
1594                 } catch (RemoteException | RuntimeException e) {
1595                     handleRadioProxyExceptionForRR(rr, "setRadioPower_1_5", e);
1596                 }
1597             } else {
1598                 try {
1599                     radioProxy.setRadioPower(rr.mSerial, on);
1600                 } catch (RemoteException | RuntimeException e) {
1601                     handleRadioProxyExceptionForRR(rr, "setRadioPower", e);
1602                 }
1603             }
1604         }
1605     }
1606 
1607     @Override
sendDtmf(char c, Message result)1608     public void sendDtmf(char c, Message result) {
1609         IRadio radioProxy = getRadioProxy(result);
1610         if (radioProxy != null) {
1611             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF, result,
1612                     mRILDefaultWorkSource);
1613 
1614             if (RILJ_LOGD) {
1615                 // Do not log function arg for privacy
1616                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1617             }
1618 
1619             try {
1620                 radioProxy.sendDtmf(rr.mSerial, c + "");
1621             } catch (RemoteException | RuntimeException e) {
1622                 handleRadioProxyExceptionForRR(rr, "sendDtmf", e);
1623             }
1624         }
1625     }
1626 
constructGsmSendSmsRilRequest(String smscPdu, String pdu)1627     private GsmSmsMessage constructGsmSendSmsRilRequest(String smscPdu, String pdu) {
1628         GsmSmsMessage msg = new GsmSmsMessage();
1629         msg.smscPdu = smscPdu == null ? "" : smscPdu;
1630         msg.pdu = pdu == null ? "" : pdu;
1631         return msg;
1632     }
1633 
1634     @Override
sendSMS(String smscPdu, String pdu, Message result)1635     public void sendSMS(String smscPdu, String pdu, Message result) {
1636         IRadio radioProxy = getRadioProxy(result);
1637         if (radioProxy != null) {
1638             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS, result,
1639                     mRILDefaultWorkSource);
1640 
1641             // Do not log function args for privacy
1642             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1643 
1644             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
1645 
1646             try {
1647                 radioProxy.sendSms(rr.mSerial, msg);
1648                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
1649                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
1650             } catch (RemoteException | RuntimeException e) {
1651                 handleRadioProxyExceptionForRR(rr, "sendSMS", e);
1652             }
1653         }
1654     }
1655 
1656     @Override
sendSMSExpectMore(String smscPdu, String pdu, Message result)1657     public void sendSMSExpectMore(String smscPdu, String pdu, Message result) {
1658         IRadio radioProxy = getRadioProxy(result);
1659         if (radioProxy != null) {
1660             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS_EXPECT_MORE, result,
1661                     mRILDefaultWorkSource);
1662 
1663             // Do not log function arg for privacy
1664             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1665 
1666             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
1667 
1668             try {
1669                 radioProxy.sendSMSExpectMore(rr.mSerial, msg);
1670                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
1671                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
1672             } catch (RemoteException | RuntimeException e) {
1673                 handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
1674             }
1675         }
1676     }
1677 
1678     /**
1679      * Convert MVNO type string into MvnoType defined in types.hal.
1680      * @param mvnoType MVNO type
1681      * @return MVNO type in integer
1682      */
convertToHalMvnoType(String mvnoType)1683     private static int convertToHalMvnoType(String mvnoType) {
1684         switch (mvnoType) {
1685             case "imsi" : return MvnoType.IMSI;
1686             case "gid" : return MvnoType.GID;
1687             case "spn" : return MvnoType.SPN;
1688             default: return MvnoType.NONE;
1689         }
1690     }
1691 
1692     /**
1693      * Convert to DataProfileInfo defined in radio/1.0/types.hal
1694      * @param dp Data profile
1695      * @return A converted data profile
1696      */
convertToHalDataProfile10( DataProfile dp)1697     private static android.hardware.radio.V1_0.DataProfileInfo convertToHalDataProfile10(
1698             DataProfile dp) {
1699         android.hardware.radio.V1_0.DataProfileInfo dpi =
1700                 new android.hardware.radio.V1_0.DataProfileInfo();
1701 
1702         dpi.profileId = dp.getProfileId();
1703         dpi.apn = dp.getApn();
1704         dpi.protocol = ApnSetting.getProtocolStringFromInt(dp.getProtocolType());
1705         dpi.roamingProtocol = ApnSetting.getProtocolStringFromInt(dp.getRoamingProtocolType());
1706         dpi.authType = dp.getAuthType();
1707         dpi.user = dp.getUserName();
1708         dpi.password = dp.getPassword();
1709         dpi.type = dp.getType();
1710         dpi.maxConnsTime = dp.getMaxConnectionsTime();
1711         dpi.maxConns = dp.getMaxConnections();
1712         dpi.waitTime = dp.getWaitTime();
1713         dpi.enabled = dp.isEnabled();
1714         dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
1715         // Shift by 1 bit due to the discrepancy between
1716         // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
1717         // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
1718         dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
1719                 dp.getBearerBitmask()) << 1;
1720         dpi.mtu = dp.getMtuV4();
1721         dpi.mvnoType = MvnoType.NONE;
1722         dpi.mvnoMatchData = "";
1723 
1724         return dpi;
1725     }
1726 
1727     /**
1728      * Convert to DataProfileInfo defined in radio/1.4/types.hal
1729      * @param dp Data profile
1730      * @return A converted data profile
1731      */
convertToHalDataProfile14( DataProfile dp)1732     private static android.hardware.radio.V1_4.DataProfileInfo convertToHalDataProfile14(
1733             DataProfile dp) {
1734         android.hardware.radio.V1_4.DataProfileInfo dpi =
1735                 new android.hardware.radio.V1_4.DataProfileInfo();
1736 
1737         dpi.apn = dp.getApn();
1738         dpi.protocol = dp.getProtocolType();
1739         dpi.roamingProtocol = dp.getRoamingProtocolType();
1740         dpi.authType = dp.getAuthType();
1741         dpi.user = dp.getUserName();
1742         dpi.password = dp.getPassword();
1743         dpi.type = dp.getType();
1744         dpi.maxConnsTime = dp.getMaxConnectionsTime();
1745         dpi.maxConns = dp.getMaxConnections();
1746         dpi.waitTime = dp.getWaitTime();
1747         dpi.enabled = dp.isEnabled();
1748         dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
1749         // Shift by 1 bit due to the discrepancy between
1750         // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
1751         // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
1752         dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
1753                 dp.getBearerBitmask()) << 1;
1754         dpi.mtu = dp.getMtuV4();
1755         dpi.persistent = dp.isPersistent();
1756         dpi.preferred = dp.isPreferred();
1757 
1758         // profile id is only meaningful when it's persistent on the modem.
1759         dpi.profileId = (dpi.persistent) ? dp.getProfileId() : DataProfileId.INVALID;
1760 
1761         return dpi;
1762     }
1763 
1764     /**
1765      * Convert to DataProfileInfo defined in radio/1.5/types.hal
1766      * @param dp Data profile
1767      * @return A converted data profile
1768      */
convertToHalDataProfile15( DataProfile dp)1769     private static android.hardware.radio.V1_5.DataProfileInfo convertToHalDataProfile15(
1770             DataProfile dp) {
1771         android.hardware.radio.V1_5.DataProfileInfo dpi =
1772                 new android.hardware.radio.V1_5.DataProfileInfo();
1773 
1774         dpi.apn = dp.getApn();
1775         dpi.protocol = dp.getProtocolType();
1776         dpi.roamingProtocol = dp.getRoamingProtocolType();
1777         dpi.authType = dp.getAuthType();
1778         dpi.user = dp.getUserName();
1779         dpi.password = dp.getPassword();
1780         dpi.type = dp.getType();
1781         dpi.maxConnsTime = dp.getMaxConnectionsTime();
1782         dpi.maxConns = dp.getMaxConnections();
1783         dpi.waitTime = dp.getWaitTime();
1784         dpi.enabled = dp.isEnabled();
1785         dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
1786         // Shift by 1 bit due to the discrepancy between
1787         // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
1788         // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
1789         dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
1790             dp.getBearerBitmask()) << 1;
1791         dpi.mtuV4 = dp.getMtuV4();
1792         dpi.mtuV6 = dp.getMtuV6();
1793         dpi.persistent = dp.isPersistent();
1794         dpi.preferred = dp.isPreferred();
1795 
1796         // profile id is only meaningful when it's persistent on the modem.
1797         dpi.profileId = (dpi.persistent) ? dp.getProfileId() : DataProfileId.INVALID;
1798 
1799         return dpi;
1800     }
1801 
1802     /**
1803      * Convert NV reset type into ResetNvType defined in types.hal.
1804      * @param resetType NV reset type.
1805      * @return Converted reset type in integer or -1 if param is invalid.
1806      */
convertToHalResetNvType(int resetType)1807     private static int convertToHalResetNvType(int resetType) {
1808         /**
1809          * resetType values
1810          * 1 - reload all NV items
1811          * 2 - erase NV reset (SCRTN)
1812          * 3 - factory reset (RTN)
1813          */
1814         switch (resetType) {
1815             case 1: return ResetNvType.RELOAD;
1816             case 2: return ResetNvType.ERASE;
1817             case 3: return ResetNvType.FACTORY_RESET;
1818         }
1819         return -1;
1820     }
1821 
1822     @Override
setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, LinkProperties linkProperties, Message result)1823     public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
1824                               boolean allowRoaming, int reason, LinkProperties linkProperties,
1825                               Message result) {
1826 
1827         IRadio radioProxy = getRadioProxy(result);
1828 
1829         if (radioProxy != null) {
1830 
1831             RILRequest rr = obtainRequest(RIL_REQUEST_SETUP_DATA_CALL, result,
1832                     mRILDefaultWorkSource);
1833 
1834             ArrayList<String> addresses = new ArrayList<>();
1835             ArrayList<String> dnses = new ArrayList<>();
1836             if (linkProperties != null) {
1837                 for (InetAddress address : linkProperties.getAddresses()) {
1838                     addresses.add(address.getHostAddress());
1839                 }
1840                 for (InetAddress dns : linkProperties.getDnsServers()) {
1841                     dnses.add(dns.getHostAddress());
1842                 }
1843             }
1844 
1845             try {
1846                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
1847                     // IRadio V1.5
1848                     android.hardware.radio.V1_5.IRadio radioProxy15 =
1849                             (android.hardware.radio.V1_5.IRadio) radioProxy;
1850 
1851                     // Convert to HAL data profile
1852                     android.hardware.radio.V1_5.DataProfileInfo dpi =
1853                             convertToHalDataProfile15(dataProfile);
1854 
1855                     ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 =
1856                             new ArrayList<>();
1857                     if (linkProperties != null) {
1858                         for (LinkAddress la : linkProperties.getAllLinkAddresses()) {
1859                             android.hardware.radio.V1_5.LinkAddress linkAddress =
1860                                     new android.hardware.radio.V1_5.LinkAddress();
1861                             linkAddress.address = la.getAddress().getHostAddress();
1862                             linkAddress.properties = la.getFlags();
1863                             linkAddress.deprecationTime = la.getDeprecationTime();
1864                             linkAddress.expirationTime = la.getExpirationTime();
1865                             addresses15.add(linkAddress);
1866                         }
1867                     }
1868 
1869                     if (RILJ_LOGD) {
1870                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1871                                 + ",accessNetworkType="
1872                                 + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
1873                                 + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
1874                                 + ",addresses=" + addresses15 + ",dnses=" + dnses);
1875                     }
1876 
1877                     radioProxy15.setupDataCall_1_5(rr.mSerial, accessNetworkType, dpi, allowRoaming,
1878                             reason, addresses15, dnses);
1879                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
1880                     // IRadio V1.4
1881                     android.hardware.radio.V1_4.IRadio radioProxy14 =
1882                             (android.hardware.radio.V1_4.IRadio) radioProxy;
1883 
1884                     // Convert to HAL data profile
1885                     android.hardware.radio.V1_4.DataProfileInfo dpi =
1886                             convertToHalDataProfile14(dataProfile);
1887 
1888                     if (RILJ_LOGD) {
1889                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1890                                 + ",accessNetworkType="
1891                                 + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
1892                                 + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
1893                                 + ",addresses=" + addresses + ",dnses=" + dnses);
1894                     }
1895 
1896                     radioProxy14.setupDataCall_1_4(rr.mSerial, accessNetworkType, dpi, allowRoaming,
1897                             reason, addresses, dnses);
1898                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
1899                     // IRadio V1.2 and IRadio V1.3
1900                     android.hardware.radio.V1_2.IRadio radioProxy12 =
1901                             (android.hardware.radio.V1_2.IRadio) radioProxy;
1902 
1903                     // Convert to HAL data profile
1904                     android.hardware.radio.V1_0.DataProfileInfo dpi =
1905                             convertToHalDataProfile10(dataProfile);
1906 
1907                     if (RILJ_LOGD) {
1908                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1909                                 + ",accessNetworkType="
1910                                 + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
1911                                 + isRoaming + ",allowRoaming=" + allowRoaming + ","
1912                                 + dataProfile + ",addresses=" + addresses + ",dnses=" + dnses);
1913                     }
1914 
1915                     radioProxy12.setupDataCall_1_2(rr.mSerial, accessNetworkType, dpi,
1916                             dataProfile.isPersistent(), allowRoaming, isRoaming, reason,
1917                             addresses, dnses);
1918                 } else {
1919                     // IRadio V1.0 and IRadio V1.1
1920 
1921                     // Convert to HAL data profile
1922                     android.hardware.radio.V1_0.DataProfileInfo dpi =
1923                             convertToHalDataProfile10(dataProfile);
1924 
1925                     // Getting data RAT here is just a workaround to support the older 1.0
1926                     // vendor RIL. The new data service interface passes access network type
1927                     // instead of RAT for setup data request. It is impossible to convert access
1928                     // network type back to RAT here, so we directly get the data RAT from
1929                     // phone.
1930                     int dataRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
1931                     Phone phone = PhoneFactory.getPhone(mPhoneId);
1932                     if (phone != null) {
1933                         ServiceState ss = phone.getServiceState();
1934                         if (ss != null) {
1935                             dataRat = ss.getRilDataRadioTechnology();
1936                         }
1937                     }
1938                     if (RILJ_LOGD) {
1939                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1940                                 + ",dataRat=" + dataRat + ",isRoaming=" + isRoaming
1941                                 + ",allowRoaming=" + allowRoaming + "," + dataProfile);
1942                     }
1943 
1944                     radioProxy.setupDataCall(rr.mSerial, dataRat, dpi,
1945                             dataProfile.isPersistent(), allowRoaming, isRoaming);
1946                 }
1947             } catch (RemoteException | RuntimeException e) {
1948                 handleRadioProxyExceptionForRR(rr, "setupDataCall", e);
1949             }
1950         }
1951     }
1952 
1953     @Override
iccIO(int command, int fileId, String path, int p1, int p2, int p3, String data, String pin2, Message result)1954     public void iccIO(int command, int fileId, String path, int p1, int p2, int p3,
1955                       String data, String pin2, Message result) {
1956         iccIOForApp(command, fileId, path, p1, p2, p3, data, pin2, null, result);
1957     }
1958 
1959     @Override
iccIOForApp(int command, int fileId, String path, int p1, int p2, int p3, String data, String pin2, String aid, Message result)1960     public void iccIOForApp(int command, int fileId, String path, int p1, int p2, int p3,
1961                  String data, String pin2, String aid, Message result) {
1962         IRadio radioProxy = getRadioProxy(result);
1963         if (radioProxy != null) {
1964             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_IO, result,
1965                     mRILDefaultWorkSource);
1966 
1967             if (RILJ_LOGD) {
1968                 if (TelephonyUtils.IS_DEBUGGABLE) {
1969                     riljLog(rr.serialString() + "> iccIO: "
1970                             + requestToString(rr.mRequest) + " command = 0x"
1971                             + Integer.toHexString(command) + " fileId = 0x"
1972                             + Integer.toHexString(fileId) + " path = " + path + " p1 = "
1973                             + p1 + " p2 = " + p2 + " p3 = " + " data = " + data
1974                             + " aid = " + aid);
1975                 } else {
1976                     riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest));
1977                 }
1978             }
1979 
1980             IccIo iccIo = new IccIo();
1981             iccIo.command = command;
1982             iccIo.fileId = fileId;
1983             iccIo.path = convertNullToEmptyString(path);
1984             iccIo.p1 = p1;
1985             iccIo.p2 = p2;
1986             iccIo.p3 = p3;
1987             iccIo.data = convertNullToEmptyString(data);
1988             iccIo.pin2 = convertNullToEmptyString(pin2);
1989             iccIo.aid = convertNullToEmptyString(aid);
1990 
1991             try {
1992                 radioProxy.iccIOForApp(rr.mSerial, iccIo);
1993             } catch (RemoteException | RuntimeException e) {
1994                 handleRadioProxyExceptionForRR(rr, "iccIOForApp", e);
1995             }
1996         }
1997     }
1998 
1999     @Override
sendUSSD(String ussd, Message result)2000     public void sendUSSD(String ussd, Message result) {
2001         IRadio radioProxy = getRadioProxy(result);
2002         if (radioProxy != null) {
2003             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_USSD, result,
2004                     mRILDefaultWorkSource);
2005 
2006             if (RILJ_LOGD) {
2007                 String logUssd = "*******";
2008                 if (RILJ_LOGV) logUssd = ussd;
2009                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2010                         + " ussd = " + logUssd);
2011             }
2012 
2013             try {
2014                 radioProxy.sendUssd(rr.mSerial, convertNullToEmptyString(ussd));
2015             } catch (RemoteException | RuntimeException e) {
2016                 handleRadioProxyExceptionForRR(rr, "sendUSSD", e);
2017             }
2018         }
2019     }
2020 
2021     @Override
cancelPendingUssd(Message result)2022     public void cancelPendingUssd(Message result) {
2023         IRadio radioProxy = getRadioProxy(result);
2024         if (radioProxy != null) {
2025             RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_USSD, result,
2026                     mRILDefaultWorkSource);
2027 
2028             if (RILJ_LOGD) {
2029                 riljLog(rr.serialString()
2030                         + "> " + requestToString(rr.mRequest));
2031             }
2032 
2033             try {
2034                 radioProxy.cancelPendingUssd(rr.mSerial);
2035             } catch (RemoteException | RuntimeException e) {
2036                 handleRadioProxyExceptionForRR(rr, "cancelPendingUssd", e);
2037             }
2038         }
2039     }
2040 
2041     @Override
getCLIR(Message result)2042     public void getCLIR(Message result) {
2043         IRadio radioProxy = getRadioProxy(result);
2044         if (radioProxy != null) {
2045             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CLIR, result,
2046                     mRILDefaultWorkSource);
2047 
2048             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2049 
2050             try {
2051                 radioProxy.getClir(rr.mSerial);
2052             } catch (RemoteException | RuntimeException e) {
2053                 handleRadioProxyExceptionForRR(rr, "getCLIR", e);
2054             }
2055         }
2056     }
2057 
2058     @Override
setCLIR(int clirMode, Message result)2059     public void setCLIR(int clirMode, Message result) {
2060         IRadio radioProxy = getRadioProxy(result);
2061         if (radioProxy != null) {
2062             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CLIR, result, mRILDefaultWorkSource);
2063 
2064             if (RILJ_LOGD) {
2065                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2066                         + " clirMode = " + clirMode);
2067             }
2068 
2069             try {
2070                 radioProxy.setClir(rr.mSerial, clirMode);
2071             } catch (RemoteException | RuntimeException e) {
2072                 handleRadioProxyExceptionForRR(rr, "setCLIR", e);
2073             }
2074         }
2075     }
2076 
2077     @Override
queryCallForwardStatus(int cfReason, int serviceClass, String number, Message result)2078     public void queryCallForwardStatus(int cfReason, int serviceClass,
2079                            String number, Message result) {
2080         IRadio radioProxy = getRadioProxy(result);
2081         if (radioProxy != null) {
2082             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
2083                     mRILDefaultWorkSource);
2084 
2085             if (RILJ_LOGD) {
2086                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2087                         + " cfreason = " + cfReason + " serviceClass = " + serviceClass);
2088             }
2089 
2090             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
2091                     new android.hardware.radio.V1_0.CallForwardInfo();
2092             cfInfo.reason = cfReason;
2093             cfInfo.serviceClass = serviceClass;
2094             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
2095             cfInfo.number = convertNullToEmptyString(number);
2096             cfInfo.timeSeconds = 0;
2097 
2098             try {
2099                 radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
2100             } catch (RemoteException | RuntimeException e) {
2101                 handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
2102             }
2103         }
2104     }
2105 
2106     @Override
setCallForward(int action, int cfReason, int serviceClass, String number, int timeSeconds, Message result)2107     public void setCallForward(int action, int cfReason, int serviceClass,
2108                    String number, int timeSeconds, Message result) {
2109         IRadio radioProxy = getRadioProxy(result);
2110         if (radioProxy != null) {
2111             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_FORWARD, result,
2112                     mRILDefaultWorkSource);
2113 
2114             if (RILJ_LOGD) {
2115                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2116                         + " action = " + action + " cfReason = " + cfReason + " serviceClass = "
2117                         + serviceClass + " timeSeconds = " + timeSeconds);
2118             }
2119 
2120             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
2121                     new android.hardware.radio.V1_0.CallForwardInfo();
2122             cfInfo.status = action;
2123             cfInfo.reason = cfReason;
2124             cfInfo.serviceClass = serviceClass;
2125             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
2126             cfInfo.number = convertNullToEmptyString(number);
2127             cfInfo.timeSeconds = timeSeconds;
2128 
2129             try {
2130                 radioProxy.setCallForward(rr.mSerial, cfInfo);
2131             } catch (RemoteException | RuntimeException e) {
2132                 handleRadioProxyExceptionForRR(rr, "setCallForward", e);
2133 
2134             }
2135         }
2136     }
2137 
2138     @Override
queryCallWaiting(int serviceClass, Message result)2139     public void queryCallWaiting(int serviceClass, Message result) {
2140         IRadio radioProxy = getRadioProxy(result);
2141         if (radioProxy != null) {
2142             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_WAITING, result,
2143                     mRILDefaultWorkSource);
2144 
2145             if (RILJ_LOGD) {
2146                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2147                         + " serviceClass = " + serviceClass);
2148             }
2149 
2150             try {
2151                 radioProxy.getCallWaiting(rr.mSerial, serviceClass);
2152             } catch (RemoteException | RuntimeException e) {
2153                 handleRadioProxyExceptionForRR(rr, "queryCallWaiting", e);
2154             }
2155         }
2156     }
2157 
2158     @Override
setCallWaiting(boolean enable, int serviceClass, Message result)2159     public void setCallWaiting(boolean enable, int serviceClass, Message result) {
2160         IRadio radioProxy = getRadioProxy(result);
2161         if (radioProxy != null) {
2162             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_WAITING, result,
2163                     mRILDefaultWorkSource);
2164 
2165             if (RILJ_LOGD) {
2166                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2167                         + " enable = " + enable + " serviceClass = " + serviceClass);
2168             }
2169 
2170             try {
2171                 radioProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
2172             } catch (RemoteException | RuntimeException e) {
2173                 handleRadioProxyExceptionForRR(rr, "setCallWaiting", e);
2174             }
2175         }
2176     }
2177 
2178     @Override
acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result)2179     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
2180         IRadio radioProxy = getRadioProxy(result);
2181         if (radioProxy != null) {
2182             RILRequest rr = obtainRequest(RIL_REQUEST_SMS_ACKNOWLEDGE, result,
2183                     mRILDefaultWorkSource);
2184 
2185             if (RILJ_LOGD) {
2186                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2187                         + " success = " + success + " cause = " + cause);
2188             }
2189 
2190             try {
2191                 radioProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
2192             } catch (RemoteException | RuntimeException e) {
2193                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingGsmSms", e);
2194             }
2195         }
2196     }
2197 
2198     @Override
acceptCall(Message result)2199     public void acceptCall(Message result) {
2200         IRadio radioProxy = getRadioProxy(result);
2201         if (radioProxy != null) {
2202             RILRequest rr = obtainRequest(RIL_REQUEST_ANSWER, result,
2203                     mRILDefaultWorkSource);
2204 
2205             if (RILJ_LOGD) {
2206                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2207             }
2208 
2209             try {
2210                 radioProxy.acceptCall(rr.mSerial);
2211                 mMetrics.writeRilAnswer(mPhoneId, rr.mSerial);
2212             } catch (RemoteException | RuntimeException e) {
2213                 handleRadioProxyExceptionForRR(rr, "acceptCall", e);
2214             }
2215         }
2216     }
2217 
2218     @Override
deactivateDataCall(int cid, int reason, Message result)2219     public void deactivateDataCall(int cid, int reason, Message result) {
2220         IRadio radioProxy = getRadioProxy(result);
2221         if (radioProxy != null) {
2222             RILRequest rr = obtainRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, result,
2223                     mRILDefaultWorkSource);
2224 
2225             if (RILJ_LOGD) {
2226                 riljLog(rr.serialString() + "> "
2227                         + requestToString(rr.mRequest) + " cid = " + cid + " reason = " + reason);
2228             }
2229 
2230             try {
2231                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
2232                     android.hardware.radio.V1_2.IRadio radioProxy12 =
2233                             (android.hardware.radio.V1_2.IRadio) radioProxy;
2234 
2235                     radioProxy12.deactivateDataCall_1_2(rr.mSerial, cid, reason);
2236                 } else {
2237                     radioProxy.deactivateDataCall(rr.mSerial, cid,
2238                             (reason == DataService.REQUEST_REASON_SHUTDOWN));
2239                 }
2240                 mMetrics.writeRilDeactivateDataCall(mPhoneId, rr.mSerial, cid, reason);
2241             } catch (RemoteException | RuntimeException e) {
2242                 handleRadioProxyExceptionForRR(rr, "deactivateDataCall", e);
2243             }
2244         }
2245     }
2246 
2247     @Override
queryFacilityLock(String facility, String password, int serviceClass, Message result)2248     public void queryFacilityLock(String facility, String password, int serviceClass,
2249                                   Message result) {
2250         queryFacilityLockForApp(facility, password, serviceClass, null, result);
2251     }
2252 
2253     @Override
queryFacilityLockForApp(String facility, String password, int serviceClass, String appId, Message result)2254     public void queryFacilityLockForApp(String facility, String password, int serviceClass,
2255                                         String appId, Message result) {
2256         IRadio radioProxy = getRadioProxy(result);
2257         if (radioProxy != null) {
2258             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_FACILITY_LOCK, result,
2259                     mRILDefaultWorkSource);
2260 
2261             if (RILJ_LOGD) {
2262                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2263                         + " facility = " + facility + " serviceClass = " + serviceClass
2264                         + " appId = " + appId);
2265             }
2266 
2267             try {
2268                 radioProxy.getFacilityLockForApp(rr.mSerial,
2269                         convertNullToEmptyString(facility),
2270                         convertNullToEmptyString(password),
2271                         serviceClass,
2272                         convertNullToEmptyString(appId));
2273             } catch (RemoteException | RuntimeException e) {
2274                 handleRadioProxyExceptionForRR(rr, "getFacilityLockForApp", e);
2275             }
2276         }
2277     }
2278 
2279     @Override
setFacilityLock(String facility, boolean lockState, String password, int serviceClass, Message result)2280     public void setFacilityLock(String facility, boolean lockState, String password,
2281                                 int serviceClass, Message result) {
2282         setFacilityLockForApp(facility, lockState, password, serviceClass, null, result);
2283     }
2284 
2285     @Override
setFacilityLockForApp(String facility, boolean lockState, String password, int serviceClass, String appId, Message result)2286     public void setFacilityLockForApp(String facility, boolean lockState, String password,
2287                                       int serviceClass, String appId, Message result) {
2288         IRadio radioProxy = getRadioProxy(result);
2289         if (radioProxy != null) {
2290             RILRequest rr = obtainRequest(RIL_REQUEST_SET_FACILITY_LOCK, result,
2291                     mRILDefaultWorkSource);
2292 
2293             if (RILJ_LOGD) {
2294                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2295                         + " facility = " + facility + " lockstate = " + lockState
2296                         + " serviceClass = " + serviceClass + " appId = " + appId);
2297             }
2298 
2299             try {
2300                 radioProxy.setFacilityLockForApp(rr.mSerial,
2301                         convertNullToEmptyString(facility),
2302                         lockState,
2303                         convertNullToEmptyString(password),
2304                         serviceClass,
2305                         convertNullToEmptyString(appId));
2306             } catch (RemoteException | RuntimeException e) {
2307                 handleRadioProxyExceptionForRR(rr, "setFacilityLockForApp", e);
2308             }
2309         }
2310     }
2311 
2312     @Override
changeBarringPassword(String facility, String oldPwd, String newPwd, Message result)2313     public void changeBarringPassword(String facility, String oldPwd, String newPwd,
2314                                       Message result) {
2315         IRadio radioProxy = getRadioProxy(result);
2316         if (radioProxy != null) {
2317             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result,
2318                     mRILDefaultWorkSource);
2319 
2320             // Do not log all function args for privacy
2321             if (RILJ_LOGD) {
2322                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2323                         + "facility = " + facility);
2324             }
2325 
2326             try {
2327                 radioProxy.setBarringPassword(rr.mSerial,
2328                         convertNullToEmptyString(facility),
2329                         convertNullToEmptyString(oldPwd),
2330                         convertNullToEmptyString(newPwd));
2331             } catch (RemoteException | RuntimeException e) {
2332                 handleRadioProxyExceptionForRR(rr, "changeBarringPassword", e);
2333             }
2334         }
2335     }
2336 
2337     @Override
getNetworkSelectionMode(Message result)2338     public void getNetworkSelectionMode(Message result) {
2339         IRadio radioProxy = getRadioProxy(result);
2340         if (radioProxy != null) {
2341             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, result,
2342                     mRILDefaultWorkSource);
2343 
2344             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2345 
2346             try {
2347                 radioProxy.getNetworkSelectionMode(rr.mSerial);
2348             } catch (RemoteException | RuntimeException e) {
2349                 handleRadioProxyExceptionForRR(rr, "getNetworkSelectionMode", e);
2350             }
2351         }
2352     }
2353 
2354     @Override
setNetworkSelectionModeAutomatic(Message result)2355     public void setNetworkSelectionModeAutomatic(Message result) {
2356         IRadio radioProxy = getRadioProxy(result);
2357         if (radioProxy != null) {
2358             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, result,
2359                     mRILDefaultWorkSource);
2360 
2361             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2362 
2363             try {
2364                 radioProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
2365             } catch (RemoteException | RuntimeException e) {
2366                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeAutomatic", e);
2367             }
2368         }
2369     }
2370 
2371     @Override
setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result)2372     public void setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result) {
2373         IRadio radioProxy = getRadioProxy(result);
2374         if (radioProxy != null) {
2375             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, result,
2376                     mRILDefaultWorkSource);
2377             try {
2378                 int halRan = convertAntToRan(ran);
2379                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
2380                     android.hardware.radio.V1_5.IRadio radioProxy15 =
2381                             (android.hardware.radio.V1_5.IRadio) radioProxy;
2382                     if (RILJ_LOGD) {
2383                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2384                                 + " operatorNumeric = " + operatorNumeric
2385                                 + ", ran = " + halRan);
2386                     }
2387                     radioProxy15.setNetworkSelectionModeManual_1_5(rr.mSerial,
2388                             convertNullToEmptyString(operatorNumeric), halRan);
2389                 } else {
2390                     if (RILJ_LOGD) {
2391                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2392                                 + " operatorNumeric = " + operatorNumeric);
2393                     }
2394                     radioProxy.setNetworkSelectionModeManual(rr.mSerial,
2395                             convertNullToEmptyString(operatorNumeric));
2396                 }
2397             } catch (RemoteException | RuntimeException e) {
2398                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeManual", e);
2399             }
2400         }
2401     }
2402 
2403     @Override
getAvailableNetworks(Message result)2404     public void getAvailableNetworks(Message result) {
2405         IRadio radioProxy = getRadioProxy(result);
2406         if (radioProxy != null) {
2407             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, result,
2408                     mRILDefaultWorkSource);
2409 
2410             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2411 
2412             try {
2413                 radioProxy.getAvailableNetworks(rr.mSerial);
2414             } catch (RemoteException | RuntimeException e) {
2415                 handleRadioProxyExceptionForRR(rr, "getAvailableNetworks", e);
2416             }
2417         }
2418     }
2419 
convertRadioAccessSpecifierToRadioHAL( RadioAccessSpecifier ras)2420     private android.hardware.radio.V1_1.RadioAccessSpecifier convertRadioAccessSpecifierToRadioHAL(
2421             RadioAccessSpecifier ras) {
2422         android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
2423                 new android.hardware.radio.V1_1.RadioAccessSpecifier();
2424         rasInHalFormat.radioAccessNetwork = ras.getRadioAccessNetwork();
2425         ArrayList<Integer> bands = new ArrayList<>();
2426         if (ras.getBands() != null) {
2427             for (int band : ras.getBands()) {
2428                 bands.add(band);
2429             }
2430         }
2431         switch (ras.getRadioAccessNetwork()) {
2432             case AccessNetworkType.GERAN:
2433                 rasInHalFormat.geranBands = bands;
2434                 break;
2435             case AccessNetworkType.UTRAN:
2436                 rasInHalFormat.utranBands = bands;
2437                 break;
2438             case AccessNetworkType.EUTRAN:
2439                 rasInHalFormat.eutranBands = bands;
2440                 break;
2441             default:
2442                 Log.wtf(RILJ_LOG_TAG, "radioAccessNetwork " + ras.getRadioAccessNetwork()
2443                         + " not supported on IRadio < 1.5!");
2444                 return null;
2445         }
2446 
2447         if (ras.getChannels() != null) {
2448             for (int channel : ras.getChannels()) {
2449                 rasInHalFormat.channels.add(channel);
2450             }
2451         }
2452 
2453         return rasInHalFormat;
2454     }
2455 
2456     private android.hardware.radio.V1_5.RadioAccessSpecifier
convertRadioAccessSpecifierToRadioHAL_1_5(RadioAccessSpecifier ras)2457             convertRadioAccessSpecifierToRadioHAL_1_5(RadioAccessSpecifier ras) {
2458         android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
2459                 new android.hardware.radio.V1_5.RadioAccessSpecifier();
2460         android.hardware.radio.V1_5.RadioAccessSpecifier.Bands bandsInHalFormat =
2461                 new android.hardware.radio.V1_5.RadioAccessSpecifier.Bands();
2462         rasInHalFormat.radioAccessNetwork = convertAntToRan(ras.getRadioAccessNetwork());
2463         ArrayList<Integer> bands = new ArrayList<>();
2464         if (ras.getBands() != null) {
2465             for (int band : ras.getBands()) {
2466                 bands.add(band);
2467             }
2468         }
2469         switch (ras.getRadioAccessNetwork()) {
2470             case AccessNetworkType.GERAN:
2471                 bandsInHalFormat.geranBands(bands);
2472                 break;
2473             case AccessNetworkType.UTRAN:
2474                 bandsInHalFormat.utranBands(bands);
2475                 break;
2476             case AccessNetworkType.EUTRAN:
2477                 bandsInHalFormat.eutranBands(bands);
2478                 break;
2479             case AccessNetworkType.NGRAN:
2480                 bandsInHalFormat.ngranBands(bands);
2481                 break;
2482             default:
2483                 Log.wtf(RILJ_LOG_TAG, "radioAccessNetwork " + ras.getRadioAccessNetwork()
2484                         + " not supported on IRadio 1.5!");
2485                 return null;
2486         }
2487         rasInHalFormat.bands = bandsInHalFormat;
2488 
2489         if (ras.getChannels() != null) {
2490             for (int channel : ras.getChannels()) {
2491                 rasInHalFormat.channels.add(channel);
2492             }
2493         }
2494 
2495         return rasInHalFormat;
2496     }
2497 
2498     /**
2499      * Radio HAL fallback compatibility feature (b/151106728) assumes that the input parameter
2500      * networkScanRequest is immutable (read-only) here. Once the caller invokes the method, the
2501      * parameter networkScanRequest should not be modified. This helps us keep a consistent and
2502      * simple data model that avoid copying it in the scan result.
2503      */
2504     @Override
startNetworkScan(NetworkScanRequest networkScanRequest, Message result)2505     public void startNetworkScan(NetworkScanRequest networkScanRequest, Message result) {
2506         final NetworkScanRequest nsr = networkScanRequest;
2507         IRadio radioProxy = getRadioProxy(result);
2508         if (radioProxy != null) {
2509 
2510             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_START_NETWORK_SCAN);
2511             if (RILJ_LOGD) {
2512                 riljLog("startNetworkScan: overrideHalVersion=" + overrideHalVersion);
2513             }
2514             if ((overrideHalVersion == null
2515                         || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
2516                     && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
2517                 android.hardware.radio.V1_5.NetworkScanRequest request =
2518                         new android.hardware.radio.V1_5.NetworkScanRequest();
2519                 request.type = nsr.getScanType();
2520                 request.interval = nsr.getSearchPeriodicity();
2521                 request.maxSearchTime = nsr.getMaxSearchTime();
2522                 request.incrementalResultsPeriodicity = nsr.getIncrementalResultsPeriodicity();
2523                 request.incrementalResults = nsr.getIncrementalResults();
2524 
2525                 for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
2526                     android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
2527                             convertRadioAccessSpecifierToRadioHAL_1_5(ras);
2528                     if (rasInHalFormat == null) {
2529                         AsyncResult.forMessage(result, null,
2530                                 CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
2531                         result.sendToTarget();
2532                         return;
2533                     }
2534                     request.specifiers.add(rasInHalFormat);
2535                 }
2536 
2537                 request.mccMncs.addAll(nsr.getPlmns());
2538                 RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
2539                         mRILDefaultWorkSource, nsr);
2540 
2541                 if (RILJ_LOGD) {
2542                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2543                 }
2544 
2545                 try {
2546                     android.hardware.radio.V1_5.IRadio radioProxy15 =
2547                             (android.hardware.radio.V1_5.IRadio) radioProxy;
2548                     radioProxy15.startNetworkScan_1_5(rr.mSerial, request);
2549                 } catch (RemoteException | RuntimeException e) {
2550                     handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
2551                 }
2552             } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
2553                 android.hardware.radio.V1_2.NetworkScanRequest request =
2554                         new android.hardware.radio.V1_2.NetworkScanRequest();
2555                 request.type = nsr.getScanType();
2556                 request.interval = nsr.getSearchPeriodicity();
2557                 request.maxSearchTime = nsr.getMaxSearchTime();
2558                 request.incrementalResultsPeriodicity = nsr.getIncrementalResultsPeriodicity();
2559                 request.incrementalResults = nsr.getIncrementalResults();
2560 
2561                 for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
2562 
2563                     android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
2564                             convertRadioAccessSpecifierToRadioHAL(ras);
2565                     if (rasInHalFormat == null) {
2566                         AsyncResult.forMessage(result, null,
2567                                 CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
2568                         result.sendToTarget();
2569                         return;
2570                     }
2571 
2572                     request.specifiers.add(rasInHalFormat);
2573                 }
2574 
2575                 request.mccMncs.addAll(nsr.getPlmns());
2576                 RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
2577                         mRILDefaultWorkSource);
2578 
2579                 if (RILJ_LOGD) {
2580                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2581                 }
2582 
2583                 try {
2584                     if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
2585                         android.hardware.radio.V1_4.IRadio radioProxy14 =
2586                                 (android.hardware.radio.V1_4.IRadio) radioProxy;
2587                         radioProxy14.startNetworkScan_1_4(rr.mSerial, request);
2588                     } else {
2589                         android.hardware.radio.V1_2.IRadio radioProxy12 =
2590                                 (android.hardware.radio.V1_2.IRadio) radioProxy;
2591                         radioProxy12.startNetworkScan_1_2(rr.mSerial, request);
2592                     }
2593                 } catch (RemoteException | RuntimeException e) {
2594                     handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
2595                 }
2596             } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
2597                 android.hardware.radio.V1_1.IRadio radioProxy11 =
2598                         (android.hardware.radio.V1_1.IRadio) radioProxy;
2599 
2600                 android.hardware.radio.V1_1.NetworkScanRequest request =
2601                         new android.hardware.radio.V1_1.NetworkScanRequest();
2602                 request.type = nsr.getScanType();
2603                 request.interval = nsr.getSearchPeriodicity();
2604                 for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
2605                     android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
2606                             convertRadioAccessSpecifierToRadioHAL(ras);
2607                     if (rasInHalFormat == null) {
2608                         AsyncResult.forMessage(result, null,
2609                                 CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
2610                         result.sendToTarget();
2611                         return;
2612                     }
2613 
2614                     request.specifiers.add(rasInHalFormat);
2615                 }
2616 
2617                 RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
2618                         mRILDefaultWorkSource);
2619 
2620                 if (RILJ_LOGD) {
2621                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2622                 }
2623 
2624                 try {
2625                     radioProxy11.startNetworkScan(rr.mSerial, request);
2626                 } catch (RemoteException | RuntimeException e) {
2627                     handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
2628                 }
2629             } else if (result != null) {
2630                 AsyncResult.forMessage(result, null,
2631                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
2632                 result.sendToTarget();
2633             }
2634         }
2635     }
2636 
2637     @Override
stopNetworkScan(Message result)2638     public void stopNetworkScan(Message result) {
2639         IRadio radioProxy = getRadioProxy(result);
2640         if (radioProxy != null) {
2641             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
2642                 android.hardware.radio.V1_1.IRadio radioProxy11 =
2643                         (android.hardware.radio.V1_1.IRadio) radioProxy;
2644 
2645                 RILRequest rr = obtainRequest(RIL_REQUEST_STOP_NETWORK_SCAN, result,
2646                         mRILDefaultWorkSource);
2647 
2648                 if (RILJ_LOGD) {
2649                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2650                 }
2651 
2652                 try {
2653                     radioProxy11.stopNetworkScan(rr.mSerial);
2654                 } catch (RemoteException | RuntimeException e) {
2655                     handleRadioProxyExceptionForRR(rr, "stopNetworkScan", e);
2656                 }
2657             } else if (result != null) {
2658                 AsyncResult.forMessage(result, null,
2659                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
2660                 result.sendToTarget();
2661             }
2662         }
2663     }
2664 
2665     @Override
startDtmf(char c, Message result)2666     public void startDtmf(char c, Message result) {
2667         IRadio radioProxy = getRadioProxy(result);
2668         if (radioProxy != null) {
2669             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_START, result,
2670                     mRILDefaultWorkSource);
2671 
2672             // Do not log function arg for privacy
2673             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2674 
2675             try {
2676                 radioProxy.startDtmf(rr.mSerial, c + "");
2677             } catch (RemoteException | RuntimeException e) {
2678                 handleRadioProxyExceptionForRR(rr, "startDtmf", e);
2679             }
2680         }
2681     }
2682 
2683     @Override
stopDtmf(Message result)2684     public void stopDtmf(Message result) {
2685         IRadio radioProxy = getRadioProxy(result);
2686         if (radioProxy != null) {
2687             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_STOP, result,
2688                     mRILDefaultWorkSource);
2689 
2690             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2691 
2692             try {
2693                 radioProxy.stopDtmf(rr.mSerial);
2694             } catch (RemoteException | RuntimeException e) {
2695                 handleRadioProxyExceptionForRR(rr, "stopDtmf", e);
2696             }
2697         }
2698     }
2699 
2700     @Override
separateConnection(int gsmIndex, Message result)2701     public void separateConnection(int gsmIndex, Message result) {
2702         IRadio radioProxy = getRadioProxy(result);
2703         if (radioProxy != null) {
2704             RILRequest rr = obtainRequest(RIL_REQUEST_SEPARATE_CONNECTION, result,
2705                     mRILDefaultWorkSource);
2706 
2707             if (RILJ_LOGD) {
2708                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2709                         + " gsmIndex = " + gsmIndex);
2710             }
2711 
2712             try {
2713                 radioProxy.separateConnection(rr.mSerial, gsmIndex);
2714             } catch (RemoteException | RuntimeException e) {
2715                 handleRadioProxyExceptionForRR(rr, "separateConnection", e);
2716             }
2717         }
2718     }
2719 
2720     @Override
getBasebandVersion(Message result)2721     public void getBasebandVersion(Message result) {
2722         IRadio radioProxy = getRadioProxy(result);
2723         if (radioProxy != null) {
2724             RILRequest rr = obtainRequest(RIL_REQUEST_BASEBAND_VERSION, result,
2725                     mRILDefaultWorkSource);
2726 
2727             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2728 
2729             try {
2730                 radioProxy.getBasebandVersion(rr.mSerial);
2731             } catch (RemoteException | RuntimeException e) {
2732                 handleRadioProxyExceptionForRR(rr, "getBasebandVersion", e);
2733             }
2734         }
2735     }
2736 
2737     @Override
setMute(boolean enableMute, Message result)2738     public void setMute(boolean enableMute, Message result) {
2739         IRadio radioProxy = getRadioProxy(result);
2740         if (radioProxy != null) {
2741             RILRequest rr = obtainRequest(RIL_REQUEST_SET_MUTE, result,
2742                     mRILDefaultWorkSource);
2743 
2744             if (RILJ_LOGD) {
2745                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2746                         + " enableMute = " + enableMute);
2747             }
2748 
2749             try {
2750                 radioProxy.setMute(rr.mSerial, enableMute);
2751             } catch (RemoteException | RuntimeException e) {
2752                 handleRadioProxyExceptionForRR(rr, "setMute", e);
2753             }
2754         }
2755     }
2756 
2757     @Override
getMute(Message result)2758     public void getMute(Message result) {
2759         IRadio radioProxy = getRadioProxy(result);
2760         if (radioProxy != null) {
2761             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MUTE, result,
2762                     mRILDefaultWorkSource);
2763 
2764             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2765 
2766             try {
2767                 radioProxy.getMute(rr.mSerial);
2768             } catch (RemoteException | RuntimeException e) {
2769                 handleRadioProxyExceptionForRR(rr, "getMute", e);
2770             }
2771         }
2772     }
2773 
2774     @Override
queryCLIP(Message result)2775     public void queryCLIP(Message result) {
2776         IRadio radioProxy = getRadioProxy(result);
2777         if (radioProxy != null) {
2778             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CLIP, result,
2779                     mRILDefaultWorkSource);
2780 
2781             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2782 
2783             try {
2784                 radioProxy.getClip(rr.mSerial);
2785             } catch (RemoteException | RuntimeException e) {
2786                 handleRadioProxyExceptionForRR(rr, "queryCLIP", e);
2787             }
2788         }
2789     }
2790 
2791     /**
2792      * @deprecated
2793      */
2794     @Override
2795     @Deprecated
getPDPContextList(Message result)2796     public void getPDPContextList(Message result) {
2797         getDataCallList(result);
2798     }
2799 
2800     @Override
getDataCallList(Message result)2801     public void getDataCallList(Message result) {
2802         IRadio radioProxy = getRadioProxy(result);
2803         if (radioProxy != null) {
2804             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_CALL_LIST, result,
2805                     mRILDefaultWorkSource);
2806 
2807             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2808 
2809             try {
2810                 radioProxy.getDataCallList(rr.mSerial);
2811             } catch (RemoteException | RuntimeException e) {
2812                 handleRadioProxyExceptionForRR(rr, "getDataCallList", e);
2813             }
2814         }
2815     }
2816 
2817     @UnsupportedAppUsage
2818     @Override
invokeOemRilRequestRaw(byte[] data, Message response)2819     public void invokeOemRilRequestRaw(byte[] data, Message response) {
2820         IOemHook oemHookProxy = getOemHookProxy(response);
2821         if (oemHookProxy != null) {
2822             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_RAW, response,
2823                     mRILDefaultWorkSource);
2824 
2825             if (RILJ_LOGD) {
2826                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2827                         + "[" + IccUtils.bytesToHexString(data) + "]");
2828             }
2829 
2830             try {
2831                 oemHookProxy.sendRequestRaw(rr.mSerial, primitiveArrayToArrayList(data));
2832             } catch (RemoteException | RuntimeException e) {
2833                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestRaw", e);
2834             }
2835         } else {
2836             // OEM Hook service is disabled for P and later devices.
2837             // Deprecated OEM Hook APIs will perform dummy before being removed.
2838             if (RILJ_LOGD) riljLog("Radio Oem Hook Service is disabled for P and later devices. ");
2839         }
2840     }
2841 
2842     @Override
invokeOemRilRequestStrings(String[] strings, Message result)2843     public void invokeOemRilRequestStrings(String[] strings, Message result) {
2844         IOemHook oemHookProxy = getOemHookProxy(result);
2845         if (oemHookProxy != null) {
2846             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_STRINGS, result,
2847                     mRILDefaultWorkSource);
2848 
2849             String logStr = "";
2850             for (int i = 0; i < strings.length; i++) {
2851                 logStr = logStr + strings[i] + " ";
2852             }
2853             if (RILJ_LOGD) {
2854                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " strings = "
2855                         + logStr);
2856             }
2857 
2858             try {
2859                 oemHookProxy.sendRequestStrings(rr.mSerial,
2860                         new ArrayList<String>(Arrays.asList(strings)));
2861             } catch (RemoteException | RuntimeException e) {
2862                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestStrings", e);
2863             }
2864         } else {
2865             // OEM Hook service is disabled for P and later devices.
2866             // Deprecated OEM Hook APIs will perform dummy before being removed.
2867             if (RILJ_LOGD) riljLog("Radio Oem Hook Service is disabled for P and later devices. ");
2868         }
2869     }
2870 
2871     @Override
setSuppServiceNotifications(boolean enable, Message result)2872     public void setSuppServiceNotifications(boolean enable, Message result) {
2873         IRadio radioProxy = getRadioProxy(result);
2874         if (radioProxy != null) {
2875             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result,
2876                     mRILDefaultWorkSource);
2877 
2878             if (RILJ_LOGD) {
2879                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
2880                         + enable);
2881             }
2882 
2883             try {
2884                 radioProxy.setSuppServiceNotifications(rr.mSerial, enable);
2885             } catch (RemoteException | RuntimeException e) {
2886                 handleRadioProxyExceptionForRR(rr, "setSuppServiceNotifications", e);
2887             }
2888         }
2889     }
2890 
2891     @Override
writeSmsToSim(int status, String smsc, String pdu, Message result)2892     public void writeSmsToSim(int status, String smsc, String pdu, Message result) {
2893         status = translateStatus(status);
2894         IRadio radioProxy = getRadioProxy(result);
2895         if (radioProxy != null) {
2896             RILRequest rr = obtainRequest(RIL_REQUEST_WRITE_SMS_TO_SIM, result,
2897                     mRILDefaultWorkSource);
2898 
2899             if (RILJ_LOGV) {
2900                 riljLog(rr.serialString() + "> "
2901                         + requestToString(rr.mRequest)
2902                         + " " + status);
2903             }
2904 
2905             SmsWriteArgs args = new SmsWriteArgs();
2906             args.status = status;
2907             args.smsc = convertNullToEmptyString(smsc);
2908             args.pdu = convertNullToEmptyString(pdu);
2909 
2910             try {
2911                 radioProxy.writeSmsToSim(rr.mSerial, args);
2912             } catch (RemoteException | RuntimeException e) {
2913                 handleRadioProxyExceptionForRR(rr, "writeSmsToSim", e);
2914             }
2915         }
2916     }
2917 
2918     @Override
deleteSmsOnSim(int index, Message result)2919     public void deleteSmsOnSim(int index, Message result) {
2920         IRadio radioProxy = getRadioProxy(result);
2921         if (radioProxy != null) {
2922             RILRequest rr = obtainRequest(RIL_REQUEST_DELETE_SMS_ON_SIM, result,
2923                     mRILDefaultWorkSource);
2924 
2925             if (RILJ_LOGV) {
2926                 riljLog(rr.serialString() + "> "
2927                         + requestToString(rr.mRequest) + " index = " + index);
2928             }
2929 
2930             try {
2931                 radioProxy.deleteSmsOnSim(rr.mSerial, index);
2932             } catch (RemoteException | RuntimeException e) {
2933                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnSim", e);
2934             }
2935         }
2936     }
2937 
2938     @Override
setBandMode(int bandMode, Message result)2939     public void setBandMode(int bandMode, Message result) {
2940         IRadio radioProxy = getRadioProxy(result);
2941         if (radioProxy != null) {
2942             RILRequest rr = obtainRequest(RIL_REQUEST_SET_BAND_MODE, result,
2943                     mRILDefaultWorkSource);
2944 
2945             if (RILJ_LOGD) {
2946                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2947                         + " bandMode = " + bandMode);
2948             }
2949 
2950             try {
2951                 radioProxy.setBandMode(rr.mSerial, bandMode);
2952             } catch (RemoteException | RuntimeException e) {
2953                 handleRadioProxyExceptionForRR(rr, "setBandMode", e);
2954             }
2955         }
2956     }
2957 
2958     @Override
queryAvailableBandMode(Message result)2959     public void queryAvailableBandMode(Message result) {
2960         IRadio radioProxy = getRadioProxy(result);
2961         if (radioProxy != null) {
2962             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, result,
2963                     mRILDefaultWorkSource);
2964 
2965             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2966 
2967             try {
2968                 radioProxy.getAvailableBandModes(rr.mSerial);
2969             } catch (RemoteException | RuntimeException e) {
2970                 handleRadioProxyExceptionForRR(rr, "queryAvailableBandMode", e);
2971             }
2972         }
2973     }
2974 
2975     @Override
sendEnvelope(String contents, Message result)2976     public void sendEnvelope(String contents, Message result) {
2977         IRadio radioProxy = getRadioProxy(result);
2978         if (radioProxy != null) {
2979             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, result,
2980                     mRILDefaultWorkSource);
2981 
2982             if (RILJ_LOGD) {
2983                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
2984                         + contents);
2985             }
2986 
2987             try {
2988                 radioProxy.sendEnvelope(rr.mSerial, convertNullToEmptyString(contents));
2989             } catch (RemoteException | RuntimeException e) {
2990                 handleRadioProxyExceptionForRR(rr, "sendEnvelope", e);
2991             }
2992         }
2993     }
2994 
2995     @Override
sendTerminalResponse(String contents, Message result)2996     public void sendTerminalResponse(String contents, Message result) {
2997         IRadio radioProxy = getRadioProxy(result);
2998         if (radioProxy != null) {
2999             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, result,
3000                     mRILDefaultWorkSource);
3001 
3002             if (RILJ_LOGD) {
3003                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
3004                         + (TelephonyUtils.IS_DEBUGGABLE
3005                             ? contents : censoredTerminalResponse(contents)));
3006             }
3007 
3008             try {
3009                 radioProxy.sendTerminalResponseToSim(rr.mSerial,
3010                         convertNullToEmptyString(contents));
3011             } catch (RemoteException | RuntimeException e) {
3012                 handleRadioProxyExceptionForRR(rr, "sendTerminalResponse", e);
3013             }
3014         }
3015     }
3016 
censoredTerminalResponse(String terminalResponse)3017     private String censoredTerminalResponse(String terminalResponse) {
3018         try {
3019             byte[] bytes = IccUtils.hexStringToBytes(terminalResponse);
3020             if (bytes != null) {
3021                 List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(bytes, 0);
3022                 int from = 0;
3023                 for (ComprehensionTlv ctlv : ctlvs) {
3024                     // Find text strings which might be personal information input by user,
3025                     // then replace it with "********".
3026                     if (ComprehensionTlvTag.TEXT_STRING.value() == ctlv.getTag()) {
3027                         byte[] target = Arrays.copyOfRange(ctlv.getRawValue(), from,
3028                                 ctlv.getValueIndex() + ctlv.getLength());
3029                         terminalResponse = terminalResponse.toLowerCase().replace(
3030                                 IccUtils.bytesToHexString(target).toLowerCase(), "********");
3031                     }
3032                     // The text string tag and the length field should also be hidden.
3033                     from = ctlv.getValueIndex() + ctlv.getLength();
3034                 }
3035             }
3036         } catch (Exception e) {
3037             Rlog.e(RILJ_LOG_TAG, "Could not censor the terminal response: " + e);
3038             terminalResponse = null;
3039         }
3040 
3041         return terminalResponse;
3042     }
3043 
3044     @Override
sendEnvelopeWithStatus(String contents, Message result)3045     public void sendEnvelopeWithStatus(String contents, Message result) {
3046         IRadio radioProxy = getRadioProxy(result);
3047         if (radioProxy != null) {
3048             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, result,
3049                     mRILDefaultWorkSource);
3050 
3051             if (RILJ_LOGD) {
3052                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
3053                         + contents);
3054             }
3055 
3056             try {
3057                 radioProxy.sendEnvelopeWithStatus(rr.mSerial, convertNullToEmptyString(contents));
3058             } catch (RemoteException | RuntimeException e) {
3059                 handleRadioProxyExceptionForRR(rr, "sendEnvelopeWithStatus", e);
3060             }
3061         }
3062     }
3063 
3064     @Override
explicitCallTransfer(Message result)3065     public void explicitCallTransfer(Message result) {
3066         IRadio radioProxy = getRadioProxy(result);
3067         if (radioProxy != null) {
3068             RILRequest rr = obtainRequest(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result,
3069                     mRILDefaultWorkSource);
3070 
3071             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3072 
3073             try {
3074                 radioProxy.explicitCallTransfer(rr.mSerial);
3075             } catch (RemoteException | RuntimeException e) {
3076                 handleRadioProxyExceptionForRR(rr, "explicitCallTransfer", e);
3077             }
3078         }
3079     }
3080 
3081     @Override
setPreferredNetworkType(@refNetworkMode int networkType , Message result)3082     public void setPreferredNetworkType(@PrefNetworkMode int networkType , Message result) {
3083         IRadio radioProxy = getRadioProxy(result);
3084         if (radioProxy != null) {
3085             RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
3086                     mRILDefaultWorkSource);
3087 
3088             if (RILJ_LOGD) {
3089                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3090                         + " networkType = " + networkType);
3091             }
3092             mPreferredNetworkType = networkType;
3093             mMetrics.writeSetPreferredNetworkType(mPhoneId, networkType);
3094 
3095             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
3096                 android.hardware.radio.V1_4.IRadio radioProxy14 =
3097                         (android.hardware.radio.V1_4.IRadio) radioProxy;
3098                 try {
3099                     radioProxy14.setPreferredNetworkTypeBitmap(
3100                             rr.mSerial, convertToHalRadioAccessFamily(
3101                                     RadioAccessFamily.getRafFromNetworkType(networkType)));
3102                 } catch (RemoteException | RuntimeException e) {
3103                     handleRadioProxyExceptionForRR(rr, "setPreferredNetworkTypeBitmap", e);
3104                 }
3105             } else {
3106                 try {
3107                     radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
3108                 } catch (RemoteException | RuntimeException e) {
3109                     handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
3110                 }
3111             }
3112         }
3113     }
3114 
3115     /**
3116      * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to
3117      * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by
3118      * {@link android.telephony.Annotation.NetworkType}.
3119      *
3120      * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily}
3121      * @return {@link TelephonyManager.NetworkTypeBitMask}
3122      */
3123     @TelephonyManager.NetworkTypeBitMask
convertToNetworkTypeBitMask(int raf)3124     public static int convertToNetworkTypeBitMask(int raf) {
3125         int networkTypeRaf = 0;
3126 
3127         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) {
3128             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
3129         }
3130         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) {
3131             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
3132         }
3133         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) {
3134             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
3135         }
3136         // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA
3137         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) {
3138             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
3139         }
3140         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) {
3141             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
3142         }
3143         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) {
3144             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
3145         }
3146         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) {
3147             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
3148         }
3149         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) {
3150             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
3151         }
3152         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) {
3153             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
3154         }
3155         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) {
3156             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
3157         }
3158         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) {
3159             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
3160         }
3161         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) {
3162             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
3163         }
3164         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) {
3165             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
3166         }
3167         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) {
3168             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
3169         }
3170         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) {
3171             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
3172         }
3173         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) {
3174             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
3175         }
3176         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) {
3177             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
3178         }
3179         if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) {
3180             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
3181         }
3182         if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) {
3183             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR;
3184         }
3185         // TODO: need hal definition
3186         if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) {
3187             networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
3188         }
3189         return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf;
3190     }
3191 
3192     // convert to android.hardware.radio.V1_0.RadioAccessFamily
convertToHalRadioAccessFamily( @elephonyManager.NetworkTypeBitMask int networkTypeBitmask)3193     private static int convertToHalRadioAccessFamily(
3194             @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask) {
3195         int raf = 0;
3196 
3197         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GSM) != 0) {
3198             raf |= android.hardware.radio.V1_0.RadioAccessFamily.GSM;
3199         }
3200         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GPRS) != 0) {
3201             raf |= android.hardware.radio.V1_0.RadioAccessFamily.GPRS;
3202         }
3203         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EDGE) != 0) {
3204             raf |= android.hardware.radio.V1_0.RadioAccessFamily.EDGE;
3205         }
3206         // convert CDMA to IS95A, consistent with ServiceState.networkTypeToRilRadioTechnology
3207         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_CDMA) != 0) {
3208             raf |= android.hardware.radio.V1_0.RadioAccessFamily.IS95A;
3209         }
3210         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) != 0) {
3211             raf |= android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT;
3212         }
3213         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0) != 0) {
3214             raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0;
3215         }
3216         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A) != 0) {
3217             raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A;
3218         }
3219         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B) != 0) {
3220             raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B;
3221         }
3222         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD) != 0) {
3223             raf |= android.hardware.radio.V1_0.RadioAccessFamily.EHRPD;
3224         }
3225         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA) != 0) {
3226             raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSUPA;
3227         }
3228         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA) != 0) {
3229             raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSDPA;
3230         }
3231         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPA) != 0) {
3232             raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPA;
3233         }
3234         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP) != 0) {
3235             raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPAP;
3236         }
3237         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_UMTS) != 0) {
3238             raf |= android.hardware.radio.V1_0.RadioAccessFamily.UMTS;
3239         }
3240         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA) != 0) {
3241             raf |= android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA;
3242         }
3243         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
3244             raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE;
3245         }
3246         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
3247             raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA;
3248         }
3249         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0) {
3250             raf |= android.hardware.radio.V1_4.RadioAccessFamily.NR;
3251         }
3252         // TODO: need hal definition for IWLAN
3253         return (raf == 0) ? android.hardware.radio.V1_4.RadioAccessFamily.UNKNOWN : raf;
3254     }
3255 
3256     @Override
getPreferredNetworkType(Message result)3257     public void getPreferredNetworkType(Message result) {
3258         IRadio radioProxy = getRadioProxy(result);
3259         if (radioProxy != null) {
3260             RILRequest rr = obtainRequest(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, result,
3261                     mRILDefaultWorkSource);
3262             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3263             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
3264                 android.hardware.radio.V1_4.IRadio radioProxy14 =
3265                         (android.hardware.radio.V1_4.IRadio) radioProxy;
3266                 try {
3267                     radioProxy14.getPreferredNetworkTypeBitmap(rr.mSerial);
3268                 } catch (RemoteException | RuntimeException e) {
3269                     handleRadioProxyExceptionForRR(rr, "getPreferredNetworkTypeBitmap", e);
3270                 }
3271             } else {
3272                 try {
3273                     radioProxy.getPreferredNetworkType(rr.mSerial);
3274                 } catch (RemoteException | RuntimeException e) {
3275                     handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
3276                 }
3277             }
3278         }
3279     }
3280 
3281     @Override
setLocationUpdates(boolean enable, Message result)3282     public void setLocationUpdates(boolean enable, Message result) {
3283         IRadio radioProxy = getRadioProxy(result);
3284         if (radioProxy != null) {
3285             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOCATION_UPDATES, result,
3286                     mRILDefaultWorkSource);
3287 
3288             if (RILJ_LOGD) {
3289                 riljLog(rr.serialString() + "> "
3290                         + requestToString(rr.mRequest) + " enable = " + enable);
3291             }
3292 
3293             try {
3294                 radioProxy.setLocationUpdates(rr.mSerial, enable);
3295             } catch (RemoteException | RuntimeException e) {
3296                 handleRadioProxyExceptionForRR(rr, "setLocationUpdates", e);
3297             }
3298         }
3299     }
3300 
3301     @Override
setCdmaSubscriptionSource(int cdmaSubscription , Message result)3302     public void setCdmaSubscriptionSource(int cdmaSubscription , Message result) {
3303         IRadio radioProxy = getRadioProxy(result);
3304         if (radioProxy != null) {
3305             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, result,
3306                     mRILDefaultWorkSource);
3307 
3308             if (RILJ_LOGD) {
3309                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3310                         + " cdmaSubscription = " + cdmaSubscription);
3311             }
3312 
3313             try {
3314                 radioProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
3315             } catch (RemoteException | RuntimeException e) {
3316                 handleRadioProxyExceptionForRR(rr, "setCdmaSubscriptionSource", e);
3317             }
3318         }
3319     }
3320 
3321     @Override
queryCdmaRoamingPreference(Message result)3322     public void queryCdmaRoamingPreference(Message result) {
3323         IRadio radioProxy = getRadioProxy(result);
3324         if (radioProxy != null) {
3325             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, result,
3326                     mRILDefaultWorkSource);
3327 
3328             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3329 
3330             try {
3331                 radioProxy.getCdmaRoamingPreference(rr.mSerial);
3332             } catch (RemoteException | RuntimeException e) {
3333                 handleRadioProxyExceptionForRR(rr, "queryCdmaRoamingPreference", e);
3334             }
3335         }
3336     }
3337 
3338     @Override
setCdmaRoamingPreference(int cdmaRoamingType, Message result)3339     public void setCdmaRoamingPreference(int cdmaRoamingType, Message result) {
3340         IRadio radioProxy = getRadioProxy(result);
3341         if (radioProxy != null) {
3342             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, result,
3343                     mRILDefaultWorkSource);
3344 
3345             if (RILJ_LOGD) {
3346                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3347                         + " cdmaRoamingType = " + cdmaRoamingType);
3348             }
3349 
3350             try {
3351                 radioProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
3352             } catch (RemoteException | RuntimeException e) {
3353                 handleRadioProxyExceptionForRR(rr, "setCdmaRoamingPreference", e);
3354             }
3355         }
3356     }
3357 
3358     @Override
queryTTYMode(Message result)3359     public void queryTTYMode(Message result) {
3360         IRadio radioProxy = getRadioProxy(result);
3361         if (radioProxy != null) {
3362             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_TTY_MODE, result,
3363                     mRILDefaultWorkSource);
3364 
3365             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3366 
3367             try {
3368                 radioProxy.getTTYMode(rr.mSerial);
3369             } catch (RemoteException | RuntimeException e) {
3370                 handleRadioProxyExceptionForRR(rr, "queryTTYMode", e);
3371             }
3372         }
3373     }
3374 
3375     @Override
setTTYMode(int ttyMode, Message result)3376     public void setTTYMode(int ttyMode, Message result) {
3377         IRadio radioProxy = getRadioProxy(result);
3378         if (radioProxy != null) {
3379             RILRequest rr = obtainRequest(RIL_REQUEST_SET_TTY_MODE, result,
3380                     mRILDefaultWorkSource);
3381 
3382             if (RILJ_LOGD) {
3383                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3384                         + " ttyMode = " + ttyMode);
3385             }
3386 
3387             try {
3388                 radioProxy.setTTYMode(rr.mSerial, ttyMode);
3389             } catch (RemoteException | RuntimeException e) {
3390                 handleRadioProxyExceptionForRR(rr, "setTTYMode", e);
3391             }
3392         }
3393     }
3394 
3395     @Override
setPreferredVoicePrivacy(boolean enable, Message result)3396     public void setPreferredVoicePrivacy(boolean enable, Message result) {
3397         IRadio radioProxy = getRadioProxy(result);
3398         if (radioProxy != null) {
3399             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, result,
3400                     mRILDefaultWorkSource);
3401 
3402             if (RILJ_LOGD) {
3403                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3404                         + " enable = " + enable);
3405             }
3406 
3407             try {
3408                 radioProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
3409             } catch (RemoteException | RuntimeException e) {
3410                 handleRadioProxyExceptionForRR(rr, "setPreferredVoicePrivacy", e);
3411             }
3412         }
3413     }
3414 
3415     @Override
getPreferredVoicePrivacy(Message result)3416     public void getPreferredVoicePrivacy(Message result) {
3417         IRadio radioProxy = getRadioProxy(result);
3418         if (radioProxy != null) {
3419             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
3420                     result, mRILDefaultWorkSource);
3421 
3422             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3423 
3424             try {
3425                 radioProxy.getPreferredVoicePrivacy(rr.mSerial);
3426             } catch (RemoteException | RuntimeException e) {
3427                 handleRadioProxyExceptionForRR(rr, "getPreferredVoicePrivacy", e);
3428             }
3429         }
3430     }
3431 
3432     @Override
sendCDMAFeatureCode(String featureCode, Message result)3433     public void sendCDMAFeatureCode(String featureCode, Message result) {
3434         IRadio radioProxy = getRadioProxy(result);
3435         if (radioProxy != null) {
3436             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_FLASH, result,
3437                     mRILDefaultWorkSource);
3438 
3439             if (RILJ_LOGD) {
3440                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3441                         + " featureCode = " + featureCode);
3442             }
3443 
3444             try {
3445                 radioProxy.sendCDMAFeatureCode(rr.mSerial, convertNullToEmptyString(featureCode));
3446             } catch (RemoteException | RuntimeException e) {
3447                 handleRadioProxyExceptionForRR(rr, "sendCDMAFeatureCode", e);
3448             }
3449         }
3450     }
3451 
3452     @Override
sendBurstDtmf(String dtmfString, int on, int off, Message result)3453     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
3454         IRadio radioProxy = getRadioProxy(result);
3455         if (radioProxy != null) {
3456             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BURST_DTMF, result,
3457                     mRILDefaultWorkSource);
3458 
3459             if (RILJ_LOGD) {
3460                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3461                         + " dtmfString = " + dtmfString + " on = " + on + " off = " + off);
3462             }
3463 
3464             try {
3465                 radioProxy.sendBurstDtmf(rr.mSerial, convertNullToEmptyString(dtmfString), on, off);
3466             } catch (RemoteException | RuntimeException e) {
3467                 handleRadioProxyExceptionForRR(rr, "sendBurstDtmf", e);
3468             }
3469         }
3470     }
3471 
constructCdmaSendSmsRilRequest(CdmaSmsMessage msg, byte[] pdu)3472     private void constructCdmaSendSmsRilRequest(CdmaSmsMessage msg, byte[] pdu) {
3473         int addrNbrOfDigits;
3474         int subaddrNbrOfDigits;
3475         int bearerDataLength;
3476         ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
3477         DataInputStream dis = new DataInputStream(bais);
3478 
3479         try {
3480             msg.teleserviceId = dis.readInt(); // teleServiceId
3481             msg.isServicePresent = (byte) dis.readInt() == 1 ? true : false; // servicePresent
3482             msg.serviceCategory = dis.readInt(); // serviceCategory
3483             msg.address.digitMode = dis.read();  // address digit mode
3484             msg.address.numberMode = dis.read(); // address number mode
3485             msg.address.numberType = dis.read(); // address number type
3486             msg.address.numberPlan = dis.read(); // address number plan
3487             addrNbrOfDigits = (byte) dis.read();
3488             for (int i = 0; i < addrNbrOfDigits; i++) {
3489                 msg.address.digits.add(dis.readByte()); // address_orig_bytes[i]
3490             }
3491             msg.subAddress.subaddressType = dis.read(); //subaddressType
3492             msg.subAddress.odd = (byte) dis.read() == 1 ? true : false; //subaddr odd
3493             subaddrNbrOfDigits = (byte) dis.read();
3494             for (int i = 0; i < subaddrNbrOfDigits; i++) {
3495                 msg.subAddress.digits.add(dis.readByte()); //subaddr_orig_bytes[i]
3496             }
3497 
3498             bearerDataLength = dis.read();
3499             for (int i = 0; i < bearerDataLength; i++) {
3500                 msg.bearerData.add(dis.readByte()); //bearerData[i]
3501             }
3502         } catch (IOException ex) {
3503             if (RILJ_LOGD) {
3504                 riljLog("sendSmsCdma: conversion from input stream to object failed: "
3505                         + ex);
3506             }
3507         }
3508     }
3509 
3510     @Override
sendCdmaSMSExpectMore(byte[] pdu, Message result)3511     public void sendCdmaSMSExpectMore(byte[] pdu, Message result) {
3512         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
3513             IRadio radioProxy = getRadioProxy(result);
3514             // IRadio V1.5
3515             android.hardware.radio.V1_5.IRadio radioProxy15 =
3516                     (android.hardware.radio.V1_5.IRadio) radioProxy;
3517             if (radioProxy15 != null) {
3518                 RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE, result,
3519                         mRILDefaultWorkSource);
3520 
3521                 // Do not log function arg for privacy
3522                 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3523 
3524                 CdmaSmsMessage msg = new CdmaSmsMessage();
3525                 constructCdmaSendSmsRilRequest(msg, pdu);
3526 
3527                 try {
3528                     radioProxy15.sendCdmaSmsExpectMore(rr.mSerial, msg);
3529                     mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
3530                             SmsSession.Event.Format.SMS_FORMAT_3GPP2);
3531                 } catch (RemoteException | RuntimeException e) {
3532                     handleRadioProxyExceptionForRR(rr, "sendCdmaSMSExpectMore", e);
3533                 }
3534             }
3535         } else {
3536             sendCdmaSms(pdu, result);
3537         }
3538     }
3539 
3540     @Override
sendCdmaSms(byte[] pdu, Message result)3541     public void sendCdmaSms(byte[] pdu, Message result) {
3542         IRadio radioProxy = getRadioProxy(result);
3543         if (radioProxy != null) {
3544             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS, result,
3545                     mRILDefaultWorkSource);
3546 
3547             // Do not log function arg for privacy
3548             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3549 
3550             CdmaSmsMessage msg = new CdmaSmsMessage();
3551             constructCdmaSendSmsRilRequest(msg, pdu);
3552 
3553             try {
3554                 radioProxy.sendCdmaSms(rr.mSerial, msg);
3555                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
3556                         SmsSession.Event.Format.SMS_FORMAT_3GPP2);
3557             } catch (RemoteException | RuntimeException e) {
3558                 handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
3559             }
3560         }
3561     }
3562 
3563     @Override
acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result)3564     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
3565         IRadio radioProxy = getRadioProxy(result);
3566         if (radioProxy != null) {
3567             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result,
3568                     mRILDefaultWorkSource);
3569 
3570             if (RILJ_LOGD) {
3571                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3572                         + " success = " + success + " cause = " + cause);
3573             }
3574 
3575             CdmaSmsAck msg = new CdmaSmsAck();
3576             msg.errorClass = success ? 0 : 1;
3577             msg.smsCauseCode = cause;
3578 
3579             try {
3580                 radioProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, msg);
3581             } catch (RemoteException | RuntimeException e) {
3582                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingCdmaSms", e);
3583             }
3584         }
3585     }
3586 
3587     @Override
getGsmBroadcastConfig(Message result)3588     public void getGsmBroadcastConfig(Message result) {
3589         IRadio radioProxy = getRadioProxy(result);
3590         if (radioProxy != null) {
3591             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, result,
3592                     mRILDefaultWorkSource);
3593 
3594             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3595 
3596             try {
3597                 radioProxy.getGsmBroadcastConfig(rr.mSerial);
3598             } catch (RemoteException | RuntimeException e) {
3599                 handleRadioProxyExceptionForRR(rr, "getGsmBroadcastConfig", e);
3600             }
3601         }
3602     }
3603 
3604     @Override
setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message result)3605     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message result) {
3606         IRadio radioProxy = getRadioProxy(result);
3607         if (radioProxy != null) {
3608             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, result,
3609                     mRILDefaultWorkSource);
3610 
3611             if (RILJ_LOGD) {
3612                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3613                         + " with " + config.length + " configs : ");
3614                 for (int i = 0; i < config.length; i++) {
3615                     riljLog(config[i].toString());
3616                 }
3617             }
3618 
3619             ArrayList<GsmBroadcastSmsConfigInfo> configs = new ArrayList<>();
3620 
3621             int numOfConfig = config.length;
3622             GsmBroadcastSmsConfigInfo info;
3623 
3624             for (int i = 0; i < numOfConfig; i++) {
3625                 info = new GsmBroadcastSmsConfigInfo();
3626                 info.fromServiceId = config[i].getFromServiceId();
3627                 info.toServiceId = config[i].getToServiceId();
3628                 info.fromCodeScheme = config[i].getFromCodeScheme();
3629                 info.toCodeScheme = config[i].getToCodeScheme();
3630                 info.selected = config[i].isSelected();
3631                 configs.add(info);
3632             }
3633 
3634             try {
3635                 radioProxy.setGsmBroadcastConfig(rr.mSerial, configs);
3636             } catch (RemoteException | RuntimeException e) {
3637                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastConfig", e);
3638             }
3639         }
3640     }
3641 
3642     @Override
setGsmBroadcastActivation(boolean activate, Message result)3643     public void setGsmBroadcastActivation(boolean activate, Message result) {
3644         IRadio radioProxy = getRadioProxy(result);
3645         if (radioProxy != null) {
3646             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, result,
3647                     mRILDefaultWorkSource);
3648 
3649             if (RILJ_LOGD) {
3650                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3651                         + " activate = " + activate);
3652             }
3653 
3654             try {
3655                 radioProxy.setGsmBroadcastActivation(rr.mSerial, activate);
3656             } catch (RemoteException | RuntimeException e) {
3657                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastActivation", e);
3658             }
3659         }
3660     }
3661 
3662     @Override
getCdmaBroadcastConfig(Message result)3663     public void getCdmaBroadcastConfig(Message result) {
3664         IRadio radioProxy = getRadioProxy(result);
3665         if (radioProxy != null) {
3666             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, result,
3667                     mRILDefaultWorkSource);
3668 
3669             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3670 
3671             try {
3672                 radioProxy.getCdmaBroadcastConfig(rr.mSerial);
3673             } catch (RemoteException | RuntimeException e) {
3674                 handleRadioProxyExceptionForRR(rr, "getCdmaBroadcastConfig", e);
3675             }
3676         }
3677     }
3678 
3679     @Override
setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result)3680     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result) {
3681         IRadio radioProxy = getRadioProxy(result);
3682         if (radioProxy != null) {
3683             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, result,
3684                     mRILDefaultWorkSource);
3685 
3686             ArrayList<CdmaBroadcastSmsConfigInfo> halConfigs = new ArrayList<>();
3687 
3688             for (CdmaSmsBroadcastConfigInfo config: configs) {
3689                 for (int i = config.getFromServiceCategory();
3690                         i <= config.getToServiceCategory();
3691                         i++) {
3692                     CdmaBroadcastSmsConfigInfo info = new CdmaBroadcastSmsConfigInfo();
3693                     info.serviceCategory = i;
3694                     info.language = config.getLanguage();
3695                     info.selected = config.isSelected();
3696                     halConfigs.add(info);
3697                 }
3698             }
3699 
3700             if (RILJ_LOGD) {
3701                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3702                         + " with " + halConfigs.size() + " configs : ");
3703                 for (CdmaBroadcastSmsConfigInfo config : halConfigs) {
3704                     riljLog(config.toString());
3705                 }
3706             }
3707 
3708             try {
3709                 radioProxy.setCdmaBroadcastConfig(rr.mSerial, halConfigs);
3710             } catch (RemoteException | RuntimeException e) {
3711                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastConfig", e);
3712             }
3713         }
3714     }
3715 
3716     @Override
setCdmaBroadcastActivation(boolean activate, Message result)3717     public void setCdmaBroadcastActivation(boolean activate, Message result) {
3718         IRadio radioProxy = getRadioProxy(result);
3719         if (radioProxy != null) {
3720             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, result,
3721                     mRILDefaultWorkSource);
3722 
3723             if (RILJ_LOGD) {
3724                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3725                         + " activate = " + activate);
3726             }
3727 
3728             try {
3729                 radioProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
3730             } catch (RemoteException | RuntimeException e) {
3731                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastActivation", e);
3732             }
3733         }
3734     }
3735 
3736     @Override
getCDMASubscription(Message result)3737     public void getCDMASubscription(Message result) {
3738         IRadio radioProxy = getRadioProxy(result);
3739         if (radioProxy != null) {
3740             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SUBSCRIPTION, result,
3741                     mRILDefaultWorkSource);
3742 
3743             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3744 
3745             try {
3746                 radioProxy.getCDMASubscription(rr.mSerial);
3747             } catch (RemoteException | RuntimeException e) {
3748                 handleRadioProxyExceptionForRR(rr, "getCDMASubscription", e);
3749             }
3750         }
3751     }
3752 
3753     @Override
writeSmsToRuim(int status, byte[] pdu, Message result)3754     public void writeSmsToRuim(int status, byte[] pdu, Message result) {
3755         status = translateStatus(status);
3756         IRadio radioProxy = getRadioProxy(result);
3757         if (radioProxy != null) {
3758             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, result,
3759                     mRILDefaultWorkSource);
3760 
3761             if (RILJ_LOGV) {
3762                 riljLog(rr.serialString() + "> "
3763                         + requestToString(rr.mRequest)
3764                         + " status = " + status);
3765             }
3766 
3767             CdmaSmsWriteArgs args = new CdmaSmsWriteArgs();
3768             args.status = status;
3769             constructCdmaSendSmsRilRequest(args.message, pdu);
3770 
3771             try {
3772                 radioProxy.writeSmsToRuim(rr.mSerial, args);
3773             } catch (RemoteException | RuntimeException e) {
3774                 handleRadioProxyExceptionForRR(rr, "writeSmsToRuim", e);
3775             }
3776         }
3777     }
3778 
3779     @Override
deleteSmsOnRuim(int index, Message result)3780     public void deleteSmsOnRuim(int index, Message result) {
3781         IRadio radioProxy = getRadioProxy(result);
3782         if (radioProxy != null) {
3783             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, result,
3784                     mRILDefaultWorkSource);
3785 
3786             if (RILJ_LOGV) {
3787                 riljLog(rr.serialString() + "> "
3788                         + requestToString(rr.mRequest)
3789                         + " index = " + index);
3790             }
3791 
3792             try {
3793                 radioProxy.deleteSmsOnRuim(rr.mSerial, index);
3794             } catch (RemoteException | RuntimeException e) {
3795                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnRuim", e);
3796             }
3797         }
3798     }
3799 
3800     @Override
getDeviceIdentity(Message result)3801     public void getDeviceIdentity(Message result) {
3802         IRadio radioProxy = getRadioProxy(result);
3803         if (radioProxy != null) {
3804             RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
3805                     mRILDefaultWorkSource);
3806 
3807             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3808 
3809             try {
3810                 radioProxy.getDeviceIdentity(rr.mSerial);
3811             } catch (RemoteException | RuntimeException e) {
3812                 handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
3813             }
3814         }
3815     }
3816 
3817     @Override
exitEmergencyCallbackMode(Message result)3818     public void exitEmergencyCallbackMode(Message result) {
3819         IRadio radioProxy = getRadioProxy(result);
3820         if (radioProxy != null) {
3821             RILRequest rr = obtainRequest(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, result,
3822                     mRILDefaultWorkSource);
3823 
3824             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3825 
3826             try {
3827                 radioProxy.exitEmergencyCallbackMode(rr.mSerial);
3828             } catch (RemoteException | RuntimeException e) {
3829                 handleRadioProxyExceptionForRR(rr, "exitEmergencyCallbackMode", e);
3830             }
3831         }
3832     }
3833 
3834     @Override
getSmscAddress(Message result)3835     public void getSmscAddress(Message result) {
3836         IRadio radioProxy = getRadioProxy(result);
3837         if (radioProxy != null) {
3838             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SMSC_ADDRESS, result,
3839                     mRILDefaultWorkSource);
3840 
3841             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3842 
3843             try {
3844                 radioProxy.getSmscAddress(rr.mSerial);
3845             } catch (RemoteException | RuntimeException e) {
3846                 handleRadioProxyExceptionForRR(rr, "getSmscAddress", e);
3847             }
3848         }
3849     }
3850 
3851     @Override
setSmscAddress(String address, Message result)3852     public void setSmscAddress(String address, Message result) {
3853         IRadio radioProxy = getRadioProxy(result);
3854         if (radioProxy != null) {
3855             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SMSC_ADDRESS, result,
3856                     mRILDefaultWorkSource);
3857 
3858             if (RILJ_LOGD) {
3859                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3860                         + " address = " + address);
3861             }
3862 
3863             try {
3864                 radioProxy.setSmscAddress(rr.mSerial, convertNullToEmptyString(address));
3865             } catch (RemoteException | RuntimeException e) {
3866                 handleRadioProxyExceptionForRR(rr, "setSmscAddress", e);
3867             }
3868         }
3869     }
3870 
3871     @Override
reportSmsMemoryStatus(boolean available, Message result)3872     public void reportSmsMemoryStatus(boolean available, Message result) {
3873         IRadio radioProxy = getRadioProxy(result);
3874         if (radioProxy != null) {
3875             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result,
3876                     mRILDefaultWorkSource);
3877 
3878             if (RILJ_LOGD) {
3879                 riljLog(rr.serialString() + "> "
3880                         + requestToString(rr.mRequest) + " available = " + available);
3881             }
3882 
3883             try {
3884                 radioProxy.reportSmsMemoryStatus(rr.mSerial, available);
3885             } catch (RemoteException | RuntimeException e) {
3886                 handleRadioProxyExceptionForRR(rr, "reportSmsMemoryStatus", e);
3887             }
3888         }
3889     }
3890 
3891     @Override
reportStkServiceIsRunning(Message result)3892     public void reportStkServiceIsRunning(Message result) {
3893         IRadio radioProxy = getRadioProxy(result);
3894         if (radioProxy != null) {
3895             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result,
3896                     mRILDefaultWorkSource);
3897 
3898             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3899 
3900             try {
3901                 radioProxy.reportStkServiceIsRunning(rr.mSerial);
3902             } catch (RemoteException | RuntimeException e) {
3903                 handleRadioProxyExceptionForRR(rr, "reportStkServiceIsRunning", e);
3904             }
3905         }
3906     }
3907 
3908     @Override
getCdmaSubscriptionSource(Message result)3909     public void getCdmaSubscriptionSource(Message result) {
3910         IRadio radioProxy = getRadioProxy(result);
3911         if (radioProxy != null) {
3912             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, result,
3913                     mRILDefaultWorkSource);
3914 
3915             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3916 
3917             try {
3918                 radioProxy.getCdmaSubscriptionSource(rr.mSerial);
3919             } catch (RemoteException | RuntimeException e) {
3920                 handleRadioProxyExceptionForRR(rr, "getCdmaSubscriptionSource", e);
3921             }
3922         }
3923     }
3924 
3925     @Override
acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result)3926     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
3927         IRadio radioProxy = getRadioProxy(result);
3928         if (radioProxy != null) {
3929             RILRequest rr = obtainRequest(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result,
3930                     mRILDefaultWorkSource);
3931 
3932             if (RILJ_LOGD) {
3933                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3934                         + " success = " + success);
3935             }
3936 
3937             try {
3938                 radioProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
3939                         convertNullToEmptyString(ackPdu));
3940             } catch (RemoteException | RuntimeException e) {
3941                 handleRadioProxyExceptionForRR(rr, "acknowledgeIncomingGsmSmsWithPdu", e);
3942             }
3943         }
3944     }
3945 
3946     @Override
getVoiceRadioTechnology(Message result)3947     public void getVoiceRadioTechnology(Message result) {
3948         IRadio radioProxy = getRadioProxy(result);
3949         if (radioProxy != null) {
3950             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_RADIO_TECH, result,
3951                     mRILDefaultWorkSource);
3952 
3953             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3954 
3955             try {
3956                 radioProxy.getVoiceRadioTechnology(rr.mSerial);
3957             } catch (RemoteException | RuntimeException e) {
3958                 handleRadioProxyExceptionForRR(rr, "getVoiceRadioTechnology", e);
3959             }
3960         }
3961     }
3962 
3963     @Override
getCellInfoList(Message result, WorkSource workSource)3964     public void getCellInfoList(Message result, WorkSource workSource) {
3965         workSource = getDeafultWorkSourceIfInvalid(workSource);
3966         IRadio radioProxy = getRadioProxy(result);
3967         if (radioProxy != null) {
3968             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CELL_INFO_LIST, result,
3969                     workSource);
3970 
3971             if (RILJ_LOGD) {
3972                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3973             }
3974 
3975             try {
3976                 radioProxy.getCellInfoList(rr.mSerial);
3977             } catch (RemoteException | RuntimeException e) {
3978                 handleRadioProxyExceptionForRR(rr, "getCellInfoList", e);
3979             }
3980         }
3981     }
3982 
3983     @Override
setCellInfoListRate(int rateInMillis, Message result, WorkSource workSource)3984     public void setCellInfoListRate(int rateInMillis, Message result, WorkSource workSource) {
3985         workSource = getDeafultWorkSourceIfInvalid(workSource);
3986         IRadio radioProxy = getRadioProxy(result);
3987         if (radioProxy != null) {
3988             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, result,
3989                     workSource);
3990 
3991             if (RILJ_LOGD) {
3992                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3993                         + " rateInMillis = " + rateInMillis);
3994             }
3995 
3996             try {
3997                 radioProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
3998             } catch (RemoteException | RuntimeException e) {
3999                 handleRadioProxyExceptionForRR(rr, "setCellInfoListRate", e);
4000             }
4001         }
4002     }
4003 
4004     @Override
setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result)4005     public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result) {
4006 
4007         IRadio radioProxy = getRadioProxy(result);
4008         if (radioProxy != null) {
4009             RILRequest rr = obtainRequest(RIL_REQUEST_SET_INITIAL_ATTACH_APN, result,
4010                     mRILDefaultWorkSource);
4011 
4012             if (RILJ_LOGD) {
4013                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + dataProfile);
4014             }
4015 
4016             try {
4017                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
4018                     // v1.5
4019                     android.hardware.radio.V1_5.IRadio radioProxy15 =
4020                             (android.hardware.radio.V1_5.IRadio) radioProxy;
4021                     radioProxy15.setInitialAttachApn_1_5(rr.mSerial,
4022                             convertToHalDataProfile15(dataProfile));
4023                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
4024                     // v1.4
4025                     android.hardware.radio.V1_4.IRadio radioProxy14 =
4026                             (android.hardware.radio.V1_4.IRadio) radioProxy;
4027                     radioProxy14.setInitialAttachApn_1_4(rr.mSerial,
4028                             convertToHalDataProfile14(dataProfile));
4029                 } else {
4030                     // v1.3, v1.2, v1.1, and v1.0
4031                     radioProxy.setInitialAttachApn(rr.mSerial,
4032                             convertToHalDataProfile10(dataProfile), dataProfile.isPersistent(),
4033                             isRoaming);
4034                 }
4035             } catch (RemoteException | RuntimeException e) {
4036                 handleRadioProxyExceptionForRR(rr, "setInitialAttachApn", e);
4037             }
4038         }
4039     }
4040 
4041     @Override
getImsRegistrationState(Message result)4042     public void getImsRegistrationState(Message result) {
4043         IRadio radioProxy = getRadioProxy(result);
4044         if (radioProxy != null) {
4045             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_REGISTRATION_STATE, result,
4046                     mRILDefaultWorkSource);
4047 
4048             if (RILJ_LOGD) {
4049                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4050             }
4051 
4052             try {
4053                 radioProxy.getImsRegistrationState(rr.mSerial);
4054             } catch (RemoteException | RuntimeException e) {
4055                 handleRadioProxyExceptionForRR(rr, "getImsRegistrationState", e);
4056             }
4057         }
4058     }
4059 
4060     @Override
sendImsGsmSms(String smscPdu, String pdu, int retry, int messageRef, Message result)4061     public void sendImsGsmSms(String smscPdu, String pdu, int retry, int messageRef,
4062                    Message result) {
4063         IRadio radioProxy = getRadioProxy(result);
4064         if (radioProxy != null) {
4065             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
4066                     mRILDefaultWorkSource);
4067 
4068             // Do not log function args for privacy
4069             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4070 
4071             ImsSmsMessage msg = new ImsSmsMessage();
4072             msg.tech = RILConstants.GSM_PHONE;
4073             msg.retry = (byte) retry >= 1 ? true : false;
4074             msg.messageRef = messageRef;
4075 
4076             GsmSmsMessage gsmMsg = constructGsmSendSmsRilRequest(smscPdu, pdu);
4077             msg.gsmMessage.add(gsmMsg);
4078             try {
4079                 radioProxy.sendImsSms(rr.mSerial, msg);
4080                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
4081                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
4082             } catch (RemoteException | RuntimeException e) {
4083                 handleRadioProxyExceptionForRR(rr, "sendImsGsmSms", e);
4084             }
4085         }
4086     }
4087 
4088     @Override
sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message result)4089     public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message result) {
4090         IRadio radioProxy = getRadioProxy(result);
4091         if (radioProxy != null) {
4092             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
4093                     mRILDefaultWorkSource);
4094 
4095             // Do not log function args for privacy
4096             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4097 
4098             ImsSmsMessage msg = new ImsSmsMessage();
4099             msg.tech = RILConstants.CDMA_PHONE;
4100             msg.retry = (byte) retry >= 1 ? true : false;
4101             msg.messageRef = messageRef;
4102 
4103             CdmaSmsMessage cdmaMsg = new CdmaSmsMessage();
4104             constructCdmaSendSmsRilRequest(cdmaMsg, pdu);
4105             msg.cdmaMessage.add(cdmaMsg);
4106 
4107             try {
4108                 radioProxy.sendImsSms(rr.mSerial, msg);
4109                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
4110                         SmsSession.Event.Format.SMS_FORMAT_3GPP2);
4111             } catch (RemoteException | RuntimeException e) {
4112                 handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
4113             }
4114         }
4115     }
4116 
createSimApdu(int channel, int cla, int instruction, int p1, int p2, int p3, String data)4117     private SimApdu createSimApdu(int channel, int cla, int instruction, int p1, int p2, int p3,
4118                                   String data) {
4119         SimApdu msg = new SimApdu();
4120         msg.sessionId = channel;
4121         msg.cla = cla;
4122         msg.instruction = instruction;
4123         msg.p1 = p1;
4124         msg.p2 = p2;
4125         msg.p3 = p3;
4126         msg.data = convertNullToEmptyString(data);
4127         return msg;
4128     }
4129 
4130     @Override
iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3, String data, Message result)4131     public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
4132                                             int p3, String data, Message result) {
4133         IRadio radioProxy = getRadioProxy(result);
4134         if (radioProxy != null) {
4135             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, result,
4136                     mRILDefaultWorkSource);
4137 
4138             if (RILJ_LOGD) {
4139                 if (TelephonyUtils.IS_DEBUGGABLE) {
4140                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4141                             + String.format(" cla = 0x%02X ins = 0x%02X", cla, instruction)
4142                             + String.format(" p1 = 0x%02X p2 = 0x%02X p3 = 0x%02X", p1, p2, p3)
4143                             + " data = " + data);
4144                 } else {
4145                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4146                 }
4147             }
4148 
4149             SimApdu msg = createSimApdu(0, cla, instruction, p1, p2, p3, data);
4150             try {
4151                 radioProxy.iccTransmitApduBasicChannel(rr.mSerial, msg);
4152             } catch (RemoteException | RuntimeException e) {
4153                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduBasicChannel", e);
4154             }
4155         }
4156     }
4157 
4158     @Override
iccOpenLogicalChannel(String aid, int p2, Message result)4159     public void iccOpenLogicalChannel(String aid, int p2, Message result) {
4160         IRadio radioProxy = getRadioProxy(result);
4161         if (radioProxy != null) {
4162             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_OPEN_CHANNEL, result,
4163                     mRILDefaultWorkSource);
4164 
4165             if (RILJ_LOGD) {
4166                 if (TelephonyUtils.IS_DEBUGGABLE) {
4167                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " aid = " + aid
4168                             + " p2 = " + p2);
4169                 } else {
4170                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4171                 }
4172             }
4173 
4174             try {
4175                 radioProxy.iccOpenLogicalChannel(rr.mSerial, convertNullToEmptyString(aid), p2);
4176             } catch (RemoteException | RuntimeException e) {
4177                 handleRadioProxyExceptionForRR(rr, "iccOpenLogicalChannel", e);
4178             }
4179         }
4180     }
4181 
4182     @Override
iccCloseLogicalChannel(int channel, Message result)4183     public void iccCloseLogicalChannel(int channel, Message result) {
4184         IRadio radioProxy = getRadioProxy(result);
4185         if (radioProxy != null) {
4186             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_CLOSE_CHANNEL, result,
4187                     mRILDefaultWorkSource);
4188 
4189             if (RILJ_LOGD) {
4190                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
4191                         + channel);
4192             }
4193 
4194             try {
4195                 radioProxy.iccCloseLogicalChannel(rr.mSerial, channel);
4196             } catch (RemoteException | RuntimeException e) {
4197                 handleRadioProxyExceptionForRR(rr, "iccCloseLogicalChannel", e);
4198             }
4199         }
4200     }
4201 
4202     @Override
iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2, int p3, String data, Message result)4203     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
4204                                               int p1, int p2, int p3, String data,
4205                                               Message result) {
4206         if (channel <= 0) {
4207             throw new RuntimeException(
4208                     "Invalid channel in iccTransmitApduLogicalChannel: " + channel);
4209         }
4210 
4211         IRadio radioProxy = getRadioProxy(result);
4212         if (radioProxy != null) {
4213             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, result,
4214                     mRILDefaultWorkSource);
4215 
4216             if (RILJ_LOGD) {
4217                 if (TelephonyUtils.IS_DEBUGGABLE) {
4218                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4219                             + String.format(" channel = %d", channel)
4220                             + String.format(" cla = 0x%02X ins = 0x%02X", cla, instruction)
4221                             + String.format(" p1 = 0x%02X p2 = 0x%02X p3 = 0x%02X", p1, p2, p3)
4222                             + " data = " + data);
4223                 } else {
4224                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4225                 }
4226             }
4227 
4228             SimApdu msg = createSimApdu(channel, cla, instruction, p1, p2, p3, data);
4229 
4230             try {
4231                 radioProxy.iccTransmitApduLogicalChannel(rr.mSerial, msg);
4232             } catch (RemoteException | RuntimeException e) {
4233                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduLogicalChannel", e);
4234             }
4235         }
4236     }
4237 
4238     @Override
nvReadItem(int itemID, Message result, WorkSource workSource)4239     public void nvReadItem(int itemID, Message result, WorkSource workSource) {
4240         workSource = getDeafultWorkSourceIfInvalid(workSource);
4241         IRadio radioProxy = getRadioProxy(result);
4242         if (radioProxy != null) {
4243             RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result,
4244                     workSource);
4245 
4246             if (RILJ_LOGD) {
4247                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4248                         + " itemId = " + itemID);
4249             }
4250 
4251             try {
4252                 radioProxy.nvReadItem(rr.mSerial, itemID);
4253             } catch (RemoteException | RuntimeException e) {
4254                 handleRadioProxyExceptionForRR(rr, "nvReadItem", e);
4255             }
4256         }
4257     }
4258 
4259     @Override
nvWriteItem(int itemId, String itemValue, Message result, WorkSource workSource)4260     public void nvWriteItem(int itemId, String itemValue, Message result, WorkSource workSource) {
4261         workSource = getDeafultWorkSourceIfInvalid(workSource);
4262         IRadio radioProxy = getRadioProxy(result);
4263         if (radioProxy != null) {
4264             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result,
4265                     workSource);
4266 
4267             if (RILJ_LOGD) {
4268                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4269                         + " itemId = " + itemId + " itemValue = " + itemValue);
4270             }
4271 
4272             NvWriteItem item = new NvWriteItem();
4273             item.itemId = itemId;
4274             item.value = convertNullToEmptyString(itemValue);
4275 
4276             try {
4277                 radioProxy.nvWriteItem(rr.mSerial, item);
4278             } catch (RemoteException | RuntimeException e) {
4279                 handleRadioProxyExceptionForRR(rr, "nvWriteItem", e);
4280             }
4281         }
4282     }
4283 
4284     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList, Message result)4285     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
4286         IRadio radioProxy = getRadioProxy(result);
4287         if (radioProxy != null) {
4288             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_CDMA_PRL, result,
4289                     mRILDefaultWorkSource);
4290 
4291             if (RILJ_LOGD) {
4292                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4293                         + " PreferredRoamingList = 0x"
4294                         + IccUtils.bytesToHexString(preferredRoamingList));
4295             }
4296 
4297             ArrayList<Byte> arrList = new ArrayList<>();
4298             for (int i = 0; i < preferredRoamingList.length; i++) {
4299                 arrList.add(preferredRoamingList[i]);
4300             }
4301 
4302             try {
4303                 radioProxy.nvWriteCdmaPrl(rr.mSerial, arrList);
4304             } catch (RemoteException | RuntimeException e) {
4305                 handleRadioProxyExceptionForRR(rr, "nvWriteCdmaPrl", e);
4306             }
4307         }
4308     }
4309 
4310     @Override
nvResetConfig(int resetType, Message result)4311     public void nvResetConfig(int resetType, Message result) {
4312         IRadio radioProxy = getRadioProxy(result);
4313         if (radioProxy != null) {
4314             RILRequest rr = obtainRequest(RIL_REQUEST_NV_RESET_CONFIG, result,
4315                     mRILDefaultWorkSource);
4316 
4317             if (RILJ_LOGD) {
4318                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4319                         + " resetType = " + resetType);
4320             }
4321 
4322             try {
4323                 radioProxy.nvResetConfig(rr.mSerial, convertToHalResetNvType(resetType));
4324             } catch (RemoteException | RuntimeException e) {
4325                 handleRadioProxyExceptionForRR(rr, "nvResetConfig", e);
4326             }
4327         }
4328     }
4329 
4330     @Override
setUiccSubscription(int slotId, int appIndex, int subId, int subStatus, Message result)4331     public void setUiccSubscription(int slotId, int appIndex, int subId,
4332                                     int subStatus, Message result) {
4333         IRadio radioProxy = getRadioProxy(result);
4334         if (radioProxy != null) {
4335             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UICC_SUBSCRIPTION, result,
4336                     mRILDefaultWorkSource);
4337 
4338             if (RILJ_LOGD) {
4339                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4340                         + " slot = " + slotId + " appIndex = " + appIndex
4341                         + " subId = " + subId + " subStatus = " + subStatus);
4342             }
4343 
4344             SelectUiccSub info = new SelectUiccSub();
4345             info.slot = slotId;
4346             info.appIndex = appIndex;
4347             info.subType = subId;
4348             info.actStatus = subStatus;
4349 
4350             try {
4351                 radioProxy.setUiccSubscription(rr.mSerial, info);
4352             } catch (RemoteException | RuntimeException e) {
4353                 handleRadioProxyExceptionForRR(rr, "setUiccSubscription", e);
4354             }
4355         }
4356     }
4357 
4358     @Override
setDataAllowed(boolean allowed, Message result)4359     public void setDataAllowed(boolean allowed, Message result) {
4360         IRadio radioProxy = getRadioProxy(result);
4361         if (radioProxy != null) {
4362             RILRequest rr = obtainRequest(RIL_REQUEST_ALLOW_DATA, result,
4363                     mRILDefaultWorkSource);
4364 
4365             if (RILJ_LOGD) {
4366                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4367                         + " allowed = " + allowed);
4368             }
4369 
4370             try {
4371                 radioProxy.setDataAllowed(rr.mSerial, allowed);
4372             } catch (RemoteException | RuntimeException e) {
4373                 handleRadioProxyExceptionForRR(rr, "setDataAllowed", e);
4374             }
4375         }
4376     }
4377 
4378     @Override
getHardwareConfig(Message result)4379     public void getHardwareConfig(Message result) {
4380         IRadio radioProxy = getRadioProxy(result);
4381         if (radioProxy != null) {
4382             RILRequest rr = obtainRequest(RIL_REQUEST_GET_HARDWARE_CONFIG, result,
4383                     mRILDefaultWorkSource);
4384 
4385             // Do not log function args for privacy
4386             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4387 
4388             try {
4389                 radioProxy.getHardwareConfig(rr.mSerial);
4390             } catch (RemoteException | RuntimeException e) {
4391                 handleRadioProxyExceptionForRR(rr, "getHardwareConfig", e);
4392             }
4393         }
4394     }
4395 
4396     @Override
requestIccSimAuthentication(int authContext, String data, String aid, Message result)4397     public void requestIccSimAuthentication(int authContext, String data, String aid,
4398                                             Message result) {
4399         IRadio radioProxy = getRadioProxy(result);
4400         if (radioProxy != null) {
4401             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_AUTHENTICATION, result,
4402                     mRILDefaultWorkSource);
4403 
4404             // Do not log function args for privacy
4405             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4406 
4407             try {
4408                 radioProxy.requestIccSimAuthentication(rr.mSerial,
4409                         authContext,
4410                         convertNullToEmptyString(data),
4411                         convertNullToEmptyString(aid));
4412             } catch (RemoteException | RuntimeException e) {
4413                 handleRadioProxyExceptionForRR(rr, "requestIccSimAuthentication", e);
4414             }
4415         }
4416     }
4417 
4418     @Override
setDataProfile(DataProfile[] dps, boolean isRoaming, Message result)4419     public void setDataProfile(DataProfile[] dps, boolean isRoaming, Message result) {
4420 
4421         IRadio radioProxy = getRadioProxy(result);
4422         if (radioProxy != null) {
4423 
4424             RILRequest rr = null;
4425             try {
4426                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
4427                     // V1.5
4428                     android.hardware.radio.V1_5.IRadio radioProxy15 =
4429                             (android.hardware.radio.V1_5.IRadio) radioProxy;
4430 
4431                     rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
4432                             mRILDefaultWorkSource);
4433 
4434                     ArrayList<android.hardware.radio.V1_5.DataProfileInfo> dpis = new ArrayList<>();
4435                     for (DataProfile dp : dps) {
4436                         dpis.add(convertToHalDataProfile15(dp));
4437                     }
4438 
4439                     if (RILJ_LOGD) {
4440                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4441                                 + " with data profiles : ");
4442                         for (DataProfile profile : dps) {
4443                             riljLog(profile.toString());
4444                         }
4445                     }
4446 
4447                     radioProxy15.setDataProfile_1_5(rr.mSerial, dpis);
4448                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
4449                     // V1.4
4450                     android.hardware.radio.V1_4.IRadio radioProxy14 =
4451                             (android.hardware.radio.V1_4.IRadio) radioProxy;
4452 
4453                     rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
4454                             mRILDefaultWorkSource);
4455 
4456                     ArrayList<android.hardware.radio.V1_4.DataProfileInfo> dpis = new ArrayList<>();
4457                     for (DataProfile dp : dps) {
4458                         dpis.add(convertToHalDataProfile14(dp));
4459                     }
4460 
4461                     if (RILJ_LOGD) {
4462                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4463                                 + " with data profiles : ");
4464                         for (DataProfile profile : dps) {
4465                             riljLog(profile.toString());
4466                         }
4467                     }
4468 
4469                     radioProxy14.setDataProfile_1_4(rr.mSerial, dpis);
4470                 } else {
4471                     // V1.0, 1.1, 1,2 and 1.3
4472                     ArrayList<android.hardware.radio.V1_0.DataProfileInfo> dpis = new ArrayList<>();
4473                     for (DataProfile dp : dps) {
4474                         // For v1.0 to v1.2, we only send data profiles that has the persistent
4475                         // (a.k.a modem cognitive) bit set to true.
4476                         if (dp.isPersistent()) {
4477                             dpis.add(convertToHalDataProfile10(dp));
4478                         }
4479                     }
4480 
4481                     if (!dpis.isEmpty()) {
4482                         rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
4483                                 mRILDefaultWorkSource);
4484 
4485                         if (RILJ_LOGD) {
4486                             riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4487                                     + " with data profiles : ");
4488                             for (DataProfile profile : dps) {
4489                                 riljLog(profile.toString());
4490                             }
4491                         }
4492 
4493                         radioProxy.setDataProfile(rr.mSerial, dpis, isRoaming);
4494                     }
4495                 }
4496             } catch (RemoteException | RuntimeException e) {
4497                 handleRadioProxyExceptionForRR(rr, "setDataProfile", e);
4498             }
4499         }
4500     }
4501 
4502     @Override
requestShutdown(Message result)4503     public void requestShutdown(Message result) {
4504         IRadio radioProxy = getRadioProxy(result);
4505         if (radioProxy != null) {
4506             RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result,
4507                     mRILDefaultWorkSource);
4508 
4509             if (RILJ_LOGD) {
4510                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4511             }
4512 
4513             try {
4514                 radioProxy.requestShutdown(rr.mSerial);
4515             } catch (RemoteException | RuntimeException e) {
4516                 handleRadioProxyExceptionForRR(rr, "requestShutdown", e);
4517             }
4518         }
4519     }
4520 
4521     @Override
getRadioCapability(Message response)4522     public void getRadioCapability(Message response) {
4523         IRadio radioProxy = getRadioProxy(response);
4524         if (radioProxy != null) {
4525             RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, response,
4526                     mRILDefaultWorkSource);
4527 
4528             if (RILJ_LOGD) {
4529                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4530             }
4531 
4532             try {
4533                 radioProxy.getRadioCapability(rr.mSerial);
4534             } catch (RemoteException | RuntimeException e) {
4535                 handleRadioProxyExceptionForRR(rr, "getRadioCapability", e);
4536             }
4537         }
4538     }
4539 
4540     @Override
setRadioCapability(RadioCapability rc, Message response)4541     public void setRadioCapability(RadioCapability rc, Message response) {
4542         IRadio radioProxy = getRadioProxy(response);
4543         if (radioProxy != null) {
4544             RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, response,
4545                     mRILDefaultWorkSource);
4546 
4547             if (RILJ_LOGD) {
4548                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4549                         + " RadioCapability = " + rc.toString());
4550             }
4551 
4552             android.hardware.radio.V1_0.RadioCapability halRc =
4553                     new android.hardware.radio.V1_0.RadioCapability();
4554 
4555             halRc.session = rc.getSession();
4556             halRc.phase = rc.getPhase();
4557             halRc.raf = rc.getRadioAccessFamily();
4558             halRc.logicalModemUuid = convertNullToEmptyString(rc.getLogicalModemUuid());
4559             halRc.status = rc.getStatus();
4560 
4561             try {
4562                 radioProxy.setRadioCapability(rr.mSerial, halRc);
4563             } catch (Exception e) {
4564                 handleRadioProxyExceptionForRR(rr, "setRadioCapability", e);
4565             }
4566         }
4567     }
4568 
4569     @Override
startLceService(int reportIntervalMs, boolean pullMode, Message result)4570     public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
4571         IRadio radioProxy = getRadioProxy(result);
4572 
4573         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
4574             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control path is unused.
4575             // Instead the LCE functionality is always-on and provides unsolicited indications.
4576             return;
4577         }
4578 
4579         if (radioProxy != null) {
4580             RILRequest rr = obtainRequest(RIL_REQUEST_START_LCE, result,
4581                     mRILDefaultWorkSource);
4582 
4583             if (RILJ_LOGD) {
4584                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
4585                         + " reportIntervalMs = " + reportIntervalMs + " pullMode = " + pullMode);
4586             }
4587 
4588             try {
4589                 radioProxy.startLceService(rr.mSerial, reportIntervalMs, pullMode);
4590             } catch (RemoteException | RuntimeException e) {
4591                 handleRadioProxyExceptionForRR(rr, "startLceService", e);
4592             }
4593         }
4594     }
4595 
4596     @Override
stopLceService(Message result)4597     public void stopLceService(Message result) {
4598         IRadio radioProxy = getRadioProxy(result);
4599         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
4600             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control is unused.
4601             // Instead the LCE functionality is always-on and provides unsolicited indications.
4602             return;
4603         }
4604 
4605         if (radioProxy != null) {
4606             RILRequest rr = obtainRequest(RIL_REQUEST_STOP_LCE, result,
4607                     mRILDefaultWorkSource);
4608 
4609             if (RILJ_LOGD) {
4610                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4611             }
4612 
4613             try {
4614                 radioProxy.stopLceService(rr.mSerial);
4615             } catch (RemoteException | RuntimeException e) {
4616                 handleRadioProxyExceptionForRR(rr, "stopLceService", e);
4617             }
4618         }
4619     }
4620 
4621     /**
4622      * This will only be called if the LCE service is started in PULL mode, which is
4623      * only enabled when using Radio HAL versions 1.1 and earlier.
4624      *
4625      * It is still possible for vendors to override this behavior and use the 1.1 version
4626      * of LCE; however, this is strongly discouraged and this functionality will be removed
4627      * when HAL 1.x support is dropped.
4628      *
4629      * @deprecated HAL 1.2 and later use an always-on LCE that relies on indications.
4630      */
4631     @Deprecated
4632     @Override
pullLceData(Message response)4633     public void pullLceData(Message response) {
4634         IRadio radioProxy = getRadioProxy(response);
4635         if (radioProxy != null) {
4636             RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, response,
4637                     mRILDefaultWorkSource);
4638 
4639             if (RILJ_LOGD) {
4640                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4641             }
4642 
4643             try {
4644                 radioProxy.pullLceData(rr.mSerial);
4645             } catch (RemoteException | RuntimeException e) {
4646                 handleRadioProxyExceptionForRR(rr, "pullLceData", e);
4647             }
4648         }
4649     }
4650 
4651     @Override
getModemActivityInfo(Message result, WorkSource workSource)4652     public void getModemActivityInfo(Message result, WorkSource workSource) {
4653         workSource = getDeafultWorkSourceIfInvalid(workSource);
4654         IRadio radioProxy = getRadioProxy(result);
4655         if (radioProxy != null) {
4656             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
4657                     workSource);
4658 
4659             if (RILJ_LOGD) {
4660                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4661             }
4662 
4663             try {
4664                 radioProxy.getModemActivityInfo(rr.mSerial);
4665 
4666                 Message msg = mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT);
4667                 msg.obj = null;
4668                 msg.arg1 = rr.mSerial;
4669                 mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
4670             } catch (RemoteException | RuntimeException e) {
4671                 handleRadioProxyExceptionForRR(rr, "getModemActivityInfo", e);
4672             }
4673         }
4674 
4675 
4676     }
4677 
4678     /**
4679      * Convert a list of CarrierIdentifier into a list of Carrier defined in 1.0/types.hal.
4680      * @param carriers List of CarrierIdentifier
4681      * @return List of converted objects
4682      */
4683     @VisibleForTesting
createCarrierRestrictionList( List<CarrierIdentifier> carriers)4684     public static ArrayList<Carrier> createCarrierRestrictionList(
4685             List<CarrierIdentifier> carriers) {
4686         ArrayList<Carrier> result = new ArrayList<>();
4687         for (CarrierIdentifier ci : carriers) {
4688             Carrier c = new Carrier();
4689             c.mcc = convertNullToEmptyString(ci.getMcc());
4690             c.mnc = convertNullToEmptyString(ci.getMnc());
4691             int matchType = CarrierIdentifier.MatchType.ALL;
4692             String matchData = null;
4693             if (!TextUtils.isEmpty(ci.getSpn())) {
4694                 matchType = CarrierIdentifier.MatchType.SPN;
4695                 matchData = ci.getSpn();
4696             } else if (!TextUtils.isEmpty(ci.getImsi())) {
4697                 matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
4698                 matchData = ci.getImsi();
4699             } else if (!TextUtils.isEmpty(ci.getGid1())) {
4700                 matchType = CarrierIdentifier.MatchType.GID1;
4701                 matchData = ci.getGid1();
4702             } else if (!TextUtils.isEmpty(ci.getGid2())) {
4703                 matchType = CarrierIdentifier.MatchType.GID2;
4704                 matchData = ci.getGid2();
4705             }
4706             c.matchType = matchType;
4707             c.matchData = convertNullToEmptyString(matchData);
4708             result.add(c);
4709         }
4710         return result;
4711     }
4712 
4713     @Override
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules, Message result, WorkSource workSource)4714     public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
4715             Message result, WorkSource workSource) {
4716         riljLog("RIL.java - setAllowedCarriers");
4717 
4718         checkNotNull(carrierRestrictionRules, "Carrier restriction cannot be null.");
4719         workSource = getDeafultWorkSourceIfInvalid(workSource);
4720 
4721         IRadio radioProxy = getRadioProxy(result);
4722         if (radioProxy == null) return;
4723 
4724         RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result, workSource);
4725 
4726         if (RILJ_LOGD) {
4727             riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " params: "
4728                     + carrierRestrictionRules);
4729         }
4730 
4731         // Extract multisim policy
4732         int policy = SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
4733         switch (carrierRestrictionRules.getMultiSimPolicy()) {
4734             case CarrierRestrictionRules.MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT:
4735                 policy = SimLockMultiSimPolicy.ONE_VALID_SIM_MUST_BE_PRESENT;
4736                 break;
4737         }
4738 
4739         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
4740             riljLog("RIL.java - Using IRadio 1.4 or greater");
4741 
4742             android.hardware.radio.V1_4.IRadio radioProxy14 =
4743                     (android.hardware.radio.V1_4.IRadio) radioProxy;
4744 
4745             // Prepare structure with allowed list, excluded list and priority
4746             CarrierRestrictionsWithPriority carrierRestrictions =
4747                     new CarrierRestrictionsWithPriority();
4748             carrierRestrictions.allowedCarriers =
4749                     createCarrierRestrictionList(carrierRestrictionRules.getAllowedCarriers());
4750             carrierRestrictions.excludedCarriers =
4751                     createCarrierRestrictionList(carrierRestrictionRules.getExcludedCarriers());
4752             carrierRestrictions.allowedCarriersPrioritized =
4753                     (carrierRestrictionRules.getDefaultCarrierRestriction()
4754                         == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED);
4755 
4756             try {
4757                 radioProxy14.setAllowedCarriers_1_4(rr.mSerial, carrierRestrictions, policy);
4758             } catch (RemoteException | RuntimeException e) {
4759                 handleRadioProxyExceptionForRR(rr, "setAllowedCarriers_1_4", e);
4760             }
4761         } else {
4762             boolean isAllCarriersAllowed = carrierRestrictionRules.isAllCarriersAllowed();
4763 
4764             boolean supported = (isAllCarriersAllowed
4765                     || (carrierRestrictionRules.getExcludedCarriers().isEmpty()
4766                         && (carrierRestrictionRules.getDefaultCarrierRestriction()
4767                             == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED)));
4768             supported = supported && (policy == SimLockMultiSimPolicy.NO_MULTISIM_POLICY);
4769 
4770             if (!supported) {
4771                 // Feature is not supported by IRadio interface
4772                 riljLoge("setAllowedCarriers does not support excluded list on IRadio version"
4773                         + " less than 1.4");
4774                 if (result != null) {
4775                     AsyncResult.forMessage(result, null,
4776                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
4777                     result.sendToTarget();
4778                 }
4779                 return;
4780             }
4781             riljLog("RIL.java - Using IRadio 1.3 or lower");
4782 
4783             // Prepare structure with allowed list
4784             CarrierRestrictions carrierRestrictions = new CarrierRestrictions();
4785             carrierRestrictions.allowedCarriers =
4786                     createCarrierRestrictionList(carrierRestrictionRules.getAllowedCarriers());
4787 
4788             try {
4789                 radioProxy.setAllowedCarriers(rr.mSerial, isAllCarriersAllowed,
4790                         carrierRestrictions);
4791             } catch (RemoteException | RuntimeException e) {
4792                 handleRadioProxyExceptionForRR(rr, "setAllowedCarriers", e);
4793             }
4794         }
4795     }
4796 
4797     @Override
getAllowedCarriers(Message result, WorkSource workSource)4798     public void getAllowedCarriers(Message result, WorkSource workSource) {
4799         workSource = getDeafultWorkSourceIfInvalid(workSource);
4800 
4801         IRadio radioProxy = getRadioProxy(result);
4802         if (radioProxy == null) return;
4803 
4804         RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result,
4805                 workSource);
4806 
4807         if (RILJ_LOGD) {
4808             riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4809         }
4810 
4811         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
4812             riljLog("RIL.java - Using IRadio 1.4 or greater");
4813 
4814             android.hardware.radio.V1_4.IRadio radioProxy14 =
4815                     (android.hardware.radio.V1_4.IRadio) radioProxy;
4816 
4817             try {
4818                 radioProxy14.getAllowedCarriers_1_4(rr.mSerial);
4819             } catch (RemoteException | RuntimeException e) {
4820                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers_1_4", e);
4821             }
4822         } else {
4823             riljLog("RIL.java - Using IRadio 1.3 or lower");
4824 
4825             try {
4826                 radioProxy.getAllowedCarriers(rr.mSerial);
4827             } catch (RemoteException | RuntimeException e) {
4828                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
4829             }
4830         }
4831     }
4832 
4833     @Override
sendDeviceState(int stateType, boolean state, Message result)4834     public void sendDeviceState(int stateType, boolean state,
4835                                 Message result) {
4836         IRadio radioProxy = getRadioProxy(result);
4837         if (radioProxy != null) {
4838             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
4839                     mRILDefaultWorkSource);
4840 
4841             if (RILJ_LOGD) {
4842                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
4843                         + stateType + ":" + state);
4844             }
4845 
4846             try {
4847                 radioProxy.sendDeviceState(rr.mSerial, stateType, state);
4848             } catch (RemoteException | RuntimeException e) {
4849                 handleRadioProxyExceptionForRR(rr, "sendDeviceState", e);
4850             }
4851         }
4852     }
4853 
4854     @Override
setUnsolResponseFilter(int filter, Message result)4855     public void setUnsolResponseFilter(int filter, Message result) {
4856         IRadio radioProxy = getRadioProxy(result);
4857         if (radioProxy != null) {
4858             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, result,
4859                     mRILDefaultWorkSource);
4860 
4861             if (RILJ_LOGD) {
4862                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + filter);
4863             }
4864 
4865             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
4866                 try {
4867                     android.hardware.radio.V1_5.IRadio radioProxy15 =
4868                             (android.hardware.radio.V1_5.IRadio) radioProxy;
4869 
4870                     filter &= INDICATION_FILTERS_ALL_V1_5;
4871                     radioProxy15.setIndicationFilter_1_5(rr.mSerial, filter);
4872                 } catch (RemoteException | RuntimeException e) {
4873                     handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_5", e);
4874                 }
4875             } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
4876                 try {
4877                     android.hardware.radio.V1_2.IRadio radioProxy12 =
4878                             (android.hardware.radio.V1_2.IRadio) radioProxy;
4879 
4880                     filter &= INDICATION_FILTERS_ALL_V1_2;
4881                     radioProxy12.setIndicationFilter_1_2(rr.mSerial, filter);
4882                 } catch (RemoteException | RuntimeException e) {
4883                     handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_2", e);
4884                 }
4885             } else {
4886                 try {
4887                     filter &= INDICATION_FILTERS_ALL_V1_0;
4888                     radioProxy.setIndicationFilter(rr.mSerial, filter);
4889                 } catch (RemoteException | RuntimeException e) {
4890                     handleRadioProxyExceptionForRR(rr, "setIndicationFilter", e);
4891                 }
4892             }
4893         }
4894     }
4895 
4896     @Override
setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo, int ran, Message result)4897     public void setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo,
4898             int ran, Message result) {
4899         IRadio radioProxy = getRadioProxy(result);
4900         if (radioProxy != null) {
4901             if (mRadioVersion.less(RADIO_HAL_VERSION_1_2)) {
4902                 riljLoge("setSignalStrengthReportingCriteria ignored on IRadio version less "
4903                         + "than 1.2");
4904                 return;
4905             }
4906             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)
4907                     && mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
4908                 RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
4909                         result, mRILDefaultWorkSource);
4910                 if (RILJ_LOGD) {
4911                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4912                 }
4913                 try {
4914                     android.hardware.radio.V1_2.IRadio radioProxy12 =
4915                         (android.hardware.radio.V1_2.IRadio) radioProxy;
4916                     radioProxy12.setSignalStrengthReportingCriteria(rr.mSerial,
4917                             signalThresholdInfo.getHysteresisMs(),
4918                             signalThresholdInfo.getHysteresisDb(),
4919                             primitiveArrayToArrayList(signalThresholdInfo.getThresholds()),
4920                             convertAntToHalAnt(ran));
4921                 } catch (RemoteException | RuntimeException e) {
4922                     handleRadioProxyExceptionForRR(rr, "setSignalStrengthReportingCriteria", e);
4923                 }
4924             }
4925             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
4926                 RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
4927                         result, mRILDefaultWorkSource);
4928                 if (RILJ_LOGD) {
4929                     riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4930                 }
4931                 try {
4932                     android.hardware.radio.V1_5.IRadio radioProxy15 =
4933                             (android.hardware.radio.V1_5.IRadio) radioProxy;
4934                     radioProxy15.setSignalStrengthReportingCriteria_1_5(rr.mSerial,
4935                             convertToHalSignalThresholdInfo(signalThresholdInfo),
4936                             convertAntToHalAnt(ran));
4937                 } catch (RemoteException | RuntimeException e) {
4938                     handleRadioProxyExceptionForRR(
4939                             rr, "setSignalStrengthReportingCriteria_1_5", e);
4940                 }
4941             }
4942         }
4943     }
4944 
convertToHalSignalThresholdInfo( SignalThresholdInfo signalThresholdInfo)4945     private static android.hardware.radio.V1_5.SignalThresholdInfo convertToHalSignalThresholdInfo(
4946             SignalThresholdInfo signalThresholdInfo) {
4947         android.hardware.radio.V1_5.SignalThresholdInfo signalThresholdInfoHal =
4948                 new android.hardware.radio.V1_5.SignalThresholdInfo();
4949         signalThresholdInfoHal.signalMeasurement = signalThresholdInfo.getSignalMeasurement();
4950         signalThresholdInfoHal.hysteresisMs = signalThresholdInfo.getHysteresisMs();
4951         signalThresholdInfoHal.hysteresisDb = signalThresholdInfo.getHysteresisDb();
4952         signalThresholdInfoHal.thresholds = primitiveArrayToArrayList(
4953                 signalThresholdInfo.getThresholds());
4954         signalThresholdInfoHal.isEnabled = signalThresholdInfo.isEnabled();
4955         return signalThresholdInfoHal;
4956     }
4957 
4958     @Override
setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps, int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran, Message result)4959     public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
4960             int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
4961             Message result) {
4962         IRadio radioProxy = getRadioProxy(result);
4963         if (radioProxy != null) {
4964             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA, result,
4965                     mRILDefaultWorkSource);
4966             if (RILJ_LOGD) {
4967                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
4968             }
4969             try {
4970                 if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
4971                     android.hardware.radio.V1_5.IRadio radioProxy15 =
4972                             (android.hardware.radio.V1_5.IRadio) radioProxy;
4973                     radioProxy15.setLinkCapacityReportingCriteria_1_5(rr.mSerial, hysteresisMs,
4974                             hysteresisDlKbps, hysteresisUlKbps,
4975                             primitiveArrayToArrayList(thresholdsDlKbps),
4976                             primitiveArrayToArrayList(thresholdsUlKbps), convertAntToHalAnt(ran));
4977                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
4978                     android.hardware.radio.V1_2.IRadio radioProxy12 =
4979                             (android.hardware.radio.V1_2.IRadio) radioProxy;
4980                     if (ran == AccessNetworkType.NGRAN) {
4981                         throw new RuntimeException("NGRAN unsupported on IRadio version 1.2.");
4982                     }
4983                     radioProxy12.setLinkCapacityReportingCriteria(rr.mSerial, hysteresisMs,
4984                             hysteresisDlKbps, hysteresisUlKbps,
4985                             primitiveArrayToArrayList(thresholdsDlKbps),
4986                             primitiveArrayToArrayList(thresholdsUlKbps), convertAntToHalAnt(ran));
4987                 } else {
4988                     riljLoge("setLinkCapacityReportingCriteria ignored on IRadio version less "
4989                             + "than 1.2");
4990                 }
4991             } catch (RemoteException | RuntimeException e) {
4992                 handleRadioProxyExceptionForRR(rr, "setLinkCapacityReportingCriteria", e);
4993             }
4994         }
4995     }
4996 
4997     /** Converts from AccessNetworkType in frameworks to AccessNetwork in HAL. */
convertAntToHalAnt(int radioAccessNetwork)4998     private static int convertAntToHalAnt(int radioAccessNetwork) {
4999         switch (radioAccessNetwork) {
5000             case AccessNetworkType.GERAN:
5001                 return AccessNetwork.GERAN;
5002             case AccessNetworkType.UTRAN:
5003                 return AccessNetwork.UTRAN;
5004             case AccessNetworkType.EUTRAN:
5005                 return AccessNetwork.EUTRAN;
5006             case AccessNetworkType.CDMA2000:
5007                 return AccessNetwork.CDMA2000;
5008             case AccessNetworkType.IWLAN:
5009                 return AccessNetwork.IWLAN;
5010             case AccessNetworkType.NGRAN:
5011                 return AccessNetwork.NGRAN;
5012             case AccessNetworkType.UNKNOWN:
5013             default:
5014                 return AccessNetwork.UNKNOWN;
5015         }
5016     }
5017 
5018     /** Converts from AccessNetworkType in frameworks to RadioAccessNetworks in HAL. */
convertAntToRan(int accessNetworkType)5019     private static int convertAntToRan(int accessNetworkType) {
5020         switch (accessNetworkType) {
5021             case AccessNetworkType.GERAN:
5022                 return RadioAccessNetworks.GERAN;
5023             case AccessNetworkType.UTRAN:
5024                 return RadioAccessNetworks.UTRAN;
5025             case AccessNetworkType.EUTRAN:
5026                 return RadioAccessNetworks.EUTRAN;
5027             case AccessNetworkType.NGRAN:
5028                 return RadioAccessNetworks.NGRAN;
5029             case AccessNetworkType.CDMA2000:
5030                 return RadioAccessNetworks.CDMA2000;
5031             case AccessNetworkType.UNKNOWN:
5032             default:
5033                 return RadioAccessNetworks.UNKNOWN;
5034         }
5035     }
5036 
5037     @Override
setSimCardPower(int state, Message result, WorkSource workSource)5038     public void setSimCardPower(int state, Message result, WorkSource workSource) {
5039         workSource = getDeafultWorkSourceIfInvalid(workSource);
5040         IRadio radioProxy = getRadioProxy(result);
5041         if (radioProxy != null) {
5042             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIM_CARD_POWER, result,
5043                     workSource);
5044 
5045             if (RILJ_LOGD) {
5046                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + state);
5047             }
5048 
5049             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
5050                 try {
5051                     android.hardware.radio.V1_1.IRadio radioProxy11 =
5052                             (android.hardware.radio.V1_1.IRadio) radioProxy;
5053                     radioProxy11.setSimCardPower_1_1(rr.mSerial, state);
5054                 } catch (RemoteException | RuntimeException e) {
5055                     handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
5056                 }
5057             } else {
5058                 try {
5059                     switch (state) {
5060                         case TelephonyManager.CARD_POWER_DOWN: {
5061                             radioProxy.setSimCardPower(rr.mSerial, false);
5062                             break;
5063                         }
5064                         case TelephonyManager.CARD_POWER_UP: {
5065                             radioProxy.setSimCardPower(rr.mSerial, true);
5066                             break;
5067                         }
5068                         default: {
5069                             if (result != null) {
5070                                 AsyncResult.forMessage(result, null,
5071                                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5072                                 result.sendToTarget();
5073                             }
5074                         }
5075                     }
5076                 } catch (RemoteException | RuntimeException e) {
5077                     handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
5078                 }
5079             }
5080         }
5081     }
5082 
5083     @Override
setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo, Message result)5084     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
5085                                                 Message result) {
5086         checkNotNull(imsiEncryptionInfo, "ImsiEncryptionInfo cannot be null.");
5087         IRadio radioProxy = getRadioProxy(result);
5088         if (radioProxy != null) {
5089             if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
5090                 android.hardware.radio.V1_1.IRadio radioProxy11 =
5091                         (android.hardware.radio.V1_1.IRadio ) radioProxy;
5092 
5093                 RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
5094                         mRILDefaultWorkSource);
5095                 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5096 
5097                 try {
5098                     android.hardware.radio.V1_1.ImsiEncryptionInfo halImsiInfo =
5099                             new android.hardware.radio.V1_1.ImsiEncryptionInfo();
5100                     halImsiInfo.mnc = imsiEncryptionInfo.getMnc();
5101                     halImsiInfo.mcc = imsiEncryptionInfo.getMcc();
5102                     halImsiInfo.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
5103                     if (imsiEncryptionInfo.getExpirationTime() != null) {
5104                         halImsiInfo.expirationTime =
5105                                 imsiEncryptionInfo.getExpirationTime().getTime();
5106                     }
5107                     for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
5108                         halImsiInfo.carrierKey.add(new Byte(b));
5109                     }
5110 
5111                     radioProxy11.setCarrierInfoForImsiEncryption(
5112                             rr.mSerial, halImsiInfo);
5113                 } catch (RemoteException | RuntimeException e) {
5114                     handleRadioProxyExceptionForRR(rr, "setCarrierInfoForImsiEncryption", e);
5115                 }
5116             } else if (result != null) {
5117                 AsyncResult.forMessage(result, null,
5118                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5119                 result.sendToTarget();
5120             }
5121         }
5122     }
5123 
5124     @Override
startNattKeepalive( int contextId, KeepalivePacketData packetData, int intervalMillis, Message result)5125     public void startNattKeepalive(
5126             int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) {
5127         checkNotNull(packetData, "KeepaliveRequest cannot be null.");
5128         IRadio radioProxy = getRadioProxy(result);
5129         if (radioProxy == null) return;
5130 
5131         if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) {
5132             if (result != null) {
5133                 AsyncResult.forMessage(result, null,
5134                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5135                 result.sendToTarget();
5136             }
5137             return;
5138         }
5139 
5140         android.hardware.radio.V1_1.IRadio radioProxy11 =
5141                 (android.hardware.radio.V1_1.IRadio) radioProxy;
5142 
5143         RILRequest rr = obtainRequest(
5144                 RIL_REQUEST_START_KEEPALIVE, result, mRILDefaultWorkSource);
5145 
5146         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5147 
5148         try {
5149             android.hardware.radio.V1_1.KeepaliveRequest req =
5150                     new android.hardware.radio.V1_1.KeepaliveRequest();
5151 
5152             req.cid = contextId;
5153 
5154             if (packetData.getDstAddress() instanceof Inet4Address) {
5155                 req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV4;
5156             } else if (packetData.getDstAddress() instanceof Inet6Address) {
5157                 req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV6;
5158             } else {
5159                 AsyncResult.forMessage(result, null,
5160                         CommandException.fromRilErrno(INVALID_ARGUMENTS));
5161                 result.sendToTarget();
5162                 return;
5163             }
5164 
5165             final InetAddress srcAddress = packetData.getSrcAddress();
5166             final InetAddress dstAddress = packetData.getDstAddress();
5167             appendPrimitiveArrayToArrayList(
5168                     srcAddress.getAddress(), req.sourceAddress);
5169             req.sourcePort = packetData.getSrcPort();
5170             appendPrimitiveArrayToArrayList(
5171                     dstAddress.getAddress(), req.destinationAddress);
5172             req.destinationPort = packetData.getDstPort();
5173             req.maxKeepaliveIntervalMillis = intervalMillis;
5174 
5175             radioProxy11.startKeepalive(rr.mSerial, req);
5176         } catch (RemoteException | RuntimeException e) {
5177             handleRadioProxyExceptionForRR(rr, "startNattKeepalive", e);
5178         }
5179     }
5180 
5181     @Override
stopNattKeepalive(int sessionHandle, Message result)5182     public void stopNattKeepalive(int sessionHandle, Message result) {
5183         IRadio radioProxy = getRadioProxy(result);
5184         if (radioProxy == null) return;
5185 
5186         if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) {
5187             if (result != null) {
5188                 AsyncResult.forMessage(result, null,
5189                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5190                 result.sendToTarget();
5191             }
5192             return;
5193         }
5194 
5195         android.hardware.radio.V1_1.IRadio radioProxy11 =
5196                 (android.hardware.radio.V1_1.IRadio) radioProxy;
5197 
5198         RILRequest rr = obtainRequest(
5199                 RIL_REQUEST_STOP_KEEPALIVE, result, mRILDefaultWorkSource);
5200 
5201         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5202 
5203         try {
5204             radioProxy11.stopKeepalive(rr.mSerial, sessionHandle);
5205         } catch (RemoteException | RuntimeException e) {
5206             handleRadioProxyExceptionForRR(rr, "stopNattKeepalive", e);
5207         }
5208     }
5209 
5210     @Override
getIMEI(Message result)5211     public void getIMEI(Message result) {
5212         throw new RuntimeException("getIMEI not expected to be called");
5213     }
5214 
5215     @Override
getIMEISV(Message result)5216     public void getIMEISV(Message result) {
5217         throw new RuntimeException("getIMEISV not expected to be called");
5218     }
5219 
5220     /**
5221      * @deprecated
5222      */
5223     @Deprecated
5224     @Override
getLastPdpFailCause(Message result)5225     public void getLastPdpFailCause(Message result) {
5226         throw new RuntimeException("getLastPdpFailCause not expected to be called");
5227     }
5228 
5229     /**
5230      * The preferred new alternative to getLastPdpFailCause
5231      */
5232     @Override
getLastDataCallFailCause(Message result)5233     public void getLastDataCallFailCause(Message result) {
5234         throw new RuntimeException("getLastDataCallFailCause not expected to be called");
5235     }
5236 
5237     /**
5238      * Enable or disable uicc applications on the SIM.
5239      *
5240      * @param enable whether to enable or disable uicc applications.
5241      * @param onCompleteMessage a Message to return to the requester
5242      */
5243     @Override
enableUiccApplications(boolean enable, Message onCompleteMessage)5244     public void enableUiccApplications(boolean enable, Message onCompleteMessage) {
5245         IRadio radioProxy = getRadioProxy(onCompleteMessage);
5246         if (radioProxy == null) return;
5247 
5248         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
5249             if (onCompleteMessage != null) {
5250                 AsyncResult.forMessage(onCompleteMessage, null,
5251                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5252                 onCompleteMessage.sendToTarget();
5253             }
5254             return;
5255         }
5256 
5257         android.hardware.radio.V1_5.IRadio radioProxy15 =
5258                 (android.hardware.radio.V1_5.IRadio) radioProxy;
5259 
5260         RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS,
5261                 onCompleteMessage, mRILDefaultWorkSource);
5262 
5263         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5264 
5265         try {
5266             radioProxy15.enableUiccApplications(rr.mSerial, enable);
5267         } catch (RemoteException | RuntimeException e) {
5268             handleRadioProxyExceptionForRR(rr, "enableUiccApplications", e);
5269         }
5270     }
5271 
5272     /**
5273      * Whether uicc applications are enabled or not.
5274      *
5275      * @param onCompleteMessage a Message to return to the requester
5276      */
5277     @Override
areUiccApplicationsEnabled(Message onCompleteMessage)5278     public void areUiccApplicationsEnabled(Message onCompleteMessage) {
5279         IRadio radioProxy = getRadioProxy(onCompleteMessage);
5280         if (radioProxy == null) return;
5281 
5282         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
5283             if (onCompleteMessage != null) {
5284                 AsyncResult.forMessage(onCompleteMessage, null,
5285                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5286                 onCompleteMessage.sendToTarget();
5287             }
5288             return;
5289         }
5290 
5291         android.hardware.radio.V1_5.IRadio radioProxy15 =
5292                 (android.hardware.radio.V1_5.IRadio) radioProxy;
5293 
5294         RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT,
5295                 onCompleteMessage, mRILDefaultWorkSource);
5296 
5297         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5298 
5299         try {
5300             radioProxy15.areUiccApplicationsEnabled(rr.mSerial);
5301         } catch (RemoteException | RuntimeException e) {
5302             handleRadioProxyExceptionForRR(rr, "areUiccApplicationsEnabled", e);
5303         }
5304     }
5305 
5306     /**
5307      * Whether {@link #enableUiccApplications} is supported, which is supported in 1.5 version.
5308      */
5309     @Override
canToggleUiccApplicationsEnablement()5310     public boolean canToggleUiccApplicationsEnablement() {
5311         return getRadioProxy(null) != null && mRadioVersion
5312                 .greaterOrEqual(RADIO_HAL_VERSION_1_5);
5313     }
5314 
5315     /**
5316      *  Translates EF_SMS status bits to a status value compatible with
5317      *  SMS AT commands.  See TS 27.005 3.1.
5318      */
translateStatus(int status)5319     private int translateStatus(int status) {
5320         switch(status & 0x7) {
5321             case SmsManager.STATUS_ON_ICC_READ:
5322                 return 1;
5323             case SmsManager.STATUS_ON_ICC_UNREAD:
5324                 return 0;
5325             case SmsManager.STATUS_ON_ICC_SENT:
5326                 return 3;
5327             case SmsManager.STATUS_ON_ICC_UNSENT:
5328                 return 2;
5329         }
5330 
5331         // Default to READ.
5332         return 1;
5333     }
5334 
5335     @Override
resetRadio(Message result)5336     public void resetRadio(Message result) {
5337         throw new RuntimeException("resetRadio not expected to be called");
5338     }
5339 
5340     /**
5341      * {@inheritDoc}
5342      */
5343     @Override
handleCallSetupRequestFromSim(boolean accept, Message result)5344     public void handleCallSetupRequestFromSim(boolean accept, Message result) {
5345         IRadio radioProxy = getRadioProxy(result);
5346         if (radioProxy != null) {
5347             RILRequest rr = obtainRequest(RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
5348                     result, mRILDefaultWorkSource);
5349 
5350             if (RILJ_LOGD) {
5351                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5352             }
5353 
5354             try {
5355                 radioProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
5356             } catch (RemoteException | RuntimeException e) {
5357                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
5358             }
5359         }
5360     }
5361 
5362     /**
5363      * {@inheritDoc}
5364      */
5365     @Override
getBarringInfo(Message result)5366     public void getBarringInfo(Message result) {
5367         IRadio radioProxy = getRadioProxy(result);
5368         if (radioProxy == null) return;
5369 
5370         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
5371             if (result != null) {
5372                 AsyncResult.forMessage(result, null,
5373                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
5374                 result.sendToTarget();
5375             }
5376             return;
5377         }
5378 
5379         android.hardware.radio.V1_5.IRadio radioProxy15 =
5380                 (android.hardware.radio.V1_5.IRadio) radioProxy;
5381         if (radioProxy15 != null) {
5382             RILRequest rr = obtainRequest(RIL_REQUEST_GET_BARRING_INFO, result,
5383                     mRILDefaultWorkSource);
5384 
5385             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
5386 
5387             try {
5388                 radioProxy15.getBarringInfo(rr.mSerial);
5389             } catch (RemoteException | RuntimeException e) {
5390                 handleRadioProxyExceptionForRR(rr, "getBarringInfo", e);
5391             }
5392         }
5393     }
5394 
5395     //***** Private Methods
5396 
5397     /**
5398      * This is a helper function to be called when a RadioIndication callback is called.
5399      * It takes care of acquiring wakelock and sending ack if needed.
5400      * @param indicationType RadioIndicationType received
5401      */
processIndication(int indicationType)5402     void processIndication(int indicationType) {
5403         if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
5404             sendAck();
5405             if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
5406         } else {
5407             // ack is not expected to be sent back. Nothing is required to be done here.
5408         }
5409     }
5410 
processRequestAck(int serial)5411     void processRequestAck(int serial) {
5412         RILRequest rr;
5413         synchronized (mRequestList) {
5414             rr = mRequestList.get(serial);
5415         }
5416         if (rr == null) {
5417             Rlog.w(RIL.RILJ_LOG_TAG, "processRequestAck: Unexpected solicited ack response! "
5418                     + "serial: " + serial);
5419         } else {
5420             decrementWakeLock(rr);
5421             if (RIL.RILJ_LOGD) {
5422                 riljLog(rr.serialString() + " Ack < " + RIL.requestToString(rr.mRequest));
5423             }
5424         }
5425     }
5426 
5427     /**
5428      * This is a helper function to be called when a RadioResponse callback is called.
5429      * It takes care of acks, wakelocks, and finds and returns RILRequest corresponding to the
5430      * response if one is found.
5431      * @param responseInfo RadioResponseInfo received in response callback
5432      * @return RILRequest corresponding to the response
5433      */
5434     @VisibleForTesting
processResponse(RadioResponseInfo responseInfo)5435     public RILRequest processResponse(RadioResponseInfo responseInfo) {
5436         int serial = responseInfo.serial;
5437         int error = responseInfo.error;
5438         int type = responseInfo.type;
5439 
5440         RILRequest rr = null;
5441 
5442         if (type == RadioResponseType.SOLICITED_ACK) {
5443             synchronized (mRequestList) {
5444                 rr = mRequestList.get(serial);
5445             }
5446             if (rr == null) {
5447                 Rlog.w(RILJ_LOG_TAG, "Unexpected solicited ack response! sn: " + serial);
5448             } else {
5449                 decrementWakeLock(rr);
5450                 if (mRadioBugDetector != null) {
5451                     mRadioBugDetector.detectRadioBug(rr.mRequest, error);
5452                 }
5453                 if (RILJ_LOGD) {
5454                     riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest));
5455                 }
5456             }
5457             return rr;
5458         }
5459 
5460         rr = findAndRemoveRequestFromList(serial);
5461         if (rr == null) {
5462             Rlog.e(RIL.RILJ_LOG_TAG, "processResponse: Unexpected response! serial: " + serial
5463                     + " error: " + error);
5464             return null;
5465         }
5466 
5467         // Time logging for RIL command and storing it in TelephonyHistogram.
5468         addToRilHistogram(rr);
5469         if (mRadioBugDetector != null) {
5470             mRadioBugDetector.detectRadioBug(rr.mRequest, error);
5471         }
5472         if (type == RadioResponseType.SOLICITED_ACK_EXP) {
5473             sendAck();
5474             if (RIL.RILJ_LOGD) {
5475                 riljLog("Response received for " + rr.serialString() + " "
5476                         + RIL.requestToString(rr.mRequest) + " Sending ack to ril.cpp");
5477             }
5478         } else {
5479             // ack sent for SOLICITED_ACK_EXP above; nothing to do for SOLICITED response
5480         }
5481 
5482         // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
5483         // This is needed otherwise we don't automatically transition to the main lock
5484         // screen when the pin or puk is entered incorrectly.
5485         switch (rr.mRequest) {
5486             case RIL_REQUEST_ENTER_SIM_PUK:
5487             case RIL_REQUEST_ENTER_SIM_PUK2:
5488                 if (mIccStatusChangedRegistrants != null) {
5489                     if (RILJ_LOGD) {
5490                         riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
5491                                 + mIccStatusChangedRegistrants.size());
5492                     }
5493                     mIccStatusChangedRegistrants.notifyRegistrants();
5494                 }
5495                 break;
5496             case RIL_REQUEST_SHUTDOWN:
5497                 setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE,
5498                         false /* forceNotifyRegistrants */);
5499                 break;
5500         }
5501 
5502         if (error != RadioError.NONE) {
5503             switch (rr.mRequest) {
5504                 case RIL_REQUEST_ENTER_SIM_PIN:
5505                 case RIL_REQUEST_ENTER_SIM_PIN2:
5506                 case RIL_REQUEST_CHANGE_SIM_PIN:
5507                 case RIL_REQUEST_CHANGE_SIM_PIN2:
5508                 case RIL_REQUEST_SET_FACILITY_LOCK:
5509                     if (mIccStatusChangedRegistrants != null) {
5510                         if (RILJ_LOGD) {
5511                             riljLog("ON some errors fakeSimStatusChanged: reg count="
5512                                     + mIccStatusChangedRegistrants.size());
5513                         }
5514                         mIccStatusChangedRegistrants.notifyRegistrants();
5515                     }
5516                     break;
5517 
5518             }
5519         } else {
5520             switch (rr.mRequest) {
5521                 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
5522                 if (mTestingEmergencyCall.getAndSet(false)) {
5523                     if (mEmergencyCallbackModeRegistrant != null) {
5524                         riljLog("testing emergency call, notify ECM Registrants");
5525                         mEmergencyCallbackModeRegistrant.notifyRegistrant();
5526                     }
5527                 }
5528             }
5529         }
5530         return rr;
5531     }
5532 
5533     /**
5534      * This is a helper function to be called at the end of all RadioResponse callbacks.
5535      * It takes care of sending error response, logging, decrementing wakelock if needed, and
5536      * releases the request from memory pool.
5537      * @param rr RILRequest for which response callback was called
5538      * @param responseInfo RadioResponseInfo received in the callback
5539      * @param ret object to be returned to request sender
5540      */
5541     @VisibleForTesting
processResponseDone(RILRequest rr, RadioResponseInfo responseInfo, Object ret)5542     public void processResponseDone(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
5543         if (responseInfo.error == 0) {
5544             if (RILJ_LOGD) {
5545                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
5546                         + " " + retToString(rr.mRequest, ret));
5547             }
5548         } else {
5549             if (RILJ_LOGD) {
5550                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
5551                         + " error " + responseInfo.error);
5552             }
5553             rr.onError(responseInfo.error, ret);
5554         }
5555         processResponseCleanUp(rr, responseInfo, ret);
5556     }
5557 
5558     /**
5559      * This is a helper function to be called at the end of all RadioResponse callbacks for
5560      * radio HAL fallback cases. It takes care of logging, decrementing wakelock if needed, and
5561      * releases the request from memory pool. Unlike processResponseDone, it will not send
5562      * error response to caller.
5563      * @param rr RILRequest for which response callback was called
5564      * @param responseInfo RadioResponseInfo received in the callback
5565      * @param ret object to be returned to request sender
5566      */
5567     @VisibleForTesting
processResponseFallback(RILRequest rr, RadioResponseInfo responseInfo, Object ret)5568     public void processResponseFallback(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
5569         if (responseInfo.error == REQUEST_NOT_SUPPORTED && RILJ_LOGD) {
5570             riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
5571                     + " request not supported, falling back");
5572         }
5573         processResponseCleanUp(rr, responseInfo, ret);
5574     }
5575 
processResponseCleanUp(RILRequest rr, RadioResponseInfo responseInfo, Object ret)5576     private void processResponseCleanUp(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
5577         mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error,
5578                 rr.mRequest, ret);
5579         if (rr != null) {
5580             if (responseInfo.type == RadioResponseType.SOLICITED) {
5581                 decrementWakeLock(rr);
5582             }
5583             rr.release();
5584         }
5585     }
5586 
5587     /**
5588      * Function to send ack and acquire related wakelock
5589      */
sendAck()5590     private void sendAck() {
5591         // TODO: Remove rr and clean up acquireWakelock for response and ack
5592         RILRequest rr = RILRequest.obtain(RIL_RESPONSE_ACKNOWLEDGEMENT, null,
5593                 mRILDefaultWorkSource);
5594         acquireWakeLock(rr, RIL.FOR_ACK_WAKELOCK);
5595         IRadio radioProxy = getRadioProxy(null);
5596         if (radioProxy != null) {
5597             try {
5598                 radioProxy.responseAcknowledgement();
5599             } catch (RemoteException | RuntimeException e) {
5600                 handleRadioProxyExceptionForRR(rr, "sendAck", e);
5601                 riljLoge("sendAck: " + e);
5602             }
5603         } else {
5604             Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");
5605         }
5606         rr.release();
5607     }
5608 
getDeafultWorkSourceIfInvalid(WorkSource workSource)5609     private WorkSource getDeafultWorkSourceIfInvalid(WorkSource workSource) {
5610         if (workSource == null) {
5611             workSource = mRILDefaultWorkSource;
5612         }
5613 
5614         return workSource;
5615     }
5616 
5617 
5618     /**
5619      * Holds a PARTIAL_WAKE_LOCK whenever
5620      * a) There is outstanding RIL request sent to RIL deamon and no replied
5621      * b) There is a request pending to be sent out.
5622      *
5623      * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
5624      * happen often.
5625      */
5626     @UnsupportedAppUsage
acquireWakeLock(RILRequest rr, int wakeLockType)5627     private void acquireWakeLock(RILRequest rr, int wakeLockType) {
5628         synchronized (rr) {
5629             if (rr.mWakeLockType != INVALID_WAKELOCK) {
5630                 Rlog.d(RILJ_LOG_TAG, "Failed to aquire wakelock for " + rr.serialString());
5631                 return;
5632             }
5633 
5634             switch(wakeLockType) {
5635                 case FOR_WAKELOCK:
5636                     synchronized (mWakeLock) {
5637                         mWakeLock.acquire();
5638                         mWakeLockCount++;
5639                         mWlSequenceNum++;
5640 
5641                         String clientId = rr.getWorkSourceClientId();
5642                         if (!mClientWakelockTracker.isClientActive(clientId)) {
5643                             mActiveWakelockWorkSource.add(rr.mWorkSource);
5644                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
5645                         }
5646 
5647                         mClientWakelockTracker.startTracking(rr.mClientId,
5648                                 rr.mRequest, rr.mSerial, mWakeLockCount);
5649 
5650                         Message msg = mRilHandler.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
5651                         msg.arg1 = mWlSequenceNum;
5652                         mRilHandler.sendMessageDelayed(msg, mWakeLockTimeout);
5653                     }
5654                     break;
5655                 case FOR_ACK_WAKELOCK:
5656                     synchronized (mAckWakeLock) {
5657                         mAckWakeLock.acquire();
5658                         mAckWlSequenceNum++;
5659 
5660                         Message msg = mRilHandler.obtainMessage(EVENT_ACK_WAKE_LOCK_TIMEOUT);
5661                         msg.arg1 = mAckWlSequenceNum;
5662                         mRilHandler.sendMessageDelayed(msg, mAckWakeLockTimeout);
5663                     }
5664                     break;
5665                 default: //WTF
5666                     Rlog.w(RILJ_LOG_TAG, "Acquiring Invalid Wakelock type " + wakeLockType);
5667                     return;
5668             }
5669             rr.mWakeLockType = wakeLockType;
5670         }
5671     }
5672 
5673     /** Returns the wake lock of the given type. */
5674     @VisibleForTesting
getWakeLock(int wakeLockType)5675     public WakeLock getWakeLock(int wakeLockType) {
5676         return wakeLockType == FOR_WAKELOCK ? mWakeLock : mAckWakeLock;
5677     }
5678 
5679     /** Returns the {@link RilHandler} instance. */
5680     @VisibleForTesting
getRilHandler()5681     public RilHandler getRilHandler() {
5682         return mRilHandler;
5683     }
5684 
5685     /** Returns the Ril request list. */
5686     @VisibleForTesting
getRilRequestList()5687     public SparseArray<RILRequest> getRilRequestList() {
5688         return mRequestList;
5689     }
5690 
5691     @UnsupportedAppUsage
decrementWakeLock(RILRequest rr)5692     private void decrementWakeLock(RILRequest rr) {
5693         synchronized (rr) {
5694             switch(rr.mWakeLockType) {
5695                 case FOR_WAKELOCK:
5696                     synchronized (mWakeLock) {
5697                         mClientWakelockTracker.stopTracking(rr.mClientId,
5698                                 rr.mRequest, rr.mSerial,
5699                                 (mWakeLockCount > 1) ? mWakeLockCount - 1 : 0);
5700                         String clientId = rr.getWorkSourceClientId();
5701                         if (!mClientWakelockTracker.isClientActive(clientId)) {
5702                             mActiveWakelockWorkSource.remove(rr.mWorkSource);
5703                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
5704                         }
5705 
5706                         if (mWakeLockCount > 1) {
5707                             mWakeLockCount--;
5708                         } else {
5709                             mWakeLockCount = 0;
5710                             mWakeLock.release();
5711                         }
5712                     }
5713                     break;
5714                 case FOR_ACK_WAKELOCK:
5715                     //We do not decrement the ACK wakelock
5716                     break;
5717                 case INVALID_WAKELOCK:
5718                     break;
5719                 default:
5720                     Rlog.w(RILJ_LOG_TAG, "Decrementing Invalid Wakelock type " + rr.mWakeLockType);
5721             }
5722             rr.mWakeLockType = INVALID_WAKELOCK;
5723         }
5724     }
5725 
5726     @UnsupportedAppUsage
clearWakeLock(int wakeLockType)5727     private boolean clearWakeLock(int wakeLockType) {
5728         if (wakeLockType == FOR_WAKELOCK) {
5729             synchronized (mWakeLock) {
5730                 if (mWakeLockCount == 0 && !mWakeLock.isHeld()) return false;
5731                 Rlog.d(RILJ_LOG_TAG, "NOTE: mWakeLockCount is " + mWakeLockCount
5732                         + "at time of clearing");
5733                 mWakeLockCount = 0;
5734                 mWakeLock.release();
5735                 mClientWakelockTracker.stopTrackingAll();
5736                 mActiveWakelockWorkSource = new WorkSource();
5737                 return true;
5738             }
5739         } else {
5740             synchronized (mAckWakeLock) {
5741                 if (!mAckWakeLock.isHeld()) return false;
5742                 mAckWakeLock.release();
5743                 return true;
5744             }
5745         }
5746     }
5747 
5748     /**
5749      * Release each request in mRequestList then clear the list
5750      * @param error is the RIL_Errno sent back
5751      * @param loggable true means to print all requests in mRequestList
5752      */
5753     @UnsupportedAppUsage
clearRequestList(int error, boolean loggable)5754     private void clearRequestList(int error, boolean loggable) {
5755         RILRequest rr;
5756         synchronized (mRequestList) {
5757             int count = mRequestList.size();
5758             if (RILJ_LOGD && loggable) {
5759                 Rlog.d(RILJ_LOG_TAG, "clearRequestList " + " mWakeLockCount="
5760                         + mWakeLockCount + " mRequestList=" + count);
5761             }
5762 
5763             for (int i = 0; i < count; i++) {
5764                 rr = mRequestList.valueAt(i);
5765                 if (RILJ_LOGD && loggable) {
5766                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
5767                             + requestToString(rr.mRequest));
5768                 }
5769                 rr.onError(error, null);
5770                 decrementWakeLock(rr);
5771                 rr.release();
5772             }
5773             mRequestList.clear();
5774         }
5775     }
5776 
5777     @UnsupportedAppUsage
findAndRemoveRequestFromList(int serial)5778     private RILRequest findAndRemoveRequestFromList(int serial) {
5779         RILRequest rr = null;
5780         synchronized (mRequestList) {
5781             rr = mRequestList.get(serial);
5782             if (rr != null) {
5783                 mRequestList.remove(serial);
5784             }
5785         }
5786 
5787         return rr;
5788     }
5789 
addToRilHistogram(RILRequest rr)5790     private void addToRilHistogram(RILRequest rr) {
5791         long endTime = SystemClock.elapsedRealtime();
5792         int totalTime = (int) (endTime - rr.mStartTimeMs);
5793 
5794         synchronized (mRilTimeHistograms) {
5795             TelephonyHistogram entry = mRilTimeHistograms.get(rr.mRequest);
5796             if (entry == null) {
5797                 // We would have total #RIL_HISTOGRAM_BUCKET_COUNT range buckets for RIL commands
5798                 entry = new TelephonyHistogram(TelephonyHistogram.TELEPHONY_CATEGORY_RIL,
5799                         rr.mRequest, RIL_HISTOGRAM_BUCKET_COUNT);
5800                 mRilTimeHistograms.put(rr.mRequest, entry);
5801             }
5802             entry.addTimeTaken(totalTime);
5803         }
5804     }
5805 
5806     @UnsupportedAppUsage
makeStaticRadioCapability()5807     RadioCapability makeStaticRadioCapability() {
5808         // default to UNKNOWN so we fail fast.
5809         int raf = RadioAccessFamily.RAF_UNKNOWN;
5810 
5811         String rafString = mContext.getResources().getString(
5812                 com.android.internal.R.string.config_radio_access_family);
5813         if (!TextUtils.isEmpty(rafString)) {
5814             raf = RadioAccessFamily.rafTypeFromString(rafString);
5815         }
5816         RadioCapability rc = new RadioCapability(mPhoneId.intValue(), 0, 0, raf,
5817                 "", RadioCapability.RC_STATUS_SUCCESS);
5818         if (RILJ_LOGD) riljLog("Faking RIL_REQUEST_GET_RADIO_CAPABILITY response using " + raf);
5819         return rc;
5820     }
5821 
5822     @UnsupportedAppUsage
retToString(int req, Object ret)5823     static String retToString(int req, Object ret) {
5824         if (ret == null) return "";
5825         switch (req) {
5826             // Don't log these return values, for privacy's sake.
5827             case RIL_REQUEST_GET_IMSI:
5828             case RIL_REQUEST_GET_IMEI:
5829             case RIL_REQUEST_GET_IMEISV:
5830             case RIL_REQUEST_SIM_OPEN_CHANNEL:
5831             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
5832 
5833                 if (!RILJ_LOGV) {
5834                     // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
5835                     return "";
5836                 }
5837         }
5838 
5839         StringBuilder sb;
5840         String s;
5841         int length;
5842         if (ret instanceof int[]) {
5843             int[] intArray = (int[]) ret;
5844             length = intArray.length;
5845             sb = new StringBuilder("{");
5846             if (length > 0) {
5847                 int i = 0;
5848                 sb.append(intArray[i++]);
5849                 while (i < length) {
5850                     sb.append(", ").append(intArray[i++]);
5851                 }
5852             }
5853             sb.append("}");
5854             s = sb.toString();
5855         } else if (ret instanceof String[]) {
5856             String[] strings = (String[]) ret;
5857             length = strings.length;
5858             sb = new StringBuilder("{");
5859             if (length > 0) {
5860                 int i = 0;
5861                 // position 0 is IMEI in RIL_REQUEST_DEVICE_IDENTITY
5862                 if (req == RIL_REQUEST_DEVICE_IDENTITY) {
5863                     sb.append(Rlog.pii(RILJ_LOG_TAG, strings[i++]));
5864                 } else {
5865                     sb.append(strings[i++]);
5866                 }
5867                 while (i < length) {
5868                     sb.append(", ").append(strings[i++]);
5869                 }
5870             }
5871             sb.append("}");
5872             s = sb.toString();
5873         } else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
5874             ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
5875             sb = new StringBuilder("{");
5876             for (DriverCall dc : calls) {
5877                 sb.append("[").append(dc).append("] ");
5878             }
5879             sb.append("}");
5880             s = sb.toString();
5881         } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
5882             ArrayList<NeighboringCellInfo> cells = (ArrayList<NeighboringCellInfo>) ret;
5883             sb = new StringBuilder("{");
5884             for (NeighboringCellInfo cell : cells) {
5885                 sb.append("[").append(cell).append("] ");
5886             }
5887             sb.append("}");
5888             s = sb.toString();
5889         } else if (req == RIL_REQUEST_QUERY_CALL_FORWARD_STATUS) {
5890             CallForwardInfo[] cinfo = (CallForwardInfo[]) ret;
5891             length = cinfo.length;
5892             sb = new StringBuilder("{");
5893             for (int i = 0; i < length; i++) {
5894                 sb.append("[").append(cinfo[i]).append("] ");
5895             }
5896             sb.append("}");
5897             s = sb.toString();
5898         } else if (req == RIL_REQUEST_GET_HARDWARE_CONFIG) {
5899             ArrayList<HardwareConfig> hwcfgs = (ArrayList<HardwareConfig>) ret;
5900             sb = new StringBuilder(" ");
5901             for (HardwareConfig hwcfg : hwcfgs) {
5902                 sb.append("[").append(hwcfg).append("] ");
5903             }
5904             s = sb.toString();
5905         } else {
5906             s = ret.toString();
5907         }
5908         return s;
5909     }
5910 
writeMetricsCallRing(char[] response)5911     void writeMetricsCallRing(char[] response) {
5912         mMetrics.writeRilCallRing(mPhoneId, response);
5913     }
5914 
writeMetricsSrvcc(int state)5915     void writeMetricsSrvcc(int state) {
5916         mMetrics.writeRilSrvcc(mPhoneId, state);
5917         PhoneFactory.getPhone(mPhoneId).getVoiceCallSessionStats().onRilSrvccStateChanged(state);
5918     }
5919 
writeMetricsModemRestartEvent(String reason)5920     void writeMetricsModemRestartEvent(String reason) {
5921         mMetrics.writeModemRestartEvent(mPhoneId, reason);
5922     }
5923 
5924     /**
5925      * Notify all registrants that the ril has connected or disconnected.
5926      *
5927      * @param rilVer is the version of the ril or -1 if disconnected.
5928      */
5929     @UnsupportedAppUsage
notifyRegistrantsRilConnectionChanged(int rilVer)5930     void notifyRegistrantsRilConnectionChanged(int rilVer) {
5931         mRilVersion = rilVer;
5932         if (mRilConnectedRegistrants != null) {
5933             mRilConnectedRegistrants.notifyRegistrants(
5934                     new AsyncResult(null, new Integer(rilVer), null));
5935         }
5936     }
5937 
5938     @UnsupportedAppUsage
5939     void
notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec)5940     notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
5941         int response = RIL_UNSOL_CDMA_INFO_REC;
5942         if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
5943             if (mDisplayInfoRegistrants != null) {
5944                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5945                 mDisplayInfoRegistrants.notifyRegistrants(
5946                         new AsyncResult(null, infoRec.record, null));
5947             }
5948         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
5949             if (mSignalInfoRegistrants != null) {
5950                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5951                 mSignalInfoRegistrants.notifyRegistrants(
5952                         new AsyncResult(null, infoRec.record, null));
5953             }
5954         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
5955             if (mNumberInfoRegistrants != null) {
5956                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5957                 mNumberInfoRegistrants.notifyRegistrants(
5958                         new AsyncResult(null, infoRec.record, null));
5959             }
5960         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
5961             if (mRedirNumInfoRegistrants != null) {
5962                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5963                 mRedirNumInfoRegistrants.notifyRegistrants(
5964                         new AsyncResult(null, infoRec.record, null));
5965             }
5966         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
5967             if (mLineControlInfoRegistrants != null) {
5968                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5969                 mLineControlInfoRegistrants.notifyRegistrants(
5970                         new AsyncResult(null, infoRec.record, null));
5971             }
5972         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
5973             if (mT53ClirInfoRegistrants != null) {
5974                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
5975                 mT53ClirInfoRegistrants.notifyRegistrants(
5976                         new AsyncResult(null, infoRec.record, null));
5977             }
5978         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
5979             if (mT53AudCntrlInfoRegistrants != null) {
5980                 if (RILJ_LOGD) {
5981                     unsljLogRet(response, infoRec.record);
5982                 }
5983                 mT53AudCntrlInfoRegistrants.notifyRegistrants(
5984                         new AsyncResult(null, infoRec.record, null));
5985             }
5986         }
5987     }
5988 
5989     @UnsupportedAppUsage
requestToString(int request)5990     static String requestToString(int request) {
5991         switch(request) {
5992             case RIL_REQUEST_GET_SIM_STATUS:
5993                 return "GET_SIM_STATUS";
5994             case RIL_REQUEST_ENTER_SIM_PIN:
5995                 return "ENTER_SIM_PIN";
5996             case RIL_REQUEST_ENTER_SIM_PUK:
5997                 return "ENTER_SIM_PUK";
5998             case RIL_REQUEST_ENTER_SIM_PIN2:
5999                 return "ENTER_SIM_PIN2";
6000             case RIL_REQUEST_ENTER_SIM_PUK2:
6001                 return "ENTER_SIM_PUK2";
6002             case RIL_REQUEST_CHANGE_SIM_PIN:
6003                 return "CHANGE_SIM_PIN";
6004             case RIL_REQUEST_CHANGE_SIM_PIN2:
6005                 return "CHANGE_SIM_PIN2";
6006             case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
6007                 return "ENTER_NETWORK_DEPERSONALIZATION";
6008             case RIL_REQUEST_GET_CURRENT_CALLS:
6009                 return "GET_CURRENT_CALLS";
6010             case RIL_REQUEST_DIAL:
6011                 return "DIAL";
6012             case RIL_REQUEST_EMERGENCY_DIAL:
6013                 return "EMERGENCY_DIAL";
6014             case RIL_REQUEST_GET_IMSI:
6015                 return "GET_IMSI";
6016             case RIL_REQUEST_HANGUP:
6017                 return "HANGUP";
6018             case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
6019                 return "HANGUP_WAITING_OR_BACKGROUND";
6020             case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
6021                 return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
6022             case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
6023                 return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
6024             case RIL_REQUEST_CONFERENCE:
6025                 return "CONFERENCE";
6026             case RIL_REQUEST_UDUB:
6027                 return "UDUB";
6028             case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
6029                 return "LAST_CALL_FAIL_CAUSE";
6030             case RIL_REQUEST_SIGNAL_STRENGTH:
6031                 return "SIGNAL_STRENGTH";
6032             case RIL_REQUEST_VOICE_REGISTRATION_STATE:
6033                 return "VOICE_REGISTRATION_STATE";
6034             case RIL_REQUEST_DATA_REGISTRATION_STATE:
6035                 return "DATA_REGISTRATION_STATE";
6036             case RIL_REQUEST_OPERATOR:
6037                 return "OPERATOR";
6038             case RIL_REQUEST_RADIO_POWER:
6039                 return "RADIO_POWER";
6040             case RIL_REQUEST_DTMF:
6041                 return "DTMF";
6042             case RIL_REQUEST_SEND_SMS:
6043                 return "SEND_SMS";
6044             case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
6045                 return "SEND_SMS_EXPECT_MORE";
6046             case RIL_REQUEST_SETUP_DATA_CALL:
6047                 return "SETUP_DATA_CALL";
6048             case RIL_REQUEST_SIM_IO:
6049                 return "SIM_IO";
6050             case RIL_REQUEST_SEND_USSD:
6051                 return "SEND_USSD";
6052             case RIL_REQUEST_CANCEL_USSD:
6053                 return "CANCEL_USSD";
6054             case RIL_REQUEST_GET_CLIR:
6055                 return "GET_CLIR";
6056             case RIL_REQUEST_SET_CLIR:
6057                 return "SET_CLIR";
6058             case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
6059                 return "QUERY_CALL_FORWARD_STATUS";
6060             case RIL_REQUEST_SET_CALL_FORWARD:
6061                 return "SET_CALL_FORWARD";
6062             case RIL_REQUEST_QUERY_CALL_WAITING:
6063                 return "QUERY_CALL_WAITING";
6064             case RIL_REQUEST_SET_CALL_WAITING:
6065                 return "SET_CALL_WAITING";
6066             case RIL_REQUEST_SMS_ACKNOWLEDGE:
6067                 return "SMS_ACKNOWLEDGE";
6068             case RIL_REQUEST_GET_IMEI:
6069                 return "GET_IMEI";
6070             case RIL_REQUEST_GET_IMEISV:
6071                 return "GET_IMEISV";
6072             case RIL_REQUEST_ANSWER:
6073                 return "ANSWER";
6074             case RIL_REQUEST_DEACTIVATE_DATA_CALL:
6075                 return "DEACTIVATE_DATA_CALL";
6076             case RIL_REQUEST_QUERY_FACILITY_LOCK:
6077                 return "QUERY_FACILITY_LOCK";
6078             case RIL_REQUEST_SET_FACILITY_LOCK:
6079                 return "SET_FACILITY_LOCK";
6080             case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
6081                 return "CHANGE_BARRING_PASSWORD";
6082             case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
6083                 return "QUERY_NETWORK_SELECTION_MODE";
6084             case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
6085                 return "SET_NETWORK_SELECTION_AUTOMATIC";
6086             case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
6087                 return "SET_NETWORK_SELECTION_MANUAL";
6088             case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS :
6089                 return "QUERY_AVAILABLE_NETWORKS ";
6090             case RIL_REQUEST_DTMF_START:
6091                 return "DTMF_START";
6092             case RIL_REQUEST_DTMF_STOP:
6093                 return "DTMF_STOP";
6094             case RIL_REQUEST_BASEBAND_VERSION:
6095                 return "BASEBAND_VERSION";
6096             case RIL_REQUEST_SEPARATE_CONNECTION:
6097                 return "SEPARATE_CONNECTION";
6098             case RIL_REQUEST_SET_MUTE:
6099                 return "SET_MUTE";
6100             case RIL_REQUEST_GET_MUTE:
6101                 return "GET_MUTE";
6102             case RIL_REQUEST_QUERY_CLIP:
6103                 return "QUERY_CLIP";
6104             case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
6105                 return "LAST_DATA_CALL_FAIL_CAUSE";
6106             case RIL_REQUEST_DATA_CALL_LIST:
6107                 return "DATA_CALL_LIST";
6108             case RIL_REQUEST_RESET_RADIO:
6109                 return "RESET_RADIO";
6110             case RIL_REQUEST_OEM_HOOK_RAW:
6111                 return "OEM_HOOK_RAW";
6112             case RIL_REQUEST_OEM_HOOK_STRINGS:
6113                 return "OEM_HOOK_STRINGS";
6114             case RIL_REQUEST_SCREEN_STATE:
6115                 return "SCREEN_STATE";
6116             case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
6117                 return "SET_SUPP_SVC_NOTIFICATION";
6118             case RIL_REQUEST_WRITE_SMS_TO_SIM:
6119                 return "WRITE_SMS_TO_SIM";
6120             case RIL_REQUEST_DELETE_SMS_ON_SIM:
6121                 return "DELETE_SMS_ON_SIM";
6122             case RIL_REQUEST_SET_BAND_MODE:
6123                 return "SET_BAND_MODE";
6124             case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
6125                 return "QUERY_AVAILABLE_BAND_MODE";
6126             case RIL_REQUEST_STK_GET_PROFILE:
6127                 return "REQUEST_STK_GET_PROFILE";
6128             case RIL_REQUEST_STK_SET_PROFILE:
6129                 return "REQUEST_STK_SET_PROFILE";
6130             case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
6131                 return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
6132             case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
6133                 return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
6134             case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
6135                 return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
6136             case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
6137             case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
6138                 return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
6139             case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
6140                 return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
6141             case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
6142                 return "REQUEST_GET_NEIGHBORING_CELL_IDS";
6143             case RIL_REQUEST_SET_LOCATION_UPDATES:
6144                 return "REQUEST_SET_LOCATION_UPDATES";
6145             case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
6146                 return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
6147             case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
6148                 return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
6149             case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
6150                 return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
6151             case RIL_REQUEST_SET_TTY_MODE:
6152                 return "RIL_REQUEST_SET_TTY_MODE";
6153             case RIL_REQUEST_QUERY_TTY_MODE:
6154                 return "RIL_REQUEST_QUERY_TTY_MODE";
6155             case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
6156                 return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
6157             case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
6158                 return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
6159             case RIL_REQUEST_CDMA_FLASH:
6160                 return "RIL_REQUEST_CDMA_FLASH";
6161             case RIL_REQUEST_CDMA_BURST_DTMF:
6162                 return "RIL_REQUEST_CDMA_BURST_DTMF";
6163             case RIL_REQUEST_CDMA_SEND_SMS:
6164                 return "RIL_REQUEST_CDMA_SEND_SMS";
6165             case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
6166                 return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
6167             case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG:
6168                 return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
6169             case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG:
6170                 return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
6171             case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:
6172                 return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
6173             case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:
6174                 return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
6175             case RIL_REQUEST_GSM_BROADCAST_ACTIVATION:
6176                 return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
6177             case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
6178                 return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
6179             case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION:
6180                 return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
6181             case RIL_REQUEST_CDMA_SUBSCRIPTION:
6182                 return "RIL_REQUEST_CDMA_SUBSCRIPTION";
6183             case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
6184                 return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
6185             case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
6186                 return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
6187             case RIL_REQUEST_DEVICE_IDENTITY:
6188                 return "RIL_REQUEST_DEVICE_IDENTITY";
6189             case RIL_REQUEST_GET_SMSC_ADDRESS:
6190                 return "RIL_REQUEST_GET_SMSC_ADDRESS";
6191             case RIL_REQUEST_SET_SMSC_ADDRESS:
6192                 return "RIL_REQUEST_SET_SMSC_ADDRESS";
6193             case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
6194                 return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
6195             case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
6196                 return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
6197             case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
6198                 return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
6199             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
6200                 return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
6201             case RIL_REQUEST_ISIM_AUTHENTICATION:
6202                 return "RIL_REQUEST_ISIM_AUTHENTICATION";
6203             case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
6204                 return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
6205             case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
6206                 return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
6207             case RIL_REQUEST_VOICE_RADIO_TECH:
6208                 return "RIL_REQUEST_VOICE_RADIO_TECH";
6209             case RIL_REQUEST_GET_CELL_INFO_LIST:
6210                 return "RIL_REQUEST_GET_CELL_INFO_LIST";
6211             case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
6212                 return "RIL_REQUEST_SET_CELL_INFO_LIST_RATE";
6213             case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
6214                 return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
6215             case RIL_REQUEST_SET_DATA_PROFILE:
6216                 return "RIL_REQUEST_SET_DATA_PROFILE";
6217             case RIL_REQUEST_IMS_REGISTRATION_STATE:
6218                 return "RIL_REQUEST_IMS_REGISTRATION_STATE";
6219             case RIL_REQUEST_IMS_SEND_SMS:
6220                 return "RIL_REQUEST_IMS_SEND_SMS";
6221             case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
6222                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC";
6223             case RIL_REQUEST_SIM_OPEN_CHANNEL:
6224                 return "RIL_REQUEST_SIM_OPEN_CHANNEL";
6225             case RIL_REQUEST_SIM_CLOSE_CHANNEL:
6226                 return "RIL_REQUEST_SIM_CLOSE_CHANNEL";
6227             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
6228                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL";
6229             case RIL_REQUEST_NV_READ_ITEM:
6230                 return "RIL_REQUEST_NV_READ_ITEM";
6231             case RIL_REQUEST_NV_WRITE_ITEM:
6232                 return "RIL_REQUEST_NV_WRITE_ITEM";
6233             case RIL_REQUEST_NV_WRITE_CDMA_PRL:
6234                 return "RIL_REQUEST_NV_WRITE_CDMA_PRL";
6235             case RIL_REQUEST_NV_RESET_CONFIG:
6236                 return "RIL_REQUEST_NV_RESET_CONFIG";
6237             case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
6238                 return "RIL_REQUEST_SET_UICC_SUBSCRIPTION";
6239             case RIL_REQUEST_ALLOW_DATA:
6240                 return "RIL_REQUEST_ALLOW_DATA";
6241             case RIL_REQUEST_GET_HARDWARE_CONFIG:
6242                 return "GET_HARDWARE_CONFIG";
6243             case RIL_REQUEST_SIM_AUTHENTICATION:
6244                 return "RIL_REQUEST_SIM_AUTHENTICATION";
6245             case RIL_REQUEST_SHUTDOWN:
6246                 return "RIL_REQUEST_SHUTDOWN";
6247             case RIL_REQUEST_SET_RADIO_CAPABILITY:
6248                 return "RIL_REQUEST_SET_RADIO_CAPABILITY";
6249             case RIL_REQUEST_GET_RADIO_CAPABILITY:
6250                 return "RIL_REQUEST_GET_RADIO_CAPABILITY";
6251             case RIL_REQUEST_START_LCE:
6252                 return "RIL_REQUEST_START_LCE";
6253             case RIL_REQUEST_STOP_LCE:
6254                 return "RIL_REQUEST_STOP_LCE";
6255             case RIL_REQUEST_PULL_LCEDATA:
6256                 return "RIL_REQUEST_PULL_LCEDATA";
6257             case RIL_REQUEST_GET_ACTIVITY_INFO:
6258                 return "RIL_REQUEST_GET_ACTIVITY_INFO";
6259             case RIL_REQUEST_SET_ALLOWED_CARRIERS:
6260                 return "RIL_REQUEST_SET_ALLOWED_CARRIERS";
6261             case RIL_REQUEST_GET_ALLOWED_CARRIERS:
6262                 return "RIL_REQUEST_GET_ALLOWED_CARRIERS";
6263             case RIL_REQUEST_SET_SIM_CARD_POWER:
6264                 return "RIL_REQUEST_SET_SIM_CARD_POWER";
6265             case RIL_REQUEST_SEND_DEVICE_STATE:
6266                 return "RIL_REQUEST_SEND_DEVICE_STATE";
6267             case RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER:
6268                 return "RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER";
6269             case RIL_RESPONSE_ACKNOWLEDGEMENT:
6270                 return "RIL_RESPONSE_ACKNOWLEDGEMENT";
6271             case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION:
6272                 return "RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION";
6273             case RIL_REQUEST_START_NETWORK_SCAN:
6274                 return "RIL_REQUEST_START_NETWORK_SCAN";
6275             case RIL_REQUEST_STOP_NETWORK_SCAN:
6276                 return "RIL_REQUEST_STOP_NETWORK_SCAN";
6277             case RIL_REQUEST_GET_SLOT_STATUS:
6278                 return "RIL_REQUEST_GET_SLOT_STATUS";
6279             case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
6280                 return "RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
6281             case RIL_REQUEST_START_KEEPALIVE:
6282                 return "RIL_REQUEST_START_KEEPALIVE";
6283             case RIL_REQUEST_STOP_KEEPALIVE:
6284                 return "RIL_REQUEST_STOP_KEEPALIVE";
6285             case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
6286                 return "RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
6287             case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
6288                 return "RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA";
6289             case RIL_REQUEST_ENABLE_MODEM:
6290                 return "RIL_REQUEST_ENABLE_MODEM";
6291             case RIL_REQUEST_GET_MODEM_STATUS:
6292                 return "RIL_REQUEST_GET_MODEM_STATUS";
6293             case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
6294                 return "RIL_REQUEST_ENABLE_UICC_APPLICATIONS";
6295             case RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT:
6296                 return "RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT";
6297             case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
6298                 return "RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS";
6299             case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
6300                 return "RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE";
6301             case RIL_REQUEST_GET_BARRING_INFO:
6302                 return "RIL_REQUEST_GET_BARRING_INFO";
6303             case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION:
6304                 return "RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION";
6305 
6306             default: return "<unknown request>";
6307         }
6308     }
6309 
6310     @UnsupportedAppUsage
responseToString(int request)6311     static String responseToString(int request) {
6312         switch(request) {
6313             case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
6314                 return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
6315             case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
6316                 return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
6317             case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
6318                 return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
6319             case RIL_UNSOL_RESPONSE_NEW_SMS:
6320                 return "UNSOL_RESPONSE_NEW_SMS";
6321             case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
6322                 return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
6323             case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
6324                 return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
6325             case RIL_UNSOL_ON_USSD:
6326                 return "UNSOL_ON_USSD";
6327             case RIL_UNSOL_ON_USSD_REQUEST:
6328                 return "UNSOL_ON_USSD_REQUEST";
6329             case RIL_UNSOL_NITZ_TIME_RECEIVED:
6330                 return "UNSOL_NITZ_TIME_RECEIVED";
6331             case RIL_UNSOL_SIGNAL_STRENGTH:
6332                 return "UNSOL_SIGNAL_STRENGTH";
6333             case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
6334                 return "UNSOL_DATA_CALL_LIST_CHANGED";
6335             case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
6336                 return "UNSOL_SUPP_SVC_NOTIFICATION";
6337             case RIL_UNSOL_STK_SESSION_END:
6338                 return "UNSOL_STK_SESSION_END";
6339             case RIL_UNSOL_STK_PROACTIVE_COMMAND:
6340                 return "UNSOL_STK_PROACTIVE_COMMAND";
6341             case RIL_UNSOL_STK_EVENT_NOTIFY:
6342                 return "UNSOL_STK_EVENT_NOTIFY";
6343             case RIL_UNSOL_STK_CALL_SETUP:
6344                 return "UNSOL_STK_CALL_SETUP";
6345             case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
6346                 return "UNSOL_SIM_SMS_STORAGE_FULL";
6347             case RIL_UNSOL_SIM_REFRESH:
6348                 return "UNSOL_SIM_REFRESH";
6349             case RIL_UNSOL_CALL_RING:
6350                 return "UNSOL_CALL_RING";
6351             case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
6352                 return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
6353             case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
6354                 return "UNSOL_RESPONSE_CDMA_NEW_SMS";
6355             case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
6356                 return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
6357             case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
6358                 return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
6359             case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
6360                 return "UNSOL_RESTRICTED_STATE_CHANGED";
6361             case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
6362                 return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
6363             case RIL_UNSOL_CDMA_CALL_WAITING:
6364                 return "UNSOL_CDMA_CALL_WAITING";
6365             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
6366                 return "UNSOL_CDMA_OTA_PROVISION_STATUS";
6367             case RIL_UNSOL_CDMA_INFO_REC:
6368                 return "UNSOL_CDMA_INFO_REC";
6369             case RIL_UNSOL_OEM_HOOK_RAW:
6370                 return "UNSOL_OEM_HOOK_RAW";
6371             case RIL_UNSOL_RINGBACK_TONE:
6372                 return "UNSOL_RINGBACK_TONE";
6373             case RIL_UNSOL_RESEND_INCALL_MUTE:
6374                 return "UNSOL_RESEND_INCALL_MUTE";
6375             case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
6376                 return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
6377             case RIL_UNSOl_CDMA_PRL_CHANGED:
6378                 return "UNSOL_CDMA_PRL_CHANGED";
6379             case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
6380                 return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
6381             case RIL_UNSOL_RIL_CONNECTED:
6382                 return "UNSOL_RIL_CONNECTED";
6383             case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
6384                 return "UNSOL_VOICE_RADIO_TECH_CHANGED";
6385             case RIL_UNSOL_CELL_INFO_LIST:
6386                 return "UNSOL_CELL_INFO_LIST";
6387             case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
6388                 return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
6389             case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
6390                 return "RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
6391             case RIL_UNSOL_SRVCC_STATE_NOTIFY:
6392                 return "UNSOL_SRVCC_STATE_NOTIFY";
6393             case RIL_UNSOL_HARDWARE_CONFIG_CHANGED:
6394                 return "RIL_UNSOL_HARDWARE_CONFIG_CHANGED";
6395             case RIL_UNSOL_RADIO_CAPABILITY:
6396                 return "RIL_UNSOL_RADIO_CAPABILITY";
6397             case RIL_UNSOL_ON_SS:
6398                 return "UNSOL_ON_SS";
6399             case RIL_UNSOL_STK_CC_ALPHA_NOTIFY:
6400                 return "UNSOL_STK_CC_ALPHA_NOTIFY";
6401             case RIL_UNSOL_LCEDATA_RECV:
6402                 return "UNSOL_LCE_INFO_RECV";
6403             case RIL_UNSOL_PCO_DATA:
6404                 return "UNSOL_PCO_DATA";
6405             case RIL_UNSOL_MODEM_RESTART:
6406                 return "UNSOL_MODEM_RESTART";
6407             case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION:
6408                 return "RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
6409             case RIL_UNSOL_NETWORK_SCAN_RESULT:
6410                 return "RIL_UNSOL_NETWORK_SCAN_RESULT";
6411             case RIL_UNSOL_ICC_SLOT_STATUS:
6412                 return "RIL_UNSOL_ICC_SLOT_STATUS";
6413             case RIL_UNSOL_KEEPALIVE_STATUS:
6414                 return "RIL_UNSOL_KEEPALIVE_STATUS";
6415             case RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG:
6416                 return "RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG";
6417             case RIL_UNSOL_EMERGENCY_NUMBER_LIST:
6418                 return "RIL_UNSOL_EMERGENCY_NUMBER_LIST";
6419             case RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED:
6420                 return "RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED";
6421             case RIL_UNSOL_REGISTRATION_FAILED:
6422                 return "RIL_UNSOL_REGISTRATION_FAILED";
6423             case RIL_UNSOL_BARRING_INFO_CHANGED:
6424                 return "RIL_UNSOL_BARRING_INFO_CHANGED";
6425             default:
6426                 return "<unknown response>";
6427         }
6428     }
6429 
6430     @UnsupportedAppUsage
riljLog(String msg)6431     void riljLog(String msg) {
6432         Rlog.d(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
6433     }
6434 
riljLoge(String msg)6435     void riljLoge(String msg) {
6436         Rlog.e(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
6437     }
6438 
riljLoge(String msg, Exception e)6439     void riljLoge(String msg, Exception e) {
6440         Rlog.e(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"), e);
6441     }
6442 
riljLogv(String msg)6443     void riljLogv(String msg) {
6444         Rlog.v(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
6445     }
6446 
6447     @UnsupportedAppUsage
unsljLog(int response)6448     void unsljLog(int response) {
6449         riljLog("[UNSL]< " + responseToString(response));
6450     }
6451 
6452     @UnsupportedAppUsage
unsljLogMore(int response, String more)6453     void unsljLogMore(int response, String more) {
6454         riljLog("[UNSL]< " + responseToString(response) + " " + more);
6455     }
6456 
6457     @UnsupportedAppUsage
unsljLogRet(int response, Object ret)6458     void unsljLogRet(int response, Object ret) {
6459         riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
6460     }
6461 
6462     @UnsupportedAppUsage
unsljLogvRet(int response, Object ret)6463     void unsljLogvRet(int response, Object ret) {
6464         riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
6465     }
6466 
6467     @Override
setPhoneType(int phoneType)6468     public void setPhoneType(int phoneType) { // Called by GsmCdmaPhone
6469         if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
6470         mPhoneType = phoneType;
6471     }
6472 
6473     /* (non-Javadoc)
6474      * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
6475      */
6476     @Override
testingEmergencyCall()6477     public void testingEmergencyCall() {
6478         if (RILJ_LOGD) riljLog("testingEmergencyCall");
6479         mTestingEmergencyCall.set(true);
6480     }
6481 
dump(FileDescriptor fd, PrintWriter pw, String[] args)6482     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6483         pw.println("RIL: " + this);
6484         pw.println(" mWakeLock=" + mWakeLock);
6485         pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
6486         synchronized (mRequestList) {
6487             synchronized (mWakeLock) {
6488                 pw.println(" mWakeLockCount=" + mWakeLockCount);
6489             }
6490             int count = mRequestList.size();
6491             pw.println(" mRequestList count=" + count);
6492             for (int i = 0; i < count; i++) {
6493                 RILRequest rr = mRequestList.valueAt(i);
6494                 pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
6495             }
6496         }
6497         pw.println(" mLastNITZTimeInfo=" + Arrays.toString(mLastNITZTimeInfo));
6498         pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
6499         mClientWakelockTracker.dumpClientRequestTracker(pw);
6500     }
6501 
getClientRequestStats()6502     public List<ClientRequestStats> getClientRequestStats() {
6503         return mClientWakelockTracker.getClientRequestStats();
6504     }
6505 
6506     /** Append the data to the end of an ArrayList */
appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst)6507     public static void appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst) {
6508         for (byte b : src) {
6509             dst.add(b);
6510         }
6511     }
6512 
primitiveArrayToArrayList(byte[] arr)6513     public static ArrayList<Byte> primitiveArrayToArrayList(byte[] arr) {
6514         ArrayList<Byte> arrayList = new ArrayList<>(arr.length);
6515         for (byte b : arr) {
6516             arrayList.add(b);
6517         }
6518         return arrayList;
6519     }
6520 
6521     /** Convert a primitive int array to an ArrayList<Integer>. */
primitiveArrayToArrayList(int[] arr)6522     public static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
6523         ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
6524         for (int i : arr) {
6525             arrayList.add(i);
6526         }
6527         return arrayList;
6528     }
6529 
6530     /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
arrayListToPrimitiveArray(ArrayList<Byte> bytes)6531     public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
6532         byte[] ret = new byte[bytes.size()];
6533         for (int i = 0; i < ret.length; i++) {
6534             ret[i] = bytes.get(i);
6535         }
6536         return ret;
6537     }
6538 
convertHalHwConfigList( ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil, RIL ril)6539     static ArrayList<HardwareConfig> convertHalHwConfigList(
6540             ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil,
6541             RIL ril) {
6542         int num;
6543         ArrayList<HardwareConfig> response;
6544         HardwareConfig hw;
6545 
6546         num = hwListRil.size();
6547         response = new ArrayList<HardwareConfig>(num);
6548 
6549         if (RILJ_LOGV) {
6550             ril.riljLog("convertHalHwConfigList: num=" + num);
6551         }
6552         for (android.hardware.radio.V1_0.HardwareConfig hwRil : hwListRil) {
6553             int type = hwRil.type;
6554             switch(type) {
6555                 case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
6556                     hw = new HardwareConfig(type);
6557                     HardwareConfigModem hwModem = hwRil.modem.get(0);
6558                     hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
6559                             hwModem.maxVoice, hwModem.maxData, hwModem.maxStandby);
6560                     break;
6561                 }
6562                 case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
6563                     hw = new HardwareConfig(type);
6564                     hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim.get(0).modemUuid);
6565                     break;
6566                 }
6567                 default: {
6568                     throw new RuntimeException(
6569                             "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardward type:" + type);
6570                 }
6571             }
6572 
6573             response.add(hw);
6574         }
6575 
6576         return response;
6577     }
6578 
convertHalRadioCapability( android.hardware.radio.V1_0.RadioCapability rcRil, RIL ril)6579     static RadioCapability convertHalRadioCapability(
6580             android.hardware.radio.V1_0.RadioCapability rcRil, RIL ril) {
6581         int session = rcRil.session;
6582         int phase = rcRil.phase;
6583         // convert to public bitmask {@link TelephonyManager.NetworkTypeBitMask}
6584         int rat = convertToNetworkTypeBitMask(rcRil.raf);
6585         String logicModemUuid = rcRil.logicalModemUuid;
6586         int status = rcRil.status;
6587 
6588         ril.riljLog("convertHalRadioCapability: session=" + session +
6589                 ", phase=" + phase +
6590                 ", rat=" + rat +
6591                 ", logicModemUuid=" + logicModemUuid +
6592                 ", status=" + status + ", rcRil.raf=" + rcRil.raf);
6593         RadioCapability rc = new RadioCapability(
6594                 ril.mPhoneId, session, phase, rat, logicModemUuid, status);
6595         return rc;
6596     }
6597 
convertHalLceData(LceDataInfo halData, RIL ril)6598     static LinkCapacityEstimate convertHalLceData(LceDataInfo halData, RIL ril) {
6599         final LinkCapacityEstimate lce = new LinkCapacityEstimate(
6600                 halData.lastHopCapacityKbps,
6601                 Byte.toUnsignedInt(halData.confidenceLevel),
6602                 halData.lceSuspended ? LinkCapacityEstimate.STATUS_SUSPENDED
6603                         : LinkCapacityEstimate.STATUS_ACTIVE);
6604 
6605         ril.riljLog("LCE capacity information received:" + lce);
6606         return lce;
6607     }
6608 
convertHalLceData( android.hardware.radio.V1_2.LinkCapacityEstimate halData, RIL ril)6609     static LinkCapacityEstimate convertHalLceData(
6610             android.hardware.radio.V1_2.LinkCapacityEstimate halData, RIL ril) {
6611         final LinkCapacityEstimate lce = new LinkCapacityEstimate(
6612                 halData.downlinkCapacityKbps,
6613                 halData.uplinkCapacityKbps);
6614         ril.riljLog("LCE capacity information received:" + lce);
6615         return lce;
6616     }
6617 
6618     /**
6619      * Convert CellInfo defined in 1.0/types.hal to CellInfo type.
6620      * @param records List of CellInfo defined in 1.0/types.hal
6621      * @return List of converted CellInfo object
6622      */
6623     @VisibleForTesting
convertHalCellInfoList( ArrayList<android.hardware.radio.V1_0.CellInfo> records)6624     public static ArrayList<CellInfo> convertHalCellInfoList(
6625             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
6626         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
6627 
6628         final long nanotime = SystemClock.elapsedRealtimeNanos();
6629         for (android.hardware.radio.V1_0.CellInfo record : records) {
6630             record.timeStamp = nanotime;
6631             response.add(CellInfo.create(record));
6632         }
6633 
6634         return response;
6635     }
6636 
6637     /**
6638      * Convert CellInfo defined in 1.2/types.hal to CellInfo type.
6639      * @param records List of CellInfo defined in 1.2/types.hal
6640      * @return List of converted CellInfo object
6641      */
6642     @VisibleForTesting
convertHalCellInfoList_1_2( ArrayList<android.hardware.radio.V1_2.CellInfo> records)6643     public static ArrayList<CellInfo> convertHalCellInfoList_1_2(
6644             ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
6645         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
6646 
6647         final long nanotime = SystemClock.elapsedRealtimeNanos();
6648         for (android.hardware.radio.V1_2.CellInfo record : records) {
6649             record.timeStamp = nanotime;
6650             response.add(CellInfo.create(record));
6651         }
6652         return response;
6653     }
6654 
6655     /**
6656      * Fixup for SignalStrength 1.0 to Assume GSM to WCDMA when
6657      * The current RAT type is one of the UMTS RATs.
6658      * @param signalStrength the initial signal strength
6659      * @return a new SignalStrength if RAT is UMTS or existing SignalStrength
6660      */
fixupSignalStrength10(SignalStrength signalStrength)6661     public SignalStrength fixupSignalStrength10(SignalStrength signalStrength) {
6662         List<CellSignalStrengthGsm> gsmList = signalStrength.getCellSignalStrengths(
6663                 CellSignalStrengthGsm.class);
6664         // If GSM is not the primary type, then bail out; no fixup needed.
6665         if (gsmList.isEmpty() || !gsmList.get(0).isValid()) {
6666             return signalStrength;
6667         }
6668 
6669         CellSignalStrengthGsm gsmStrength = gsmList.get(0);
6670 
6671         // Use the voice RAT which is a guarantee in GSM and UMTS
6672         int voiceRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
6673         Phone phone = PhoneFactory.getPhone(mPhoneId);
6674         if (phone != null) {
6675             ServiceState ss = phone.getServiceState();
6676             if (ss != null) {
6677                 voiceRat = ss.getRilVoiceRadioTechnology();
6678             }
6679         }
6680         switch (voiceRat) {
6681             case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: /* fallthrough */
6682             case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: /* fallthrough */
6683             case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: /* fallthrough */
6684             case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: /* fallthrough */
6685             case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: /* fallthrough */
6686                 break;
6687             default:
6688                 // If we are not currently on WCDMA/HSPA, then we don't need to do a fixup.
6689                 return signalStrength;
6690         }
6691 
6692         // The service state reports WCDMA, and the SignalStrength is reported for GSM, so at this
6693         // point we take an educated guess that the GSM SignalStrength report is actually for
6694         // WCDMA. Also, if we are in WCDMA/GSM we can safely assume that there are no other valid
6695         // signal strength reports (no SRLTE, which is the only supported case in HAL 1.0).
6696         // Thus, we just construct a new SignalStrength and migrate RSSI and BER from the
6697         // GSM report to the WCDMA report, leaving everything else empty.
6698         return new SignalStrength(
6699                 new CellSignalStrengthCdma(), new CellSignalStrengthGsm(),
6700                 new CellSignalStrengthWcdma(gsmStrength.getRssi(),
6701                         gsmStrength.getBitErrorRate(),
6702                         CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE),
6703                 new CellSignalStrengthTdscdma(), new CellSignalStrengthLte(),
6704                 new CellSignalStrengthNr());
6705     }
6706 
6707     /**
6708      * Convert CellInfo defined in 1.4/types.hal to CellInfo type.
6709      * @param records List of CellInfo defined in 1.4/types.hal.
6710      * @return List of converted CellInfo object.
6711      */
6712     @VisibleForTesting
convertHalCellInfoList_1_4( ArrayList<android.hardware.radio.V1_4.CellInfo> records)6713     public static ArrayList<CellInfo> convertHalCellInfoList_1_4(
6714             ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
6715         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
6716 
6717         final long nanotime = SystemClock.elapsedRealtimeNanos();
6718         for (android.hardware.radio.V1_4.CellInfo record : records) {
6719             response.add(CellInfo.create(record, nanotime));
6720         }
6721         return response;
6722     }
6723 
6724     /**
6725      * Convert CellInfo defined in 1.5/types.hal to CellInfo type.
6726      * @param records List of CellInfo defined in 1.5/types.hal.
6727      * @return List of converted CellInfo object.
6728      */
6729     @VisibleForTesting
convertHalCellInfoList_1_5( ArrayList<android.hardware.radio.V1_5.CellInfo> records)6730     public static ArrayList<CellInfo> convertHalCellInfoList_1_5(
6731             ArrayList<android.hardware.radio.V1_5.CellInfo> records) {
6732         ArrayList<CellInfo> response = new ArrayList<>(records.size());
6733 
6734         final long nanotime = SystemClock.elapsedRealtimeNanos();
6735         for (android.hardware.radio.V1_5.CellInfo record : records) {
6736             response.add(CellInfo.create(record, nanotime));
6737         }
6738         return response;
6739     }
6740 
createLinkAddressFromString(String addressString)6741     private static LinkAddress createLinkAddressFromString(String addressString) {
6742         return createLinkAddressFromString(addressString, 0, LinkAddress.LIFETIME_UNKNOWN,
6743                 LinkAddress.LIFETIME_UNKNOWN);
6744     }
6745 
createLinkAddressFromString(String addressString, int properties, long deprecationTime, long expirationTime)6746     private static LinkAddress createLinkAddressFromString(String addressString, int properties,
6747             long deprecationTime, long expirationTime) {
6748         addressString = addressString.trim();
6749         InetAddress address = null;
6750         int prefixLength = -1;
6751         try {
6752             String[] pieces = addressString.split("/", 2);
6753             address = InetAddresses.parseNumericAddress(pieces[0]);
6754             if (pieces.length == 1) {
6755                 prefixLength = (address instanceof Inet4Address) ? 32 : 128;
6756             } else if (pieces.length == 2) {
6757                 prefixLength = Integer.parseInt(pieces[1]);
6758             }
6759         } catch (NullPointerException e) {            // Null string.
6760         } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
6761         } catch (NumberFormatException e) {           // Non-numeric prefix.
6762         } catch (IllegalArgumentException e) {        // Invalid IP address.
6763         }
6764 
6765         if (address == null || prefixLength == -1) {
6766             throw new IllegalArgumentException("Invalid link address " + addressString);
6767         }
6768 
6769         return new LinkAddress(address, prefixLength, properties, 0,
6770                 deprecationTime, expirationTime);
6771     }
6772 
6773     /**
6774      * Convert SetupDataCallResult defined in 1.0, 1.4, or 1.5 types.hal into DataCallResponse
6775      * @param dcResult setup data call result
6776      * @return converted DataCallResponse object
6777      */
6778     @VisibleForTesting
convertDataCallResult(Object dcResult)6779     public static DataCallResponse convertDataCallResult(Object dcResult) {
6780         if (dcResult == null) return null;
6781 
6782         int cause, suggestedRetryTime, cid, active, mtu, mtuV4, mtuV6;
6783         String ifname;
6784         int protocolType;
6785         String[] addresses = null;
6786         String[] dnses = null;
6787         String[] gateways = null;
6788         String[] pcscfs = null;
6789 
6790         List<LinkAddress> laList = new ArrayList<>();
6791 
6792         if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) {
6793             final android.hardware.radio.V1_0.SetupDataCallResult result =
6794                     (android.hardware.radio.V1_0.SetupDataCallResult) dcResult;
6795             cause = result.status;
6796             suggestedRetryTime = result.suggestedRetryTime;
6797             cid = result.cid;
6798             active = result.active;
6799             protocolType = ApnSetting.getProtocolIntFromString(result.type);
6800             ifname = result.ifname;
6801             if (!TextUtils.isEmpty(result.addresses)) {
6802                 addresses = result.addresses.split("\\s+");
6803             }
6804             if (!TextUtils.isEmpty(result.dnses)) {
6805                 dnses = result.dnses.split("\\s+");
6806             }
6807             if (!TextUtils.isEmpty(result.gateways)) {
6808                 gateways = result.gateways.split("\\s+");
6809             }
6810             if (!TextUtils.isEmpty(result.pcscf)) {
6811                 pcscfs = result.pcscf.split("\\s+");
6812             }
6813             mtu = mtuV4 = mtuV6 = result.mtu;
6814             if (addresses != null) {
6815                 for (String address : addresses) {
6816                     laList.add(createLinkAddressFromString(address));
6817                 }
6818             }
6819         } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) {
6820             final android.hardware.radio.V1_4.SetupDataCallResult result =
6821                     (android.hardware.radio.V1_4.SetupDataCallResult) dcResult;
6822             cause = result.cause;
6823             suggestedRetryTime = result.suggestedRetryTime;
6824             cid = result.cid;
6825             active = result.active;
6826             protocolType = result.type;
6827             ifname = result.ifname;
6828             addresses = result.addresses.stream().toArray(String[]::new);
6829             dnses = result.dnses.stream().toArray(String[]::new);
6830             gateways = result.gateways.stream().toArray(String[]::new);
6831             pcscfs = result.pcscf.stream().toArray(String[]::new);
6832             mtu = mtuV4 = mtuV6 = result.mtu;
6833             if (addresses != null) {
6834                 for (String address : addresses) {
6835                     laList.add(createLinkAddressFromString(address));
6836                 }
6837             }
6838         } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) {
6839             final android.hardware.radio.V1_5.SetupDataCallResult result =
6840                     (android.hardware.radio.V1_5.SetupDataCallResult) dcResult;
6841             cause = result.cause;
6842             suggestedRetryTime = result.suggestedRetryTime;
6843             cid = result.cid;
6844             active = result.active;
6845             protocolType = result.type;
6846             ifname = result.ifname;
6847             laList = result.addresses.stream().map(la -> createLinkAddressFromString(
6848                     la.address, la.properties, la.deprecationTime, la.expirationTime))
6849                     .collect(Collectors.toList());
6850 
6851             dnses = result.dnses.stream().toArray(String[]::new);
6852             gateways = result.gateways.stream().toArray(String[]::new);
6853             pcscfs = result.pcscf.stream().toArray(String[]::new);
6854             mtu = Math.max(result.mtuV4, result.mtuV6);
6855             mtuV4 = result.mtuV4;
6856             mtuV6 = result.mtuV6;
6857         } else {
6858             Rlog.e(RILJ_LOG_TAG, "Unsupported SetupDataCallResult " + dcResult);
6859             return null;
6860         }
6861 
6862         // Process dns
6863         List<InetAddress> dnsList = new ArrayList<>();
6864         if (dnses != null) {
6865             for (String dns : dnses) {
6866                 dns = dns.trim();
6867                 InetAddress ia;
6868                 try {
6869                     ia = InetAddresses.parseNumericAddress(dns);
6870                     dnsList.add(ia);
6871                 } catch (IllegalArgumentException e) {
6872                     Rlog.e(RILJ_LOG_TAG, "Unknown dns: " + dns, e);
6873                 }
6874             }
6875         }
6876 
6877         // Process gateway
6878         List<InetAddress> gatewayList = new ArrayList<>();
6879         if (gateways != null) {
6880             for (String gateway : gateways) {
6881                 gateway = gateway.trim();
6882                 InetAddress ia;
6883                 try {
6884                     ia = InetAddresses.parseNumericAddress(gateway);
6885                     gatewayList.add(ia);
6886                 } catch (IllegalArgumentException e) {
6887                     Rlog.e(RILJ_LOG_TAG, "Unknown gateway: " + gateway, e);
6888                 }
6889             }
6890         }
6891 
6892         // Process gateway
6893         List<InetAddress> pcscfList = new ArrayList<>();
6894         if (pcscfs != null) {
6895             for (String pcscf : pcscfs) {
6896                 pcscf = pcscf.trim();
6897                 InetAddress ia;
6898                 try {
6899                     ia = InetAddresses.parseNumericAddress(pcscf);
6900                     pcscfList.add(ia);
6901                 } catch (IllegalArgumentException e) {
6902                     Rlog.e(RILJ_LOG_TAG, "Unknown pcscf: " + pcscf, e);
6903                 }
6904             }
6905         }
6906 
6907         return new DataCallResponse.Builder()
6908                 .setCause(cause)
6909                 .setSuggestedRetryTime(suggestedRetryTime)
6910                 .setId(cid)
6911                 .setLinkStatus(active)
6912                 .setProtocolType(protocolType)
6913                 .setInterfaceName(ifname)
6914                 .setAddresses(laList)
6915                 .setDnsAddresses(dnsList)
6916                 .setGatewayAddresses(gatewayList)
6917                 .setPcscfAddresses(pcscfList)
6918                 .setMtu(mtu)
6919                 .setMtuV4(mtuV4)
6920                 .setMtuV6(mtuV6)
6921                 .build();
6922     }
6923 
6924     /**
6925      * Convert SetupDataCallResult defined in 1.0 or 1.4/types.hal into DataCallResponse
6926      * @param dataCallResultList List of SetupDataCallResult defined in 1.0 or 1.4/types.hal
6927      * @return List of converted DataCallResponse object
6928      */
6929     @VisibleForTesting
convertDataCallResultList( List<? extends Object> dataCallResultList)6930     public static ArrayList<DataCallResponse> convertDataCallResultList(
6931             List<? extends Object> dataCallResultList) {
6932         ArrayList<DataCallResponse> response =
6933                 new ArrayList<DataCallResponse>(dataCallResultList.size());
6934 
6935         for (Object obj : dataCallResultList) {
6936             response.add(convertDataCallResult(obj));
6937         }
6938         return response;
6939     }
6940 
6941     /**
6942      * Get the HAL version.
6943      *
6944      * @return the current HalVersion
6945      */
getHalVersion()6946     public HalVersion getHalVersion() {
6947         return mRadioVersion;
6948     }
6949 }
6950