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.util.Log; 32 import android.view.View; 33 import android.widget.AdapterView; 34 import android.widget.ListView; 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 BleEncryptedClientBaseActivity extends PassFailButtons.Activity { 43 44 private TestAdapter mTestAdapter; 45 private int mAllPassed; 46 private Dialog mDialog; 47 private Handler mHandler; 48 49 private final int BLE_WRITE_ENCRIPTED_CHARACTERISTIC = 0; 50 private final int BLE_READ_ENCRIPTED_CHARACTERISTIC = 1; 51 private final int BLE_WRITE_ENCRIPTED_DESCRIPTOR = 2; 52 private final int BLE_READ_ENCRIPTED_DESCRIPTOR = 3; 53 54 @Override onCreate(Bundle savedInstanceState)55 protected void onCreate(Bundle savedInstanceState) { 56 super.onCreate(savedInstanceState); 57 setContentView(R.layout.ble_encrypted_client_test); 58 setPassFailButtonClickListeners(); 59 setInfoResources(R.string.ble_encrypted_client_name, 60 R.string.ble_encrypted_client_info, -1); 61 getPassButton().setEnabled(false); 62 63 mHandler = new Handler(); 64 65 mTestAdapter = new TestAdapter(this, setupTestList()); 66 ListView listView = (ListView) findViewById(R.id.ble_client_enctypted_tests); 67 listView.setAdapter(mTestAdapter); 68 listView.setOnItemClickListener(new ListView.OnItemClickListener() { 69 @Override 70 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 71 Intent intent = new Intent(BleEncryptedClientBaseActivity.this, BleEncryptedClientService.class); 72 Log.v(getLocalClassName(), "onItemClick()"); 73 switch (position) { 74 case BLE_WRITE_ENCRIPTED_CHARACTERISTIC: 75 intent.setAction(BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_CHARACTERISTIC); 76 break; 77 case BLE_READ_ENCRIPTED_CHARACTERISTIC: 78 intent.setAction(BleEncryptedClientService.ACTION_READ_ENCRYPTED_CHARACTERISTIC); 79 break; 80 case BLE_WRITE_ENCRIPTED_DESCRIPTOR: 81 intent.setAction(BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_DESCRIPTOR); 82 break; 83 case BLE_READ_ENCRIPTED_DESCRIPTOR: 84 intent.setAction(BleEncryptedClientService.ACTION_READ_ENCRYPTED_DESCRIPTOR); 85 break; 86 default: 87 return; 88 } 89 startService(intent); 90 showProgressDialog(); 91 } 92 }); 93 94 mAllPassed = 0; 95 } 96 97 @Override onResume()98 public void onResume() { 99 super.onResume(); 100 101 IntentFilter filter = new IntentFilter(); 102 filter.addAction(BleEncryptedClientService.INTENT_BLE_BLUETOOTH_DISABLED); 103 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC); 104 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC); 105 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR); 106 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR); 107 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC); 108 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC); 109 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR); 110 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR); 111 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC); 112 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC); 113 filter.addAction(BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR); 114 filter.addAction(BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR); 115 filter.addAction(BleEncryptedClientService.ACTION_DISCONNECTED); 116 registerReceiver(mBroadcast, filter); 117 } 118 119 @Override onPause()120 public void onPause() { 121 super.onPause(); 122 unregisterReceiver(mBroadcast); 123 closeDialog(); 124 } 125 setupTestList()126 private List<Integer> setupTestList() { 127 ArrayList<Integer> testList = new ArrayList<Integer>(); 128 testList.add(R.string.ble_write_authenticated_characteristic_name); 129 testList.add(R.string.ble_read_authenticated_characteristic_name); 130 testList.add(R.string.ble_write_authenticated_descriptor_name); 131 testList.add(R.string.ble_read_authenticated_descriptor_name); 132 return testList; 133 } 134 showErrorDialog(String title, String message, boolean finish)135 private void showErrorDialog(String title, String message, boolean finish) { 136 closeDialog(); 137 138 AlertDialog.Builder builder = new AlertDialog.Builder(this) 139 .setTitle(title) 140 .setMessage(message); 141 if (finish) { 142 builder.setOnCancelListener(new Dialog.OnCancelListener() { 143 @Override 144 public void onCancel(DialogInterface dialog) { 145 finish(); 146 } 147 }); 148 } 149 builder.create().show(); 150 } 151 closeDialog()152 private synchronized void closeDialog() { 153 if (mDialog != null) { 154 mDialog.dismiss(); 155 mDialog = null; 156 } 157 } 158 showProgressDialog()159 private synchronized void showProgressDialog() { 160 closeDialog(); 161 162 ProgressDialog dialog = new ProgressDialog(this); 163 dialog.setTitle(R.string.ble_test_running); 164 dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 165 dialog.setMessage(getString(R.string.ble_test_running_message)); 166 dialog.setCanceledOnTouchOutside(false); 167 mDialog = dialog; 168 mDialog.show(); 169 } 170 shouldRebootBluetoothAfterTest()171 public boolean shouldRebootBluetoothAfterTest() { 172 return false; 173 } 174 isSecure()175 public boolean isSecure() { return false; } 176 177 private BroadcastReceiver mBroadcast = new BroadcastReceiver() { 178 @Override 179 public void onReceive(Context context, Intent intent) { 180 String action = intent.getAction(); 181 switch (action) { 182 case BleEncryptedClientService.INTENT_BLE_BLUETOOTH_DISABLED: 183 showErrorDialog(getString(R.string.ble_bluetooth_disable_title), getString(R.string.ble_bluetooth_disable_message), true); 184 break; 185 case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC: 186 mTestAdapter.setTestPass(BLE_WRITE_ENCRIPTED_CHARACTERISTIC); 187 mAllPassed |= 0x01; 188 if (!isSecure()) { 189 closeDialog(); 190 } 191 break; 192 case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC: 193 mTestAdapter.setTestPass(BLE_READ_ENCRIPTED_CHARACTERISTIC); 194 mAllPassed |= 0x02; 195 if (!isSecure()) { 196 closeDialog(); 197 } 198 break; 199 case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR: 200 mTestAdapter.setTestPass(BLE_WRITE_ENCRIPTED_DESCRIPTOR); 201 mAllPassed |= 0x04; 202 if (!isSecure()) { 203 closeDialog(); 204 } 205 break; 206 case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR: 207 mTestAdapter.setTestPass(BLE_READ_ENCRIPTED_DESCRIPTOR); 208 mAllPassed |= 0x08; 209 if (!isSecure()) { 210 closeDialog(); 211 } 212 break; 213 case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC: 214 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_characteristic), false); 215 break; 216 case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC: 217 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_characteristic), false); 218 break; 219 case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR: 220 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_descriptor), false); 221 break; 222 case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR: 223 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_descriptor), false); 224 break; 225 226 case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC: 227 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_write_encrypted_characteristic), false); 228 break; 229 case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC: 230 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_read_encrypted_characteristic), false); 231 break; 232 case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR: 233 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_write_encrypted_descriptor), false); 234 break; 235 case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR: 236 showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_read_encrypted_descriptor), false); 237 break; 238 239 case BleEncryptedClientService.ACTION_DISCONNECTED: 240 if (shouldRebootBluetoothAfterTest()) { 241 mBtPowerSwitcher.executeSwitching(); 242 } else { 243 closeDialog(); 244 } 245 break; 246 } 247 248 mTestAdapter.notifyDataSetChanged(); 249 if (mAllPassed == 0x0F) { 250 getPassButton().setEnabled(true); 251 } 252 } 253 }; 254 255 private static final long BT_ON_DELAY = 10000; 256 private final BluetoothPowerSwitcher mBtPowerSwitcher = new BluetoothPowerSwitcher(); 257 private class BluetoothPowerSwitcher extends BroadcastReceiver { 258 259 private boolean mIsSwitching = false; 260 private BluetoothAdapter mAdapter; 261 executeSwitching()262 public void executeSwitching() { 263 if (mAdapter == null) { 264 BluetoothManager btMgr = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 265 mAdapter = btMgr.getAdapter(); 266 } 267 268 if (!mIsSwitching) { 269 IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 270 registerReceiver(this, filter); 271 mIsSwitching = true; 272 mHandler.postDelayed(new Runnable() { 273 @Override 274 public void run() { 275 mAdapter.disable(); 276 } 277 }, 1000); 278 } 279 } 280 281 @Override onReceive(Context context, Intent intent)282 public void onReceive(Context context, Intent intent) { 283 if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 284 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 285 if (state == BluetoothAdapter.STATE_OFF) { 286 mHandler.postDelayed(new Runnable() { 287 @Override 288 public void run() { 289 mAdapter.enable(); 290 } 291 }, BT_ON_DELAY); 292 } else if (state == BluetoothAdapter.STATE_ON) { 293 mIsSwitching = false; 294 unregisterReceiver(this); 295 getPassButton().setEnabled(true); 296 closeDialog(); 297 } 298 } 299 } 300 } 301 } 302