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

Commit 23f52ee1 authored by Mohamed Abdalkader's avatar Mohamed Abdalkader Committed by android-build-merger
Browse files

Implement ImsSmsDispatcher

am: d68e767b

Change-Id: I8530845966f35a018e3783429709bb66dd5f9929
parents ab8365b2 d68e767b
Loading
Loading
Loading
Loading
+11 −1
Original line number Original line Diff line number Diff line
@@ -473,7 +473,17 @@ public class IccSmsInterfaceManager {
                "\n format=" + format +
                "\n format=" + format +
                "\n receivedIntent=" + receivedIntent);
                "\n receivedIntent=" + receivedIntent);
        }
        }
        mDispatchersController.injectSmsPdu(pdu, format, receivedIntent);
        mDispatchersController.injectSmsPdu(pdu, format,
                result -> {
                    if (receivedIntent != null) {
                        try {
                            receivedIntent.send(result);
                        } catch (PendingIntent.CanceledException e) {
                            Rlog.d(LOG_TAG, "receivedIntent cancelled.");
                        }
                    }
                }
        );
    }
    }


    /**
    /**
+164 −6
Original line number Original line Diff line number Diff line
@@ -16,25 +16,134 @@


package com.android.internal.telephony;
package com.android.internal.telephony;


import android.app.Activity;
import android.os.RemoteException;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.provider.Telephony.Sms;
import android.content.Intent;
import android.telephony.Rlog;

import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.ims.internal.IImsSmsListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.util.SMSDispatcherUtil;
import com.android.internal.telephony.util.SMSDispatcherUtil;
import com.android.internal.telephony.gsm.SmsMessage;
import android.telephony.ims.internal.SmsImplBase;
import android.telephony.ims.internal.SmsImplBase.SendStatusResult;
import android.telephony.ims.internal.SmsImplBase.StatusReportResult;
import android.provider.Telephony.Sms.Intents;
import android.util.Pair;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import libcore.util.Nullable;


/**
/**
 * Responsible for communications with {@link com.android.ims.ImsManager} to send/receive messages
 * Responsible for communications with {@link com.android.ims.ImsManager} to send/receive messages
 * over IMS.
 * over IMS.
 *
 * TODO: implement
 */
 */
public class ImsSmsDispatcher extends SMSDispatcher {
public class ImsSmsDispatcher extends SMSDispatcher {
    @VisibleForTesting
    public Map<Integer, SmsTracker> mTrackers = new ConcurrentHashMap<>();
    @VisibleForTesting
    public AtomicInteger mNextToken = new AtomicInteger();

