| 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 |