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