1 /*
2  * Copyright (C) 2021 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.REQUEST_NOT_SUPPORTED;
20 
21 import android.annotation.NonNull;
22 import android.os.AsyncResult;
23 import android.os.Message;
24 import android.os.RemoteException;
25 import android.telephony.AccessNetworkConstants;
26 import android.telephony.NetworkScanRequest;
27 import android.telephony.RadioAccessSpecifier;
28 import android.telephony.Rlog;
29 import android.telephony.SignalThresholdInfo;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.stream.Collectors;
34 
35 /**
36  * A holder for IRadioNetwork.
37  * Use getAidl to get IRadioNetwork and call the AIDL implementations of the HAL APIs.
38  */
39 public class RadioNetworkProxy extends RadioServiceProxy {
40     private static final String TAG = "RadioNetworkProxy";
41     private volatile android.hardware.radio.network.IRadioNetwork mNetworkProxy = null;
42 
43     private static final int INDICATION_FILTERS_ALL_V1_2 =
44             android.hardware.radio.V1_5.IndicationFilter.SIGNAL_STRENGTH
45                     | android.hardware.radio.V1_5.IndicationFilter.FULL_NETWORK_STATE
46                     | android.hardware.radio.V1_5.IndicationFilter.DATA_CALL_DORMANCY_CHANGED
47                     | android.hardware.radio.V1_5.IndicationFilter.LINK_CAPACITY_ESTIMATE
48                     | android.hardware.radio.V1_5.IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
49     private static final int INDICATION_FILTERS_ALL_V1_5 =
50             INDICATION_FILTERS_ALL_V1_2
51                     | android.hardware.radio.V1_5.IndicationFilter.REGISTRATION_FAILURE
52                     | android.hardware.radio.V1_5.IndicationFilter.BARRING_INFO;
53     private static final int INDICATION_FILTERS_ALL_AIDL =
54             android.hardware.radio.network.IndicationFilter.SIGNAL_STRENGTH
55                     | android.hardware.radio.network.IndicationFilter.FULL_NETWORK_STATE
56                     | android.hardware.radio.network.IndicationFilter.DATA_CALL_DORMANCY_CHANGED
57                     | android.hardware.radio.network.IndicationFilter.LINK_CAPACITY_ESTIMATE
58                     | android.hardware.radio.network.IndicationFilter.PHYSICAL_CHANNEL_CONFIG
59                     | android.hardware.radio.network.IndicationFilter.REGISTRATION_FAILURE
60                     | android.hardware.radio.network.IndicationFilter.BARRING_INFO;
61 
62     /**
63      * Set IRadioNetwork as the AIDL implementation for RadioServiceProxy
64      * @param halVersion Radio HAL version
65      * @param network IRadioNetwork implementation
66      *
67      * @return updated HAL version
68      */
setAidl(HalVersion halVersion, android.hardware.radio.network.IRadioNetwork network)69     public HalVersion setAidl(HalVersion halVersion,
70             android.hardware.radio.network.IRadioNetwork network) {
71         HalVersion version = halVersion;
72         try {
73             version = RIL.getServiceHalVersion(network.getInterfaceVersion());
74         } catch (RemoteException e) {
75             Rlog.e(TAG, "setAidl: " + e);
76         }
77         mHalVersion = version;
78         mNetworkProxy = network;
79         mIsAidl = true;
80 
81         Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
82         return mHalVersion;
83     }
84 
85     /**
86      * Get the AIDL implementation of RadioNetworkProxy
87      * @return IRadioNetwork implementation
88      */
getAidl()89     public android.hardware.radio.network.IRadioNetwork getAidl() {
90         return mNetworkProxy;
91     }
92 
93     /**
94      * Reset RadioNetworkProxy
95      */
96     @Override
clear()97     public void clear() {
98         super.clear();
99         mNetworkProxy = null;
100     }
101 
102     /**
103      * Check whether a RadioNetwork implementation exists
104      * @return true if there is neither a HIDL nor AIDL implementation
105      */
106     @Override
isEmpty()107     public boolean isEmpty() {
108         return mRadioProxy == null && mNetworkProxy == null;
109     }
110 
111     /**
112      * Call IRadioNetwork#getAllowedNetworkTypesBitmap
113      * @param serial Serial number of request
114      * @throws RemoteException
115      */
getAllowedNetworkTypesBitmap(int serial)116     public void getAllowedNetworkTypesBitmap(int serial) throws RemoteException {
117         if (isEmpty()) return;
118         if (isAidl()) {
119             mNetworkProxy.getAllowedNetworkTypesBitmap(serial);
120         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
121             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getAllowedNetworkTypesBitmap(serial);
122         } else {
123             mRadioProxy.getPreferredNetworkTypeBitmap(serial);
124         }
125     }
126 
127     /**
128      * Call IRadioNetwork#getAvailableBandModes
129      * @param serial Serial number of request
130      * @throws RemoteException
131      */
getAvailableBandModes(int serial)132     public void getAvailableBandModes(int serial) throws RemoteException {
133         if (isEmpty()) return;
134         if (isAidl()) {
135             mNetworkProxy.getAvailableBandModes(serial);
136         } else {
137             mRadioProxy.getAvailableBandModes(serial);
138         }
139     }
140 
141     /**
142      * Call IRadioNetwork#getAvailableNetworks
143      * @param serial Serial number of request
144      * @throws RemoteException
145      */
getAvailableNetworks(int serial)146     public void getAvailableNetworks(int serial) throws RemoteException {
147         if (isEmpty()) return;
148         if (isAidl()) {
149             mNetworkProxy.getAvailableNetworks(serial);
150         } else {
151             mRadioProxy.getAvailableNetworks(serial);
152         }
153     }
154 
155     /**
156      * Call IRadioNetwork#getBarringInfo
157      * @param serial Serial number of request
158      * @throws RemoteException
159      */
getBarringInfo(int serial)160     public void getBarringInfo(int serial) throws RemoteException {
161         if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_5)) return;
162         if (isAidl()) {
163             mNetworkProxy.getBarringInfo(serial);
164         } else {
165             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).getBarringInfo(serial);
166         }
167     }
168 
169     /**
170      * Call IRadioNetwork#getCdmaRoamingPreference
171      * @param serial Serial number of request
172      * @throws RemoteException
173      */
getCdmaRoamingPreference(int serial)174     public void getCdmaRoamingPreference(int serial) throws RemoteException {
175         if (isEmpty()) return;
176         if (isAidl()) {
177             mNetworkProxy.getCdmaRoamingPreference(serial);
178         } else {
179             mRadioProxy.getCdmaRoamingPreference(serial);
180         }
181     }
182 
183     /**
184      * Call IRadioNetwork#getCellInfoList
185      * @param serial Serial number of request
186      * @throws RemoteException
187      */
getCellInfoList(int serial)188     public void getCellInfoList(int serial) throws RemoteException {
189         if (isEmpty()) return;
190         if (isAidl()) {
191             mNetworkProxy.getCellInfoList(serial);
192         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
193             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getCellInfoList_1_6(serial);
194         } else {
195             mRadioProxy.getCellInfoList(serial);
196         }
197     }
198 
199     /**
200      * Call IRadioNetwork#getDataRegistrationState
201      * @param serial Serial number of request
202      * @param overrideHalVersion Radio HAL fallback compatibility override
203      * @throws RemoteException
204      */
getDataRegistrationState(int serial, HalVersion overrideHalVersion)205     public void getDataRegistrationState(int serial, HalVersion overrideHalVersion)
206             throws RemoteException {
207         if (isEmpty()) return;
208         if (isAidl()) {
209             mNetworkProxy.getDataRegistrationState(serial);
210         } else if ((overrideHalVersion == null
211                 || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6))
212                 && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
213             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getDataRegistrationState_1_6(serial);
214         } else if ((overrideHalVersion == null
215                 || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
216                 && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
217             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).getDataRegistrationState_1_5(serial);
218         } else {
219             mRadioProxy.getDataRegistrationState(serial);
220         }
221     }
222 
223     /**
224      * Call IRadioNetwork#getImsRegistrationState
225      * @param serial Serial number of request
226      * @throws RemoteException
227      */
getImsRegistrationState(int serial)228     public void getImsRegistrationState(int serial) throws RemoteException {
229         if (isEmpty()) return;
230         if (isAidl()) {
231             mNetworkProxy.getImsRegistrationState(serial);
232         } else {
233             mRadioProxy.getImsRegistrationState(serial);
234         }
235     }
236 
237     /**
238      * Call IRadioNetwork#getNetworkSelectionMode
239      * @param serial Serial number of request
240      * @throws RemoteException
241      */
getNetworkSelectionMode(int serial)242     public void getNetworkSelectionMode(int serial) throws RemoteException {
243         if (isEmpty()) return;
244         if (isAidl()) {
245             mNetworkProxy.getNetworkSelectionMode(serial);
246         } else {
247             mRadioProxy.getNetworkSelectionMode(serial);
248         }
249     }
250 
251     /**
252      * Call IRadioNetwork#getOperator
253      * @param serial Serial number of request
254      * @throws RemoteException
255      */
getOperator(int serial)256     public void getOperator(int serial) throws RemoteException {
257         if (isEmpty()) return;
258         if (isAidl()) {
259             mNetworkProxy.getOperator(serial);
260         } else {
261             mRadioProxy.getOperator(serial);
262         }
263     }
264 
265     /**
266      * Call IRadioNetwork#getSignalStrength
267      * @param serial Serial number of request
268      * @throws RemoteException
269      */
getSignalStrength(int serial)270     public void getSignalStrength(int serial) throws RemoteException {
271         if (isEmpty()) return;
272         if (isAidl()) {
273             mNetworkProxy.getSignalStrength(serial);
274         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
275             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSignalStrength_1_6(serial);
276         } else {
277             mRadioProxy.getSignalStrength_1_4(serial);
278         }
279     }
280 
281     /**
282      * Call IRadioNetwork#getSystemSelectionChannels
283      * @param serial Serial number of request
284      * @throws RemoteException
285      */
getSystemSelectionChannels(int serial)286     public void getSystemSelectionChannels(int serial) throws RemoteException {
287         if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
288         if (isAidl()) {
289             mNetworkProxy.getSystemSelectionChannels(serial);
290         } else {
291             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSystemSelectionChannels(serial);
292         }
293     }
294 
295     /**
296      * Call IRadioNetwork#getVoiceRadioTechnology
297      * @param serial Serial number of request
298      * @throws RemoteException
299      */
getVoiceRadioTechnology(int serial)300     public void getVoiceRadioTechnology(int serial) throws RemoteException {
301         if (isEmpty()) return;
302         if (isAidl()) {
303             mNetworkProxy.getVoiceRadioTechnology(serial);
304         } else {
305             mRadioProxy.getVoiceRadioTechnology(serial);
306         }
307     }
308 
309     /**
310      * Call IRadioNetwork#getVoiceRegistrationState
311      * @param serial Serial number of request
312      * @param overrideHalVersion Radio HAL fallback compatibility override
313      * @throws RemoteException
314      */
getVoiceRegistrationState(int serial, HalVersion overrideHalVersion)315     public void getVoiceRegistrationState(int serial, HalVersion overrideHalVersion)
316             throws RemoteException {
317         if (isEmpty()) return;
318         if (isAidl()) {
319             mNetworkProxy.getVoiceRegistrationState(serial);
320         } else if ((overrideHalVersion == null
321                 || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6))
322                 && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
323             ((android.hardware.radio.V1_6.IRadio) mRadioProxy)
324                     .getVoiceRegistrationState_1_6(serial);
325         } else if ((overrideHalVersion == null
326                 || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
327                 && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
328             ((android.hardware.radio.V1_5.IRadio) mRadioProxy)
329                     .getVoiceRegistrationState_1_5(serial);
330         } else {
331             mRadioProxy.getVoiceRegistrationState(serial);
332         }
333     }
334 
335     /**
336      * Call IRadioNetwork#isNrDualConnectivityEnabled
337      * @param serial Serial number of request
338      * @throws RemoteException
339      */
isNrDualConnectivityEnabled(int serial)340     public void isNrDualConnectivityEnabled(int serial) throws RemoteException {
341         if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
342         if (isAidl()) {
343             mNetworkProxy.isNrDualConnectivityEnabled(serial);
344         } else {
345             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).isNrDualConnectivityEnabled(serial);
346         }
347     }
348 
349     /**
350      * Call IRadioNetwork#responseAcknowledgement
351      * @throws RemoteException
352      */
353     @Override
responseAcknowledgement()354     public void responseAcknowledgement() throws RemoteException {
355         if (isEmpty()) return;
356         if (isAidl()) {
357             mNetworkProxy.responseAcknowledgement();
358         } else {
359             mRadioProxy.responseAcknowledgement();
360         }
361     }
362 
363     /**
364      * Call IRadioNetwork#setAllowedNetworkTypesBitmap
365      * @param serial Serial number of request
366      * @param networkTypeBitmask Network type bitmask to set
367      * @throws RemoteException
368      */
setAllowedNetworkTypesBitmap(int serial, int networkTypeBitmask)369     public void setAllowedNetworkTypesBitmap(int serial, int networkTypeBitmask)
370             throws RemoteException {
371         if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
372         if (isAidl()) {
373             mNetworkProxy.setAllowedNetworkTypesBitmap(serial,
374                     RILUtils.convertToHalRadioAccessFamilyAidl(networkTypeBitmask));
375         } else {
376             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setAllowedNetworkTypesBitmap(
377                     serial, RILUtils.convertToHalRadioAccessFamily(networkTypeBitmask));
378         }
379     }
380 
381     /**
382      * Call IRadioNetwork#setPreferredNetworkTypeBitmap
383      * @param serial Serial number of request
384      * @param networkTypesBitmask Preferred network types bitmask to set
385      * @throws RemoteException
386      */
setPreferredNetworkTypeBitmap(int serial, int networkTypesBitmask)387     public void setPreferredNetworkTypeBitmap(int serial, int networkTypesBitmask)
388             throws RemoteException {
389         if (isEmpty() || mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) return;
390         mRadioProxy.setPreferredNetworkTypeBitmap(serial,
391                 RILUtils.convertToHalRadioAccessFamily(networkTypesBitmask));
392     }
393 
394     /**
395      * Call IRadioNetwork#setBandMode
396      * @param serial Serial number of request
397      * @param bandMode One of BM_*_BAND
398      * @throws RemoteException
399      */
setBandMode(int serial, int bandMode)400     public void setBandMode(int serial, int bandMode) throws RemoteException {
401         if (isEmpty()) return;
402         if (isAidl()) {
403             mNetworkProxy.setBandMode(serial, bandMode);
404         } else {
405             mRadioProxy.setBandMode(serial, bandMode);
406         }
407     }
408 
409     /**
410      * Call IRadioNetwork#setBarringPassword
411      * @param serial Serial number of request
412      * @param facility Facility string code
413      * @param oldPassword Old password
414      * @param newPassword New password
415      * @throws RemoteException
416      */
setBarringPassword(int serial, String facility, String oldPassword, String newPassword)417     public void setBarringPassword(int serial, String facility, String oldPassword,
418             String newPassword) throws RemoteException {
419         if (isEmpty()) return;
420         if (isAidl()) {
421             mNetworkProxy.setBarringPassword(serial, facility, oldPassword, newPassword);
422         } else {
423             mRadioProxy.setBarringPassword(serial, facility, oldPassword, newPassword);
424         }
425     }
426 
427     /**
428      * Call IRadioNetwork#setCdmaRoamingPreference
429      * @param serial Serial number of request
430      * @param cdmaRoamingType One of CDMA_RM_*
431      * @throws RemoteException
432      */
setCdmaRoamingPreference(int serial, int cdmaRoamingType)433     public void setCdmaRoamingPreference(int serial, int cdmaRoamingType) throws RemoteException {
434         if (isEmpty()) return;
435         if (isAidl()) {
436             mNetworkProxy.setCdmaRoamingPreference(serial, cdmaRoamingType);
437         } else {
438             mRadioProxy.setCdmaRoamingPreference(serial, cdmaRoamingType);
439         }
440     }
441 
442     /**
443      * Call IRadioNetwork#setCellInfoListRate
444      * @param serial Serial number of request
445      * @param rate Minimum time in milliseconds to indicate time between unsolicited cellInfoList()
446      * @throws RemoteException
447      */
setCellInfoListRate(int serial, int rate)448     public void setCellInfoListRate(int serial, int rate) throws RemoteException {
449         if (isEmpty()) return;
450         if (isAidl()) {
451             mNetworkProxy.setCellInfoListRate(serial, rate);
452         } else {
453             mRadioProxy.setCellInfoListRate(serial, rate);
454         }
455     }
456 
457     /**
458      * Call IRadioNetwork#setIndicationFilter
459      * @param serial Serial number of request
460      * @param filter Unsolicited response filter
461      * @throws RemoteException
462      */
setIndicationFilter(int serial, int filter)463     public void setIndicationFilter(int serial, int filter) throws RemoteException {
464         if (isEmpty()) return;
465         if (isAidl()) {
466             mNetworkProxy.setIndicationFilter(serial, filter & INDICATION_FILTERS_ALL_AIDL);
467         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
468             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setIndicationFilter_1_5(serial,
469                     filter & INDICATION_FILTERS_ALL_V1_5);
470         } else {
471             mRadioProxy.setIndicationFilter_1_2(serial, filter & INDICATION_FILTERS_ALL_V1_2);
472         }
473     }
474 
475     /**
476      * Call IRadioNetwork#setLinkCapacityReportingCriteria
477      * @param serial Serial number of request
478      * @param hysteresisMs A hysteresis time in milliseconds. A value of 0 disables hysteresis.
479      * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
480      *                         reports. A value of 0 disables hysteresis
481      * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
482      *                         reports. A value of 0 disables hysteresis
483      * @param thresholdsDlKbps An array of trigger thresholds in kbps for DL reports. A size of 0
484      *                         disables thresholds
485      * @param thresholdsUlKbps An array of trigger thresholds in kbps for UL reports. A size of 0
486      *                         disables thresholds
487      * @param ran RadioAccessNetwork for which to apply criteria
488      * @throws RemoteException
489      */
setLinkCapacityReportingCriteria(int serial, int hysteresisMs, int hysteresisDlKbps, int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran)490     public void setLinkCapacityReportingCriteria(int serial, int hysteresisMs, int hysteresisDlKbps,
491             int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran)
492             throws RemoteException {
493         if (isEmpty()) return;
494         if (isAidl()) {
495             mNetworkProxy.setLinkCapacityReportingCriteria(serial, hysteresisMs, hysteresisDlKbps,
496                     hysteresisUlKbps, thresholdsDlKbps, thresholdsUlKbps,
497                     RILUtils.convertToHalAccessNetworkAidl(ran));
498         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
499             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setLinkCapacityReportingCriteria_1_5(
500                     serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps,
501                     RILUtils.primitiveArrayToArrayList(thresholdsDlKbps),
502                     RILUtils.primitiveArrayToArrayList(thresholdsUlKbps),
503                     RILUtils.convertToHalAccessNetwork(ran));
504         } else {
505             if (ran == AccessNetworkConstants.AccessNetworkType.NGRAN) {
506                 throw new RuntimeException("NGRAN unsupported on IRadio version: " + mHalVersion);
507             }
508             mRadioProxy.setLinkCapacityReportingCriteria(
509                     serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps,
510                     RILUtils.primitiveArrayToArrayList(thresholdsDlKbps),
511                     RILUtils.primitiveArrayToArrayList(thresholdsUlKbps),
512                     RILUtils.convertToHalAccessNetwork(ran));
513         }
514     }
515 
516     /**
517      * Call IRadioNetwork#setLocationUpdates
518      * @param serial Serial number of request
519      * @param enable Whether to enable or disable network state change notifications when location
520      *               information (lac and/or cid) has changed
521      * @throws RemoteException
522      */
setLocationUpdates(int serial, boolean enable)523     public void setLocationUpdates(int serial, boolean enable) throws RemoteException {
524         if (isEmpty()) return;
525         if (isAidl()) {
526             mNetworkProxy.setLocationUpdates(serial, enable);
527         } else {
528             mRadioProxy.setLocationUpdates(serial, enable);
529         }
530     }
531 
532     /**
533      * Call IRadioNetwork#setNetworkSelectionModeAutomatic
534      * @param serial Serial number of request
535      * @throws RemoteException
536      */
setNetworkSelectionModeAutomatic(int serial)537     public void setNetworkSelectionModeAutomatic(int serial) throws RemoteException {
538         if (isEmpty()) return;
539         if (isAidl()) {
540             mNetworkProxy.setNetworkSelectionModeAutomatic(serial);
541         } else {
542             mRadioProxy.setNetworkSelectionModeAutomatic(serial);
543         }
544     }
545 
546     /**
547      * Call IRadioNetwork#setNetworkSelectionModeManual
548      * @param serial Serial number of request
549      * @param operatorNumeric PLMN ID of the network to select
550      * @param ran Radio access network type
551      * @throws RemoteException
552      */
setNetworkSelectionModeManual(int serial, String operatorNumeric, int ran)553     public void setNetworkSelectionModeManual(int serial, String operatorNumeric, int ran)
554             throws RemoteException {
555         if (isEmpty()) return;
556         if (isAidl()) {
557             mNetworkProxy.setNetworkSelectionModeManual(serial, operatorNumeric,
558                     RILUtils.convertToHalAccessNetworkAidl(ran));
559         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
560             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setNetworkSelectionModeManual_1_5(
561                     serial, operatorNumeric, RILUtils.convertToHalRadioAccessNetworks(ran));
562         } else {
563             mRadioProxy.setNetworkSelectionModeManual(serial, operatorNumeric);
564         }
565     }
566 
567     /**
568      * Call IRadioNetwork#setNrDualConnectivityState
569      * @param serial Serial number of request
570      * @param nrDualConnectivityState Expected NR dual connectivity state
571      * @throws RemoteException
572      */
setNrDualConnectivityState(int serial, byte nrDualConnectivityState)573     public void setNrDualConnectivityState(int serial, byte nrDualConnectivityState)
574             throws RemoteException {
575         if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
576         if (isAidl()) {
577             mNetworkProxy.setNrDualConnectivityState(serial, nrDualConnectivityState);
578         } else {
579             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setNrDualConnectivityState(
580                     serial, nrDualConnectivityState);
581         }
582     }
583 
584     /**
585      * Call IRadioNetwork#setSignalStrengthReportingCriteria
586      * @param serial Serial number of request
587      * @param signalThresholdInfos a list of {@link SignalThresholdInfo} to set with.
588      * @throws RemoteException
589      */
setSignalStrengthReportingCriteria(int serial, @NonNull List<SignalThresholdInfo> signalThresholdInfos)590     public void setSignalStrengthReportingCriteria(int serial,
591             @NonNull List<SignalThresholdInfo> signalThresholdInfos) throws RemoteException {
592         if (isEmpty()) return;
593         if (isAidl()) {
594             android.hardware.radio.network.SignalThresholdInfo[] halSignalThresholdsInfos =
595             new android.hardware.radio.network.SignalThresholdInfo[signalThresholdInfos.size()];
596             for (int i = 0; i < signalThresholdInfos.size(); i++) {
597                 halSignalThresholdsInfos[i] = RILUtils.convertToHalSignalThresholdInfoAidl(
598                         signalThresholdInfos.get(i));
599             }
600             mNetworkProxy.setSignalStrengthReportingCriteria(serial, halSignalThresholdsInfos);
601         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
602             for (SignalThresholdInfo signalThresholdInfo : signalThresholdInfos) {
603                 ((android.hardware.radio.V1_5.IRadio) mRadioProxy)
604                         .setSignalStrengthReportingCriteria_1_5(serial,
605                                 RILUtils.convertToHalSignalThresholdInfo(signalThresholdInfo),
606                                 RILUtils.convertToHalAccessNetwork(
607                                         signalThresholdInfo.getRadioAccessNetworkType()));
608             }
609         } else {
610             for (SignalThresholdInfo signalThresholdInfo : signalThresholdInfos) {
611                 mRadioProxy.setSignalStrengthReportingCriteria(serial,
612                         signalThresholdInfo.getHysteresisMs(),
613                         signalThresholdInfo.getHysteresisDb(),
614                         RILUtils.primitiveArrayToArrayList(signalThresholdInfo.getThresholds()),
615                         RILUtils.convertToHalAccessNetwork(
616                                 signalThresholdInfo.getRadioAccessNetworkType()));
617             }
618         }
619     }
620 
621     /**
622      * Call IRadioNetwork#setSuppServiceNotifications
623      * @param serial Serial number of request
624      * @param enable True to enable notifications, false to disable
625      * @throws RemoteException
626      */
setSuppServiceNotifications(int serial, boolean enable)627     public void setSuppServiceNotifications(int serial, boolean enable) throws RemoteException {
628         if (isEmpty()) return;
629         if (isAidl()) {
630             mNetworkProxy.setSuppServiceNotifications(serial, enable);
631         } else {
632             mRadioProxy.setSuppServiceNotifications(serial, enable);
633         }
634     }
635 
636     /**
637      * Call IRadioNetwork#setSystemSelectionChannels
638      * @param serial Serial number of request
639      * @param specifiers Which bands to scan
640      * @throws RemoteException
641      */
setSystemSelectionChannels(int serial, List<RadioAccessSpecifier> specifiers)642     public void setSystemSelectionChannels(int serial, List<RadioAccessSpecifier> specifiers)
643             throws RemoteException {
644         if (isEmpty()) return;
645         if (isAidl()) {
646             mNetworkProxy.setSystemSelectionChannels(serial, !specifiers.isEmpty(),
647                     specifiers.stream().map(RILUtils::convertToHalRadioAccessSpecifierAidl)
648                             .toArray(android.hardware.radio.network.RadioAccessSpecifier[]::new));
649         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
650             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setSystemSelectionChannels_1_5(
651                     serial, !specifiers.isEmpty(), specifiers.stream()
652                             .map(RILUtils::convertToHalRadioAccessSpecifier15)
653                             .collect(Collectors.toCollection(ArrayList::new)));
654         } else {
655             mRadioProxy.setSystemSelectionChannels(serial, !specifiers.isEmpty(),
656                     specifiers.stream()
657                             .map(RILUtils::convertToHalRadioAccessSpecifier11)
658                             .collect(Collectors.toCollection(ArrayList::new)));
659         }
660     }
661 
662     /**
663      * Call IRadioNetwork#startNetworkScan
664      * @param serial Serial number of request
665      * @param request Defines the radio networks/bands/channels which need to be scanned
666      * @param overrideHalVersion Radio HAL fallback compatibility override
667      * @throws RemoteException
668      */
startNetworkScan(int serial, NetworkScanRequest request, HalVersion overrideHalVersion, Message result)669     public void startNetworkScan(int serial, NetworkScanRequest request,
670             HalVersion overrideHalVersion, Message result) throws RemoteException {
671         if (isEmpty()) return;
672         if (isAidl()) {
673             android.hardware.radio.network.NetworkScanRequest halRequest =
674                     new android.hardware.radio.network.NetworkScanRequest();
675             halRequest.type = request.getScanType();
676             halRequest.interval = request.getSearchPeriodicity();
677             halRequest.maxSearchTime = request.getMaxSearchTime();
678             halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
679             halRequest.incrementalResults = request.getIncrementalResults();
680             halRequest.mccMncs = request.getPlmns().stream().toArray(String[]::new);
681             ArrayList<android.hardware.radio.network.RadioAccessSpecifier> specifiers =
682                     new ArrayList<>();
683             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
684                 android.hardware.radio.network.RadioAccessSpecifier rasInHalFormat =
685                         RILUtils.convertToHalRadioAccessSpecifierAidl(ras);
686                 if (rasInHalFormat == null) {
687                     AsyncResult.forMessage(result, null,
688                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
689                     result.sendToTarget();
690                     return;
691                 }
692                 specifiers.add(rasInHalFormat);
693             }
694             halRequest.specifiers = specifiers.stream().toArray(
695                     android.hardware.radio.network.RadioAccessSpecifier[]::new);
696             mNetworkProxy.startNetworkScan(serial, halRequest);
697         } else if ((overrideHalVersion == null
698                 || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
699                 && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
700             android.hardware.radio.V1_5.NetworkScanRequest halRequest =
701                     new android.hardware.radio.V1_5.NetworkScanRequest();
702             halRequest.type = request.getScanType();
703             halRequest.interval = request.getSearchPeriodicity();
704             halRequest.maxSearchTime = request.getMaxSearchTime();
705             halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
706             halRequest.incrementalResults = request.getIncrementalResults();
707             halRequest.mccMncs.addAll(request.getPlmns());
708             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
709                 android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
710                         RILUtils.convertToHalRadioAccessSpecifier15(ras);
711                 if (rasInHalFormat == null) {
712                     AsyncResult.forMessage(result, null,
713                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
714                     result.sendToTarget();
715                     return;
716                 }
717                 halRequest.specifiers.add(rasInHalFormat);
718             }
719             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).startNetworkScan_1_5(
720                     serial, halRequest);
721         } else {
722             android.hardware.radio.V1_2.NetworkScanRequest halRequest =
723                     new android.hardware.radio.V1_2.NetworkScanRequest();
724             halRequest.type = request.getScanType();
725             halRequest.interval = request.getSearchPeriodicity();
726             halRequest.maxSearchTime = request.getMaxSearchTime();
727             halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
728             halRequest.incrementalResults = request.getIncrementalResults();
729             halRequest.mccMncs.addAll(request.getPlmns());
730 
731             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
732                 android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
733                         RILUtils.convertToHalRadioAccessSpecifier11(ras);
734                 if (rasInHalFormat == null) {
735                     AsyncResult.forMessage(result, null,
736                             CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
737                     result.sendToTarget();
738                     return;
739                 }
740                 halRequest.specifiers.add(rasInHalFormat);
741             }
742             mRadioProxy.startNetworkScan_1_4(serial, halRequest);
743         }
744     }
745 
746     /**
747      * Call IRadioNetwork#stopNetworkScan
748      * @param serial Serial number of request
749      * @throws RemoteException
750      */
stopNetworkScan(int serial)751     public void stopNetworkScan(int serial) throws RemoteException {
752         if (isEmpty()) return;
753         if (isAidl()) {
754             mNetworkProxy.stopNetworkScan(serial);
755         } else {
756             mRadioProxy.stopNetworkScan(serial);
757         }
758     }
759 
760     /**
761      * Call IRadioNetwork#supplyNetworkDepersonalization
762      * @param serial Serial number of request
763      * @param netPin Network depersonalization code
764      * @throws RemoteException
765      */
supplyNetworkDepersonalization(int serial, String netPin)766     public void supplyNetworkDepersonalization(int serial, String netPin) throws RemoteException {
767         if (isEmpty()) return;
768         if (isAidl()) {
769             mNetworkProxy.supplyNetworkDepersonalization(serial, netPin);
770         } else {
771             mRadioProxy.supplyNetworkDepersonalization(serial, netPin);
772         }
773     }
774 
775     /**
776      * Call IRadioNetwork#getUsageSetting()
777      * @param serial Serial number of request
778      * @throws RemoteException
779      */
getUsageSetting(int serial)780     public void getUsageSetting(int serial) throws RemoteException {
781         if (isEmpty()) return;
782         if (isAidl()) {
783             mNetworkProxy.getUsageSetting(serial);
784         }
785         // Only supported on AIDL.
786     }
787 
788     /**
789      * Call IRadioNetwork#setUsageSetting()
790      * @param serial Serial number of request
791      * @throws RemoteException
792      */
setUsageSetting(int serial, int usageSetting)793     public void setUsageSetting(int serial,
794             /* TelephonyManager.UsageSetting */ int usageSetting) throws RemoteException {
795         if (isEmpty()) return;
796         if (isAidl()) {
797             mNetworkProxy.setUsageSetting(serial, usageSetting);
798         }
799         // Only supported on AIDL.
800     }
801 
802     /**
803      * Set the Emergency Mode
804      *
805      * @param serial Serial number of the request.
806      * @param emcModeType Defines the radio emergency mode type.
807      * @throws RemoteException
808      */
setEmergencyMode(int serial, int emcModeType)809     public void setEmergencyMode(int serial, int emcModeType) throws RemoteException {
810         if (isEmpty()) return;
811         if (isAidl()) {
812             mNetworkProxy.setEmergencyMode(serial, emcModeType);
813         }
814         // Only supported on AIDL.
815     }
816 
817     /**
818      * Triggers an Emergency network scan.
819      *
820      * @param serial Serial number of the request.
821      * @param scanRequest Contains the preferred networks and type of service to be scanned.
822      * @throws RemoteException
823      */
triggerEmergencyNetworkScan(int serial, android.hardware.radio.network.EmergencyNetworkScanTrigger scanRequest)824     public void triggerEmergencyNetworkScan(int serial,
825             android.hardware.radio.network.EmergencyNetworkScanTrigger scanRequest)
826             throws RemoteException {
827         if (isEmpty()) return;
828         if (isAidl()) {
829             mNetworkProxy.triggerEmergencyNetworkScan(serial, scanRequest);
830         }
831         // Only supported on AIDL.
832     }
833 
834     /**
835      * Cancels ongoing Emergency network scan
836      *
837      * @param serial Serial number of the request.
838      * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
839      *        If {@code true}, then the modem shall start the new scan from the beginning,
840      *        otherwise the modem shall resume from the last search.
841      *
842      * @throws RemoteException
843      */
cancelEmergencyNetworkScan(int serial, boolean resetScan)844     public void cancelEmergencyNetworkScan(int serial, boolean resetScan) throws RemoteException {
845         if (isEmpty()) return;
846         if (isAidl()) {
847             mNetworkProxy.cancelEmergencyNetworkScan(serial, resetScan);
848         }
849         // Only supported on AIDL.
850     }
851 
852     /**
853      * Exits ongoing Emergency Mode
854      *
855      * @param serial Serial number of the request.
856      * @throws RemoteException
857      */
exitEmergencyMode(int serial)858     public void exitEmergencyMode(int serial) throws RemoteException {
859         if (isEmpty()) return;
860         if (isAidl()) {
861             mNetworkProxy.exitEmergencyMode(serial);
862         }
863         // Only supported on AIDL.
864     }
865 
866     /**
867      * Set if null ciphering / null integrity is permitted.
868      *
869      * @param serial Serial number of the request.
870      * @param enabled true if null modes are allowed, false otherwise
871      * @throws RemoteException
872      */
setNullCipherAndIntegrityEnabled(int serial, boolean enabled)873     public void setNullCipherAndIntegrityEnabled(int serial,
874             boolean enabled) throws RemoteException {
875         if (isEmpty()) return;
876         if (isAidl()) {
877             mNetworkProxy.setNullCipherAndIntegrityEnabled(serial, enabled);
878         }
879         // Only supported on AIDL.
880     }
881 
882     /**
883      * Get if null ciphering / null integrity is permitted.
884      * @param serial Serial number of the request.
885      * @throws RemoteException
886      *
887      */
isNullCipherAndIntegrityEnabled(int serial)888     public void isNullCipherAndIntegrityEnabled(int serial) throws RemoteException {
889         if (isEmpty()) return;
890         if (isAidl()) {
891             mNetworkProxy.isNullCipherAndIntegrityEnabled(serial);
892         }
893         // Only supported on AIDL.
894     }
895 
896     /**
897      * Checks whether N1 mode is enabled.
898      *
899      * @param serial Serial number of the request.
900      * @throws RemoteException
901      */
isN1ModeEnabled(int serial)902     public void isN1ModeEnabled(int serial) throws RemoteException {
903         if (isEmpty()) return;
904         if (isAidl()) {
905             mNetworkProxy.isN1ModeEnabled(serial);
906         }
907         // Only supported on AIDL.
908     }
909 
910     /**
911      * Enables or disables N1 mode.
912      *
913      * @param serial Serial number of request.
914      * @param enable Indicates whether to enable N1 mode or not.
915      * @throws RemoteException
916      */
setN1ModeEnabled(int serial, boolean enable)917     public void setN1ModeEnabled(int serial, boolean enable) throws RemoteException {
918         if (isEmpty()) return;
919         if (isAidl()) {
920             mNetworkProxy.setN1ModeEnabled(serial, enable);
921         }
922         // Only supported on AIDL.
923     }
924 
925     /**
926      * Enables or disables cellular identifier disclosure transparency.
927      *
928      * @param serial Serial number of request.
929      * @param enable Indicates whether to enable disclosure transparency or not.
930      */
setCellularIdentifierTransparencyEnabled(int serial, boolean enable)931     public void setCellularIdentifierTransparencyEnabled(int serial, boolean enable)
932             throws RemoteException {
933         if (isEmpty()) return;
934         if (isAidl()) {
935             mNetworkProxy.setCellularIdentifierTransparencyEnabled(serial, enable);
936         }
937         // Only supported on AIDL.
938     }
939 
940     /**
941      * Checks whether cellular identifier transparency disclosure is enabled.
942      *
943      * @param serial Serial number of request.
944      */
isCellularIdentifierTransparencyEnabled(int serial)945     public void isCellularIdentifierTransparencyEnabled(int serial) throws RemoteException {
946         if (isEmpty()) return;
947         if (isAidl()) {
948             mNetworkProxy.isCellularIdentifierTransparencyEnabled(serial);
949         }
950         // Only supported on AIDL.
951     }
952 
953     /**
954      * Checks security algorithm update reports are enabled.
955      *
956      * @param serial Serial number of the request.
957      * @throws RemoteException
958      */
isSecurityAlgorithmsUpdatedEnabled(int serial)959     public void isSecurityAlgorithmsUpdatedEnabled(int serial) throws RemoteException {
960         if (isEmpty()) return;
961         if (isAidl()) {
962             mNetworkProxy.isSecurityAlgorithmsUpdatedEnabled(serial);
963         }
964         // Only supported on AIDL.
965     }
966 
967     /**
968      * Enables or disables security algorithm update reports.
969      *
970      * @param serial Serial number of request.
971      * @param enable Indicates whether to enable or disable security algorithm update reports.
972      * @throws RemoteException
973      */
setSecurityAlgorithmsUpdatedEnabled(int serial, boolean enable)974     public void setSecurityAlgorithmsUpdatedEnabled(int serial,
975             boolean enable) throws RemoteException {
976         if (isEmpty()) return;
977         if (isAidl()) {
978             mNetworkProxy.setSecurityAlgorithmsUpdatedEnabled(serial, enable);
979         }
980         // Only supported on AIDL.
981     }
982 }
983