Home | History | Annotate | Download | only in verifier
      1 // Copyright 2013 Google Inc. All Rights Reserved.
      2 
      3 package com.android.cts.verifier;
      4 
      5 import android.content.Intent;
      6 import android.os.Bundle;
      7 import android.os.Parcel;
      8 import android.os.Parcelable;
      9 import android.view.View;
     10 import android.view.View.OnClickListener;
     11 import android.view.ViewGroup;
     12 import android.widget.Button;
     13 import android.widget.TextView;
     14 
     15 /**
     16  *  A generic activity for intent based tests.
     17  *
     18  *  This activity can be reused for various tests that are intent based. The activity consists of a
     19  *  text view containing instructions and one or more buttons that trigger intents.
     20  *  Each button can send one or more intenrs as startActivity() calls.
     21  *
     22  *  The intents can either be generated statically and passed as an extra to the intent that started
     23  *  this activity or in some cases where the intent needs to be based on dynamic data (for example
     24  *  time of day), an {@link IntentFactory} class name can be passed instead. This intent factory
     25  *  will dynamically create the intent when the button is clicked based on the test id and the
     26  *  button that was clicked.
     27  */
     28 public class IntentDrivenTestActivity extends PassFailButtons.Activity implements OnClickListener {
     29     public static final String EXTRA_ID = "id";
     30     public static final String EXTRA_TITLE = "title";
     31     public static final String EXTRA_INFO = "info";
     32     public static final String EXTRA_BUTTONS = "buttons";
     33 
     34     private String mTestId;
     35     private ButtonInfo[] mButtonInfos;
     36 
     37 
     38     @Override
     39     protected void onCreate(Bundle savedInstanceState) {
     40         super.onCreate(savedInstanceState);
     41         setContentView(R.layout.intent_driven_test);
     42         setPassFailButtonClickListeners();
     43 
     44         final Intent intent = getIntent();
     45         if (!intent.hasExtra(EXTRA_ID)
     46                 || !intent.hasExtra(EXTRA_TITLE)
     47                 || !intent.hasExtra(EXTRA_INFO)
     48                 || !intent.hasExtra(EXTRA_BUTTONS)) {
     49             throw new IllegalArgumentException(
     50                     "Intent must have EXTRA_ID, EXTRA_TITLE, EXTRA_INFO & EXTRA_BUTTONS");
     51         }
     52 
     53         mTestId = intent.getStringExtra(EXTRA_ID);
     54         setTitle(intent.getIntExtra(EXTRA_TITLE, -1));
     55 
     56         final TextView info = (TextView) findViewById(R.id.info);
     57         info.setText(intent.getIntExtra(EXTRA_INFO, -1));
     58 
     59         final ViewGroup buttons = (ViewGroup) findViewById(R.id.buttons);
     60         final Parcelable[] parcelables = intent.getParcelableArrayExtra(EXTRA_BUTTONS);
     61         mButtonInfos = new ButtonInfo[parcelables.length];
     62         for (int i = 0; i < parcelables.length; i++) {
     63             final ButtonInfo buttonInfo = (ButtonInfo) parcelables[i];
     64             mButtonInfos[i] = buttonInfo;
     65             final Button button = new Button(this);
     66             buttons.addView(button);
     67             button.setText(buttonInfo.mButtonText);
     68             button.setTag(i);
     69             button.setOnClickListener(this);
     70         }
     71     }
     72 
     73     @Override
     74     protected void onResume() {
     75         super.onResume();
     76         setResult(RESULT_CANCELED);
     77     }
     78 
     79     @Override
     80     public void onClick(View v) {
     81         final ButtonInfo buttonInfo = mButtonInfos[(Integer) v.getTag()];
     82         final Intent[] intents = buttonInfo.getIntents();
     83         if (intents != null) {
     84             for (Parcelable intent : intents) {
     85                 startActivity((Intent) intent);
     86             }
     87         } else {
     88             final Class<?> factoryClass;
     89             final String className = buttonInfo.getIntentFactoryClassName();
     90             try {
     91                 factoryClass = Thread.currentThread().getContextClassLoader().loadClass(className);
     92             } catch (ClassNotFoundException e) {
     93                 throw new IllegalArgumentException("Factory not found: " + className, e);
     94             }
     95             final IntentFactory factory;
     96             try {
     97                 factory = (IntentFactory) factoryClass.newInstance();
     98             } catch (InstantiationException e) {
     99                 throw new IllegalArgumentException("Can't create factory: " + className, e);
    100             } catch (IllegalAccessException e) {
    101                 throw new IllegalArgumentException("Can't create factory: " + className, e);
    102             }
    103 
    104             for (Intent intent : factory.createIntents(mTestId, buttonInfo.getButtonText())) {
    105                 startActivity(intent);
    106             }
    107         }
    108     }
    109 
    110     @Override
    111     public String getTestId() {
    112         return mTestId;
    113     }
    114 
    115     public static class TestInfo {
    116         private final String mTestId;
    117         private final int mTitle;
    118         private final int mInfoText;
    119         private final ButtonInfo[] mButtons;
    120 
    121         public TestInfo(String testId,  int title, int infoText, ButtonInfo... buttons) {
    122             /** The Intent Driven Test layout {@link R.layout.intent_driven_test} is designed for
    123              *  up to 2 buttons and won't render well with more buttons on small screen devices.
    124              *  If you need more than 2 buttons, please change the layout so it can properly render
    125              *  them even on the smallest devices.
    126              */
    127             if (buttons.length > 2) {
    128                 throw new RuntimeException("Too many buttons");
    129             }
    130             mTestId = testId;
    131             mTitle = title;
    132             mInfoText = infoText;
    133             mButtons = buttons;
    134         }
    135 
    136         public String getTestId() {
    137             return mTestId;
    138         }
    139 
    140         public int getTitle() {
    141             return mTitle;
    142         }
    143 
    144         public int getInfoText() {
    145             return mInfoText;
    146         }
    147 
    148         public ButtonInfo[] getButtons() {
    149             return mButtons;
    150         }
    151     }
    152 
    153     public static class ButtonInfo implements Parcelable {
    154         private final int mButtonText;
    155         private final Intent[] mIntents;
    156         private final String mIntentFactoryClassName;
    157 
    158         public ButtonInfo(int buttonText, Intent... intents) {
    159             mButtonText = buttonText;
    160             mIntents = intents;
    161             mIntentFactoryClassName = null;
    162         }
    163 
    164         public ButtonInfo(int buttonText, String intentFactoryClassName) {
    165             mButtonText = buttonText;
    166             mIntents = null;
    167             mIntentFactoryClassName = intentFactoryClassName;
    168         }
    169 
    170         public ButtonInfo(Parcel source) {
    171             mButtonText = source.readInt();
    172             final Parcelable[] parcelables = source.readParcelableArray(null);
    173             if (parcelables != null) {
    174                 mIntents = new Intent[parcelables.length];
    175                 for (int i = 0, parcelablesLength = parcelables.length; i < parcelablesLength; i++) {
    176                     mIntents[i] = (Intent) parcelables[i];
    177                 }
    178             } else {
    179                 mIntents = null;
    180             }
    181             mIntentFactoryClassName = source.readString();
    182         }
    183 
    184         public int getButtonText() {
    185             return mButtonText;
    186         }
    187 
    188         public Intent[] getIntents() {
    189             return mIntents;
    190         }
    191 
    192         public String getIntentFactoryClassName() {
    193             return mIntentFactoryClassName;
    194         }
    195 
    196         @Override
    197         public int describeContents() {
    198             return 0;
    199         }
    200 
    201         @Override
    202         public void writeToParcel(Parcel dest, int flags) {
    203             dest.writeInt(mButtonText);
    204             dest.writeParcelableArray(mIntents, 0);
    205             dest.writeString(mIntentFactoryClassName);
    206         }
    207 
    208         public static final Creator<ButtonInfo> CREATOR = new Creator<ButtonInfo>() {
    209             public ButtonInfo createFromParcel(Parcel source) {
    210                 return new ButtonInfo(source);
    211             }
    212 
    213             public ButtonInfo[] newArray(int size) {
    214                 return new ButtonInfo[size];
    215             }
    216         };
    217 
    218     }
    219 
    220     public interface IntentFactory {
    221         Intent[] createIntents(String testId, int buttonText);
    222     }
    223 }
    224