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