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