1 /* 2 * Copyright (C) 2013 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.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.DialogInterface; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.os.Bundle; 29 import android.widget.ListView; 30 import android.widget.Toast; 31 32 import com.android.cts.verifier.PassFailButtons; 33 import com.android.cts.verifier.R; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 public class BleServerTestBaseActivity extends PassFailButtons.Activity { 39 40 private static final int PASS_FLAG_ADD_SERVICE = 0x1; 41 private static final int PASS_FLAG_CONNECT = 0x2; 42 private static final int PASS_FLAG_READ_CHARACTERISTIC = 0x4; 43 private static final int PASS_FLAG_WRITE_CHARACTERISTIC = 0x8; 44 private static final int PASS_FLAG_READ_DESCRIPTOR = 0x10; 45 private static final int PASS_FLAG_WRITE_DESCRIPTOR = 0x20; 46 private static final int PASS_FLAG_WRITE = 0x40; 47 private static final int PASS_FLAG_DISCONNECT = 0x80; 48 private static final int PASS_FLAG_NOTIFY_CHARACTERISTIC = 0x100; 49 private static final int PASS_FLAG_READ_CHARACTERISTIC_NO_PERMISSION = 0x200; 50 private static final int PASS_FLAG_WRITE_CHARACTERISTIC_NO_PERMISSION = 0x400; 51 private static final int PASS_FLAG_READ_DESCRIPTOR_NO_PERMISSION = 0x800; 52 private static final int PASS_FLAG_WRITE_DESCRIPTOR_NO_PERMISSION = 0x1000; 53 private static final int PASS_FLAG_INDICATE_CHARACTERISTIC = 0x2000; 54 private static final int PASS_FLAG_MTU_CHANGE_23BYTES = 0x4000; 55 private static final int PASS_FLAG_MTU_CHANGE_512BYTES = 0x8000; 56 private static final int PASS_FLAG_RELIABLE_WRITE_BAD_RESP = 0x10000; 57 private static final int PASS_FLAG_SERVICE_CHANGED_INDICATION = 0x20000; 58 private static final int PASS_FLAG_ALL = 0x3FFFF; 59 60 private final int BLE_SERVICE_ADDED = 0; 61 private final int BLE_SERVER_CONNECTED = 1; 62 private final int BLE_CHARACTERISTIC_READ_REQUEST = 2; 63 private final int BLE_CHARACTERISTIC_WRITE_REQUEST = 3; 64 private final int BLE_SERVER_MTU_23BYTES = 4; 65 private final int BLE_SERVER_MTU_512BYTES = 5; 66 private final int BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION = 6; 67 private final int BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION = 7; 68 private final int BLE_EXECUTE_WRITE = 8; 69 private final int BLE_EXECUTE_WRITE_BAD_RESP = 9; 70 private final int BLE_CHARACTERISTIC_NOTIFICATION_REQUEST = 9; //10; 71 private final int BLE_CHARACTERISTIC_INDICATE_REQUEST = 10; //11; 72 private final int BLE_DESCRIPTOR_READ_REQUEST = 11; //12; 73 private final int BLE_DESCRIPTOR_WRITE_REQUEST = 12; //13; 74 private final int BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION = 13; //14; 75 private final int BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION = 14; //15; 76 private final int BLE_SERVOCE_CHANGED_INDICATION = 15; // 16; 77 private final int BLE_SERVER_DISCONNECTED = 16; //17; 78 private final int BLE_OPEN_FAIL = 17; //18; 79 80 private TestAdapter mTestAdapter; 81 private long mAllPassed; 82 83 @Override onCreate(Bundle savedInstanceState)84 public void onCreate(Bundle savedInstanceState) { 85 super.onCreate(savedInstanceState); 86 setContentView(R.layout.ble_server_start); 87 setPassFailButtonClickListeners(); 88 setInfoResources(R.string.ble_server_start_name, 89 R.string.ble_server_start_info, -1); 90 getPassButton().setEnabled(false); 91 92 mTestAdapter = new TestAdapter(this, setupTestList()); 93 ListView listView = (ListView) findViewById(R.id.ble_server_tests); 94 listView.setAdapter(mTestAdapter); 95 96 // mAllPassed = 0; 97 // skip Reliable write (bad response) test 98 mAllPassed = PASS_FLAG_RELIABLE_WRITE_BAD_RESP; 99 } 100 101 @Override onResume()102 public void onResume() { 103 super.onResume(); 104 105 IntentFilter filter = new IntentFilter(); 106 filter.addAction(BleServerService.BLE_BLUETOOTH_DISABLED); 107 filter.addAction(BleServerService.BLE_SERVICE_ADDED); 108 filter.addAction(BleServerService.BLE_SERVER_CONNECTED); 109 filter.addAction(BleServerService.BLE_MTU_REQUEST_23BYTES); 110 filter.addAction(BleServerService.BLE_MTU_REQUEST_512BYTES); 111 filter.addAction(BleServerService.BLE_CHARACTERISTIC_READ_REQUEST); 112 filter.addAction(BleServerService.BLE_CHARACTERISTIC_WRITE_REQUEST); 113 filter.addAction(BleServerService.BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION); 114 filter.addAction(BleServerService.BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION); 115 filter.addAction(BleServerService.BLE_CHARACTERISTIC_NOTIFICATION_REQUEST); 116 filter.addAction(BleServerService.BLE_CHARACTERISTIC_INDICATE_REQUEST); 117 filter.addAction(BleServerService.BLE_DESCRIPTOR_READ_REQUEST); 118 filter.addAction(BleServerService.BLE_DESCRIPTOR_WRITE_REQUEST); 119 filter.addAction(BleServerService.BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION); 120 filter.addAction(BleServerService.BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION); 121 filter.addAction(BleServerService.BLE_EXECUTE_WRITE); 122 filter.addAction(BleServerService.BLE_RELIABLE_WRITE_BAD_RESP); 123 filter.addAction(BleServerService.BLE_SERVER_DISCONNECTED); 124 filter.addAction(BleServerService.BLE_OPEN_FAIL); 125 filter.addAction(BleServerService.BLE_BLUETOOTH_MISMATCH_SECURE); 126 filter.addAction(BleServerService.BLE_BLUETOOTH_MISMATCH_INSECURE); 127 filter.addAction(BleServerService.BLE_ADVERTISE_UNSUPPORTED); 128 filter.addAction(BleServerService.BLE_ADD_SERVICE_FAIL); 129 filter.addAction(BleServerService.BLE_SERVICE_CHANGED_INDICATION); 130 131 registerReceiver(mBroadcast, filter, RECEIVER_EXPORTED); 132 } 133 134 @Override onPause()135 public void onPause() { 136 super.onPause(); 137 unregisterReceiver(mBroadcast); 138 } 139 140 @Override onDestroy()141 public void onDestroy() { 142 super.onDestroy(); 143 } 144 setupTestList()145 private List<Integer> setupTestList() { 146 ArrayList<Integer> testList = new ArrayList<Integer>(); 147 testList.add(R.string.ble_server_add_service); 148 testList.add(R.string.ble_server_receiving_connect); 149 testList.add(R.string.ble_server_read_characteristic); 150 testList.add(R.string.ble_server_write_characteristic); 151 testList.add(R.string.ble_server_mtu_23bytes); 152 testList.add(R.string.ble_server_mtu_512bytes); 153 testList.add(R.string.ble_server_read_characteristic_without_permission); 154 testList.add(R.string.ble_server_write_characteristic_without_permission); 155 testList.add(R.string.ble_server_reliable_write); 156 // testList.add(R.string.ble_server_reliable_write_bad_resp); 157 testList.add(R.string.ble_server_notify_characteristic); 158 testList.add(R.string.ble_server_indicate_characteristic); 159 testList.add(R.string.ble_server_read_descriptor); 160 testList.add(R.string.ble_server_write_descriptor); 161 testList.add(R.string.ble_server_read_descriptor_without_permission); 162 testList.add(R.string.ble_server_write_descriptor_without_permission); 163 testList.add(R.string.ble_server_service_changed_indication); 164 testList.add(R.string.ble_server_receiving_disconnect); 165 return testList; 166 } 167 showErrorDialog(int titleId, int messageId, boolean finish)168 private void showErrorDialog(int titleId, int messageId, boolean finish) { 169 AlertDialog.Builder builder = new AlertDialog.Builder(this) 170 .setTitle(titleId) 171 .setMessage(messageId); 172 if (finish) { 173 builder.setOnCancelListener(new Dialog.OnCancelListener() { 174 @Override 175 public void onCancel(DialogInterface dialog) { 176 finish(); 177 } 178 }); 179 } 180 builder.create().show(); 181 } 182 183 private BroadcastReceiver mBroadcast = new BroadcastReceiver() { 184 @Override 185 public void onReceive(Context context, Intent intent) { 186 String action = intent.getAction(); 187 switch (action) { 188 case BleServerService.BLE_BLUETOOTH_DISABLED: 189 showErrorDialog(R.string.ble_bluetooth_disable_title, R.string.ble_bluetooth_disable_message, true); 190 break; 191 case BleServerService.BLE_SERVICE_ADDED: 192 mTestAdapter.setTestPass(BLE_SERVICE_ADDED); 193 mAllPassed |= PASS_FLAG_ADD_SERVICE; 194 break; 195 case BleServerService.BLE_SERVER_CONNECTED: 196 mTestAdapter.setTestPass(BLE_SERVER_CONNECTED); 197 mAllPassed |= PASS_FLAG_CONNECT; 198 break; 199 case BleServerService.BLE_CHARACTERISTIC_READ_REQUEST: 200 // Sometimes server returns incorrect pairing status. 201 // And it causes the mismatch of pairing status and connection status. 202 // So consider the connection went well if reading characteristic went well. 203 mTestAdapter.setTestPass(BLE_SERVER_CONNECTED); 204 mAllPassed |= PASS_FLAG_CONNECT; 205 206 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_READ_REQUEST); 207 mAllPassed |= PASS_FLAG_READ_CHARACTERISTIC; 208 break; 209 case BleServerService.BLE_CHARACTERISTIC_WRITE_REQUEST: 210 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_WRITE_REQUEST); 211 mAllPassed |= PASS_FLAG_WRITE_CHARACTERISTIC; 212 break; 213 case BleServerService.BLE_DESCRIPTOR_READ_REQUEST: 214 mTestAdapter.setTestPass(BLE_DESCRIPTOR_READ_REQUEST); 215 mAllPassed |= PASS_FLAG_READ_DESCRIPTOR; 216 break; 217 case BleServerService.BLE_DESCRIPTOR_WRITE_REQUEST: 218 mTestAdapter.setTestPass(BLE_DESCRIPTOR_WRITE_REQUEST); 219 mAllPassed |= PASS_FLAG_WRITE_DESCRIPTOR; 220 break; 221 case BleServerService.BLE_EXECUTE_WRITE: 222 mTestAdapter.setTestPass(BLE_EXECUTE_WRITE); 223 mAllPassed |= PASS_FLAG_WRITE; 224 break; 225 case BleServerService.BLE_RELIABLE_WRITE_BAD_RESP: 226 mTestAdapter.setTestPass(BLE_EXECUTE_WRITE_BAD_RESP); 227 mAllPassed |= PASS_FLAG_RELIABLE_WRITE_BAD_RESP; 228 break; 229 case BleServerService.BLE_SERVER_DISCONNECTED: 230 mTestAdapter.setTestPass(BLE_SERVER_DISCONNECTED); 231 mAllPassed |= PASS_FLAG_DISCONNECT; 232 break; 233 case BleServerService.BLE_CHARACTERISTIC_NOTIFICATION_REQUEST: 234 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_NOTIFICATION_REQUEST); 235 mAllPassed |= PASS_FLAG_NOTIFY_CHARACTERISTIC; 236 break; 237 case BleServerService.BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION: 238 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION); 239 mAllPassed |= PASS_FLAG_READ_CHARACTERISTIC_NO_PERMISSION; 240 break; 241 case BleServerService.BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION: 242 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION); 243 mAllPassed |= PASS_FLAG_WRITE_CHARACTERISTIC_NO_PERMISSION; 244 break; 245 case BleServerService.BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION: 246 mTestAdapter.setTestPass(BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION); 247 mAllPassed |= PASS_FLAG_READ_DESCRIPTOR_NO_PERMISSION; 248 break; 249 case BleServerService.BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION: 250 mTestAdapter.setTestPass(BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION); 251 mAllPassed |= PASS_FLAG_WRITE_DESCRIPTOR_NO_PERMISSION; 252 break; 253 case BleServerService.BLE_CHARACTERISTIC_INDICATE_REQUEST: 254 mTestAdapter.setTestPass(BLE_CHARACTERISTIC_INDICATE_REQUEST); 255 mAllPassed |= PASS_FLAG_INDICATE_CHARACTERISTIC; 256 break; 257 case BleServerService.BLE_MTU_REQUEST_23BYTES: 258 mTestAdapter.setTestPass(BLE_SERVER_MTU_23BYTES); 259 mAllPassed |= PASS_FLAG_MTU_CHANGE_23BYTES; 260 break; 261 case BleServerService.BLE_MTU_REQUEST_512BYTES: 262 mTestAdapter.setTestPass(BLE_SERVER_MTU_512BYTES); 263 mAllPassed |= PASS_FLAG_MTU_CHANGE_512BYTES; 264 break; 265 case BleServerService.BLE_MTU_BAD_REQUEST: 266 mTestAdapter.clearTestPass(BLE_SERVER_MTU_23BYTES); 267 mTestAdapter.clearTestPass(BLE_SERVER_MTU_512BYTES); 268 mAllPassed &= ~PASS_FLAG_MTU_CHANGE_23BYTES; 269 mAllPassed &= ~PASS_FLAG_MTU_CHANGE_512BYTES; 270 break; 271 case BleServerService.BLE_SERVICE_CHANGED_INDICATION: 272 mTestAdapter.setTestPass(BLE_SERVOCE_CHANGED_INDICATION); 273 mAllPassed |= PASS_FLAG_SERVICE_CHANGED_INDICATION; 274 break; 275 case BleServerService.BLE_BLUETOOTH_MISMATCH_SECURE: 276 showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_secure_message, true); 277 break; 278 case BleServerService.BLE_BLUETOOTH_MISMATCH_INSECURE: 279 showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_insecure_message, true); 280 break; 281 case BleServerService.BLE_ADVERTISE_UNSUPPORTED: 282 showErrorDialog(R.string.bt_advertise_unsupported_title, R.string.bt_advertise_unsupported_message, true); 283 break; 284 case BleServerService.BLE_OPEN_FAIL: 285 setTestResultAndFinish(false); 286 runOnUiThread(new Runnable() { 287 @Override 288 public void run() { 289 Toast.makeText(BleServerTestBaseActivity.this, R.string.bt_open_failed_message, Toast.LENGTH_SHORT).show(); 290 } 291 }); 292 break; 293 case BleServerService.BLE_ADD_SERVICE_FAIL: 294 showErrorDialog(R.string.bt_add_service_failed_title, R.string.bt_add_service_failed_message, true); 295 break; 296 } 297 298 mTestAdapter.notifyDataSetChanged(); 299 if (mAllPassed == PASS_FLAG_ALL) getPassButton().setEnabled(true); 300 } 301 }; 302 } 303