diff options
4 files changed, 74 insertions, 27 deletions
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 0207330..0865b1d 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -558,6 +558,23 @@ public final class Telephony { "android.provider.Telephony.SIM_FULL"; /** + * Broadcast Action: An incoming SMS has been rejected by the + * telephony framework. This intent is sent in lieu of any + * of the RECEIVED_ACTION intents. The intent will have the + * following extra value:</p> + * + * <ul> + * <li><em>result</em> - An int result code, eg, + * <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>, + * indicating the error returned to the network.</li> + * </ul> + + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String SMS_REJECTED_ACTION = + "android.provider.Telephony.SMS_REJECTED"; + + /** * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a * {@link #DATA_SMS_RECEIVED_ACTION} intent. * diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 7efaa2e..d26a092 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -150,7 +150,8 @@ public abstract class SMSDispatcher extends Handler { private static SmsMessage mSmsMessage; private static SmsMessageBase mSmsMessageBase; private SmsMessageBase.SubmitPduBase mSubmitPduBase; - private boolean mStorageAvailable = true; + + protected boolean mStorageAvailable = true; protected static int getNextConcatenatedRef() { sConcatenatedRef += 1; @@ -294,19 +295,15 @@ public abstract class SMSDispatcher extends Handler { sms = (SmsMessage) ar.result; try { - if (mStorageAvailable) { - int result = dispatchMessage(sms.mWrappedSmsMessage); - if (result != Activity.RESULT_OK) { - // RESULT_OK means that message was broadcast for app(s) to handle. - // Any other result, we should ack here. - boolean handled = (result == Intents.RESULT_SMS_HANDLED); - acknowledgeLastIncomingSms(handled, result, null); - } - } else { - acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null); + int result = dispatchMessage(sms.mWrappedSmsMessage); + if (result != Activity.RESULT_OK) { + // RESULT_OK means that message was broadcast for app(s) to handle. + // Any other result, we should ack here. + boolean handled = (result == Intents.RESULT_SMS_HANDLED); + notifyAndAcknowledgeLastIncomingSms(handled, result, null); } } catch (RuntimeException ex) { - acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); + notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); } break; @@ -866,6 +863,25 @@ public abstract class SMSDispatcher extends Handler { int result, Message response); /** + * Notify interested apps if the framework has rejected an incoming SMS, + * and send an acknowledge message to the network. + * @param success indicates that last message was successfully received. + * @param result result code indicating any error + * @param response callback message sent when operation completes. + */ + private void notifyAndAcknowledgeLastIncomingSms(boolean success, + int result, Message response) { + if (!success) { + // broadcast SMS_REJECTED_ACTION intent + Intent intent = new Intent(Intents.SMS_REJECTED_ACTION); + intent.putExtra("result", result); + mWakeLock.acquire(WAKE_LOCK_TIMEOUT); + mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS"); + } + acknowledgeLastIncomingSms(success, result, response); + } + + /** * Check if a SmsTracker holds multi-part Sms * * @param tracker a SmsTracker could hold a multi-part Sms diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index ca15a03..1e3a2e1 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -33,6 +33,7 @@ import android.preference.PreferenceManager; import android.util.Config; import android.util.Log; import android.telephony.SmsManager; +import android.telephony.SmsMessage.MessageClass; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.CommandsInterface; @@ -91,8 +92,20 @@ final class CdmaSMSDispatcher extends SMSDispatcher { int teleService = sms.getTeleService(); boolean handled = false; - if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService) && - (SmsEnvelope.TELESERVICE_VMN != teleService)) { + if ((SmsEnvelope.TELESERVICE_VMN == teleService) || + (SmsEnvelope.TELESERVICE_MWI == teleService)) { + // handling Voicemail + int voicemailCount = sms.getNumOfVoicemails(); + Log.d(TAG, "Voicemail count=" + voicemailCount); + // Store the voicemail count in preferences. + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( + ((CDMAPhone) mPhone).getContext()); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); + editor.commit(); + ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); + handled = true; + } else if ((sms.getUserData() == null)) { if (Config.LOGD) { Log.d(TAG, "Received SMS without user data"); } @@ -103,22 +116,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_HANDLED; } + if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { + // It's a storable message and there's no storage available. Bail. + // (See C.S0015-B v2.0 for a description of "Immediate Display" + // messages, which we represent as CLASS_0.) + return Intents.RESULT_SMS_OUT_OF_MEMORY; + } + if (SmsEnvelope.TELESERVICE_WAP == teleService) { return processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress()); - } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) || - (SmsEnvelope.TELESERVICE_MWI == teleService)) { - // handling Voicemail - int voicemailCount = sms.getNumOfVoicemails(); - Log.d(TAG, "Voicemail count=" + voicemailCount); - // Store the voicemail count in preferences. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( - ((CDMAPhone) mPhone).getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); - editor.commit(); - ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); - return Intents.RESULT_SMS_HANDLED; } /** diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index b412fec..0ca3148 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.SmsMessageBase; import java.util.ArrayList; import java.util.HashMap; +import static android.telephony.SmsMessage.MessageClass; final class GsmSMSDispatcher extends SMSDispatcher { private static final String TAG = "GSM"; @@ -111,6 +112,12 @@ final class GsmSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_HANDLED; } + if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { + // It's a storable message and there's no storage available. Bail. + // (See TS 23.038 for a description of class 0 messages.) + return Intents.RESULT_SMS_OUT_OF_MEMORY; + } + SmsHeader smsHeader = sms.getUserDataHeader(); // See if message is partial or port addressed. if ((smsHeader == null) || (smsHeader.concatRef == null)) { |
