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.nano.PersistAtomsProto.IncomingSms; 61 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; 62 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; 63 import com.android.internal.telephony.satellite.SatelliteController; 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, boolean isMtSmsPolling)161 public void onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs, 162 @SmsManager.Result int sendErrorCode, long messageId, boolean isFromDefaultApp, 163 long intervalMillis, boolean isEmergency, boolean isMtSmsPolling) { 164 onOutgoingSms(isOverIms, is3gpp2, fallbackToCs, sendErrorCode, NO_ERROR_CODE, 165 messageId, isFromDefaultApp, intervalMillis, isEmergency, isMtSmsPolling); 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, boolean isMtSmsPolling)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 boolean isMtSmsPolling) { 173 OutgoingSms proto = 174 getOutgoingDefaultProto(is3gpp2, isOverIms, messageId, isFromDefaultApp, 175 intervalMillis, isEmergency, isMtSmsPolling); 176 177 // The field errorCode is used for up-to-Android-13 devices. From Android 14, sendErrorCode 178 // and networkErrorCode will be used. The field errorCode will be deprecated when most 179 // devices use Android 14 or higher versions. 180 if (isOverIms) { 181 // Populate error code and result for IMS case 182 proto.errorCode = sendErrorCode; 183 if (fallbackToCs) { 184 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK; 185 } else if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) { 186 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 187 } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) { 188 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 189 } 190 } else { 191 // Populate error code and result for CS case 192 if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) { 193 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 194 } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) { 195 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 196 } 197 proto.errorCode = networkErrorCode; 198 if (sendErrorCode == SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE 199 && networkErrorCode == NO_ERROR_CODE) { 200 proto.errorCode = is3gpp2 ? NO_NETWORK_ERROR_3GPP2 : NO_NETWORK_ERROR_3GPP; 201 } 202 } 203 204 proto.sendErrorCode = sendErrorCode; 205 proto.networkErrorCode = networkErrorCode; 206 207 mAtomsStorage.addOutgoingSms(proto); 208 CarrierRoamingSatelliteSessionStats sessionStats = 209 CarrierRoamingSatelliteSessionStats.getInstance(mPhone.getSubId()); 210 sessionStats.onOutgoingSms(mPhone.getSubId()); 211 } 212 213 /** Create a new atom when user attempted to send an outgoing short code sms. */ onOutgoingShortCodeSms(int category, int xmlVersion)214 public void onOutgoingShortCodeSms(int category, int xmlVersion) { 215 OutgoingShortCodeSms proto = new OutgoingShortCodeSms(); 216 proto.category = category; 217 proto.xmlVersion = xmlVersion; 218 proto.shortCodeSmsCount = 1; 219 mAtomsStorage.addOutgoingShortCodeSms(proto); 220 } 221 222 /** Creates a proto for a normal single-part {@code IncomingSms} with default values. */ getIncomingDefaultProto(boolean is3gpp2, @InboundSmsHandler.SmsSource int smsSource, boolean isEmergency)223 private IncomingSms getIncomingDefaultProto(boolean is3gpp2, 224 @InboundSmsHandler.SmsSource int smsSource, boolean isEmergency) { 225 IncomingSms proto = new IncomingSms(); 226 proto.smsFormat = getSmsFormat(is3gpp2); 227 proto.smsTech = getSmsTech(smsSource, is3gpp2); 228 proto.rat = getRat(smsSource); 229 proto.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_NORMAL; 230 proto.totalParts = 1; 231 proto.receivedParts = 1; 232 proto.blocked = false; 233 proto.error = INCOMING_SMS__ERROR__SMS_SUCCESS; 234 proto.isRoaming = getIsRoaming(); 235 proto.simSlotIndex = getPhoneId(); 236 proto.isMultiSim = SimSlotState.isMultiSim(); 237 proto.isEsim = SimSlotState.isEsim(getPhoneId()); 238 proto.carrierId = getCarrierId(); 239 // Message ID is initialized with random number, as it is not available for all incoming 240 // SMS messages (e.g. those handled by OS or error cases). 241 proto.messageId = RANDOM.nextLong(); 242 proto.count = 1; 243 proto.isManagedProfile = mPhone.isManagedProfile(); 244 proto.isNtn = isNonTerrestrialNetwork(); 245 proto.isEmergency = isEmergency; 246 proto.isNbIotNtn = isNbIotNtn(mPhone); 247 return proto; 248 } 249 250 /** Create a proto for a normal {@code OutgoingSms} with default values. */ getOutgoingDefaultProto(boolean is3gpp2, boolean isOverIms, long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency, boolean isMtSmsPolling)251 private OutgoingSms getOutgoingDefaultProto(boolean is3gpp2, boolean isOverIms, 252 long messageId, boolean isFromDefaultApp, long intervalMillis, boolean isEmergency, 253 boolean isMtSmsPolling) { 254 OutgoingSms proto = new OutgoingSms(); 255 proto.smsFormat = getSmsFormat(is3gpp2); 256 proto.smsTech = getSmsTech(isOverIms, is3gpp2); 257 proto.rat = getRat(isOverIms); 258 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS; 259 proto.errorCode = isOverIms ? SmsManager.RESULT_ERROR_NONE : NO_ERROR_CODE; 260 proto.isRoaming = getIsRoaming(); 261 proto.isFromDefaultApp = isFromDefaultApp; 262 proto.simSlotIndex = getPhoneId(); 263 proto.isMultiSim = SimSlotState.isMultiSim(); 264 proto.isEsim = SimSlotState.isEsim(getPhoneId()); 265 proto.carrierId = getCarrierId(); 266 // If the message ID is invalid, generate a random value 267 proto.messageId = messageId != 0L ? messageId : RANDOM.nextLong(); 268 // Setting the retry ID to zero. If needed, it will be incremented when the atom is added 269 // in the persistent storage. 270 proto.retryId = 0; 271 proto.intervalMillis = intervalMillis; 272 proto.count = 1; 273 proto.isManagedProfile = mPhone.isManagedProfile(); 274 proto.isEmergency = isEmergency; 275 proto.isNtn = isNonTerrestrialNetwork(); 276 proto.isMtSmsPolling = isMtSmsPolling; 277 proto.isNbIotNtn = isNbIotNtn(mPhone); 278 return proto; 279 } 280 getSmsFormat(boolean is3gpp2)281 private static int getSmsFormat(boolean is3gpp2) { 282 if (is3gpp2) { 283 return INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2; 284 } else { 285 return INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP; 286 } 287 } 288 getSmsTech(@nboundSmsHandler.SmsSource int smsSource, boolean is3gpp2)289 private int getSmsTech(@InboundSmsHandler.SmsSource int smsSource, boolean is3gpp2) { 290 if (smsSource == SOURCE_INJECTED_FROM_UNKNOWN) { 291 return INCOMING_SMS__SMS_TECH__SMS_TECH_UNKNOWN; 292 } 293 return getSmsTech(smsSource == SOURCE_INJECTED_FROM_IMS, is3gpp2); 294 } 295 getSmsTech(boolean isOverIms, boolean is3gpp2)296 private int getSmsTech(boolean isOverIms, boolean is3gpp2) { 297 if (isOverIms) { 298 return INCOMING_SMS__SMS_TECH__SMS_TECH_IMS; 299 } else if (is3gpp2) { 300 return INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2; 301 } else { 302 return INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP; 303 } 304 } 305 getIncomingSmsError(int result)306 private static int getIncomingSmsError(int result) { 307 switch (result) { 308 case Activity.RESULT_OK: 309 case Intents.RESULT_SMS_HANDLED: 310 return INCOMING_SMS__ERROR__SMS_SUCCESS; 311 case Intents.RESULT_SMS_OUT_OF_MEMORY: 312 return INCOMING_SMS__ERROR__SMS_ERROR_NO_MEMORY; 313 case Intents.RESULT_SMS_UNSUPPORTED: 314 return INCOMING_SMS__ERROR__SMS_ERROR_NOT_SUPPORTED; 315 case Intents.RESULT_SMS_GENERIC_ERROR: 316 default: 317 return INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 318 } 319 } 320 getIncomingSmsError(boolean success)321 private static int getIncomingSmsError(boolean success) { 322 if (success) { 323 return INCOMING_SMS__ERROR__SMS_SUCCESS; 324 } else { 325 return INCOMING_SMS__ERROR__SMS_ERROR_GENERIC; 326 } 327 } 328 getOutgoingSmsError(@endStatusResult int imsSendResult)329 private static int getOutgoingSmsError(@SendStatusResult int imsSendResult) { 330 switch (imsSendResult) { 331 case ImsSmsImplBase.SEND_STATUS_OK: 332 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS; 333 case ImsSmsImplBase.SEND_STATUS_ERROR: 334 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR; 335 case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY: 336 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY; 337 case ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK: 338 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK; 339 default: 340 return OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_UNKNOWN; 341 } 342 } 343 344 /** 345 * Returns a hash value to identify messages that are identical for the purpose of merging them 346 * together when storage is full. 347 */ getSmsHashCode(OutgoingSms sms)348 static int getSmsHashCode(OutgoingSms sms) { 349 return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.sendResult, sms.errorCode, 350 sms.isRoaming, sms.isFromDefaultApp, sms.simSlotIndex, sms.isMultiSim, sms.isEsim, 351 sms.carrierId, sms.isEmergency, sms.isNtn, sms.isMtSmsPolling, sms.isNbIotNtn); 352 } 353 354 /** 355 * Returns a hash value to identify messages that are identical for the purpose of merging them 356 * together when storage is full. 357 */ getSmsHashCode(IncomingSms sms)358 static int getSmsHashCode(IncomingSms sms) { 359 return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.smsType, 360 sms.totalParts, sms.receivedParts, sms.blocked, sms.error, 361 sms.isRoaming, sms.simSlotIndex, sms.isMultiSim, sms.isEsim, sms.carrierId, 362 sms.isNtn, sms.isNbIotNtn); 363 } 364 getPhoneId()365 private int getPhoneId() { 366 Phone phone = mPhone; 367 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 368 phone = mPhone.getDefaultPhone(); 369 } 370 return phone.getPhoneId(); 371 } 372 373 @Nullable getServiceState()374 private ServiceState getServiceState() { 375 Phone phone = mPhone; 376 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 377 phone = mPhone.getDefaultPhone(); 378 } 379 ServiceStateTracker serviceStateTracker = phone.getServiceStateTracker(); 380 return serviceStateTracker != null ? serviceStateTracker.getServiceState() : null; 381 } 382 getRat(@nboundSmsHandler.SmsSource int smsSource)383 private @NetworkType int getRat(@InboundSmsHandler.SmsSource int smsSource) { 384 if (smsSource == SOURCE_INJECTED_FROM_UNKNOWN) { 385 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 386 } 387 return getRat(smsSource == SOURCE_INJECTED_FROM_IMS); 388 } 389 getRat(boolean isOverIms)390 private @NetworkType int getRat(boolean isOverIms) { 391 if (isOverIms) { 392 if (mPhone.getImsRegistrationTech() 393 == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) { 394 return TelephonyManager.NETWORK_TYPE_IWLAN; 395 } 396 } 397 // TODO(b/168837897): Returns the RAT at the time the SMS was received.. 398 ServiceState serviceState = getServiceState(); 399 return serviceState != null 400 ? serviceState.getVoiceNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN; 401 } 402 getIsRoaming()403 private boolean getIsRoaming() { 404 ServiceState serviceState = getServiceState(); 405 return ServiceStateStats.isNetworkRoaming(serviceState); 406 } 407 getCarrierId()408 private int getCarrierId() { 409 Phone phone = mPhone; 410 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 411 phone = mPhone.getDefaultPhone(); 412 } 413 return phone.getCarrierId(); 414 } 415 isNonTerrestrialNetwork()416 private boolean isNonTerrestrialNetwork() { 417 ServiceState ss = getServiceState(); 418 if (ss != null) { 419 return ss.isUsingNonTerrestrialNetwork(); 420 } else { 421 Rlog.e(TAG, "isNonTerrestrialNetwork(), ServiceState is null"); 422 return false; 423 } 424 } 425 isNbIotNtn(Phone phone)426 private boolean isNbIotNtn(Phone phone) { 427 return SatelliteController.getInstance().isInCarrierRoamingNbIotNtn(phone); 428 } 429 loge(String format, Object... args)430 private void loge(String format, Object... args) { 431 Rlog.e(TAG, "[" + mPhone.getPhoneId() + "]" + String.format(format, args)); 432 } 433 } 434