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

ImsSMSDispatcher

public final class ImsSMSDispatcher extends SMSDispatcher

Fields Summary
private static final String
TAG
private SMSDispatcher
mCdmaDispatcher
private SMSDispatcher
mGsmDispatcher
private com.android.internal.telephony.gsm.GsmInboundSmsHandler
mGsmInboundSmsHandler
private com.android.internal.telephony.cdma.CdmaInboundSmsHandler
mCdmaInboundSmsHandler
private boolean
mIms
true if IMS is registered and sms is supported, false otherwise.
private String
mImsSmsFormat
Constructors Summary
public ImsSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor, SmsUsageMonitor usageMonitor)


        
              
        super(phone, usageMonitor, null);
        Rlog.d(TAG, "ImsSMSDispatcher created");

        // Create dispatchers, inbound SMS handlers and
        // broadcast undelivered messages in raw table.
        mCdmaDispatcher = new CdmaSMSDispatcher(phone, usageMonitor, this);
        mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
                storageMonitor, phone);
        mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
                storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher);
        mGsmDispatcher = new GsmSMSDispatcher(phone, usageMonitor, this, mGsmInboundSmsHandler);
        Thread broadcastThread = new Thread(new SmsBroadcastUndelivered(phone.getContext(),
                mGsmInboundSmsHandler, mCdmaInboundSmsHandler));
        broadcastThread.start();

        mCi.registerForOn(this, EVENT_RADIO_ON, null);
        mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
    
Methods Summary
protected GsmAlphabet.TextEncodingDetailscalculateLength(java.lang.CharSequence messageBody, boolean use7bitOnly)

        Rlog.e(TAG, "Error! Not implemented for IMS.");
        return null;
    
public voiddispose()

        mCi.unregisterForOn(this);
        mCi.unregisterForImsNetworkStateChanged(this);
        mGsmDispatcher.dispose();
        mCdmaDispatcher.dispose();
        mGsmInboundSmsHandler.dispose();
        mCdmaInboundSmsHandler.dispose();
    
protected java.lang.StringgetFormat()

        // this function should be defined in Gsm/CdmaDispatcher.
        Rlog.e(TAG, "getFormat should never be called from here!");
        return "unknown";
    
public java.lang.StringgetImsSmsFormat()

        return mImsSmsFormat;
    
protected SmsTrackergetNewSubmitPduTracker(java.lang.String destinationAddress, java.lang.String scAddress, java.lang.String message, SmsHeader smsHeader, int format, android.app.PendingIntent sentIntent, android.app.PendingIntent deliveryIntent, boolean lastPart, java.util.concurrent.atomic.AtomicInteger unsentPartCount, java.util.concurrent.atomic.AtomicBoolean anyPartFailed, android.net.Uri messageUri, java.lang.String fullMessageText)

        Rlog.e(TAG, "Error! Not implemented for IMS.");
        return null;
    
public voidhandleMessage(android.os.Message msg)
Handles events coming from the phone stack. Overridden from handler.

param
msg the message to handle

        AsyncResult ar;

        switch (msg.what) {
        case EVENT_RADIO_ON:
        case EVENT_IMS_STATE_CHANGED: // received unsol
            mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE));
            break;

        case EVENT_IMS_STATE_DONE:
            ar = (AsyncResult) msg.obj;

            if (ar.exception == null) {
                updateImsInfo(ar);
            } else {
                Rlog.e(TAG, "IMS State query failed with exp "
                        + ar.exception);
            }
            break;

        default:
            super.handleMessage(msg);
        }
    
