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 android.holo.cts; 18 19 import android.app.Activity; 20 import android.content.Intent; 21 import android.os.Bundle; 22 import android.util.Log; 23 24 import java.util.ArrayList; 25 import java.util.Iterator; 26 import java.util.List; 27 import java.util.concurrent.CountDownLatch; 28 import java.util.concurrent.Future; 29 import java.util.concurrent.TimeUnit; 30 import java.util.concurrent.TimeoutException; 31 32 /** 33 * {@link Activity} that iterates over all the test layouts for a single theme 34 * and either compares or generates bitmaps. 35 */ 36 public class ThemeTestActivity extends Activity { 37 38 private static final String TAG = ThemeTestActivity.class.getSimpleName(); 39 40 static final String EXTRA_TASK = "task"; 41 static final String EXTRA_THEME_INDEX = "themeIndex"; 42 static final String EXTRA_LAYOUT_INDEX = "layoutIndex"; 43 static final String EXTRA_LAYOUT_ADAPTER_MODE = "layoutAdapterMode"; 44 45 static final int TASK_VIEW_LAYOUTS = 1; 46 static final int TASK_GENERATE_BITMAPS = 2; 47 static final int TASK_COMPARE_BITMAPS = 3; 48 49 private static final int VIEW_TESTS_REQUEST_CODE = 1; 50 private static final int GENERATE_BITMAP_REQUEST_CODE = 2; 51 private static final int COMPARE_BITMAPS_REQUEST_CODE = 3; 52 53 private int mRequestCode; 54 private Iterator<Intent> mIterator; 55 private Result mPendingResult; 56 private ResultFuture<Result> mResultFuture; 57 58 @Override 59 protected void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 62 mResultFuture = new ResultFuture<Result>(); 63 mPendingResult = new Result(); 64 65 int task = getIntent().getIntExtra(EXTRA_TASK, -1); 66 switch (task) { 67 case TASK_VIEW_LAYOUTS: 68 mRequestCode = VIEW_TESTS_REQUEST_CODE; 69 break; 70 71 case TASK_GENERATE_BITMAPS: 72 mRequestCode = GENERATE_BITMAP_REQUEST_CODE; 73 break; 74 75 case TASK_COMPARE_BITMAPS: 76 // Don't delete any failure bitmap images that may be useful. 77 mRequestCode = COMPARE_BITMAPS_REQUEST_CODE; 78 break; 79 80 default: 81 throw new IllegalArgumentException("Bad task: " + task); 82 } 83 84 int themeIndex = getIntent().getIntExtra(EXTRA_THEME_INDEX, -1); 85 int layoutIndex = getIntent().getIntExtra(EXTRA_LAYOUT_INDEX, -1); 86 int adapterMode = getIntent().getIntExtra(EXTRA_LAYOUT_ADAPTER_MODE, -1); 87 88 Log.i(TAG, "Theme index: " + themeIndex + " Layout index: " + layoutIndex); 89 90 if (themeIndex < 0 && layoutIndex < 0) { 91 mIterator = new AllThemesIterator(task, adapterMode); 92 } else if (themeIndex >= 0 && layoutIndex >= 0) { 93 mIterator = new SingleThemeLayoutIterator(themeIndex, layoutIndex, task, adapterMode); 94 } else if (layoutIndex >= 0) { 95 mIterator = new SingleLayoutIterator(layoutIndex, task, adapterMode); 96 } else if (themeIndex >= 0) { 97 mIterator = new SingleThemeIterator(themeIndex, task, adapterMode); 98 } else { 99 throw new IllegalStateException(); 100 } 101 102 generateNextBitmap(); 103 } 104 105 private void generateNextBitmap() { 106 if (mIterator.hasNext()) { 107 Intent intent = mIterator.next(); 108 intent.setClass(this, LayoutTestActivity.class); 109 startActivityForResult(intent, mRequestCode); 110 } else { 111 mResultFuture.set(mPendingResult); 112 } 113 } 114 115 @Override 116 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 117 switch (requestCode) { 118 case VIEW_TESTS_REQUEST_CODE: 119 return; 120 121 case GENERATE_BITMAP_REQUEST_CODE: 122 case COMPARE_BITMAPS_REQUEST_CODE: 123 handleResult(resultCode, data); 124 break; 125 126 default: 127 throw new IllegalArgumentException("Bad request code: " + requestCode); 128 } 129 } 130 131 private void handleResult(int resultCode, Intent data) { 132 if (resultCode == RESULT_CANCELED) { 133 throw new IllegalStateException("Did you interrupt the activity?"); 134 } 135 136 boolean success = data.getBooleanExtra(LayoutTestActivity.EXTRA_SUCCESS, false); 137 if (!success) { 138 String bitmapName = data.getStringExtra(LayoutTestActivity.EXTRA_BITMAP_NAME); 139 mPendingResult.addFailedBitmapName(bitmapName); 140 } 141 generateNextBitmap(); 142 } 143 144 public Future<Result> getResultFuture() { 145 return mResultFuture; 146 } 147 148 static class Result { 149 150 private List<String> mFailedBitmapNames = new ArrayList<String>(); 151 152 public boolean passed() { 153 return mFailedBitmapNames.isEmpty(); 154 } 155 156 public List<String> getFailedBitmapNames() { 157 return mFailedBitmapNames; 158 } 159 160 private void addFailedBitmapName(String bitmapName) { 161 mFailedBitmapNames.add(bitmapName); 162 } 163 } 164 165 class ResultFuture<T> implements Future<T> { 166 167 private final CountDownLatch mLatch = new CountDownLatch(1); 168 169 private T mResult; 170 171 public void set(T result) { 172 mResult = result; 173 mLatch.countDown(); 174 } 175 176 @Override 177 public T get() throws InterruptedException { 178 mLatch.await(); 179 return mResult; 180 } 181 182 @Override 183 public T get(long timeout, TimeUnit unit) throws InterruptedException, 184 TimeoutException { 185 if (!mLatch.await(timeout, unit)) { 186 throw new TimeoutException(); 187 } 188 return mResult; 189 } 190 191 @Override 192 public boolean isDone() { 193 return mLatch.getCount() > 0; 194 } 195 196 @Override 197 public boolean cancel(boolean mayInterruptIfRunning) { 198 return false; 199 } 200 201 @Override 202 public boolean isCancelled() { 203 return false; 204 } 205 } 206 } 207