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