protected voidinjectSmsPdu(byte[] pdu, java.lang.String format, android.app.PendingIntent receivedIntent)

        Rlog.d(TAG, "ImsSMSDispatcher:injectSmsPdu");
        try {
            // TODO We need to decide whether we should allow injecting GSM(3gpp)
            // SMS pdus when the phone is camping on CDMA(3gpp2) network and vice versa.
            android.telephony.SmsMessage msg =
                    android.telephony.SmsMessage.createFromPdu(pdu, format);

            // Only class 1 SMS are allowed to be injected.
            if (msg.getMessageClass() != android.telephony.SmsMessage.MessageClass.CLASS_1) {
                if (receivedIntent != null)
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
                return;
            }

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

            if (format.equals(SmsConstants.FORMAT_3GPP)) {
                Rlog.i(TAG, "ImsSMSDispatcher:injectSmsText Sending msg=" + msg +
                        ", format=" + format + "to mGsmInboundSmsHandler");
                mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, ar);
            } else if (format.equals(SmsConstants.FORMAT_3GPP2)) {
                Rlog.i(TAG, "ImsSMSDispatcher:injectSmsText Sending msg=" + msg +
                        ", format=" + format + "to mCdmaInboundSmsHandler");
                mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, ar);
            } else {
                // Invalid pdu format.
                Rlog.e(TAG, "Invalid pdu format: " + format);
                if (receivedIntent != null)
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
            }
        } catch (Exception e) {
            Rlog.e(TAG, "injectSmsPdu failed: ", e);
            try {
                if (receivedIntent != null)
                    receivedIntent.send(Intents.RESULT_SMS_GENERIC_ERROR);
            } catch (CanceledException ex) {}
        }
    
private booleanisCdmaFormat(java.lang.String format)
Determines whether or not format given is CDMA format.

param
format
return
true if format given is CDMA format, false otherwise.

        return (mCdmaDispatcher.getFormat().equals(format));
    
private booleanisCdmaMo()
Determines whether or not to use CDMA format for MO SMS. If SMS over IMS is supported, then format is based on IMS SMS format, otherwise format is based on current phone type.

return
true if Cdma format should be used for MO SMS, false otherwise.

        if (!isIms()) {
            // IMS is not registered, use Voice technology to determine SMS format.
            return (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType());
        }
        // IMS is registered with SMS support
        return isCdmaFormat(mImsSmsFormat);
    
public booleanisIms()

        return mIms;
    
protected voidsendData(java.lang.String destAddr, java.lang.String scAddr, int destPort, byte[] data, android.app.PendingIntent sentIntent, android.app.PendingIntent deliveryIntent)

        if (isCdmaMo()) {
            mCdmaDispatcher.sendData(destAddr, scAddr, destPort,
                    data, sentIntent, deliveryIntent);
        } else {
            mGsmDispatcher.sendData(destAddr, scAddr, destPort,
                    data, sentIntent, deliveryIntent);
        }
    
protected voidsendMultipartText(java.lang.String destAddr, java.lang.String scAddr, java.util.ArrayList parts, java.util.ArrayList sentIntents, java.util.ArrayList deliveryIntents, android.net.Uri messageUri, java.lang.String callingPkg)

        if (isCdmaMo()) {
            mCdmaDispatcher.sendMultipartText(destAddr, scAddr,
                    parts, sentIntents, deliveryIntents, messageUri, callingPkg);
        } else {
            mGsmDispatcher.sendMultipartText(destAddr, scAddr,
                    parts, sentIntents, deliveryIntents, messageUri, callingPkg);
        }
    
