1 /*
2  * Copyright (C) 2011 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.mms.ui;
18 
19 import static com.android.mms.ui.MessageListAdapter.COLUMN_ID;
20 import static com.android.mms.ui.MessageListAdapter.COLUMN_MSG_TYPE;
21 
22 import com.android.mms.R;
23 import com.android.mms.ui.ComposeMessageActivity;
24 import com.android.mms.ui.RecipientsEditor;
25 import com.android.mms.SmsTestRunner;
26 
27 import android.database.Cursor;
28 import android.content.Context;
29 import android.test.ActivityInstrumentationTestCase2;
30 import android.view.View;
31 import android.view.ViewStub;
32 import android.widget.EditText;
33 import android.widget.ImageButton;
34 import android.util.Log;
35 
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.BufferedInputStream;
39 import java.io.IOException;
40 import java.util.List;
41 import java.util.ArrayList;
42 
43 /**
44  * Base class for sms tests.
45  */
46 public class SmsTest
47     extends ActivityInstrumentationTestCase2<ComposeMessageActivity> {
48 
49     private final static String TAG = "SmsTest";
50     protected ComposeMessageActivity mActivity;
51     protected RecipientsEditor mRecipientsEditor;
52     protected EditText mTextEditor;
53     protected SmsTestRunner mInst;
54     protected String mRecipient;
55     protected List mRecipientsList = null;
56     protected long mReceiveTimer = 5 * 60 * 1000 ; // 5 minutes
57 
58     // default message to sent
59     protected String mMessage =
60         "Is this a dagger which I see before me,"
61         +" The handle toward my hand? Come, let me clutch thee."
62         +" I have thee not, and yet I see thee still."
63         +" Art thou not, fatal vision, sensible"
64         +" To feeling as to sight? or art thou but"
65         +" A dagger of the mind, a false creation,"
66         +" Proceeding from the heat-oppressed brain?"
67         +" I see thee yet, in form as palpable"
68         +" As this which now I draw.";
69 
70     protected Long mThreadId;
71 
SmsTest()72     public SmsTest() {
73        super(ComposeMessageActivity.class);
74     }
75 
76     @Override
setUp()77     protected void setUp() throws Exception {
78         super.setUp();
79 
80         mActivity = getActivity();
81         ViewStub stub = (ViewStub)mActivity.findViewById(R.id.recipients_editor_stub);
82         if (stub != null) {
83             View stubView = stub.inflate();
84             mRecipientsEditor = (RecipientsEditor) stubView.findViewById(R.id.recipients_editor);
85         } else {
86             mRecipientsEditor = (RecipientsEditor) mActivity.findViewById(R.id.recipients_editor);
87             mRecipientsEditor.setVisibility(View.VISIBLE);
88         }
89         mTextEditor = (EditText)mActivity.findViewById(R.id.embedded_text_editor);
90 
91         // parse input argument
92         mInst = (SmsTestRunner)getInstrumentation();
93         if (mInst.mRecipient != null) {
94             mRecipient = mInst.mRecipient;
95         } else {
96             mRecipient = getLocalNumber();
97         }
98         if (mInst.mReceiveTimer > 0) {
99             mReceiveTimer = mInst.mReceiveTimer;
100         }
101         loadRecipientsList();
102         loadMessage();
103         Log.v(TAG, String.format("mReceiveTimer: %d, mRecipient: %s, mMessage: ",
104                                  mReceiveTimer, mRecipient, mMessage));
105     }
106 
107     @Override
tearDown()108     protected void tearDown() throws Exception {
109         super.tearDown();
110     }
111 
112     /**
113      * Load recipients from a file
114      */
loadRecipientsList()115     private void loadRecipientsList() {
116         String recipientFileName = mInst.mRecipientFileName;
117         if (recipientFileName == null) {
118             return;
119         }
120         // Read recipients from a file
121         mRecipientsList = new ArrayList<String>();
122         StringBuilder sb = new StringBuilder();
123         try {
124             Log.v(TAG, "Loading recipients");
125             FileInputStream f = mInst.getTargetContext().openFileInput(recipientFileName);
126             int c;
127             while ((c = f.read()) != -1) {
128                 if (c == '\r' || c == '\n' || c == ',') {
129                     String recipient = sb.toString().trim();
130                     if (recipient.length() > 0) {
131                         mRecipientsList.add(recipient);
132                     }
133                     sb.setLength(0);
134                 } else {
135                     sb.append((char)c);
136                 }
137             }
138             f.close();
139         } catch (Exception e) {
140             Log.e(TAG, "can't open recipients file " + recipientFileName);
141             return;
142         }
143     }
144 
145     /**
146      * Load messages from a file, save the message in mMessage
147      */
loadMessage()148     private void loadMessage() {
149         String messageFileName = mInst.mMessageFileName;
150         if (messageFileName == null) {
151             return;
152         }
153 
154         Context targetAppContext = mInst.getTargetContext().getApplicationContext();
155         String filePath = String.format("%s/%s", targetAppContext.getFilesDir(), messageFileName);
156         Log.v(TAG, "filePath: " + filePath);
157         // Read messages from a file
158         byte[] buffer = new byte[(int) new File(filePath).length()];
159         BufferedInputStream bf = null;
160         int numStrs = 0;
161         try {
162             Log.v(TAG, "Loading messages");
163             bf = new BufferedInputStream(
164                     mInst.getTargetContext().openFileInput(messageFileName));
165             numStrs = bf.read(buffer);
166         } catch (Exception e) {
167             Log.e(TAG, "can't open message file at " +
168                     targetAppContext.getFileStreamPath(messageFileName));
169         } finally {
170             if (bf != null) {
171                 try { bf.close(); } catch (IOException e) {
172                     Log.v(TAG, "failed to close message file: " +
173                             targetAppContext.getFileStreamPath(messageFileName));
174                 }
175             }
176         }
177         if (numStrs > 0) {
178             mMessage = new String(buffer);
179         }
180     }
181 
182     private abstract class MessageRunnable implements Runnable {
183         protected String mRecipient;
184 
setRecipient(String recipient)185         public void setRecipient(String recipient) {
186             mRecipient = recipient;
187         }
188     }
189 
190     private MessageRunnable mSendSmsMessage = new MessageRunnable() {
191         public void run() {
192             // only on the first message will there be a recipients editor
193             if (mRecipientsEditor.getVisibility() == View.VISIBLE) {
194                 mRecipientsEditor.setText(mRecipient);
195             }
196             mTextEditor.setText(mMessage);
197             ImageButton send = (ImageButton)mActivity.findViewById(R.id.send_button_sms);
198             send.performClick();
199         }
200     };
201 
sleep(long sleepTime)202     protected void sleep(long sleepTime) {
203         try {
204             Thread.sleep(sleepTime);
205         } catch (InterruptedException e) {}
206     }
207 
208     /**
209      * @return the local number for this test device
210      */
getLocalNumber()211     protected String getLocalNumber() {
212         return MessageUtils.getLocalNumber();
213     }
214 
215     /**
216      * send a message and verify the receiption using the local number and default timer
217      * @return
218      */
sendAndReceiveMessage()219     protected boolean sendAndReceiveMessage() throws Throwable {
220         return sendAndReceiveMessage(mRecipient, mReceiveTimer);
221     }
222 
223     /**
224      * @param recipientNumber the recipient number for this sms
225      * @param receiveTimer timer to wait for the received message, if it is null, default timer
226      *        is used.
227      * @return true if received message is equal to what sent, otherwise, return false
228      * @throws Throwable
229      */
sendAndReceiveMessage(String recipientNumber, long timer)230     protected boolean sendAndReceiveMessage(String recipientNumber, long timer)
231         throws Throwable {
232         long receiveTimer = mReceiveTimer;
233         if (timer > 0) {
234             receiveTimer = timer;
235         }
236         int msgCount = mActivity.mMsgListAdapter.getCount();
237         Log.v(TAG, "msgCount: " + msgCount);
238           mSendSmsMessage.setRecipient(recipientNumber);
239         runTestOnUiThread(mSendSmsMessage);
240 
241         // Wait for maximum 5 minutes to send the long message
242         // and then receive it. Make sure the sent and received messages are the same.
243         boolean received = false;
244         long startTime = System.currentTimeMillis();
245         while ((System.currentTimeMillis() - startTime) <= receiveTimer) {
246             sleep( 5 * 1000);     // wait 5 seconds between checks
247             Log.v(TAG, "Message Count: " + mActivity.mMsgListAdapter.getCount());
248             if (msgCount + 2 == mActivity.mMsgListAdapter.getCount()) {
249                 // The "msgCount + 2" is to account for the sent and received message.
250                 // Other cases: 1) fail to send/receive sms message, test fail
251                 // 2) another message could be received by the target phone during this time
252                 //    test will falsely fail
253                 Cursor cursor = mActivity.mMsgListAdapter.getCursor();
254                 cursor.moveToLast();
255                 String type = cursor.getString(COLUMN_MSG_TYPE);
256                 long msgId = cursor.getLong(COLUMN_ID);
257                 MessageItem msgItem =
258                     mActivity.mMsgListAdapter.getCachedMessageItem(type, msgId, cursor);
259                 assertNotNull("got a null last MessageItem", msgItem);
260                 assertEquals("The sent and received messages aren't the same",
261                         mMessage,
262                         msgItem.mBody);
263                 received = true;
264                 break;
265             }
266         }
267         assertTrue("Never received the sent message", received);
268         return received;
269     }
270 }
271