FileDocCategorySizeDatePackage
InboundSmsTracker.javaAPI DocAndroid 5.1 API11024Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony

InboundSmsTracker

public final class InboundSmsTracker extends Object
Tracker for an incoming SMS message ready to broadcast to listeners. This is similar to {@link com.android.internal.telephony.SMSDispatcher.SmsTracker} used for outgoing messages.

Fields Summary
private final byte[]
mPdu
private final long
mTimestamp
private final int
mDestPort
private final boolean
mIs3gpp2
private final boolean
mIs3gpp2WapPdu
private final String
mAddress
private final int
mReferenceNumber
private final int
mSequenceNumber
private final int
mMessageCount
private String
mDeleteWhere
private String[]
mDeleteWhereArgs
private static final int
DEST_PORT_FLAG_NO_PORT
Destination port flag bit for no destination port.
private static final int
DEST_PORT_FLAG_3GPP
Destination port flag bit to indicate 3GPP format message.
private static final int
DEST_PORT_FLAG_3GPP2
Destination port flag bit to indicate 3GPP2 format message.
private static final int
DEST_PORT_FLAG_3GPP2_WAP_PDU
Destination port flag bit to indicate 3GPP2 format WAP message.
private static final int
DEST_PORT_MASK
Destination port mask (16-bit unsigned value on GSM and CDMA).
Constructors Summary
InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2, boolean is3gpp2WapPdu)
Create a tracker for a single-part SMS.

param
pdu the message PDU
param
timestamp the message timestamp
param
destPort the destination port
param
is3gpp2 true for 3GPP2 format; false for 3GPP format
param
is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise


                                                   
           
              
        mPdu = pdu;
        mTimestamp = timestamp;
        mDestPort = destPort;
        mIs3gpp2 = is3gpp2;
        mIs3gpp2WapPdu = is3gpp2WapPdu;
        // fields for multi-part SMS
        mAddress = null;
        mReferenceNumber = -1;
        mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
        mMessageCount = 1;
    
public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2, String address, int referenceNumber, int sequenceNumber, int messageCount, boolean is3gpp2WapPdu)
Create a tracker for a multi-part SMS. Sequence numbers start at 1 for 3GPP and regular concatenated 3GPP2 messages, but CDMA WAP push sequence numbers start at 0. The caller will subtract 1 if necessary so that the sequence number is always 0-based. When loading and saving to the raw table, the sequence number is adjusted if necessary for backwards compatibility.

param
pdu the message PDU
param
timestamp the message timestamp
param
destPort the destination port
param
is3gpp2 true for 3GPP2 format; false for 3GPP format
param
address the originating address
param
referenceNumber the concatenated reference number
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

        mPdu = pdu;
        mTimestamp = timestamp;
        mDestPort = destPort;
        mIs3gpp2 = is3gpp2;
        mIs3gpp2WapPdu = is3gpp2WapPdu;
        // fields for multi-part SMS
        mAddress = address;
        mReferenceNumber = referenceNumber;
        mSequenceNumber = sequenceNumber;
        mMessageCount = messageCount;
    
InboundSmsTracker(android.database.Cursor cursor, boolean isCurrentFormat3gpp2)
Create a new tracker from the row of the raw table pointed to by Cursor. Since this constructor is used only for recovery during startup, the Dispatcher is null.

param
cursor a Cursor pointing to the row to construct this SmsTracker for

        mPdu = HexDump.hexStringToByteArray(cursor.getString(InboundSmsHandler.PDU_COLUMN));

        if (cursor.isNull(InboundSmsHandler.DESTINATION_PORT_COLUMN)) {
            mDestPort = -1;
            mIs3gpp2 = isCurrentFormat3gpp2;
            mIs3gpp2WapPdu = false;
        } else {
            int destPort = cursor.getInt(InboundSmsHandler.DESTINATION_PORT_COLUMN);
            if ((destPort & DEST_PORT_FLAG_3GPP) != 0) {
                mIs3gpp2 = false;
            } else if ((destPort & DEST_PORT_FLAG_3GPP2) != 0) {
                mIs3gpp2 = true;
            } else {
                mIs3gpp2 = isCurrentFormat3gpp2;
            }
            mIs3gpp2WapPdu = ((destPort & DEST_PORT_FLAG_3GPP2_WAP_PDU) != 0);
            mDestPort = getRealDestPort(destPort);
        }

        mTimestamp = cursor.getLong(InboundSmsHandler.DATE_COLUMN);

        if (cursor.isNull(InboundSmsHandler.COUNT_COLUMN)) {
            // single-part message
            long rowId = cursor.getLong(InboundSmsHandler.ID_COLUMN);
            mAddress = null;
            mReferenceNumber = -1;
            mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
            mMessageCount = 1;
            mDeleteWhere = InboundSmsHandler.SELECT_BY_ID;
            mDeleteWhereArgs = new String[]{Long.toString(rowId)};
        } else {
            // multi-part message
            mAddress = cursor.getString(InboundSmsHandler.ADDRESS_COLUMN);
            mReferenceNumber = cursor.getInt(InboundSmsHandler.REFERENCE_NUMBER_COLUMN);
            mMessageCount = cursor.getInt(InboundSmsHandler.COUNT_COLUMN);

            // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
            mSequenceNumber = cursor.getInt(InboundSmsHandler.SEQUENCE_COLUMN);
            int index = mSequenceNumber - getIndexOffset();

            if (index < 0 || index >= mMessageCount) {
                throw new IllegalArgumentException("invalid PDU sequence " + mSequenceNumber
                        + " of " + mMessageCount);
            }

            mDeleteWhere = InboundSmsHandler.SELECT_BY_REFERENCE;
            mDeleteWhereArgs = new String[]{mAddress,
                    Integer.toString(mReferenceNumber), Integer.toString(mMessageCount)};
        }
    
