Home | History | Annotate | Download | only in app
      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