Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 752c49fe authored by Michele's avatar Michele
Browse files

Enhance metrics for incoming SMS

Add ability to detect dropped multi-part SMS messages due to missing part.
Add ability to combine together into a single SMS session all the SMS messages that are part of a single multipart SMS.
Add ability to track various SMS types (voicemail indicator, SMS-PP,
type 0)
Add ability to track errors decoding WAP-PUSH messages.

Bug: 75387685
Test: Tested on device, receiving short SMS.
Test: Tested on device, receiving concatenated SMS
Test: Tested on device, dropping part of concatenated SMS
Test: Tested on device, receiving MMS (WAP-PUSH message)
Change-Id: I0ed89d728e1a32c576d71c5809c618ee0f3a1508
parent 6f5e3637
Loading
Loading
Loading
Loading
+47 −6
Original line number Diff line number Diff line
@@ -1389,6 +1389,9 @@ message SmsSession {

      // CB message received
      CB_SMS_RECEIVED = 9;

      // Incomplete multipart message received
      INCOMPLETE_SMS_RECEIVED = 10;
    }

    // Formats used to encode SMS messages
@@ -1465,6 +1468,33 @@ message SmsSession {
      EMERGENCY = 4;
    }

    // Types of SMS messages
    enum SmsType {

      // Normal type
      SMS_TYPE_NORMAL = 0;

      // SMS-PP.
      SMS_TYPE_SMS_PP = 1;

      // Voicemail indication
      SMS_TYPE_VOICEMAIL_INDICATION = 2;

      // Type 0 message (3GPP TS 23.040 9.2.3.9)
      SMS_TYPE_ZERO = 3;

      // WAP-PUSH message
      SMS_TYPE_WAP_PUSH = 4;
    }

    message IncompleteSms {
      // Number of received parts
      optional int32 received_parts = 1;

      // Number of expected parts
      optional int32 total_parts = 2;
    }

    // Event type
    optional Type type = 1;

@@ -1492,24 +1522,35 @@ message SmsSession {
    // Technology used to send/receive SMS
    optional Tech tech = 9;

    // See 3GPP 27.005, 3.2.5 for GSM/UMTS,
    // 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA,
    // Will map to a SmsManager.RESULT_* code if ims_error is populated
    // For outgoing SMS:
    //  - See 3GPP 27.005, 3.2.5 for GSM/UMTS,
    //  - 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA,
    // For incoming SMS of any type:
    //  - it is mapped to a SmsManager.RESULT_* code
    // SmsManager can be accessed from
    // frameworks/base/telephony/java/android/telephony/SmsManager.java
    optional int32 error_code = 10;

    // RIL error code
    // RIL error code - Not used.
    optional RilErrno error = 11;

    // Numeric ID
    // Numeric ID - Used only for outgoing SMS
    optional int32 ril_request_id = 12;

    // Cellbroadcast message content
    optional CBMessage cell_broadcast_message = 13;

    // ImsService error code.
    // ImsService error code. Used only for outgoing SMS
    optional ImsServiceErrno ims_error = 14;

    // Details of incoming incomplete multipart SMS
    optional IncompleteSms incomplete_sms = 15;

    // Indicate the type of incoming SMS
    optional SmsType sms_type = 16;

    // Indicates if the incoming SMS was blocked
    optional bool blocked = 17;
  }

  // Time when session has started, in minutes since epoch,
+0 −3
Original line number Diff line number Diff line
@@ -199,11 +199,8 @@ public class ImsSmsDispatcher extends SMSDispatcher {
                        Rlog.w(TAG, "SMS Received with a PDU that could not be parsed.");
                        getImsManager().acknowledgeSms(token, 0, mappedResult);
                    }
                    mMetrics.writeImsServiceNewSms(mPhone.getPhoneId(), format, mappedResult);
                } catch (ImsException e) {
                    Rlog.e(TAG, "Failed to acknowledgeSms(). Error: " + e.getMessage());
                    mMetrics.writeImsServiceNewSms(mPhone.getPhoneId(), format,
                            ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
                }
            }, true);
        }
+48 −4
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.util.Pair;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.util.NotificationChannelController;
import com.android.internal.util.HexDump;
import com.android.internal.util.State;
@@ -120,7 +121,8 @@ public abstract class InboundSmsHandler extends StateMachine {
            "pdu",
            "sequence",
            "destination_port",
            "display_originating_addr"
            "display_originating_addr",
            "date"
    };

    /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
@@ -130,6 +132,7 @@ public abstract class InboundSmsHandler extends StateMachine {
                put(SEQUENCE_COLUMN, 1);
                put(DESTINATION_PORT_COLUMN, 2);
                put(DISPLAY_ADDRESS_COLUMN, 3);
                put(DATE_COLUMN, 4);
    }};

    public static final int PDU_COLUMN = 0;
