1 /*
2  * Copyright (C) 2008 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 com.android.basicsmsreceiver;
18 
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 import android.app.Activity;
23 import android.app.PendingIntent;
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.database.Cursor;
29 import android.graphics.Color;
30 import android.os.Bundle;
31 import android.provider.Telephony;
32 import android.telephony.SmsManager;
33 import android.telephony.SmsMessage;
34 import android.telephony.TelephonyManager;
35 import android.test.ActivityInstrumentationTestCase2;
36 import android.test.suitebuilder.annotation.MediumTest;
37 import android.test.suitebuilder.annotation.SmallTest;
38 import android.test.suitebuilder.annotation.LargeTest;
39 import android.util.Log;
40 
41 /**
42  * Various instrumentation tests for BasicSmsReceiver.
43  *
44  * To run this test: runtest basicsmsreceiver
45  *
46  * TODO: write tests that verify that notifications get created. As of now, I don't see a way
47  * to query the NotificationManager for what notifications are there. I only see methods to
48  * post and cancel notifications.
49  *
50  */
51 public class DialogSmsDisplayTests
52         extends ActivityInstrumentationTestCase2<DialogSmsDisplay> {
53 
54     private boolean mHasSms;
55     private String mMyNumber;       // phone number of this device
56     public static final String ACTION_SMS_SENT =
57         "com.android.basicsmsreceiver.tests.SMS_SENT_ACTION";
58     private static String TAG = "DialogSmsDisplayTests";
59     private List<String> mReceivedMessages = new ArrayList<String>();
60     private String mReceivedSender;
61     private DialogSmsDisplay dialogSmsDisplayActivity;
62     private int mMessageReceivedCount;
63     private BroadcastReceiver mSmsSenderReceiver;
64     private BroadcastReceiver mSmsReceiverReceiver;
65 
DialogSmsDisplayTests()66     public DialogSmsDisplayTests() {
67         super("com.android.basicsmsreceiver", DialogSmsDisplay.class);
68         Log.i(TAG, "DialogSmsDisplayTests");
69     }
70 
71     @Override
setUp()72     protected void setUp() throws Exception {
73         super.setUp();
74 
75         dialogSmsDisplayActivity = (DialogSmsDisplay)getActivity();
76 
77         TelephonyManager telephonyManager = ((TelephonyManager)dialogSmsDisplayActivity
78                 .getSystemService(Context.TELEPHONY_SERVICE));
79         mHasSms = true;     //telephonyManager.isSmsCapable();
80         mMyNumber = telephonyManager.getLine1Number();
81 
82         Log.i(TAG, "hasSms: " + mHasSms + " my number: " + mMyNumber);
83 
84         assertTrue("SMS must be enabled on the device", mHasSms);
85         assertNotNull("Device does not have a phone number", mMyNumber);
86 
87         if (mHasSms) {
88             // Register broadcast receivers for SMS sent and delivered intents
89             mSmsSenderReceiver = new BroadcastReceiver() {
90                 @Override
91                 public void onReceive(Context context, Intent intent) {
92                     String message = null;
93                     boolean error = true;
94                     switch (getResultCode()) {
95                         case Activity.RESULT_OK:
96                             message = "Message sent!";
97                             error = false;
98                             break;
99                         case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
100                             message = "Error.";
101                             break;
102                         case SmsManager.RESULT_ERROR_NO_SERVICE:
103                             message = "Error: No SMS service.";
104                             break;
105                         case SmsManager.RESULT_ERROR_NULL_PDU:
106                             message = "Error: Null PDU.";
107                             break;
108                         case SmsManager.RESULT_ERROR_RADIO_OFF:
109                             message = "Error: Radio off.";
110                             break;
111                     }
112                     assertFalse(message, error);
113                 }
114             };
115             dialogSmsDisplayActivity.registerReceiver(mSmsSenderReceiver,
116                     new IntentFilter(ACTION_SMS_SENT));
117 
118             // Register broadcast receivers for received SMS
119             mSmsReceiverReceiver = new BroadcastReceiver() {
120                 @Override
121                 public void onReceive(Context context, Intent intent) {
122                     Bundle extras = intent.getExtras();
123                     Log.i(TAG, "onReceive");
124                     if (extras == null)
125                         return;
126 
127                     Object[] pdus = (Object[]) extras.get("pdus");
128 
129                     for (int i = 0; i < pdus.length; i++) {
130                         SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]);
131                         String sender = message.getOriginatingAddress();
132                         if (mReceivedSender != null) {
133                             assertEquals(mReceivedSender, sender);
134                         } else {
135                             mReceivedSender = sender;
136                         }
137                         mReceivedMessages.add(message.getMessageBody().toString());
138 
139                         Log.i(TAG, "From: " + mReceivedSender + " message: " +
140                                 mReceivedMessages.get(mReceivedMessages.size() - 1));
141                     }
142                 }
143             };
144             dialogSmsDisplayActivity.registerReceiver(mSmsReceiverReceiver,
145                     new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
146         }
147     }
148 
149     @Override
tearDown()150     protected void tearDown() throws Exception {
151         if (mSmsSenderReceiver != null) {
152             dialogSmsDisplayActivity.unregisterReceiver(mSmsSenderReceiver);
153             mSmsSenderReceiver = null;
154         }
155         if (mSmsReceiverReceiver != null) {
156             dialogSmsDisplayActivity.unregisterReceiver(mSmsReceiverReceiver);
157             mSmsReceiverReceiver = null;
158         }
159         super.tearDown();
160     }
161 
162     // Returns the broken up list of messages for long messages or the original message in
163     // element 0.
sendSmsMessageInternal(String messageOut)164     private List<String> sendSmsMessageInternal(String messageOut) {
165         if (!mHasSms) {
166             fail("no sms on device");
167             return null;
168         }
169         SmsManager sms = SmsManager.getDefault();
170 
171         List<String> messages = sms.divideMessage(messageOut);
172         mMessageReceivedCount = 0;
173         mReceivedSender = null;
174         mReceivedMessages.clear();
175 
176         for (String message : messages) {
177             Log.i(TAG, "sendSmsMessage: " + messageOut + " to: " + mMyNumber);
178             sms.sendTextMessage(mMyNumber, null, message, PendingIntent.getBroadcast(
179                     dialogSmsDisplayActivity, 0, new Intent(ACTION_SMS_SENT), 0), null);
180         }
181         return messages;
182     }
183 
184     // returns true if "messageCount" sms messages are received, false if timeout
waitForSms(int messageCount)185     private boolean waitForSms(int messageCount) {
186         // wait up to two minutes for the sent message to be received
187         long now = System.currentTimeMillis();
188         boolean success = true;
189         Log.i(TAG, "waitForSms -- waiting for: " + messageCount + " parts");
190         while (mReceivedMessages.size() < messageCount) {
191             try {
192                 Thread.sleep(1000);
193             } catch (Exception e) {
194             }
195             if (System.currentTimeMillis() - now > 1000 * 2 * 60) {
196                 // Give up after two minutes
197                 success = false;
198                 break;
199             }
200         }
201         if (success) {
202             // Wait 5 seconds for the dialog to launch and update
203             try {
204                 Thread.sleep(5000);
205             } catch (Exception e) {
206             }
207         }
208         return success;
209     }
210 
sendMessageTest(String message)211     private void sendMessageTest(String message) {
212         List<String> messages = sendSmsMessageInternal(message);
213         Log.i(TAG, "sendMessageTest -- message broken into " + messages.size() + "parts");
214 
215         boolean receivedSms = waitForSms(messages.size());
216         assertTrue("sms not received after two minutes", receivedSms);
217 
218         // Check to see if message/# matches
219         assertEquals(mMyNumber, mReceivedSender);
220         assertEquals(messages.size(), mReceivedMessages.size());
221         int i = 0;
222         for (String messageFrag : messages) {
223             assertEquals(messageFrag, mReceivedMessages.get(i++));
224         }
225     }
226 
testSendingSmallSmsMessage()227     public void testSendingSmallSmsMessage() {
228         sendMessageTest("This is a regular size message that might be sent");
229     }
230 
testSendingLargeSmsMessage()231     public void testSendingLargeSmsMessage() {
232         sendMessageTest("This is a long long message. " +
233                 "This is a long long message. " +
234                 "This is a long long message. " +
235                 "This is a long long message. " +
236                 "This is a long long message. " +
237                 "This is a long long message. " +
238                 "This is a long long message. " +
239                 "This is a long long message. " +
240                 "This is a long long message. " +
241                 "This is a long long message. " +
242                 "This is a long long message. " +
243                 "This is a long long message. " +
244                 "This is a long long message. " +
245                 "This is a long long message. " +
246                 "This is a long long message. " +
247                 "This is a long long message. " +
248                 "This is a long long message. " +
249                 "This is a long long message. " +
250                 "This is a long long message. " +
251                 "This is a long long message. " +
252                 "This is a long long message. " +
253                 "This is a long long message. " +
254                 "This is a long long message. " +
255                 "This is a long long message. " +
256                 "This is a long long message. " +
257                 "This is a long long message. " +
258                 "This is a long long message. " +
259                 "This is a long long message. ");
260     }
261 
testOnNewIntentSmall()262     public void testOnNewIntentSmall() {
263         // Test a small message and a non-numeric phone number
264         sendOnNewIntent("this is a big fat test", "xyzzy", 2000);
265     }
266 
testOnNewIntentLarge()267     public void testOnNewIntentLarge() {
268         // A long message like this should never really happen because SMS messages are limited
269         // to about 140 characters.
270         sendOnNewIntent("now is the time for all good men to come to the aid of their country1" +
271                 "now is the time for all good men to come to the aid of their country2" +
272                 "now is the time for all good men to come to the aid of their country3",
273                 "513-891-7823", 2001);
274     }
275 
sendOnNewIntent(String message, String dest, int notificationId)276     public void sendOnNewIntent(String message, String dest, int notificationId) {
277         Intent di = new Intent();
278         di.setClass(dialogSmsDisplayActivity, DialogSmsDisplay.class);
279         di.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP |
280                 Intent.FLAG_ACTIVITY_CLEAR_TOP);
281         di.putExtra(DialogSmsDisplay.SMS_FROM_ADDRESS_EXTRA, dest);
282         di.putExtra(DialogSmsDisplay.SMS_MESSAGE_EXTRA, message);
283         di.putExtra(DialogSmsDisplay.SMS_NOTIFICATION_ID_EXTRA, notificationId);
284         dialogSmsDisplayActivity.onNewIntent(di);
285 
286         // Check to see if message/# matches
287         assertEquals(dest, dialogSmsDisplayActivity.mFromAddress);
288         assertEquals(message, dialogSmsDisplayActivity.mMessage);
289     }
290 }
291