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

Commit 2579058d authored by Chi Zhang's avatar Chi Zhang Committed by Automerger Merge Worker
Browse files

Merge "Add support for new SMS metrics" am: 1559e86f am: b0436adb

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1544666

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ice560ba6d118a3a5a005734e128902556adc8068
parents 09b9f04b b0436adb
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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:
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+1 −1
Original line number Diff line number Diff line
@@ -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);
            }
+67 −39
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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";
@@ -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;

    /**
@@ -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;

@@ -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;
@@ -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 {
@@ -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);
@@ -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");
@@ -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;
    }
@@ -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.
@@ -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;

@@ -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;
@@ -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);
@@ -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);
@@ -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;
        }

@@ -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;
                    }
                }
@@ -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;
@@ -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.
+14 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -136,6 +139,7 @@ public class InboundSmsTracker {
        mMessageCount = 1;
        mSubId = subId;
        mMessageId = createMessageId(context, timestamp, subId);
        mSmsSource = smsSource;
    }

    /**
@@ -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;
@@ -177,6 +182,7 @@ public class InboundSmsTracker {
        mMessageCount = messageCount;
        mSubId = subId;
        mMessageId = createMessageId(context, timestamp, subId);
        mSmsSource = smsSource;
    }

    /**
@@ -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() {
@@ -497,4 +505,8 @@ public class InboundSmsTracker {
    public long getMessageId() {
        return mMessageId;
    }

    public @InboundSmsHandler.SmsSource int getSource() {
        return mSmsSource;
    }
}
Loading