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 onCreate(Bundle savedInstanceState)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 onResume()74 protected void onResume() { 75 super.onResume(); 76 setResult(RESULT_CANCELED); 77 } 78 79 @Override onClick(View v)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 getTestId()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 TestInfo(String testId, int title, int infoText, ButtonInfo... buttons)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 getTestId()136 public String getTestId() { 137 return mTestId; 138 } 139 getTitle()140 public int getTitle() { 141 return mTitle; 142 } 143 getInfoText()144 public int getInfoText() { 145 return mInfoText; 146 } 147 getButtons()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 ButtonInfo(int buttonText, Intent... intents)158 public ButtonInfo(int buttonText, Intent... intents) { 159 mButtonText = buttonText; 160 mIntents = intents; 161 mIntentFactoryClassName = null; 162 } 163 ButtonInfo(int buttonText, String intentFactoryClassName)164 public ButtonInfo(int buttonText, String intentFactoryClassName) { 165 mButtonText = buttonText; 166 mIntents = null; 167 mIntentFactoryClassName = intentFactoryClassName; 168 } 169 ButtonInfo(Parcel source)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 getButtonText()184 public int getButtonText() { 185 return mButtonText; 186 } 187 getIntents()188 public Intent[] getIntents() { 189 return mIntents; 190 } 191 getIntentFactoryClassName()192 public String getIntentFactoryClassName() { 193 return mIntentFactoryClassName; 194 } 195 196 @Override describeContents()197 public int describeContents() { 198 return 0; 199 } 200 201 @Override writeToParcel(Parcel dest, int flags)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 { createIntents(String testId, int buttonText)221 Intent[] createIntents(String testId, int buttonText); 222 } 223 } 224