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.Service;
20 import android.bluetooth.BluetoothAdapter;
21 import android.bluetooth.BluetoothDevice;
22 import android.bluetooth.BluetoothGatt;
23 import android.bluetooth.BluetoothGattCallback;
24 import android.bluetooth.BluetoothGattCharacteristic;
25 import android.bluetooth.BluetoothGattDescriptor;
26 import android.bluetooth.BluetoothGattService;
27 import android.bluetooth.BluetoothManager;
28 import android.bluetooth.BluetoothProfile;
29 import android.bluetooth.le.BluetoothLeScanner;
30 import android.bluetooth.le.ScanCallback;
31 import android.bluetooth.le.ScanFilter;
32 import android.bluetooth.le.ScanResult;
33 import android.bluetooth.le.ScanSettings;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.os.Handler;
37 import android.os.IBinder;
38 import android.os.ParcelUuid;
39 import android.util.Log;
40 import android.widget.Toast;
41 
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.UUID;
45 
46 public class BleEncryptedClientService extends Service {
47     public static final boolean DEBUG = true;
48     public static final String TAG = "BleEncryptedClient";
49 
50     public static final String ACTION_CONNECT_WITH_SECURE =
51             "com.android.cts.verifier.bluetooth.encripted.action.ACTION_CONNECT_WITH_SECURE";
52     public static final String ACTION_CONNECT_WITHOUT_SECURE =
53             "com.android.cts.verifier.bluetooth.encripted.action.ACTION_CONNECT_WITHOUT_SECURE";
54 
55     public static final String INTENT_BLE_BLUETOOTH_DISABLED =
56             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_BLUETOOTH_DISABLED";
57     public static final String INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC =
58             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_WRITE_ENCRYPTED_CHARACTERISTIC";
59     public static final String INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC =
60             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC";
61     public static final String INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC =
62             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_READ_ENCRYPTED_CHARACTERISTIC";
63     public static final String INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC =
64             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC";
65     public static final String INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR =
66             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_WRITE_ENCRYPTED_DESCRIPTOR";
67     public static final String INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR =
68             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR";
69     public static final String INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR =
70             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_READ_ENCRYPTED_DESCRIPTOR";
71     public static final String INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR =
72             "com.android.cts.verifier.bluetooth.encripted.intent.BLE_READ_NOT_ENCRYPTED_DESCRIPTOR";
73     public static final String INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC =
74             "com.android.cts.verifier.bluetooth.encripted.intent.INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC";
75     public static final String INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC =
76             "com.android.cts.verifier.bluetooth.encripted.intent.INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC";
77     public static final String INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR =
78             "com.android.cts.verifier.bluetooth.encripted.intent.INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR";
79     public static final String INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR =
80             "com.android.cts.verifier.bluetooth.encripted.intent.INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR";
81 
82     public static final String ACTION_WRITE_ENCRYPTED_CHARACTERISTIC =
83             "com.android.cts.verifier.bluetooth.encripted.action.WRITE_ENCRYPTED_CHARACTERISTIC";
84     public static final String ACTION_READ_ENCRYPTED_CHARACTERISTIC =
85             "com.android.cts.verifier.bluetooth.encripted.action.READ_ENCRYPTED_CHARACTERISTIC";
86     public static final String ACTION_WRITE_ENCRYPTED_DESCRIPTOR =
87             "com.android.cts.verifier.bluetooth.encripted.action.WRITE_ENCRYPTED_DESCRIPTOR";
88     public static final String ACTION_READ_ENCRYPTED_DESCRIPTOR =
89             "com.android.cts.verifier.bluetooth.encripted.action.READ_ENCRYPTED_DESCRIPTOR";
90 
91     public static final String ACTION_DISCONNECTED =
92             "com.android.cts.verifier.bluetooth.encripted.action.DISCONNECTED";
93 
94     public static final String WRITE_VALUE = "ENC_CLIENT_TEST";
95 
96     private static final UUID SERVICE_UUID =
97             UUID.fromString("00009999-0000-1000-8000-00805f9b34fb");
98     private static final UUID CHARACTERISTIC_UUID =
99             UUID.fromString("00009998-0000-1000-8000-00805f9b34fb");
100     private static final UUID DESCRIPTOR_UUID =
101             UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");
102     private static final UUID CHARACTERISTIC_ENCRYPTED_WRITE_UUID =
103             UUID.fromString("00009996-0000-1000-8000-00805f9b34fb");
104     private static final UUID CHARACTERISTIC_ENCRYPTED_READ_UUID =
105             UUID.fromString("00009995-0000-1000-8000-00805f9b34fb");
106     private static final UUID DESCRIPTOR_ENCRYPTED_WRITE_UUID =
107             UUID.fromString("00009994-0000-1000-8000-00805f9b34fb");
108     private static final UUID DESCRIPTOR_ENCRYPTED_READ_UUID =
109             UUID.fromString("00009993-0000-1000-8000-00805f9b34fb");
110 
111     private BluetoothManager mBluetoothManager;
112     private BluetoothAdapter mBluetoothAdapter;
113     private BluetoothGatt mBluetoothGatt;
114     private BluetoothLeScanner mScanner;
115     private BluetoothDevice mDevice;
116     private Handler mHandler;
117     private Context mContext;
118     private String mAction;
119     private boolean mSecure;
120     private String mTarget;
121 
122     private String mLastScanError;
123     private TestTaskQueue mTaskQueue;
124 
BleEncryptedClientService()125     public BleEncryptedClientService() {
126     }
127 
128     @Override
onBind(Intent intent)129     public IBinder onBind(Intent intent) {
130         return null;
131     }
132 
133     @Override
onCreate()134     public void onCreate() {
135         super.onCreate();
136 
137         mTaskQueue = new TestTaskQueue(getClass().getName() + "_enc_cli_taskHandlerThread");
138 
139         mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
140         mBluetoothAdapter = mBluetoothManager.getAdapter();
141 
142         mScanner = mBluetoothAdapter.getBluetoothLeScanner();
143         mHandler = new Handler();
144         mContext = this;
145         mSecure = false;
146     }
147 
148     @Override
onDestroy()149     public void onDestroy() {
150         super.onDestroy();
151 
152         mTaskQueue.quit();
153 
154         if (mBluetoothGatt != null) {
155             mBluetoothGatt.disconnect();
156             mBluetoothGatt.close();
157             mBluetoothGatt = null;
158             mDevice = null;
159         }
160         stopScan();
161     }
162 
notifyBluetoothDisabled()163     private void notifyBluetoothDisabled() {
164         Intent intent = new Intent(INTENT_BLE_BLUETOOTH_DISABLED);
165         sendBroadcast(intent);
166     }
167 
notifyDisconnected()168     private void notifyDisconnected() {
169         Intent intent = new Intent(ACTION_DISCONNECTED);
170         sendBroadcast(intent);
171     }
172 
173     @Override
onStartCommand(Intent intent, int flags, int startId)174     public int onStartCommand(Intent intent, int flags, int startId) {
175         if (!mBluetoothAdapter.isEnabled()) {
176             notifyBluetoothDisabled();
177         } else {
178             if (intent != null) {
179                 mAction = intent.getAction();
180                 if (mAction == null) {
181                     mSecure = intent.getBooleanExtra(BleEncryptedServerService.EXTRA_SECURE, false);
182                 } else {
183                     switch (mAction) {
184                     case ACTION_CONNECT_WITH_SECURE:
185                         mSecure = true;
186                         break;
187                     case ACTION_CONNECT_WITHOUT_SECURE:
188                         mSecure = false;
189                         break;
190                     case ACTION_WRITE_ENCRYPTED_CHARACTERISTIC:
191                         mTarget = BleEncryptedServerService.WRITE_CHARACTERISTIC;
192                         startScan();
193                         break;
194                     case ACTION_READ_ENCRYPTED_CHARACTERISTIC:
195                         mTarget = BleEncryptedServerService.READ_CHARACTERISTIC;
196                         startScan();
197                         break;
198                     case ACTION_WRITE_ENCRYPTED_DESCRIPTOR:
199                         mTarget = BleEncryptedServerService.WRITE_DESCRIPTOR;
200                         startScan();
201                         break;
202                     case ACTION_READ_ENCRYPTED_DESCRIPTOR:
203                         mTarget = BleEncryptedServerService.READ_DESCRIPTOR;
204                         startScan();
205                         break;
206                     default:
207                         return START_NOT_STICKY;
208                     }
209                 }
210             }
211         }
212         return START_NOT_STICKY;
213     }
214 
getService()215     private BluetoothGattService getService() {
216         BluetoothGattService service = null;
217 
218         if (mBluetoothGatt != null) {
219             service = mBluetoothGatt.getService(SERVICE_UUID);
220             if (service == null) {
221                 showMessage("Service not found");
222             }
223         }
224         return service;
225     }
226 
getCharacteristic(UUID uuid)227     private BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
228         BluetoothGattCharacteristic characteristic = null;
229 
230         BluetoothGattService service = getService();
231         if (service != null) {
232             characteristic = service.getCharacteristic(uuid);
233             if (characteristic == null) {
234                 showMessage("Characteristic not found");
235             }
236         }
237         return characteristic;
238     }
239 
getDescriptor(UUID uid)240     private BluetoothGattDescriptor getDescriptor(UUID uid) {
241         BluetoothGattDescriptor descriptor = null;
242 
243         BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID);
244         if (characteristic != null) {
245             descriptor = characteristic.getDescriptor(uid);
246             if (descriptor == null) {
247                 showMessage("Descriptor not found");
248             }
249         }
250         return descriptor;
251     }
252 
sleep(int millis)253     private void sleep(int millis) {
254         try {
255             Thread.sleep(millis);
256         } catch (InterruptedException e) {
257             Log.e(TAG, "Error in thread sleep", e);
258         }
259     }
260 
startEncryptedAction()261     private void startEncryptedAction() {
262         BluetoothGattCharacteristic characteristic;
263         BluetoothGattCharacteristic caseCharacteristic;
264         BluetoothGattDescriptor descriptor;
265         switch (mTarget) {
266         case BleEncryptedServerService.WRITE_CHARACTERISTIC:
267             Log.v(TAG, "WRITE_CHARACTERISTIC");
268             characteristic = getCharacteristic(CHARACTERISTIC_ENCRYPTED_WRITE_UUID);
269             characteristic.setValue(WRITE_VALUE);
270             mBluetoothGatt.writeCharacteristic(characteristic);
271             break;
272         case BleEncryptedServerService.READ_CHARACTERISTIC:
273             Log.v(TAG, "READ_CHARACTERISTIC");
274             characteristic = getCharacteristic(CHARACTERISTIC_ENCRYPTED_READ_UUID);
275             mBluetoothGatt.readCharacteristic(characteristic);
276             break;
277         case BleEncryptedServerService.WRITE_DESCRIPTOR:
278             Log.v(TAG, "WRITE_DESCRIPTOR");
279             descriptor = getDescriptor(DESCRIPTOR_ENCRYPTED_WRITE_UUID);
280             descriptor.setValue(WRITE_VALUE.getBytes());
281             mBluetoothGatt.writeDescriptor(descriptor);
282             break;
283         case BleEncryptedServerService.READ_DESCRIPTOR:
284             Log.v(TAG, "READ_DESCRIPTOR");
285             descriptor = getDescriptor(DESCRIPTOR_ENCRYPTED_READ_UUID);
286             mBluetoothGatt.readDescriptor(descriptor);
287             break;
288         }
289     }
290 
showMessage(final String msg)291     private void showMessage(final String msg) {
292         mHandler.post(new Runnable() {
293             public void run() {
294                 Toast.makeText(BleEncryptedClientService.this, msg, Toast.LENGTH_SHORT).show();
295             }
296         });
297     }
298 
299     private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() {
300         @Override
301         public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
302             if (DEBUG) Log.d(TAG, "onConnectionStateChange: status = " + status + ", newState = " + newState);
303             if (status == BluetoothGatt.GATT_SUCCESS) {
304                 if (newState == BluetoothProfile.STATE_CONNECTED) {
305                     showMessage("Bluetooth LE connected");
306                     mTaskQueue.addTask(new Runnable() {
307                         @Override
308                         public void run() {
309                             mBluetoothGatt.discoverServices();
310                         }
311                     }, 1000);
312                 } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
313                     showMessage("Bluetooth LE disconnected");
314                     mTaskQueue.addTask(new Runnable() {
315                         @Override
316                         public void run() {
317                             if (mBluetoothGatt != null) {
318                                 mBluetoothGatt.close();
319                                 mBluetoothGatt = null;
320                                 mTarget = null;
321                                 mDevice = null;
322                                 notifyDisconnected();
323                             }
324                         }
325                     }, 1000);
326                 }
327             } else {
328                 showMessage("Connection Not Success.");
329                 if (mTarget != null) {
330                     Intent intent;
331                     switch (mTarget) {
332                     case BleEncryptedServerService.READ_CHARACTERISTIC:
333                         intent = new Intent(INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC);
334                         break;
335                     case BleEncryptedServerService.WRITE_CHARACTERISTIC:
336                         if (mSecure) {
337                             intent = new Intent(INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC);
338                         } else {
339                             intent = new Intent(INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC);
340                         }
341                         break;
342                     case BleEncryptedServerService.READ_DESCRIPTOR:
343                         intent = new Intent(INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR);
344                         break;
345                     case BleEncryptedServerService.WRITE_DESCRIPTOR:
346                         if (mSecure) {
347                             intent = new Intent(INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR);
348                         } else {
349                             intent = new Intent(INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR);
350                         }
351                         break;
352                     default:
353                         return;
354                     }
355                     if (mBluetoothGatt != null) {
356                         mBluetoothGatt.close();
357                         mBluetoothGatt = null;
358                         mDevice = null;
359                         mTarget = null;
360                     }
361                     sendBroadcast(intent);
362                 }
363             }
364         }
365 
366         @Override
367         public void onServicesDiscovered(BluetoothGatt gatt, int status) {
368             if (DEBUG){
369                 Log.d(TAG, "onServiceDiscovered");
370             }
371             if ((status == BluetoothGatt.GATT_SUCCESS) && (mBluetoothGatt.getService(SERVICE_UUID) != null)) {
372                 showMessage("Service discovered");
373                 startEncryptedAction();
374             }
375         }
376 
377         @Override
378         public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, final int status) {
379             final String value = characteristic.getStringValue(0);
380             UUID uid = characteristic.getUuid();
381             if (DEBUG) {
382                 Log.d(TAG, "onCharacteristicWrite: characteristic.val=" + value + " status=" + status + " uid=" + uid);
383             }
384 
385             if (uid.equals(CHARACTERISTIC_ENCRYPTED_WRITE_UUID)) {
386                 mTaskQueue.addTask(new Runnable() {
387                     @Override
388                     public void run() {
389                         if (status == BluetoothGatt.GATT_SUCCESS) {
390                             if (mSecure) {
391                                 mBluetoothGatt.disconnect();
392                                 if (WRITE_VALUE.equals(value)) {
393                                     Intent intent = new Intent(INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC);
394                                     sendBroadcast(intent);
395                                 } else {
396                                     showMessage("Written data is not correct");
397                                 }
398                             }
399                         } else {
400                             if (!mSecure) {
401                                 mBluetoothGatt.disconnect();
402                                 Intent intent = new Intent(INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC);
403                                 sendBroadcast(intent);
404                             } else {
405                                 mBluetoothGatt.disconnect();
406                                 Intent intent = new Intent(INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC);
407                                 sendBroadcast(intent);
408                             }
409                         }
410                     }
411                 }, 1000);
412             }
413         }
414 
415         @Override
416         public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
417             UUID uid = characteristic.getUuid();
418             if (DEBUG) {
419                 Log.d(TAG, "onCharacteristicRead: status=" + status);
420             }
421             if (uid.equals(CHARACTERISTIC_ENCRYPTED_READ_UUID)) {
422                 mTaskQueue.addTask(new Runnable() {
423                     @Override
424                     public void run() {
425                         if (status == BluetoothGatt.GATT_SUCCESS) {
426                             if (mSecure) {
427                                 mBluetoothGatt.disconnect();
428                                 if (Arrays.equals(BleEncryptedServerService.WRITE_VALUE.getBytes(), characteristic.getValue())) {
429                                     Intent intent = new Intent(INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC);
430                                     sendBroadcast(intent);
431                                 } else {
432                                     showMessage("Read data is not correct");
433                                 }
434                             } else {
435                                 mBluetoothGatt.disconnect();
436                                 Intent intent = new Intent(INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC);
437                                 sendBroadcast(intent);
438                             }
439                         } else {
440                             if (!mSecure) {
441                                 mBluetoothGatt.disconnect();
442                                 Intent intent = new Intent(INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC);
443                                 sendBroadcast(intent);
444                             } else {
445                                 mBluetoothGatt.disconnect();
446                                 Intent intent = new Intent(INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC);
447                                 sendBroadcast(intent);
448                             }
449                         }
450                     }
451                 }, 1000);
452             }
453         }
454 
455         @Override
456         public void onDescriptorRead(BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) {
457             if (DEBUG) {
458                 Log.d(TAG, "onDescriptorRead: status=" + status);
459             }
460 
461             mTaskQueue.addTask(new Runnable() {
462                 @Override
463                 public void run() {
464                     UUID uid = descriptor.getUuid();
465                     if ((status == BluetoothGatt.GATT_SUCCESS)) {
466                         if (uid.equals(DESCRIPTOR_ENCRYPTED_READ_UUID)) {
467                             if (mSecure) {
468                                 mBluetoothGatt.disconnect();
469                                 if (Arrays.equals(BleEncryptedServerService.WRITE_VALUE.getBytes(), descriptor.getValue())) {
470                                     Intent intent = new Intent(INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR);
471                                     sendBroadcast(intent);
472                                 } else {
473                                     showMessage("Read data is not correct");
474                                 }
475                             } else {
476                                 mBluetoothGatt.disconnect();
477                                 Intent intent = new Intent(INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR);
478                                 sendBroadcast(intent);
479                             }
480                         }
481                     } else {
482                         if (!mSecure) {
483                             mBluetoothGatt.disconnect();
484                             Intent intent = new Intent(INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR);
485                             sendBroadcast(intent);
486                         } else {
487                             if (uid.equals(DESCRIPTOR_ENCRYPTED_READ_UUID)) {
488                                 mBluetoothGatt.disconnect();
489                                 Intent intent = new Intent(INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR);
490                                 sendBroadcast(intent);
491                             }
492                         }
493                     }
494                 }
495             }, 1000);
496         }
497 
498         @Override
499         public void onDescriptorWrite(BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) {
500             if (DEBUG) {
501                 Log.d(TAG, "onDescriptorWrite: status=" + status);
502             }
503 
504             mTaskQueue.addTask(new Runnable() {
505                 @Override
506                 public void run() {
507                     UUID uid = descriptor.getUuid();
508                     if (uid.equals(DESCRIPTOR_ENCRYPTED_WRITE_UUID)) {
509                         if ((status == BluetoothGatt.GATT_SUCCESS)) {
510                             if (mSecure) {
511                                 mBluetoothGatt.disconnect();
512                                 if (Arrays.equals(WRITE_VALUE.getBytes(), descriptor.getValue())) {
513                                     Intent intent = new Intent(INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR);
514                                     sendBroadcast(intent);
515                                 } else {
516                                     showMessage("Written data is not correct");
517                                 }
518                             }
519                         } else {
520                             if (!mSecure) {
521                                 mBluetoothGatt.disconnect();
522                                 Intent intent = new Intent(INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR);
523                                 sendBroadcast(intent);
524                             } else {
525                                 mBluetoothGatt.disconnect();
526                                 Intent intent = new Intent(INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR);
527                                 sendBroadcast(intent);
528                             }
529                         }
530                     }
531                 }
532             }, 1000);
533         }
534     };
535 
536     private final ScanCallback mScanCallback = new ScanCallback() {
537         @Override
538         public void onScanResult(int callbackType, final ScanResult result) {
539             if (mBluetoothGatt== null) {
540                 mDevice = result.getDevice();
541                 int bond_state = mDevice.getBondState();
542                 if (mSecure && bond_state != BluetoothDevice.BOND_BONDED) {
543                     mLastScanError = "This test is a test of Secure.\n Before running the test, please do the pairing.";
544                     return;
545                 } else if (!mSecure && bond_state != BluetoothDevice.BOND_NONE) {
546                     mLastScanError = "This test is a test of Insecure\n Before running the test, please release the pairing.";
547                     return;
548                 }
549                 mLastScanError = null;
550                 stopScan();
551                 mBluetoothGatt = BleClientService.connectGatt(mDevice, mContext, false, mSecure, mGattCallbacks);
552             }
553         }
554     };
555 
startScan()556     private void startScan() {
557         if (DEBUG) Log.d(TAG, "startScan");
558         List<ScanFilter> filter = Arrays.asList(new ScanFilter.Builder().setServiceUuid(
559                 new ParcelUuid(BleEncryptedServerService.ADV_SERVICE_UUID)).build());
560         ScanSettings setting = new ScanSettings.Builder()
561                 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
562         mScanner.startScan(filter, setting, mScanCallback);
563 
564         mTaskQueue.addTask(new Runnable() {
565             @Override
566             public void run() {
567                 if (mLastScanError != null) {
568                     stopScan();
569                     Toast.makeText(BleEncryptedClientService.this, mLastScanError, Toast.LENGTH_LONG).show();
570                     mLastScanError = null;
571                 }
572             }
573         }, 10000);
574     }
575 
stopScan()576     private void stopScan() {
577         if (DEBUG) Log.d(TAG, "stopScan");
578         if (mScanner != null) {
579             mScanner.stopScan(mScanCallback);
580         }
581     }
582 }
583