| 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> |
| 66 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { | 67 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { |
| 67 return base::android::ScopedJavaLocalRef<jobject>(j_characteristic_); | 68 return base::android::ScopedJavaLocalRef<jobject>(j_characteristic_); |
| 68 } | 69 } |
| 69 | 70 |
| 70 std::string BluetoothRemoteGattCharacteristicAndroid::GetIdentifier() const { | 71 std::string BluetoothRemoteGattCharacteristicAndroid::GetIdentifier() const { |
| 71 return instance_id_; | 72 return instance_id_; |
| 72 } | 73 } |
| 73 | 74 |
| 74 BluetoothUUID BluetoothRemoteGattCharacteristicAndroid::GetUUID() const { | 75 BluetoothUUID BluetoothRemoteGattCharacteristicAndroid::GetUUID() const { |
| 75 return device::BluetoothUUID(ConvertJavaStringToUTF8( | 76 return device::BluetoothUUID(ConvertJavaStringToUTF8( |
| 76 Java_ChromeBluetoothRemoteGattCharacteristic_getUUID( | 77 Java_ChromeBluetoothRemoteGattCharacteristic_getUUID( |
| 77 AttachCurrentThread(), j_characteristic_.obj()))); | 78 AttachCurrentThread(), j_characteristic_.obj()))); |
| 78 } | 79 } |
| 79 | 80 |
| 80 bool BluetoothRemoteGattCharacteristicAndroid::IsLocal() const { | |
| 81 return false; | |
| 82 } | |
| 83 | |
| 84 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicAndroid::GetValue() | 81 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicAndroid::GetValue() |
| 85 const { | 82 const { |
| 86 return value_; | 83 return value_; |
| 87 } | 84 } |
| 88 | 85 |
| 89 BluetoothGattService* BluetoothRemoteGattCharacteristicAndroid::GetService() | 86 BluetoothRemoteGattService* |
| 90 const { | 87 BluetoothRemoteGattCharacteristicAndroid::GetService() const { |
| 91 return service_; | 88 return service_; |
| 92 } | 89 } |
| 93 | 90 |
| 94 BluetoothGattCharacteristic::Properties | 91 BluetoothRemoteGattCharacteristic::Properties |
| 95 BluetoothRemoteGattCharacteristicAndroid::GetProperties() const { | 92 BluetoothRemoteGattCharacteristicAndroid::GetProperties() const { |
| 96 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( | 93 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( |
| 97 AttachCurrentThread(), j_characteristic_.obj()); | 94 AttachCurrentThread(), j_characteristic_.obj()); |
| 98 } | 95 } |
| 99 | 96 |
| 100 BluetoothGattCharacteristic::Permissions | 97 BluetoothRemoteGattCharacteristic::Permissions |
| 101 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { | 98 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { |
| 102 NOTIMPLEMENTED(); | 99 NOTIMPLEMENTED(); |
| 103 return 0; | 100 return 0; |
| 104 } | 101 } |
| 105 | 102 |
| 106 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const { | 103 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const { |
| 107 NOTIMPLEMENTED(); | 104 NOTIMPLEMENTED(); |
| 108 return false; | 105 return false; |
| 109 } | 106 } |
| 110 | 107 |
| 111 std::vector<BluetoothGattDescriptor*> | 108 std::vector<BluetoothRemoteGattDescriptor*> |
| 112 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { | 109 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { |
| 113 EnsureDescriptorsCreated(); | 110 EnsureDescriptorsCreated(); |
| 114 std::vector<BluetoothGattDescriptor*> descriptors; | 111 std::vector<BluetoothRemoteGattDescriptor*> descriptors; |
| 115 for (const auto& map_iter : descriptors_) | 112 for (const auto& map_iter : descriptors_) |
| 116 descriptors.push_back(map_iter.second); | 113 descriptors.push_back(map_iter.second); |
| 117 return descriptors; | 114 return descriptors; |
| 118 } | 115 } |
| 119 | 116 |
| 120 BluetoothGattDescriptor* | 117 BluetoothRemoteGattDescriptor* |
| 121 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( | 118 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( |
| 122 const std::string& identifier) const { | 119 const std::string& identifier) const { |
| 123 EnsureDescriptorsCreated(); | 120 EnsureDescriptorsCreated(); |
| 124 const auto& iter = descriptors_.find(identifier); | 121 const auto& iter = descriptors_.find(identifier); |
| 125 if (iter == descriptors_.end()) | 122 if (iter == descriptors_.end()) |
| 126 return nullptr; | 123 return nullptr; |
| 127 return iter->second; | 124 return iter->second; |
| 128 } | 125 } |
| 129 | 126 |
| 130 bool BluetoothRemoteGattCharacteristicAndroid::AddDescriptor( | |
| 131 BluetoothGattDescriptor* descriptor) { | |
| 132 NOTIMPLEMENTED(); | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 bool BluetoothRemoteGattCharacteristicAndroid::UpdateValue( | |
| 137 const std::vector<uint8_t>& value) { | |
| 138 NOTIMPLEMENTED(); | |
| 139 return false; | |
| 140 } | |
| 141 | |
| 142 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( | 127 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession( |
| 143 const NotifySessionCallback& callback, | 128 const NotifySessionCallback& callback, |
| 144 const ErrorCallback& error_callback) { | 129 const ErrorCallback& error_callback) { |
| 145 if (!pending_start_notify_calls_.empty()) { | 130 if (!pending_start_notify_calls_.empty()) { |
| 146 pending_start_notify_calls_.push_back( | 131 pending_start_notify_calls_.push_back( |
| 147 std::make_pair(callback, error_callback)); | 132 std::make_pair(callback, error_callback)); |
| 148 return; | 133 return; |
| 149 } | 134 } |
| 150 | 135 |
| 151 Properties properties = GetProperties(); | 136 Properties properties = GetProperties(); |
| 152 | 137 |
| 153 bool hasNotify = properties & PROPERTY_NOTIFY; | 138 bool hasNotify = properties & PROPERTY_NOTIFY; |
| 154 bool hasIndicate = properties & PROPERTY_INDICATE; | 139 bool hasIndicate = properties & PROPERTY_INDICATE; |
| 155 | 140 |
| 156 if (!hasNotify && !hasIndicate) { | 141 if (!hasNotify && !hasIndicate) { |
| 157 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; | 142 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE"; |
| 158 base::MessageLoop::current()->PostTask( | 143 base::MessageLoop::current()->PostTask( |
| 159 FROM_HERE, base::Bind(error_callback, | 144 FROM_HERE, |
| 160 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | 145 base::Bind(error_callback, |
| 146 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
| 161 return; | 147 return; |
| 162 } | 148 } |
| 163 | 149 |
| 164 std::vector<BluetoothGattDescriptor*> ccc_descriptor = GetDescriptorsByUUID( | 150 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor = |
| 165 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 151 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor:: |
| 152 ClientCharacteristicConfigurationUuid()); |
| 166 | 153 |
| 167 if (ccc_descriptor.size() != 1u) { | 154 if (ccc_descriptor.size() != 1u) { |
| 168 LOG(ERROR) << "Found " << ccc_descriptor.size() | 155 LOG(ERROR) << "Found " << ccc_descriptor.size() |
| 169 << " client characteristic configuration descriptors."; | 156 << " client characteristic configuration descriptors."; |
| 170 base::MessageLoop::current()->PostTask( | 157 base::MessageLoop::current()->PostTask( |
| 171 FROM_HERE, | 158 FROM_HERE, |
| 172 base::Bind(error_callback, | 159 base::Bind(error_callback, |
| 173 (ccc_descriptor.size() == 0) | 160 (ccc_descriptor.size() == 0) |
| 174 ? BluetoothGattService::GATT_ERROR_NOT_SUPPORTED | 161 ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED |
| 175 : BluetoothGattService::GATT_ERROR_FAILED)); | 162 : BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
| 176 return; | 163 return; |
| 177 } | 164 } |
| 178 | 165 |
| 179 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( | 166 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio
n( |
| 180 AttachCurrentThread(), j_characteristic_.obj(), true)) { | 167 AttachCurrentThread(), j_characteristic_.obj(), true)) { |
| 181 LOG(ERROR) << "Error enabling characteristic notification"; | 168 LOG(ERROR) << "Error enabling characteristic notification"; |
| 182 base::MessageLoop::current()->PostTask( | 169 base::MessageLoop::current()->PostTask( |
| 183 FROM_HERE, | 170 FROM_HERE, base::Bind(error_callback, |
| 184 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 171 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
| 185 return; | 172 return; |
| 186 } | 173 } |
| 187 | 174 |
| 188 std::vector<uint8_t> value(2); | 175 std::vector<uint8_t> value(2); |
| 189 value[0] = hasNotify ? 1 : 2; | 176 value[0] = hasNotify ? 1 : 2; |
| 190 | 177 |
| 191 pending_start_notify_calls_.push_back( | 178 pending_start_notify_calls_.push_back( |
| 192 std::make_pair(callback, error_callback)); | 179 std::make_pair(callback, error_callback)); |
| 193 ccc_descriptor[0]->WriteRemoteDescriptor( | 180 ccc_descriptor[0]->WriteRemoteDescriptor( |
| 194 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: | 181 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid:: |
| 195 OnStartNotifySessionSuccess, | 182 OnStartNotifySessionSuccess, |
| 196 base::Unretained(this)), | 183 base::Unretained(this)), |
| 197 base::Bind( | 184 base::Bind( |
| 198 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, | 185 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError, |
| 199 base::Unretained(this))); | 186 base::Unretained(this))); |
| 200 } | 187 } |
| 201 | 188 |
| 202 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( | 189 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( |
| 203 const ValueCallback& callback, | 190 const ValueCallback& callback, |
| 204 const ErrorCallback& error_callback) { | 191 const ErrorCallback& error_callback) { |
| 205 if (read_pending_ || write_pending_) { | 192 if (read_pending_ || write_pending_) { |
| 206 base::MessageLoop::current()->PostTask( | 193 base::MessageLoop::current()->PostTask( |
| 207 FROM_HERE, base::Bind(error_callback, | 194 FROM_HERE, |
| 208 BluetoothGattService::GATT_ERROR_IN_PROGRESS)); | 195 base::Bind(error_callback, |
| 196 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 209 return; | 197 return; |
| 210 } | 198 } |
| 211 | 199 |
| 212 if (!Java_ChromeBluetoothRemoteGattCharacteristic_readRemoteCharacteristic( | 200 if (!Java_ChromeBluetoothRemoteGattCharacteristic_readRemoteCharacteristic( |
| 213 AttachCurrentThread(), j_characteristic_.obj())) { | 201 AttachCurrentThread(), j_characteristic_.obj())) { |
| 214 base::MessageLoop::current()->PostTask( | 202 base::MessageLoop::current()->PostTask( |
| 215 FROM_HERE, | 203 FROM_HERE, base::Bind(error_callback, |
| 216 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 204 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
| 217 return; | 205 return; |
| 218 } | 206 } |
| 219 | 207 |
| 220 read_pending_ = true; | 208 read_pending_ = true; |
| 221 read_callback_ = callback; | 209 read_callback_ = callback; |
| 222 read_error_callback_ = error_callback; | 210 read_error_callback_ = error_callback; |
| 223 } | 211 } |
| 224 | 212 |
| 225 void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic( | 213 void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic( |
| 226 const std::vector<uint8_t>& new_value, | 214 const std::vector<uint8_t>& new_value, |
| 227 const base::Closure& callback, | 215 const base::Closure& callback, |
| 228 const ErrorCallback& error_callback) { | 216 const ErrorCallback& error_callback) { |
| 229 if (read_pending_ || write_pending_) { | 217 if (read_pending_ || write_pending_) { |
| 230 base::MessageLoop::current()->PostTask( | 218 base::MessageLoop::current()->PostTask( |
| 231 FROM_HERE, base::Bind(error_callback, | 219 FROM_HERE, |
| 232 BluetoothGattService::GATT_ERROR_IN_PROGRESS)); | 220 base::Bind(error_callback, |
| 221 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 233 return; | 222 return; |
| 234 } | 223 } |
| 235 | 224 |
| 236 JNIEnv* env = AttachCurrentThread(); | 225 JNIEnv* env = AttachCurrentThread(); |
| 237 if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic( | 226 if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic( |
| 238 env, j_characteristic_.obj(), | 227 env, j_characteristic_.obj(), |
| 239 base::android::ToJavaByteArray(env, new_value).obj())) { | 228 base::android::ToJavaByteArray(env, new_value).obj())) { |
| 240 base::MessageLoop::current()->PostTask( | 229 base::MessageLoop::current()->PostTask( |
| 241 FROM_HERE, | 230 FROM_HERE, base::Bind(error_callback, |
| 242 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 231 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
| 243 return; | 232 return; |
| 244 } | 233 } |
| 245 | 234 |
| 246 write_pending_ = true; | 235 write_pending_ = true; |
| 247 write_callback_ = callback; | 236 write_callback_ = callback; |
| 248 write_error_callback_ = error_callback; | 237 write_error_callback_ = error_callback; |
| 249 } | 238 } |
| 250 | 239 |
| 251 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( | 240 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( |
| 252 JNIEnv* env, | 241 JNIEnv* env, |
| 253 const JavaParamRef<jobject>& jcaller, | 242 const JavaParamRef<jobject>& jcaller, |
| 254 const JavaParamRef<jbyteArray>& value) { | 243 const JavaParamRef<jbyteArray>& value) { |
| 255 base::android::JavaByteArrayToByteVector(env, value, &value_); | 244 base::android::JavaByteArrayToByteVector(env, value, &value_); |
| 256 adapter_->NotifyGattCharacteristicValueChanged(this, value_); | 245 adapter_->NotifyGattCharacteristicValueChanged(this, value_); |
| 257 } | 246 } |
| 258 | 247 |
| 259 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { | 248 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() { |
| 260 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; | 249 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 261 reentrant_safe_callbacks.swap(pending_start_notify_calls_); | 250 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 262 | 251 |
| 263 for (const auto& callback_pair : reentrant_safe_callbacks) { | 252 for (const auto& callback_pair : reentrant_safe_callbacks) { |
| 264 std::unique_ptr<device::BluetoothGattNotifySession> notify_session( | 253 std::unique_ptr<device::BluetoothGattNotifySession> notify_session( |
| 265 new BluetoothGattNotifySessionAndroid(instance_id_)); | 254 new BluetoothGattNotifySessionAndroid(instance_id_)); |
| 266 callback_pair.first.Run(std::move(notify_session)); | 255 callback_pair.first.Run(std::move(notify_session)); |
| 267 } | 256 } |
| 268 } | 257 } |
| 269 | 258 |
| 270 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( | 259 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError( |
| 271 BluetoothGattService::GattErrorCode error) { | 260 BluetoothRemoteGattService::GattErrorCode error) { |
| 272 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; | 261 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks; |
| 273 reentrant_safe_callbacks.swap(pending_start_notify_calls_); | 262 reentrant_safe_callbacks.swap(pending_start_notify_calls_); |
| 274 | 263 |
| 275 for (auto const& callback_pair : reentrant_safe_callbacks) { | 264 for (auto const& callback_pair : reentrant_safe_callbacks) { |
| 276 callback_pair.second.Run(error); | 265 callback_pair.second.Run(error); |
| 277 } | 266 } |
| 278 } | 267 } |
| 279 | 268 |
| 280 void BluetoothRemoteGattCharacteristicAndroid::OnRead( | 269 void BluetoothRemoteGattCharacteristicAndroid::OnRead( |
| 281 JNIEnv* env, | 270 JNIEnv* env, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() | 341 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() |
| 353 const { | 342 const { |
| 354 if (!descriptors_.empty()) | 343 if (!descriptors_.empty()) |
| 355 return; | 344 return; |
| 356 | 345 |
| 357 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( | 346 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( |
| 358 AttachCurrentThread(), j_characteristic_.obj()); | 347 AttachCurrentThread(), j_characteristic_.obj()); |
| 359 } | 348 } |
| 360 | 349 |
| 361 } // namespace device | 350 } // namespace device |
| OLD | NEW |