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 "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 base::android::ConvertUTF8ToJavaString(env, instance_id).obj(), | 41 base::android::ConvertUTF8ToJavaString(env, instance_id).obj(), |
42 chrome_bluetooth_device)); | 42 chrome_bluetooth_device)); |
43 | 43 |
44 return characteristic; | 44 return characteristic; |
45 } | 45 } |
46 | 46 |
47 BluetoothRemoteGattCharacteristicAndroid:: | 47 BluetoothRemoteGattCharacteristicAndroid:: |
48 ~BluetoothRemoteGattCharacteristicAndroid() { | 48 ~BluetoothRemoteGattCharacteristicAndroid() { |
49 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist
icAndroidDestruction( | 49 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist
icAndroidDestruction( |
50 AttachCurrentThread(), j_characteristic_.obj()); | 50 AttachCurrentThread(), j_characteristic_.obj()); |
| 51 |
| 52 if (pending_start_notify_calls_.size()) { |
| 53 OnStartNotifySessionError(device::BluetoothGattService::GATT_ERROR_FAILED); |
| 54 } |
51 } | 55 } |
52 | 56 |
53 // static | 57 // static |
54 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { | 58 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { |
55 return RegisterNativesImpl( | 59 return RegisterNativesImpl( |
56 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h | 60 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h |
57 } | 61 } |
58 | 62 |
59 base::android::ScopedJavaLocalRef<jobject> | 63 base::android::ScopedJavaLocalRef<jobject> |
60 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { | 64 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue( | 134 bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue( |
131 const std::vector<uint8_t>& value) { | 135 const std::vector<uint8_t>& value) { |
132 NOTIMPLEMENTED(); | 136 NOTIMPLEMENTED(); |
133 return false; | 137 return false; |
134 } | 138 } |
135 | 139 |
136 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( | 140 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( |
137 const NotifySessionCallback& callback, | 141 const NotifySessionCallback& callback, |
138 const ErrorCallback& error_callback) { | 142 const ErrorCallback& error_callback) { |
139 if (!pending_start_notify_calls_.empty()) { | 143 if (!pending_start_notify_calls_.empty()) { |
140 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 144 pending_start_notify_calls_.push_back( |
| 145 std::make_pair(callback, error_callback)); |
141 return; | 146 return; |
142 } | 147 } |
143 | 148 |
144 Properties properties = GetProperties(); | 149 Properties properties = GetProperties(); |
145 | 150 |
146 bool hasNotify = properties & PROPERTY_NOTIFY; | 151 bool hasNotify = properties & PROPERTY_NOTIFY; |
147 bool hasIndicate = properties & PROPERTY_INDICATE; | 152 bool hasIndicate = properties & PROPERTY_INDICATE; |
148 | 153 |
149 if (!hasNotify && !hasIndicate) { | 154 if (!hasNotify && !hasIndicate) { |
150 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; | 155 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; |
151 base::MessageLoop::current()->PostTask( | 156 base::MessageLoop::current()->PostTask( |
152 FROM_HERE, | 157 FROM_HERE, base::Bind(error_callback, |
153 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 158 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); |
154 return; | 159 return; |
155 } | 160 } |
156 | 161 |
157 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( | 162 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( |
158 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 163 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); |
159 | 164 |
160 if (ccc_descriptor.size() != 1u) { | 165 if (ccc_descriptor.size() != 1u) { |
161 LOG(ERROR) << "Found " << ccc_descriptor.size() | 166 LOG(ERROR) << "Found " << ccc_descriptor.size() |
162 << " client characteristic configuration descriptors."; | 167 << " client characteristic configuration descriptors."; |
163 base::MessageLoop::current()->PostTask( | 168 base::MessageLoop::current()->PostTask( |
164 FROM_HERE, | 169 FROM_HERE, |
165 base::Bind(error_callback, | 170 base::Bind(error_callback, |
166 (ccc_descriptor.size() == 0) | 171 (ccc_descriptor.size() == 0) |
167 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED | 172 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED |
168 : BluetoothGattService::GATT_ERROR_FAILED)); | 173 : BluetoothGattService::GATT_ERROR_FAILED)); |
169 return; | 174 return; |
170 } | 175 } |
171 | 176 |
172 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( | 177 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( |
173 AttachCurrentThread(), j_characteristic_.obj(), true)) { | 178 AttachCurrentThread(), j_characteristic_.obj(), true)) { |
174 LOG(ERROR) << "Error enabling characteristic notification"; | 179 LOG(ERROR) << "Error enabling characteristic notification"; |
175 base::MessageLoop::current()->PostTask( | 180 base::MessageLoop::current()->PostTask( |
176 FROM_HERE, | 181 FROM_HERE, |
177 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 182 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); |
178 return; | 183 return; |
179 } | 184 } |
180 | 185 |
181 std::vector<uint8_t> value; | 186 std::vector<uint8_t> value(2); |
182 value.push_back(hasNotify ? 1 : 2); | 187 value[0] = hasNotify ? 1 : 2; |
183 value.push_back(0); | |
184 | 188 |
185 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 189 pending_start_notify_calls_.push_back( |
| 190 std::make_pair(callback, error_callback)); |
186 ccc_descriptor[0]->WriteRemoteDescriptor( | 191 ccc_descriptor[0]->WriteRemoteDescriptor( |
187 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: | 192 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
188 OnStartNotifySessionSuccess, | 193 OnStartNotifySessionSuccess, |
189 base::Unretained(this)), | 194 base::Unretained(this)), |
190 base::Bind( | 195 base::Bind( |
191 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, | 196 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
192 base::Unretained(this))); | 197 base::Unretained(this))); |
193 } | 198 } |
194 | 199 |
195 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( | 200 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 248 |
244 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( | 249 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( |
245 JNIEnv* env, | 250 JNIEnv* env, |
246 const JavaParamRef<jobject>& jcaller, | 251 const JavaParamRef<jobject>& jcaller, |
247 const JavaParamRef<jbyteArray>& value) { | 252 const JavaParamRef<jbyteArray>& value) { |
248 base::android::JavaByteArrayToByteVector(env, value, &value_); | 253 base::android::JavaByteArrayToByteVector(env, value, &value_); |
249 adapter_->NotifyGattCharacteristicValueChanged(this, value_); | 254 adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
250 } | 255 } |
251 | 256 |
252 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { | 257 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
253 while (!pending_start_notify_calls_.empty()) { | 258 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
254 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 259 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
255 pending_start_notify_calls_.pop(); | 260 |
| 261 for (const auto& callback_pair : reentrant_safe_callbacks) { |
256 scoped_ptr<device::BluetoothGattNotifySession> notify_session( | 262 scoped_ptr<device::BluetoothGattNotifySession> notify_session( |
257 new BluetoothGattNotifySessionAndroid(instance_id_)); | 263 new BluetoothGattNotifySessionAndroid(instance_id_)); |
258 callbacks.first.Run(std::move(notify_session)); | 264 callback_pair.first.Run(std::move(notify_session)); |
259 } | 265 } |
260 } | 266 } |
261 | 267 |
262 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( | 268 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
263 BluetoothGattService::GattErrorCode error) { | 269 BluetoothGattService::GattErrorCode error) { |
264 while (!pending_start_notify_calls_.empty()) { | 270 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
265 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 271 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
266 pending_start_notify_calls_.pop(); | 272 |
267 callbacks.second.Run(error); | 273 for (auto const& callback_pair : reentrant_safe_callbacks) { |
| 274 callback_pair.second.Run(error); |
268 } | 275 } |
269 } | 276 } |
270 | 277 |
271 void BluetoothRemoteGattCharacteristicAndroid::OnRead( | 278 void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
272 JNIEnv* env, | 279 JNIEnv* env, |
273 const JavaParamRef<jobject>& jcaller, | 280 const JavaParamRef<jobject>& jcaller, |
274 int32_t status, | 281 int32_t status, |
275 const JavaParamRef<jbyteArray>& value) { | 282 const JavaParamRef<jbyteArray>& value) { |
276 read_pending_ = false; | 283 read_pending_ = false; |
277 | 284 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() | 350 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() |
344 const { | 351 const { |
345 if (!descriptors_.empty()) | 352 if (!descriptors_.empty()) |
346 return; | 353 return; |
347 | 354 |
348 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( | 355 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( |
349 AttachCurrentThread(), j_characteristic_.obj()); | 356 AttachCurrentThread(), j_characteristic_.obj()); |
350 } | 357 } |
351 | 358 |
352 } // namespace device | 359 } // namespace device |
OLD | NEW |