    private final IImsSmsListener mImsSmsListener = new IImsSmsListener.Stub() {
        @Override
        public void onSendSmsResult(int token, int messageRef, @SendStatusResult int status,
                int reason) throws RemoteException {
            SmsTracker tracker = mTrackers.get(token);
            if (tracker == null) {
                throw new IllegalArgumentException("Invalid token.");
            }
            switch(reason) {
                case SmsImplBase.SEND_STATUS_OK:
                    tracker.onSent(mContext);
                    break;
                case SmsImplBase.SEND_STATUS_ERROR:
                    tracker.onFailed(mContext, reason, 0 /* errorCode */);
                    mTrackers.remove(token);
                    break;
                case SmsImplBase.SEND_STATUS_ERROR_RETRY:
                    tracker.mRetryCount += 1;
                    sendSms(tracker);
                    break;
                case SmsImplBase.SEND_STATUS_ERROR_FALLBACK:
                    fallbackToPstn(token, tracker);
                    break;
                default:
            }
        }


    /** {@inheritDoc} */
        @Override
    protected ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
        public void onSmsStatusReportReceived(int token, int messageRef, String format, byte[] pdu)
                throws RemoteException {
            Rlog.d(TAG, "Status report received.");
            SmsTracker tracker = mTrackers.get(token);
            if (tracker == null) {
                throw new RemoteException("Invalid token.");
            }
            Pair<Boolean, Boolean> result = mSmsDispatchersController.handleSmsStatusReport(
                    tracker, format, pdu);
            Rlog.d(TAG, "Status report handle result, success: " + result.first +
                    "complete: " + result.second);
            try {
                getImsManager().acknowledgeSmsReport(
                        token,
                        messageRef,
                        result.first ? SmsImplBase.STATUS_REPORT_STATUS_OK
                                : SmsImplBase.STATUS_REPORT_STATUS_ERROR);
            } catch (ImsException e) {
                Rlog.e(TAG, "Failed to acknowledgeSmsReport(). Error: "
                        + e.getMessage());
            }
            if (result.second) {
                mTrackers.remove(token);
            }
        }

        @Override
        public void onSmsReceived(int token, String format, byte[] pdu)
                throws RemoteException {
            Rlog.d(TAG, "SMS received.");
            mSmsDispatchersController.injectSmsPdu(pdu, format, result -> {
                Rlog.d(TAG, "SMS handled result: " + result);
                try {
                    getImsManager().acknowledgeSms(token,
                            0,
                            result == Intents.RESULT_SMS_HANDLED
                                    ? SmsImplBase.STATUS_REPORT_STATUS_OK
                                    : SmsImplBase.DELIVER_STATUS_ERROR);
                } catch (ImsException e) {
                    Rlog.e(TAG, "Failed to acknowledgeSms(). Error: " + e.getMessage());
                }
            });
        }
    };

    public ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
        super(phone, smsDispatchersController);
        super(phone, smsDispatchersController);
    }
    }


    public boolean isAvailable() {
        // TODO: implement
        return false;
    }

    @Override
    @Override
    protected String getFormat() {
    protected String getFormat() {
        return null;
        try {
            return getImsManager().getSmsFormat();
        } catch (ImsException e) {
            Rlog.e(TAG, "Failed to get sms format. Error: " + e.getMessage());
            return SmsConstants.FORMAT_UNKNOWN;
        }
    }
    }


    @Override
    @Override