Methods Summary
java.lang.StringgetAddress()

        return mAddress;
    
android.content.ContentValuesgetContentValues()

        ContentValues values = new ContentValues();
        values.put("pdu", HexDump.toHexString(mPdu));
        values.put("date", mTimestamp);
        // Always set the destination port, since it now contains message format flags.
        // Port is a 16-bit value, or -1, so clear the upper bits before setting flags.
        int destPort;
        if (mDestPort == -1) {
            destPort = DEST_PORT_FLAG_NO_PORT;
        } else {
            destPort = mDestPort & DEST_PORT_MASK;
        }
        if (mIs3gpp2) {
            destPort |= DEST_PORT_FLAG_3GPP2;
        } else {
            destPort |= DEST_PORT_FLAG_3GPP;
        }
        if (mIs3gpp2WapPdu) {
            destPort |= DEST_PORT_FLAG_3GPP2_WAP_PDU;
        }
        values.put("destination_port", destPort);
        if (mAddress != null) {
            values.put("address", mAddress);
            values.put("reference_number", mReferenceNumber);
            values.put("sequence", mSequenceNumber);
            values.put("count", mMessageCount);
        }
        return values;
    
java.lang.StringgetDeleteWhere()

        return mDeleteWhere;
    
java.lang.String[]getDeleteWhereArgs()

        return mDeleteWhereArgs;
    
intgetDestPort()

        return mDestPort;
    
java.lang.StringgetFormat()

        return mIs3gpp2 ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP;
    
intgetIndexOffset()
Sequence numbers for concatenated messages start at 1. The exception is CDMA WAP PDU messages, which use a 0-based index.

return
the offset to use to convert between mIndex and the sequence number

        return (mIs3gpp2 && mIs3gpp2WapPdu) ? 0 : 1;
    
intgetMessageCount()

        return mMessageCount;
    
byte[]getPdu()

        return mPdu;
    
static intgetRealDestPort(int destPort)
Get the port number, or -1 if there is no destination port.

param
destPort the destination port value, with flags
return
the real destination port, or -1 for no port

        if ((destPort & DEST_PORT_FLAG_NO_PORT) != 0) {
            return -1;
        } else {
           return destPort & DEST_PORT_MASK;
        }
    
intgetReferenceNumber()

        return mReferenceNumber;
    
intgetSequenceNumber()

        return mSequenceNumber;
    
longgetTimestamp()

        return mTimestamp;
    
booleanis3gpp2()

        return mIs3gpp2;
    
voidsetDeleteWhere(java.lang.String deleteWhere, java.lang.String[] deleteWhereArgs)
Update the values to delete all rows of the message from raw table.

param
deleteWhere the selection to use
param
deleteWhereArgs the selection args to use

        mDeleteWhere = deleteWhere;
        mDeleteWhereArgs = deleteWhereArgs;
    
public java.lang.StringtoString()

        StringBuilder builder = new StringBuilder("SmsTracker{timestamp=");
        builder.append(new Date(mTimestamp));
        builder.append(" destPort=").append(mDestPort);
        builder.append(" is3gpp2=").append(mIs3gpp2);
        if (mAddress != null) {
            builder.append(" address=").append(mAddress);
            builder.append(" refNumber=").append(mReferenceNumber);
            builder.append(" seqNumber=").append(mSequenceNumber);
            builder.append(" msgCount=").append(mMessageCount);
        }
        if (mDeleteWhere != null) {
            builder.append(" deleteWhere(").append(mDeleteWhere);
            builder.append(") deleteArgs=(").append(Arrays.toString(mDeleteWhereArgs));
            builder.append(')");
        }
        builder.append('}");
        return builder.toString();