#include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
#include <memory>
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/containers/contains.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 "device/bluetooth/jni_headers/ChromeBluetoothRemoteGattService_jni.h"
using base::android::AttachCurrentThread;
using base::android::JavaParamRef;
using base::android::JavaRef;
namespace device {
std::unique_ptr<BluetoothRemoteGattServiceAndroid>
BluetoothRemoteGattServiceAndroid::Create(
BluetoothAdapterAndroid* adapter,
BluetoothDeviceAndroid* device,
const JavaRef<jobject>&
bluetooth_gatt_service_wrapper,
const std::string& instance_id,
const JavaRef<jobject>& chrome_bluetooth_device) {
std::unique_ptr<BluetoothRemoteGattServiceAndroid> service(
new BluetoothRemoteGattServiceAndroid(adapter, device, instance_id));
JNIEnv* env = AttachCurrentThread();
service->j_service_.Reset(Java_ChromeBluetoothRemoteGattService_create(
env, reinterpret_cast<intptr_t>(service.get()),
bluetooth_gatt_service_wrapper,
base::android::ConvertUTF8ToJavaString(env, instance_id),
chrome_bluetooth_device));
return service;
}
BluetoothRemoteGattServiceAndroid::~BluetoothRemoteGattServiceAndroid() {
Java_ChromeBluetoothRemoteGattService_onBluetoothRemoteGattServiceAndroidDestruction(
AttachCurrentThread(), j_service_);
}
base::android::ScopedJavaLocalRef<jobject>
BluetoothRemoteGattServiceAndroid::GetJavaObject() {
return base::android::ScopedJavaLocalRef<jobject>(j_service_);
}
BluetoothGattService::GattErrorCode
BluetoothRemoteGattServiceAndroid::GetGattErrorCode(int bluetooth_gatt_code) {
DCHECK(bluetooth_gatt_code != 0) << "Only errors valid. 0 == GATT_SUCCESS.";
switch (bluetooth_gatt_code) {
case 0x00000101:
return GattErrorCode::kFailed;
case 0x0000000d:
return GattErrorCode::kInvalidLength;
case 0x00000002:
return GattErrorCode::kNotPermitted;
case 0x00000006:
return GattErrorCode::kNotSupported;
case 0x00000003:
return GattErrorCode::kNotPermitted;
default:
DVLOG(1) << "Unhandled status: " << bluetooth_gatt_code;
return BluetoothGattService::GattErrorCode::kUnknown;
}
}
int BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(
BluetoothGattService::GattErrorCode error_code) {
switch (error_code) {
case GattErrorCode::kUnknown:
return 0x00000101;
case GattErrorCode::kFailed:
return 0x00000101;
case GattErrorCode::kInProgress:
return 0x00000101;
case GattErrorCode::kInvalidLength:
return 0x0000000d;
case GattErrorCode::kNotPermitted:
return 0x00000101;
case GattErrorCode::kNotAuthorized:
return 0x00000101;
case GattErrorCode::kNotPaired:
return 0x00000101;
case GattErrorCode::kNotSupported:
return 0x00000006;
}
DVLOG(1) << "Unhandled error_code: " << static_cast<int>(error_code);
return 0x00000101;
}
std::string BluetoothRemoteGattServiceAndroid::GetIdentifier() const {
return instance_id_;
}
device::BluetoothUUID BluetoothRemoteGattServiceAndroid::GetUUID() const {
return device::BluetoothUUID(
ConvertJavaStringToUTF8(Java_ChromeBluetoothRemoteGattService_getUUID(
AttachCurrentThread(), j_service_)));
}
bool BluetoothRemoteGattServiceAndroid::IsPrimary() const {
NOTIMPLEMENTED();
return true;
}
device::BluetoothDevice* BluetoothRemoteGattServiceAndroid::GetDevice() const {
return device_;
}
std::vector<device::BluetoothRemoteGattCharacteristic*>
BluetoothRemoteGattServiceAndroid::GetCharacteristics() const {
EnsureCharacteristicsCreated();
return BluetoothRemoteGattService::GetCharacteristics();
}
std::vector<device::BluetoothRemoteGattService*>
BluetoothRemoteGattServiceAndroid::GetIncludedServices() const {
NOTIMPLEMENTED();
return std::vector<device::BluetoothRemoteGattService*>();
}
device::BluetoothRemoteGattCharacteristic*
BluetoothRemoteGattServiceAndroid::GetCharacteristic(
const std::string& identifier) const {
EnsureCharacteristicsCreated();
return BluetoothRemoteGattService::GetCharacteristic(identifier);
}
std::vector<BluetoothRemoteGattCharacteristic*>
BluetoothRemoteGattServiceAndroid::GetCharacteristicsByUUID(
const BluetoothUUID& characteristic_uuid) const {
EnsureCharacteristicsCreated();
return BluetoothRemoteGattService::GetCharacteristicsByUUID(
characteristic_uuid);
}
bool BluetoothRemoteGattServiceAndroid::IsDiscoveryComplete() const {
NOTIMPLEMENTED();
return true;
}
void BluetoothRemoteGattServiceAndroid::SetDiscoveryComplete(bool complete) {
NOTIMPLEMENTED();
}
void BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic(
JNIEnv* env,
const JavaParamRef<jobject>& caller,
const JavaParamRef<jstring>& instance_id,
const JavaParamRef<jobject>&
bluetooth_gatt_characteristic_wrapper,
const JavaParamRef<jobject>&
chrome_bluetooth_device) {
std::string instance_id_string =
base::android::ConvertJavaStringToUTF8(env, instance_id);
DCHECK(!base::Contains(characteristics_, instance_id_string));
AddCharacteristic(BluetoothRemoteGattCharacteristicAndroid::Create(
adapter_, this, instance_id_string, bluetooth_gatt_characteristic_wrapper,
chrome_bluetooth_device));
}
BluetoothRemoteGattServiceAndroid::BluetoothRemoteGattServiceAndroid(
BluetoothAdapterAndroid* adapter,
BluetoothDeviceAndroid* device,
const std::string& instance_id)
: adapter_(adapter), device_(device), instance_id_(instance_id) {}
void BluetoothRemoteGattServiceAndroid::EnsureCharacteristicsCreated() const {
if (!characteristics_.empty())
return;
Java_ChromeBluetoothRemoteGattService_createCharacteristics(
AttachCurrentThread(), j_service_);
}
}