// Copyright 2014 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_service_android.h" #include #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 { // static std::unique_ptr BluetoothRemoteGattServiceAndroid::Create( BluetoothAdapterAndroid* adapter, BluetoothDeviceAndroid* device, const JavaRef& bluetooth_gatt_service_wrapper, // BluetoothGattServiceWrapper const std::string& instance_id, const JavaRef& chrome_bluetooth_device) { // ChromeBluetoothDevice std::unique_ptr service( new BluetoothRemoteGattServiceAndroid(adapter, device, instance_id)); JNIEnv* env = AttachCurrentThread(); service->j_service_.Reset(Java_ChromeBluetoothRemoteGattService_create( env, reinterpret_cast(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 BluetoothRemoteGattServiceAndroid::GetJavaObject() { return base::android::ScopedJavaLocalRef(j_service_); } // static BluetoothGattService::GattErrorCode BluetoothRemoteGattServiceAndroid::GetGattErrorCode(int bluetooth_gatt_code) { DCHECK(bluetooth_gatt_code != 0) << "Only errors valid. 0 == GATT_SUCCESS."; // TODO(scheib) Create new BluetoothGattService::GattErrorCode enums for // android values not yet represented. http://crbug.com/548498 switch (bluetooth_gatt_code) { // android.bluetooth.BluetoothGatt values: case 0x00000101: // GATT_FAILURE return GATT_ERROR_FAILED; case 0x0000000d: // GATT_INVALID_ATTRIBUTE_LENGTH return GATT_ERROR_INVALID_LENGTH; case 0x00000002: // GATT_READ_NOT_PERMITTED return GATT_ERROR_NOT_PERMITTED; case 0x00000006: // GATT_REQUEST_NOT_SUPPORTED return GATT_ERROR_NOT_SUPPORTED; case 0x00000003: // GATT_WRITE_NOT_PERMITTED return GATT_ERROR_NOT_PERMITTED; default: DVLOG(1) << "Unhandled status: " << bluetooth_gatt_code; return BluetoothGattService::GATT_ERROR_UNKNOWN; } } // static int BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode( BluetoothGattService::GattErrorCode error_code) { // TODO(scheib) Create new BluetoothGattService::GattErrorCode enums for // android values not yet represented. http://crbug.com/548498 switch (error_code) { // Return values from android.bluetooth.BluetoothGatt: case GATT_ERROR_UNKNOWN: return 0x00000101; // GATT_FAILURE. No good match. case GATT_ERROR_FAILED: return 0x00000101; // GATT_FAILURE case GATT_ERROR_IN_PROGRESS: return 0x00000101; // GATT_FAILURE. No good match. case GATT_ERROR_INVALID_LENGTH: return 0x0000000d; // GATT_INVALID_ATTRIBUTE_LENGTH case GATT_ERROR_NOT_PERMITTED: // Can't distinguish between: // 0x00000002: // GATT_READ_NOT_PERMITTED // 0x00000003: // GATT_WRITE_NOT_PERMITTED return 0x00000101; // GATT_FAILURE. No good match. case GATT_ERROR_NOT_AUTHORIZED: return 0x00000101; // GATT_FAILURE. No good match. case GATT_ERROR_NOT_PAIRED: return 0x00000101; // GATT_FAILURE. No good match. case GATT_ERROR_NOT_SUPPORTED: return 0x00000006; // GATT_REQUEST_NOT_SUPPORTED } DVLOG(1) << "Unhandled error_code: " << error_code; return 0x00000101; // GATT_FAILURE. No good match. } 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 BluetoothRemoteGattServiceAndroid::GetCharacteristics() const { EnsureCharacteristicsCreated(); return BluetoothRemoteGattService::GetCharacteristics(); } std::vector BluetoothRemoteGattServiceAndroid::GetIncludedServices() const { NOTIMPLEMENTED(); return std::vector(); } device::BluetoothRemoteGattCharacteristic* BluetoothRemoteGattServiceAndroid::GetCharacteristic( const std::string& identifier) const { EnsureCharacteristicsCreated(); return BluetoothRemoteGattService::GetCharacteristic(identifier); } std::vector BluetoothRemoteGattServiceAndroid::GetCharacteristicsByUUID( const BluetoothUUID& characteristic_uuid) const { EnsureCharacteristicsCreated(); return BluetoothRemoteGattService::GetCharacteristicsByUUID( characteristic_uuid); } bool BluetoothRemoteGattServiceAndroid::IsDiscoveryComplete() const { // Not used on Android, because Android sends an event when service discovery // is complete for the entire device. NOTIMPLEMENTED(); return true; } void BluetoothRemoteGattServiceAndroid::SetDiscoveryComplete(bool complete) { // Not used on Android, because Android sends an event when service discovery // is complete for the entire device. NOTIMPLEMENTED(); } void BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic( JNIEnv* env, const JavaParamRef& caller, const JavaParamRef& instance_id, const JavaParamRef& /* BluetoothGattCharacteristicWrapper */ bluetooth_gatt_characteristic_wrapper, const JavaParamRef& /* ChromeBluetoothDevice */ 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 call Java_ChromeBluetoothRemoteGattService_createCharacteristics( AttachCurrentThread(), j_service_); } } // namespace device