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 // Verizon 92 "310004", 93 "310012", 94 "311280", 95 "311281", 96 "311282", 97 "311283", 98 "311284", 99 "311285", 100 "311286", 101 "311287", 102 "311288", 103 "311289", 104 "311480", 105 "311481", 106 "311482", 107 "311483", 108 "311484", 109 "311485", 110 "311486", 111 "311487", 112 "311488", 113 "311489" 114 ); 115 116 // List of network operators that doesn't support Data(binary) SMS message 117 private static final List<String> UNSUPPORT_DATA_SMS_MESSAGES = 118 Arrays.asList( 119 "44010", // NTT DOCOMO 120 "44020", // SBM 121 "302720", // Rogers 122 "30272", // Rogers 123 "302370", // Fido 124 "30237", // Fido 125 "45008", // KT 126 "45005", // SKT Mobility 127 "45002", // SKT Mobility 128 // Verizon 129 "310004", 130 "310012", 131 "311280", 132 "311281", 133 "311282", 134 "311283", 135 "311284", 136 "311285", 137 "311286", 138 "311287", 139 "311288", 140 "311289", 141 "311480", 142 "311481", 143 "311482", 144 "311483", 145 "311484", 146 "311485", 147 "311486", 148 "311487", 149 "311488", 150 "311489" 151 ); 152 153 // List of network operators that doesn't support Maltipart SMS message 154 private static final List<String> UNSUPPORT_MULTIPART_SMS_MESSAGES = 155 Arrays.asList( 156 "44010", // NTT DOCOMO 157 "44020", // SBM 158 "302720", // Rogers 159 "30272", // Rogers 160 "302370", // Fido 161 "30237", // Fido 162 "45008" // KT 163 ); 164 165 private TelephonyManager mTelephonyManager; 166 private PackageManager mPackageManager; 167 private String mDestAddr; 168 private String mText; 169 private SmsBroadcastReceiver mSendReceiver; 170 private SmsBroadcastReceiver mDeliveryReceiver; 171 private SmsBroadcastReceiver mDataSmsReceiver; 172 private PendingIntent mSentIntent; 173 private PendingIntent mDeliveredIntent; 174 private Intent mSendIntent; 175 private Intent mDeliveryIntent; 176 private boolean mDeliveryReportSupported; 177 private static boolean mReceivedDataSms; 178 private static String mReceivedText; 179 180 private static final int TIME_OUT = 1000 * 60 * 5; 181 182 @Override 183 protected void setUp() throws Exception { 184 super.setUp(); 185 mTelephonyManager = 186 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 187 mPackageManager = mContext.getPackageManager(); 188 mDestAddr = mTelephonyManager.getLine1Number(); 189 mText = "This is a test message"; 190 191 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 192 mDeliveryReportSupported = false; 193 } else { 194 // exclude the networks that don't support SMS delivery report 195 String mccmnc = mTelephonyManager.getSimOperator(); 196 mDeliveryReportSupported = !(NO_DELIVERY_REPORTS.contains(mccmnc)); 197 } 198 } 199 200 public void testDivideMessage() { 201 ArrayList<String> dividedMessages = divideMessage(LONG_TEXT); 202 assertNotNull(dividedMessages); 203 int numParts; 204 if (TelephonyUtils.isSkt(mTelephonyManager)) { 205 assertTrue(isComplete(dividedMessages, 5) || isComplete(dividedMessages, 3)); 206 } else if (TelephonyUtils.isKt(mTelephonyManager)) { 207 assertTrue(isComplete(dividedMessages, 4) || isComplete(dividedMessages, 3)); 208 } else { 209 assertTrue(isComplete(dividedMessages, 3)); 210 } 211 } 212 213 private boolean isComplete(List<String> dividedMessages, int numParts) { 214 if (dividedMessages.size() != numParts) { 215 return false; 216 } 217 218 String actualMessage = ""; 219 for (int i = 0; i < numParts; i++) { 220 actualMessage += dividedMessages.get(i); 221 } 222 return LONG_TEXT.equals(actualMessage); 223 } 224 225 public void testSendMessages() throws InterruptedException { 226 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 227 return; 228 } 229 230 String mccmnc = mTelephonyManager.getSimOperator(); 231 232 mSendIntent = new Intent(SMS_SEND_ACTION); 233 mDeliveryIntent = new Intent(SMS_DELIVERY_ACTION); 234 235 IntentFilter sendIntentFilter = new IntentFilter(SMS_SEND_ACTION); 236 IntentFilter deliveryIntentFilter = new IntentFilter(SMS_DELIVERY_ACTION); 237 IntentFilter dataSmsReceivedIntentFilter = new IntentFilter(DATA_SMS_RECEIVED_ACTION); 238 dataSmsReceivedIntentFilter.addDataScheme("sms"); 239 dataSmsReceivedIntentFilter.addDataAuthority("localhost", "19989"); 240 241 mSendReceiver = new SmsBroadcastReceiver(SMS_SEND_ACTION); 242 mDeliveryReceiver = new SmsBroadcastReceiver(SMS_DELIVERY_ACTION); 243 mDataSmsReceiver = new SmsBroadcastReceiver(DATA_SMS_RECEIVED_ACTION); 244 245 getContext().registerReceiver(mSendReceiver, sendIntentFilter); 246 getContext().registerReceiver(mDeliveryReceiver, deliveryIntentFilter); 247 getContext().registerReceiver(mDataSmsReceiver, dataSmsReceivedIntentFilter); 248 249 // send single text sms 250 init(); 251 sendTextMessage(mDestAddr, mDestAddr, mSentIntent, mDeliveredIntent); 252 assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT)); 253 if (mDeliveryReportSupported) { 254 assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT)); 255 } 256 257 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 258 // TODO: temp workaround, OCTET encoding for EMS not properly supported 259 return; 260 } 261 262 // send data sms 263 if (!UNSUPPORT_DATA_SMS_MESSAGES.contains(mccmnc)) { 264 byte[] data = mText.getBytes(); 265 short port = 19989; 266 267 init(); 268 sendDataMessage(mDestAddr, port, data, mSentIntent, mDeliveredIntent); 269 assertTrue(mSendReceiver.waitForCalls(1, TIME_OUT)); 270 if (mDeliveryReportSupported) { 271 assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT)); 272 } 273 mDataSmsReceiver.waitForCalls(1, TIME_OUT); 274 assertTrue(mReceivedDataSms); 275 assertEquals(mReceivedText, mText); 276 } else { 277 // This GSM network doesn't support Data(binary) SMS message. 278 // Skip the test. 279 } 280 281 // send multi parts text sms 282 if (!UNSUPPORT_MULTIPART_SMS_MESSAGES.contains(mccmnc)) { 283 init(); 284 ArrayList<String> parts = divideMessage(LONG_TEXT); 285 int numParts = parts.size(); 286 ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(); 287 ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(); 288 for (int i = 0; i < numParts; i++) { 289 sentIntents.add(PendingIntent.getBroadcast(getContext(), 0, mSendIntent, 0)); 290 deliveryIntents.add(PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent, 0)); 291 } 292 sendMultiPartTextMessage(mDestAddr, parts, sentIntents, deliveryIntents); 293 assertTrue(mSendReceiver.waitForCalls(numParts, TIME_OUT)); 294 if (mDeliveryReportSupported) { 295 assertTrue(mDeliveryReceiver.waitForCalls(numParts, TIME_OUT)); 296 } 297 } else { 298 // This GSM network doesn't support Multipart SMS message. 299 // Skip the test. 300 } 301 } 302 303 private void init() { 304 mSendReceiver.reset(); 305 mDeliveryReceiver.reset(); 306 mDataSmsReceiver.reset(); 307 mReceivedDataSms = false; 308 mSentIntent = PendingIntent.getBroadcast(getContext(), 0, mSendIntent, 309 PendingIntent.FLAG_ONE_SHOT); 310 mDeliveredIntent = PendingIntent.getBroadcast(getContext(), 0, mDeliveryIntent, 311 PendingIntent.FLAG_ONE_SHOT); 312 } 313 314 public void testGetDefault() { 315 assertNotNull(getSmsManager()); 316 } 317 318 protected ArrayList<String> divideMessage(String text) { 319 return getSmsManager().divideMessage(text); 320 } 321 322 private android.telephony.SmsManager getSmsManager() { 323 return android.telephony.SmsManager.getDefault(); 324 } 325 326 protected void sendMultiPartTextMessage(String destAddr, ArrayList<String> parts, 327 ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { 328 getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, deliveryIntents); 329 } 330 331 protected void sendDataMessage(String destAddr,short port, byte[] data, PendingIntent sentIntent, PendingIntent deliveredIntent) { 332 getSmsManager().sendDataMessage(destAddr, null, port, data, sentIntent, deliveredIntent); 333 } 334 335 protected void sendTextMessage(String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveredIntent) { 336 getSmsManager().sendTextMessage(destAddr, null, text, sentIntent, deliveredIntent); 337 } 338 339 private static class SmsBroadcastReceiver extends BroadcastReceiver { 340 private int mCalls; 341 private int mExpectedCalls; 342 private String mAction; 343 private Object mLock; 344 345 SmsBroadcastReceiver(String action) { 346 mAction = action; 347 reset(); 348 mLock = new Object(); 349 } 350 351 void reset() { 352 mExpectedCalls = Integer.MAX_VALUE; 353 mCalls = 0; 354 } 355 356 @Override 357 public void onReceive(Context context, Intent intent) { 358 if(mAction.equals(DATA_SMS_RECEIVED_ACTION)){ 359 StringBuilder sb = new StringBuilder(); 360 Bundle bundle = intent.getExtras(); 361 if (bundle != null) { 362 Object[] obj = (Object[]) bundle.get("pdus"); 363 SmsMessage[] message = new SmsMessage[obj.length]; 364 for (int i = 0; i < obj.length; i++) { 365 message[i] = SmsMessage.createFromPdu((byte[]) obj[i]); 366 } 367 368 for (SmsMessage currentMessage : message) { 369 byte[] binaryContent = currentMessage.getUserData(); 370 String readableContent = new String(binaryContent); 371 sb.append(readableContent); 372 } 373 } 374 mReceivedDataSms = true; 375 mReceivedText=sb.toString(); 376 } 377 Log.i(TAG, "onReceive " + intent.getAction()); 378 if (intent.getAction().equals(mAction)) { 379 synchronized (mLock) { 380 mCalls += 1; 381 mLock.notify(); 382 } 383 } 384 } 385 386 public boolean waitForCalls(int expectedCalls, long timeout) throws InterruptedException { 387 synchronized(mLock) { 388 mExpectedCalls = expectedCalls; 389 long startTime = SystemClock.elapsedRealtime(); 390 391 while (mCalls < mExpectedCalls) { 392 long waitTime = timeout - (SystemClock.elapsedRealtime() - startTime); 393 if (waitTime > 0) { 394 mLock.wait(waitTime); 395 } else { 396 return false; // timed out 397 } 398 } 399 return true; // success 400 } 401 } 402 } 403 } 404