1 /*
2  * Copyright (C) 2017 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.verifier.wifiaware;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.net.wifi.aware.WifiAwareManager;
22 import android.os.Handler;
23 import android.os.HandlerThread;
24 
25 import com.android.cts.verifier.R;
26 
27 /**
28  * Base class for all Aware test cases.
29  */
30 public abstract class BaseTestCase {
31     protected Context mContext;
32     protected Resources mResources;
33     protected Listener mListener;
34 
35     private Thread mThread;
36     private HandlerThread mHandlerThread;
37     protected Handler mHandler;
38 
39     protected WifiAwareManager mWifiAwareManager;
40 
BaseTestCase(Context context)41     public BaseTestCase(Context context) {
42         mContext = context;
43         mResources = mContext.getResources();
44     }
45 
46     /**
47      * Set up the test case. Executed once before test starts.
48      */
setUp()49     protected void setUp() {
50         mWifiAwareManager = (WifiAwareManager) mContext.getSystemService(
51                 Context.WIFI_AWARE_SERVICE);
52     }
53 
54     /**
55      * Tear down the test case. Executed after test finishes - whether on success or failure.
56      */
tearDown()57     protected void tearDown() {
58         mWifiAwareManager = null;
59     }
60 
61     /**
62      * Execute test case.
63      *
64      * @return true on success, false on failure. In case of failure
65      */
executeTest()66     protected abstract boolean executeTest() throws InterruptedException;
67 
68     /**
69      * Returns a String describing the failure reason of the most recent test failure (not valid
70      * in other scenarios). Override to customize the failure string.
71      */
getFailureReason()72     protected String getFailureReason() {
73         return mContext.getString(R.string.aware_unexpected_error);
74     }
75 
76     /**
77      * Start running the test case.
78      *
79      * Test case is executed in another thread.
80      */
start(Listener listener)81     public void start(Listener listener) {
82         mListener = listener;
83 
84         stop();
85         mHandlerThread = new HandlerThread("CtsVerifier-Aware");
86         mHandlerThread.start();
87         mHandler = new Handler(mHandlerThread.getLooper());
88         mThread = new Thread(
89                 new Runnable() {
90                     @Override
91                     public void run() {
92                         mListener.onTestStarted();
93                         try {
94                             setUp();
95                         } catch (Exception e) {
96                             mListener.onTestFailed(mContext.getString(R.string.aware_setup_error));
97                             return;
98                         }
99 
100                         try {
101                             if (executeTest()) {
102                                 mListener.onTestSuccess();
103                             } else {
104                                 mListener.onTestFailed(getFailureReason());
105                             }
106                         } catch (Exception e) {
107                             e.printStackTrace();
108                             mListener.onTestFailed(
109                                     mContext.getString(R.string.aware_unexpected_error));
110                         } finally {
111                             tearDown();
112                         }
113                     }
114                 });
115         mThread.start();
116     }
117 
118     /**
119      * Stop the currently running test case.
120      */
stop()121     public void stop() {
122         if (mThread != null) {
123             mThread.interrupt();
124             mThread = null;
125         }
126         if (mHandlerThread != null) {
127             mHandlerThread.quitSafely();
128             mHandlerThread = null;
129             mHandler = null;
130         }
131     }
132 
133     /**
134      * Listener interface used to communicate the state and status of the test case. It should
135      * be implemented by any activity encompassing a test case.
136      */
137     public interface Listener {
138         /**
139          * This function is invoked when the test case starts.
140          */
onTestStarted()141         void onTestStarted();
142 
143         /**
144          * This function is invoked by the test to send a message to listener.
145          */
onTestMsgReceived(String msg)146         void onTestMsgReceived(String msg);
147 
148         /**
149          * This function is invoked when the test finished successfully.
150          */
onTestSuccess()151         void onTestSuccess();
152 
153         /**
154          * This function is invoked when the test failed (test is done).
155          */
onTestFailed(String reason)156         void onTestFailed(String reason);
157     }
158 
159     /**
160      * Convert byte array to hex string representation utility.
161      */
bytesToHex(byte[] bytes, Character separator)162     public static String bytesToHex(byte[] bytes, Character separator) {
163         final char[] hexArray = "0123456789ABCDEF".toCharArray();
164         boolean useSeparator = separator != null;
165         char sep = 0;
166         if (useSeparator) {
167             sep = separator;
168         }
169         char[] hexChars = new char[bytes.length * 2 + (useSeparator ? bytes.length - 1 : 0)];
170         int base = 0;
171         for (int j = 0; j < bytes.length; j++) {
172             if (useSeparator && j != 0) {
173                 hexChars[base++] = sep;
174             }
175             int v = bytes[j] & 0xFF;
176             hexChars[base++] = hexArray[v >> 4];
177             hexChars[base++] = hexArray[v & 0x0F];
178         }
179         return new String(hexChars);
180     }
181 }
182