summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscheib <scheib@chromium.org>2015-10-22 20:23:24 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-23 03:24:16 +0000
commit41bcc6805171e2ab23a84b95f2c7cdfb1e3e473d (patch)
treef4d421bf5d0bc60825ef1d2f221907d63b043cb9
parent36a9ce13a885ab83e7bcc74422b6f6b1a8c1e1e8 (diff)
downloadchromium_src-41bcc6805171e2ab23a84b95f2c7cdfb1e3e473d.zip
chromium_src-41bcc6805171e2ab23a84b95f2c7cdfb1e3e473d.tar.gz
chromium_src-41bcc6805171e2ab23a84b95f2c7cdfb1e3e473d.tar.bz2
bluetooth: android: Implement BluetoothRemoteGattServiceAndroid::GetCharacteristic{s}
Create intial C++ Stub for BluetoothRemoteGattCharacteristicAndroid. Return Characteristic objects from BluetoothRemoteGattServiceAndroid::GetCharacteristics() BluetoothRemoteGattServiceAndroid::GetCharacteristic() BUG=541400, 545682 Review URL: https://codereview.chromium.org/1406323004 Cr-Commit-Position: refs/heads/master@{#355723}
-rw-r--r--device/bluetooth/BUILD.gn2
-rw-r--r--device/bluetooth/android/bluetooth_jni_registrar.cc3
-rw-r--r--device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java2
-rw-r--r--device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java47
-rw-r--r--device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java30
-rw-r--r--device/bluetooth/bluetooth.gyp2
-rw-r--r--device/bluetooth/bluetooth_device_android.h2
-rw-r--r--device/bluetooth/bluetooth_gatt_service_unittest.cc60
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc111
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_characteristic_android.h63
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_service_android.cc49
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_service_android.h35
-rw-r--r--device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java54
-rw-r--r--device/bluetooth/test/bluetooth_test.h3
-rw-r--r--device/bluetooth/test/bluetooth_test_android.cc13
-rw-r--r--device/bluetooth/test/bluetooth_test_android.h2
16 files changed, 460 insertions, 18 deletions
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index a5ea564..f1b7bc9 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -98,6 +98,8 @@ component("bluetooth") {
"bluetooth_low_energy_win.h",
"bluetooth_pairing_chromeos.cc",
"bluetooth_pairing_chromeos.h",
+ "bluetooth_remote_gatt_characteristic_android.cc",
+ "bluetooth_remote_gatt_characteristic_android.h",
"bluetooth_remote_gatt_characteristic_chromeos.cc",
"bluetooth_remote_gatt_characteristic_chromeos.h",
"bluetooth_remote_gatt_descriptor_chromeos.cc",
diff --git a/device/bluetooth/android/bluetooth_jni_registrar.cc b/device/bluetooth/android/bluetooth_jni_registrar.cc
index a72ddf6..82b9894 100644
--- a/device/bluetooth/android/bluetooth_jni_registrar.cc
+++ b/device/bluetooth/android/bluetooth_jni_registrar.cc
@@ -9,6 +9,7 @@
#include "device/bluetooth/android/wrappers.h"
#include "device/bluetooth/bluetooth_adapter_android.h"
#include "device/bluetooth/bluetooth_device_android.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
namespace device {
namespace android {
@@ -17,6 +18,8 @@ namespace {
const base::android::RegistrationMethod kRegisteredMethods[] = {
{"BluetoothAdapterAndroid", device::BluetoothAdapterAndroid::RegisterJNI},
{"BluetoothDeviceAndroid", device::BluetoothDeviceAndroid::RegisterJNI},
+ {"BluetoothRemoteGattServiceAndroid",
+ device::BluetoothRemoteGattServiceAndroid::RegisterJNI},
{"Wrappers", device::WrappersRegisterJNI},
};
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
index c55fb45..82a7273 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
@@ -165,6 +165,8 @@ final class ChromeBluetoothDevice {
mBluetoothGatt.getServices()) {
// Create a device unique service ID. getInstanceId only differs
// between service instances with the same UUID.
+ // TODO(scheib): Make instance IDs unique to the whole adapter.
+ // http://crbug.com/546747
String serviceInstanceId =
service.getUuid().toString() + service.getInstanceId();
nativeCreateGattRemoteService(
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java
index 62c379a..2d9a0e4 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattService.java
@@ -8,6 +8,8 @@ import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
+import java.util.List;
+
/**
* Exposes android.bluetooth.BluetoothGattService as necessary
* for C++ device::BluetoothRemoteGattServiceAndroid.
@@ -19,13 +21,24 @@ import org.chromium.base.annotations.JNINamespace;
final class ChromeBluetoothRemoteGattService {
private static final String TAG = "Bluetooth";
+ private long mNativeBluetoothRemoteGattServiceAndroid;
final Wrappers.BluetoothGattServiceWrapper mService;
- private ChromeBluetoothRemoteGattService(Wrappers.BluetoothGattServiceWrapper serviceWrapper) {
+ private ChromeBluetoothRemoteGattService(long nativeBluetoothRemoteGattServiceAndroid,
+ Wrappers.BluetoothGattServiceWrapper serviceWrapper) {
+ mNativeBluetoothRemoteGattServiceAndroid = nativeBluetoothRemoteGattServiceAndroid;
mService = serviceWrapper;
Log.v(TAG, "ChromeBluetoothRemoteGattService created.");
}
+ /**
+ * Handles C++ object being destroyed.
+ */
+ @CalledByNative
+ private void onBluetoothRemoteGattServiceAndroidDestruction() {
+ mNativeBluetoothRemoteGattServiceAndroid = 0;
+ }
+
// ---------------------------------------------------------------------------------------------
// BluetoothRemoteGattServiceAndroid methods implemented in java:
@@ -33,8 +46,9 @@ final class ChromeBluetoothRemoteGattService {
// 'Object' type must be used because inner class Wrappers.BluetoothGattServiceWrapper reference
// is not handled by jni_generator.py JavaToJni. http://crbug.com/505554
@CalledByNative
- private static ChromeBluetoothRemoteGattService create(Object serviceWrapper) {
- return new ChromeBluetoothRemoteGattService(
+ private static ChromeBluetoothRemoteGattService create(
+ long nativeBluetoothRemoteGattServiceAndroid, Object serviceWrapper) {
+ return new ChromeBluetoothRemoteGattService(nativeBluetoothRemoteGattServiceAndroid,
(Wrappers.BluetoothGattServiceWrapper) serviceWrapper);
}
@@ -43,4 +57,31 @@ final class ChromeBluetoothRemoteGattService {
private String getUUID() {
return mService.getUuid().toString();
}
+
+ // Implements BluetoothRemoteGattServiceAndroid::EnsureCharacteristicsCreated
+ @CalledByNative
+ private void ensureCharacteristicsCreated() {
+ List<Wrappers.BluetoothGattCharacteristicWrapper> characteristics =
+ mService.getCharacteristics();
+ for (Wrappers.BluetoothGattCharacteristicWrapper characteristic : characteristics) {
+ // Create a unique characteristic ID. getInstanceId only differs between characteristic
+ // instances with the same UUID.
+ // TODO(scheib): Make instance IDs unique to the whole adapter. http://crbug.com/546747
+ String characteristicInstanceId =
+ characteristic.getUuid().toString() + characteristic.getInstanceId();
+ nativeCreateGattRemoteCharacteristic(mNativeBluetoothRemoteGattServiceAndroid,
+ characteristicInstanceId, characteristic);
+ }
+ }
+
+ // ---------------------------------------------------------------------------------------------
+ // BluetoothAdapterDevice C++ methods declared for access from java:
+ // Binds to BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic.
+ // 'Object' type must be used for |bluetoothGattCarachteristicWrapper| because inner class
+ // Wrappers.BluetoothGattCharacteristicWrapper reference is not handled by jni_generator.py
+ // JavaToJni.
+ // http://crbug.com/505554
+ private native void nativeCreateGattRemoteCharacteristic(
+ long nativeBluetoothRemoteGattServiceAndroid, String instanceId,
+ Object bluetoothGattCarachteristicWrapper);
}
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
index 9f4d35f..9bfaeda 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
@@ -10,6 +10,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
@@ -331,6 +332,16 @@ class Wrappers {
mService = service;
}
+ public List<BluetoothGattCharacteristicWrapper> getCharacteristics() {
+ List<BluetoothGattCharacteristic> characteristics = mService.getCharacteristics();
+ ArrayList<BluetoothGattCharacteristicWrapper> characteristicsWrapped =
+ new ArrayList<BluetoothGattCharacteristicWrapper>(characteristics.size());
+ for (BluetoothGattCharacteristic characteristic : characteristics) {
+ characteristicsWrapped.add(new BluetoothGattCharacteristicWrapper(characteristic));
+ }
+ return characteristicsWrapped;
+ }
+
public int getInstanceId() {
return mService.getInstanceId();
}
@@ -339,4 +350,23 @@ class Wrappers {
return mService.getUuid();
}
}
+
+ /**
+ * Wraps android.bluetooth.BluetoothGattCharacteristic.
+ */
+ static class BluetoothGattCharacteristicWrapper {
+ private final BluetoothGattCharacteristic mCharacteristic;
+
+ public BluetoothGattCharacteristicWrapper(BluetoothGattCharacteristic characteristic) {
+ mCharacteristic = characteristic;
+ }
+
+ public int getInstanceId() {
+ return mCharacteristic.getInstanceId();
+ }
+
+ public UUID getUuid() {
+ return mCharacteristic.getUuid();
+ }
+ }
}
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index f99d017..e9fa47c 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -101,6 +101,8 @@
'bluetooth_low_energy_win.h',
'bluetooth_pairing_chromeos.cc',
'bluetooth_pairing_chromeos.h',
+ 'bluetooth_remote_gatt_characteristic_android.cc',
+ 'bluetooth_remote_gatt_characteristic_android.h',
'bluetooth_remote_gatt_characteristic_chromeos.cc',
'bluetooth_remote_gatt_characteristic_chromeos.h',
'bluetooth_remote_gatt_descriptor_chromeos.cc',
diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h
index bed6780..2dc96c5 100644
--- a/device/bluetooth/bluetooth_device_android.h
+++ b/device/bluetooth/bluetooth_device_android.h
@@ -12,7 +12,7 @@
namespace device {
-// BluetoothDeviceAndroid along with the Java class
+// BluetoothDeviceAndroid along with its owned Java class
// org.chromium.device.bluetooth.ChromeBluetoothDevice implement
// BluetoothDevice.
class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceAndroid final
diff --git a/device/bluetooth/bluetooth_gatt_service_unittest.cc b/device/bluetooth/bluetooth_gatt_service_unittest.cc
index c6b8733..595905d 100644
--- a/device/bluetooth/bluetooth_gatt_service_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_service_unittest.cc
@@ -4,6 +4,7 @@
#include "device/bluetooth/bluetooth_gatt_service.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_ANDROID)
@@ -21,9 +22,7 @@ TEST_F(BluetoothTest, GetUUIDAndGetIdentifier) {
BluetoothDevice* device = DiscoverLowEnergyDevice(3);
device->CreateGattConnection(GetGattConnectionCallback(),
GetConnectErrorCallback());
- ResetEventCounts();
SimulateGattConnection(device);
- EXPECT_EQ(1, gatt_discovery_attempts_);
// Create multiple instances with the same UUID.
BluetoothUUID uuid("00000000-0000-1000-8000-00805f9b34fb");
@@ -42,4 +41,61 @@ TEST_F(BluetoothTest, GetUUIDAndGetIdentifier) {
}
#endif // defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+TEST_F(BluetoothTest, GetCharacteristics_FindNone) {
+ InitWithFakeAdapter();
+ StartLowEnergyDiscoverySession();
+ BluetoothDevice* device = DiscoverLowEnergyDevice(3);
+ device->CreateGattConnection(GetGattConnectionCallback(),
+ GetConnectErrorCallback());
+ SimulateGattConnection(device);
+
+ // Simulate a service, with no Characteristics:
+ std::vector<std::string> services;
+ services.push_back("00000000-0000-1000-8000-00805f9b34fb");
+ SimulateGattServicesDiscovered(device, services);
+ BluetoothGattService* service = device->GetGattServices()[0];
+
+ EXPECT_EQ(0u, service->GetCharacteristics().size());
+}
+#endif // defined(OS_ANDROID)
+
+#if defined(OS_ANDROID)
+TEST_F(BluetoothTest, GetCharacteristic_FindSeveral) {
+ InitWithFakeAdapter();
+ StartLowEnergyDiscoverySession();
+ BluetoothDevice* device = DiscoverLowEnergyDevice(3);
+ device->CreateGattConnection(GetGattConnectionCallback(),
+ GetConnectErrorCallback());
+ SimulateGattConnection(device);
+
+ // Simulate a service, with no Characteristics:
+ std::vector<std::string> services;
+ services.push_back("00000000-0000-1000-8000-00805f9b34fb");
+ SimulateGattServicesDiscovered(device, services);
+ BluetoothGattService* service = device->GetGattServices()[0];
+
+ std::string characteristic_uuid1 = "00000001-0000-1000-8000-00805f9b34fb";
+ std::string characteristic_uuid2 = "00000002-0000-1000-8000-00805f9b34fb";
+ std::string characteristic_uuid3 = characteristic_uuid2; // Duplicate UUID.
+ SimulateGattCharacteristic(service, characteristic_uuid1);
+ SimulateGattCharacteristic(service, characteristic_uuid2);
+ SimulateGattCharacteristic(service, characteristic_uuid3);
+
+ EXPECT_EQ(3u, service->GetCharacteristics().size());
+ // TODO(scheib): Implement GetIdentifier. crbug.com/545682
+ // std::string characteristic_id1 =
+ // service->GetCharacteristics()[0]->GetIdentifier();
+ // ...
+ // EXPECT_NE(characteristic_id2, characteristic_id3);
+ // For now, just hard-code:
+ std::string characteristic_id1 = "00000001-0000-1000-8000-00805f9b34fb0";
+ std::string characteristic_id2 = "00000002-0000-1000-8000-00805f9b34fb0";
+ std::string characteristic_id3 = "00000002-0000-1000-8000-00805f9b34fb1";
+ EXPECT_TRUE(service->GetCharacteristic(characteristic_id1));
+ EXPECT_TRUE(service->GetCharacteristic(characteristic_id2));
+ EXPECT_TRUE(service->GetCharacteristic(characteristic_id3));
+}
+#endif // defined(OS_ANDROID)
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
new file mode 100644
index 0000000..1c2a99a
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
@@ -0,0 +1,111 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h"
+
+#include "base/logging.h"
+
+namespace device {
+
+// static
+scoped_ptr<BluetoothRemoteGattCharacteristicAndroid>
+BluetoothRemoteGattCharacteristicAndroid::Create() {
+ return make_scoped_ptr<BluetoothRemoteGattCharacteristicAndroid>(
+ new BluetoothRemoteGattCharacteristicAndroid());
+}
+
+BluetoothRemoteGattCharacteristicAndroid::
+ ~BluetoothRemoteGattCharacteristicAndroid() {}
+
+std::string BluetoothRemoteGattCharacteristicAndroid::GetIdentifier() const {
+ NOTIMPLEMENTED();
+ return "";
+}
+
+BluetoothUUID BluetoothRemoteGattCharacteristicAndroid::GetUUID() const {
+ NOTIMPLEMENTED();
+ return BluetoothUUID();
+}
+
+bool BluetoothRemoteGattCharacteristicAndroid::IsLocal() const {
+ return false;
+}
+
+const std::vector<uint8>& BluetoothRemoteGattCharacteristicAndroid::GetValue()
+ const {
+ NOTIMPLEMENTED();
+ return value_;
+}
+
+BluetoothGattService* BluetoothRemoteGattCharacteristicAndroid::GetService()
+ const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+BluetoothGattCharacteristic::Properties
+BluetoothRemoteGattCharacteristicAndroid::GetProperties() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+BluetoothGattCharacteristic::Permissions
+BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+std::vector<BluetoothGattDescriptor*>
+BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const {
+ NOTIMPLEMENTED();
+ return std::vector<BluetoothGattDescriptor*>();
+}
+
+BluetoothGattDescriptor*
+BluetoothRemoteGattCharacteristicAndroid::GetDescriptor(
+ const std::string& identifier) const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+bool BluetoothRemoteGattCharacteristicAndroid::AddDescriptor(
+ BluetoothGattDescriptor* descriptor) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue(
+ const std::vector<uint8>& value) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession(
+ const NotifySessionCallback& callback,
+ const ErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+}
+
+void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
+ const ValueCallback& callback,
+ const ErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+}
+
+void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic(
+ const std::vector<uint8>& new_value,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+}
+
+BluetoothRemoteGattCharacteristicAndroid::
+ BluetoothRemoteGattCharacteristicAndroid() {}
+
+} // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
new file mode 100644
index 0000000..58e139d
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
@@ -0,0 +1,63 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_ANDROID_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_ANDROID_H_
+
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_gatt_characteristic.h"
+
+namespace device {
+
+// BluetoothRemoteGattCharacteristicAndroid along with its owned Java class
+// org.chromium.device.bluetooth.ChromeBluetoothRemoteGattCharacteristic
+// implement BluetootGattCharacteristic.
+class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid
+ : public BluetoothGattCharacteristic {
+ public:
+ // Create a BluetoothRemoteGattServiceAndroid instance and associated Java
+ // ChromeBluetoothRemoteGattService using the provided
+ // |bluetooth_remote_gatt_service_wrapper|.
+ //
+ // The ChromeBluetoothRemoteGattService instance will hold a Java reference
+ // to |bluetooth_remote_gatt_service_wrapper|.
+ //
+ // TODO(scheib): Actually create the Java object. crbug.com/545682
+ static scoped_ptr<BluetoothRemoteGattCharacteristicAndroid> Create();
+
+ ~BluetoothRemoteGattCharacteristicAndroid() override;
+
+ // BluetoothGattCharacteristic interface:
+ std::string GetIdentifier() const override;
+ BluetoothUUID GetUUID() const override;
+ bool IsLocal() const override;
+ const std::vector<uint8>& GetValue() const override;
+ BluetoothGattService* GetService() const override;
+ Properties GetProperties() const override;
+ Permissions GetPermissions() const override;
+ bool IsNotifying() const override;
+ std::vector<BluetoothGattDescriptor*> GetDescriptors() const override;
+ BluetoothGattDescriptor* GetDescriptor(
+ const std::string& identifier) const override;
+ bool AddDescriptor(BluetoothGattDescriptor* descriptor) override;
+ bool UpdateValue(const std::vector<uint8>& value) override;
+ void StartNotifySession(const NotifySessionCallback& callback,
+ const ErrorCallback& error_callback) override;
+ void ReadRemoteCharacteristic(const ValueCallback& callback,
+ const ErrorCallback& error_callback) override;
+ void WriteRemoteCharacteristic(const std::vector<uint8>& new_value,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+
+ private:
+ BluetoothRemoteGattCharacteristicAndroid();
+
+ std::vector<uint8> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicAndroid);
+};
+
+} // namespace device
+
+#endif // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_ANDROID_H_
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_android.cc b/device/bluetooth/bluetooth_remote_gatt_service_android.cc
index c9caa3a..b5bc1a5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_android.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_android.cc
@@ -8,6 +8,7 @@
#include "base/android/jni_string.h"
#include "device/bluetooth/bluetooth_adapter_android.h"
#include "device/bluetooth/bluetooth_device_android.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h"
#include "jni/ChromeBluetoothRemoteGattService_jni.h"
using base::android::AttachCurrentThread;
@@ -24,7 +25,8 @@ BluetoothRemoteGattServiceAndroid* BluetoothRemoteGattServiceAndroid::Create(
new BluetoothRemoteGattServiceAndroid(adapter, device, instanceId);
service->j_service_.Reset(Java_ChromeBluetoothRemoteGattService_create(
- AttachCurrentThread(), bluetooth_remote_gatt_service_wrapper));
+ AttachCurrentThread(), reinterpret_cast<intptr_t>(service),
+ bluetooth_remote_gatt_service_wrapper));
return service;
}
@@ -35,6 +37,11 @@ bool BluetoothRemoteGattServiceAndroid::RegisterJNI(JNIEnv* env) {
env); // Generated in ChromeBluetoothRemoteGattService_jni.h
}
+base::android::ScopedJavaLocalRef<jobject>
+BluetoothRemoteGattServiceAndroid::GetJavaObject() {
+ return base::android::ScopedJavaLocalRef<jobject>(j_service_);
+}
+
std::string BluetoothRemoteGattServiceAndroid::GetIdentifier() const {
return instanceId_;
}
@@ -60,8 +67,10 @@ device::BluetoothDevice* BluetoothRemoteGattServiceAndroid::GetDevice() const {
std::vector<device::BluetoothGattCharacteristic*>
BluetoothRemoteGattServiceAndroid::GetCharacteristics() const {
- NOTIMPLEMENTED();
+ EnsureCharacteristicsCreated();
std::vector<device::BluetoothGattCharacteristic*> characteristics;
+ for (const auto& map_iter : characteristics_)
+ characteristics.push_back(map_iter.second);
return characteristics;
}
@@ -74,8 +83,11 @@ BluetoothRemoteGattServiceAndroid::GetIncludedServices() const {
device::BluetoothGattCharacteristic*
BluetoothRemoteGattServiceAndroid::GetCharacteristic(
const std::string& identifier) const {
- NOTIMPLEMENTED();
- return nullptr;
+ EnsureCharacteristicsCreated();
+ const auto& iter = characteristics_.find(identifier);
+ if (iter == characteristics_.end())
+ return nullptr;
+ return iter->second;
}
bool BluetoothRemoteGattServiceAndroid::AddCharacteristic(
@@ -100,12 +112,39 @@ void BluetoothRemoteGattServiceAndroid::Unregister(
error_callback.Run();
}
+void BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic(
+ JNIEnv* env,
+ jobject caller,
+ const jstring& instanceId,
+ jobject /* BluetoothGattCharacteristicWrapper */
+ bluetooth_gatt_characteristic_wrapper) {
+ std::string instanceIdString =
+ base::android::ConvertJavaStringToUTF8(env, instanceId);
+
+ DCHECK(!characteristics_.contains(instanceIdString));
+
+ characteristics_.set(instanceIdString,
+ BluetoothRemoteGattCharacteristicAndroid::Create());
+}
+
BluetoothRemoteGattServiceAndroid::BluetoothRemoteGattServiceAndroid(
BluetoothAdapterAndroid* adapter,
BluetoothDeviceAndroid* device,
std::string instanceId)
: adapter_(adapter), device_(device), instanceId_(instanceId) {}
-BluetoothRemoteGattServiceAndroid::~BluetoothRemoteGattServiceAndroid() {}
+BluetoothRemoteGattServiceAndroid::~BluetoothRemoteGattServiceAndroid() {
+ Java_ChromeBluetoothRemoteGattService_onBluetoothRemoteGattServiceAndroidDestruction(
+ AttachCurrentThread(), j_service_.obj());
+}
+
+void BluetoothRemoteGattServiceAndroid::EnsureCharacteristicsCreated() const {
+ if (!characteristics_.empty())
+ return;
+
+ // Java call
+ Java_ChromeBluetoothRemoteGattService_ensureCharacteristicsCreated(
+ AttachCurrentThread(), j_service_.obj());
+}
} // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_android.h b/device/bluetooth/bluetooth_remote_gatt_service_android.h
index 5bc9e3d..b1d19e0 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_android.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_android.h
@@ -10,20 +10,21 @@
#include <vector>
#include "base/android/jni_android.h"
+#include "base/containers/scoped_ptr_hash_map.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluetooth_uuid.h"
namespace device {
-class BluetoothAdapter;
-class BluetoothGattCharacteristic;
-
class BluetoothAdapterAndroid;
class BluetoothDeviceAndroid;
+class BluetoothRemoteGattCharacteristicAndroid;
-// The BluetoothRemoteGattServiceAndroid class implements BluetootGattService
-// for remote GATT services on Android.
-class BluetoothRemoteGattServiceAndroid : public device::BluetoothGattService {
+// BluetoothRemoteGattServiceAndroid along with its owned Java class
+// org.chromium.device.bluetooth.ChromeBluetoothRemoteGattService implement
+// BluetoothGattService.
+class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattServiceAndroid
+ : public device::BluetoothGattService {
public:
// Create a BluetoothRemoteGattServiceAndroid instance and associated Java
// ChromeBluetoothRemoteGattService using the provided
@@ -44,6 +45,9 @@ class BluetoothRemoteGattServiceAndroid : public device::BluetoothGattService {
// Register C++ methods exposed to Java using JNI.
static bool RegisterJNI(JNIEnv* env);
+ // Returns the associated ChromeBluetoothRemoteGattService Java object.
+ base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
// device::BluetoothGattService overrides.
std::string GetIdentifier() const override;
device::BluetoothUUID GetUUID() const override;
@@ -64,6 +68,15 @@ class BluetoothRemoteGattServiceAndroid : public device::BluetoothGattService {
void Unregister(const base::Closure& callback,
const ErrorCallback& error_callback) override;
+ // Creates a Bluetooth GATT characteristic object and adds it to
+ // |characteristics_| if it is not already there.
+ void CreateGattRemoteCharacteristic(
+ JNIEnv* env,
+ jobject caller,
+ const jstring& instanceId,
+ jobject /* BluetoothGattCharacteristicWrapper */
+ bluetooth_gatt_characteristic_wrapper);
+
private:
friend class BluetoothDeviceAndroid;
@@ -72,6 +85,9 @@ class BluetoothRemoteGattServiceAndroid : public device::BluetoothGattService {
std::string instanceId);
~BluetoothRemoteGattServiceAndroid() override;
+ // Populates |characteristics_| from Java objects if necessary.
+ void EnsureCharacteristicsCreated() const;
+
// Java object org.chromium.device.bluetooth.ChromeBluetoothRemoteGattService.
base::android::ScopedJavaGlobalRef<jobject> j_service_;
@@ -86,9 +102,14 @@ class BluetoothRemoteGattServiceAndroid : public device::BluetoothGattService {
// Instance ID, cached from Android object.
std::string instanceId_;
+ // Map of characteristics, keyed by characteristic identifier.
+ base::ScopedPtrHashMap<std::string,
+ scoped_ptr<BluetoothRemoteGattCharacteristicAndroid>>
+ characteristics_;
+
DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceAndroid);
};
-} // namespace android
+} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_ANDROID_H_
diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
index 2499c7b..7bf77c8 100644
--- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
+++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
@@ -305,11 +305,65 @@ class Fakes {
static class FakeBluetoothGattService extends Wrappers.BluetoothGattServiceWrapper {
final int mInstanceId;
final UUID mUuid;
+ final ArrayList<Wrappers.BluetoothGattCharacteristicWrapper> mCharacteristics;
public FakeBluetoothGattService(UUID uuid, int instanceId) {
super(null);
mUuid = uuid;
mInstanceId = instanceId;
+ mCharacteristics = new ArrayList<Wrappers.BluetoothGattCharacteristicWrapper>();
+ }
+
+ // Create a characteristic and add it to this service.
+ @CalledByNative("FakeBluetoothGattService")
+ private static void addCharacteristic(
+ ChromeBluetoothRemoteGattService chromeService, String uuidString) {
+ FakeBluetoothGattService fakeService =
+ (FakeBluetoothGattService) chromeService.mService;
+ UUID uuid = UUID.fromString(uuidString);
+
+ int countOfDuplicateUUID = 0;
+ for (Wrappers.BluetoothGattCharacteristicWrapper characteristic :
+ fakeService.mCharacteristics) {
+ if (characteristic.getUuid().equals(uuid)) {
+ countOfDuplicateUUID++;
+ }
+ }
+ fakeService.mCharacteristics.add(new FakeBluetoothGattCharacteristic(
+ uuid, /* instanceId */ countOfDuplicateUUID));
+ }
+
+ // -----------------------------------------------------------------------------------------
+ // Wrappers.BluetoothGattServiceWrapper overrides:
+
+ @Override
+ public List<Wrappers.BluetoothGattCharacteristicWrapper> getCharacteristics() {
+ return mCharacteristics;
+ }
+
+ @Override
+ public int getInstanceId() {
+ return mInstanceId;
+ }
+
+ @Override
+ public UUID getUuid() {
+ return mUuid;
+ }
+ }
+
+ /**
+ * Fakes android.bluetooth.BluetoothGattCharacteristic.
+ */
+ static class FakeBluetoothGattCharacteristic
+ extends Wrappers.BluetoothGattCharacteristicWrapper {
+ final UUID mUuid;
+ final int mInstanceId;
+
+ public FakeBluetoothGattCharacteristic(UUID uuid, int instanceId) {
+ super(null);
+ mUuid = uuid;
+ mInstanceId = instanceId;
}
@Override
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h
index 6271313..fa946a3 100644
--- a/device/bluetooth/test/bluetooth_test.h
+++ b/device/bluetooth/test/bluetooth_test.h
@@ -94,6 +94,9 @@ class BluetoothTestBase : public testing::Test {
// Simulates failure to discover services.
virtual void SimulateGattServicesDiscoveryError(BluetoothDevice* device) {}
+ virtual void SimulateGattCharacteristic(BluetoothGattService* service,
+ const std::string& uuid){};
+
// Remove the device from the adapter and delete it.
virtual void DeleteDevice(BluetoothDevice* device);
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc
index 48c2ab2..7761f56 100644
--- a/device/bluetooth/test/bluetooth_test_android.cc
+++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -12,6 +12,7 @@
#include "device/bluetooth/android/wrappers.h"
#include "device/bluetooth/bluetooth_adapter_android.h"
#include "device/bluetooth/bluetooth_device_android.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "jni/Fakes_jni.h"
@@ -140,6 +141,18 @@ void BluetoothTestAndroid::SimulateGattServicesDiscoveryError(
nullptr);
}
+void BluetoothTestAndroid::SimulateGattCharacteristic(
+ BluetoothGattService* service,
+ const std::string& uuid) {
+ BluetoothRemoteGattServiceAndroid* service_android =
+ static_cast<BluetoothRemoteGattServiceAndroid*>(service);
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ Java_FakeBluetoothGattService_addCharacteristic(
+ env, service_android->GetJavaObject().obj(),
+ base::android::ConvertUTF8ToJavaString(env, uuid).obj());
+}
+
void BluetoothTestAndroid::OnFakeBluetoothDeviceConnectGattCalled(
JNIEnv* env,
jobject caller) {
diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h
index 306d81a..beb5e2b 100644
--- a/device/bluetooth/test/bluetooth_test_android.h
+++ b/device/bluetooth/test/bluetooth_test_android.h
@@ -35,6 +35,8 @@ class BluetoothTestAndroid : public BluetoothTestBase {
BluetoothDevice* device,
const std::vector<std::string>& uuids) override;
void SimulateGattServicesDiscoveryError(BluetoothDevice* device) override;
+ void SimulateGattCharacteristic(BluetoothGattService* service,
+ const std::string& uuid) override;
// Records that Java FakeBluetoothDevice connectGatt was called.
void OnFakeBluetoothDeviceConnectGattCalled(JNIEnv* env, jobject caller);