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