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