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

Commit e6a2e298 authored by Ramya Manoharan's avatar Ramya Manoharan
Browse files

Incrementing of TP - Message reference for every SMS sent.

Telephony will start managing TP MR, which includes incrementing and updating pdu. TPMR values will be persisted in telephony db.
Test: Sequential sms case for CS and IMS , UT
Bug: 228299168

Change-Id: I543b13d05a460c698d2f37c11bdd507c135b2493
parent 26001604
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -504,6 +504,7 @@ public class ImsSmsDispatcher extends SMSDispatcher {

    @VisibleForTesting
    public void fallbackToPstn(SmsTracker tracker) {
        tracker.mMessageRef = nextMessageRef();
        mSmsDispatchersController.sendRetrySms(tracker);
    }

+191 −83
Original line number Diff line number Diff line
@@ -28,11 +28,13 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -80,6 +82,7 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.cdma.sms.UserData;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
@@ -144,6 +147,12 @@ public abstract class SMSDispatcher extends Handler {
    protected static final int EVENT_ICC_CHANGED = 15;
    protected static final int EVENT_GET_IMS_SERVICE = 16;

    /** Last TP - Message Reference value update to SIM */
    private static final int EVENT_TPMR_SIM_UPDATE_RESPONSE = 17;

    /** Handle SIM loaded  */
    private static final int EVENT_SIM_LOADED = 18;

    @UnsupportedAppUsage
    protected Phone mPhone;
    @UnsupportedAppUsage
@@ -190,6 +199,9 @@ public abstract class SMSDispatcher extends Handler {
    @VisibleForTesting
    public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes

    /** Used for storing last TP - Message Reference used*/
    private int mMessageRef = -1;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    protected static int getNextConcatenatedRef() {
        sConcatenatedRef += 1;
@@ -215,10 +227,33 @@ public abstract class SMSDispatcher extends Handler {
                com.android.internal.R.bool.config_sms_capable);
        mSmsSendDisabled = !mTelephonyManager.getSmsSendCapableForPhone(
                mPhone.getPhoneId(), mSmsCapable);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
        Rlog.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
                + " mSmsSendDisabled=" + mSmsSendDisabled);
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, Intent intent) {
            Rlog.d(TAG, "Received broadcast " + intent.getAction());
            if (Intent.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
                if (!intent.hasExtra(Intent.EXTRA_SIM_STATE)) {
                    Rlog.d(TAG, "Extra not found in intent.");
                } else {
                    String simState = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
                    if (simState.equals(Intent.SIM_STATE_LOADED)) {
                        Rlog.d(TAG, "SIM_STATE_CHANGED : SIM_LOADED");
                        Message msg = obtainMessage(EVENT_SIM_LOADED);
                        msg.arg1 = getSubId();
                        sendMessage(msg);
                    }
                }
            }
        }
    };

    /**
     * Observe the secure setting for updated premium sms determination rules
     */
@@ -302,8 +337,7 @@ public abstract class SMSDispatcher extends Handler {
                handleConfirmShortCode(true, (SmsTracker[]) (msg.obj));
                break;

        case EVENT_SEND_CONFIRMED_SMS:
        {
            case EVENT_SEND_CONFIRMED_SMS: {
                SmsTracker[] trackers = (SmsTracker[]) msg.obj;
                for (SmsTracker tracker : trackers) {
                    sendSms(tracker);
@@ -312,8 +346,7 @@ public abstract class SMSDispatcher extends Handler {
                break;
            }

        case EVENT_SENDING_NOT_ALLOWED:
        {
            case EVENT_SENDING_NOT_ALLOWED: {
                SmsTracker[] trackers = (SmsTracker[]) msg.obj;
                Rlog.d(TAG, "SMSDispatcher: EVENT_SENDING_NOT_ALLOWED - "
                        + "sending SHORT_CODE_NEVER_ALLOWED error code.");
@@ -322,8 +355,7 @@ public abstract class SMSDispatcher extends Handler {
                break;
            }

        case EVENT_STOP_SENDING:
        {
            case EVENT_STOP_SENDING: {
                SmsTracker[] trackers = (SmsTracker[]) msg.obj;
                int error;
                if (msg.arg1 == ConfirmDialogListener.SHORT_CODE_MSG) {
@@ -353,12 +385,83 @@ public abstract class SMSDispatcher extends Handler {
            case EVENT_NEW_SMS_STATUS_REPORT:
                handleStatusReport(msg.obj);
                break;
            case EVENT_TPMR_SIM_UPDATE_RESPONSE:
                handleMessageRefStatus(msg);
                break;

            case EVENT_SIM_LOADED:
                /* sim TPMR value is given higher priority if both are non-negative number.
                   Use case:
                   if sim was used on another device and inserted in a new device,
                   that device will start sending the next TPMR after reading from the SIM.
                 */
                mMessageRef = getTpmrValueFromSIM();
                if (mMessageRef == -1) {
                    mMessageRef = SubscriptionController.getInstance().getMessageRef(msg.arg1);
                }
                break;

            default:
                Rlog.e(TAG, "handleMessage() ignoring message of unexpected type " + msg.what);
        }
    }

    private void handleMessageRefStatus(Message msg) {
        AsyncResult ar = (AsyncResult) msg.obj;
        if (ar.exception != null) {
            Rlog.e(TAG, "Failed to update TP - Message reference value to SIM " + ar.exception);
        } else {
            Rlog.d(TAG, "TP - Message reference updated to SIM Successfully");
        }
    }

    private void updateTPMessageReference() {
        updateSIMLastTPMRValue(mMessageRef);
        final long identity = Binder.clearCallingIdentity();
        try {
            SubscriptionController.getInstance().updateMessageRef(getSubId(), mMessageRef);
        } catch (SecurityException e) {
            Rlog.e(TAG, "Security Exception caused on messageRef updation to DB " + e.getMessage());
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void updateSIMLastTPMRValue(int messageRef) {
        Message msg = obtainMessage(EVENT_TPMR_SIM_UPDATE_RESPONSE);
        IccRecords iccRecords = getIccRecords();
        if (iccRecords != null) {
            iccRecords.setSmssTpmrValue(messageRef, msg);
        }
    }

    private int getTpmrValueFromSIM() {
        IccRecords iccRecords = getIccRecords();
        if (iccRecords != null) {
            return iccRecords.getSmssTpmrValue();
        }
        return -1;
    }

    private IccRecords getIccRecords() {
        if (mPhone != null && mPhone.getIccRecords() != null) {
            return mPhone.getIccRecords();
        }
        return null;
    }

    /**
     *  Returns the next TP message Reference value incremented by 1 for every sms sent .
     *  once a max of 255 is reached TP message Reference is reset to 0.
     *
     *  @return messageRef TP message Reference value
     */
    public int nextMessageRef() {
        mMessageRef = (mMessageRef + 1) % 256;
        updateTPMessageReference();
        return mMessageRef;
    }

    /**
     * Use the carrier messaging service to send a data or text SMS.
     */
@@ -1133,14 +1236,15 @@ public abstract class SMSDispatcher extends Handler {
    @UnsupportedAppUsage
    protected void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm) {
        int messageRef = nextMessageRef();
        SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
                scAddr, destAddr, destPort, data, (deliveryIntent != null));
                scAddr, destAddr, destPort, data, (deliveryIntent != null), messageRef);
        if (pdu != null) {
            HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu);
            SmsTracker tracker = getSmsTracker(callingPackage, map, sentIntent, deliveryIntent,
                    getFormat(), null /*messageUri*/, false /*expectMore*/,
                    null /*fullMessageText*/, false /*isText*/,
                    true /*persistMessage*/, isForVvm, 0L /* messageId */);
                    true /*persistMessage*/, isForVvm, 0L /* messageId */, messageRef);

            if (!sendSmsByCarrierApp(true /* isDataSms */, tracker)) {
                sendSubmitPdu(tracker);
@@ -1257,13 +1361,15 @@ public abstract class SMSDispatcher extends Handler {
                         boolean expectMore, int validityPeriod, boolean isForVvm,
                         long messageId) {
        Rlog.d(TAG, "sendText id: " + SmsController.formatCrossStackMessageId(messageId));
        int messageRef = nextMessageRef();
        SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
                scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod);
                scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod,
                messageRef);
        if (pdu != null) {
            HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu);
            SmsTracker tracker = getSmsTracker(callingPkg, map, sentIntent, deliveryIntent,
                    getFormat(), messageUri, expectMore, text, true /*isText*/,
                    persistMessage, priority, validityPeriod, isForVvm, messageId);
                    persistMessage, priority, validityPeriod, isForVvm, messageId, messageRef);

            if (!sendSmsByCarrierApp(false /* isDataSms */, tracker)) {
                sendSubmitPdu(tracker);
@@ -1502,12 +1608,13 @@ public abstract class SMSDispatcher extends Handler {
            if (deliveryIntents != null && deliveryIntents.size() > i) {
                deliveryIntent = deliveryIntents.get(i);
            }

            int messageRef = nextMessageRef();
            trackers[i] =
                getNewSubmitPduTracker(callingPkg, destAddr, scAddr, parts.get(i), smsHeader,
                        encoding, sentIntent, deliveryIntent, (i == (msgCount - 1)),
                        unsentPartCount, anyPartFailed, messageUri,
                        fullMessageText, priority, expectMore, validityPeriod, messageId);
                        fullMessageText, priority, expectMore, validityPeriod, messageId,
                        messageRef);
            if (trackers[i] == null) {
                triggerSentIntentForFailure(sentIntents);
                return;
@@ -1545,7 +1652,7 @@ public abstract class SMSDispatcher extends Handler {
            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart,
            AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
            String fullMessageText, int priority, boolean expectMore, int validityPeriod,
            long messageId) {
            long messageId, int messageRef) {
        if (isCdmaMo()) {
            UserData uData = new UserData();
            uData.payloadStr = message;
@@ -1575,7 +1682,7 @@ public abstract class SMSDispatcher extends Handler {
                        getFormat(), unsentPartCount, anyPartFailed, messageUri, smsHeader,
                        (!lastPart || expectMore), fullMessageText, true /*isText*/,
                        true /*persistMessage*/, priority, validityPeriod, false /* isForVvm */,
                        messageId);
                        messageId, messageRef);
            } else {
                Rlog.e(TAG, "CdmaSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
                        + "null " + SmsController.formatCrossStackMessageId(messageId));
@@ -1586,7 +1693,7 @@ public abstract class SMSDispatcher extends Handler {
                    com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
                            destinationAddress, message, deliveryIntent != null,
                            SmsHeader.toByteArray(smsHeader), encoding, smsHeader.languageTable,
                            smsHeader.languageShiftTable, validityPeriod);
                            smsHeader.languageShiftTable, validityPeriod, messageRef);
            if (pdu != null) {
                HashMap map =  getSmsTrackerMap(destinationAddress, scAddress,
                        message, pdu);
@@ -1594,7 +1701,7 @@ public abstract class SMSDispatcher extends Handler {
                        deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri,
                        smsHeader, (!lastPart || expectMore), fullMessageText, true /*isText*/,
                        false /*persistMessage*/, priority, validityPeriod, false /* isForVvm */,
                        messageId);
                        messageId, messageRef);
            } else {
                Rlog.e(TAG, "GsmSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
                        + "null " + SmsController.formatCrossStackMessageId(messageId));
@@ -2099,7 +2206,8 @@ public abstract class SMSDispatcher extends Handler {
                AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
                SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId,
                boolean isText, boolean persistMessage, int userId, int priority,
                int validityPeriod, boolean isForVvm, long messageId, int carrierId) {
                int validityPeriod, boolean isForVvm, long messageId, int carrierId,
                int messageRef) {
            mData = data;
            mSentIntent = sentIntent;
            mDeliveryIntent = deliveryIntent;
@@ -2110,7 +2218,7 @@ public abstract class SMSDispatcher extends Handler {
            mExpectMore = expectMore;
            mImsRetry = 0;
            mUsesImsServiceForIms = false;
            mMessageRef = 0;
            mMessageRef = messageRef;
            mUnsentPartCount = unsentPartCount;
            mAnyPartFailed = anyPartFailed;
            mMessageUri = messageUri;
@@ -2392,7 +2500,7 @@ public abstract class SMSDispatcher extends Handler {
            AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
            SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText,
            boolean persistMessage, int priority, int validityPeriod, boolean isForVvm,
            long messageId) {
            long messageId, int messageRef) {
        // Get package info via packagemanager
        UserHandle callingUser = UserHandle.getUserHandleForUid(Binder.getCallingUid());
        final int userId = callingUser.getIdentifier();
@@ -2409,28 +2517,28 @@ public abstract class SMSDispatcher extends Handler {
        return new SmsTracker(data, sentIntent, deliveryIntent, appInfo, destAddr, format,
                unsentPartCount, anyPartFailed, messageUri, smsHeader, expectMore,
                fullMessageText, getSubId(), isText, persistMessage, userId, priority,
                validityPeriod, isForVvm, messageId, mPhone.getCarrierId());
                validityPeriod, isForVvm, messageId, mPhone.getCarrierId(), messageRef);
    }

    protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
            PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri,
            boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage,
            boolean isForVvm, long messageId) {
            boolean isForVvm, long messageId, int messageRef) {
        return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format,
                null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
                expectMore, fullMessageText, isText, persistMessage,
                SMS_MESSAGE_PRIORITY_NOT_SPECIFIED, SMS_MESSAGE_PERIOD_NOT_SPECIFIED, isForVvm,
                messageId);
                messageId, messageRef);
    }

    protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
            PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri,
            boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage,
            int priority, int validityPeriod, boolean isForVvm, long messageId) {
            int priority, int validityPeriod, boolean isForVvm, long messageId, int messageRef) {
        return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format,
                null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
                expectMore, fullMessageText, isText, persistMessage, priority, validityPeriod,
                isForVvm, messageId);
                isForVvm, messageId, messageRef);
    }

    protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
+3 −2
Original line number Diff line number Diff line
@@ -503,7 +503,8 @@ public class SmsDispatchersController extends Handler {
                            scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
                } else {
                    pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
                            scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
                            scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null,
                            0, 0, 0, -1, tracker.mMessageRef);
                }
            } else if (map.containsKey("data")) {
                byte[] data = (byte[]) map.get("data");
@@ -518,7 +519,7 @@ public class SmsDispatchersController extends Handler {
                } else {
                    pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
                            scAddr, destAddr, destPort.intValue(), data,
                            (tracker.mDeliveryIntent != null));
                            (tracker.mDeliveryIntent != null), tracker.mMessageRef);
                }
            }

+57 −0
Original line number Diff line number Diff line
@@ -4740,6 +4740,63 @@ public class SubscriptionController extends ISub.Stub {
        return ret;
    }

    /**
     * Querying last used TP - MessageRef for particular subId from SIMInfo table.
     * @return messageRef
     */
    public int getMessageRef(int subId) {
        try (Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
                new String[]{SubscriptionManager.TP_MESSAGE_REF},
                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=\"" + subId
                        + "\"", null, null)) {
            try {
                if (cursor != null && cursor.moveToFirst()) {
                    do {
                        return cursor.getInt(cursor.getColumnIndexOrThrow(
                                SubscriptionManager.TP_MESSAGE_REF));
                    } while (cursor.moveToNext());
                } else {
                    if (DBG) logd("Valid row not present in db");
                }
            } catch (Exception e) {
                if (DBG) logd("Query failed " + e.getMessage());
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
        return -1;
    }

    /**
     * Update the TP - Message Reference value for every SMS Sent
     * @param messageRef
     * @param subId
     */
    public void updateMessageRef(int subId, int messageRef) {
        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                mContext, subId, mContext.getOpPackageName());

        if (mContext == null) {
            logel("[updateMessageRef] mContext is null");
            return;
        }
        try {
            if (SubscriptionManager.CONTENT_URI != null) {
                ContentValues values = new ContentValues(1);
                values.put(SubscriptionManager.TP_MESSAGE_REF, messageRef);
                mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, values,
                        SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=\"" + subId
                                + "\"", null);
            } else {
                if (DBG) logd("TP - Message reference value not updated to DB");
            }
        } finally {
            if (DBG) logd("TP - Message reference updated to DB Successfully :" + messageRef);
        }
    }

    /**
     * @hide
     */
+2 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ public class FakeTelephonyProvider extends MockContentProvider {
                    + Telephony.SimInfo.COLUMN_PORT_INDEX + " INTEGER DEFAULT -1,"
                    + Telephony.SimInfo.COLUMN_USAGE_SETTING + " INTEGER DEFAULT "
                            + SubscriptionManager.USAGE_SETTING_UNKNOWN
                    + "," + Telephony.SimInfo.COLUMN_TP_MESSAGE_REF
                    + "  INTEGER DEFAULT -1"
                    + ");";
        }

Loading