@@ -218,6 +221,8 @@ public abstract class InboundSmsHandler extends StateMachine {

    private UserManager mUserManager;

    protected TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();

    private LocalLog mLocalLog = new LocalLog(64);

    IDeviceIdleController mDeviceIdleController;
@@ -233,6 +238,10 @@ 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;

    /**
     * Create a new SMS broadcast helper.
     * @param name the class name for logging
@@ -572,6 +581,7 @@ public abstract class InboundSmsHandler extends StateMachine {
        int result;
        try {
            SmsMessage sms = (SmsMessage) ar.result;
            mLastSmsWasInjected = false;
            result = dispatchMessage(sms.mWrappedSmsMessage);
        } catch (RuntimeException ex) {
            loge("Exception dispatching message", ex);
@@ -599,6 +609,7 @@ public abstract class InboundSmsHandler extends StateMachine {
            if (sms == null) {
                result = Intents.RESULT_SMS_GENERIC_ERROR;
            } else {
                mLastSmsWasInjected = true;
                result = dispatchMessage(sms.mWrappedSmsMessage);
            }
        } catch (RuntimeException ex) {
@@ -646,7 +657,14 @@ public abstract class InboundSmsHandler extends StateMachine {
            return Intents.RESULT_SMS_GENERIC_ERROR;
        }

        return dispatchMessageRadioSpecific(smsb);
        int result = dispatchMessageRadioSpecific(smsb);

        // 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);
        }
        return result;
    }

    /**
@@ -776,6 +794,7 @@ public abstract class InboundSmsHandler extends StateMachine {
    private boolean processMessagePart(InboundSmsTracker tracker) {
        int messageCount = tracker.getMessageCount();
        byte[][] pdus;
        long[] timestamps;
        int destPort = tracker.getDestPort();
        boolean block = false;
        String address = tracker.getAddress();
@@ -790,6 +809,7 @@ public abstract class InboundSmsHandler extends StateMachine {
        if (messageCount == 1) {
            // single-part message
            pdus = new byte[][]{tracker.getPdu()};
            timestamps = new long[]{tracker.getTimestamp()};
            block = BlockChecker.isBlocked(mContext, tracker.getDisplayAddress(), null);
        } else {
            // multi-part message
@@ -816,6 +836,7 @@ public abstract class InboundSmsHandler extends StateMachine {

                // All the parts are in place, deal with them
                pdus = new byte[messageCount][];
                timestamps = new long[messageCount];
                while (cursor.moveToNext()) {
                    // subtract offset to convert sequence to 0-based array index
                    int index = cursor.getInt(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING
@@ -847,6 +868,10 @@ public abstract class InboundSmsHandler extends StateMachine {
                            destPort = port;
                        }
                    }

                    timestamps[index] = cursor.getLong(
                            PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DATE_COLUMN));

                    // check if display address should be blocked or not
                    if (!block) {
                        // Depending on the nature of the gateway, the display origination address
@@ -870,6 +895,14 @@ public abstract class InboundSmsHandler extends StateMachine {
            }
        }

        // 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.is3gpp2() ? SmsConstants.FORMAT_3GPP : SmsConstants.FORMAT_3GPP2);
        if (destPort != SmsHeader.PORT_WAP_PUSH) {
            mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), mLastSmsWasInjected,
                    format, timestamps, block);
        }

        // Do not process null pdu(s). Check for that and return false in that case.
        List<byte[]> pduList = Arrays.asList(pdus);
        if (pduList.size() == 0 || pduList.contains(null)) {
@@ -897,6 +930,8 @@ public abstract class InboundSmsHandler extends StateMachine {
                        pdu = msg.getUserData();
                    } else {
                        loge("processMessagePart: SmsMessage.createFromPdu returned null");
                        mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected,
                                format, timestamps, false);
                        return false;
                    }
                }
@@ -905,6 +940,15 @@ public abstract class InboundSmsHandler extends StateMachine {
            int result = mWapPush.dispatchWapPdu(output.toByteArray(), resultReceiver,
                    this, address);
            if (DBG) log("dispatchWapPdu() returned " + result);
            // 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);
            } else {
                mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected,
                        format, timestamps, false);
            }
            // result is Activity.RESULT_OK if an ordered broadcast was sent
            if (result == Activity.RESULT_OK) {
                return true;
+0 −4
Original line number Diff line number Diff line
@@ -4775,10 +4775,6 @@ public class RIL extends BaseCommands implements CommandsInterface {
        return s;
    }

    void writeMetricsNewSms(int tech, int format) {
        mMetrics.writeRilNewSms(mPhoneId, tech, format);
    }

    void writeMetricsCallRing(char[] response) {
        mMetrics.writeRilCallRing(mPhoneId, response);
    }
+0 −7
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ import com.android.internal.telephony.cdma.SmsMessageConverter;
import com.android.internal.telephony.dataconnection.KeepaliveStatus;
import com.android.internal.telephony.gsm.SsData;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
import com.android.internal.telephony.uicc.IccRefreshResponse;
import com.android.internal.telephony.uicc.IccUtils;

@@ -160,9 +159,6 @@ public class RadioIndication extends IRadioIndication.Stub {
        byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);

        mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_GSM,
                SmsSession.Event.Format.SMS_FORMAT_3GPP);

        SmsMessage sms = SmsMessage.newFromCMT(pduArray);
        if (mRil.mGsmSmsRegistrant != null) {
            mRil.mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
@@ -438,9 +434,6 @@ public class RadioIndication extends IRadioIndication.Stub {

        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);

        mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_CDMA,
                SmsSession.Event.Format.SMS_FORMAT_3GPP2);

        // todo: conversion from CdmaSmsMessage to SmsMessage should be contained in this class so
        // that usage of auto-generated HAL classes is limited to this file
        SmsMessage sms = SmsMessageConverter.newSmsMessageFromCdmaSmsMessage(msg);
Loading