Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc

Issue 2051333004: Implement BluetoothGattNotifySession::Stop on Android, 2nd attempt (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address new review comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/android/jni_string.h" 11 #include "base/android/jni_string.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "device/bluetooth/bluetooth_adapter_android.h" 17 #include "device/bluetooth/bluetooth_adapter_android.h"
18 #include "device/bluetooth/bluetooth_gatt_notify_session_android.h"
19 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_android.h" 18 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_android.h"
20 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h" 19 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
21 #include "jni/ChromeBluetoothRemoteGattCharacteristic_jni.h" 20 #include "jni/ChromeBluetoothRemoteGattCharacteristic_jni.h"
22 21
23 using base::android::AttachCurrentThread; 22 using base::android::AttachCurrentThread;
24 using base::android::JavaParamRef; 23 using base::android::JavaParamRef;
25 24
26 namespace device { 25 namespace device {
27 26
28 // static 27 // static
(...skipping 17 matching lines...) Expand all
46 base::android::ConvertUTF8ToJavaString(env, instance_id), 45 base::android::ConvertUTF8ToJavaString(env, instance_id),
47 chrome_bluetooth_device)); 46 chrome_bluetooth_device));
48 47
49 return characteristic; 48 return characteristic;
50 } 49 }
51 50
52 BluetoothRemoteGattCharacteristicAndroid:: 51 BluetoothRemoteGattCharacteristicAndroid::
53 ~BluetoothRemoteGattCharacteristicAndroid() { 52 ~BluetoothRemoteGattCharacteristicAndroid() {
54 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist icAndroidDestruction( 53 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist icAndroidDestruction(
55 AttachCurrentThread(), j_characteristic_); 54 AttachCurrentThread(), j_characteristic_);
56
57 if (pending_start_notify_calls_.size()) {
58 OnStartNotifySessionError(
59 device::BluetoothRemoteGattService::GATT_ERROR_FAILED);
60 }
61 } 55 }
62 56
63 // static 57 // static
64 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { 58 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) {
65 return RegisterNativesImpl( 59 return RegisterNativesImpl(
66 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h 60 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h
67 } 61 }
68 62
69 base::android::ScopedJavaLocalRef<jobject> 63 base::android::ScopedJavaLocalRef<jobject>
70 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { 64 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() {
(...skipping 25 matching lines...) Expand all
96 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( 90 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties(
97 AttachCurrentThread(), j_characteristic_); 91 AttachCurrentThread(), j_characteristic_);
98 } 92 }
99 93
100 BluetoothRemoteGattCharacteristic::Permissions 94 BluetoothRemoteGattCharacteristic::Permissions
101 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { 95 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const {
102 NOTIMPLEMENTED(); 96 NOTIMPLEMENTED();
103 return 0; 97 return 0;
104 } 98 }
105 99
106 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const {
107 NOTIMPLEMENTED();
108 return false;
109 }
110
111 std::vector<BluetoothRemoteGattDescriptor*> 100 std::vector<BluetoothRemoteGattDescriptor*>
112 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { 101 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const {
113 EnsureDescriptorsCreated(); 102 EnsureDescriptorsCreated();
114 std::vector<BluetoothRemoteGattDescriptor*> descriptors; 103 std::vector<BluetoothRemoteGattDescriptor*> descriptors;
115 for (const auto& map_iter : descriptors_) 104 for (const auto& map_iter : descriptors_)
116 descriptors.push_back(map_iter.second); 105 descriptors.push_back(map_iter.second);
117 return descriptors; 106 return descriptors;
118 } 107 }
119 108
120 BluetoothRemoteGattDescriptor* 109 BluetoothRemoteGattDescriptor*
121 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( 110 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor(
122 const std::string& identifier) const { 111 const std::string& identifier) const {
123 EnsureDescriptorsCreated(); 112 EnsureDescriptorsCreated();
124 const auto& iter = descriptors_.find(identifier); 113 const auto& iter = descriptors_.find(identifier);
125 if (iter == descriptors_.end()) 114 if (iter == descriptors_.end())
126 return nullptr; 115 return nullptr;
127 return iter->second; 116 return iter->second;
128 } 117 }
129 118
130 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession(
131 const NotifySessionCallback& callback,
132 const ErrorCallback& error_callback) {
133 if (!pending_start_notify_calls_.empty()) {
134 pending_start_notify_calls_.push_back(
135 std::make_pair(callback, error_callback));
136 return;
137 }
138
139 Properties properties = GetProperties();
140
141 bool hasNotify = properties & PROPERTY_NOTIFY;
142 bool hasIndicate = properties & PROPERTY_INDICATE;
143
144 if (!hasNotify && !hasIndicate) {
145 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE";
146 base::ThreadTaskRunnerHandle::Get()->PostTask(
147 FROM_HERE,
148 base::Bind(error_callback,
149 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED));
150 return;
151 }
152
153 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor =
154 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
155 ClientCharacteristicConfigurationUuid());
156
157 if (ccc_descriptor.size() != 1u) {
158 LOG(ERROR) << "Found " << ccc_descriptor.size()
159 << " client characteristic configuration descriptors.";
160 base::ThreadTaskRunnerHandle::Get()->PostTask(
161 FROM_HERE,
162 base::Bind(error_callback,
163 (ccc_descriptor.size() == 0)
164 ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED
165 : BluetoothRemoteGattService::GATT_ERROR_FAILED));
166 return;
167 }
168
169 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
170 AttachCurrentThread(), j_characteristic_, true)) {
171 LOG(ERROR) << "Error enabling characteristic notification";
172 base::ThreadTaskRunnerHandle::Get()->PostTask(
173 FROM_HERE, base::Bind(error_callback,
174 BluetoothRemoteGattService::GATT_ERROR_FAILED));
175 return;
176 }
177
178 std::vector<uint8_t> value(2);
179 value[0] = hasNotify ? 1 : 2;
180
181 pending_start_notify_calls_.push_back(
182 std::make_pair(callback, error_callback));
183 ccc_descriptor[0]->WriteRemoteDescriptor(
184 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid::
185 OnStartNotifySessionSuccess,
186 base::Unretained(this)),
187 base::Bind(
188 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError,
189 base::Unretained(this)));
190 }
191
192 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( 119 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
193 const ValueCallback& callback, 120 const ValueCallback& callback,
194 const ErrorCallback& error_callback) { 121 const ErrorCallback& error_callback) {
195 if (read_pending_ || write_pending_) { 122 if (read_pending_ || write_pending_) {
196 base::ThreadTaskRunnerHandle::Get()->PostTask( 123 base::ThreadTaskRunnerHandle::Get()->PostTask(
197 FROM_HERE, 124 FROM_HERE,
198 base::Bind(error_callback, 125 base::Bind(error_callback,
199 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); 126 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
200 return; 127 return;
201 } 128 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } 168 }
242 169
243 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( 170 void BluetoothRemoteGattCharacteristicAndroid::OnChanged(
244 JNIEnv* env, 171 JNIEnv* env,
245 const JavaParamRef<jobject>& jcaller, 172 const JavaParamRef<jobject>& jcaller,
246 const JavaParamRef<jbyteArray>& value) { 173 const JavaParamRef<jbyteArray>& value) {
247 base::android::JavaByteArrayToByteVector(env, value, &value_); 174 base::android::JavaByteArrayToByteVector(env, value, &value_);
248 adapter_->NotifyGattCharacteristicValueChanged(this, value_); 175 adapter_->NotifyGattCharacteristicValueChanged(this, value_);
249 } 176 }
250 177
251 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() {
252 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks;
253 reentrant_safe_callbacks.swap(pending_start_notify_calls_);
254
255 for (const auto& callback_pair : reentrant_safe_callbacks) {
256 std::unique_ptr<device::BluetoothGattNotifySession> notify_session(
257 new BluetoothGattNotifySessionAndroid(instance_id_));
258 callback_pair.first.Run(std::move(notify_session));
259 }
260 }
261
262 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError(
263 BluetoothRemoteGattService::GattErrorCode error) {
264 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks;
265 reentrant_safe_callbacks.swap(pending_start_notify_calls_);
266
267 for (auto const& callback_pair : reentrant_safe_callbacks) {
268 callback_pair.second.Run(error);
269 }
270 }
271
272 void BluetoothRemoteGattCharacteristicAndroid::OnRead( 178 void BluetoothRemoteGattCharacteristicAndroid::OnRead(
273 JNIEnv* env, 179 JNIEnv* env,
274 const JavaParamRef<jobject>& jcaller, 180 const JavaParamRef<jobject>& jcaller,
275 int32_t status, 181 int32_t status,
276 const JavaParamRef<jbyteArray>& value) { 182 const JavaParamRef<jbyteArray>& value) {
277 read_pending_ = false; 183 read_pending_ = false;
278 184
279 // Clear callbacks before calling to avoid reentrancy issues. 185 // Clear callbacks before calling to avoid reentrancy issues.
280 ValueCallback read_callback = read_callback_; 186 ValueCallback read_callback = read_callback_;
281 ErrorCallback read_error_callback = read_error_callback_; 187 ErrorCallback read_error_callback = read_error_callback_;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 base::android::ConvertJavaStringToUTF8(env, instanceId); 233 base::android::ConvertJavaStringToUTF8(env, instanceId);
328 234
329 DCHECK(!descriptors_.contains(instanceIdString)); 235 DCHECK(!descriptors_.contains(instanceIdString));
330 236
331 descriptors_.set(instanceIdString, 237 descriptors_.set(instanceIdString,
332 BluetoothRemoteGattDescriptorAndroid::Create( 238 BluetoothRemoteGattDescriptorAndroid::Create(
333 instanceIdString, bluetooth_gatt_descriptor_wrapper, 239 instanceIdString, bluetooth_gatt_descriptor_wrapper,
334 chrome_bluetooth_device)); 240 chrome_bluetooth_device));
335 } 241 }
336 242
243 void BluetoothRemoteGattCharacteristicAndroid::SubscribeToNotifications(
244 BluetoothRemoteGattDescriptor* ccc_descriptor,
245 const base::Closure& callback,
246 const ErrorCallback& error_callback) {
247 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
248 AttachCurrentThread(), j_characteristic_.obj(), true)) {
249 LOG(ERROR) << "Error enabling characteristic notification";
250 base::ThreadTaskRunnerHandle::Get()->PostTask(
251 FROM_HERE, base::Bind(error_callback,
252 BluetoothRemoteGattService::GATT_ERROR_FAILED));
253 return;
254 }
255
256 bool hasNotify = GetProperties() & PROPERTY_NOTIFY;
257 std::vector<uint8_t> value(2);
258 value[0] = hasNotify ? 1 : 2;
259
260 ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback);
261 }
262
263 void BluetoothRemoteGattCharacteristicAndroid::UnsubscribeFromNotifications(
264 BluetoothRemoteGattDescriptor* ccc_descriptor,
265 const base::Closure& callback,
266 const ErrorCallback& error_callback) {
267 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
268 AttachCurrentThread(), j_characteristic_.obj(), false)) {
269 LOG(ERROR) << "Error disabling characteristic notification";
270 base::ThreadTaskRunnerHandle::Get()->PostTask(
271 FROM_HERE,
272 base::Bind(error_callback,
273 device::BluetoothRemoteGattService::GATT_ERROR_FAILED));
274 return;
275 }
276
277 std::vector<uint8_t> value(2);
278 value[0] = 0;
279
280 ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback);
281 }
282
337 BluetoothRemoteGattCharacteristicAndroid:: 283 BluetoothRemoteGattCharacteristicAndroid::
338 BluetoothRemoteGattCharacteristicAndroid( 284 BluetoothRemoteGattCharacteristicAndroid(
339 BluetoothAdapterAndroid* adapter, 285 BluetoothAdapterAndroid* adapter,
340 BluetoothRemoteGattServiceAndroid* service, 286 BluetoothRemoteGattServiceAndroid* service,
341 const std::string& instance_id) 287 const std::string& instance_id)
342 : adapter_(adapter), service_(service), instance_id_(instance_id) {} 288 : adapter_(adapter), service_(service), instance_id_(instance_id) {}
343 289
344 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() 290 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated()
345 const { 291 const {
346 if (!descriptors_.empty()) 292 if (!descriptors_.empty())
347 return; 293 return;
348 294
349 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( 295 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors(
350 AttachCurrentThread(), j_characteristic_); 296 AttachCurrentThread(), j_characteristic_);
351 } 297 }
352 298
353 } // namespace device 299 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698