GsmInboundSmsHandler.java revision 0d4bcdf379842af4b6304809156971e926f374f0
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony.gsm; 18 19import android.app.Activity; 20import android.content.Context; 21import android.os.Message; 22import android.provider.Telephony.Sms.Intents; 23 24import com.android.internal.telephony.CommandsInterface; 25import com.android.internal.telephony.InboundSmsHandler; 26import com.android.internal.telephony.PhoneBase; 27import com.android.internal.telephony.SmsConstants; 28import com.android.internal.telephony.SmsMessageBase; 29import com.android.internal.telephony.SmsStorageMonitor; 30import com.android.internal.telephony.uicc.UsimServiceTable; 31 32/** 33 * This class broadcasts incoming SMS messages to interested apps after storing them in 34 * the SmsProvider "raw" table and ACKing them to the SMSC. After each message has been 35 */ 36public class GsmInboundSmsHandler extends InboundSmsHandler { 37 38 /** Handler for SMS-PP data download messages to UICC. */ 39 private final UsimDataDownloadHandler mDataDownloadHandler; 40 41 private final GsmCellBroadcastHandler mCellBroadcastDispatcher; 42 43 private final PhoneBase mPhone; 44 45 /** 46 * Create a new GSM inbound SMS handler. 47 */ 48 private GsmInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor, 49 PhoneBase phone) { 50 super("GsmInboundSmsHandler", context, storageMonitor); 51 mPhone = phone; 52 phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null); 53 mCellBroadcastDispatcher = GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(context, 54 phone); 55 mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi); 56 } 57 58 /** 59 * Unregister for GSM SMS. 60 */ 61 @Override 62 protected void onQuitting() { 63 mPhone.mCi.unSetOnNewGsmSms(getHandler()); 64 mCellBroadcastDispatcher.dispose(); 65 66 if (DBG) log("unregistered for 3GPP SMS"); 67 super.onQuitting(); // release wakelock 68 } 69 70 /** 71 * Wait for state machine to enter startup state. We can't send any messages until then. 72 */ 73 public static GsmInboundSmsHandler makeInboundSmsHandler(Context context, 74 SmsStorageMonitor storageMonitor, PhoneBase phone) { 75 GsmInboundSmsHandler handler = new GsmInboundSmsHandler(context, storageMonitor, phone); 76 handler.start(); 77 return handler; 78 } 79 80 /** 81 * Return true if this handler is for 3GPP2 messages; false for 3GPP format. 82 * @return false (3GPP) 83 */ 84 @Override 85 protected boolean is3gpp2() { 86 return false; 87 } 88 89 /** 90 * Handle type zero, SMS-PP data download, and 3GPP/CPHS MWI type SMS. Normal SMS messages 91 * are handled by {@link #dispatchNormalMessage} in parent class. 92 * 93 * @param smsb the SmsMessageBase object from the RIL 94 * @return a result code from {@link android.provider.Telephony.Sms.Intents}, 95 * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC 96 */ 97 @Override 98 protected int dispatchMessageRadioSpecific(SmsMessageBase smsb) { 99 SmsMessage sms = (SmsMessage) smsb; 100 101 if (sms.isTypeZero()) { 102 // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be 103 // Displayed/Stored/Notified. They should only be acknowledged. 104 log("Received short message type 0, Don't display or store it. Send Ack"); 105 return Intents.RESULT_SMS_HANDLED; 106 } 107 108 // Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section 7.1.1. 109 if (sms.isUsimDataDownload()) { 110 UsimServiceTable ust = mPhone.getUsimServiceTable(); 111 return mDataDownloadHandler.handleUsimDataDownload(ust, sms); 112 } 113 114 boolean handled = false; 115 if (sms.isMWISetMessage()) { 116 mPhone.setVoiceMessageWaiting(1, -1); // line 1: unknown number of msgs waiting 117 handled = sms.isMwiDontStore(); 118 if (DBG) log("Received voice mail indicator set SMS shouldStore=" + !handled); 119 } else if (sms.isMWIClearMessage()) { 120 mPhone.setVoiceMessageWaiting(1, 0); // line 1: no msgs waiting 121 handled = sms.isMwiDontStore(); 122 if (DBG) log("Received voice mail indicator clear SMS shouldStore=" + !handled); 123 } 124 if (handled) { 125 return Intents.RESULT_SMS_HANDLED; 126 } 127 128 if (!mStorageMonitor.isStorageAvailable() && 129 sms.getMessageClass() != SmsConstants.MessageClass.CLASS_0) { 130 // It's a storable message and there's no storage available. Bail. 131 // (See TS 23.038 for a description of class 0 messages.) 132 return Intents.RESULT_SMS_OUT_OF_MEMORY; 133 } 134 135 return dispatchNormalMessage(smsb); 136 } 137 138 /** 139 * Send an acknowledge message. 140 * @param success indicates that last message was successfully received. 141 * @param result result code indicating any error 142 * @param response callback message sent when operation completes. 143 */ 144 @Override 145 protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { 146 mPhone.mCi.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response); 147 } 148 149 /** 150 * Convert Android result code to 3GPP SMS failure cause. 151 * @param rc the Android SMS intent result value 152 * @return 0 for success, or a 3GPP SMS failure cause value 153 */ 154 private static int resultToCause(int rc) { 155 switch (rc) { 156 case Activity.RESULT_OK: 157 case Intents.RESULT_SMS_HANDLED: 158 // Cause code is ignored on success. 159 return 0; 160 case Intents.RESULT_SMS_OUT_OF_MEMORY: 161 return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED; 162 case Intents.RESULT_SMS_GENERIC_ERROR: 163 default: 164 return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR; 165 } 166 } 167} 168