1 /* 2 * Copyright (C) 2020 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.metrics; 18 19 import static com.android.internal.telephony.InboundSmsHandler.SOURCE_INJECTED_FROM_IMS; 20 import static com.android.internal.telephony.InboundSmsHandler.SOURCE_INJECTED_FROM_UNKNOWN; 21 import static com.android.internal.telephony.InboundSmsHandler.SOURCE_NOT_INJECTED; 22 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE; 23 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 24 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_ERROR_NOT_SUPPORTED; 25 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_ERROR_NO_MEMORY; 26 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_SUCCESS; 27 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP; 28 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2; 29 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP; 30 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2; 31 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_IMS; 32 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_UNKNOWN; 33 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_NORMAL; 34 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_SMS_PP; 35 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_VOICEMAIL_INDICATION; 36 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_WAP_PUSH; 37 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_ZERO; 38 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 39 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK; 40 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 41 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS; 42 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_UNKNOWN; 43 44 import android.annotation.Nullable; 45 import android.app.Activity; 46 import android.provider.Telephony.Sms.Intents; 47 import android.telephony.Annotation.NetworkType; 48 import android.telephony.ServiceState; 49 import android.telephony.SmsManager; 50 import android.telephony.TelephonyManager; 51 import android.telephony.ims.stub.ImsRegistrationImplBase; 52 import android.telephony.ims.stub.ImsSmsImplBase; 53 import android.telephony.ims.stub.ImsSmsImplBase.SendStatusResult; 54 55 import com.android.internal.telephony.InboundSmsHandler; 56 import com.android.internal.telephony.Phone; 57 import com.android.internal.telephony.PhoneConstants; 58 import com.android.internal.telephony.PhoneFactory; 59 import com.android.internal.telephony.ServiceStateTracker; 60 import com.android.internal.telephony.flags.Flags; 61 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms; 62 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; 63 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; 64 import com.android.internal.telephony.satellite.metrics.CarrierRoamingSatelliteSessionStats; 65 import com.android.telephony.Rlog; 66 67 import java.util.Objects; 68 import java.util.Random; 69 70 /** Collects sms events per phone ID for the pulled atom. */ 71 public class SmsStats { 72 private static final String TAG = SmsStats.class.getSimpleName(); 73 74 /** 3GPP error for out of service: "no network service" in TS 27.005 cl 3.2.5 */ 75 private static final int NO_NETWORK_ERROR_3GPP = 331; 76 77 /** 3GPP2 error for out of service: "Other radio interface problem" in N.S0005 Table 171 */ 78 private static final int NO_NETWORK_ERROR_3GPP2 = 66; 79 80 private final Phone mPhone; 81 82 private final PersistAtomsStorage mAtomsStorage = 83 PhoneFactory.getMetricsCollector().getAtomsStorage(); 84 85 private static final Random RANDOM = new Random(); 86 SmsStats(Phone phone)87 public SmsStats(Phone phone) { 88 mPhone = phone; 89 } 90 91 /** Create a new atom when multi-part incoming SMS is dropped due to missing parts. */ onDroppedIncomingMultipartSms(boolean is3gpp2, int receivedCount, int totalCount, boolean isEmergency)92 public void onDroppedIncomingMultipartSms(boolean is3gpp2, int receivedCount, int totalCount, 93 boolean isEmergency) { 94 IncomingSms proto = getIncomingDefaultProto(is3gpp2, SOURCE_NOT_INJECTED, isEmergency); 95 // Keep SMS tech as unknown because it's possible that it changed overtime and is not 96 // necessarily the current one. Similarly mark the RAT as unknown. 97 proto.smsTech = INCOMING_SMS__SMS_TECH__SMS_TECH_UNKNOWN; 98 proto.rat = TelephonyManager.NETWORK_TYPE_UNKNOWN; 99 proto.error = INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 100 proto.totalParts = totalCount; 101 proto.receivedParts = receivedCount; 102 mAtomsStorage.addIncomingSms(proto); 103 } 104 105 /** Create a new atom when an SMS for the voicemail indicator is received. */ onIncomingSmsVoicemail(boolean is3gpp2, @InboundSmsHandler.SmsSource int smsSource)106 public void onIncomingSmsVoicemail(boolean is3gpp2, 107 @InboundSmsHandler.SmsSource int smsSource) { 108 IncomingSms proto = getIncomingDefaultProto(is3gpp2, smsSource, false); 109 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_VOICEMAIL_INDICATION; 110 mAtomsStorage.addIncomingSms(proto); 111 } 112 113 /** Create a new atom when an SMS of type zero is received. */ onIncomingSmsTypeZero(@nboundSmsHandler.SmsSource int smsSource)114 public void onIncomingSmsTypeZero(@InboundSmsHandler.SmsSource int smsSource) { 115 IncomingSms proto = getIncomingDefaultProto(false /* is3gpp2 */, smsSource, false); 116 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_ZERO; 117 mAtomsStorage.addIncomingSms(proto); 118 } 119 120 /** Create a new atom when an SMS-PP for the SIM card is received. */ onIncomingSmsPP(@nboundSmsHandler.SmsSource int smsSource, boolean success)121 public void onIncomingSmsPP(@InboundSmsHandler.SmsSource int smsSource, boolean success) { 122 IncomingSms proto = getIncomingDefaultProto(false /* is3gpp2 */, smsSource, false); 123 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_SMS_PP; 124 proto.error = getIncomingSmsError(success); 125 mAtomsStorage.addIncomingSms(proto); 126 } 127 128 /** Create a new atom when an SMS is received successfully. */ onIncomingSmsSuccess(boolean is3gpp2, @InboundSmsHandler.SmsSource int smsSource, int messageCount, boolean blocked, long messageId, boolean isEmergency)129 public void onIncomingSmsSuccess(boolean is3gpp2, 130 @InboundSmsHandler.SmsSource int smsSource, int messageCount, 131 boolean blocked, long messageId, boolean isEmergency) { 132 IncomingSms proto = getIncomingDefaultProto(is3gpp2, smsSource, isEmergency); 133 proto.totalParts = messageCount; 134 proto.receivedParts = messageCount; 135 proto.blocked = blocked; 136 proto.messageId = messageId; 137 mAtomsStorage.addIncomingSms(proto); 138 } 139 140 /** Create a new atom when an incoming SMS has an error. */ onIncomingSmsError(boolean is3gpp2, @InboundSmsHandler.SmsSource int smsSource, int result, boolean isEmergency)141 public void onIncomingSmsError(boolean is3gpp2, 142 @InboundSmsHandler.SmsSource int smsSource, int result, boolean isEmergency) { 143 IncomingSms proto = getIncomingDefaultProto(is3gpp2, smsSource, isEmergency); 144 proto.error = getIncomingSmsError(result); 145 mAtomsStorage.addIncomingSms(proto); 146 } 147 148 /** Create a new atom when an incoming WAP_PUSH SMS is received. */ onIncomingSmsWapPush(@nboundSmsHandler.SmsSource int smsSource, int messageCount, int result, long messageId, boolean isEmergency)149 public void onIncomingSmsWapPush(@InboundSmsHandler.SmsSource int smsSource, 150 int messageCount, int result, long messageId, boolean isEmergency) { 151 IncomingSms proto = getIncomingDefaultProto(false, smsSource, isEmergency); 152 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_WAP_PUSH; 153 proto.totalParts = messageCount; 154 proto.receivedParts = messageCount; 155 proto.error = getIncomingSmsError(result); 156 proto.messageId = messageId; 157 mAtomsStorage.addIncomingSms(proto); 158 } 159 160 /** Create a new atom when an outgoing SMS is sent. */ onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs, @SmsManager.Result int sendErrorCode, long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency)161 public void onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs, 162 @SmsManager.Result int sendErrorCode, long messageId, boolean isFromDefaultApp, 163 long intervalMillis, boolean isEmergency) { 164 onOutgoingSms(isOverIms, is3gpp2, fallbackToCs, sendErrorCode, NO_ERROR_CODE, 165 messageId, isFromDefaultApp, intervalMillis, isEmergency); 166 } 167 168 /** Create a new atom when an outgoing SMS is sent. */ onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs, @SmsManager.Result int sendErrorCode, int networkErrorCode, long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency)169 public void onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs, 170 @SmsManager.Result int sendErrorCode, int networkErrorCode, long messageId, 171 boolean isFromDefaultApp, long intervalMillis, boolean isEmergency) { 172 OutgoingSms proto = 173 getOutgoingDefaultProto(is3gpp2, isOverIms, messageId, isFromDefaultApp, 174 intervalMillis, isEmergency); 175 176 // The field errorCode is used for up-to-Android-13 devices. From Android 14, sendErrorCode 177 // and networkErrorCode will be used. The field errorCode will be deprecated when most 178 // devices use Android 14 or higher versions. 179 if (isOverIms) { 180 // Populate error code and result for IMS case 181 proto.errorCode = sendErrorCode; 182 if (fallbackToCs) { 183 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK; 184 } else if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) { 185 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 186 } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) { 187 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 188 } 189 } else { 190 // Populate error code and result for CS case 191 if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) { 192 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 193 } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) { 194 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 195 } 196 proto.errorCode = networkErrorCode; 197 if (sendErrorCode == SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE 198 && networkErrorCode == NO_ERROR_CODE) { 199 proto.errorCode = is3gpp2 ? NO_NETWORK_ERROR_3GPP2 : NO_NETWORK_ERROR_3GPP; 200 } 201 } 202 203 proto.sendErrorCode = sendErrorCode; 204 proto.networkErrorCode = networkErrorCode; 205 206 mAtomsStorage.addOutgoingSms(proto); 207 CarrierRoamingSatelliteSessionStats sessionStats = 208 CarrierRoamingSatelliteSessionStats.getInstance(mPhone.getSubId()); 209 sessionStats.onOutgoingSms(mPhone.getSubId()); 210 } 211 212 /** Create a new atom when user attempted to send an outgoing short code sms. */ onOutgoingShortCodeSms(int category, int xmlVersion)213 public void onOutgoingShortCodeSms(int category, int xmlVersion) { 214 OutgoingShortCodeSms proto = new OutgoingShortCodeSms(); 215 proto.category = category; 216 proto.xmlVersion = xmlVersion; 217 proto.shortCodeSmsCount = 1; 218 mAtomsStorage.addOutgoingShortCodeSms(proto); 219 } 220 221 /** Creates a proto for a normal single-part {@code IncomingSms} with default values. */ getIncomingDefaultProto(boolean is3gpp2, @InboundSmsHandler.SmsSource int smsSource, boolean isEmergency)222 private IncomingSms getIncomingDefaultProto(boolean is3gpp2, 223 @InboundSmsHandler.SmsSource int smsSource, boolean isEmergency) { 224 IncomingSms proto = new IncomingSms(); 225 proto.smsFormat = getSmsFormat(is3gpp2); 226 proto.smsTech = getSmsTech(smsSource, is3gpp2); 227 proto.rat = getRat(smsSource); 228 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_NORMAL; 229 proto.totalParts = 1; 230 proto.receivedParts = 1; 231 proto.blocked = false; 232 proto.error = INCOMING_SMS__ERROR__SMS_SUCCESS; 233 proto.isRoaming = getIsRoaming(); 234 proto.simSlotIndex = getPhoneId(); 235 proto.isMultiSim = SimSlotState.isMultiSim(); 236 proto.isEsim = SimSlotState.isEsim(getPhoneId()); 237 proto.carrierId = getCarrierId(); 238 // Message ID is initialized with random number, as it is not available for all incoming 239 // SMS messages (e.g. those handled by OS or error cases). 240 proto.messageId = RANDOM.nextLong(); 241 proto.count = 1; 242 proto.isManagedProfile = mPhone.isManagedProfile(); 243 proto.isNtn = isNonTerrestrialNetwork(); 244 proto.isEmergency = isEmergency; 245 return proto; 246 } 247 248 /** Create a proto for a normal {@code OutgoingSms} with default values. */ getOutgoingDefaultProto(boolean is3gpp2, boolean isOverIms, long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency)249 private OutgoingSms getOutgoingDefaultProto(boolean is3gpp2, boolean isOverIms, 250 long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency) { 251 OutgoingSms proto = new OutgoingSms(); 252 proto.smsFormat = getSmsFormat(is3gpp2); 253 proto.smsTech = getSmsTech(isOverIms, is3gpp2); 254 proto.rat = getRat(isOverIms); 255 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS; 256 proto.errorCode = isOverIms ? SmsManager.RESULT_ERROR_NONE : NO_ERROR_CODE; 257 proto.isRoaming = getIsRoaming(); 258 proto.isFromDefaultApp = isFromDefaultApp; 259 proto.simSlotIndex = getPhoneId(); 260 proto.isMultiSim = SimSlotState.isMultiSim(); 261 proto.isEsim = SimSlotState.isEsim(getPhoneId()); 262 proto.carrierId = getCarrierId(); 263 // If the message ID is invalid, generate a random value 264 proto.messageId = messageId != 0L ? messageId : RANDOM.nextLong(); 265 // Setting the retry ID to zero. If needed, it will be incremented when the atom is added 266 // in the persistent storage. 267 proto.retryId = 0; 268 proto.intervalMillis = intervalMillis; 269 proto.count = 1; 270 proto.isManagedProfile = mPhone.isManagedProfile(); 271 proto.isEmergency = isEmergency; 272 proto.isNtn = isNonTerrestrialNetwork(); 273 return proto; 274 } 275 getSmsFormat(boolean is3gpp2)276 private static int getSmsFormat(boolean is3gpp2) { 277 if (is3gpp2) { 278 return INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2; 279 } else { 280 return INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP; 281 } 282 } 283 getSmsTech(@nboundSmsHandler.SmsSource int smsSource, boolean is3gpp2)284 private int getSmsTech(@InboundSmsHandler.SmsSource int smsSource, boolean is3gpp2) { 285 if (smsSource == SOURCE_INJECTED_FROM_UNKNOWN) { 286 return INCOMING_SMS__SMS_TECH__SMS_TECH_UNKNOWN; 287 } 288 return getSmsTech(smsSource == SOURCE_INJECTED_FROM_IMS, is3gpp2); 289 } 290 getSmsTech(boolean isOverIms, boolean is3gpp2)291 private int getSmsTech(boolean isOverIms, boolean is3gpp2) { 292 if (isOverIms) { 293 return INCOMING_SMS__SMS_TECH__SMS_TECH_IMS; 294 } else if (is3gpp2) { 295 return INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2; 296 } else { 297 return INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP; 298 } 299 } 300 getIncomingSmsError(int result)301 private static int getIncomingSmsError(int result) { 302 switch (result) { 303 case Activity.RESULT_OK: 304 case Intents.RESULT_SMS_HANDLED: 305 return INCOMING_SMS__ERROR__SMS_SUCCESS; 306 case Intents.RESULT_SMS_OUT_OF_MEMORY: 307 return INCOMING_SMS__ERROR__SMS_ERROR_NO_MEMORY; 308 case Intents.RESULT_SMS_UNSUPPORTED: 309 return INCOMING_SMS__ERROR__SMS_ERROR_NOT_SUPPORTED; 310 case Intents.RESULT_SMS_GENERIC_ERROR: 311 default: 312 return INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 313 } 314 } 315 getIncomingSmsError(boolean success)316 private static int getIncomingSmsError(boolean success) { 317 if (success) { 318 return INCOMING_SMS__ERROR__SMS_SUCCESS; 319 } else { 320 return INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 321 } 322 } 323 getOutgoingSmsError(@endStatusResult int imsSendResult)324 private static int getOutgoingSmsError(@SendStatusResult int imsSendResult) { 325 switch (imsSendResult) { 326 case ImsSmsImplBase.SEND_STATUS_OK: 327 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS; 328 case ImsSmsImplBase.SEND_STATUS_ERROR: 329 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 330 case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY: 331 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 332 case ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK: 333 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK; 334 default: 335 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_UNKNOWN; 336 } 337 } 338 339 /** 340 * Returns a hash value to identify messages that are identical for the purpose of merging them 341 * together when storage is full. 342 */ getSmsHashCode(OutgoingSms sms)343 static int getSmsHashCode(OutgoingSms sms) { 344 return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.sendResult, sms.errorCode, 345 sms.isRoaming, sms.isFromDefaultApp, sms.simSlotIndex, sms.isMultiSim, 346 sms.isEsim, sms.carrierId); 347 } 348 349 /** 350 * Returns a hash value to identify messages that are identical for the purpose of merging them 351 * together when storage is full. 352 */ getSmsHashCode(IncomingSms sms)353 static int getSmsHashCode(IncomingSms sms) { 354 return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.smsType, 355 sms.totalParts, sms.receivedParts, sms.blocked, sms.error, 356 sms.isRoaming, sms.simSlotIndex, sms.isMultiSim, sms.isEsim, sms.carrierId); 357 } 358 getPhoneId()359 private int getPhoneId() { 360 Phone phone = mPhone; 361 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 362 phone = mPhone.getDefaultPhone(); 363 } 364 return phone.getPhoneId(); 365 } 366 367 @Nullable getServiceState()368 private ServiceState getServiceState() { 369 Phone phone = mPhone; 370 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 371 phone = mPhone.getDefaultPhone(); 372 } 373 ServiceStateTracker serviceStateTracker = phone.getServiceStateTracker(); 374 return serviceStateTracker != null ? serviceStateTracker.getServiceState() : null; 375 } 376 getRat(@nboundSmsHandler.SmsSource int smsSource)377 private @NetworkType int getRat(@InboundSmsHandler.SmsSource int smsSource) { 378 if (smsSource == SOURCE_INJECTED_FROM_UNKNOWN) { 379 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 380 } 381 return getRat(smsSource == SOURCE_INJECTED_FROM_IMS); 382 } 383 getRat(boolean isOverIms)384 private @NetworkType int getRat(boolean isOverIms) { 385 if (isOverIms) { 386 if (mPhone.getImsRegistrationTech() 387 == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) { 388 return TelephonyManager.NETWORK_TYPE_IWLAN; 389 } 390 } 391 // TODO(b/168837897): Returns the RAT at the time the SMS was received.. 392 ServiceState serviceState = getServiceState(); 393 return serviceState != null 394 ? serviceState.getVoiceNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN; 395 } 396 getIsRoaming()397 private boolean getIsRoaming() { 398 ServiceState serviceState = getServiceState(); 399 return ServiceStateStats.isNetworkRoaming(serviceState); 400 } 401 getCarrierId()402 private int getCarrierId() { 403 Phone phone = mPhone; 404 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 405 phone = mPhone.getDefaultPhone(); 406 } 407 return phone.getCarrierId(); 408 } 409 isNonTerrestrialNetwork()410 private boolean isNonTerrestrialNetwork() { 411 if (!Flags.carrierEnabledSatelliteFlag()) { 412 return false; 413 } 414 415 ServiceState ss = getServiceState(); 416 if (ss != null) { 417 return ss.isUsingNonTerrestrialNetwork(); 418 } else { 419 Rlog.e(TAG, "isNonTerrestrialNetwork(), ServiceState is null"); 420 return false; 421 } 422 } 423 loge(String format, Object... args)424 private void loge(String format, Object... args) { 425 Rlog.e(TAG, "[" + mPhone.getPhoneId() + "]" + String.format(format, args)); 426 } 427 } 428