• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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