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); | |
| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 NOTIMPLEMENTED(); | 130 NOTIMPLEMENTED(); |
| 127 return false; | 131 return false; |
| 128 } | 132 } |
| 129 | 133 |
| 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( |
|
ortuno
2016/03/13 22:45:03
We need an issue to track IsNotifying(). Otherwise
scheib
2016/03/14 20:00:16
Done. https://bugs.chromium.org/p/chromium/issues/
| |
| 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, | 158 base::Bind( |
| 154 BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED)); | 159 error_callback, |
| 160 BluetoothRemoteGattServiceAndroid::GATT_ERROR_NOT_SUPPORTED)); | |
| 155 return; | 161 return; |
| 156 } | 162 } |
| 157 | 163 |
| 158 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsForUUID( | 164 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsForUUID( |
| 159 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 165 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); |
| 160 | 166 |
| 161 if (ccc_descriptor.size() != 1u) { | 167 if (ccc_descriptor.size() != 1u) { |
| 162 LOG(ERROR) | 168 LOG(ERROR) |
| 163 << "Could not find client characteristic configuration descriptor"; | 169 << "Could not find client characteristic configuration descriptor"; |
| 164 base::MessageLoop::current()->PostTask( | 170 base::MessageLoop::current()->PostTask( |
| 165 FROM_HERE, | 171 FROM_HERE, |
| 166 base::Bind(error_callback, | 172 base::Bind( |
| 167 BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED)); | 173 error_callback, |
| 174 BluetoothRemoteGattServiceAndroid::GATT_ERROR_NOT_SUPPORTED)); | |
| 168 return; | 175 return; |
| 169 } | 176 } |
| 170 | 177 |
| 171 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n( | 178 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n( |
| 172 AttachCurrentThread(), j_characteristic_.obj(), true)) { | 179 AttachCurrentThread(), j_characteristic_.obj(), true)) { |
| 173 LOG(ERROR) << "Error enabling characteristic notification"; | 180 LOG(ERROR) << "Error enabling characteristic notification"; |
| 174 base::MessageLoop::current()->PostTask( | 181 base::MessageLoop::current()->PostTask( |
| 175 FROM_HERE, | 182 FROM_HERE, |
| 176 base::Bind(error_callback, | 183 base::Bind(error_callback, |
| 177 BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED)); | 184 BluetoothRemoteGattServiceAndroid::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.push_back(hasNotify ? 1 : 2); |
| 183 value.push_back(0); | 190 value.push_back(0); |
| 184 | 191 |
| 185 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 192 pending_start_notify_calls_.push_back( |
| 193 std::make_pair(callback, error_callback)); | |
| 186 ccc_descriptor[0]->WriteRemoteDescriptor( | 194 ccc_descriptor[0]->WriteRemoteDescriptor( |
| 187 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: | 195 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
| 188 OnStartNotifySessionSuccess, | 196 OnStartNotifySessionSuccess, |
| 189 base::Unretained(this)), | 197 base::Unretained(this)), |
| 190 base::Bind( | 198 base::Bind( |
| 191 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, | 199 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
| 192 base::Unretained(this))); | 200 base::Unretained(this))); |
| 193 } | 201 } |
| 194 | 202 |
| 195 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( | 203 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 | 253 |
| 246 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( | 254 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( |
| 247 JNIEnv* env, | 255 JNIEnv* env, |
| 248 const JavaParamRef<jobject>& jcaller, | 256 const JavaParamRef<jobject>& jcaller, |
| 249 const JavaParamRef<jbyteArray>& value) { | 257 const JavaParamRef<jbyteArray>& value) { |
| 250 base::android::JavaByteArrayToByteVector(env, value, &value_); | 258 base::android::JavaByteArrayToByteVector(env, value, &value_); |
| 251 adapter_->NotifyGattCharacteristicValueChanged(this, value_); | 259 adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
| 252 } | 260 } |
| 253 | 261 |
| 254 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { | 262 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
| 255 while (!pending_start_notify_calls_.empty()) { | 263 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 256 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 264 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 257 pending_start_notify_calls_.pop(); | 265 |
| 266 for (const auto& callback_pair : reentrant_safe_callbacks) { | |
| 258 scoped_ptr<device::BluetoothGattNotifySession> notify_session( | 267 scoped_ptr<device::BluetoothGattNotifySession> notify_session( |
| 259 new BluetoothGattNotifySessionAndroid(instance_id_)); | 268 new BluetoothGattNotifySessionAndroid(instance_id_)); |
| 260 callbacks.first.Run(std::move(notify_session)); | 269 callback_pair.first.Run(std::move(notify_session)); |
| 261 } | 270 } |
| 262 } | 271 } |
| 263 | 272 |
| 264 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( | 273 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
| 265 BluetoothGattService::GattErrorCode error) { | 274 BluetoothGattService::GattErrorCode error) { |
| 266 while (!pending_start_notify_calls_.empty()) { | 275 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 267 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 276 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 268 pending_start_notify_calls_.pop(); | 277 |
| 269 callbacks.second.Run(error); | 278 for (auto const& callback_pair : reentrant_safe_callbacks) { |
| 279 callback_pair.second.Run(error); | |
| 270 } | 280 } |
| 271 } | 281 } |
| 272 | 282 |
| 273 void BluetoothRemoteGattCharacteristicAndroid::OnRead( | 283 void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
| 274 JNIEnv* env, | 284 JNIEnv* env, |
| 275 const JavaParamRef<jobject>& jcaller, | 285 const JavaParamRef<jobject>& jcaller, |
| 276 int32_t status, | 286 int32_t status, |
| 277 const JavaParamRef<jbyteArray>& value) { | 287 const JavaParamRef<jbyteArray>& value) { |
| 278 read_pending_ = false; | 288 read_pending_ = false; |
| 279 | 289 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() | 355 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() |
| 346 const { | 356 const { |
| 347 if (!descriptors_.empty()) | 357 if (!descriptors_.empty()) |
| 348 return; | 358 return; |
| 349 | 359 |
| 350 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( | 360 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( |
| 351 AttachCurrentThread(), j_characteristic_.obj()); | 361 AttachCurrentThread(), j_characteristic_.obj()); |
| 352 } | 362 } |
| 353 | 363 |
| 354 } // namespace device | 364 } // namespace device |
| OLD | NEW |