1 // Copyright 2014 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/bluetooth_remote_gatt_service_android.h"
6
7 #include <memory>
8
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/stl_util.h"
12 #include "device/bluetooth/bluetooth_adapter_android.h"
13 #include "device/bluetooth/bluetooth_device_android.h"
14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h"
15 #include "device/bluetooth/jni_headers/ChromeBluetoothRemoteGattService_jni.h"
16
17 using base::android::AttachCurrentThread;
18 using base::android::JavaParamRef;
19 using base::android::JavaRef;
20
21 namespace device {
22
23 // static
24 std::unique_ptr<BluetoothRemoteGattServiceAndroid>
Create(BluetoothAdapterAndroid * adapter,BluetoothDeviceAndroid * device,const JavaRef<jobject> & bluetooth_gatt_service_wrapper,const std::string & instance_id,const JavaRef<jobject> & chrome_bluetooth_device)25 BluetoothRemoteGattServiceAndroid::Create(
26 BluetoothAdapterAndroid* adapter,
27 BluetoothDeviceAndroid* device,
28 const JavaRef<jobject>&
29 bluetooth_gatt_service_wrapper, // BluetoothGattServiceWrapper
30 const std::string& instance_id,
31 const JavaRef<jobject>& chrome_bluetooth_device) { // ChromeBluetoothDevice
32 std::unique_ptr<BluetoothRemoteGattServiceAndroid> service(
33 new BluetoothRemoteGattServiceAndroid(adapter, device, instance_id));
34
35 JNIEnv* env = AttachCurrentThread();
36 service->j_service_.Reset(Java_ChromeBluetoothRemoteGattService_create(
37 env, reinterpret_cast<intptr_t>(service.get()),
38 bluetooth_gatt_service_wrapper,
39 base::android::ConvertUTF8ToJavaString(env, instance_id),
40 chrome_bluetooth_device));
41
42 return service;
43 }
44
~BluetoothRemoteGattServiceAndroid()45 BluetoothRemoteGattServiceAndroid::~BluetoothRemoteGattServiceAndroid() {
46 Java_ChromeBluetoothRemoteGattService_onBluetoothRemoteGattServiceAndroidDestruction(
47 AttachCurrentThread(), j_service_);
48 }
49
50 base::android::ScopedJavaLocalRef<jobject>
GetJavaObject()51 BluetoothRemoteGattServiceAndroid::GetJavaObject() {
52 return base::android::ScopedJavaLocalRef<jobject>(j_service_);
53 }
54
55 // static
56 BluetoothRemoteGattService::GattErrorCode
GetGattErrorCode(int bluetooth_gatt_code)57 BluetoothRemoteGattServiceAndroid::GetGattErrorCode(int bluetooth_gatt_code) {
58 DCHECK(bluetooth_gatt_code != 0) << "Only errors valid. 0 == GATT_SUCCESS.";
59
60 // TODO(scheib) Create new BluetoothRemoteGattService::GattErrorCode enums for
61 // android values not yet represented. http://crbug.com/548498
62 switch (bluetooth_gatt_code) { // android.bluetooth.BluetoothGatt values:
63 case 0x00000101: // GATT_FAILURE
64 return GATT_ERROR_FAILED;
65 case 0x0000000d: // GATT_INVALID_ATTRIBUTE_LENGTH
66 return GATT_ERROR_INVALID_LENGTH;
67 case 0x00000002: // GATT_READ_NOT_PERMITTED
68 return GATT_ERROR_NOT_PERMITTED;
69 case 0x00000006: // GATT_REQUEST_NOT_SUPPORTED
70 return GATT_ERROR_NOT_SUPPORTED;
71 case 0x00000003: // GATT_WRITE_NOT_PERMITTED
72 return GATT_ERROR_NOT_PERMITTED;
73 default:
74 DVLOG(1) << "Unhandled status: " << bluetooth_gatt_code;
75 return BluetoothRemoteGattService::GATT_ERROR_UNKNOWN;
76 }
77 }
78
79 // static
GetAndroidErrorCode(BluetoothRemoteGattService::GattErrorCode error_code)80 int BluetoothRemoteGattServiceAndroid::GetAndroidErrorCode(
81 BluetoothRemoteGattService::GattErrorCode error_code) {
82 // TODO(scheib) Create new BluetoothRemoteGattService::GattErrorCode enums for
83 // android values not yet represented. http://crbug.com/548498
84 switch (error_code) { // Return values from android.bluetooth.BluetoothGatt:
85 case GATT_ERROR_UNKNOWN:
86 return 0x00000101; // GATT_FAILURE. No good match.
87 case GATT_ERROR_FAILED:
88 return 0x00000101; // GATT_FAILURE
89 case GATT_ERROR_IN_PROGRESS:
90 return 0x00000101; // GATT_FAILURE. No good match.
91 case GATT_ERROR_INVALID_LENGTH:
92 return 0x0000000d; // GATT_INVALID_ATTRIBUTE_LENGTH
93 case GATT_ERROR_NOT_PERMITTED:
94 // Can't distinguish between:
95 // 0x00000002: // GATT_READ_NOT_PERMITTED
96 // 0x00000003: // GATT_WRITE_NOT_PERMITTED
97 return 0x00000101; // GATT_FAILURE. No good match.
98 case GATT_ERROR_NOT_AUTHORIZED:
99 return 0x00000101; // GATT_FAILURE. No good match.
100 case GATT_ERROR_NOT_PAIRED:
101 return 0x00000101; // GATT_FAILURE. No good match.
102 case GATT_ERROR_NOT_SUPPORTED:
103 return 0x00000006; // GATT_REQUEST_NOT_SUPPORTED
104 }
105 DVLOG(1) << "Unhandled error_code: " << error_code;
106 return 0x00000101; // GATT_FAILURE. No good match.
107 }
108
GetIdentifier() const109 std::string BluetoothRemoteGattServiceAndroid::GetIdentifier() const {
110 return instance_id_;
111 }
112
GetUUID() const113 device::BluetoothUUID BluetoothRemoteGattServiceAndroid::GetUUID() const {
114 return device::BluetoothUUID(
115 ConvertJavaStringToUTF8(Java_ChromeBluetoothRemoteGattService_getUUID(
116 AttachCurrentThread(), j_service_)));
117 }
118
IsPrimary() const119 bool BluetoothRemoteGattServiceAndroid::IsPrimary() const {
120 NOTIMPLEMENTED();
121 return true;
122 }
123
GetDevice() const124 device::BluetoothDevice* BluetoothRemoteGattServiceAndroid::GetDevice() const {
125 return device_;
126 }
127
128 std::vector<device::BluetoothRemoteGattCharacteristic*>
GetCharacteristics() const129 BluetoothRemoteGattServiceAndroid::GetCharacteristics() const {
130 EnsureCharacteristicsCreated();
131 return BluetoothRemoteGattService::GetCharacteristics();
132 }
133
134 std::vector<device::BluetoothRemoteGattService*>
GetIncludedServices() const135 BluetoothRemoteGattServiceAndroid::GetIncludedServices() const {
136 NOTIMPLEMENTED();
137 return std::vector<device::BluetoothRemoteGattService*>();
138 }
139
140 device::BluetoothRemoteGattCharacteristic*
GetCharacteristic(const std::string & identifier) const141 BluetoothRemoteGattServiceAndroid::GetCharacteristic(
142 const std::string& identifier) const {
143 EnsureCharacteristicsCreated();
144 return BluetoothRemoteGattService::GetCharacteristic(identifier);
145 }
146
147 std::vector<BluetoothRemoteGattCharacteristic*>
GetCharacteristicsByUUID(const BluetoothUUID & characteristic_uuid) const148 BluetoothRemoteGattServiceAndroid::GetCharacteristicsByUUID(
149 const BluetoothUUID& characteristic_uuid) const {
150 EnsureCharacteristicsCreated();
151 return BluetoothRemoteGattService::GetCharacteristicsByUUID(
152 characteristic_uuid);
153 }
154
IsDiscoveryComplete() const155 bool BluetoothRemoteGattServiceAndroid::IsDiscoveryComplete() const {
156 // Not used on Android, because Android sends an event when service discovery
157 // is complete for the entire device.
158 NOTIMPLEMENTED();
159 return true;
160 }
161
SetDiscoveryComplete(bool complete)162 void BluetoothRemoteGattServiceAndroid::SetDiscoveryComplete(bool complete) {
163 // Not used on Android, because Android sends an event when service discovery
164 // is complete for the entire device.
165 NOTIMPLEMENTED();
166 }
167
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)168 void BluetoothRemoteGattServiceAndroid::CreateGattRemoteCharacteristic(
169 JNIEnv* env,
170 const JavaParamRef<jobject>& caller,
171 const JavaParamRef<jstring>& instance_id,
172 const JavaParamRef<jobject>& /* BluetoothGattCharacteristicWrapper */
173 bluetooth_gatt_characteristic_wrapper,
174 const JavaParamRef<jobject>& /* ChromeBluetoothDevice */
175 chrome_bluetooth_device) {
176 std::string instance_id_string =
177 base::android::ConvertJavaStringToUTF8(env, instance_id);
178
179 DCHECK(!base::Contains(characteristics_, instance_id_string));
180 AddCharacteristic(BluetoothRemoteGattCharacteristicAndroid::Create(
181 adapter_, this, instance_id_string, bluetooth_gatt_characteristic_wrapper,
182 chrome_bluetooth_device));
183 }
184
BluetoothRemoteGattServiceAndroid(BluetoothAdapterAndroid * adapter,BluetoothDeviceAndroid * device,const std::string & instance_id)185 BluetoothRemoteGattServiceAndroid::BluetoothRemoteGattServiceAndroid(
186 BluetoothAdapterAndroid* adapter,
187 BluetoothDeviceAndroid* device,
188 const std::string& instance_id)
189 : adapter_(adapter), device_(device), instance_id_(instance_id) {}
190
EnsureCharacteristicsCreated() const191 void BluetoothRemoteGattServiceAndroid::EnsureCharacteristicsCreated() const {
192 if (!characteristics_.empty())
193 return;
194
195 // Java call
196 Java_ChromeBluetoothRemoteGattService_createCharacteristics(
197 AttachCurrentThread(), j_service_);
198 }
199
200 } // namespace device
201