Home | History | Annotate | Download | only in verifierusbcompanion
      1 /*
      2  * Copyright (C) 2016 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 com.android.cts.verifierusbcompanion;
     18 
     19 import android.content.Context;
     20 import android.os.Handler;
     21 import android.os.Message;
     22 import android.support.annotation.NonNull;
     23 import android.util.Log;
     24 
     25 import java.util.Arrays;
     26 
     27 /**
     28  * Framework for all companion tests of this app.
     29  */
     30 abstract class TestCompanion extends Thread {
     31     private final @NonNull Context mContext;
     32     private final @NonNull TestHandler mHandler;
     33     private boolean mShouldAbort;
     34 
     35     /**
     36      * Create a new test companion
     37      *
     38      * @param context Context to be used for the test companion
     39      * @param observer Observer observing the test companion
     40      */
     41     TestCompanion(@NonNull Context context, @NonNull TestObserver observer) {
     42         mContext = context;
     43         mHandler = new TestHandler(observer);
     44     }
     45 
     46     /**
     47      * @return the context to be used by the test companion
     48      */
     49     protected @NonNull Context getContext() {
     50         return mContext;
     51     }
     52 
     53     void requestAbort() {
     54         mShouldAbort = true;
     55         interrupt();
     56     }
     57 
     58     /**
     59      * @return if the test companion should abort
     60      */
     61     protected boolean shouldAbort() {
     62         return mShouldAbort;
     63     }
     64 
     65     /**
     66      * Indicate that the test companion succeeded.
     67      */
     68     protected void success() {
     69         mHandler.obtainMessage(TestHandler.SUCCESS).sendToTarget();
     70     }
     71 
     72     /**
     73      * Indicate that the test companion failed.
     74      *
     75      * @param error Description why the test failed
     76      */
     77     protected void fail(@NonNull CharSequence error) {
     78         mHandler.obtainMessage(TestHandler.FAIL, error).sendToTarget();
     79     }
     80 
     81     /**
     82      * Indicate that the test companion was aborted.
     83      */
     84     private void abort() {
     85         mHandler.obtainMessage(TestHandler.ABORT).sendToTarget();
     86     }
     87 
     88     /**
     89      * Update the status of the test companion.
     90      *
     91      * @param status The new status message
     92      */
     93     protected void updateStatus(@NonNull CharSequence status) {
     94         Log.i(this.getClass().getSimpleName(), "Status: " + status);
     95 
     96         mHandler.obtainMessage(TestHandler.UPDATE_STATUS, status).sendToTarget();
     97     }
     98 
     99     @Override
    100     public final void run() {
    101         try {
    102             runTest();
    103         } catch (Throwable e) {
    104             if (e instanceof InterruptedException && shouldAbort()) {
    105                 abort();
    106             } else {
    107                 fail(e + "\n" + Arrays.toString(e.getStackTrace()));
    108             }
    109 
    110             return;
    111         }
    112 
    113         success();
    114     }
    115 
    116     /**
    117      * The test companion code.
    118      *
    119      * @throws Throwable  If this returns without an exception, the test companion succeeded.
    120      */
    121     protected abstract void runTest() throws Throwable;
    122 
    123     /**
    124      * Observe the state of this test companion
    125      */
    126     public interface TestObserver {
    127         void onStatusUpdate(@NonNull CharSequence status);
    128         void onSuccess();
    129         void onFail(@NonNull CharSequence error);
    130         void onAbort();
    131     }
    132 
    133     /**
    134      * Serialize callbacks to main thread.
    135      */
    136     public static class TestHandler extends Handler {
    137         static final int SUCCESS = 0;
    138         static final int FAIL = 1;
    139         static final int ABORT = 2;
    140         static final int UPDATE_STATUS = 3;
    141 
    142         private final @NonNull TestObserver mObserver;
    143 
    144         TestHandler(@NonNull TestObserver observer) {
    145             mObserver = observer;
    146         }
    147 
    148         @Override
    149         public void handleMessage(Message msg) {
    150             switch (msg.what) {
    151                 case SUCCESS:
    152                     mObserver.onSuccess();
    153                     break;
    154                 case FAIL:
    155                     mObserver.onFail((CharSequence)msg.obj);
    156                     break;
    157                 case ABORT:
    158                     mObserver.onAbort();
    159                     break;
    160                 case UPDATE_STATUS:
    161                     mObserver.onStatusUpdate((CharSequence)msg.obj);
    162                     break;
    163             }
    164         }
    165     }
    166 }
    167