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