public voidsendRetrySms(SmsTracker tracker)

        String oldFormat = tracker.mFormat;

        // newFormat will be based on voice technology
        String newFormat =
            (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType()) ?
                    mCdmaDispatcher.getFormat() :
                        mGsmDispatcher.getFormat();

        // was previously sent sms format match with voice tech?
        if (oldFormat.equals(newFormat)) {
            if (isCdmaFormat(newFormat)) {
                Rlog.d(TAG, "old format matched new format (cdma)");
                mCdmaDispatcher.sendSms(tracker);
                return;
            } else {
                Rlog.d(TAG, "old format matched new format (gsm)");
                mGsmDispatcher.sendSms(tracker);
                return;
            }
        }

        // format didn't match, need to re-encode.
        HashMap map = tracker.mData;

        // to re-encode, fields needed are:  scAddr, destAddr, and
        //   text if originally sent as sendText or
        //   data and destPort if originally sent as sendData.
        if (!( map.containsKey("scAddr") && map.containsKey("destAddr") &&
               ( map.containsKey("text") ||
                       (map.containsKey("data") && map.containsKey("destPort"))))) {
            // should never come here...
            Rlog.e(TAG, "sendRetrySms failed to re-encode per missing fields!");
            tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
            return;
        }
        String scAddr = (String)map.get("scAddr");
        String destAddr = (String)map.get("destAddr");

        SmsMessageBase.SubmitPduBase pdu = null;
        //    figure out from tracker if this was sendText/Data
        if (map.containsKey("text")) {
            Rlog.d(TAG, "sms failed was text");
            String text = (String)map.get("text");

            if (isCdmaFormat(newFormat)) {
                Rlog.d(TAG, "old format (gsm) ==> new format (cdma)");
                pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
                        scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
            } else {
                Rlog.d(TAG, "old format (cdma) ==> new format (gsm)");
                pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
                        scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
            }
        } else if (map.containsKey("data")) {
            Rlog.d(TAG, "sms failed was data");
            byte[] data = (byte[])map.get("data");
            Integer destPort = (Integer)map.get("destPort");

            if (isCdmaFormat(newFormat)) {
                Rlog.d(TAG, "old format (gsm) ==> new format (cdma)");
                pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
                            scAddr, destAddr, destPort.intValue(), data,
                            (tracker.mDeliveryIntent != null));
            } else {
                Rlog.d(TAG, "old format (cdma) ==> new format (gsm)");
                pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
                            scAddr, destAddr, destPort.intValue(), data,
                            (tracker.mDeliveryIntent != null));
            }
        }

        // replace old smsc and pdu with newly encoded ones
        map.put("smsc", pdu.encodedScAddress);
        map.put("pdu", pdu.encodedMessage);

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

        tracker.mFormat = dispatcher.getFormat();
        dispatcher.sendSms(tracker);
    
protected voidsendSms(SmsTracker tracker)

        //  sendSms is a helper function to other send functions, sendText/Data...
        //  it is not part of ISms.stub
        Rlog.e(TAG, "sendSms should never be called from here!");
    
protected voidsendSmsByPstn(SmsTracker tracker)

        // This function should be defined in Gsm/CdmaDispatcher.
        Rlog.e(TAG, "sendSmsByPstn should never be called from here!");
    
protected voidsendSubmitPdu(SmsTracker tracker)

        sendRawPdu(tracker);
    
protected voidsendText(java.lang.String destAddr, java.lang.String scAddr, java.lang.String text, android.app.PendingIntent sentIntent, android.app.PendingIntent deliveryIntent, android.net.Uri messageUri, java.lang.String callingPkg)

        Rlog.d(TAG, "sendText");
        if (isCdmaMo()) {
            mCdmaDispatcher.sendText(destAddr, scAddr,
                    text, sentIntent, deliveryIntent, messageUri, callingPkg);
        } else {
            mGsmDispatcher.sendText(destAddr, scAddr,
                    text, sentIntent, deliveryIntent, messageUri, callingPkg);
        }
    
private voidsetImsSmsFormat(int format)

        // valid format?
        switch (format) {
            case PhoneConstants.PHONE_TYPE_GSM:
                mImsSmsFormat = "3gpp";
                break;
            case PhoneConstants.PHONE_TYPE_CDMA:
                mImsSmsFormat = "3gpp2";
                break;
            default:
                mImsSmsFormat = "unknown";
                break;
        }
    
private voidupdateImsInfo(android.os.AsyncResult ar)

        int[] responseArray = (int[])ar.result;

        mIms = false;
        if (responseArray[0] == 1) {  // IMS is registered
            Rlog.d(TAG, "IMS is registered!");
            mIms = true;
        } else {
            Rlog.d(TAG, "IMS is NOT registered!");
        }

        setImsSmsFormat(responseArray[1]);

        if (("unknown".equals(mImsSmsFormat))) {
            Rlog.e(TAG, "IMS format was unknown!");
            // failed to retrieve valid IMS SMS format info, set IMS to unregistered
            mIms = false;
        }
    
protected voidupdatePhoneObject(PhoneBase phone)

        Rlog.d(TAG, "In IMS updatePhoneObject ");
        super.updatePhoneObject(phone);
        mCdmaDispatcher.updatePhoneObject(phone);
        mGsmDispatcher.updatePhoneObject(phone);
        mGsmInboundSmsHandler.updatePhoneObject(phone);
        mCdmaInboundSmsHandler.updatePhoneObject(phone);