Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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 
     17 package android.telephony.cts;
     18 
     19 
     20 import android.app.PendingIntent;
     21 import android.content.BroadcastReceiver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.IntentFilter;
     25 import android.content.pm.PackageManager;
     26 import android.os.Bundle;
     27 import android.os.SystemClock;
     28 import android.telephony.SmsManager;
     29 import android.telephony.SmsMessage;
     30 import android.telephony.TelephonyManager;
     31 import android.test.AndroidTestCase;
     32 import android.util.Log;
     33 
     34 import java.util.ArrayList;
     35 import java.util.Arrays;
     36 import java.util.List;
     37 
     38 /**
     39  * Tests for {@link android.telephony.SmsManager}.
     40  *
     41  * Structured so tests can be reused to test {@link android.telephony.gsm.SmsManager}
     42  */
     43 public class SmsManagerTest extends AndroidTestCase {
     44 
     45     private static final String TAG = "SmsManagerTest";
     46     private static final String LONG_TEXT =
     47         "This is a very long text. This text should be broken into three " +
     48         "separate messages.This is a very long text. This text should be broken into " +
     49         "three separate messages.This is a very long text. This text should be broken " +
     50         "into three separate messages.This is a very long text. This text should be " +
     51         "broken into three separate messages.";;
     52 
     53     private static final String SMS_SEND_ACTION = "CTS_SMS_SEND_ACTION";
     54     private static final String SMS_DELIVERY_ACTION = "CTS_SMS_DELIVERY_ACTION";
     55     private static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
     56 
     57     // List of network operators that don't support SMS delivery report
     58     private static final List<String> NO_DELIVERY_REPORTS =
     59             Arrays.asList(
     60                     "310410",   // AT&T Mobility
     61                     "44010",    // NTT DOCOMO
     62                     "45005",    // SKT Mobility
     63                     "45002",    // SKT Mobility
     64                     "45008",    // KT Mobility
     65                     "45006",    // LGT
     66                     "311660",   // MetroPCS
     67                     "310120",   // Sprint
     68                     "44053",    // KDDI
     69                     "44054",    // KDDI
     70                     "44070",    // KDDI
     71                     "44071",    // KDDI
     72                     "44072",    // KDDI
     73                     "44073",    // KDDI
     74                     "44074",    // KDDI
     75                     "44075",    // KDDI
     76                     "44076",    // KDDI
     77                     "311870",   // Boost Mobile
     78                     "311220",   // USCC
     79                     "311225",   // USCC LTE
     80                     "311580",   // USCC LTE
     81                     "302720",   // Rogers
     82                     "30272",    // Rogers
     83                     "302370",   // Fido
     84                     "30237",    // Fido
     85                     "311490",   // Virgin Mobile
     86                     "310000",   // Tracfone
     87                     "46003",    // China Telecom
     88                     "311230",   // C SPire Wireless + Celluar South
     89                     "310600",    // Cellcom
     90                     "31000",     // Republic Wireless US
     91                     "310026",     // T-Mobile US
     92                     // Verizon
     93                     "310004",
     94                     "310012",
     95                     "311280",
     96                     "311281",
     97                     "311282",
     98                     "311283",
     99                     "311284",
    100                     "311285",
    101                     "311286",
    102                     "311287",
    103                     "311288",
    104                     "311289",
    105                     "311480",
    106                     "311481",
    107                     "311482",
    108                     "311483",
    109                     "311484",
    110                     "311485",
    111                     "311486",
    112                     "311487",
    113                     "311488",
    114                     "311489"
    115             );
    116 
    117     // List of network operators that doesn't support Data(binary) SMS message
    118     private static final List<String> UNSUPPORT_DATA_SMS_MESSAGES =
    119             Arrays.asList(
    120                     "44010",    // NTT DOCOMO
    121                     "44020",    // SBM
    122                     "302720",   // Rogers
    123                     "30272",    // Rogers
    124                     "302370",   // Fido
    125                     "30237",    // Fido
    126                     "45008",    // KT
    127                     "45005",    // SKT Mobility
    128                     "45002",     // SKT Mobility
    129                     "45006",    // LGT
    130                     // Verizon
    131                     "310004",
    132                     "310012",
    133                     "311280",
    134                     "311281",
    135                     "311282",
    136                     "311283",
    137                     "311284",
    138                     "311285",
    139                     "311286",
    140                     "311287",
    141                     "311288",
    142                     "311289",
    143                     "311480",
    144                     "311481",
    145                     "311482",
    146                     "311483",
    147                     "311484",
    148                     "311485",
    149                     "311486",
    150                     "311487",
    151                     "311488",
    152                     "311489"
    153             );
    154 
    155     // List of network operators that doesn't support Maltipart SMS message
    156     private static final List<String> UNSUPPORT_MULTIPART_SMS_MESSAGES =
    157             Arrays.asList(
    158                     "44010",    // NTT DOCOMO
    159                     "44020",    // SBM
    160                     "302720",   // Rogers
    161                     "30272",    // Rogers
    162                     "302370",   // Fido
    163                     "30237",    // Fido
    164                     "45006",    // LGT
    165                     "45008"     // KT
    166             );
    167 
    168     private TelephonyManager mTelephonyManager;
    169     private PackageManager mPackageManager;
    170     private String mDestAddr;
    171     private String mText;
    172     private SmsBroadcastReceiver mSendReceiver;
    173     private SmsBroadcastReceiver mDeliveryReceiver;
    174     private SmsBroadcastReceiver mDataSmsReceiver;
    175     private PendingIntent mSentIntent;
    176     private PendingIntent mDeliveredIntent;
    177     private Intent mSendIntent;
    178     private Intent mDeliveryIntent;
    179     private boolean mDeliveryReportSupported;
    180     private static boolean mReceivedDataSms;
    181     private static String mReceivedText;
    182 
    183     private static final int TIME_OUT = 1000 * 60 * 5;
    184 
    185     @Override
    186     protected void setUp() throws Exception {
    187         super.setUp();
    188         mTelephonyManager =
    189             (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
    190         mPackageManager = mContext.getPackageManager();
    191         mDestAddr = mTelephonyManager.getLine1Number();
    192         mText = "This is a test message";
    193 
    194         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    195             mDeliveryReportSupported = false;
    196         } else {
    197             // exclude the networks that don't support SMS delivery report
    198             String mccmnc = mTelephonyManager.getSimOperator();
    199             mDeliveryReportSupported = !(NO_DELIVERY_REPORTS.contains(mccmnc));
    200         }
    201     }
    202 
    203     public void testDivideMessage() {
    204         ArrayList<String> dividedMessages = divideMessage(LONG_TEXT);
    205         assertNotNull(dividedMessages);
    206         int numParts;
    207         if (TelephonyUtils.isSkt(mTelephonyManager)) {
    208             assertTrue(isComplete(dividedMessages, 5) || isComplete(dividedMessages, 3));
    209         } else if (TelephonyUtils.isKt(mTelephonyManager)) {
    210             assertTrue(isComplete(dividedMessages, 4) || isComplete(dividedMessages, 3));
    211         } else {
    212             assertTrue(isComplete(dividedMessages, 3));
    213         }
    214     }
    215 
    216     private boolean isComplete(List<String> dividedMessages, int numParts) {
    217         if (dividedMessages.size() != numParts) {
    218             return false;
    219         }
    220 
    221         String actualMessage = "";
    222         for (int i = 0; i < numParts; i++) {
    223             actualMessage += dividedMessages.get(i);
    224         }
    225         return LONG_TEXT.equals(actualMessage);
    226     }
    227 
    228     public void testSendMessages() throws InterruptedException {
    229         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    230             return;
    231         }
    232 
    233         String mccmnc = mTelephonyManager.getSimOperator();
    234 
    235         mSendIntent = new Intent(SMS_SEND_ACTION);
    236         mDeliveryIntent = new Intent(SMS_DELIVERY_ACTION);
    237 
    238         IntentFilter sendIntentFilter = new IntentFilter(SMS_SEND_ACTION);
    239         IntentFilter deliveryIntentFilter = new IntentFilter(SMS_DELIVERY_ACTION);
    240         IntentFilter dataSmsReceivedIntentFilter = new IntentFilter(DATA_SMS_RECEIVED_ACTION);
    241         dataSmsReceivedIntentFilter.addDataScheme("sms");
    242         dataSmsReceivedIntentFilter.addDataAuthority("localhost", "19989");
    243 
    244         mSendReceiver = new SmsBroadcastReceiver(SMS_SEND_ACTION);
    245         mDeliveryReceiver = new SmsBroadcastReceiver(SMS_DELIVERY_ACTION);
    246         mDataSmsReceiver = new SmsBroadcastReceiver(DATA_SMS_RECEIVED_ACTION);
    247 
    248         getContext().registerReceiver(mSendReceiver, sendIntentFilter);
    249         getContext().registerReceiver(mDeliveryReceiver, deliveryIntentFilter);
    250         getContext().registerReceiver(mDataSmsReceiver, dataSmsReceivedIntentFilter);
    251 
    252         // send single text sms
    253         init();
    254         sendTextMessage(mDestAddr, mDestAddr, mSentIntent, mDeliveredIntent);
    255         assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT));
    256         if (mDeliveryReportSupported) {
    257             assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT));
    258         }
    259 
    260         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
    261             // TODO: temp workaround, OCTET encoding for EMS not properly supported
    262             return;
    263         }
    264 
    265         // send data sms
    266         if (!UNSUPPORT_DATA_SMS_MESSAGES.contains(mccmnc)) {
    267             byte[] data = mText.getBytes();
    268             short port = 19989;
    269 
    270             init();
    271             sendDataMessage(mDestAddr, port, data, mSentIntent, mDeliveredIntent);
    272             assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT));
    273             if (mDeliveryReportSupported) {
    274                 assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT));
    275             }
    276             mDataSmsReceiver.waitForCalls(1, TIME_OUT);
    277             assertTrue(mReceivedDataSms);
    278             assertEquals(mReceivedText, mText);
    279         } else {
    280             // This GSM network doesn't support Data(binary) SMS message.
    281             // Skip the test.
    282         }
    283 
    284         // send multi parts text sms
    285         if (!UNSUPPORT_MULTIPART_SMS_MESSAGES.contains(mccmnc)) {
    286             init();
    287             ArrayList<String> parts = divideMessage(LONG_TEXT);
    288             int numParts = parts.size();
    289             ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
    290             ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
    291             for (int i = 0; i < numParts; i++) {
    292                 sentIntents.add(PendingIntent.getBroadcast(getContext(), 0, mSendIntent, 0));
    293                 deliveryIntents.add(PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent, 0));
    294             }
    295             sendMultiPartTextMessage(mDestAddr, parts, sentIntents, deliveryIntents);
    296             assertTrue(mSendReceiver.waitForCalls(numParts, TIME_OUT));
    297             if (mDeliveryReportSupported) {
    298               assertTrue(mDeliveryReceiver.waitForCalls(numParts, TIME_OUT));
    299             }
    300         } else {
    301             // This GSM network doesn't support Multipart SMS message.
    302             // Skip the test.
    303         }
    304     }
    305 
    306     private void init() {
    307         mSendReceiver.reset();
    308         mDeliveryReceiver.reset();
    309         mDataSmsReceiver.reset();
    310         mReceivedDataSms = false;
    311         mSentIntent = PendingIntent.getBroadcast(getContext(), 0, mSendIntent,
    312                 PendingIntent.FLAG_ONE_SHOT);
    313         mDeliveredIntent = PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent,
    314                 PendingIntent.FLAG_ONE_SHOT);
    315     }
    316 
    317     public void testGetDefault() {
    318         assertNotNull(getSmsManager());
    319     }
    320 
    321     protected ArrayList<String> divideMessage(String text) {
    322         return getSmsManager().divideMessage(text);
    323     }
    324 
    325     private android.telephony.SmsManager getSmsManager() {
    326         return android.telephony.SmsManager.getDefault();
    327     }
    328 
    329     protected void sendMultiPartTextMessage(String destAddr, ArrayList<String> parts,
    330             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
    331         getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, deliveryIntents);
    332     }
    333 
    334     protected void sendDataMessage(String destAddr,short port, byte[] data, PendingIntent sentIntent, PendingIntent deliveredIntent) {
    335         getSmsManager().sendDataMessage(destAddr, null, port, data, sentIntent, deliveredIntent);
    336     }
    337 
    338     protected void sendTextMessage(String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveredIntent) {
    339         getSmsManager().sendTextMessage(destAddr, null, text, sentIntent, deliveredIntent);
    340     }
    341 
    342     private static class SmsBroadcastReceiver extends BroadcastReceiver {
    343         private int mCalls;
    344         private int mExpectedCalls;
    345         private String mAction;
    346         private Object mLock;
    347 
    348         SmsBroadcastReceiver(String action) {
    349             mAction = action;
    350             reset();
    351             mLock = new Object();
    352         }
    353 
    354         void reset() {
    355             mExpectedCalls = Integer.MAX_VALUE;
    356             mCalls = 0;
    357         }
    358 
    359         @Override
    360         public void onReceive(Context context, Intent intent) {
    361             if(mAction.equals(DATA_SMS_RECEIVED_ACTION)){
    362                 StringBuilder sb = new StringBuilder();
    363                 Bundle bundle = intent.getExtras();
    364                 if (bundle != null) {
    365                     Object[] obj = (Object[]) bundle.get("pdus");
    366                     SmsMessage[] message = new SmsMessage[obj.length];
    367                     for (int i = 0; i < obj.length; i++) {
    368                         message[i] = SmsMessage.createFromPdu((byte[]) obj[i]);
    369                     }
    370 
    371                     for (SmsMessage currentMessage : message) {
    372                         byte[] binaryContent = currentMessage.getUserData();
    373                         String readableContent = new String(binaryContent);
    374                         sb.append(readableContent);
    375                     }
    376                 }
    377                 mReceivedDataSms = true;
    378                 mReceivedText=sb.toString();
    379             }
    380             Log.i(TAG, "onReceive " + intent.getAction());
    381             if (intent.getAction().equals(mAction)) {
    382                 synchronized (mLock) {
    383                     mCalls += 1;
    384                     mLock.notify();
    385                 }
    386             }
    387         }
    388 
    389         public boolean waitForCalls(int expectedCalls, long timeout) throws InterruptedException {
    390             synchronized(mLock) {
    391                 mExpectedCalls = expectedCalls;
    392                 long startTime = SystemClock.elapsedRealtime();
    393 
    394                 while (mCalls < mExpectedCalls) {
    395                     long waitTime = timeout - (SystemClock.elapsedRealtime() - startTime);
    396                     if (waitTime > 0) {
    397                         mLock.wait(waitTime);
    398                     } else {
    399                         return false;  // timed out
    400                     }
    401                 }
    402                 return true;  // success
    403             }
    404         }
    405     }
    406 }
    407