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_0.RegState; 22 import android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator; 23 import android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo; 24 import android.os.AsyncResult; 25 import android.os.Handler; 26 import android.os.Looper; 27 import android.os.Message; 28 import android.telephony.AccessNetworkConstants; 29 import android.telephony.AccessNetworkConstants.AccessNetworkType; 30 import android.telephony.CellIdentity; 31 import android.telephony.CellIdentityCdma; 32 import android.telephony.LteVopsSupportInfo; 33 import android.telephony.NetworkRegistrationInfo; 34 import android.telephony.NetworkService; 35 import android.telephony.NetworkServiceCallback; 36 import android.telephony.NrVopsSupportInfo; 37 import android.telephony.ServiceState; 38 import android.telephony.SubscriptionManager; 39 import android.telephony.TelephonyManager; 40 import android.telephony.VopsSupportInfo; 41 import android.text.TextUtils; 42 43 import com.android.telephony.Rlog; 44 45 import java.util.ArrayList; 46 import java.util.HashMap; 47 import java.util.List; 48 import java.util.Map; 49 50 /** 51 * Implementation of network services for Cellular. It's a service that handles network requests 52 * for Cellular. It passes the requests to inner CellularNetworkServiceProvider which has a 53 * handler thread for each slot. 54 */ 55 public class CellularNetworkService extends NetworkService { 56 private static final boolean DBG = false; 57 58 private static final String TAG = CellularNetworkService.class.getSimpleName(); 59 60 private static final int GET_CS_REGISTRATION_STATE_DONE = 1; 61 private static final int GET_PS_REGISTRATION_STATE_DONE = 2; 62 private static final int NETWORK_REGISTRATION_STATE_CHANGED = 3; 63 64 // From 24.008 6.1.3.0 and 10.5.6.2 the maximum number of PDP Contexts is 16. 65 private static final int MAX_DATA_CALLS = 16; 66 67 private class CellularNetworkServiceProvider extends NetworkServiceProvider { 68 69 private final Map<Message, NetworkServiceCallback> mCallbackMap = new HashMap<>(); 70 71 private final Handler mHandler; 72 73 private final Phone mPhone; 74 CellularNetworkServiceProvider(int slotId)75 CellularNetworkServiceProvider(int slotId) { 76 super(slotId); 77 78 mPhone = PhoneFactory.getPhone(getSlotIndex()); 79 80 mHandler = new Handler(Looper.myLooper()) { 81 @Override 82 public void handleMessage(Message message) { 83 NetworkServiceCallback callback = mCallbackMap.remove(message); 84 85 AsyncResult ar; 86 switch (message.what) { 87 case GET_CS_REGISTRATION_STATE_DONE: 88 case GET_PS_REGISTRATION_STATE_DONE: 89 if (callback == null) return; 90 ar = (AsyncResult) message.obj; 91 int domain = (message.what == GET_CS_REGISTRATION_STATE_DONE) 92 ? NetworkRegistrationInfo.DOMAIN_CS 93 : NetworkRegistrationInfo.DOMAIN_PS; 94 NetworkRegistrationInfo netState = 95 getRegistrationStateFromResult(ar.result, domain); 96 97 int resultCode; 98 if (ar.exception != null || netState == null) { 99 resultCode = NetworkServiceCallback.RESULT_ERROR_FAILED; 100 } else { 101 resultCode = NetworkServiceCallback.RESULT_SUCCESS; 102 } 103 104 try { 105 if (DBG) { 106 log("Calling onRequestNetworkRegistrationInfoComplete." 107 + "resultCode = " + resultCode 108 + ", netState = " + netState); 109 } 110 callback.onRequestNetworkRegistrationInfoComplete( 111 resultCode, netState); 112 } catch (Exception e) { 113 loge("Exception: " + e); 114 } 115 break; 116 case NETWORK_REGISTRATION_STATE_CHANGED: 117 notifyNetworkRegistrationInfoChanged(); 118 break; 119 default: 120 return; 121 } 122 } 123 }; 124 125 mPhone.mCi.registerForNetworkStateChanged( 126 mHandler, NETWORK_REGISTRATION_STATE_CHANGED, null); 127 } 128 getRegStateFromHalRegState(int halRegState)129 private int getRegStateFromHalRegState(int halRegState) { 130 switch (halRegState) { 131 case RegState.NOT_REG_MT_NOT_SEARCHING_OP: 132 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM: 133 return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; 134 case RegState.REG_HOME: 135 return NetworkRegistrationInfo.REGISTRATION_STATE_HOME; 136 case RegState.NOT_REG_MT_SEARCHING_OP: 137 case RegState.NOT_REG_MT_SEARCHING_OP_EM: 138 return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; 139 case RegState.REG_DENIED: 140 case RegState.REG_DENIED_EM: 141 return NetworkRegistrationInfo.REGISTRATION_STATE_DENIED; 142 case RegState.UNKNOWN: 143 case RegState.UNKNOWN_EM: 144 return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN; 145 case RegState.REG_ROAMING: 146 return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING; 147 default: 148 return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; 149 } 150 } 151 isEmergencyOnly(int halRegState)152 private boolean isEmergencyOnly(int halRegState) { 153 switch (halRegState) { 154 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM: 155 case RegState.NOT_REG_MT_SEARCHING_OP_EM: 156 case RegState.REG_DENIED_EM: 157 case RegState.UNKNOWN_EM: 158 return true; 159 case RegState.NOT_REG_MT_NOT_SEARCHING_OP: 160 case RegState.REG_HOME: 161 case RegState.NOT_REG_MT_SEARCHING_OP: 162 case RegState.REG_DENIED: 163 case RegState.UNKNOWN: 164 case RegState.REG_ROAMING: 165 default: 166 return false; 167 } 168 } 169 getAvailableServices(int regState, int domain, boolean emergencyOnly)170 private List<Integer> getAvailableServices(int regState, int domain, 171 boolean emergencyOnly) { 172 List<Integer> availableServices = new ArrayList<>(); 173 174 // In emergency only states, only SERVICE_TYPE_EMERGENCY is available. 175 // Otherwise, certain services are available only if it's registered on home or roaming 176 // network. 177 if (emergencyOnly) { 178 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY); 179 } else if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING 180 || regState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) { 181 if (domain == NetworkRegistrationInfo.DOMAIN_PS) { 182 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA); 183 } else if (domain == NetworkRegistrationInfo.DOMAIN_CS) { 184 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE); 185 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_SMS); 186 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VIDEO); 187 } 188 } 189 190 return availableServices; 191 } 192 getRegistrationStateFromResult(Object result, int domain)193 private NetworkRegistrationInfo getRegistrationStateFromResult(Object result, int domain) { 194 if (result == null) { 195 return null; 196 } 197 198 // TODO: unify when voiceRegStateResult and DataRegStateResult are unified. 199 if (domain == NetworkRegistrationInfo.DOMAIN_CS) { 200 return createRegistrationStateFromVoiceRegState(result); 201 } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) { 202 return createRegistrationStateFromDataRegState(result); 203 } else { 204 return null; 205 } 206 } 207 getPlmnFromCellIdentity(@ullable final CellIdentity ci)208 private @NonNull String getPlmnFromCellIdentity(@Nullable final CellIdentity ci) { 209 if (ci == null || ci instanceof CellIdentityCdma) return ""; 210 211 final String mcc = ci.getMccString(); 212 final String mnc = ci.getMncString(); 213 214 if (TextUtils.isEmpty(mcc) || TextUtils.isEmpty(mnc)) return ""; 215 216 return mcc + mnc; 217 } 218 createRegistrationStateFromVoiceRegState(Object result)219 private NetworkRegistrationInfo createRegistrationStateFromVoiceRegState(Object result) { 220 final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 221 final int domain = NetworkRegistrationInfo.DOMAIN_CS; 222 223 if (result instanceof android.hardware.radio.V1_6.RegStateResult) { 224 return getNetworkRegistrationInfo1_6( 225 domain, 226 transportType, 227 (android.hardware.radio.V1_6.RegStateResult) result); 228 } 229 // 1.5 at the top so that we can do an "early exit" from the method 230 else if (result instanceof android.hardware.radio.V1_5.RegStateResult) { 231 return getNetworkRegistrationInfo( 232 domain, 233 transportType, 234 (android.hardware.radio.V1_5.RegStateResult) result); 235 } else if (result instanceof android.hardware.radio.V1_0.VoiceRegStateResult) { 236 android.hardware.radio.V1_0.VoiceRegStateResult voiceRegState = 237 (android.hardware.radio.V1_0.VoiceRegStateResult) result; 238 int regState = getRegStateFromHalRegState(voiceRegState.regState); 239 int networkType = ServiceState.rilRadioTechnologyToNetworkType(voiceRegState.rat); 240 int reasonForDenial = voiceRegState.reasonForDenial; 241 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState); 242 boolean cssSupported = voiceRegState.cssSupported; 243 int roamingIndicator = voiceRegState.roamingIndicator; 244 int systemIsInPrl = voiceRegState.systemIsInPrl; 245 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator; 246 List<Integer> availableServices = getAvailableServices( 247 regState, domain, emergencyOnly); 248 CellIdentity cellIdentity = CellIdentity.create(voiceRegState.cellIdentity); 249 final String rplmn = getPlmnFromCellIdentity(cellIdentity); 250 251 return new NetworkRegistrationInfo(domain, transportType, regState, 252 networkType, reasonForDenial, emergencyOnly, availableServices, 253 cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl, 254 defaultRoamingIndicator); 255 } else if (result instanceof android.hardware.radio.V1_2.VoiceRegStateResult) { 256 android.hardware.radio.V1_2.VoiceRegStateResult voiceRegState = 257 (android.hardware.radio.V1_2.VoiceRegStateResult) result; 258 int regState = getRegStateFromHalRegState(voiceRegState.regState); 259 int networkType = ServiceState.rilRadioTechnologyToNetworkType(voiceRegState.rat); 260 int reasonForDenial = voiceRegState.reasonForDenial; 261 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState); 262 boolean cssSupported = voiceRegState.cssSupported; 263 int roamingIndicator = voiceRegState.roamingIndicator; 264 int systemIsInPrl = voiceRegState.systemIsInPrl; 265 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator; 266 List<Integer> availableServices = getAvailableServices( 267 regState, domain, emergencyOnly); 268 CellIdentity cellIdentity = CellIdentity.create(voiceRegState.cellIdentity); 269 final String rplmn = getPlmnFromCellIdentity(cellIdentity); 270 271 return new NetworkRegistrationInfo(domain, transportType, regState, 272 networkType, reasonForDenial, emergencyOnly, availableServices, 273 cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl, 274 defaultRoamingIndicator); 275 } 276 277 return null; 278 } 279 createRegistrationStateFromDataRegState(Object result)280 private NetworkRegistrationInfo createRegistrationStateFromDataRegState(Object result) { 281 final int domain = NetworkRegistrationInfo.DOMAIN_PS; 282 final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 283 284 int regState = NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN; 285 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 286 int reasonForDenial = 0; 287 boolean emergencyOnly = false; 288 int maxDataCalls = 0; 289 CellIdentity cellIdentity; 290 boolean isEndcAvailable = false; 291 boolean isNrAvailable = false; 292 boolean isDcNrRestricted = false; 293 294 LteVopsSupportInfo lteVopsSupportInfo = 295 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE, 296 LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE); 297 298 if (result instanceof android.hardware.radio.V1_6.RegStateResult) { 299 return getNetworkRegistrationInfo1_6( 300 domain, 301 transportType, 302 (android.hardware.radio.V1_6.RegStateResult) result); 303 } 304 // 1.5 at the top so that we can do an "early exit" from the method 305 else if (result instanceof android.hardware.radio.V1_5.RegStateResult) { 306 return getNetworkRegistrationInfo( 307 domain, 308 transportType, 309 (android.hardware.radio.V1_5.RegStateResult) result); 310 } else if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) { 311 android.hardware.radio.V1_0.DataRegStateResult dataRegState = 312 (android.hardware.radio.V1_0.DataRegStateResult) result; 313 regState = getRegStateFromHalRegState(dataRegState.regState); 314 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.rat); 315 reasonForDenial = dataRegState.reasonDataDenied; 316 emergencyOnly = isEmergencyOnly(dataRegState.regState); 317 maxDataCalls = dataRegState.maxDataCalls; 318 cellIdentity = CellIdentity.create(dataRegState.cellIdentity); 319 } else if (result instanceof android.hardware.radio.V1_2.DataRegStateResult) { 320 android.hardware.radio.V1_2.DataRegStateResult dataRegState = 321 (android.hardware.radio.V1_2.DataRegStateResult) result; 322 regState = getRegStateFromHalRegState(dataRegState.regState); 323 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.rat); 324 reasonForDenial = dataRegState.reasonDataDenied; 325 emergencyOnly = isEmergencyOnly(dataRegState.regState); 326 maxDataCalls = dataRegState.maxDataCalls; 327 cellIdentity = CellIdentity.create(dataRegState.cellIdentity); 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 regState = getRegStateFromHalRegState(dataRegState.base.regState); 332 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.base.rat); 333 334 reasonForDenial = dataRegState.base.reasonDataDenied; 335 emergencyOnly = isEmergencyOnly(dataRegState.base.regState); 336 maxDataCalls = dataRegState.base.maxDataCalls; 337 cellIdentity = CellIdentity.create(dataRegState.base.cellIdentity); 338 android.hardware.radio.V1_4.NrIndicators nrIndicators = dataRegState.nrIndicators; 339 340 // Check for lteVopsInfo only if its initialized and RAT is EUTRAN 341 if (dataRegState.vopsInfo.getDiscriminator() == hidl_discriminator.lteVopsInfo 342 && ServiceState.rilRadioTechnologyToAccessNetworkType(dataRegState.base.rat) 343 == AccessNetworkType.EUTRAN) { 344 android.hardware.radio.V1_4.LteVopsInfo vopsSupport = 345 dataRegState.vopsInfo.lteVopsInfo(); 346 lteVopsSupportInfo = convertHalLteVopsSupportInfo(vopsSupport.isVopsSupported, 347 vopsSupport.isEmcBearerSupported); 348 } else { 349 lteVopsSupportInfo = 350 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE, 351 LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE); 352 } 353 354 isEndcAvailable = nrIndicators.isEndcAvailable; 355 isNrAvailable = nrIndicators.isNrAvailable; 356 isDcNrRestricted = nrIndicators.isDcNrRestricted; 357 } else { 358 loge("Unknown type of DataRegStateResult " + result); 359 return null; 360 } 361 362 String rplmn = getPlmnFromCellIdentity(cellIdentity); 363 List<Integer> availableServices = getAvailableServices( 364 regState, domain, emergencyOnly); 365 366 return new NetworkRegistrationInfo(domain, transportType, regState, networkType, 367 reasonForDenial, emergencyOnly, availableServices, cellIdentity, rplmn, 368 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, 369 lteVopsSupportInfo); 370 } 371 getNetworkRegistrationInfo( int domain, int transportType, android.hardware.radio.V1_5.RegStateResult regResult)372 private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo( 373 int domain, int transportType, 374 android.hardware.radio.V1_5.RegStateResult regResult) { 375 376 // Perform common conversions that aren't domain specific 377 final int regState = getRegStateFromHalRegState(regResult.regState); 378 final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState); 379 final List<Integer> availableServices = getAvailableServices( 380 regState, domain, isEmergencyOnly); 381 final int rejectCause = regResult.reasonForDenial; 382 final CellIdentity cellIdentity = CellIdentity.create(regResult.cellIdentity); 383 final String rplmn = regResult.registeredPlmn; 384 final int reasonForDenial = regResult.reasonForDenial; 385 386 int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat); 387 if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) { 388 // In Radio HAL v1.5, NETWORK_TYPE_LTE_CA is ignored. Callers should use 389 // PhysicalChannelConfig. 390 networkType = TelephonyManager.NETWORK_TYPE_LTE; 391 } 392 393 // Conditional parameters for specific RANs 394 boolean cssSupported = false; 395 int roamingIndicator = 0; 396 int systemIsInPrl = 0; 397 int defaultRoamingIndicator = 0; 398 boolean isEndcAvailable = false; 399 boolean isNrAvailable = false; 400 boolean isDcNrRestricted = false; 401 LteVopsSupportInfo vopsInfo = new LteVopsSupportInfo( 402 LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE, 403 LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE); 404 405 switch (regResult.accessTechnologySpecificInfo.getDiscriminator()) { 406 case android.hardware.radio.V1_5.RegStateResult 407 .AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo: 408 android.hardware.radio.V1_5.RegStateResult 409 .AccessTechnologySpecificInfo.Cdma2000RegistrationInfo cdmaInfo = 410 regResult.accessTechnologySpecificInfo.cdmaInfo(); 411 cssSupported = cdmaInfo.cssSupported; 412 roamingIndicator = cdmaInfo.roamingIndicator; 413 systemIsInPrl = cdmaInfo.systemIsInPrl; 414 defaultRoamingIndicator = cdmaInfo.defaultRoamingIndicator; 415 break; 416 case android.hardware.radio.V1_5.RegStateResult 417 .AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo: 418 android.hardware.radio.V1_5.RegStateResult 419 .AccessTechnologySpecificInfo.EutranRegistrationInfo eutranInfo = 420 regResult.accessTechnologySpecificInfo.eutranInfo(); 421 422 isDcNrRestricted = eutranInfo.nrIndicators.isDcNrRestricted; 423 isNrAvailable = eutranInfo.nrIndicators.isNrAvailable; 424 isEndcAvailable = eutranInfo.nrIndicators.isEndcAvailable; 425 vopsInfo = convertHalLteVopsSupportInfo( 426 eutranInfo.lteVopsInfo.isVopsSupported, 427 eutranInfo.lteVopsInfo.isEmcBearerSupported); 428 break; 429 default: 430 log("No access tech specific info passes for RegStateResult"); 431 break; 432 } 433 434 // build the result based on the domain for the request 435 switch(domain) { 436 case NetworkRegistrationInfo.DOMAIN_CS: 437 return new NetworkRegistrationInfo(domain, transportType, regState, 438 networkType, reasonForDenial, isEmergencyOnly, availableServices, 439 cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl, 440 defaultRoamingIndicator); 441 default: 442 loge("Unknown domain passed to CellularNetworkService= " + domain); 443 // fall through 444 case NetworkRegistrationInfo.DOMAIN_PS: 445 return new NetworkRegistrationInfo(domain, transportType, regState, networkType, 446 reasonForDenial, isEmergencyOnly, availableServices, cellIdentity, 447 rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable, 448 vopsInfo); 449 } 450 } 451 getNetworkRegistrationInfo1_6( int domain, int transportType, android.hardware.radio.V1_6.RegStateResult regResult)452 private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo1_6( 453 int domain, int transportType, 454 android.hardware.radio.V1_6.RegStateResult regResult) { 455 456 // Perform common conversions that aren't domain specific 457 final int regState = getRegStateFromHalRegState(regResult.regState); 458 final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState); 459 final List<Integer> availableServices = getAvailableServices( 460 regState, domain, isEmergencyOnly); 461 final int rejectCause = regResult.reasonForDenial; 462 final CellIdentity cellIdentity = CellIdentity.create(regResult.cellIdentity); 463 final String rplmn = regResult.registeredPlmn; 464 final int reasonForDenial = regResult.reasonForDenial; 465 466 int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat); 467 if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) { 468 // In Radio HAL v1.5, NETWORK_TYPE_LTE_CA is ignored. Callers should use 469 // PhysicalChannelConfig. 470 networkType = TelephonyManager.NETWORK_TYPE_LTE; 471 } 472 473 // Conditional parameters for specific RANs 474 boolean cssSupported = false; 475 int roamingIndicator = 0; 476 int systemIsInPrl = 0; 477 int defaultRoamingIndicator = 0; 478 boolean isEndcAvailable = false; 479 boolean isNrAvailable = false; 480 boolean isDcNrRestricted = false; 481 VopsSupportInfo vopsInfo = null; 482 483 android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo info = 484 regResult.accessTechnologySpecificInfo; 485 486 switch (info.getDiscriminator()) { 487 case AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo: 488 cssSupported = info.cdmaInfo().cssSupported; 489 roamingIndicator = info.cdmaInfo().roamingIndicator; 490 systemIsInPrl = info.cdmaInfo().systemIsInPrl; 491 defaultRoamingIndicator = info.cdmaInfo().defaultRoamingIndicator; 492 break; 493 case AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo: 494 isDcNrRestricted = info.eutranInfo().nrIndicators.isDcNrRestricted; 495 isNrAvailable = info.eutranInfo().nrIndicators.isNrAvailable; 496 isEndcAvailable = info.eutranInfo().nrIndicators.isEndcAvailable; 497 vopsInfo = convertHalLteVopsSupportInfo( 498 info.eutranInfo().lteVopsInfo.isVopsSupported, 499 info.eutranInfo().lteVopsInfo.isEmcBearerSupported); 500 break; 501 case AccessTechnologySpecificInfo.hidl_discriminator.ngranNrVopsInfo: 502 vopsInfo = new NrVopsSupportInfo(info.ngranNrVopsInfo().vopsSupported, 503 info.ngranNrVopsInfo().emcSupported, 504 info.ngranNrVopsInfo().emfSupported); 505 break; 506 case AccessTechnologySpecificInfo.hidl_discriminator.geranDtmSupported: 507 cssSupported = info.geranDtmSupported(); 508 break; 509 default: 510 log("No access tech specific info passes for RegStateResult"); 511 break; 512 } 513 514 // build the result based on the domain for the request 515 switch(domain) { 516 case NetworkRegistrationInfo.DOMAIN_CS: 517 return new NetworkRegistrationInfo(domain, transportType, regState, 518 networkType, reasonForDenial, isEmergencyOnly, availableServices, 519 cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl, 520 defaultRoamingIndicator); 521 default: 522 loge("Unknown domain passed to CellularNetworkService= " + domain); 523 // fall through 524 case NetworkRegistrationInfo.DOMAIN_PS: 525 return new NetworkRegistrationInfo(domain, transportType, regState, networkType, 526 reasonForDenial, isEmergencyOnly, availableServices, cellIdentity, 527 rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable, 528 vopsInfo); 529 } 530 } 531 convertHalLteVopsSupportInfo( boolean vopsSupport, boolean emcBearerSupport)532 private LteVopsSupportInfo convertHalLteVopsSupportInfo( 533 boolean vopsSupport, boolean emcBearerSupport) { 534 int vops = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED; 535 int emergency = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED; 536 537 if (vopsSupport) { 538 vops = LteVopsSupportInfo.LTE_STATUS_SUPPORTED; 539 } 540 if (emcBearerSupport) { 541 emergency = LteVopsSupportInfo.LTE_STATUS_SUPPORTED; 542 } 543 return new LteVopsSupportInfo(vops, emergency); 544 } 545 546 @Override requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback)547 public void requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback) { 548 if (DBG) log("requestNetworkRegistrationInfo for domain " + domain); 549 Message message = null; 550 551 if (domain == NetworkRegistrationInfo.DOMAIN_CS) { 552 message = Message.obtain(mHandler, GET_CS_REGISTRATION_STATE_DONE); 553 mCallbackMap.put(message, callback); 554 mPhone.mCi.getVoiceRegistrationState(message); 555 } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) { 556 message = Message.obtain(mHandler, GET_PS_REGISTRATION_STATE_DONE); 557 mCallbackMap.put(message, callback); 558 mPhone.mCi.getDataRegistrationState(message); 559 } else { 560 loge("requestNetworkRegistrationInfo invalid domain " + domain); 561 callback.onRequestNetworkRegistrationInfoComplete( 562 NetworkServiceCallback.RESULT_ERROR_INVALID_ARG, null); 563 } 564 } 565 566 @Override close()567 public void close() { 568 mCallbackMap.clear(); 569 mPhone.mCi.unregisterForNetworkStateChanged(mHandler); 570 } 571 } 572 573 @Override onCreateNetworkServiceProvider(int slotIndex)574 public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) { 575 if (DBG) log("Cellular network service created for slot " + slotIndex); 576 if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { 577 loge("Tried to Cellular network service with invalid slotId " + slotIndex); 578 return null; 579 } 580 return new CellularNetworkServiceProvider(slotIndex); 581 } 582 log(String s)583 private void log(String s) { 584 Rlog.d(TAG, s); 585 } 586 loge(String s)587 private void loge(String s) { 588 Rlog.e(TAG, s); 589 } 590 } 591