• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.mobileer.oboetester;
2 
3 import android.content.Context;
4 import android.content.Intent;
5 import android.os.Build;
6 import android.util.AttributeSet;
7 import android.util.Log;
8 import android.view.LayoutInflater;
9 import android.view.View;
10 import android.view.WindowManager;
11 import android.widget.Button;
12 import android.widget.LinearLayout;
13 import android.widget.ScrollView;
14 import android.widget.TextView;
15 
16 import java.text.DateFormat;
17 import java.text.SimpleDateFormat;
18 import java.util.Calendar;
19 import java.util.Date;
20 
21 /**
22  * Run an automated test from a UI, gather logs,
23  * and display a summary.
24  */
25 public  class AutomatedTestRunner extends LinearLayout implements Runnable {
26 
27     private Button       mStartButton;
28     private Button       mStopButton;
29     private Button       mShareButton;
30     private TextView     mAutoTextView;
31     private ScrollView   mAutoTextScroller;
32     private TextView     mSingleTestIndex;
33     private StringBuffer mFailedSummary;
34     private StringBuffer mSummary;
35     private StringBuffer mFullSummary;
36     private int          mTestCount;
37     private int          mPassCount;
38     private int          mFailCount;
39     private TestAudioActivity  mActivity;
40 
41     private Thread            mAutoThread;
42     private volatile boolean  mThreadEnabled;
43     private CachedTextViewLog mCachedTextView;
44 
AutomatedTestRunner(Context context)45     public AutomatedTestRunner(Context context) {
46         super(context);
47         initializeViews(context);
48     }
49 
AutomatedTestRunner(Context context, AttributeSet attrs)50     public AutomatedTestRunner(Context context, AttributeSet attrs) {
51         super(context, attrs);
52         initializeViews(context);
53     }
54 
AutomatedTestRunner(Context context, AttributeSet attrs, int defStyle)55     public AutomatedTestRunner(Context context,
56                                AttributeSet attrs,
57                                int defStyle) {
58         super(context, attrs, defStyle);
59         initializeViews(context);
60     }
61 
getActivity()62     public TestAudioActivity getActivity() {
63         return mActivity;
64     }
65 
setActivity(TestAudioActivity activity)66     public void setActivity(TestAudioActivity activity) {
67         this.mActivity = activity;
68         mCachedTextView = new CachedTextViewLog(activity, mAutoTextView);
69     }
70 
71     /**
72      * Inflates the views in the layout.
73      *
74      * @param context
75      *           the current context for the view.
76      */
initializeViews(Context context)77     private void initializeViews(Context context) {
78         LayoutInflater inflater = (LayoutInflater) context
79                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
80         inflater.inflate(R.layout.auto_test_runner, this);
81 
82         mStartButton = (Button) findViewById(R.id.button_start);
83         mStartButton.setOnClickListener( new OnClickListener() {
84             @Override
85             public void onClick(View v) {
86                 startTest();
87             }
88         });
89 
90         mStopButton = (Button) findViewById(R.id.button_stop);
91         mStopButton.setOnClickListener( new OnClickListener() {
92             @Override
93             public void onClick(View v) {
94                 stopTest();
95             }
96         });
97 
98         mShareButton = (Button) findViewById(R.id.button_share);
99         mShareButton.setOnClickListener( new OnClickListener() {
100             @Override
101             public void onClick(View v) {
102                 shareResult();
103                 mShareButton.setEnabled(true);
104             }
105         });
106         mShareButton.setEnabled(false);
107 
108         mSingleTestIndex = (TextView) findViewById(R.id.single_test_index);
109 
110         mAutoTextScroller = (ScrollView) findViewById(R.id.text_log_auto_scroller);
111         mAutoTextView = (TextView) findViewById(R.id.text_log_auto);
112 
113         mFailedSummary = new StringBuffer();
114         mSummary = new StringBuffer();
115         mFullSummary = new StringBuffer();
116     }
117 
updateStartStopButtons(boolean running)118     private void updateStartStopButtons(boolean running) {
119         mStartButton.setEnabled(!running);
120         mStopButton.setEnabled(running);
121     }
122 
getTestCount()123     public int getTestCount() {
124         return mTestCount;
125     }
126 
isThreadEnabled()127     public boolean isThreadEnabled() {
128         return mThreadEnabled;
129     }
130 
appendFailedSummary(String text)131     public void appendFailedSummary(String text) {
132         mFailedSummary.append(text);
133     }
134 
appendSummary(String text)135     public void appendSummary(String text) {
136         mSummary.append(text);
137     }
138 
incrementFailCount()139     public void incrementFailCount() {
140         mFailCount++;
141     }
incrementPassCount()142     public void incrementPassCount() {
143         mPassCount++;
144     }
incrementTestCount()145     public void incrementTestCount() {
146         mTestCount++;
147     }
148 
149     // Write to scrollable TextView
log(final String text)150     public void log(final String text) {
151         if (text == null) return;
152         Log.d(TestAudioActivity.TAG, "LOG - " + text);
153         mCachedTextView.append(text + "\n");
154         mFullSummary.append(text + "\n");
155         scrollToBottom();
156     }
157 
scrollToBottom()158     public void scrollToBottom() {
159         mAutoTextScroller.fullScroll(View.FOCUS_DOWN);
160     }
161 
162     // Flush any logs that are stuck in the cache.
flushLog()163     public void flushLog() {
164         mCachedTextView.flush();
165         scrollToBottom();
166     }
167 
logClear()168     private void logClear() {
169         mCachedTextView.clear();
170         mFullSummary.delete(0, mFullSummary.length());
171         mSummary.delete(0, mSummary.length());
172         mFailedSummary.delete(0, mFailedSummary.length());
173     }
174 
getFullLogs()175     protected String getFullLogs() {
176         return mFullSummary.toString();
177     }
178 
startAutoThread()179     private void startAutoThread() {
180         mThreadEnabled = true;
181         mAutoThread = new Thread(this);
182         mAutoThread.start();
183     }
184 
stopAutoThread()185     private void stopAutoThread() {
186         try {
187             if (mAutoThread != null) {
188                 Log.d(TestAudioActivity.TAG,
189                         "Who called stopAutoThread()?",
190                         new RuntimeException("Just for debugging."));
191                 mThreadEnabled = false;
192                 mAutoThread.interrupt();
193                 mAutoThread.join(100);
194                 mAutoThread = null;
195             }
196         } catch (InterruptedException e) {
197             e.printStackTrace();
198         }
199     }
200 
setTestIndexText(int newTestIndex)201     protected void setTestIndexText(int newTestIndex) {
202         if (newTestIndex >= 0) {
203             mSingleTestIndex.setText(String.valueOf(newTestIndex));
204         } else {
205             mSingleTestIndex.setText("");
206         }
207     }
208 
updateTestIndex()209     private void updateTestIndex() {
210         CharSequence chars = mSingleTestIndex.getText();
211         String text = chars.toString();
212         int testIndex = -1;
213         String trimmed = chars.toString().trim();
214         if (trimmed.length() > 0) {
215             try {
216                 testIndex = Integer.parseInt(text);
217             } catch (NumberFormatException e) {
218                 mActivity.showErrorToast("Badly formated callback size: " + text);
219                 mSingleTestIndex.setText("");
220             }
221         }
222         mActivity.setSingleTestIndex(testIndex);
223     }
224 
startTest()225     protected void startTest() {
226         updateTestIndex();
227         updateStartStopButtons(true);
228         startAutoThread();
229     }
230 
stopTest()231     public void stopTest() {
232         stopAutoThread();
233     }
234 
235     // Only call from UI thread.
onTestStarted()236     public void onTestStarted() {
237         mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
238     }
239 
240     // Only call from UI thread.
onTestFinished()241     public void onTestFinished() {
242         mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
243         updateStartStopButtons(false);
244         mShareButton.setEnabled(true);
245     }
246 
getTimestampString()247     public static String getTimestampString() {
248         DateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss");
249         Date now = Calendar.getInstance().getTime();
250         return df.format(now);
251     }
252 
253     // Share text from log via GMail, Drive or other method.
shareResult()254     public void shareResult() {
255         Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
256         sharingIntent.setType("text/plain");
257 
258         String subjectText = "OboeTester-" + mActivity.getTestName()
259                 + "-" + Build.MANUFACTURER
260                 + "-" + Build.MODEL
261                 + "-" + getTimestampString();
262         subjectText = subjectText.replace(' ', '-');
263         sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subjectText);
264 
265         String shareBody = mAutoTextView.getText().toString();
266         sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
267 
268         mActivity.startActivity(Intent.createChooser(sharingIntent, "Share using:"));
269     }
270 
271     @Override
run()272     public void run() {
273         mActivity.runOnUiThread(new Runnable() {
274             @Override
275             public void run() {
276                 onTestStarted();
277             }
278         });
279         logClear();
280         log("=== STARTED at " + new Date());
281         log(mActivity.getTestName());
282         log(MainActivity.getVersionText());
283         log(Build.MANUFACTURER + ", " + Build.MODEL + ", " + Build.PRODUCT);
284         log(Build.DISPLAY);
285         appendFailedSummary("Summary\n");
286         mTestCount = 0;
287         mPassCount = 0;
288         mFailCount = 0;
289         try {
290             mActivity.runTest();
291             log("Tests finished.");
292         } catch(Exception e) {
293             log("EXCEPTION: " + e.getMessage());
294         } finally {
295             mActivity.stopTest();
296             if (!mThreadEnabled) {
297                 log("== TEST STOPPED ==");
298             }
299             log("\n==== SUMMARY ========");
300             log(mSummary.toString());
301             if (mFailCount > 0) {
302                 log("These tests FAILED:");
303                 log(mFailedSummary.toString());
304                 log("------------");
305             } else if (mPassCount > 0) {
306                 log("All " + mPassCount + " tests PASSED.");
307             } else {
308                 log("No tests were run!");
309             }
310             int skipped = mTestCount - (mPassCount + mFailCount);
311             log(mPassCount + " passed. "
312                     + mFailCount + " failed. "
313                     + skipped + " skipped. ");
314             log("== FINISHED at " + new Date());
315 
316             flushLog();
317 
318             mActivity.saveIntentLog();
319 
320             mActivity.runOnUiThread(new Runnable() {
321                 @Override
322                 public void run() {
323                     onTestFinished();
324                     flushLog();
325                 }
326             });
327         }
328     }
329 
330 }
331