1 /* 2 * Copyright (C) 2015 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.theme.app; 18 19 import static android.theme.app.TestConfiguration.THEMES; 20 21 import android.app.Activity; 22 import android.content.Intent; 23 import android.os.Build.VERSION; 24 import android.os.Bundle; 25 import android.os.Environment; 26 import android.util.Log; 27 import android.view.WindowManager.LayoutParams; 28 29 import java.io.File; 30 import java.io.IOException; 31 import java.util.concurrent.CountDownLatch; 32 import java.util.concurrent.TimeUnit; 33 34 /** 35 * Generates images by iterating through all themes and launching instances of 36 * {@link ThemeDeviceActivity}. 37 */ 38 public class GenerateImagesActivity extends Activity { 39 private static final String TAG = "GenerateImagesActivity"; 40 41 private static final String OUT_DIR = "cts-theme-assets"; 42 private static final int REQUEST_CODE = 1; 43 44 public static final String EXTRA_REASON = "reason"; 45 46 private final CountDownLatch mLatch = new CountDownLatch(1); 47 48 private File mOutputDir; 49 private File mOutputZip; 50 51 private int mCurrentTheme; 52 private String mFinishReason; 53 private boolean mFinishSuccess; 54 55 @Override 56 protected void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 59 // Useful for local testing. Not required for CTS harness. 60 getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); 61 62 mOutputDir = setupOutputDirectory(); 63 if (mOutputDir == null) { 64 finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false); 65 } else { 66 generateNextImage(); 67 } 68 } 69 70 private File setupOutputDirectory() { 71 mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR); 72 ThemeTestUtils.deleteDirectory(mOutputDir); 73 mOutputDir.mkdirs(); 74 75 if (mOutputDir.exists()) { 76 return mOutputDir; 77 } 78 return null; 79 } 80 81 /** 82 * @return whether the test finished successfully 83 */ 84 public boolean isFinishSuccess() { 85 return mFinishSuccess; 86 } 87 88 /** 89 * @return user-visible string explaining why the test finished, may be {@code null} if the test 90 * finished unexpectedly 91 */ 92 public String getFinishReason() { 93 return mFinishReason; 94 } 95 96 /** 97 * Starts the activity to generate the next image. 98 */ 99 private void generateNextImage() { 100 // Keep trying themes until one works. 101 boolean success = false; 102 while (++mCurrentTheme < THEMES.length && !success) { 103 success = launchThemeDeviceActivity(); 104 } 105 106 // If we ran out of themes, we're done. 107 if (!success) { 108 compressOutput(); 109 110 finish("Image generation complete!", true); 111 } 112 } 113 114 private boolean launchThemeDeviceActivity() { 115 final ThemeInfo theme = THEMES[mCurrentTheme]; 116 if (theme.apiLevel > VERSION.SDK_INT) { 117 Log.v(TAG, "Skipping theme \"" + theme.name 118 + "\" (requires API " + theme.apiLevel + ")"); 119 return false; 120 } 121 122 Log.v(TAG, "Generating images for theme \"" + theme.name + "\"..."); 123 124 final Intent intent = new Intent(this, ThemeDeviceActivity.class); 125 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 126 intent.putExtra(ThemeDeviceActivity.EXTRA_THEME, mCurrentTheme); 127 intent.putExtra(ThemeDeviceActivity.EXTRA_OUTPUT_DIR, mOutputDir.getAbsolutePath()); 128 startActivityForResult(intent, REQUEST_CODE); 129 return true; 130 } 131 132 @Override 133 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 134 if (resultCode != RESULT_OK) { 135 finish("Failed to generate images for theme " + mCurrentTheme + " (" 136 + data.getStringExtra(EXTRA_REASON) + ")", false); 137 return; 138 } 139 140 generateNextImage(); 141 } 142 143 private void compressOutput() { 144 mOutputZip = new File(mOutputDir.getParentFile(), mOutputDir.getName() + ".zip"); 145 146 if (mOutputZip.exists()) { 147 // Remove any old test results. 148 mOutputZip.delete(); 149 } 150 151 try { 152 ThemeTestUtils.compressDirectory(mOutputDir, mOutputZip); 153 ThemeTestUtils.deleteDirectory(mOutputDir); 154 } catch (IOException e) { 155 e.printStackTrace(); 156 } 157 } 158 159 private void finish(String reason, boolean success) { 160 mFinishSuccess = success; 161 mFinishReason = reason; 162 163 finish(); 164 } 165 166 @Override 167 public void finish() { 168 mLatch.countDown(); 169 170 super.finish(); 171 } 172 173 public File getOutputZip() { 174 return mOutputZip; 175 } 176 177 public boolean waitForCompletion(long timeoutMillis) throws InterruptedException { 178 return mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); 179 } 180 } 181