blob: 57ce365aca463962fb5f1db6412191b3feac8853 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony.cts;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests for {@link android.telephony.SmsManager}.
*
* Structured so tests can be reused to test {@link android.telephony.gsm.SmsManager}
*/
@TestTargetClass(SmsManager.class)
public class SmsManagerTest extends AndroidTestCase {
private static final int NUM_TEXT_PARTS = 3;
private static final String LONG_TEXT =
"This is a very long text. This text should be broken into three " +
"separate messages.This is a very long text. This text should be broken into " +
"three separate messages.This is a very long text. This text should be broken " +
"into three separate messages.This is a very long text. This text should be " +
"broken into three separate messages.";;
private static final String SMS_SEND_ACTION = "CTS_SMS_SEND_ACTION";
private static final String SMS_DELIVERY_ACTION = "CTS_SMS_DELIVERY_ACTION";
// List of network operators that don't support SMS delivery report
private static final List<String> NO_DELIVERY_REPORTS =
Arrays.asList(
"310410", // AT&T Mobility
"44010", // NTT DOCOMO
"45005", // SKT Mobility
"45002", // SKT Mobility
"45008" // KT Mobility
);
// List of network operators that doesn't support Data(binary) SMS message
private static final List<String> UNSUPPORT_DATA_SMS_MESSAGES =
Arrays.asList(
"44010" // NTT DOCOMO
);
// List of network operators that doesn't support Maltipart SMS message
private static final List<String> UNSUPPORT_MULTIPART_SMS_MESSAGES =
Arrays.asList(
"44010" // NTT DOCOMO
);
private TelephonyManager mTelephonyManager;
private PackageManager mPackageManager;
private String mDestAddr;
private String mText;
private SmsBroadcastReceiver mSendReceiver;
private SmsBroadcastReceiver mDeliveryReceiver;
private PendingIntent mSentIntent;
private PendingIntent mDeliveredIntent;
private Intent mSendIntent;
private Intent mDeliveryIntent;
private boolean mDeliveryReportSupported;
private static final int TIME_OUT = 1000 * 60 * 5;
@Override
protected void setUp() throws Exception {
super.setUp();
mTelephonyManager =
(TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
mPackageManager = mContext.getPackageManager();
mDestAddr = mTelephonyManager.getLine1Number();
mText = "This is a test message";
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
mDeliveryReportSupported = false;
} else if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
// CDMA supports SMS delivery report
mDeliveryReportSupported = true;
} else {
// is this a GSM network that doesn't support SMS delivery report?
String mccmnc = mTelephonyManager.getSimOperator();
mDeliveryReportSupported = !(NO_DELIVERY_REPORTS.contains(mccmnc));
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "divideMessage",
args = {String.class}
)
public void testDivideMessage() {
ArrayList<String> dividedMessages = divideMessage(LONG_TEXT);
assertNotNull(dividedMessages);
assertEquals(NUM_TEXT_PARTS, dividedMessages.size());
assertEquals(LONG_TEXT,
dividedMessages.get(0) + dividedMessages.get(1) + dividedMessages.get(2));
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "sendDataMessage",
args = {String.class, String.class, short.class, byte[].class,
PendingIntent.class, PendingIntent.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "sendTextMessage",
args = {String.class, String.class, String.class, PendingIntent.class,
PendingIntent.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "sendMultipartTextMessage",
args = {String.class, String.class, ArrayList.class, ArrayList.class, ArrayList.class}
)
})
public void testSendMessages() throws InterruptedException {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return;
}
String mccmnc = mTelephonyManager.getSimOperator();
mSendIntent = new Intent(SMS_SEND_ACTION);
mDeliveryIntent = new Intent(SMS_DELIVERY_ACTION);
IntentFilter sendIntentFilter = new IntentFilter(SMS_SEND_ACTION);
IntentFilter deliveryIntentFilter = new IntentFilter(SMS_DELIVERY_ACTION);
mSendReceiver = new SmsBroadcastReceiver(SMS_SEND_ACTION);
mDeliveryReceiver = new SmsBroadcastReceiver(SMS_DELIVERY_ACTION);
getContext().registerReceiver(mSendReceiver, sendIntentFilter);
getContext().registerReceiver(mDeliveryReceiver, deliveryIntentFilter);
// send single text sms
init();
sendTextMessage(mDestAddr, mDestAddr, mSentIntent, mDeliveredIntent);
assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT));
if (mDeliveryReportSupported) {
assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT));
}
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
// TODO: temp workaround, OCTET encoding for EMS not properly supported
return;
}
// send data sms
if (!UNSUPPORT_DATA_SMS_MESSAGES.contains(mccmnc)) {
byte[] data = mText.getBytes();
short port = 19989;
init();
sendDataMessage(mDestAddr, port, data, mSentIntent, mDeliveredIntent);
assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT));
if (mDeliveryReportSupported) {
assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT));
}
} else {
// This GSM network doesn't support Data(binary) SMS message.
// Skip the test.
}
// send multi parts text sms
if (!UNSUPPORT_MULTIPART_SMS_MESSAGES.contains(mccmnc)) {
init();
ArrayList<String> parts = divideMessage(LONG_TEXT);
int numParts = parts.size();
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
for (int i = 0; i < numParts; i++) {
sentIntents.add(PendingIntent.getBroadcast(getContext(), 0, mSendIntent, 0));
deliveryIntents.add(PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent, 0));
}
sendMultiPartTextMessage(mDestAddr, parts, sentIntents, deliveryIntents);
assertTrue(mSendReceiver.waitForCalls(numParts, TIME_OUT));
if (mDeliveryReportSupported) {
assertTrue(mDeliveryReceiver.waitForCalls(numParts, TIME_OUT));
}
} else {
// This GSM network doesn't support Multipart SMS message.
// Skip the test.
}
}
private void init() {
mSendReceiver.reset();
mDeliveryReceiver.reset();
mSentIntent = PendingIntent.getBroadcast(getContext(), 0, mSendIntent,
PendingIntent.FLAG_ONE_SHOT);
mDeliveredIntent = PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent,
PendingIntent.FLAG_ONE_SHOT);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getDefault",
args = {}
)
public void testGetDefault() {
assertNotNull(getSmsManager());
}
protected ArrayList<String> divideMessage(String text) {
return getSmsManager().divideMessage(text);
}
private android.telephony.SmsManager getSmsManager() {
return android.telephony.SmsManager.getDefault();
}
protected void sendMultiPartTextMessage(String destAddr, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, deliveryIntents);
}
protected void sendDataMessage(String destAddr,short port, byte[] data, PendingIntent sentIntent, PendingIntent deliveredIntent) {
getSmsManager().sendDataMessage(destAddr, null, port, data, sentIntent, deliveredIntent);
}
protected void sendTextMessage(String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveredIntent) {
getSmsManager().sendTextMessage(destAddr, null, text, sentIntent, deliveredIntent);
}
private static class SmsBroadcastReceiver extends BroadcastReceiver {
private int mCalls;
private int mExpectedCalls;
private String mAction;
private Object mLock;
SmsBroadcastReceiver(String action) {
mAction = action;
reset();
mLock = new Object();
}
void reset() {
mExpectedCalls = Integer.MAX_VALUE;
mCalls = 0;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(mAction)) {
synchronized (mLock) {
mCalls += 1;
if (mCalls >= mExpectedCalls) {
mLock.notify();
}
}
}
}
public boolean waitForCalls(int expectedCalls, long timeout) throws InterruptedException {
synchronized(mLock) {
mExpectedCalls = expectedCalls;
long startTime = SystemClock.elapsedRealtime();
while (mCalls < mExpectedCalls) {
long waitTime = timeout - (SystemClock.elapsedRealtime() - startTime);
if (waitTime > 0) {
mLock.wait(waitTime);
} else {
return false; // timed out
}
}
return true; // success
}
}
}
}