am c3b7e4e7: Merge change 2736 into donut

Merge commit 'c3b7e4e7dda7a81e7f1017f17adb717ffb3d50d2'

* commit 'c3b7e4e7dda7a81e7f1017f17adb717ffb3d50d2':
  Telephony support for SMS memory reporting to the network.
This commit is contained in:
Android (Google) Code Review
2009-05-29 15:17:27 -07:00
committed by The Android Open Source Project
10 changed files with 186 additions and 53 deletions

View File

@@ -2854,12 +2854,12 @@ public final class Settings {
* out without asking for use permit, to limit the un-authorized SMS
* usage.
*/
public static final String SMS_OUTGOING_CEHCK_INTERVAL_MS =
public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
"sms_outgoing_check_interval_ms";
/**
* The number of outgoing SMS sent without asking for user permit
* (of {@link #SMS_OUTGOING_CEHCK_INTERVAL_MS}
* (of {@link #SMS_OUTGOING_CHECK_INTERVAL_MS}
*/
public static final String SMS_OUTGOING_CEHCK_MAX_COUNT =
"sms_outgoing_check_max_count";

View File

@@ -465,6 +465,24 @@ public final class Telephony {
* Contains info about SMS related Intents that are broadcast.
*/
public static final class Intents {
/**
* Set by BroadcastReceiver. Indicates the message was handled
* successfully.
*/
public static final int RESULT_SMS_HANDLED = 1;
/**
* Set by BroadcastReceiver. Indicates a generic error while
* processing the message.
*/
public static final int RESULT_SMS_GENERIC_ERROR = 2;
/**
* Set by BroadcastReceiver. Indicates insufficient memory to store
* the message.
*/
public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
/**
* Broadcast Action: A new text based SMS message has been received
* by the device. The intent will have the following extra
@@ -476,7 +494,10 @@ public final class Telephony {
* </ul>
*
* <p>The extra values can be extracted using
* {@link #getMessagesFromIntent(Intent)}</p>
* {@link #getMessagesFromIntent(Intent)}.</p>
*
* <p>If a BroadcastReceiver encounters an error while processing
* this intent it should set the result code appropriately.</p>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SMS_RECEIVED_ACTION =
@@ -493,7 +514,10 @@ public final class Telephony {
* </ul>
*
* <p>The extra values can be extracted using
* {@link #getMessagesFromIntent(Intent)}</p>
* {@link #getMessagesFromIntent(Intent)}.</p>
*
* <p>If a BroadcastReceiver encounters an error while processing
* this intent it should set the result code appropriately.</p>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String DATA_SMS_RECEIVED_ACTION =
@@ -510,6 +534,9 @@ public final class Telephony {
* <li><em>pduType (Integer)</em> - The WAP PDU type</li>
* <li><em>data</em> - The data payload of the message</li>
* </ul>
*
* <p>If a BroadcastReceiver encounters an error while processing
* this intent it should set the result code appropriately.</p>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String WAP_PUSH_RECEIVED_ACTION =

View File

@@ -147,6 +147,14 @@ public interface CommandsInterface {
static final int SIM_REFRESH_INIT = 1; // SIM initialized; reload all
static final int SIM_REFRESH_RESET = 2; // SIM reset; may be locked
// GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0xD3;
static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR = 0xFF;
// CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms. From TS N.S00005, 6.5.2.125.
static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE = 35;
static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM = 39;
//***** Methods
RadioState getRadioState();
@@ -882,9 +890,9 @@ public interface CommandsInterface {
void setRadioPower(boolean on, Message response);
void acknowledgeLastIncomingSMS(boolean success, Message response);
void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
void acknowledgeLastIncomingCdmaSms(boolean success, Message response);
void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
/**
* parameters equivilient to 27.007 AT+CRSM command
@@ -1087,6 +1095,12 @@ public interface CommandsInterface {
*/
void setSmscAddress(String address, Message result);
/**
* Indicates whether there is storage available for new SMS messages.
* @param available true if storage is available
* @param result callback message
*/
void reportSmsMemoryStatus(boolean available, Message result);
void invokeOemRilRequestRaw(byte[] data, Message response);

View File

@@ -1339,28 +1339,32 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void
acknowledgeLastIncomingSMS(boolean success, Message result) {
acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
rr.mp.writeInt(1);
rr.mp.writeInt(2);
rr.mp.writeInt(success ? 1 : 0);
rr.mp.writeInt(cause);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + success + " " + cause);
send(rr);
}
public void
acknowledgeLastIncomingCdmaSms(boolean success, Message result) {
acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result);
rr.mp.writeInt(2);
rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
// cause code according to X.S004-550E
rr.mp.writeInt(39); //39 means other terminal problem; is not interpreted for success.
rr.mp.writeInt(cause);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + success + " " + cause);
send(rr);
}
@@ -1812,6 +1816,20 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
/**
* {@inheritDoc}
*/
public void reportSmsMemoryStatus(boolean available, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result);
rr.mp.writeInt(1);
rr.mp.writeInt(available ? 1 : 0);
if (RILJ_LOGD) riljLog(rr.serialString() + "> "
+ requestToString(rr.mRequest) + ": " + available);
send(rr);
}
//***** Private Methods
private void sendScreenState(boolean on) {

View File

@@ -222,6 +222,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99;
int RIL_REQUEST_GET_SMSC_ADDRESS = 100;
int RIL_REQUEST_SET_SMSC_ADDRESS = 101;
int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;

View File

@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.PendingIntent;
import android.app.AlertDialog;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -32,6 +33,7 @@ import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.provider.Settings;
@@ -128,6 +130,15 @@ public abstract class SMSDispatcher extends Handler {
private SmsTracker mSTracker;
/** Wake lock to ensure device stays awake while dispatching the SMS intent. */
private PowerManager.WakeLock mWakeLock;
/**
* Hold the wake lock for 5 seconds, which should be enough time for
* any receiver(s) to grab its own wake lock.
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
private static SmsMessage mSmsMessage;
private static SmsMessageBase mSmsMessageBase;
private SmsMessageBase.SubmitPduBase mSubmitPduBase;
@@ -196,14 +207,16 @@ public abstract class SMSDispatcher extends Handler {
protected SMSDispatcher(PhoneBase phone) {
mPhone = phone;
mWapPush = new WapPushOverSms(phone);
mWapPush = new WapPushOverSms(phone, this);
mContext = phone.getContext();
mResolver = mContext.getContentResolver();
mCm = phone.mCM;
mSTracker = null;
createWakelock();
int check_period = Settings.Gservices.getInt(mResolver,
Settings.Gservices.SMS_OUTGOING_CEHCK_INTERVAL_MS,
Settings.Gservices.SMS_OUTGOING_CHECK_INTERVAL_MS,
DEFAULT_SMS_CHECK_PERIOD);
int max_count = Settings.Gservices.getInt(mResolver,
Settings.Gservices.SMS_OUTGOING_CEHCK_MAX_COUNT,
@@ -257,16 +270,17 @@ public abstract class SMSDispatcher extends Handler {
ar = (AsyncResult) msg.obj;
// FIXME only acknowledge on store
acknowledgeLastIncomingSms(true, null);
if (ar.exception != null) {
Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
return;
}
sms = (SmsMessage) ar.result;
dispatchMessage(sms.mWrappedSmsMessage);
try {
dispatchMessage(sms.mWrappedSmsMessage);
} catch (RuntimeException ex) {
acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
}
break;
@@ -310,6 +324,28 @@ public abstract class SMSDispatcher extends Handler {
}
}
private void createWakelock() {
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SMSDispatcher");
mWakeLock.setReferenceCounted(true);
}
/**
* Grabs a wake lock and sends intent as an ordered broadcast.
* The resultReceiver will check for errors and ACK/NACK back
* to the RIL.
*
* @param intent intent to broadcast
* @param permission Receivers are required to have this permission
*/
void dispatch(Intent intent, String permission) {
// Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
// receivers time to take their own wake locks.
mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,
this, Activity.RESULT_OK, null, null);
}
/**
* Called when SIM_FULL message is received from the RIL. Notifies interested
* parties that SIM storage for SMS messages is full.
@@ -317,7 +353,8 @@ public abstract class SMSDispatcher extends Handler {
private void handleIccFull(){
// broadcast SIM_FULL intent
Intent intent = new Intent(Intents.SIM_FULL_ACTION);
mPhone.getContext().sendBroadcast(intent, "android.permission.RECEIVE_SMS");
mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
}
/**
@@ -454,6 +491,7 @@ public abstract class SMSDispatcher extends Handler {
values.put("destination_port", portAddrs.destPort);
}
mResolver.insert(mRawUri, values);
acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
return;
}
@@ -475,7 +513,9 @@ public abstract class SMSDispatcher extends Handler {
mResolver.delete(mRawUri, where.toString(), whereArgs);
} catch (SQLException e) {
Log.e(TAG, "Can't access multipart SMS database", e);
return; // TODO: NACK the message or something, don't just discard.
// TODO: Would OUT_OF_MEMORY be more appropriate?
acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
return;
} finally {
if (cursor != null) cursor.close();
}
@@ -519,8 +559,7 @@ public abstract class SMSDispatcher extends Handler {
protected void dispatchPdus(byte[][] pdus) {
Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
intent.putExtra("pdus", pdus);
mPhone.getContext().sendBroadcast(
intent, "android.permission.RECEIVE_SMS");
dispatch(intent, "android.permission.RECEIVE_SMS");
}
/**
@@ -533,8 +572,7 @@ public abstract class SMSDispatcher extends Handler {
Uri uri = Uri.parse("sms://localhost:" + port);
Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
intent.putExtra("pdus", pdus);
mPhone.getContext().sendBroadcast(
intent, "android.permission.RECEIVE_SMS");
dispatch(intent, "android.permission.RECEIVE_SMS");
}
@@ -698,9 +736,11 @@ public abstract class SMSDispatcher extends Handler {
/**
* Send an acknowledge message.
* @param success indicates that last message was successfully received.
* @param result result code indicating any error
* @param response callback message sent when operation completes.
*/
protected abstract void acknowledgeLastIncomingSms(boolean success, Message response);
protected abstract void acknowledgeLastIncomingSms(boolean success,
int result, Message response);
/**
* Check if a SmsTracker holds multi-part Sms
@@ -751,4 +791,17 @@ public abstract class SMSDispatcher extends Handler {
}
}
};
private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int rc = getResultCode();
boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED);
// For a multi-part message, this only ACKs the last part.
// Previous parts were ACK'd as they were received.
acknowledgeLastIncomingSms(success, rc, null);
}
};
}

View File

@@ -18,7 +18,6 @@ package com.android.internal.telephony;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.provider.Telephony.Sms.Intents;
import android.util.Config;
import android.util.Log;
@@ -34,7 +33,7 @@ public class WapPushOverSms {
private final Context mContext;
private WspTypeDecoder pduDecoder;
private PowerManager.WakeLock mWakeLock;
private SMSDispatcher mSmsDispatcher;
/**
* Hold the wake lock for 5 seconds, which should be enough time for
@@ -42,10 +41,9 @@ public class WapPushOverSms {
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
public WapPushOverSms(Phone phone) {
public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
mSmsDispatcher = smsDispatcher;
mContext = phone.getContext();
createWakelock();
}
/**
@@ -184,7 +182,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", data);
sendBroadcast(intent, "android.permission.RECEIVE_WAP_PUSH");
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) {
@@ -194,7 +192,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", pdu);
sendBroadcast(intent, "android.permission.RECEIVE_WAP_PUSH");
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) {
@@ -209,20 +207,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", data);
sendBroadcast(intent, "android.permission.RECEIVE_MMS");
}
private void createWakelock() {
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WapPushOverSms");
mWakeLock.setReferenceCounted(true);
}
private void sendBroadcast(Intent intent, String permission) {
// Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
// receivers time to take their own wake locks.
mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
mContext.sendBroadcast(intent, permission);
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
}
}

View File

@@ -17,15 +17,18 @@
package com.android.internal.telephony.cdma;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.os.AsyncResult;
import android.os.Message;
import android.provider.Telephony.Sms.Intents;
import android.util.Config;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SMSDispatcher;
@@ -330,10 +333,10 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
protected void acknowledgeLastIncomingSms(boolean success, Message response){
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
if (mCm != null) {
mCm.acknowledgeLastIncomingCdmaSms(success, response);
mCm.acknowledgeLastIncomingCdmaSms(success, resultToCause(result), response);
}
}
@@ -352,4 +355,17 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
mCm.setCdmaBroadcastConfig(configValuesArray, response);
}
private int resultToCause(int rc) {
switch (rc) {
case Activity.RESULT_OK:
case Intents.RESULT_SMS_HANDLED:
// Cause code is ignored on success.
return 0;
case Intents.RESULT_SMS_OUT_OF_MEMORY:
return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE;
case Intents.RESULT_SMS_GENERIC_ERROR:
default:
return CommandsInterface.CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM;
}
}
}

View File

@@ -22,12 +22,14 @@ import android.app.PendingIntent.CanceledException;
import android.content.Intent;
import android.os.AsyncResult;
import android.os.Message;
import android.provider.Telephony.Sms.Intents;
import android.telephony.ServiceState;
import android.util.Config;
import android.util.Log;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.gsm.SmsMessage;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.SMSDispatcher;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
@@ -78,7 +80,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
if (mCm != null) {
mCm.acknowledgeLastIncomingSMS(true, null);
mCm.acknowledgeLastIncomingGsmSms(true, Intents.RESULT_SMS_HANDLED, null);
}
}
@@ -284,10 +286,10 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
protected void acknowledgeLastIncomingSms(boolean success, Message response){
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
if (mCm != null) {
mCm.acknowledgeLastIncomingSMS(success, response);
mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
}
}
@@ -312,4 +314,17 @@ final class GsmSMSDispatcher extends SMSDispatcher {
response.recycle();
}
private int resultToCause(int rc) {
switch (rc) {
case Activity.RESULT_OK:
case Intents.RESULT_SMS_HANDLED:
// Cause code is ignored on success.
return 0;
case Intents.RESULT_SMS_OUT_OF_MEMORY:
return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED;
case Intents.RESULT_SMS_GENERIC_ERROR:
default:
return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR;
}
}
}

View File

@@ -1018,6 +1018,10 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(result);
}
public void reportSmsMemoryStatus(boolean available, Message result) {
unimplemented(result);
}
private boolean isSimLocked() {
if (mSimLockedState != SimLockState.NONE) {
return true;
@@ -1041,11 +1045,11 @@ public final class SimulatedCommands extends BaseCommands
}
public void acknowledgeLastIncomingSMS(boolean success, Message result) {
public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
unimplemented(result);
}
public void acknowledgeLastIncomingCdmaSms(boolean success, Message result) {
public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
unimplemented(result);
}