1 /*
2  * Copyright (C) 2019 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.wifi;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.net.wifi.WifiManager;
23 import android.os.Handler;
24 import android.os.HandlerThread;
25 import android.util.Log;
26 
27 import com.android.cts.verifier.R;
28 
29 /**
30  * Base class for all Wifi test cases.
31  */
32 public abstract class BaseTestCase {
33     private static final String TAG = "BaseTestCase";
34 
35     protected Context mContext;
36     protected Resources mResources;
37     protected Listener mListener;
38 
39     private Thread mThread;
40     private HandlerThread mHandlerThread;
41     protected Handler mHandler;
42     protected WifiManager mWifiManager;
43     protected TestUtils mTestUtils;
44 
45     protected String mSsid;
46     protected String mPsk;
47 
BaseTestCase(Context context)48     public BaseTestCase(Context context) {
49         mContext = context;
50         mResources = mContext.getResources();
51     }
52 
53     /**
54      * Set up the test case. Executed once before test starts.
55      */
setUp()56     protected void setUp() {
57         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
58         mTestUtils = new TestUtils(mContext, mListener);
59 
60         // Ensure we're not connected to any wifi network before we start the tests.
61         if (mTestUtils.isConnected(null, null)) {
62             mListener.onTestFailed(mContext.getString(
63                     R.string.wifi_status_connected_to_other_network));
64             throw new IllegalStateException("Should not be connected to any network");
65         }
66         /**
67          * TODO: Clear the state before each test. This needs to be an instrumentation to
68          * run the below shell commands.
69         SystemUtil.runShellCommand("wifi network-suggestions-set-user-approved "
70                 + mContext.getPackageName() + " no");
71         SystemUtil.runShellCommand("wifi network-requests-remove-user-approved-access-points "
72                 + mContext.getPackageName());
73         */
74     }
75 
76     /**
77      * Tear down the test case. Executed after test finishes - whether on success or failure.
78      */
tearDown()79     protected void tearDown() {
80         mWifiManager = null;
81     }
82 
83     /**
84      * Execute test case.
85      *
86      * @return true on success, false on failure. In case of failure
87      */
executeTest()88     protected abstract boolean executeTest() throws InterruptedException;
89 
90     /**
91      * Returns a String describing the failure reason of the most recent test failure (not valid
92      * in other scenarios). Override to customize the failure string.
93      */
getFailureReason()94     protected String getFailureReason() {
95         return mContext.getString(R.string.wifi_unexpected_error);
96     }
97 
98     /**
99      * Start running the test case.
100      * <p>
101      * Test case is executed in another thread.
102      */
start(@onNull Listener listener, @NonNull String ssid, @NonNull String psk)103     public void start(@NonNull Listener listener, @NonNull String ssid, @NonNull String psk) {
104         mListener = listener;
105         mSsid = ssid;
106         mPsk = psk;
107 
108         stop();
109         mHandlerThread = new HandlerThread("CtsVerifier-Wifi");
110         mHandlerThread.start();
111         mHandler = new Handler(mHandlerThread.getLooper());
112         mThread = new Thread(
113                 new Runnable() {
114                     @Override
115                     public void run() {
116                         mListener.onTestStarted();
117                         try {
118                             setUp();
119                         } catch (Exception e) {
120                             Log.e(TAG, "Setup failed", e);
121                             mListener.onTestFailed(mContext.getString(R.string.wifi_setup_error));
122                             return;
123                         }
124 
125                         try {
126                             if (executeTest()) {
127                                 mListener.onTestSuccess();
128                             } else {
129                                 mListener.onTestFailed(getFailureReason());
130                             }
131                         } catch (Exception e) {
132                             Log.e(TAG, "Execute failed", e);
133                             mListener.onTestFailed(
134                                     mContext.getString(R.string.wifi_unexpected_error));
135                         } finally {
136                             tearDown();
137                         }
138                     }
139                 });
140         mThread.start();
141     }
142 
143     /**
144      * Stop the currently running test case.
145      */
stop()146     public void stop() {
147         if (mThread != null) {
148             mThread.interrupt();
149             mThread = null;
150         }
151         if (mHandlerThread != null) {
152             mHandlerThread.quitSafely();
153             mHandlerThread = null;
154             mHandler = null;
155         }
156     }
157 
158     /**
159      * Listener interface used to communicate the state and status of the test case. It should
160      * be implemented by any activity encompassing a test case.
161      */
162     public interface Listener {
163         /**
164          * This function is invoked when the test case starts.
165          */
onTestStarted()166         void onTestStarted();
167 
168         /**
169          * This function is invoked by the test to send a message to listener.
170          */
onTestMsgReceived(String msg)171         void onTestMsgReceived(String msg);
172 
173         /**
174          * This function is invoked when the test finished successfully.
175          */
onTestSuccess()176         void onTestSuccess();
177 
178         /**
179          * This function is invoked when the test failed (test is done).
180          */
onTestFailed(String reason)181         void onTestFailed(String reason);
182     }
183 }
184 
185