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