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