• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator;
22 import android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo;
23 import android.hardware.radio.network.RegState;
24 import android.os.AsyncResult;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.os.Message;
28 import android.os.PersistableBundle;
29 import android.telephony.AccessNetworkConstants;
30 import android.telephony.AccessNetworkConstants.AccessNetworkType;
31 import android.telephony.AnomalyReporter;
32 import android.telephony.CarrierConfigManager;
33 import android.telephony.CellIdentity;
34 import android.telephony.CellIdentityCdma;
35 import android.telephony.CellIdentityGsm;
36 import android.telephony.CellIdentityLte;
37 import android.telephony.CellIdentityNr;
38 import android.telephony.CellIdentityTdscdma;
39 import android.telephony.CellIdentityWcdma;
40 import android.telephony.DataSpecificRegistrationInfo;
41 import android.telephony.LteVopsSupportInfo;
42 import android.telephony.NetworkRegistrationInfo;
43 import android.telephony.NetworkService;
44 import android.telephony.NetworkServiceCallback;
45 import android.telephony.NrVopsSupportInfo;
46 import android.telephony.ServiceState;
47 import android.telephony.SmsManager;
48 import android.telephony.SubscriptionManager;
49 import android.telephony.TelephonyManager;
50 import android.telephony.VopsSupportInfo;
51 import android.text.TextUtils;
52 import android.util.ArrayMap;
53 
54 import com.android.internal.annotations.VisibleForTesting;
55 import com.android.telephony.Rlog;
56 
57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.HashMap;
60 import java.util.List;
61 import java.util.Map;
62 import java.util.UUID;
63 
64 /**
65  * Implementation of network services for Cellular. It's a service that handles network requests
66  * for Cellular. It passes the requests to inner CellularNetworkServiceProvider which has a
67  * handler thread for each slot.
68  */
69 public class CellularNetworkService extends NetworkService {
70     private static final boolean DBG = false;
71 
72     private static final String TAG = CellularNetworkService.class.getSimpleName();
73 
74     private static final int GET_CS_REGISTRATION_STATE_DONE = 1;
75     private static final int GET_PS_REGISTRATION_STATE_DONE = 2;
76     private static final int NETWORK_REGISTRATION_STATE_CHANGED = 3;
77 
78     // From 24.008 6.1.3.0 and 10.5.6.2 the maximum number of PDP Contexts is 16.
79     private static final int MAX_DATA_CALLS = 16;
80 
81     private static final Map<Class<? extends CellIdentity>, List<Integer>> sNetworkTypes;
82 
83     static {
84         sNetworkTypes = new ArrayMap<>();
sNetworkTypes.put(CellIdentityGsm.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_GSM, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE}))85         sNetworkTypes.put(CellIdentityGsm.class,
86                 Arrays.asList(new Integer[]{
87                     TelephonyManager.NETWORK_TYPE_GSM,
88                     TelephonyManager.NETWORK_TYPE_GPRS,
89                     TelephonyManager.NETWORK_TYPE_EDGE}));
sNetworkTypes.put(CellIdentityWcdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_HSPAP}))90         sNetworkTypes.put(CellIdentityWcdma.class,
91                 Arrays.asList(new Integer[]{
92                     TelephonyManager.NETWORK_TYPE_UMTS,
93                     TelephonyManager.NETWORK_TYPE_HSDPA,
94                     TelephonyManager.NETWORK_TYPE_HSUPA,
95                     TelephonyManager.NETWORK_TYPE_HSPA,
96                     TelephonyManager.NETWORK_TYPE_HSPAP}));
sNetworkTypes.put(CellIdentityCdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD}))97         sNetworkTypes.put(CellIdentityCdma.class,
98                 Arrays.asList(new Integer[]{
99                     TelephonyManager.NETWORK_TYPE_CDMA,
100                     TelephonyManager.NETWORK_TYPE_1xRTT,
101                     TelephonyManager.NETWORK_TYPE_EVDO_0,
102                     TelephonyManager.NETWORK_TYPE_EVDO_A,
103                     TelephonyManager.NETWORK_TYPE_EVDO_B,
104                     TelephonyManager.NETWORK_TYPE_EHRPD}));
sNetworkTypes.put(CellIdentityLte.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_LTE}))105         sNetworkTypes.put(CellIdentityLte.class,
106                 Arrays.asList(new Integer[]{
107                     TelephonyManager.NETWORK_TYPE_LTE}));
sNetworkTypes.put(CellIdentityNr.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_NR}))108         sNetworkTypes.put(CellIdentityNr.class,
109                 Arrays.asList(new Integer[]{
110                     TelephonyManager.NETWORK_TYPE_NR}));
sNetworkTypes.put(CellIdentityTdscdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_TD_SCDMA}))111         sNetworkTypes.put(CellIdentityTdscdma.class,
112                 Arrays.asList(new Integer[]{
113                     TelephonyManager.NETWORK_TYPE_TD_SCDMA}));
114     }
115 
116     private class CellularNetworkServiceProvider extends NetworkServiceProvider {
117 
118         private final Map<Message, NetworkServiceCallback> mCallbackMap = new HashMap<>();
119 
120         private final Handler mHandler;
121 
122         private final Phone mPhone;
123 
CellularNetworkServiceProvider(int slotId)124         CellularNetworkServiceProvider(int slotId) {
125             super(slotId);
126 
127             mPhone = PhoneFactory.getPhone(getSlotIndex());
128 
129             mHandler = new Handler(Looper.myLooper()) {
130                 @Override
131                 public void handleMessage(Message message) {
132                     NetworkServiceCallback callback = mCallbackMap.remove(message);
133 
134                     AsyncResult ar;
135                     switch (message.what) {
136                         case GET_CS_REGISTRATION_STATE_DONE:
137                         case GET_PS_REGISTRATION_STATE_DONE:
138                             if (callback == null) return;
139                             ar = (AsyncResult) message.obj;
140                             int domain = (message.what == GET_CS_REGISTRATION_STATE_DONE)
141                                     ? NetworkRegistrationInfo.DOMAIN_CS
142                                     : NetworkRegistrationInfo.DOMAIN_PS;
143                             // TODO: move to RILUtils
144                             NetworkRegistrationInfo netState =
145                                     getRegistrationStateFromResult(ar.result, domain);
146 
147                             int resultCode;
148                             if (ar.exception != null || netState == null) {
149                                 resultCode = NetworkServiceCallback.RESULT_ERROR_FAILED;
150                             } else {
151                                 resultCode = NetworkServiceCallback.RESULT_SUCCESS;
152                             }
153 
154                             try {
155                                 if (DBG) {
156                                     log("Calling onRequestNetworkRegistrationInfoComplete."
157                                             + "resultCode = " + resultCode
158                                             + ", netState = " + netState);
159                                 }
160                                 callback.onRequestNetworkRegistrationInfoComplete(
161                                          resultCode, netState);
162                             } catch (Exception e) {
163                                 loge("Exception: " + e);
164                             }
165                             break;
166                         case NETWORK_REGISTRATION_STATE_CHANGED:
167                             notifyNetworkRegistrationInfoChanged();
168                             break;
169                         default:
170                             return;
171                     }
172                 }
173             };
174 
175             mPhone.mCi.registerForNetworkStateChanged(
176                     mHandler, NETWORK_REGISTRATION_STATE_CHANGED, null);
177         }
178 
getRegStateFromHalRegState(int halRegState)179         private int getRegStateFromHalRegState(int halRegState) {
180             switch (halRegState) {
181                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
182                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
183                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
184                 case RegState.REG_HOME:
185                     return NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
186                 case RegState.NOT_REG_MT_SEARCHING_OP:
187                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
188                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
189                 case RegState.REG_DENIED:
190                 case RegState.REG_DENIED_EM:
191                     return NetworkRegistrationInfo.REGISTRATION_STATE_DENIED;
192                 case RegState.UNKNOWN:
193                 case RegState.UNKNOWN_EM:
194                     return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
195                 case RegState.REG_ROAMING:
196                     return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
197                 case RegState.REG_EM:
198                     return NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY;
199                 default:
200                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
201             }
202         }
203 
isEmergencyOnly(int halRegState)204         private boolean isEmergencyOnly(int halRegState) {
205             switch (halRegState) {
206                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
207                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
208                 case RegState.REG_DENIED_EM:
209                 case RegState.UNKNOWN_EM:
210                 case RegState.REG_EM:
211                     return true;
212                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
213                 case RegState.REG_HOME:
214                 case RegState.NOT_REG_MT_SEARCHING_OP:
215                 case RegState.REG_DENIED:
216                 case RegState.UNKNOWN:
217                 case RegState.REG_ROAMING:
218                 default:
219                     return false;
220             }
221         }
222 
getAvailableServices(int regState, int domain, boolean emergencyOnly)223         private List<Integer> getAvailableServices(int regState, int domain,
224                                                    boolean emergencyOnly) {
225             List<Integer> availableServices = new ArrayList<>();
226 
227             // In emergency only states, only SERVICE_TYPE_EMERGENCY is available.
228             // Otherwise, certain services are available only if it's registered on home or roaming
229             // network.
230             if (emergencyOnly) {
231                 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY);
232             } else if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING
233                     || regState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
234                 if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
235                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
236                     if (isMmsEnabled(mPhone)) {
237                         // Add SERVICE_TYPE_MMS only if MMS is enabled
238                         availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_MMS);
239                     }
240                 } else if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
241                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
242                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_SMS);
243                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VIDEO);
244                 }
245             }
246 
247             return availableServices;
248         }
249 
getRegistrationStateFromResult(Object result, int domain)250         private NetworkRegistrationInfo getRegistrationStateFromResult(Object result, int domain) {
251             if (result == null) {
252                 return null;
253             }
254 
255             // TODO: unify when voiceRegStateResult and DataRegStateResult are unified.
256             if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
257                 return createRegistrationStateFromVoiceRegState(result);
258             } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
259                 return createRegistrationStateFromDataRegState(result);
260             } else {
261                 return null;
262             }
263         }
264 
getPlmnFromCellIdentity(@ullable final CellIdentity ci)265         private @NonNull String getPlmnFromCellIdentity(@Nullable final CellIdentity ci) {
266             if (ci == null || ci instanceof CellIdentityCdma) return "";
267 
268             final String mcc = ci.getMccString();
269             final String mnc = ci.getMncString();
270 
271             if (TextUtils.isEmpty(mcc) || TextUtils.isEmpty(mnc)) return "";
272 
273             return mcc + mnc;
274         }
275 
createRegistrationStateFromVoiceRegState(Object result)276         private NetworkRegistrationInfo createRegistrationStateFromVoiceRegState(Object result) {
277             final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
278             final int domain = NetworkRegistrationInfo.DOMAIN_CS;
279 
280             if (result instanceof android.hardware.radio.network.RegStateResult) {
281                 return getNetworkRegistrationInfoAidl(domain, transportType,
282                         (android.hardware.radio.network.RegStateResult) result);
283             } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
284                 return getNetworkRegistrationInfo1_6(domain, transportType,
285                         (android.hardware.radio.V1_6.RegStateResult) result);
286             } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
287                 return getNetworkRegistrationInfo(domain, transportType,
288                         (android.hardware.radio.V1_5.RegStateResult) result);
289             } else if (result instanceof android.hardware.radio.V1_2.VoiceRegStateResult) {
290                 android.hardware.radio.V1_2.VoiceRegStateResult voiceRegState =
291                         (android.hardware.radio.V1_2.VoiceRegStateResult) result;
292                 int regState = getRegStateFromHalRegState(voiceRegState.regState);
293                 int networkType = ServiceState.rilRadioTechnologyToNetworkType(voiceRegState.rat);
294                 int reasonForDenial = voiceRegState.reasonForDenial;
295                 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState);
296                 boolean cssSupported = voiceRegState.cssSupported;
297                 int roamingIndicator = voiceRegState.roamingIndicator;
298                 int systemIsInPrl = voiceRegState.systemIsInPrl;
299                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
300                 List<Integer> availableServices = getAvailableServices(
301                         regState, domain, emergencyOnly);
302                 CellIdentity cellIdentity =
303                         RILUtils.convertHalCellIdentity(voiceRegState.cellIdentity);
304                 final String rplmn = getPlmnFromCellIdentity(cellIdentity);
305 
306                 return new NetworkRegistrationInfo(domain, transportType, regState,
307                         networkType, reasonForDenial, emergencyOnly, availableServices,
308                         cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
309                         defaultRoamingIndicator);
310             }
311 
312             return null;
313         }
314 
createRegistrationStateFromDataRegState(Object result)315         private NetworkRegistrationInfo createRegistrationStateFromDataRegState(Object result) {
316             final int domain = NetworkRegistrationInfo.DOMAIN_PS;
317             final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
318 
319             if (result instanceof android.hardware.radio.network.RegStateResult) {
320                 return getNetworkRegistrationInfoAidl(domain, transportType,
321                         (android.hardware.radio.network.RegStateResult) result);
322             } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
323                 return getNetworkRegistrationInfo1_6(domain, transportType,
324                         (android.hardware.radio.V1_6.RegStateResult) result);
325             } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
326                 return getNetworkRegistrationInfo(domain, transportType,
327                         (android.hardware.radio.V1_5.RegStateResult) result);
328             } else if (result instanceof android.hardware.radio.V1_4.DataRegStateResult) {
329                 android.hardware.radio.V1_4.DataRegStateResult dataRegState =
330                         (android.hardware.radio.V1_4.DataRegStateResult) result;
331                 LteVopsSupportInfo lteVopsSupportInfo;
332                 // Check for lteVopsInfo only if its initialized and RAT is EUTRAN
333                 if (dataRegState.vopsInfo.getDiscriminator() == hidl_discriminator.lteVopsInfo
334                         && ServiceState.rilRadioTechnologyToAccessNetworkType(dataRegState.base.rat)
335                             == AccessNetworkType.EUTRAN) {
336                     android.hardware.radio.V1_4.LteVopsInfo vopsSupport =
337                             dataRegState.vopsInfo.lteVopsInfo();
338                     lteVopsSupportInfo = convertHalLteVopsSupportInfo(
339                             vopsSupport.isVopsSupported, vopsSupport.isEmcBearerSupported);
340                 } else {
341                     lteVopsSupportInfo = new LteVopsSupportInfo(
342                             LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
343                             LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
344                 }
345                 int regState = getRegStateFromHalRegState(dataRegState.base.regState);
346                 int networkType =
347                         ServiceState.rilRadioTechnologyToNetworkType(dataRegState.base.rat);
348                 int reasonForDenial = dataRegState.base.reasonDataDenied;
349                 boolean emergencyOnly = isEmergencyOnly(dataRegState.base.regState);
350                 int maxDataCalls = dataRegState.base.maxDataCalls;
351                 CellIdentity cellIdentity =
352                         RILUtils.convertHalCellIdentity(dataRegState.base.cellIdentity);
353                 android.hardware.radio.V1_4.NrIndicators nrIndicators = dataRegState.nrIndicators;
354                 boolean isEndcAvailable = nrIndicators.isEndcAvailable;
355                 boolean isNrAvailable = nrIndicators.isNrAvailable;
356                 boolean isDcNrRestricted = nrIndicators.isDcNrRestricted;
357                 String rplmn = getPlmnFromCellIdentity(cellIdentity);
358                 List<Integer> availableServices = getAvailableServices(
359                         regState, domain, emergencyOnly);
360                 return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
361                         reasonForDenial, emergencyOnly, availableServices, cellIdentity, rplmn,
362                         maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable,
363                         lteVopsSupportInfo);
364             } else {
365                 loge("Unknown type of DataRegStateResult " + result);
366                 return null;
367             }
368         }
369 
getNetworkRegistrationInfo( int domain, int transportType, android.hardware.radio.V1_5.RegStateResult regResult)370         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo(
371                 int domain, int transportType,
372                 android.hardware.radio.V1_5.RegStateResult regResult) {
373 
374             // Perform common conversions that aren't domain specific
375             final int regState = getRegStateFromHalRegState(regResult.regState);
376             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
377             final List<Integer> availableServices = getAvailableServices(
378                     regState, domain, isEmergencyOnly);
379             final CellIdentity cellIdentity =
380                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
381             final String rplmn = regResult.registeredPlmn;
382             final int reasonForDenial = regResult.reasonForDenial;
383 
384             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
385             networkType =
386                     getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
387 
388             // Conditional parameters for specific RANs
389             boolean cssSupported = false;
390             int roamingIndicator = 0;
391             int systemIsInPrl = 0;
392             int defaultRoamingIndicator = 0;
393             boolean isEndcAvailable = false;
394             boolean isNrAvailable = false;
395             boolean isDcNrRestricted = false;
396             LteVopsSupportInfo vopsInfo = new LteVopsSupportInfo(
397                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
398                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
399 
400             switch (regResult.accessTechnologySpecificInfo.getDiscriminator()) {
401                 case android.hardware.radio.V1_5.RegStateResult
402                         .AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo:
403                     android.hardware.radio.V1_5.RegStateResult
404                             .AccessTechnologySpecificInfo.Cdma2000RegistrationInfo cdmaInfo =
405                                     regResult.accessTechnologySpecificInfo.cdmaInfo();
406                     cssSupported = cdmaInfo.cssSupported;
407                     roamingIndicator = cdmaInfo.roamingIndicator;
408                     systemIsInPrl = cdmaInfo.systemIsInPrl;
409                     defaultRoamingIndicator = cdmaInfo.defaultRoamingIndicator;
410                     break;
411                 case android.hardware.radio.V1_5.RegStateResult
412                         .AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo:
413                     android.hardware.radio.V1_5.RegStateResult
414                             .AccessTechnologySpecificInfo.EutranRegistrationInfo eutranInfo =
415                                     regResult.accessTechnologySpecificInfo.eutranInfo();
416 
417                     isDcNrRestricted = eutranInfo.nrIndicators.isDcNrRestricted;
418                     isNrAvailable = eutranInfo.nrIndicators.isNrAvailable;
419                     isEndcAvailable = eutranInfo.nrIndicators.isEndcAvailable;
420                     vopsInfo = convertHalLteVopsSupportInfo(
421                             eutranInfo.lteVopsInfo.isVopsSupported,
422                             eutranInfo.lteVopsInfo.isEmcBearerSupported);
423                     break;
424                 default:
425                     log("No access tech specific info passes for RegStateResult");
426                     break;
427             }
428 
429             // build the result based on the domain for the request
430             switch(domain) {
431                 case NetworkRegistrationInfo.DOMAIN_CS:
432                     return new NetworkRegistrationInfo(domain, transportType, regState,
433                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
434                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
435                             defaultRoamingIndicator);
436                 default:
437                     loge("Unknown domain passed to CellularNetworkService= " + domain);
438                     // fall through
439                 case NetworkRegistrationInfo.DOMAIN_PS:
440                     return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
441                             reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
442                             rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
443                             vopsInfo);
444             }
445         }
446 
getNetworkRegistrationInfoAidl(int domain, int transportType, android.hardware.radio.network.RegStateResult regResult)447         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfoAidl(int domain,
448                 int transportType, android.hardware.radio.network.RegStateResult regResult) {
449             // Perform common conversions that aren't domain specific
450             final int regState = getRegStateFromHalRegState(regResult.regState);
451             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
452             final List<Integer> availableServices = getAvailableServices(
453                     regState, domain, isEmergencyOnly);
454             final CellIdentity cellIdentity =
455                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
456             final String rplmn = regResult.registeredPlmn;
457             final int reasonForDenial = regResult.reasonForDenial;
458 
459             if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_DENIED
460                     && reasonForDenial
461                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
462                 AnomalyReporter.reportAnomaly(
463                         UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f21"),
464                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
465             }
466 
467             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
468             if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
469                 networkType = TelephonyManager.NETWORK_TYPE_LTE;
470             }
471 
472             // Conditional parameters for specific RANs
473             boolean cssSupported = false;
474             int roamingIndicator = 0;
475             int systemIsInPrl = 0;
476             int defaultRoamingIndicator = 0;
477             boolean isEndcAvailable = false;
478             boolean isNrAvailable = false;
479             boolean isDcNrRestricted = false;
480             VopsSupportInfo vopsInfo = null;
481             int lteAttachResultType = 0;
482             int lteAttachExtraInfo = 0;
483 
484             android.hardware.radio.network.AccessTechnologySpecificInfo info =
485                     regResult.accessTechnologySpecificInfo;
486 
487             switch (info.getTag()) {
488                 case android.hardware.radio.network.AccessTechnologySpecificInfo.cdmaInfo:
489                     cssSupported = info.getCdmaInfo().cssSupported;
490                     roamingIndicator = info.getCdmaInfo().roamingIndicator;
491                     systemIsInPrl = info.getCdmaInfo().systemIsInPrl;
492                     defaultRoamingIndicator = info.getCdmaInfo().defaultRoamingIndicator;
493                     break;
494                 case android.hardware.radio.network.AccessTechnologySpecificInfo.eutranInfo:
495                     isDcNrRestricted = info.getEutranInfo().nrIndicators.isDcNrRestricted;
496                     isNrAvailable = info.getEutranInfo().nrIndicators.isNrAvailable;
497                     isEndcAvailable = info.getEutranInfo().nrIndicators.isEndcAvailable;
498                     vopsInfo = convertHalLteVopsSupportInfo(
499                             info.getEutranInfo().lteVopsInfo.isVopsSupported,
500                             info.getEutranInfo().lteVopsInfo.isEmcBearerSupported);
501                     lteAttachResultType = info.getEutranInfo().lteAttachResultType;
502                     lteAttachExtraInfo = info.getEutranInfo().extraInfo;
503                     break;
504                 case android.hardware.radio.network.AccessTechnologySpecificInfo.ngranNrVopsInfo:
505                     vopsInfo = new NrVopsSupportInfo(info.getNgranNrVopsInfo().vopsSupported,
506                             info.getNgranNrVopsInfo().emcSupported,
507                             info.getNgranNrVopsInfo().emfSupported);
508                     break;
509                 case android.hardware.radio.network.AccessTechnologySpecificInfo.geranDtmSupported:
510                     cssSupported = info.getGeranDtmSupported();
511                     break;
512                 default:
513                     log("No access tech specific info passes for RegStateResult");
514                     break;
515             }
516 
517             // build the result based on the domain for the request
518             switch (domain) {
519                 case NetworkRegistrationInfo.DOMAIN_CS:
520                     return new NetworkRegistrationInfo(domain, transportType, regState,
521                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
522                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
523                             defaultRoamingIndicator);
524                 default:
525                     loge("Unknown domain passed to CellularNetworkService= " + domain);
526                     // fall through
527                 case NetworkRegistrationInfo.DOMAIN_PS:
528                     return new NetworkRegistrationInfo.Builder()
529                         .setDomain(domain)
530                         .setTransportType(transportType)
531                         .setRegistrationState(regState)
532                         .setAccessNetworkTechnology(networkType)
533                         .setRejectCause(reasonForDenial)
534                         .setEmergencyOnly(isEmergencyOnly)
535                         .setAvailableServices(availableServices)
536                         .setCellIdentity(cellIdentity)
537                         .setRegisteredPlmn(rplmn)
538                         .setDataSpecificInfo(
539                                 new DataSpecificRegistrationInfo.Builder(MAX_DATA_CALLS)
540                                      .setDcNrRestricted(isDcNrRestricted)
541                                      .setNrAvailable(isNrAvailable)
542                                      .setEnDcAvailable(isEndcAvailable)
543                                      .setVopsSupportInfo(vopsInfo)
544                                      .setLteAttachResultType(lteAttachResultType)
545                                      .setLteAttachExtraInfo(lteAttachExtraInfo)
546                                      .build())
547                         .build();
548             }
549         }
550 
getNetworkRegistrationInfo1_6( int domain, int transportType, android.hardware.radio.V1_6.RegStateResult regResult)551         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo1_6(
552                 int domain, int transportType,
553                 android.hardware.radio.V1_6.RegStateResult regResult) {
554 
555             // Perform common conversions that aren't domain specific
556             final int regState = getRegStateFromHalRegState(regResult.regState);
557             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
558             final List<Integer> availableServices = getAvailableServices(
559                     regState, domain, isEmergencyOnly);
560             final CellIdentity cellIdentity =
561                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
562             final String rplmn = regResult.registeredPlmn;
563             final int reasonForDenial = regResult.reasonForDenial;
564 
565             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
566             networkType =
567                     getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
568 
569             if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_DENIED
570                     && reasonForDenial
571                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
572                 AnomalyReporter.reportAnomaly(
573                         UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f21"),
574                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
575             }
576 
577             // Conditional parameters for specific RANs
578             boolean cssSupported = false;
579             int roamingIndicator = 0;
580             int systemIsInPrl = 0;
581             int defaultRoamingIndicator = 0;
582             boolean isEndcAvailable = false;
583             boolean isNrAvailable = false;
584             boolean isDcNrRestricted = false;
585             VopsSupportInfo vopsInfo = null;
586 
587             android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo info =
588                     regResult.accessTechnologySpecificInfo;
589 
590             switch (info.getDiscriminator()) {
591                 case AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo:
592                     cssSupported = info.cdmaInfo().cssSupported;
593                     roamingIndicator = info.cdmaInfo().roamingIndicator;
594                     systemIsInPrl = info.cdmaInfo().systemIsInPrl;
595                     defaultRoamingIndicator = info.cdmaInfo().defaultRoamingIndicator;
596                     break;
597                 case AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo:
598                     isDcNrRestricted = info.eutranInfo().nrIndicators.isDcNrRestricted;
599                     isNrAvailable = info.eutranInfo().nrIndicators.isNrAvailable;
600                     isEndcAvailable = info.eutranInfo().nrIndicators.isEndcAvailable;
601                     vopsInfo = convertHalLteVopsSupportInfo(
602                             info.eutranInfo().lteVopsInfo.isVopsSupported,
603                             info.eutranInfo().lteVopsInfo.isEmcBearerSupported);
604                     break;
605                 case AccessTechnologySpecificInfo.hidl_discriminator.ngranNrVopsInfo:
606                     vopsInfo = new NrVopsSupportInfo(info.ngranNrVopsInfo().vopsSupported,
607                             info.ngranNrVopsInfo().emcSupported,
608                             info.ngranNrVopsInfo().emfSupported);
609                     break;
610                 case AccessTechnologySpecificInfo.hidl_discriminator.geranDtmSupported:
611                     cssSupported = info.geranDtmSupported();
612                     break;
613                 default:
614                     log("No access tech specific info passes for RegStateResult");
615                     break;
616             }
617 
618             // build the result based on the domain for the request
619             switch(domain) {
620                 case NetworkRegistrationInfo.DOMAIN_CS:
621                     return new NetworkRegistrationInfo(domain, transportType, regState,
622                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
623                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
624                             defaultRoamingIndicator);
625                 default:
626                     loge("Unknown domain passed to CellularNetworkService= " + domain);
627                     // fall through
628                 case NetworkRegistrationInfo.DOMAIN_PS:
629                     return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
630                             reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
631                             rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
632                             vopsInfo);
633             }
634         }
635 
convertHalLteVopsSupportInfo( boolean vopsSupport, boolean emcBearerSupport)636         private LteVopsSupportInfo convertHalLteVopsSupportInfo(
637                 boolean vopsSupport, boolean emcBearerSupport) {
638             int vops = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED;
639             int emergency = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED;
640 
641             if (vopsSupport) {
642                 vops = LteVopsSupportInfo.LTE_STATUS_SUPPORTED;
643             }
644             if (emcBearerSupport) {
645                 emergency = LteVopsSupportInfo.LTE_STATUS_SUPPORTED;
646             }
647             return new LteVopsSupportInfo(vops, emergency);
648         }
649 
650         @Override
requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback)651         public void requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback) {
652             if (DBG) log("requestNetworkRegistrationInfo for domain " + domain);
653             Message message = null;
654 
655             if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
656                 message = Message.obtain(mHandler, GET_CS_REGISTRATION_STATE_DONE);
657                 mCallbackMap.put(message, callback);
658                 mPhone.mCi.getVoiceRegistrationState(message);
659             } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
660                 message = Message.obtain(mHandler, GET_PS_REGISTRATION_STATE_DONE);
661                 mCallbackMap.put(message, callback);
662                 mPhone.mCi.getDataRegistrationState(message);
663             } else {
664                 loge("requestNetworkRegistrationInfo invalid domain " + domain);
665                 callback.onRequestNetworkRegistrationInfoComplete(
666                         NetworkServiceCallback.RESULT_ERROR_INVALID_ARG, null);
667             }
668         }
669 
670         @Override
close()671         public void close() {
672             mCallbackMap.clear();
673             mPhone.mCi.unregisterForNetworkStateChanged(mHandler);
674         }
675     }
676 
677     /** Cross-check the network type against the CellIdentity type */
678     @VisibleForTesting
getNetworkTypeForCellIdentity( int networkType, CellIdentity ci, int carrierId)679     public static int getNetworkTypeForCellIdentity(
680             int networkType, CellIdentity ci, int carrierId) {
681         if (ci == null) {
682             if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
683                 // Network type is non-null but CellIdentity is null
684                 AnomalyReporter.reportAnomaly(
685                         UUID.fromString("e67ea4ef-7251-4a69-a063-22c47fc58743"),
686                             "RIL Unexpected NetworkType", carrierId);
687                 if (android.os.Build.isDebuggable()) {
688                     logw("Updating incorrect network type from "
689                             + TelephonyManager.getNetworkTypeName(networkType) + " to UNKNOWN");
690                     return TelephonyManager.NETWORK_TYPE_UNKNOWN;
691                 } else {
692                     // If the build isn't debuggable and CellIdentity is null, there's no way to
693                     // guess the approximately correct type so if it's valid it gets a pass.
694                     for (List<Integer> values : sNetworkTypes.values()) {
695                         if (values.contains(networkType)) return networkType;
696                     }
697                 }
698             }
699 
700             // No valid network type, so return UNKNOWN for safety.
701             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
702         }
703 
704 
705         // If the type is reported as IWLAN but the CellIdentity is a cellular type,
706         // report that; Devices post HAL 1.4 should be operating in AP-assisted mode
707         if (networkType == TelephonyManager.NETWORK_TYPE_IWLAN) {
708             AnomalyReporter.reportAnomaly(
709                     UUID.fromString("07dfa183-b2e7-42b7-98a1-dd5ae2abdd4f"),
710                             "RIL Reported IWLAN", carrierId);
711             if (!android.os.Build.isDebuggable()) return networkType;
712 
713             if (sNetworkTypes.containsKey(ci.getClass())) {
714                 final int updatedType = sNetworkTypes.get(ci.getClass()).get(0);
715                 logw("Updating incorrect network type from IWLAN to " + updatedType);
716                 return updatedType;
717             } else {
718                 logw("Updating incorrect network type from IWLAN to UNKNOWN");
719                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
720             }
721         }
722 
723         if (!sNetworkTypes.containsKey(ci.getClass())) {
724             AnomalyReporter.reportAnomaly(
725                     UUID.fromString("469858cf-46e5-416e-bc11-5e7970917857"),
726                         "RIL Unknown CellIdentity", carrierId);
727             return networkType;
728         }
729 
730         // If the network type isn't valid for the CellIdentity type,
731         final List<Integer> typesForCi = sNetworkTypes.get(ci.getClass());
732         if (!typesForCi.contains(networkType)) {
733             AnomalyReporter.reportAnomaly(
734                     UUID.fromString("2fb634fa-cab3-44d2-bbe8-c7689b0f3e31"),
735                         "RIL Mismatched NetworkType", carrierId);
736             // Since this is a plain-and-simple mismatch between two conflicting pieces of
737             // data, and theres no way to know which one to trust, pick the one that's harder
738             // to coerce / fake / set incorrectly and make them roughly match.
739             // Note, this also does the fixup for LTE_CA -> LTE that was formerly done as a
740             // special case.
741             logw("Updating incorrect network type from "
742                     + TelephonyManager.getNetworkTypeName(networkType)
743                     + " to " + TelephonyManager.getNetworkTypeName(typesForCi.get(0)));
744             return typesForCi.get(0);
745         }
746 
747         return networkType;
748     }
749 
750     @Override
onCreateNetworkServiceProvider(int slotIndex)751     public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
752         if (DBG) log("Cellular network service created for slot " + slotIndex);
753         if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
754             loge("Tried to Cellular network service with invalid slotId " + slotIndex);
755             return null;
756         }
757         return new CellularNetworkServiceProvider(slotIndex);
758     }
759 
isMmsEnabled(Phone phone)760     private boolean isMmsEnabled(Phone phone) {
761         CarrierConfigManager carrierConfigManager = phone.getContext()
762                 .getSystemService(CarrierConfigManager.class);
763         if (carrierConfigManager != null) {
764             PersistableBundle config = carrierConfigManager.getConfigForSubId(
765                     phone.getSubId(), SmsManager.MMS_CONFIG_MMS_ENABLED);
766             if (config == null || config.isEmpty()) {
767                 config = CarrierConfigManager.getDefaultConfig();
768             }
769 
770             return config.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED);
771         } else {
772             loge("isMmsEnabled: CarrierConfigManager is null");
773             return false;
774         }
775     }
776 
log(String s)777     private static void log(String s) {
778         Rlog.d(TAG, s);
779     }
780 
logw(String s)781     private static void logw(String s) {
782         Rlog.w(TAG, s);
783     }
784 
loge(String s)785     private static void loge(String s) {
786         Rlog.e(TAG, s);
787     }
788 }
789