blob: a8e3957d4552f33013f5b6348cad89da16917062 [file] [log] [blame]
// 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 <memory>
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/stl_util.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;
using base::android::JavaParamRef;
using base::android::JavaRef;
namespace device {
// static
std::unique_ptr<BluetoothRemoteGattServiceAndroid>
BluetoothRemoteGattServiceAndroid::Create(
BluetoothAdapterAndroid* adapter,
BluetoothDeviceAndroid* device,
const JavaRef<jobject>&
bluetooth_gatt_service_wrapper, // BluetoothGattServiceWrapper
const std::string& instance_id,
const JavaRef<jobject>& chrome_bluetooth_device) { // ChromeBluetoothDevice
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_);
}
// static
BluetoothRemoteGattService::GattErrorCode
BluetoothRemoteGattServiceAndroid::GetGattErrorCode(int bluetooth_gatt_code) {
DCHECK(bluetooth_gatt_code != 0) << "Only errors valid. 0 == GATT_SUCCESS.";
// TODO(scheib) Create new BluetoothRemoteGattService::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:
VLOG(1) << "Unhandled status: " << bluetooth_gatt_code;
return BluetoothRemoteGattService::GATT_ERROR_UNKNOWN;
}
}
// static
int BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(
BluetoothRemoteGattService::GattErrorCode error_code) {
// TODO(scheib) Create new BluetoothRemoteGattService::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
}
VLOG(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<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 {
// 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<jobject>& caller,
const JavaParamRef<jstring>& instance_id,
const JavaParamRef<jobject>& /* BluetoothGattCharacteristicWrapper */
bluetooth_gatt_characteristic_wrapper,
const JavaParamRef<
jobject>& /* ChromeBluetoothDevice */ chrome_bluetooth_device) {
std::string instance_id_string =
base::android::ConvertJavaStringToUTF8(env, instance_id);
DCHECK(!base::ContainsKey(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