GsmSMSDispatcherpublic final class GsmSMSDispatcher extends com.android.internal.telephony.SMSDispatcher
Fields Summary |
---|
private static final String | TAG | private static final boolean | VDBG | protected com.android.internal.telephony.uicc.UiccController | mUiccController | private AtomicReference | mIccRecords | private AtomicReference | mUiccApplication | private GsmInboundSmsHandler | mGsmInboundSmsHandler | private static final int | EVENT_NEW_SMS_STATUS_REPORTStatus report received |
Constructors Summary |
---|
public GsmSMSDispatcher(com.android.internal.telephony.PhoneBase phone, com.android.internal.telephony.SmsUsageMonitor usageMonitor, com.android.internal.telephony.ImsSMSDispatcher imsSMSDispatcher, GsmInboundSmsHandler gsmInboundSmsHandler)
super(phone, usageMonitor, imsSMSDispatcher);
mCi.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
mGsmInboundSmsHandler = gsmInboundSmsHandler;
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
Rlog.d(TAG, "GsmSMSDispatcher created");
|
Methods Summary |
---|
protected GsmAlphabet.TextEncodingDetails | calculateLength(java.lang.CharSequence messageBody, boolean use7bitOnly){@inheritDoc}
return SmsMessage.calculateLength(messageBody, use7bitOnly);
| public void | dispose()
super.dispose();
mCi.unSetOnSmsStatus(this);
mUiccController.unregisterForIccChanged(this);
| protected java.lang.String | getFormat()
return SmsConstants.FORMAT_3GPP;
| protected SmsTracker | getNewSubmitPduTracker(java.lang.String destinationAddress, java.lang.String scAddress, java.lang.String message, com.android.internal.telephony.SmsHeader smsHeader, int encoding, 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){@inheritDoc}
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
if (pdu != null) {
HashMap map = getSmsTrackerMap(destinationAddress, scAddress,
message, pdu);
return getSmsTracker(map, sentIntent,
deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri,
smsHeader, !lastPart, fullMessageText, true /*isText*/);
} else {
Rlog.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null");
return null;
}
| protected com.android.internal.telephony.uicc.UiccCardApplication | getUiccCardApplication()
Rlog.d(TAG, "GsmSMSDispatcher: subId = " + mPhone.getSubId()
+ " slotId = " + mPhone.getPhoneId());
return mUiccController.getUiccCardApplication(mPhone.getPhoneId(),
UiccController.APP_FAM_3GPP);
| public void | handleMessage(android.os.Message msg)Handles 3GPP format-specific events coming from the phone stack.
Other events are handled by {@link SMSDispatcher#handleMessage}.
switch (msg.what) {
case EVENT_NEW_SMS_STATUS_REPORT:
handleStatusReport((AsyncResult) msg.obj);
break;
case EVENT_NEW_ICC_SMS:
// pass to InboundSmsHandler to process
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, msg.obj);
break;
case EVENT_ICC_CHANGED:
onUpdateIccAvailability();
break;
default:
super.handleMessage(msg);
}
| private void | handleStatusReport(android.os.AsyncResult ar)Called when a status report is received. This should correspond to
a previously successful SEND.
String pduString = (String) ar.result;
SmsMessage sms = SmsMessage.newFromCDS(pduString);
if (sms != null) {
int tpStatus = sms.getStatus();
int messageRef = sms.mMessageRef;
for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
SmsTracker tracker = deliveryPendingList.get(i);
if (tracker.mMessageRef == messageRef) {
// Found it. Remove from list and broadcast.
if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
deliveryPendingList.remove(i);
// Update the message status (COMPLETE or FAILED)
tracker.updateSentMessageStatus(mContext, tpStatus);
}
PendingIntent intent = tracker.mDeliveryIntent;
Intent fillIn = new Intent();
fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
fillIn.putExtra("format", getFormat());
try {
intent.send(mContext, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {}
// Only expect to see one tracker matching this messageref
break;
}
}
}
mCi.acknowledgeLastIncomingGsmSms(true, Intents.RESULT_SMS_HANDLED, null);
| protected void | injectSmsPdu(byte[] pdu, java.lang.String format, android.app.PendingIntent receivedIntent){@inheritDoc}
throw new IllegalStateException("This method must be called only on ImsSMSDispatcher");
| private void | onUpdateIccAvailability()
if (mUiccController == null ) {
return;
}
UiccCardApplication newUiccApplication = getUiccCardApplication();
UiccCardApplication app = mUiccApplication.get();
if (app != newUiccApplication) {
if (app != null) {
Rlog.d(TAG, "Removing stale icc objects.");
if (mIccRecords.get() != null) {
mIccRecords.get().unregisterForNewSms(this);
}
mIccRecords.set(null);
mUiccApplication.set(null);
}
if (newUiccApplication != null) {
Rlog.d(TAG, "New Uicc application found");
mUiccApplication.set(newUiccApplication);
mIccRecords.set(newUiccApplication.getIccRecords());
if (mIccRecords.get() != null) {
mIccRecords.get().registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
}
}
}
| protected void | sendData(java.lang.String destAddr, java.lang.String scAddr, int destPort, byte[] data, android.app.PendingIntent sentIntent, android.app.PendingIntent deliveryIntent){@inheritDoc}
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
scAddr, destAddr, destPort, data, (deliveryIntent != null));
if (pdu != null) {
HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu);
SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(),
null /*messageUri*/, false /*isExpectMore*/, null /*fullMessageText*/,
false /*isText*/);
String carrierPackage = getCarrierAppPackageName();
if (carrierPackage != null) {
Rlog.d(TAG, "Found carrier package.");
DataSmsSender smsSender = new DataSmsSender(tracker);
smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender));
} else {
Rlog.v(TAG, "No carrier package.");
sendRawPdu(tracker);
}
} else {
Rlog.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null");
}
| protected void | sendSms(SmsTracker tracker){@inheritDoc}
HashMap<String, Object> map = tracker.mData;
byte pdu[] = (byte[]) map.get("pdu");
if (tracker.mRetryCount > 0) {
Rlog.d(TAG, "sendSms: "
+ " mRetryCount=" + tracker.mRetryCount
+ " mMessageRef=" + tracker.mMessageRef
+ " SS=" + mPhone.getServiceState().getState());
// 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
}
}
Rlog.d(TAG, "sendSms: "
+ " isIms()=" + isIms()
+ " mRetryCount=" + tracker.mRetryCount
+ " mImsRetry=" + tracker.mImsRetry
+ " mMessageRef=" + tracker.mMessageRef
+ " SS=" + mPhone.getServiceState().getState());
sendSmsByPstn(tracker);
| protected void | sendSmsByPstn(SmsTracker tracker){@inheritDoc}
int ss = mPhone.getServiceState().getState();
// if sms over IMS is not supported on data and voice is not available...
if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) {
tracker.onFailed(mContext, getNotInServiceError(ss), 0/*errorCode*/);
return;
}
HashMap<String, Object> map = tracker.mData;
byte smsc[] = (byte[]) map.get("smsc");
byte[] pdu = (byte[]) map.get("pdu");
Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
// sms over gsm is used:
// if sms over IMS is not supported AND
// this is not a retry case after sms over IMS failed
// indicated by mImsRetry > 0
if (0 == tracker.mImsRetry && !isIms()) {
if (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
}
}
if (tracker.mRetryCount == 0 && tracker.mExpectMore) {
mCi.sendSMSExpectMore(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), reply);
} else {
mCi.sendSMS(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), reply);
}
} else {
mCi.sendImsGsmSms(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), tracker.mImsRetry,
tracker.mMessageRef, reply);
// increment it here, so in case of SMS_FAIL_RETRY over IMS
// next retry will be sent using IMS request again.
tracker.mImsRetry++;
}
| protected void | sendSubmitPdu(SmsTracker tracker)
sendRawPdu(tracker);
| protected void | sendText(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){@inheritDoc}
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
scAddr, destAddr, text, (deliveryIntent != null));
if (pdu != null) {
HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu);
SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(),
messageUri, false /*isExpectMore*/, text /*fullMessageText*/, true /*isText*/);
String carrierPackage = getCarrierAppPackageName();
if (carrierPackage != null) {
Rlog.d(TAG, "Found carrier package.");
TextSmsSender smsSender = new TextSmsSender(tracker);
smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender));
} else {
Rlog.v(TAG, "No carrier package.");
sendRawPdu(tracker);
}
} else {
Rlog.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null");
}
|
|