Chromium Code Reviews| 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); | |
|
ortuno
2016/03/25 02:07:31
Talked offline. This can happen when we call start
scheib
2016/03/25 02:35:00
Acknowledged.
| |
| 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, |
| 153 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 158 |
|
ortuno
2016/03/25 02:07:31
remove new line.
scheib
2016/03/25 02:35:01
Done.
| |
| 159 base::Bind(error_callback, | |
| 160 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | |
| 154 return; | 161 return; |
| 155 } | 162 } |
| 156 | 163 |
| 157 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( | 164 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( |
| 158 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 165 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); |
| 159 | 166 |
| 160 if (ccc_descriptor.size() != 1u) { | 167 if (ccc_descriptor.size() != 1u) { |
| 161 LOG(ERROR) << "Found " << ccc_descriptor.size() | 168 LOG(ERROR) << "Found " << ccc_descriptor.size() |
| 162 << " client characteristic configuration descriptors."; | 169 << " client characteristic configuration descriptors."; |
| 163 base::MessageLoop::current()->PostTask( | 170 base::MessageLoop::current()->PostTask( |
| 164 FROM_HERE, | 171 FROM_HERE, |
| 165 base::Bind(error_callback, | 172 base::Bind(error_callback, |
| 166 (ccc_descriptor.size() == 0) | 173 (ccc_descriptor.size() == 0) |
| 167 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED | 174 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED |
| 168 : BluetoothGattService::GATT_ERROR_FAILED)); | 175 : BluetoothGattService::GATT_ERROR_FAILED)); |
| 169 return; | 176 return; |
| 170 } | 177 } |
| 171 | 178 |
| 172 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n( | 179 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n( |
| 173 AttachCurrentThread(), j_characteristic_.obj(), true)) { | 180 AttachCurrentThread(), j_characteristic_.obj(), true)) { |
| 174 LOG(ERROR) << "Error enabling characteristic notification"; | 181 LOG(ERROR) << "Error enabling characteristic notification"; |
| 175 base::MessageLoop::current()->PostTask( | 182 base::MessageLoop::current()->PostTask( |
| 176 FROM_HERE, | 183 FROM_HERE, |
| 177 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 184 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); |
| 178 return; | 185 return; |
| 179 } | 186 } |
| 180 | 187 |
| 181 std::vector<uint8_t> value; | 188 std::vector<uint8_t> value(2); |
| 182 value.push_back(hasNotify ? 1 : 2); | 189 value[0] = hasNotify ? 1 : 2; |
| 183 value.push_back(0); | |
| 184 | 190 |
| 185 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 191 pending_start_notify_calls_.push_back( |
| 192 std::make_pair(callback, error_callback)); | |
| 186 ccc_descriptor[0]->WriteRemoteDescriptor( | 193 ccc_descriptor[0]->WriteRemoteDescriptor( |
| 187 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: | 194 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
| 188 OnStartNotifySessionSuccess, | 195 OnStartNotifySessionSuccess, |
| 189 base::Unretained(this)), | 196 base::Unretained(this)), |
| 190 base::Bind( | 197 base::Bind( |
| 191 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, | 198 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
| 192 base::Unretained(this))); | 199 base::Unretained(this))); |
| 193 } | 200 } |
| 194 | 201 |
| 195 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( | 202 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 | 250 |
| 244 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( | 251 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( |
| 245 JNIEnv* env, | 252 JNIEnv* env, |
| 246 const JavaParamRef<jobject>& jcaller, | 253 const JavaParamRef<jobject>& jcaller, |
| 247 const JavaParamRef<jbyteArray>& value) { | 254 const JavaParamRef<jbyteArray>& value) { |
| 248 base::android::JavaByteArrayToByteVector(env, value, &value_); | 255 base::android::JavaByteArrayToByteVector(env, value, &value_); |
| 249 adapter_->NotifyGattCharacteristicValueChanged(this, value_); | 256 adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
| 250 } | 257 } |
| 251 | 258 |
| 252 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { | 259 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
| 253 while (!pending_start_notify_calls_.empty()) { | 260 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 254 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 261 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 255 pending_start_notify_calls_.pop(); | 262 |
| 263 for (const auto& callback_pair : reentrant_safe_callbacks) { | |
| 256 scoped_ptr<device::BluetoothGattNotifySession> notify_session( | 264 scoped_ptr<device::BluetoothGattNotifySession> notify_session( |
| 257 new BluetoothGattNotifySessionAndroid(instance_id_)); | 265 new BluetoothGattNotifySessionAndroid(instance_id_)); |
| 258 callbacks.first.Run(std::move(notify_session)); | 266 callback_pair.first.Run(std::move(notify_session)); |
| 259 } | 267 } |
| 260 } | 268 } |
| 261 | 269 |
| 262 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( | 270 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
| 263 BluetoothGattService::GattErrorCode error) { | 271 BluetoothGattService::GattErrorCode error) { |
| 264 while (!pending_start_notify_calls_.empty()) { | 272 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 265 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 273 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 266 pending_start_notify_calls_.pop(); | 274 |
| 267 callbacks.second.Run(error); | 275 for (auto const& callback_pair : reentrant_safe_callbacks) { |
| 276 callback_pair.second.Run(error); | |
| 268 } | 277 } |
| 269 } | 278 } |
| 270 | 279 |
| 271 void BluetoothRemoteGattCharacteristicAndroid::OnRead( | 280 void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
| 272 JNIEnv* env, | 281 JNIEnv* env, |
| 273 const JavaParamRef<jobject>& jcaller, | 282 const JavaParamRef<jobject>& jcaller, |
| 274 int32_t status, | 283 int32_t status, |
| 275 const JavaParamRef<jbyteArray>& value) { | 284 const JavaParamRef<jbyteArray>& value) { |
| 276 read_pending_ = false; | 285 read_pending_ = false; |
| 277 | 286 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() | 352 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() |
| 344 const { | 353 const { |
| 345 if (!descriptors_.empty()) | 354 if (!descriptors_.empty()) |
| 346 return; | 355 return; |
| 347 | 356 |
| 348 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( | 357 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( |
| 349 AttachCurrentThread(), j_characteristic_.obj()); | 358 AttachCurrentThread(), j_characteristic_.obj()); |
| 350 } | 359 } |
| 351 | 360 |
| 352 } // namespace device | 361 } // namespace device |
| OLD | NEW |