Loading proto/src/persist_atoms.proto +23 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ message PersistAtoms { /* Timestamp of last voice_call_sessions pull. */ optional int64 voice_call_session_pull_timestamp_millis = 4; /* Incoming SMS statistics and information. */ repeated IncomingSms incoming_sms = 5; /* Timestamp of last incoming_sms pull. */ optional int64 incoming_sms_pull_timestamp_millis = 6; } // The canonical versions of the following enums live in: Loading Loading @@ -82,3 +88,20 @@ message RawVoiceCallRatUsage { optional int64 total_duration_millis = 3; optional int64 call_count = 4; } message IncomingSms { optional int32 sms_format = 1; optional int32 sms_tech = 2; optional int32 rat = 3; optional int32 sms_type = 4; optional int32 total_parts = 5; optional int32 received_parts = 6; optional bool blocked = 7; optional int32 error = 8; optional bool is_roaming = 9; optional int32 sim_slot_index = 10; optional bool is_multi_sim = 11; optional bool is_esim = 12; optional int32 carrier_id = 13; optional int64 message_id = 14; } src/java/com/android/internal/telephony/IccSmsInterfaceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -628,7 +628,7 @@ public class IccSmsInterfaceManager { "\n format=" + format + "\n receivedIntent=" + receivedIntent); } mDispatchersController.injectSmsPdu(pdu, format, mDispatchersController.injectSmsPdu(pdu, format, false /* isOverIms */, result -> { if (receivedIntent != null) { try { Loading src/java/com/android/internal/telephony/ImsSmsDispatcher.java +1 −1 Original line number Diff line number Diff line Loading @@ -245,7 +245,7 @@ public class ImsSmsDispatcher extends SMSDispatcher { } catch (ImsException e) { loge("Failed to acknowledgeSms(). Error: " + e.getMessage()); } }, true); }, true /* ignoreClass */, true /* isOverIms */); } finally { Binder.restoreCallingIdentity(identity); } Loading src/java/com/android/internal/telephony/InboundSmsHandler.java +67 −39 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_PDU; import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE; import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; import android.annotation.IntDef; import android.annotation.Nullable; import android.app.Activity; import android.app.AppOpsManager; Loading Loading @@ -80,6 +81,8 @@ import com.android.telephony.Rlog; import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; Loading Loading @@ -183,6 +186,24 @@ public abstract class InboundSmsHandler extends StateMachine { /** Wakelock release delay when returning to idle state. */ private static final int WAKELOCK_TIMEOUT = 3000; /** Received SMS was not injected. */ public static final int SOURCE_NOT_INJECTED = 0; /** Received SMS was received over IMS and injected. */ public static final int SOURCE_INJECTED_FROM_IMS = 1; /** Received SMS was injected from source different than IMS. */ public static final int SOURCE_INJECTED_FROM_UNKNOWN = 2; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SOURCE_"}, value = { SOURCE_NOT_INJECTED, SOURCE_INJECTED_FROM_IMS, SOURCE_INJECTED_FROM_UNKNOWN }) public @interface SmsSource {} // The notitfication tag used when showing a notification. The combination of notification tag // and notification id should be unique within the phone app. private static final String NOTIFICATION_TAG = "InboundSmsHandler"; Loading Loading @@ -255,10 +276,6 @@ public abstract class InboundSmsHandler extends StateMachine { /** Timeout for releasing wakelock */ private int mWakeLockTimeout; /** Indicates if last SMS was injected. This is used to recognize SMS received over IMS from others in order to update metrics. */ private boolean mLastSmsWasInjected = false; private List<SmsFilter> mSmsFilters; /** Loading Loading @@ -516,7 +533,7 @@ public abstract class InboundSmsHandler extends StateMachine { case EVENT_INJECT_SMS: // handle new injected SMS handleInjectSms((AsyncResult) msg.obj); handleInjectSms((AsyncResult) msg.obj, msg.arg1 == 1 /* isOverIms */); sendMessage(EVENT_RETURN_TO_IDLE); return HANDLED; Loading Loading @@ -641,8 +658,7 @@ public abstract class InboundSmsHandler extends StateMachine { int result; try { SmsMessage sms = (SmsMessage) ar.result; mLastSmsWasInjected = false; result = dispatchMessage(sms.mWrappedSmsMessage); result = dispatchMessage(sms.mWrappedSmsMessage, SOURCE_NOT_INJECTED); } catch (RuntimeException ex) { loge("Exception dispatching message", ex); result = RESULT_SMS_DISPATCH_FAILURE; Loading @@ -661,7 +677,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @param ar is the AsyncResult that has the SMS PDU to be injected. */ @UnsupportedAppUsage private void handleInjectSms(AsyncResult ar) { private void handleInjectSms(AsyncResult ar, boolean isOverIms) { int result; SmsDispatchersController.SmsInjectionCallback callback = null; try { Loading @@ -671,8 +687,9 @@ public abstract class InboundSmsHandler extends StateMachine { loge("Null injected sms"); result = RESULT_SMS_NULL_PDU; } else { mLastSmsWasInjected = true; result = dispatchMessage(sms.mWrappedSmsMessage); @SmsSource int smsSource = isOverIms ? SOURCE_INJECTED_FROM_IMS : SOURCE_INJECTED_FROM_UNKNOWN; result = dispatchMessage(sms.mWrappedSmsMessage, smsSource); } } catch (RuntimeException ex) { loge("Exception dispatching message", ex); Loading @@ -689,10 +706,11 @@ public abstract class InboundSmsHandler extends StateMachine { * 3GPP2-specific message types. * * @param smsb the SmsMessageBase object from the RIL * @param smsSource the source of the SMS message * @return a result code from {@link android.provider.Telephony.Sms.Intents}, * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC */ private int dispatchMessage(SmsMessageBase smsb) { private int dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource) { // If sms is null, there was a parsing error. if (smsb == null) { loge("dispatchSmsMessage: message is null"); Loading @@ -719,12 +737,13 @@ public abstract class InboundSmsHandler extends StateMachine { return Intents.RESULT_SMS_RECEIVED_WHILE_ENCRYPTED; } int result = dispatchMessageRadioSpecific(smsb); int result = dispatchMessageRadioSpecific(smsb, smsSource); // In case of error, add to metrics. This is not required in case of success, as the // data will be tracked when the message is processed (processMessagePart). if (result != Intents.RESULT_SMS_HANDLED) { mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), mLastSmsWasInjected, result); if (result != Intents.RESULT_SMS_HANDLED && result != Activity.RESULT_OK) { mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), smsSource, result); mPhone.getSmsStats().onIncomingSmsError(is3gpp2(), smsSource, result); } return result; } Loading @@ -735,10 +754,12 @@ public abstract class InboundSmsHandler extends StateMachine { * {@link #dispatchNormalMessage} from this class. * * @param smsb the SmsMessageBase object from the RIL * @param smsSource the source of the SMS message * @return a result code from {@link android.provider.Telephony.Sms.Intents}, * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC */ protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb); protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource); /** * Send an acknowledge message to the SMSC. Loading Loading @@ -782,10 +803,11 @@ public abstract class InboundSmsHandler extends StateMachine { * {@link #EVENT_BROADCAST_SMS}. Returns {@link Intents#RESULT_SMS_HANDLED} or an error value. * * @param sms the message to dispatch * @param smsSource the source of the SMS message * @return {@link Intents#RESULT_SMS_HANDLED} if the message was accepted, or an error status */ @UnsupportedAppUsage protected int dispatchNormalMessage(SmsMessageBase sms) { protected int dispatchNormalMessage(SmsMessageBase sms, @SmsSource int smsSource) { SmsHeader smsHeader = sms.getUserDataHeader(); InboundSmsTracker tracker; Loading @@ -803,7 +825,7 @@ public abstract class InboundSmsHandler extends StateMachine { sms.getTimestampMillis(), destPort, is3gpp2(), false, sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId()); mPhone.getSubId(), smsSource); } else { // Create a tracker for this message segment. SmsHeader.ConcatRef concatRef = smsHeader.concatRef; Loading @@ -812,10 +834,11 @@ public abstract class InboundSmsHandler extends StateMachine { tracker = TelephonyComponentFactory.getInstance() .inject(InboundSmsTracker.class.getName()) .makeInboundSmsTracker(mContext, sms.getPdu(), sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false, sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId()); sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false, sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId(), smsSource); } if (VDBG) log("created tracker: " + tracker); Loading Loading @@ -975,14 +998,7 @@ public abstract class InboundSmsHandler extends StateMachine { } final boolean isWapPush = (destPort == SmsHeader.PORT_WAP_PUSH); // At this point, all parts of the SMS are received. Update metrics for incoming SMS. // WAP-PUSH messages are handled below to also keep track of the result of the processing. String format = tracker.getFormat(); if (!isWapPush) { mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, block, tracker.getMessageId()); } // Do not process null pdu(s). Check for that and return false in that case. List<byte[]> pduList = Arrays.asList(pdus); Loading @@ -990,6 +1006,8 @@ public abstract class InboundSmsHandler extends StateMachine { String errorMsg = "processMessagePart: returning false due to " + (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)"); logeWithLocalLog(errorMsg, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsError( is3gpp2(), tracker.getSource(), RESULT_SMS_NULL_PDU); return false; } Loading @@ -1004,9 +1022,11 @@ public abstract class InboundSmsHandler extends StateMachine { } else { loge("processMessagePart: SmsMessage.createFromPdu returned null", tracker.getMessageId()); mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), SmsConstants.FORMAT_3GPP, timestamps, false, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount, RESULT_SMS_NULL_MESSAGE, tracker.getMessageId()); return false; } } Loading Loading @@ -1035,13 +1055,12 @@ public abstract class InboundSmsHandler extends StateMachine { } // Add result of WAP-PUSH into metrics. RESULT_SMS_HANDLED indicates that the WAP-PUSH // needs to be ignored, so treating it as a success case. if (result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED) { mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, true, tracker.getMessageId()); } else { mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, false, tracker.getMessageId()); } boolean wapPushResult = result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED; mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), format, timestamps, wapPushResult, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount, result, tracker.getMessageId()); // result is Activity.RESULT_OK if an ordered broadcast was sent if (result == Activity.RESULT_OK) { return true; Loading @@ -1054,6 +1073,15 @@ public abstract class InboundSmsHandler extends StateMachine { } } // All parts of SMS are received. Update metrics for incoming SMS. // The metrics are generated before SMS filters are invoked. // For messages composed by multiple parts, the metrics are generated considering the // characteristics of the last one. mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), tracker.getSource(), format, timestamps, block, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsSuccess(is3gpp2(), tracker.getSource(), messageCount, block, tracker.getMessageId()); // Always invoke SMS filters, even if the number ends up being blocked, to prevent // surprising bugs due to blocking numbers that happen to be used for visual voicemail SMS // or other carrier system messages. Loading src/java/com/android/internal/telephony/InboundSmsTracker.java +14 −2 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class InboundSmsTracker { private final boolean mIsClass0; private final int mSubId; private final long mMessageId; private final @InboundSmsHandler.SmsSource int mSmsSource; // Fields for concatenating multi-part SMS messages private final String mAddress; Loading Loading @@ -117,10 +118,12 @@ public class InboundSmsTracker { * @param address originating address * @param displayAddress email address if this message was from an email gateway, otherwise same * as originating address * @param smsSource the source of the SMS message */ public InboundSmsTracker(Context context, byte[] pdu, long timestamp, int destPort, boolean is3gpp2, boolean is3gpp2WapPdu, String address, String displayAddress, String messageBody, boolean isClass0, int subId) { String messageBody, boolean isClass0, int subId, @InboundSmsHandler.SmsSource int smsSource) { mPdu = pdu; mTimestamp = timestamp; mDestPort = destPort; Loading @@ -136,6 +139,7 @@ public class InboundSmsTracker { mMessageCount = 1; mSubId = subId; mMessageId = createMessageId(context, timestamp, subId); mSmsSource = smsSource; } /** Loading @@ -156,11 +160,12 @@ public class InboundSmsTracker { * @param sequenceNumber the sequence number of this segment (0-based) * @param messageCount the total number of segments * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise * @param smsSource the source of the SMS message */ public InboundSmsTracker(Context context, byte[] pdu, long timestamp, int destPort, boolean is3gpp2, String address, String displayAddress, int referenceNumber, int sequenceNumber, int messageCount, boolean is3gpp2WapPdu, String messageBody, boolean isClass0, int subId) { boolean isClass0, int subId, @InboundSmsHandler.SmsSource int smsSource) { mPdu = pdu; mTimestamp = timestamp; mDestPort = destPort; Loading @@ -177,6 +182,7 @@ public class InboundSmsTracker { mMessageCount = messageCount; mSubId = subId; mMessageId = createMessageId(context, timestamp, subId); mSmsSource = smsSource; } /** Loading Loading @@ -241,6 +247,8 @@ public class InboundSmsTracker { } mMessageBody = cursor.getString(InboundSmsHandler.MESSAGE_BODY_COLUMN); mMessageId = createMessageId(context, mTimestamp, mSubId); // TODO(b/167713264): Use the correct SMS source mSmsSource = InboundSmsHandler.SOURCE_NOT_INJECTED; } public ContentValues getContentValues() { Loading Loading @@ -497,4 +505,8 @@ public class InboundSmsTracker { public long getMessageId() { return mMessageId; } public @InboundSmsHandler.SmsSource int getSource() { return mSmsSource; } } Loading
proto/src/persist_atoms.proto +23 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ message PersistAtoms { /* Timestamp of last voice_call_sessions pull. */ optional int64 voice_call_session_pull_timestamp_millis = 4; /* Incoming SMS statistics and information. */ repeated IncomingSms incoming_sms = 5; /* Timestamp of last incoming_sms pull. */ optional int64 incoming_sms_pull_timestamp_millis = 6; } // The canonical versions of the following enums live in: Loading Loading @@ -82,3 +88,20 @@ message RawVoiceCallRatUsage { optional int64 total_duration_millis = 3; optional int64 call_count = 4; } message IncomingSms { optional int32 sms_format = 1; optional int32 sms_tech = 2; optional int32 rat = 3; optional int32 sms_type = 4; optional int32 total_parts = 5; optional int32 received_parts = 6; optional bool blocked = 7; optional int32 error = 8; optional bool is_roaming = 9; optional int32 sim_slot_index = 10; optional bool is_multi_sim = 11; optional bool is_esim = 12; optional int32 carrier_id = 13; optional int64 message_id = 14; }
src/java/com/android/internal/telephony/IccSmsInterfaceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -628,7 +628,7 @@ public class IccSmsInterfaceManager { "\n format=" + format + "\n receivedIntent=" + receivedIntent); } mDispatchersController.injectSmsPdu(pdu, format, mDispatchersController.injectSmsPdu(pdu, format, false /* isOverIms */, result -> { if (receivedIntent != null) { try { Loading
src/java/com/android/internal/telephony/ImsSmsDispatcher.java +1 −1 Original line number Diff line number Diff line Loading @@ -245,7 +245,7 @@ public class ImsSmsDispatcher extends SMSDispatcher { } catch (ImsException e) { loge("Failed to acknowledgeSms(). Error: " + e.getMessage()); } }, true); }, true /* ignoreClass */, true /* isOverIms */); } finally { Binder.restoreCallingIdentity(identity); } Loading
src/java/com/android/internal/telephony/InboundSmsHandler.java +67 −39 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_PDU; import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE; import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; import android.annotation.IntDef; import android.annotation.Nullable; import android.app.Activity; import android.app.AppOpsManager; Loading Loading @@ -80,6 +81,8 @@ import com.android.telephony.Rlog; import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; Loading Loading @@ -183,6 +186,24 @@ public abstract class InboundSmsHandler extends StateMachine { /** Wakelock release delay when returning to idle state. */ private static final int WAKELOCK_TIMEOUT = 3000; /** Received SMS was not injected. */ public static final int SOURCE_NOT_INJECTED = 0; /** Received SMS was received over IMS and injected. */ public static final int SOURCE_INJECTED_FROM_IMS = 1; /** Received SMS was injected from source different than IMS. */ public static final int SOURCE_INJECTED_FROM_UNKNOWN = 2; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SOURCE_"}, value = { SOURCE_NOT_INJECTED, SOURCE_INJECTED_FROM_IMS, SOURCE_INJECTED_FROM_UNKNOWN }) public @interface SmsSource {} // The notitfication tag used when showing a notification. The combination of notification tag // and notification id should be unique within the phone app. private static final String NOTIFICATION_TAG = "InboundSmsHandler"; Loading Loading @@ -255,10 +276,6 @@ public abstract class InboundSmsHandler extends StateMachine { /** Timeout for releasing wakelock */ private int mWakeLockTimeout; /** Indicates if last SMS was injected. This is used to recognize SMS received over IMS from others in order to update metrics. */ private boolean mLastSmsWasInjected = false; private List<SmsFilter> mSmsFilters; /** Loading Loading @@ -516,7 +533,7 @@ public abstract class InboundSmsHandler extends StateMachine { case EVENT_INJECT_SMS: // handle new injected SMS handleInjectSms((AsyncResult) msg.obj); handleInjectSms((AsyncResult) msg.obj, msg.arg1 == 1 /* isOverIms */); sendMessage(EVENT_RETURN_TO_IDLE); return HANDLED; Loading Loading @@ -641,8 +658,7 @@ public abstract class InboundSmsHandler extends StateMachine { int result; try { SmsMessage sms = (SmsMessage) ar.result; mLastSmsWasInjected = false; result = dispatchMessage(sms.mWrappedSmsMessage); result = dispatchMessage(sms.mWrappedSmsMessage, SOURCE_NOT_INJECTED); } catch (RuntimeException ex) { loge("Exception dispatching message", ex); result = RESULT_SMS_DISPATCH_FAILURE; Loading @@ -661,7 +677,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @param ar is the AsyncResult that has the SMS PDU to be injected. */ @UnsupportedAppUsage private void handleInjectSms(AsyncResult ar) { private void handleInjectSms(AsyncResult ar, boolean isOverIms) { int result; SmsDispatchersController.SmsInjectionCallback callback = null; try { Loading @@ -671,8 +687,9 @@ public abstract class InboundSmsHandler extends StateMachine { loge("Null injected sms"); result = RESULT_SMS_NULL_PDU; } else { mLastSmsWasInjected = true; result = dispatchMessage(sms.mWrappedSmsMessage); @SmsSource int smsSource = isOverIms ? SOURCE_INJECTED_FROM_IMS : SOURCE_INJECTED_FROM_UNKNOWN; result = dispatchMessage(sms.mWrappedSmsMessage, smsSource); } } catch (RuntimeException ex) { loge("Exception dispatching message", ex); Loading @@ -689,10 +706,11 @@ public abstract class InboundSmsHandler extends StateMachine { * 3GPP2-specific message types. * * @param smsb the SmsMessageBase object from the RIL * @param smsSource the source of the SMS message * @return a result code from {@link android.provider.Telephony.Sms.Intents}, * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC */ private int dispatchMessage(SmsMessageBase smsb) { private int dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource) { // If sms is null, there was a parsing error. if (smsb == null) { loge("dispatchSmsMessage: message is null"); Loading @@ -719,12 +737,13 @@ public abstract class InboundSmsHandler extends StateMachine { return Intents.RESULT_SMS_RECEIVED_WHILE_ENCRYPTED; } int result = dispatchMessageRadioSpecific(smsb); int result = dispatchMessageRadioSpecific(smsb, smsSource); // In case of error, add to metrics. This is not required in case of success, as the // data will be tracked when the message is processed (processMessagePart). if (result != Intents.RESULT_SMS_HANDLED) { mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), mLastSmsWasInjected, result); if (result != Intents.RESULT_SMS_HANDLED && result != Activity.RESULT_OK) { mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), smsSource, result); mPhone.getSmsStats().onIncomingSmsError(is3gpp2(), smsSource, result); } return result; } Loading @@ -735,10 +754,12 @@ public abstract class InboundSmsHandler extends StateMachine { * {@link #dispatchNormalMessage} from this class. * * @param smsb the SmsMessageBase object from the RIL * @param smsSource the source of the SMS message * @return a result code from {@link android.provider.Telephony.Sms.Intents}, * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC */ protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb); protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource); /** * Send an acknowledge message to the SMSC. Loading Loading @@ -782,10 +803,11 @@ public abstract class InboundSmsHandler extends StateMachine { * {@link #EVENT_BROADCAST_SMS}. Returns {@link Intents#RESULT_SMS_HANDLED} or an error value. * * @param sms the message to dispatch * @param smsSource the source of the SMS message * @return {@link Intents#RESULT_SMS_HANDLED} if the message was accepted, or an error status */ @UnsupportedAppUsage protected int dispatchNormalMessage(SmsMessageBase sms) { protected int dispatchNormalMessage(SmsMessageBase sms, @SmsSource int smsSource) { SmsHeader smsHeader = sms.getUserDataHeader(); InboundSmsTracker tracker; Loading @@ -803,7 +825,7 @@ public abstract class InboundSmsHandler extends StateMachine { sms.getTimestampMillis(), destPort, is3gpp2(), false, sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId()); mPhone.getSubId(), smsSource); } else { // Create a tracker for this message segment. SmsHeader.ConcatRef concatRef = smsHeader.concatRef; Loading @@ -812,10 +834,11 @@ public abstract class InboundSmsHandler extends StateMachine { tracker = TelephonyComponentFactory.getInstance() .inject(InboundSmsTracker.class.getName()) .makeInboundSmsTracker(mContext, sms.getPdu(), sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false, sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId()); sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false, sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId(), smsSource); } if (VDBG) log("created tracker: " + tracker); Loading Loading @@ -975,14 +998,7 @@ public abstract class InboundSmsHandler extends StateMachine { } final boolean isWapPush = (destPort == SmsHeader.PORT_WAP_PUSH); // At this point, all parts of the SMS are received. Update metrics for incoming SMS. // WAP-PUSH messages are handled below to also keep track of the result of the processing. String format = tracker.getFormat(); if (!isWapPush) { mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, block, tracker.getMessageId()); } // Do not process null pdu(s). Check for that and return false in that case. List<byte[]> pduList = Arrays.asList(pdus); Loading @@ -990,6 +1006,8 @@ public abstract class InboundSmsHandler extends StateMachine { String errorMsg = "processMessagePart: returning false due to " + (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)"); logeWithLocalLog(errorMsg, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsError( is3gpp2(), tracker.getSource(), RESULT_SMS_NULL_PDU); return false; } Loading @@ -1004,9 +1022,11 @@ public abstract class InboundSmsHandler extends StateMachine { } else { loge("processMessagePart: SmsMessage.createFromPdu returned null", tracker.getMessageId()); mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), SmsConstants.FORMAT_3GPP, timestamps, false, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount, RESULT_SMS_NULL_MESSAGE, tracker.getMessageId()); return false; } } Loading Loading @@ -1035,13 +1055,12 @@ public abstract class InboundSmsHandler extends StateMachine { } // Add result of WAP-PUSH into metrics. RESULT_SMS_HANDLED indicates that the WAP-PUSH // needs to be ignored, so treating it as a success case. if (result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED) { mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, true, tracker.getMessageId()); } else { mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, false, tracker.getMessageId()); } boolean wapPushResult = result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED; mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), format, timestamps, wapPushResult, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount, result, tracker.getMessageId()); // result is Activity.RESULT_OK if an ordered broadcast was sent if (result == Activity.RESULT_OK) { return true; Loading @@ -1054,6 +1073,15 @@ public abstract class InboundSmsHandler extends StateMachine { } } // All parts of SMS are received. Update metrics for incoming SMS. // The metrics are generated before SMS filters are invoked. // For messages composed by multiple parts, the metrics are generated considering the // characteristics of the last one. mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), tracker.getSource(), format, timestamps, block, tracker.getMessageId()); mPhone.getSmsStats().onIncomingSmsSuccess(is3gpp2(), tracker.getSource(), messageCount, block, tracker.getMessageId()); // Always invoke SMS filters, even if the number ends up being blocked, to prevent // surprising bugs due to blocking numbers that happen to be used for visual voicemail SMS // or other carrier system messages. Loading
src/java/com/android/internal/telephony/InboundSmsTracker.java +14 −2 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class InboundSmsTracker { private final boolean mIsClass0; private final int mSubId; private final long mMessageId; private final @InboundSmsHandler.SmsSource int mSmsSource; // Fields for concatenating multi-part SMS messages private final String mAddress; Loading Loading @@ -117,10 +118,12 @@ public class InboundSmsTracker { * @param address originating address * @param displayAddress email address if this message was from an email gateway, otherwise same * as originating address * @param smsSource the source of the SMS message */ public InboundSmsTracker(Context context, byte[] pdu, long timestamp, int destPort, boolean is3gpp2, boolean is3gpp2WapPdu, String address, String displayAddress, String messageBody, boolean isClass0, int subId) { String messageBody, boolean isClass0, int subId, @InboundSmsHandler.SmsSource int smsSource) { mPdu = pdu; mTimestamp = timestamp; mDestPort = destPort; Loading @@ -136,6 +139,7 @@ public class InboundSmsTracker { mMessageCount = 1; mSubId = subId; mMessageId = createMessageId(context, timestamp, subId); mSmsSource = smsSource; } /** Loading @@ -156,11 +160,12 @@ public class InboundSmsTracker { * @param sequenceNumber the sequence number of this segment (0-based) * @param messageCount the total number of segments * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise * @param smsSource the source of the SMS message */ public InboundSmsTracker(Context context, byte[] pdu, long timestamp, int destPort, boolean is3gpp2, String address, String displayAddress, int referenceNumber, int sequenceNumber, int messageCount, boolean is3gpp2WapPdu, String messageBody, boolean isClass0, int subId) { boolean isClass0, int subId, @InboundSmsHandler.SmsSource int smsSource) { mPdu = pdu; mTimestamp = timestamp; mDestPort = destPort; Loading @@ -177,6 +182,7 @@ public class InboundSmsTracker { mMessageCount = messageCount; mSubId = subId; mMessageId = createMessageId(context, timestamp, subId); mSmsSource = smsSource; } /** Loading Loading @@ -241,6 +247,8 @@ public class InboundSmsTracker { } mMessageBody = cursor.getString(InboundSmsHandler.MESSAGE_BODY_COLUMN); mMessageId = createMessageId(context, mTimestamp, mSubId); // TODO(b/167713264): Use the correct SMS source mSmsSource = InboundSmsHandler.SOURCE_NOT_INJECTED; } public ContentValues getContentValues() { Loading Loading @@ -497,4 +505,8 @@ public class InboundSmsTracker { public long getMessageId() { return mMessageId; } public @InboundSmsHandler.SmsSource int getSource() { return mSmsSource; } }