Home | History | Annotate | Download | only in dumprendertree2
      1 /*
      2  * Copyright (C) 2010 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.dumprendertree2;
     18 
     19 import com.android.dumprendertree2.scriptsupport.OnEverythingFinishedCallback;
     20 
     21 import android.app.Activity;
     22 import android.app.ProgressDialog;
     23 import android.content.Intent;
     24 import android.content.res.Configuration;
     25 import android.os.Bundle;
     26 import android.os.Handler;
     27 import android.os.Message;
     28 import android.view.Gravity;
     29 import android.view.Window;
     30 import android.webkit.WebView;
     31 import android.widget.Toast;
     32 
     33 import java.io.File;
     34 import java.util.ArrayList;
     35 
     36 /**
     37  * An Activity that generates a list of tests and sends the intent to
     38  * LayoutTestsExecuter to run them. It also restarts the LayoutTestsExecuter
     39  * after it crashes.
     40  */
     41 public class TestsListActivity extends Activity {
     42 
     43     private static final int MSG_TEST_LIST_PRELOADER_DONE = 0;
     44 
     45     /** Constants for adding extras to an intent */
     46     public static final String EXTRA_TEST_PATH = "TestPath";
     47 
     48     private static ProgressDialog sProgressDialog;
     49 
     50     private Handler mHandler = new Handler() {
     51         @Override
     52         public void handleMessage(Message msg) {
     53             switch (msg.what) {
     54                 case MSG_TEST_LIST_PRELOADER_DONE:
     55                     sProgressDialog.dismiss();
     56                     mTestsList = (ArrayList<String>)msg.obj;
     57                     mTotalTestCount = mTestsList.size();
     58                     restartExecutor(0);
     59                     break;
     60             }
     61         }
     62     };
     63 
     64     private ArrayList<String> mTestsList;
     65     private int mTotalTestCount;
     66 
     67     private OnEverythingFinishedCallback mOnEverythingFinishedCallback;
     68     private boolean mEverythingFinished;
     69 
     70     @Override
     71     protected void onCreate(Bundle savedInstanceState) {
     72         super.onCreate(savedInstanceState);
     73 
     74         /** Prepare the progress dialog */
     75         sProgressDialog = new ProgressDialog(TestsListActivity.this);
     76         sProgressDialog.setCancelable(false);
     77         sProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     78         sProgressDialog.setTitle(R.string.dialog_progress_title);
     79         sProgressDialog.setMessage(getText(R.string.dialog_progress_msg));
     80 
     81         requestWindowFeature(Window.FEATURE_PROGRESS);
     82 
     83         Intent intent = getIntent();
     84         if (!intent.getAction().equals(Intent.ACTION_RUN)) {
     85             return;
     86         }
     87         String path = intent.getStringExtra(EXTRA_TEST_PATH);
     88 
     89         sProgressDialog.show();
     90         Message doneMsg = Message.obtain(mHandler, MSG_TEST_LIST_PRELOADER_DONE);
     91 
     92         Intent serviceIntent = new Intent(this, ManagerService.class);
     93         serviceIntent.putExtra("path", path);
     94         startService(serviceIntent);
     95 
     96         new TestsListPreloaderThread(path, doneMsg).start();
     97     }
     98 
     99     @Override
    100     protected void onNewIntent(Intent intent) {
    101         if (intent.getAction().equals(Intent.ACTION_REBOOT)) {
    102             onCrashIntent(intent);
    103         } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
    104             onEverythingFinishedIntent(intent);
    105         }
    106     }
    107 
    108     /**
    109      * This method handles an intent that comes from ManageService when crash is detected.
    110      * The intent contains an index in mTestsList of the test that crashed. TestsListActivity
    111      * restarts the LayoutTestsExecutor from the following test in mTestsList, by sending
    112      * an intent to it. This new intent contains a list of remaining tests to run,
    113      * total count of all tests, and the index of the first test to run after restarting.
    114      * LayoutTestExecutor runs then as usual, sending reports to ManagerService. If it
    115      * detects the crash it sends a new intent and the flow repeats.
    116      */
    117     private void onCrashIntent(Intent intent) {
    118         int nextTestToRun = intent.getIntExtra("crashedTestIndex", -1) + 1;
    119         if (nextTestToRun > 0 && nextTestToRun <= mTotalTestCount) {
    120             restartExecutor(nextTestToRun);
    121         }
    122     }
    123 
    124     public void registerOnEverythingFinishedCallback(OnEverythingFinishedCallback callback) {
    125         mOnEverythingFinishedCallback = callback;
    126         if (mEverythingFinished) {
    127             mOnEverythingFinishedCallback.onFinished();
    128         }
    129     }
    130 
    131     private void onEverythingFinishedIntent(Intent intent) {
    132         Toast toast = Toast.makeText(this,
    133                 "All tests finished.\nPress back key to return to the tests' list.",
    134                 Toast.LENGTH_LONG);
    135         toast.setGravity(Gravity.CENTER, -40, 0);
    136         toast.show();
    137 
    138         /** Show the details to the user */
    139         WebView webView = new WebView(this);
    140         webView.getSettings().setJavaScriptEnabled(true);
    141         webView.getSettings().setBuiltInZoomControls(true);
    142         webView.getSettings().setEnableSmoothTransition(true);
    143         /** This enables double-tap to zoom */
    144         webView.getSettings().setUseWideViewPort(true);
    145 
    146         setContentView(webView);
    147         webView.loadUrl(Summarizer.getDetailsUri().toString());
    148 
    149         mEverythingFinished = true;
    150         if (mOnEverythingFinishedCallback != null) {
    151             mOnEverythingFinishedCallback.onFinished();
    152         }
    153     }
    154 
    155     /**
    156      * This, together with android:configChanges="orientation" in manifest file, prevents
    157      * the activity from restarting on orientation change.
    158      */
    159     @Override
    160     public void onConfigurationChanged(Configuration newConfig) {
    161         super.onConfigurationChanged(newConfig);
    162     }
    163 
    164     @Override
    165     protected void onSaveInstanceState(Bundle outState) {
    166         outState.putStringArrayList("testsList", mTestsList);
    167         outState.putInt("totalCount", mTotalTestCount);
    168 
    169         super.onSaveInstanceState(outState);
    170     }
    171 
    172     @Override
    173     protected void onRestoreInstanceState(Bundle savedInstanceState) {
    174         super.onRestoreInstanceState(savedInstanceState);
    175 
    176         mTestsList = savedInstanceState.getStringArrayList("testsList");
    177         mTotalTestCount = savedInstanceState.getInt("totalCount");
    178     }
    179 
    180     /**
    181      * (Re)starts the executer activity from the given test number (inclusive, 0-based).
    182      * This number is an index in mTestsList, not the sublist passed in the intent.
    183      *
    184      * @param startFrom
    185      *      test index in mTestsList to start the tests from (inclusive, 0-based)
    186      */
    187     private void restartExecutor(int startFrom) {
    188         Intent intent = new Intent();
    189         intent.setClass(this, LayoutTestsExecutor.class);
    190         intent.setAction(Intent.ACTION_RUN);
    191 
    192         if (startFrom < mTotalTestCount) {
    193             File testListFile = new File(getExternalFilesDir(null), "test_list.txt");
    194             FsUtils.saveTestListToStorage(testListFile, startFrom, mTestsList);
    195             intent.putExtra(LayoutTestsExecutor.EXTRA_TESTS_FILE, testListFile.getAbsolutePath());
    196             intent.putExtra(LayoutTestsExecutor.EXTRA_TEST_INDEX, startFrom);
    197         } else {
    198             intent.putExtra(LayoutTestsExecutor.EXTRA_TESTS_FILE, "");
    199         }
    200 
    201         startActivity(intent);
    202     }
    203 }