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.verifier.bluetooth;
18 
19 import static android.content.Context.RECEIVER_EXPORTED;
20 
21 import android.app.AlertDialog;
22 import android.app.Dialog;
23 import android.app.ProgressDialog;
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.Looper;
32 import android.os.Message;
33 import android.widget.ListView;
34 import android.widget.Toast;
35 
36 import com.android.cts.verifier.PassFailButtons;
37 import com.android.cts.verifier.R;
38 
39 import java.util.ArrayList;
40 import java.util.List;
41 
42 public class BleConnectionPriorityClientBaseActivity extends PassFailButtons.Activity {
43 
44     public static final int DISABLE_ADAPTER = 0;
45 
46     private TestAdapter mTestAdapter;
47     private boolean mPassed = false;
48     private Dialog mDialog;
49 
50     private static final int BLE_CONNECTION_UPDATE = 0;
51     public static final String TAG = BleConnectionPriorityClientBaseActivity.class.getSimpleName();
52 
53     private static final int ALL_PASSED = 0x1;
54 
55     private boolean mSecure;
56 
57     private Handler mHandler;
58     private int mCurrentTest = -1;
59 
60     @Override
onCreate(Bundle savedInstanceState)61     protected void onCreate(Bundle savedInstanceState) {
62         super.onCreate(savedInstanceState);
63         setContentView(R.layout.ble_connection_priority_client_test);
64         setPassFailButtonClickListeners();
65         setInfoResources(
66                 R.string.ble_connection_priority_client_name,
67                 R.string.ble_connection_priority_client_info,
68                 -1);
69         getPassButton().setEnabled(false);
70 
71         mHandler = new Handler();
72 
73         mTestAdapter = new TestAdapter(this, setupTestList());
74         ListView listView = (ListView) findViewById(R.id.ble_client_connection_tests);
75         listView.setAdapter(mTestAdapter);
76     }
77 
78     @Override
onResume()79     public void onResume() {
80         super.onResume();
81 
82         IntentFilter filter = new IntentFilter();
83         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_DISABLED);
84         filter.addAction(BleConnectionPriorityClientService.ACTION_CONNECTION_SERVICES_DISCOVERED);
85         filter.addAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_FINISH);
86         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_SECURE);
87         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_INSECURE);
88         filter.addAction(BleConnectionPriorityClientService.ACTION_FINISH_DISCONNECT);
89         registerReceiver(mBroadcast, filter, RECEIVER_EXPORTED);
90     }
91 
92     @Override
onPause()93     public void onPause() {
94         super.onPause();
95         unregisterReceiver(mBroadcast);
96         closeDialog();
97     }
98 
setSecure(boolean secure)99     protected void setSecure(boolean secure) {
100         mSecure = secure;
101     }
102 
isSecure()103     public boolean isSecure() {
104         return mSecure;
105     }
106 
closeDialog()107     private synchronized void closeDialog() {
108         if (mDialog != null) {
109             mDialog.dismiss();
110             mDialog = null;
111         }
112     }
113 
showProgressDialog()114     private synchronized void showProgressDialog() {
115         closeDialog();
116 
117         ProgressDialog dialog = new ProgressDialog(this);
118         dialog.setTitle(R.string.ble_test_running);
119         dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
120         dialog.setMessage(getString(R.string.ble_test_running_message));
121         dialog.setCanceledOnTouchOutside(false);
122         mDialog = dialog;
123         mDialog.show();
124     }
125 
showErrorDialog(int titleId, int messageId, boolean finish)126     private void showErrorDialog(int titleId, int messageId, boolean finish) {
127         AlertDialog.Builder builder =
128                 new AlertDialog.Builder(this).setTitle(titleId).setMessage(messageId);
129         if (finish) {
130             builder.setOnCancelListener(
131                     new Dialog.OnCancelListener() {
132                         @Override
133                         public void onCancel(DialogInterface dialog) {
134                             finish();
135                         }
136                     });
137         }
138         builder.create().show();
139     }
140 
setupTestList()141     private List<Integer> setupTestList() {
142         ArrayList<Integer> testList = new ArrayList<Integer>();
143         testList.add(R.string.ble_connection_priority_client_description);
144         return testList;
145     }
146 
executeNextTest(long delay)147     private void executeNextTest(long delay) {
148         mHandler.postDelayed(
149                 new Runnable() {
150                     @Override
151                     public void run() {
152                         executeNextTestImpl();
153                     }
154                 },
155                 delay);
156     }
157 
executeNextTestImpl()158     private void executeNextTestImpl() {
159         switch (mCurrentTest) {
160             case -1:
161             {
162                 mCurrentTest = BLE_CONNECTION_UPDATE;
163                 Intent intent = new Intent(this, BleConnectionPriorityClientService.class);
164                 intent.setAction(
165                         BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_START);
166                 startService(intent);
167                 String msg = getString(R.string.ble_client_connection_priority);
168                 Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
169                 break;
170             }
171             case BLE_CONNECTION_UPDATE:
172             {
173                 // all test done
174                 closeDialog();
175                 if (mPassed == true) {
176                     Intent intent = new Intent(this, BleConnectionPriorityClientService.class);
177                     intent.setAction(BleConnectionPriorityClientService.ACTION_DISCONNECT);
178                     startService(intent);
179                 }
180                 break;
181             }
182             default:
183                 // something went wrong
184                 closeDialog();
185                 break;
186         }
187     }
188 
shouldRebootBluetoothAfterTest()189     public boolean shouldRebootBluetoothAfterTest() {
190         return false;
191     }
192 
193     private BroadcastReceiver mBroadcast =
194             new BroadcastReceiver() {
195                 @Override
196                 public void onReceive(Context context, Intent intent) {
197                     String action = intent.getAction();
198                     switch (action) {
199                         case BleConnectionPriorityClientService.ACTION_BLUETOOTH_DISABLED:
200                             new AlertDialog.Builder(context)
201                                     .setTitle(R.string.ble_bluetooth_disable_title)
202                                     .setMessage(R.string.ble_bluetooth_disable_message)
203                                     .setOnCancelListener(
204                                             new Dialog.OnCancelListener() {
205                                                 @Override
206                                                 public void onCancel(DialogInterface dialog) {
207                                                     finish();
208                                                 }
209                                             })
210                                     .create()
211                                     .show();
212                             break;
213                         case BleConnectionPriorityClientService
214                                 .ACTION_CONNECTION_SERVICES_DISCOVERED:
215                             showProgressDialog();
216                             executeNextTest(3000);
217                             break;
218                         case BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_FINISH:
219                             mTestAdapter.setTestPass(BLE_CONNECTION_UPDATE);
220                             mPassed = true;
221                             executeNextTest(1000);
222                             break;
223                         case BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_SECURE:
224                             showErrorDialog(
225                                     R.string.ble_bluetooth_mismatch_title,
226                                     R.string.ble_bluetooth_mismatch_secure_message,
227                                     true);
228                             break;
229                         case BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_INSECURE:
230                             showErrorDialog(
231                                     R.string.ble_bluetooth_mismatch_title,
232                                     R.string.ble_bluetooth_mismatch_insecure_message,
233                                     true);
234                             break;
235                         case BleConnectionPriorityClientService.ACTION_FINISH_DISCONNECT:
236                             if (shouldRebootBluetoothAfterTest()) {
237                                 mBtPowerSwitcher.executeSwitching();
238                             } else {
239                                 getPassButton().setEnabled(true);
240                             }
241                             break;
242                     }
243                     mTestAdapter.notifyDataSetChanged();
244                 }
245             };
246 
247     private final BluetoothPowerSwitcher mBtPowerSwitcher = new BluetoothPowerSwitcher();
248 
249     private class BluetoothPowerSwitcher extends BroadcastReceiver {
250 
251         private boolean mIsSwitching = false;
252 
253         private class BluetoothHandler extends Handler {
BluetoothHandler(Looper looper)254             BluetoothHandler(Looper looper) {
255                 super(looper);
256             }
257 
258             @Override
handleMessage(Message msg)259             public void handleMessage(Message msg) {
260                 switch (msg.what) {
261                     case BleConnectionPriorityClientBaseActivity.DISABLE_ADAPTER:
262                         mIsSwitching = false;
263                         getPassButton().setEnabled(true);
264                         closeDialog();
265                         break;
266                 }
267             }
268         }
269 
executeSwitching()270         public void executeSwitching() {
271             mHandler = new BluetoothHandler(Looper.getMainLooper());
272             if (!mIsSwitching) {
273                 mIsSwitching = true;
274                 Message msg =
275                         mHandler.obtainMessage(
276                                 BleConnectionPriorityClientBaseActivity.DISABLE_ADAPTER);
277                 mHandler.sendMessageDelayed(msg, 5000);
278                 showProgressDialog();
279             }
280         }
281 
282         @Override
onReceive(Context context, Intent intent)283         public void onReceive(Context context, Intent intent) {}
284     }
285 }
286