OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_android.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 return characteristic; | 46 return characteristic; |
47 } | 47 } |
48 | 48 |
49 BluetoothRemoteGattCharacteristicAndroid:: | 49 BluetoothRemoteGattCharacteristicAndroid:: |
50 ~BluetoothRemoteGattCharacteristicAndroid() { | 50 ~BluetoothRemoteGattCharacteristicAndroid() { |
51 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist
icAndroidDestruction( | 51 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist
icAndroidDestruction( |
52 AttachCurrentThread(), j_characteristic_.obj()); | 52 AttachCurrentThread(), j_characteristic_.obj()); |
53 | 53 |
54 if (pending_start_notify_calls_.size()) { | 54 if (pending_start_notify_calls_.size()) { |
55 OnStartNotifySessionError(device::BluetoothGattService::GATT_ERROR_FAILED); | 55 OnStartNotifySessionError( |
| 56 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
56 } | 57 } |
57 } | 58 } |
58 | 59 |
59 // static | 60 // static |
60 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { | 61 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { |
61 return RegisterNativesImpl( | 62 return RegisterNativesImpl( |
62 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h | 63 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h |
63 } | 64 } |
64 | 65 |
65 base::android::ScopedJavaLocalRef<jobject> | 66 base::android::ScopedJavaLocalRef<jobject> |
(...skipping 13 matching lines...) Expand all Loading... |
79 | 80 |
80 bool BluetoothRemoteGattCharacteristicAndroid::IsLocal() const { | 81 bool BluetoothRemoteGattCharacteristicAndroid::IsLocal() const { |
81 return false; | 82 return false; |
82 } | 83 } |
83 | 84 |
84 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicAndroid::GetValue() | 85 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicAndroid::GetValue() |
85 const { | 86 const { |
86 return value_; | 87 return value_; |
87 } | 88 } |
88 | 89 |
89 BluetoothGattService* BluetoothRemoteGattCharacteristicAndroid::GetService() | 90 BluetoothRemoteGattService* |
90 const { | 91 BluetoothRemoteGattCharacteristicAndroid::GetService() const { |
91 return service_; | 92 return service_; |
92 } | 93 } |
93 | 94 |
94 BluetoothGattCharacteristic::Properties | 95 BluetoothRemoteGattCharacteristic::Properties |
95 BluetoothRemoteGattCharacteristicAndroid::GetProperties() const { | 96 BluetoothRemoteGattCharacteristicAndroid::GetProperties() const { |
96 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( | 97 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( |
97 AttachCurrentThread(), j_characteristic_.obj()); | 98 AttachCurrentThread(), j_characteristic_.obj()); |
98 } | 99 } |
99 | 100 |
100 BluetoothGattCharacteristic::Permissions | 101 BluetoothRemoteGattCharacteristic::Permissions |
101 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { | 102 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { |
102 NOTIMPLEMENTED(); | 103 NOTIMPLEMENTED(); |
103 return 0; | 104 return 0; |
104 } | 105 } |
105 | 106 |
106 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const { | 107 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const { |
107 NOTIMPLEMENTED(); | 108 NOTIMPLEMENTED(); |
108 return false; | 109 return false; |
109 } | 110 } |
110 | 111 |
111 std::vector<BluetoothGattDescriptor*> | 112 std::vector<BluetoothRemoteGattDescriptor*> |
112 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { | 113 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { |
113 EnsureDescriptorsCreated(); | 114 EnsureDescriptorsCreated(); |
114 std::vector<BluetoothGattDescriptor*> descriptors; | 115 std::vector<BluetoothRemoteGattDescriptor*> descriptors; |
115 for (const auto& map_iter : descriptors_) | 116 for (const auto& map_iter : descriptors_) |
116 descriptors.push_back(map_iter.second); | 117 descriptors.push_back(map_iter.second); |
117 return descriptors; | 118 return descriptors; |
118 } | 119 } |
119 | 120 |
120 BluetoothGattDescriptor* | 121 BluetoothRemoteGattDescriptor* |
121 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( | 122 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( |
122 const std::string& identifier) const { | 123 const std::string& identifier) const { |
123 EnsureDescriptorsCreated(); | 124 EnsureDescriptorsCreated(); |
124 const auto& iter = descriptors_.find(identifier); | 125 const auto& iter = descriptors_.find(identifier); |
125 if (iter == descriptors_.end()) | 126 if (iter == descriptors_.end()) |
126 return nullptr; | 127 return nullptr; |
127 return iter->second; | 128 return iter->second; |
128 } | 129 } |
129 | 130 |
130 bool BluetoothRemoteGattCharacteristicAndroid::AddDescriptor( | 131 bool BluetoothRemoteGattCharacteristicAndroid::AddDescriptor( |
131 BluetoothGattDescriptor* descriptor) { | 132 BluetoothRemoteGattDescriptor* descriptor) { |
132 NOTIMPLEMENTED(); | 133 NOTIMPLEMENTED(); |
133 return false; | 134 return false; |
134 } | 135 } |
135 | 136 |
136 bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue( | 137 bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue( |
137 const std::vector<uint8_t>& value) { | 138 const std::vector<uint8_t>& value) { |
138 NOTIMPLEMENTED(); | 139 NOTIMPLEMENTED(); |
139 return false; | 140 return false; |
140 } | 141 } |
141 | 142 |
142 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( | 143 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( |
143 const NotifySessionCallback& callback, | 144 const NotifySessionCallback& callback, |
144 const ErrorCallback& error_callback) { | 145 const ErrorCallback& error_callback) { |
145 if (!pending_start_notify_calls_.empty()) { | 146 if (!pending_start_notify_calls_.empty()) { |
146 pending_start_notify_calls_.push_back( | 147 pending_start_notify_calls_.push_back( |
147 std::make_pair(callback, error_callback)); | 148 std::make_pair(callback, error_callback)); |
148 return; | 149 return; |
149 } | 150 } |
150 | 151 |
151 Properties properties = GetProperties(); | 152 Properties properties = GetProperties(); |
152 | 153 |
153 bool hasNotify = properties & PROPERTY_NOTIFY; | 154 bool hasNotify = properties & PROPERTY_NOTIFY; |
154 bool hasIndicate = properties & PROPERTY_INDICATE; | 155 bool hasIndicate = properties & PROPERTY_INDICATE; |
155 | 156 |
156 if (!hasNotify && !hasIndicate) { | 157 if (!hasNotify && !hasIndicate) { |
157 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; | 158 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; |
158 base::MessageLoop::current()->PostTask( | 159 base::MessageLoop::current()->PostTask( |
159 FROM_HERE, base::Bind(error_callback, | 160 FROM_HERE, |
160 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | 161 base::Bind(error_callback, |
| 162 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
161 return; | 163 return; |
162 } | 164 } |
163 | 165 |
164 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( | 166 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor = |
165 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 167 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor:: |
| 168 ClientCharacteristicConfigurationUuid()); |
166 | 169 |
167 if (ccc_descriptor.size() != 1u) { | 170 if (ccc_descriptor.size() != 1u) { |
168 LOG(ERROR) << "Found " << ccc_descriptor.size() | 171 LOG(ERROR) << "Found " << ccc_descriptor.size() |
169 << " client characteristic configuration descriptors."; | 172 << " client characteristic configuration descriptors."; |
170 base::MessageLoop::current()->PostTask( | 173 base::MessageLoop::current()->PostTask( |
171 FROM_HERE, | 174 FROM_HERE, |
172 base::Bind(error_callback, | 175 base::Bind(error_callback, |
173 (ccc_descriptor.size() == 0) | 176 (ccc_descriptor.size() == 0) |
174 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED | 177 ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED |
175 : BluetoothGattService::GATT_ERROR_FAILED)); | 178 : BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
176 return; | 179 return; |
177 } | 180 } |
178 | 181 |
179 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( | 182 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( |
180 AttachCurrentThread(), j_characteristic_.obj(), true)) { | 183 AttachCurrentThread(), j_characteristic_.obj(), true)) { |
181 LOG(ERROR) << "Error enabling characteristic notification"; | 184 LOG(ERROR) << "Error enabling characteristic notification"; |
182 base::MessageLoop::current()->PostTask( | 185 base::MessageLoop::current()->PostTask( |
183 FROM_HERE, | 186 FROM_HERE, base::Bind(error_callback, |
184 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 187 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
185 return; | 188 return; |
186 } | 189 } |
187 | 190 |
188 std::vector<uint8_t> value(2); | 191 std::vector<uint8_t> value(2); |
189 value[0] = hasNotify ? 1 : 2; | 192 value[0] = hasNotify ? 1 : 2; |
190 | 193 |
191 pending_start_notify_calls_.push_back( | 194 pending_start_notify_calls_.push_back( |
192 std::make_pair(callback, error_callback)); | 195 std::make_pair(callback, error_callback)); |
193 ccc_descriptor[0]->WriteRemoteDescriptor( | 196 ccc_descriptor[0]->WriteRemoteDescriptor( |
194 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: | 197 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
195 OnStartNotifySessionSuccess, | 198 OnStartNotifySessionSuccess, |
196 base::Unretained(this)), | 199 base::Unretained(this)), |
197 base::Bind( | 200 base::Bind( |
198 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, | 201 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
199 base::Unretained(this))); | 202 base::Unretained(this))); |
200 } | 203 } |
201 | 204 |
202 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( | 205 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
203 const ValueCallback& callback, | 206 const ValueCallback& callback, |
204 const ErrorCallback& error_callback) { | 207 const ErrorCallback& error_callback) { |
205 if (read_pending_ || write_pending_) { | 208 if (read_pending_ || write_pending_) { |
206 base::MessageLoop::current()->PostTask( | 209 base::MessageLoop::current()->PostTask( |
207 FROM_HERE, base::Bind(error_callback, | 210 FROM_HERE, |
208 BluetoothGattService::GATT_ERROR_IN_PROGRESS)); | 211 base::Bind(error_callback, |
| 212 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
209 return; | 213 return; |
210 } | 214 } |
211 | 215 |
212 if (!Java_ChromeBluetoothRemoteGattCharacteristic_readRemoteCharacteristic( | 216 if (!Java_ChromeBluetoothRemoteGattCharacteristic_readRemoteCharacteristic( |
213 AttachCurrentThread(), j_characteristic_.obj())) { | 217 AttachCurrentThread(), j_characteristic_.obj())) { |
214 base::MessageLoop::current()->PostTask( | 218 base::MessageLoop::current()->PostTask( |
215 FROM_HERE, | 219 FROM_HERE, base::Bind(error_callback, |
216 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 220 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
217 return; | 221 return; |
218 } | 222 } |
219 | 223 |
220 read_pending_ = true; | 224 read_pending_ = true; |
221 read_callback_ = callback; | 225 read_callback_ = callback; |
222 read_error_callback_ = error_callback; | 226 read_error_callback_ = error_callback; |
223 } | 227 } |
224 | 228 |
225 void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic( | 229 void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic( |
226 const std::vector<uint8_t>& new_value, | 230 const std::vector<uint8_t>& new_value, |
227 const base::Closure& callback, | 231 const base::Closure& callback, |
228 const ErrorCallback& error_callback) { | 232 const ErrorCallback& error_callback) { |
229 if (read_pending_ || write_pending_) { | 233 if (read_pending_ || write_pending_) { |
230 base::MessageLoop::current()->PostTask( | 234 base::MessageLoop::current()->PostTask( |
231 FROM_HERE, base::Bind(error_callback, | 235 FROM_HERE, |
232 BluetoothGattService::GATT_ERROR_IN_PROGRESS)); | 236 base::Bind(error_callback, |
| 237 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
233 return; | 238 return; |
234 } | 239 } |
235 | 240 |
236 JNIEnv* env = AttachCurrentThread(); | 241 JNIEnv* env = AttachCurrentThread(); |
237 if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic( | 242 if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic( |
238 env, j_characteristic_.obj(), | 243 env, j_characteristic_.obj(), |
239 base::android::ToJavaByteArray(env, new_value).obj())) { | 244 base::android::ToJavaByteArray(env, new_value).obj())) { |
240 base::MessageLoop::current()->PostTask( | 245 base::MessageLoop::current()->PostTask( |
241 FROM_HERE, | 246 FROM_HERE, base::Bind(error_callback, |
242 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 247 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
243 return; | 248 return; |
244 } | 249 } |
245 | 250 |
246 write_pending_ = true; | 251 write_pending_ = true; |
247 write_callback_ = callback; | 252 write_callback_ = callback; |
248 write_error_callback_ = error_callback; | 253 write_error_callback_ = error_callback; |
249 } | 254 } |
250 | 255 |
251 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( | 256 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( |
252 JNIEnv* env, | 257 JNIEnv* env, |
253 const JavaParamRef<jobject>& jcaller, | 258 const JavaParamRef<jobject>& jcaller, |
254 const JavaParamRef<jbyteArray>& value) { | 259 const JavaParamRef<jbyteArray>& value) { |
255 base::android::JavaByteArrayToByteVector(env, value, &value_); | 260 base::android::JavaByteArrayToByteVector(env, value, &value_); |
256 adapter_->NotifyGattCharacteristicValueChanged(this, value_); | 261 adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
257 } | 262 } |
258 | 263 |
259 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { | 264 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
260 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; | 265 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
261 reentrant_safe_callbacks.swap(pending_start_notify_calls_); | 266 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
262 | 267 |
263 for (const auto& callback_pair : reentrant_safe_callbacks) { | 268 for (const auto& callback_pair : reentrant_safe_callbacks) { |
264 std::unique_ptr<device::BluetoothGattNotifySession> notify_session( | 269 std::unique_ptr<device::BluetoothGattNotifySession> notify_session( |
265 new BluetoothGattNotifySessionAndroid(instance_id_)); | 270 new BluetoothGattNotifySessionAndroid(instance_id_)); |
266 callback_pair.first.Run(std::move(notify_session)); | 271 callback_pair.first.Run(std::move(notify_session)); |
267 } | 272 } |
268 } | 273 } |
269 | 274 |
270 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( | 275 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
271 BluetoothGattService::GattErrorCode error) { | 276 BluetoothRemoteGattService::GattErrorCode error) { |
272 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; | 277 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
273 reentrant_safe_callbacks.swap(pending_start_notify_calls_); | 278 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
274 | 279 |
275 for (auto const& callback_pair : reentrant_safe_callbacks) { | 280 for (auto const& callback_pair : reentrant_safe_callbacks) { |
276 callback_pair.second.Run(error); | 281 callback_pair.second.Run(error); |
277 } | 282 } |
278 } | 283 } |
279 | 284 |
280 void BluetoothRemoteGattCharacteristicAndroid::OnRead( | 285 void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
281 JNIEnv* env, | 286 JNIEnv* env, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() | 357 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() |
353 const { | 358 const { |
354 if (!descriptors_.empty()) | 359 if (!descriptors_.empty()) |
355 return; | 360 return; |
356 | 361 |
357 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( | 362 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( |
358 AttachCurrentThread(), j_characteristic_.obj()); | 363 AttachCurrentThread(), j_characteristic_.obj()); |
359 } | 364 } |
360 | 365 |
361 } // namespace device | 366 } // namespace device |
OLD | NEW |