@@ -62,7 +171,56 @@ public class ImsSmsDispatcher extends SMSDispatcher {
    }
    }


    @Override
    @Override
    protected void sendSms(SmsTracker tracker) {
    public void sendSms(SmsTracker tracker) {
        Rlog.d(TAG, "sendSms: "
                + " mRetryCount=" + tracker.mRetryCount
                + " mMessageRef=" + tracker.mMessageRef
                + " SS=" + mPhone.getServiceState().getState());

        HashMap<String, Object> map = tracker.getData();

        byte[] pdu = (byte[]) map.get(MAP_KEY_PDU);
        byte smsc[] = (byte[]) map.get(MAP_KEY_SMSC);
        boolean isRetry = tracker.mRetryCount > 0;

        if (SmsConstants.FORMAT_3GPP.equals(getFormat()) && tracker.mRetryCount > 0) {
            // per TS 23.040 Section 9.2.3.6:  If TP-MTI SMS-SUBMIT (0x01) type
            //   TP-RD (bit 2) is 1 for retry
            //   and TP-MR is set to previously failed sms TP-MR
            if (((0x01 & pdu[0]) == 0x01)) {
                pdu[0] |= 0x04; // TP-RD
                pdu[1] = (byte) tracker.mMessageRef; // TP-MR
            }
        }


        int token = mNextToken.incrementAndGet();
        mTrackers.put(token, tracker);
        try {
            getImsManager().sendSms(
                    token,
                    tracker.mMessageRef,
                    getFormat(),
                    smsc != null ? new String(smsc) : null,
                    isRetry,
                    pdu);
        } catch (ImsException e) {
            Rlog.e(TAG, "sendSms failed. Falling back to PSTN. Error: " + e.getMessage());
            fallbackToPstn(token, tracker);
        }
    }

    private ImsManager getImsManager() {
        return ImsManager.getInstance(mContext, mPhone.getPhoneId());
    }

    @VisibleForTesting
    public void fallbackToPstn(int token, SmsTracker tracker) {
        mSmsDispatchersController.sendRetrySms(tracker);
        mTrackers.remove(token);
    }

    @Override
    protected boolean isCdmaMo() {
        return mSmsDispatchersController.isCdmaFormat(getFormat());
    }
    }
}
}
+4 −6
Original line number Original line Diff line number Diff line
@@ -603,9 +603,9 @@ public abstract class InboundSmsHandler extends StateMachine {
     */
     */
    private void handleInjectSms(AsyncResult ar) {
    private void handleInjectSms(AsyncResult ar) {
        int result;
        int result;
        PendingIntent receivedIntent = null;
        SmsDispatchersController.SmsInjectionCallback callback = null;
        try {
        try {
            receivedIntent = (PendingIntent) ar.userObj;
            callback = (SmsDispatchersController.SmsInjectionCallback) ar.userObj;
            SmsMessage sms = (SmsMessage) ar.result;
            SmsMessage sms = (SmsMessage) ar.result;
            if (sms == null) {
            if (sms == null) {
              result = Intents.RESULT_SMS_GENERIC_ERROR;
              result = Intents.RESULT_SMS_GENERIC_ERROR;
@@ -617,10 +617,8 @@ public abstract class InboundSmsHandler extends StateMachine {
            result = Intents.RESULT_SMS_GENERIC_ERROR;
            result = Intents.RESULT_SMS_GENERIC_ERROR;
        }
        }


        if (receivedIntent != null) {
        if (callback != null) {
            try {
            callback.onSmsInjectedResult(result);
                receivedIntent.send(result);
            } catch (CanceledException e) { }
        }
        }
    }
    }


+24 −17
Original line number Original line Diff line number Diff line
@@ -94,6 +94,13 @@ public abstract class SMSDispatcher extends Handler {
    static final String TAG = "SMSDispatcher";    // accessed from inner class
    static final String TAG = "SMSDispatcher";    // accessed from inner class
    static final boolean DBG = false;
    static final boolean DBG = false;
    private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
    private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
    protected static final String MAP_KEY_PDU = "pdu";
    protected static final String MAP_KEY_SMSC = "smsc";
    protected static final String MAP_KEY_DEST_ADDR = "destAddr";
    protected static final String MAP_KEY_SC_ADDR = "scAddr";
    protected static final String MAP_KEY_DEST_PORT = "destPort";
    protected static final String MAP_KEY_DATA = "data";
    protected static final String MAP_KEY_TEXT = "text";


    private static final int PREMIUM_RULE_USE_SIM = 1;
    private static final int PREMIUM_RULE_USE_SIM = 1;
    private static final int PREMIUM_RULE_USE_NETWORK = 2;
    private static final int PREMIUM_RULE_USE_NETWORK = 2;
@@ -152,7 +159,7 @@ public abstract class SMSDispatcher extends Handler {
     */
     */
    private static int sConcatenatedRef = new Random().nextInt(256);
    private static int sConcatenatedRef = new Random().nextInt(256);


    private SmsDispatchersController mSmsDispatchersController;
    protected SmsDispatchersController mSmsDispatchersController;


    /** Number of outgoing SmsTrackers waiting for user confirmation. */
    /** Number of outgoing SmsTrackers waiting for user confirmation. */
    private int mPendingTrackerCount;
    private int mPendingTrackerCount;
@@ -378,7 +385,7 @@ public abstract class SMSDispatcher extends Handler {
        @Override
        @Override
        protected void onServiceReady(ICarrierMessagingService carrierMessagingService) {
        protected void onServiceReady(ICarrierMessagingService carrierMessagingService) {
            HashMap<String, Object> map = mTracker.getData();
            HashMap<String, Object> map = mTracker.getData();
            String text = (String) map.get("text");
            String text = (String) map.get(MAP_KEY_TEXT);


            if (text != null) {
            if (text != null) {
                try {
                try {
@@ -410,8 +417,8 @@ public abstract class SMSDispatcher extends Handler {
        @Override
        @Override
        protected void onServiceReady(ICarrierMessagingService carrierMessagingService) {
        protected void onServiceReady(ICarrierMessagingService carrierMessagingService) {
            HashMap<String, Object> map = mTracker.getData();
            HashMap<String, Object> map = mTracker.getData();
            byte[] data = (byte[]) map.get("data");
            byte[] data = (byte[]) map.get(MAP_KEY_DATA);
            int destPort = (int) map.get("destPort");
            int destPort = (int) map.get(MAP_KEY_DEST_PORT);


            if (data != null) {
            if (data != null) {
                try {
                try {
@@ -1076,7 +1083,7 @@ public abstract class SMSDispatcher extends Handler {
    @VisibleForTesting
    @VisibleForTesting
    public void sendRawPdu(SmsTracker tracker) {
    public void sendRawPdu(SmsTracker tracker) {
        HashMap map = tracker.getData();
        HashMap map = tracker.getData();
        byte pdu[] = (byte[]) map.get("pdu");
        byte pdu[] = (byte[]) map.get(MAP_KEY_PDU);


        if (mSmsSendDisabled) {
        if (mSmsSendDisabled) {
            Rlog.e(TAG, "Device does not support sending sms.");
            Rlog.e(TAG, "Device does not support sending sms.");
@@ -1713,23 +1720,23 @@ public abstract class SMSDispatcher extends Handler {
    protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
    protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
            String text, SmsMessageBase.SubmitPduBase pdu) {
            String text, SmsMessageBase.SubmitPduBase pdu) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("destAddr", destAddr);
        map.put(MAP_KEY_DEST_ADDR, destAddr);
        map.put("scAddr", scAddr);
        map.put(MAP_KEY_SC_ADDR, scAddr);
        map.put("text", text);
        map.put(MAP_KEY_TEXT, text);
        map.put("smsc", pdu.encodedScAddress);
        map.put(MAP_KEY_SMSC, pdu.encodedScAddress);
        map.put("pdu", pdu.encodedMessage);
        map.put(MAP_KEY_PDU, pdu.encodedMessage);
        return map;
        return map;
    }
    }


    protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
    protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
            int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu) {
            int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("destAddr", destAddr);
        map.put(MAP_KEY_DEST_ADDR, destAddr);
        map.put("scAddr", scAddr);
        map.put(MAP_KEY_SC_ADDR, scAddr);
        map.put("destPort", destPort);
        map.put(MAP_KEY_DEST_PORT, destPort);
        map.put("data", data);
        map.put(MAP_KEY_DATA, data);
        map.put("smsc", pdu.encodedScAddress);
        map.put(MAP_KEY_SMSC, pdu.encodedScAddress);
        map.put("pdu", pdu.encodedMessage);
        map.put(MAP_KEY_PDU, pdu.encodedMessage);
        return map;
        return map;
    }
    }


@@ -1886,7 +1893,7 @@ public abstract class SMSDispatcher extends Handler {
        }
        }
    }
    }


    protected final boolean isCdmaMo() {
    protected boolean isCdmaMo() {
        return mSmsDispatchersController.isCdmaMo();
        return mSmsDispatchersController.isCdmaMo();
    }
    }
}
}
+94 −27
Original line number Original line Diff line number Diff line
@@ -16,17 +16,22 @@


package com.android.internal.telephony;
package com.android.internal.telephony;


import android.app.Activity;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Handler;
import android.os.Message;
import android.os.Message;
import android.provider.Telephony.Sms;
import android.provider.Telephony.Sms.Intents;
import android.provider.Telephony.Sms.Intents;
import android.telephony.Rlog;
import android.telephony.Rlog;
import android.telephony.SmsManager;
import android.telephony.SmsManager;
import android.util.Pair;


import com.android.ims.ImsManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaInboundSmsHandler;
import com.android.internal.telephony.cdma.CdmaInboundSmsHandler;
import com.android.internal.telephony.cdma.CdmaSMSDispatcher;
import com.android.internal.telephony.cdma.CdmaSMSDispatcher;
@@ -40,7 +45,7 @@ import java.util.HashMap;
 *
 *
 */
 */
public class SmsDispatchersController extends Handler {
public class SmsDispatchersController extends Handler {
    private static final String TAG = "RIL_ImsSms";
    private static final String TAG = "SmsDispatchersController";


    /** Radio is ON */
    /** Radio is ON */
    private static final int EVENT_RADIO_ON = 11;
    private static final int EVENT_RADIO_ON = 11;
@@ -53,6 +58,7 @@ public class SmsDispatchersController extends Handler {


    private SMSDispatcher mCdmaDispatcher;
    private SMSDispatcher mCdmaDispatcher;
    private SMSDispatcher mGsmDispatcher;
    private SMSDispatcher mGsmDispatcher;
    private ImsSmsDispatcher mImsSmsDispatcher;


    private GsmInboundSmsHandler mGsmInboundSmsHandler;
    private GsmInboundSmsHandler mGsmInboundSmsHandler;
    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
@@ -78,6 +84,7 @@ public class SmsDispatchersController extends Handler {


        // Create dispatchers, inbound SMS handlers and
        // Create dispatchers, inbound SMS handlers and
        // broadcast undelivered messages in raw table.
        // broadcast undelivered messages in raw table.
        mImsSmsDispatcher = new ImsSmsDispatcher(phone, this);
        mCdmaDispatcher = new CdmaSMSDispatcher(phone, this);
        mCdmaDispatcher = new CdmaSMSDispatcher(phone, this);
        mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
        mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
                storageMonitor, phone);
                storageMonitor, phone);
@@ -146,7 +153,6 @@ public class SmsDispatchersController extends Handler {
    }
    }


    private void setImsSmsFormat(int format) {
    private void setImsSmsFormat(int format) {
        // valid format?
        switch (format) {
        switch (format) {
            case PhoneConstants.PHONE_TYPE_GSM:
            case PhoneConstants.PHONE_TYPE_GSM:
                mImsSmsFormat = SmsConstants.FORMAT_3GPP;
                mImsSmsFormat = SmsConstants.FORMAT_3GPP;
@@ -172,13 +178,12 @@ public class SmsDispatchersController extends Handler {
     *
     *
     * @param pdu is the byte array of pdu to be injected into android telephony layer
     * @param pdu is the byte array of pdu to be injected into android telephony layer
     * @param format is the format of SMS pdu (3gpp or 3gpp2)
     * @param format is the format of SMS pdu (3gpp or 3gpp2)
     * @param receivedIntent if not NULL this <code>PendingIntent</code> is
     * @param callback if not NULL this callback is triggered when the message is successfully
     *  broadcast when the message is successfully received by the
     *                 received by the android telephony layer. This callback is triggered at
     *  android telephony layer. This intent is broadcasted at
     *                 the same time an SMS received from radio is responded back.
     *                 the same time an SMS received from radio is responded back.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    public void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) {
    public void injectSmsPdu(byte[] pdu, String format, SmsInjectionCallback callback) {
        Rlog.d(TAG, "SmsDispatchersController:injectSmsPdu");
        Rlog.d(TAG, "SmsDispatchersController:injectSmsPdu");
        try {
        try {
            // TODO We need to decide whether we should allow injecting GSM(3gpp)
            // TODO We need to decide whether we should allow injecting GSM(3gpp)
@@ -192,13 +197,11 @@ public class SmsDispatchersController extends Handler {
                if (msg == null) {
                if (msg == null) {
                    Rlog.e(TAG, "injectSmsPdu: createFromPdu returned null");
                    Rlog.e(TAG, "injectSmsPdu: createFromPdu returned null");
                }
                }
                if (receivedIntent != null) {
                callback.onSmsInjectedResult(Intents.RESULT_SMS_GENERIC_ERROR);
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
                }
                return;
                return;
            }
            }


            AsyncResult ar = new AsyncResult(receivedIntent, msg, null);
            AsyncResult ar = new AsyncResult(callback, msg, null);


            if (format.equals(SmsConstants.FORMAT_3GPP)) {
            if (format.equals(SmsConstants.FORMAT_3GPP)) {
                Rlog.i(TAG, "SmsDispatchersController:injectSmsText Sending msg=" + msg
                Rlog.i(TAG, "SmsDispatchersController:injectSmsText Sending msg=" + msg
@@ -211,19 +214,11 @@ public class SmsDispatchersController extends Handler {
            } else {
            } else {
                // Invalid pdu format.
                // Invalid pdu format.
                Rlog.e(TAG, "Invalid pdu format: " + format);
                Rlog.e(TAG, "Invalid pdu format: " + format);
                if (receivedIntent != null) {
                callback.onSmsInjectedResult(Intents.RESULT_SMS_GENERIC_ERROR);
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
                }
            }
            }
        } catch (Exception e) {
        } catch (Exception e) {
            Rlog.e(TAG, "injectSmsPdu failed: ", e);
            Rlog.e(TAG, "injectSmsPdu failed: ", e);
            try {
            callback.onSmsInjectedResult(Intents.RESULT_SMS_GENERIC_ERROR);
                if (receivedIntent != null) {
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
                }
            } catch (CanceledException ex) {
                Rlog.e(TAG, "Failed to send result");
            }
        }
        }
    }
    }


@@ -307,8 +302,7 @@ public class SmsDispatchersController extends Handler {
        map.put("smsc", pdu.encodedScAddress);
        map.put("smsc", pdu.encodedScAddress);
        map.put("pdu", pdu.encodedMessage);
        map.put("pdu", pdu.encodedMessage);


        SMSDispatcher dispatcher = (isCdmaFormat(newFormat))
        SMSDispatcher dispatcher = (isCdmaFormat(newFormat)) ? mCdmaDispatcher : mGsmDispatcher;
                ? mCdmaDispatcher : mGsmDispatcher;


        tracker.mFormat = dispatcher.getFormat();
        tracker.mFormat = dispatcher.getFormat();
        dispatcher.sendSms(tracker);
        dispatcher.sendSms(tracker);
@@ -344,7 +338,7 @@ public class SmsDispatchersController extends Handler {
     * @param format
     * @param format
     * @return true if format given is CDMA format, false otherwise.
     * @return true if format given is CDMA format, false otherwise.
     */
     */
    private boolean isCdmaFormat(String format) {
    public boolean isCdmaFormat(String format) {
        return (mCdmaDispatcher.getFormat().equals(format));
        return (mCdmaDispatcher.getFormat().equals(format));
    }
    }


@@ -376,7 +370,10 @@ public class SmsDispatchersController extends Handler {
     */
     */
    protected void sendData(String destAddr, String scAddr, int destPort,
    protected void sendData(String destAddr, String scAddr, int destPort,
                            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
                            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
        if (isCdmaMo()) {
        if (mImsSmsDispatcher.isAvailable()) {
            mImsSmsDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent,
                    deliveryIntent);
        } else if (isCdmaMo()) {
            mCdmaDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
            mCdmaDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
        } else {
        } else {
            mGsmDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
            mGsmDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
@@ -413,7 +410,10 @@ public class SmsDispatchersController extends Handler {
    public void sendText(String destAddr, String scAddr, String text,
    public void sendText(String destAddr, String scAddr, String text,
                            PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
                            PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
                            String callingPkg, boolean persistMessage) {
                            String callingPkg, boolean persistMessage) {
        if (isCdmaMo()) {
        if (mImsSmsDispatcher.isAvailable()) {
            mImsSmsDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
                    messageUri, callingPkg, persistMessage);
        } else if (isCdmaMo()) {
            mCdmaDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, messageUri,
            mCdmaDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, messageUri,
                    callingPkg, persistMessage);
                    callingPkg, persistMessage);
        } else {
        } else {
@@ -454,7 +454,10 @@ public class SmsDispatchersController extends Handler {
            ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
            ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
            ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg,
            ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg,
            boolean persistMessage) {
            boolean persistMessage) {
        if (isCdmaMo()) {
        if (mImsSmsDispatcher.isAvailable()) {
            mImsSmsDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents,
                    deliveryIntents, messageUri, callingPkg, persistMessage);
        } else if (isCdmaMo()) {
            mCdmaDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents,
            mCdmaDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents,
                    messageUri, callingPkg, persistMessage);
                    messageUri, callingPkg, persistMessage);
        } else {
        } else {
@@ -492,4 +495,68 @@ public class SmsDispatchersController extends Handler {
    public SmsUsageMonitor getUsageMonitor() {
    public SmsUsageMonitor getUsageMonitor() {
        return mUsageMonitor;
        return mUsageMonitor;
    }
    }

    /**
     * Triggers the correct method for handling the sms status report based on the format.
     *
     * @param tracker the sms tracker.
     * @param format the format.
     * @param pdu the pdu of the report.
     * @return a Pair in which the first boolean is whether the report was handled successfully
     *          or not and the second boolean is whether processing the sms is complete and the
     *          tracker no longer need to be kept track of, false if we should expect more callbacks
     *          and the tracker should be kept.
     */
    public Pair<Boolean, Boolean> handleSmsStatusReport(SMSDispatcher.SmsTracker tracker,
            String format, byte[] pdu) {
        if (isCdmaFormat(format)) {
            return handleCdmaStatusReport(tracker, format, pdu);
        } else {
            return handleGsmStatusReport(tracker, format, pdu);
        }
    }

    private Pair<Boolean, Boolean> handleCdmaStatusReport(SMSDispatcher.SmsTracker tracker,
            String format, byte[] pdu) {
        tracker.updateSentMessageStatus(mContext, Sms.STATUS_COMPLETE);
        boolean success = triggerDeliveryIntent(tracker, format, pdu);
        return new Pair(success, true /* complete */);
    }

    private Pair<Boolean, Boolean> handleGsmStatusReport(SMSDispatcher.SmsTracker tracker,
            String format, byte[] pdu) {
        com.android.internal.telephony.gsm.SmsMessage sms =
                com.android.internal.telephony.gsm.SmsMessage.newFromCDS(pdu);
        boolean complete = false;
        boolean success = false;
        if (sms != null) {
            int tpStatus = sms.getStatus();
            if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
                // Update the message status (COMPLETE or FAILED)
                tracker.updateSentMessageStatus(mContext, tpStatus);
                complete = true;
            }
            success = triggerDeliveryIntent(tracker, format, pdu);
        }
        return new Pair(success, complete);
    }

    private boolean triggerDeliveryIntent(SMSDispatcher.SmsTracker tracker, String format,
                                          byte[] pdu) {
        PendingIntent intent = tracker.mDeliveryIntent;
        Intent fillIn = new Intent();
        fillIn.putExtra("pdu", pdu);
        fillIn.putExtra("format", format);
        try {
            intent.send(mContext, Activity.RESULT_OK, fillIn);
            return true;
        } catch (CanceledException ex) {
            return false;
        }
    }


    public interface SmsInjectionCallback {
        void onSmsInjectedResult(int result);
    }
}
}
Loading