1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "device/bluetooth/test/bluetooth_test_android.h"
6 
7 #include <iterator>
8 #include <sstream>
9 
10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h"
12 #include "base/bind.h"
13 #include "base/check.h"
14 #include "base/run_loop.h"
15 #include "device/bluetooth/android/wrappers.h"
16 #include "device/bluetooth/bluetooth_adapter_android.h"
17 #include "device/bluetooth/bluetooth_device_android.h"
18 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h"
19 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_android.h"
20 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
21 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
22 #include "device/bluetooth_test_jni_headers/Fakes_jni.h"
23 
24 using base::android::AttachCurrentThread;
25 using base::android::JavaParamRef;
26 using base::android::ScopedJavaLocalRef;
27 
28 namespace device {
29 
BluetoothTestAndroid()30 BluetoothTestAndroid::BluetoothTestAndroid() {
31 }
32 
~BluetoothTestAndroid()33 BluetoothTestAndroid::~BluetoothTestAndroid() {
34 }
35 
SetUp()36 void BluetoothTestAndroid::SetUp() {
37   // Set the permission to true so that we can use the API.
38   Java_Fakes_setLocationServicesState(
39       AttachCurrentThread(), true /* hasPermission */, true /* isEnabled */);
40   Java_Fakes_initFakeThreadUtilsWrapper(AttachCurrentThread(),
41                                         reinterpret_cast<intptr_t>(this));
42 }
43 
TearDown()44 void BluetoothTestAndroid::TearDown() {
45   // Unit tests are able to reset the adapter themselves (e.g.
46   // BluetoothTest::TogglePowerFakeAdapter_DestroyWithPending), so this check is
47   // necessary.
48   if (adapter_) {
49     BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
50     for (auto* device : devices) {
51       DeleteDevice(device);
52     }
53   }
54   EXPECT_EQ(0, gatt_open_connections_);
55 
56   BluetoothTestBase::TearDown();
57 }
58 
RunJavaRunnable(const base::android::ScopedJavaGlobalRef<jobject> & runnable_ref)59 static void RunJavaRunnable(
60     const base::android::ScopedJavaGlobalRef<jobject>& runnable_ref) {
61   Java_Fakes_runRunnable(AttachCurrentThread(), runnable_ref);
62 }
63 
PostTaskFromJava(JNIEnv * env,const JavaParamRef<jobject> & runnable)64 void BluetoothTestAndroid::PostTaskFromJava(
65     JNIEnv* env,
66     const JavaParamRef<jobject>& runnable) {
67   base::android::ScopedJavaGlobalRef<jobject> runnable_ref;
68   // ScopedJavaGlobalRef does not hold onto the env reference, so it is safe to
69   // use it across threads. |RunJavaRunnable| will acquire a new JNIEnv before
70   // running the Runnable.
71   runnable_ref.Reset(env, runnable);
72   task_environment_.GetMainThreadTaskRunner()->PostTask(
73       FROM_HERE, base::BindOnce(&RunJavaRunnable, runnable_ref));
74 }
75 
PlatformSupportsLowEnergy()76 bool BluetoothTestAndroid::PlatformSupportsLowEnergy() {
77   return true;
78 }
79 
InitWithDefaultAdapter()80 void BluetoothTestAndroid::InitWithDefaultAdapter() {
81   adapter_ = BluetoothAdapterAndroid::Create(
82       BluetoothAdapterWrapper_CreateWithDefaultAdapter());
83 }
84 
InitWithoutDefaultAdapter()85 void BluetoothTestAndroid::InitWithoutDefaultAdapter() {
86   adapter_ = BluetoothAdapterAndroid::Create(nullptr);
87 }
88 
InitWithFakeAdapter()89 void BluetoothTestAndroid::InitWithFakeAdapter() {
90   j_fake_bluetooth_adapter_.Reset(Java_FakeBluetoothAdapter_create(
91       AttachCurrentThread(), reinterpret_cast<intptr_t>(this)));
92 
93   adapter_ = BluetoothAdapterAndroid::Create(j_fake_bluetooth_adapter_).get();
94 }
95 
DenyPermission()96 bool BluetoothTestAndroid::DenyPermission() {
97   Java_Fakes_setLocationServicesState(
98       AttachCurrentThread(), false /* hasPermission */, true /* isEnabled */);
99   return true;
100 }
101 
SimulateLowEnergyDevice(int device_ordinal)102 BluetoothDevice* BluetoothTestAndroid::SimulateLowEnergyDevice(
103     int device_ordinal) {
104   TestBluetoothAdapterObserver observer(adapter_);
105   Java_FakeBluetoothAdapter_simulateLowEnergyDevice(
106       AttachCurrentThread(), j_fake_bluetooth_adapter_, device_ordinal);
107   return observer.last_device();
108 }
109 
RememberDeviceForSubsequentAction(BluetoothDevice * device)110 void BluetoothTestAndroid::RememberDeviceForSubsequentAction(
111     BluetoothDevice* device) {
112   BluetoothDeviceAndroid* device_android =
113       static_cast<BluetoothDeviceAndroid*>(device);
114 
115   Java_FakeBluetoothDevice_rememberDeviceForSubsequentAction(
116       base::android::AttachCurrentThread(), device_android->GetJavaObject());
117 }
118 
SimulateLocationServicesOff()119 void BluetoothTestAndroid::SimulateLocationServicesOff() {
120   Java_Fakes_setLocationServicesState(
121       AttachCurrentThread(), true /* hasPermission */, false /* isEnabled */);
122 }
123 
ForceIllegalStateException()124 void BluetoothTestAndroid::ForceIllegalStateException() {
125   Java_FakeBluetoothAdapter_forceIllegalStateException(
126       AttachCurrentThread(), j_fake_bluetooth_adapter_);
127 }
128 
SimulateGattConnection(BluetoothDevice * device)129 void BluetoothTestAndroid::SimulateGattConnection(BluetoothDevice* device) {
130   BluetoothDeviceAndroid* device_android =
131       static_cast<BluetoothDeviceAndroid*>(device);
132 
133   Java_FakeBluetoothDevice_connectionStateChange(
134       AttachCurrentThread(), device_android->GetJavaObject(),
135       0,      // android.bluetooth.BluetoothGatt.GATT_SUCCESS
136       true);  // connected
137 }
138 
SimulateGattConnectionError(BluetoothDevice * device,BluetoothDevice::ConnectErrorCode)139 void BluetoothTestAndroid::SimulateGattConnectionError(
140     BluetoothDevice* device,
141     BluetoothDevice::ConnectErrorCode) {
142   BluetoothDeviceAndroid* device_android =
143       static_cast<BluetoothDeviceAndroid*>(device);
144 
145   Java_FakeBluetoothDevice_connectionStateChange(
146       AttachCurrentThread(), device_android->GetJavaObject(),
147       // TODO(ortuno): Add all types of errors Android can produce. For now we
148       // just return a timeout error.
149       // http://crbug.com/578191
150       0x08,    // Connection Timeout from Bluetooth Spec.
151       false);  // connected
152 }
153 
SimulateGattDisconnection(BluetoothDevice * device)154 void BluetoothTestAndroid::SimulateGattDisconnection(BluetoothDevice* device) {
155   BluetoothDeviceAndroid* device_android =
156       static_cast<BluetoothDeviceAndroid*>(device);
157 
158   Java_FakeBluetoothDevice_connectionStateChange(
159       AttachCurrentThread(), device_android->GetJavaObject(),
160       0x13,    // Connection terminate by peer user from Bluetooth Spec.
161       false);  // disconnected
162 }
163 
SimulateGattServicesDiscovered(BluetoothDevice * device,const std::vector<std::string> & uuids,const std::vector<std::string> & blocked_uuids)164 void BluetoothTestAndroid::SimulateGattServicesDiscovered(
165     BluetoothDevice* device,
166     const std::vector<std::string>& uuids,
167     const std::vector<std::string>& blocked_uuids) {
168   DCHECK(blocked_uuids.empty()) << "Setting blocked_uuids unsupported.";
169   BluetoothDeviceAndroid* device_android = nullptr;
170   if (device) {
171     device_android = static_cast<BluetoothDeviceAndroid*>(device);
172   }
173 
174   // Join UUID strings into a single string.
175   std::ostringstream uuids_space_delimited;
176   std::copy(uuids.begin(), uuids.end(),
177             std::ostream_iterator<std::string>(uuids_space_delimited, " "));
178 
179   JNIEnv* env = base::android::AttachCurrentThread();
180   Java_FakeBluetoothDevice_servicesDiscovered(
181       env, device_android ? device_android->GetJavaObject() : nullptr,
182       0,  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
183       base::android::ConvertUTF8ToJavaString(env, uuids_space_delimited.str()));
184 }
185 
SimulateGattServicesDiscoveryError(BluetoothDevice * device)186 void BluetoothTestAndroid::SimulateGattServicesDiscoveryError(
187     BluetoothDevice* device) {
188   BluetoothDeviceAndroid* device_android = nullptr;
189   if (device) {
190     device_android = static_cast<BluetoothDeviceAndroid*>(device);
191   }
192 
193   Java_FakeBluetoothDevice_servicesDiscovered(
194       AttachCurrentThread(),
195       device_android ? device_android->GetJavaObject() : nullptr,
196       0x00000101,  // android.bluetooth.BluetoothGatt.GATT_FAILURE
197       nullptr);
198 }
199 
SimulateGattCharacteristic(BluetoothRemoteGattService * service,const std::string & uuid,int properties)200 void BluetoothTestAndroid::SimulateGattCharacteristic(
201     BluetoothRemoteGattService* service,
202     const std::string& uuid,
203     int properties) {
204   BluetoothRemoteGattServiceAndroid* service_android =
205       static_cast<BluetoothRemoteGattServiceAndroid*>(service);
206   JNIEnv* env = base::android::AttachCurrentThread();
207 
208   Java_FakeBluetoothGattService_addCharacteristic(
209       env, service_android->GetJavaObject(),
210       base::android::ConvertUTF8ToJavaString(env, uuid), properties);
211 }
212 
RememberCharacteristicForSubsequentAction(BluetoothRemoteGattCharacteristic * characteristic)213 void BluetoothTestAndroid::RememberCharacteristicForSubsequentAction(
214     BluetoothRemoteGattCharacteristic* characteristic) {
215   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
216       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
217 
218   Java_FakeBluetoothGattCharacteristic_rememberCharacteristicForSubsequentAction(
219       base::android::AttachCurrentThread(),
220       characteristic_android->GetJavaObject());
221 }
222 
RememberCCCDescriptorForSubsequentAction(BluetoothRemoteGattCharacteristic * characteristic)223 void BluetoothTestAndroid::RememberCCCDescriptorForSubsequentAction(
224     BluetoothRemoteGattCharacteristic* characteristic) {
225   remembered_ccc_descriptor_ =
226       characteristic
227           ->GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
228                                      ClientCharacteristicConfigurationUuid())
229           .at(0);
230   DCHECK(remembered_ccc_descriptor_);
231   RememberDescriptorForSubsequentAction(remembered_ccc_descriptor_);
232 }
233 
SimulateGattNotifySessionStarted(BluetoothRemoteGattCharacteristic * characteristic)234 void BluetoothTestAndroid::SimulateGattNotifySessionStarted(
235     BluetoothRemoteGattCharacteristic* characteristic) {
236   BluetoothRemoteGattDescriptorAndroid* descriptor_android = nullptr;
237   if (characteristic) {
238     descriptor_android = static_cast<BluetoothRemoteGattDescriptorAndroid*>(
239         characteristic
240             ->GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
241                                        ClientCharacteristicConfigurationUuid())
242             .at(0));
243   }
244   Java_FakeBluetoothGattDescriptor_valueWrite(
245       base::android::AttachCurrentThread(),
246       descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
247       0);  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
248 }
249 
SimulateGattNotifySessionStartError(BluetoothRemoteGattCharacteristic * characteristic,BluetoothRemoteGattService::GattErrorCode error_code)250 void BluetoothTestAndroid::SimulateGattNotifySessionStartError(
251     BluetoothRemoteGattCharacteristic* characteristic,
252     BluetoothRemoteGattService::GattErrorCode error_code) {
253   BluetoothRemoteGattDescriptorAndroid* descriptor_android = nullptr;
254   if (characteristic) {
255     descriptor_android = static_cast<BluetoothRemoteGattDescriptorAndroid*>(
256         characteristic
257             ->GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
258                                        ClientCharacteristicConfigurationUuid())
259             .at(0));
260   }
261   Java_FakeBluetoothGattDescriptor_valueWrite(
262       base::android::AttachCurrentThread(),
263       descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
264       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code));
265 }
266 
SimulateGattNotifySessionStopped(BluetoothRemoteGattCharacteristic * characteristic)267 void BluetoothTestAndroid::SimulateGattNotifySessionStopped(
268     BluetoothRemoteGattCharacteristic* characteristic) {
269   BluetoothRemoteGattDescriptorAndroid* descriptor_android = nullptr;
270   if (characteristic) {
271     descriptor_android = static_cast<BluetoothRemoteGattDescriptorAndroid*>(
272         characteristic
273             ->GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
274                                        ClientCharacteristicConfigurationUuid())
275             .at(0));
276   }
277   Java_FakeBluetoothGattDescriptor_valueWrite(
278       base::android::AttachCurrentThread(),
279       descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
280       0);  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
281 }
282 
SimulateGattNotifySessionStopError(BluetoothRemoteGattCharacteristic * characteristic,BluetoothRemoteGattService::GattErrorCode error_code)283 void BluetoothTestAndroid::SimulateGattNotifySessionStopError(
284     BluetoothRemoteGattCharacteristic* characteristic,
285     BluetoothRemoteGattService::GattErrorCode error_code) {
286   BluetoothRemoteGattDescriptorAndroid* descriptor_android = nullptr;
287   if (characteristic) {
288     descriptor_android = static_cast<BluetoothRemoteGattDescriptorAndroid*>(
289         characteristic
290             ->GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
291                                        ClientCharacteristicConfigurationUuid())
292             .at(0));
293   }
294   Java_FakeBluetoothGattDescriptor_valueWrite(
295       base::android::AttachCurrentThread(),
296       descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
297       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code));
298 }
299 
300 void BluetoothTestAndroid::
SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(BluetoothRemoteGattCharacteristic * characteristic)301     SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(
302         BluetoothRemoteGattCharacteristic* characteristic) {
303   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
304       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
305   JNIEnv* env = base::android::AttachCurrentThread();
306 
307   Java_FakeBluetoothGattCharacteristic_setCharacteristicNotificationWillFailSynchronouslyOnce(
308       env, characteristic_android->GetJavaObject());
309 }
310 
SimulateGattCharacteristicChanged(BluetoothRemoteGattCharacteristic * characteristic,const std::vector<uint8_t> & value)311 void BluetoothTestAndroid::SimulateGattCharacteristicChanged(
312     BluetoothRemoteGattCharacteristic* characteristic,
313     const std::vector<uint8_t>& value) {
314   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
315       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
316   JNIEnv* env = base::android::AttachCurrentThread();
317 
318   Java_FakeBluetoothGattCharacteristic_valueChanged(
319       env, characteristic_android ? characteristic_android->GetJavaObject()
320                                   : nullptr,
321       base::android::ToJavaByteArray(env, value));
322 }
323 
SimulateGattCharacteristicRead(BluetoothRemoteGattCharacteristic * characteristic,const std::vector<uint8_t> & value)324 void BluetoothTestAndroid::SimulateGattCharacteristicRead(
325     BluetoothRemoteGattCharacteristic* characteristic,
326     const std::vector<uint8_t>& value) {
327   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
328       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
329   JNIEnv* env = base::android::AttachCurrentThread();
330 
331   Java_FakeBluetoothGattCharacteristic_valueRead(
332       env, characteristic_android ? characteristic_android->GetJavaObject()
333                                   : nullptr,
334       0,  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
335       base::android::ToJavaByteArray(env, value));
336 }
337 
SimulateGattCharacteristicReadError(BluetoothRemoteGattCharacteristic * characteristic,BluetoothRemoteGattService::GattErrorCode error_code)338 void BluetoothTestAndroid::SimulateGattCharacteristicReadError(
339     BluetoothRemoteGattCharacteristic* characteristic,
340     BluetoothRemoteGattService::GattErrorCode error_code) {
341   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
342       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
343   JNIEnv* env = base::android::AttachCurrentThread();
344   std::vector<uint8_t> empty_value;
345 
346   Java_FakeBluetoothGattCharacteristic_valueRead(
347       env, characteristic_android->GetJavaObject(),
348       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code),
349       base::android::ToJavaByteArray(env, empty_value));
350 }
351 
352 void BluetoothTestAndroid::
SimulateGattCharacteristicReadWillFailSynchronouslyOnce(BluetoothRemoteGattCharacteristic * characteristic)353     SimulateGattCharacteristicReadWillFailSynchronouslyOnce(
354         BluetoothRemoteGattCharacteristic* characteristic) {
355   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
356       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
357   JNIEnv* env = base::android::AttachCurrentThread();
358 
359   Java_FakeBluetoothGattCharacteristic_setReadCharacteristicWillFailSynchronouslyOnce(
360       env, characteristic_android->GetJavaObject());
361 }
362 
SimulateGattCharacteristicWrite(BluetoothRemoteGattCharacteristic * characteristic)363 void BluetoothTestAndroid::SimulateGattCharacteristicWrite(
364     BluetoothRemoteGattCharacteristic* characteristic) {
365   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
366       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
367   Java_FakeBluetoothGattCharacteristic_valueWrite(
368       base::android::AttachCurrentThread(),
369       characteristic_android ? characteristic_android->GetJavaObject()
370                              : nullptr,
371       0);  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
372 }
373 
SimulateGattCharacteristicWriteError(BluetoothRemoteGattCharacteristic * characteristic,BluetoothRemoteGattService::GattErrorCode error_code)374 void BluetoothTestAndroid::SimulateGattCharacteristicWriteError(
375     BluetoothRemoteGattCharacteristic* characteristic,
376     BluetoothRemoteGattService::GattErrorCode error_code) {
377   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
378       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
379   Java_FakeBluetoothGattCharacteristic_valueWrite(
380       base::android::AttachCurrentThread(),
381       characteristic_android->GetJavaObject(),
382       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code));
383 }
384 
385 void BluetoothTestAndroid::
SimulateGattCharacteristicWriteWillFailSynchronouslyOnce(BluetoothRemoteGattCharacteristic * characteristic)386     SimulateGattCharacteristicWriteWillFailSynchronouslyOnce(
387         BluetoothRemoteGattCharacteristic* characteristic) {
388   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
389       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
390   Java_FakeBluetoothGattCharacteristic_setWriteCharacteristicWillFailSynchronouslyOnce(
391       base::android::AttachCurrentThread(),
392       characteristic_android->GetJavaObject());
393 }
394 
SimulateGattDescriptor(BluetoothRemoteGattCharacteristic * characteristic,const std::string & uuid)395 void BluetoothTestAndroid::SimulateGattDescriptor(
396     BluetoothRemoteGattCharacteristic* characteristic,
397     const std::string& uuid) {
398   BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
399       static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
400   JNIEnv* env = base::android::AttachCurrentThread();
401 
402   Java_FakeBluetoothGattCharacteristic_addDescriptor(
403       env, characteristic_android->GetJavaObject(),
404       base::android::ConvertUTF8ToJavaString(env, uuid));
405 }
406 
RememberDescriptorForSubsequentAction(BluetoothRemoteGattDescriptor * descriptor)407 void BluetoothTestAndroid::RememberDescriptorForSubsequentAction(
408     BluetoothRemoteGattDescriptor* descriptor) {
409   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
410       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
411 
412   Java_FakeBluetoothGattDescriptor_rememberDescriptorForSubsequentAction(
413       base::android::AttachCurrentThread(),
414       descriptor_android->GetJavaObject());
415 }
416 
SimulateGattDescriptorRead(BluetoothRemoteGattDescriptor * descriptor,const std::vector<uint8_t> & value)417 void BluetoothTestAndroid::SimulateGattDescriptorRead(
418     BluetoothRemoteGattDescriptor* descriptor,
419     const std::vector<uint8_t>& value) {
420   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
421       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
422   JNIEnv* env = base::android::AttachCurrentThread();
423 
424   Java_FakeBluetoothGattDescriptor_valueRead(
425       env, descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
426       0,  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
427       base::android::ToJavaByteArray(env, value));
428 }
429 
SimulateGattDescriptorReadError(BluetoothRemoteGattDescriptor * descriptor,BluetoothRemoteGattService::GattErrorCode error_code)430 void BluetoothTestAndroid::SimulateGattDescriptorReadError(
431     BluetoothRemoteGattDescriptor* descriptor,
432     BluetoothRemoteGattService::GattErrorCode error_code) {
433   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
434       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
435   JNIEnv* env = base::android::AttachCurrentThread();
436   std::vector<uint8_t> empty_value;
437 
438   Java_FakeBluetoothGattDescriptor_valueRead(
439       env, descriptor_android->GetJavaObject(),
440       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code),
441       base::android::ToJavaByteArray(env, empty_value));
442 }
443 
SimulateGattDescriptorReadWillFailSynchronouslyOnce(BluetoothRemoteGattDescriptor * descriptor)444 void BluetoothTestAndroid::SimulateGattDescriptorReadWillFailSynchronouslyOnce(
445     BluetoothRemoteGattDescriptor* descriptor) {
446   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
447       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
448   JNIEnv* env = base::android::AttachCurrentThread();
449 
450   Java_FakeBluetoothGattDescriptor_setReadDescriptorWillFailSynchronouslyOnce(
451       env, descriptor_android->GetJavaObject());
452 }
453 
SimulateGattDescriptorWrite(BluetoothRemoteGattDescriptor * descriptor)454 void BluetoothTestAndroid::SimulateGattDescriptorWrite(
455     BluetoothRemoteGattDescriptor* descriptor) {
456   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
457       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
458   Java_FakeBluetoothGattDescriptor_valueWrite(
459       base::android::AttachCurrentThread(),
460       descriptor_android ? descriptor_android->GetJavaObject() : nullptr,
461       0);  // android.bluetooth.BluetoothGatt.GATT_SUCCESS
462 }
463 
SimulateGattDescriptorWriteError(BluetoothRemoteGattDescriptor * descriptor,BluetoothRemoteGattService::GattErrorCode error_code)464 void BluetoothTestAndroid::SimulateGattDescriptorWriteError(
465     BluetoothRemoteGattDescriptor* descriptor,
466     BluetoothRemoteGattService::GattErrorCode error_code) {
467   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
468       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
469   Java_FakeBluetoothGattDescriptor_valueWrite(
470       base::android::AttachCurrentThread(), descriptor_android->GetJavaObject(),
471       BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(error_code));
472 }
473 
SimulateGattDescriptorWriteWillFailSynchronouslyOnce(BluetoothRemoteGattDescriptor * descriptor)474 void BluetoothTestAndroid::SimulateGattDescriptorWriteWillFailSynchronouslyOnce(
475     BluetoothRemoteGattDescriptor* descriptor) {
476   BluetoothRemoteGattDescriptorAndroid* descriptor_android =
477       static_cast<BluetoothRemoteGattDescriptorAndroid*>(descriptor);
478   Java_FakeBluetoothGattDescriptor_setWriteDescriptorWillFailSynchronouslyOnce(
479       base::android::AttachCurrentThread(),
480       descriptor_android->GetJavaObject());
481 }
482 
OnFakeBluetoothDeviceConnectGattCalled(JNIEnv * env)483 void BluetoothTestAndroid::OnFakeBluetoothDeviceConnectGattCalled(JNIEnv* env) {
484   gatt_open_connections_++;
485   gatt_connection_attempts_++;
486 }
487 
OnFakeBluetoothGattDisconnect(JNIEnv * env)488 void BluetoothTestAndroid::OnFakeBluetoothGattDisconnect(JNIEnv* env) {
489   gatt_disconnection_attempts_++;
490 }
491 
OnFakeBluetoothGattClose(JNIEnv * env)492 void BluetoothTestAndroid::OnFakeBluetoothGattClose(JNIEnv* env) {
493   gatt_open_connections_--;
494 
495   // close implies disconnect
496   gatt_disconnection_attempts_++;
497 }
498 
OnFakeBluetoothGattDiscoverServices(JNIEnv * env)499 void BluetoothTestAndroid::OnFakeBluetoothGattDiscoverServices(JNIEnv* env) {
500   gatt_discovery_attempts_++;
501 }
502 
OnFakeBluetoothGattSetCharacteristicNotification(JNIEnv * env)503 void BluetoothTestAndroid::OnFakeBluetoothGattSetCharacteristicNotification(
504     JNIEnv* env) {
505   gatt_notify_characteristic_attempts_++;
506 }
507 
OnFakeBluetoothGattReadCharacteristic(JNIEnv * env)508 void BluetoothTestAndroid::OnFakeBluetoothGattReadCharacteristic(JNIEnv* env) {
509   gatt_read_characteristic_attempts_++;
510 }
511 
OnFakeBluetoothGattWriteCharacteristic(JNIEnv * env,const JavaParamRef<jbyteArray> & value)512 void BluetoothTestAndroid::OnFakeBluetoothGattWriteCharacteristic(
513     JNIEnv* env,
514     const JavaParamRef<jbyteArray>& value) {
515   gatt_write_characteristic_attempts_++;
516   base::android::JavaByteArrayToByteVector(env, value, &last_write_value_);
517 }
518 
OnFakeBluetoothGattReadDescriptor(JNIEnv * env)519 void BluetoothTestAndroid::OnFakeBluetoothGattReadDescriptor(JNIEnv* env) {
520   gatt_read_descriptor_attempts_++;
521 }
522 
OnFakeBluetoothGattWriteDescriptor(JNIEnv * env,const JavaParamRef<jbyteArray> & value)523 void BluetoothTestAndroid::OnFakeBluetoothGattWriteDescriptor(
524     JNIEnv* env,
525     const JavaParamRef<jbyteArray>& value) {
526   gatt_write_descriptor_attempts_++;
527   base::android::JavaByteArrayToByteVector(env, value, &last_write_value_);
528 }
529 
OnFakeAdapterStateChanged(JNIEnv * env,const bool powered)530 void BluetoothTestAndroid::OnFakeAdapterStateChanged(
531     JNIEnv* env,
532     const bool powered) {
533   // Delegate to the real implementation if the adapter is still alive.
534   if (adapter_) {
535     static_cast<BluetoothAdapterAndroid*>(adapter_.get())
536         ->OnAdapterStateChanged(
537             env, base::android::JavaParamRef<jobject>(nullptr), powered);
538   }
539 }
540 
541 }  // namespace device
542