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

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: Make the rest of the methods in BluetoothGattNotifySession virtual 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 23
25 namespace device { 24 namespace device {
26 25
27 // static 26 // static
28 std::unique_ptr<BluetoothRemoteGattCharacteristicAndroid> 27 std::unique_ptr<BluetoothRemoteGattCharacteristicAndroid>
(...skipping 16 matching lines...) Expand all
45 base::android::ConvertUTF8ToJavaString(env, instance_id).obj(), 44 base::android::ConvertUTF8ToJavaString(env, instance_id).obj(),
46 chrome_bluetooth_device)); 45 chrome_bluetooth_device));
47 46
48 return characteristic; 47 return characteristic;
49 } 48 }
50 49
51 BluetoothRemoteGattCharacteristicAndroid:: 50 BluetoothRemoteGattCharacteristicAndroid::
52 ~BluetoothRemoteGattCharacteristicAndroid() { 51 ~BluetoothRemoteGattCharacteristicAndroid() {
53 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist icAndroidDestruction( 52 Java_ChromeBluetoothRemoteGattCharacteristic_onBluetoothRemoteGattCharacterist icAndroidDestruction(
54 AttachCurrentThread(), j_characteristic_.obj()); 53 AttachCurrentThread(), j_characteristic_.obj());
55
56 if (pending_start_notify_calls_.size()) {
57 OnStartNotifySessionError(
58 device::BluetoothRemoteGattService::GATT_ERROR_FAILED);
59 }
60 } 54 }
61 55
62 // static 56 // static
63 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) { 57 bool BluetoothRemoteGattCharacteristicAndroid::RegisterJNI(JNIEnv* env) {
64 return RegisterNativesImpl( 58 return RegisterNativesImpl(
65 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h 59 env); // Generated in ChromeBluetoothRemoteGattCharacteristic_jni.h
66 } 60 }
67 61
68 base::android::ScopedJavaLocalRef<jobject> 62 base::android::ScopedJavaLocalRef<jobject>
69 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() { 63 BluetoothRemoteGattCharacteristicAndroid::GetJavaObject() {
(...skipping 25 matching lines...) Expand all
95 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties( 89 return Java_ChromeBluetoothRemoteGattCharacteristic_getProperties(
96 AttachCurrentThread(), j_characteristic_.obj()); 90 AttachCurrentThread(), j_characteristic_.obj());
97 } 91 }
98 92
99 BluetoothRemoteGattCharacteristic::Permissions 93 BluetoothRemoteGattCharacteristic::Permissions
100 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const { 94 BluetoothRemoteGattCharacteristicAndroid::GetPermissions() const {
101 NOTIMPLEMENTED(); 95 NOTIMPLEMENTED();
102 return 0; 96 return 0;
103 } 97 }
104 98
105 bool BluetoothRemoteGattCharacteristicAndroid::IsNotifying() const {
106 NOTIMPLEMENTED();
107 return false;
108 }
109
110 std::vector<BluetoothRemoteGattDescriptor*> 99 std::vector<BluetoothRemoteGattDescriptor*>
111 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const { 100 BluetoothRemoteGattCharacteristicAndroid::GetDescriptors() const {
112 EnsureDescriptorsCreated(); 101 EnsureDescriptorsCreated();
113 std::vector<BluetoothRemoteGattDescriptor*> descriptors; 102 std::vector<BluetoothRemoteGattDescriptor*> descriptors;
114 for (const auto& map_iter : descriptors_) 103 for (const auto& map_iter : descriptors_)
115 descriptors.push_back(map_iter.second); 104 descriptors.push_back(map_iter.second);
116 return descriptors; 105 return descriptors;
117 } 106 }
118 107
119 BluetoothRemoteGattDescriptor* 108 BluetoothRemoteGattDescriptor*
120 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor( 109 BluetoothRemoteGattCharacteristicAndroid::GetDescriptor(
121 const std::string& identifier) const { 110 const std::string& identifier) const {
122 EnsureDescriptorsCreated(); 111 EnsureDescriptorsCreated();
123 const auto& iter = descriptors_.find(identifier); 112 const auto& iter = descriptors_.find(identifier);
124 if (iter == descriptors_.end()) 113 if (iter == descriptors_.end())
125 return nullptr; 114 return nullptr;
126 return iter->second; 115 return iter->second;
127 } 116 }
128 117
129 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession(
130 const NotifySessionCallback& callback,
131 const ErrorCallback& error_callback) {
132 if (!pending_start_notify_calls_.empty()) {
133 pending_start_notify_calls_.push_back(
134 std::make_pair(callback, error_callback));
135 return;
136 }
137
138 Properties properties = GetProperties();
139
140 bool hasNotify = properties & PROPERTY_NOTIFY;
141 bool hasIndicate = properties & PROPERTY_INDICATE;
142
143 if (!hasNotify && !hasIndicate) {
144 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE";
145 base::ThreadTaskRunnerHandle::Get()->PostTask(
146 FROM_HERE,
147 base::Bind(error_callback,
148 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED));
149 return;
150 }
151
152 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor =
153 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
154 ClientCharacteristicConfigurationUuid());
155
156 if (ccc_descriptor.size() != 1u) {
157 LOG(ERROR) << "Found " << ccc_descriptor.size()
158 << " client characteristic configuration descriptors.";
159 base::ThreadTaskRunnerHandle::Get()->PostTask(
160 FROM_HERE,
161 base::Bind(error_callback,
162 (ccc_descriptor.size() == 0)
163 ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED
164 : BluetoothRemoteGattService::GATT_ERROR_FAILED));
165 return;
166 }
167
168 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
169 AttachCurrentThread(), j_characteristic_.obj(), true)) {
170 LOG(ERROR) << "Error enabling characteristic notification";
171 base::ThreadTaskRunnerHandle::Get()->PostTask(
172 FROM_HERE, base::Bind(error_callback,
173 BluetoothRemoteGattService::GATT_ERROR_FAILED));
174 return;
175 }
176
177 std::vector<uint8_t> value(2);
178 value[0] = hasNotify ? 1 : 2;
179
180 pending_start_notify_calls_.push_back(
181 std::make_pair(callback, error_callback));
182 ccc_descriptor[0]->WriteRemoteDescriptor(
183 value, base::Bind(&BluetoothRemoteGattCharacteristicAndroid::
184 OnStartNotifySessionSuccess,
185 base::Unretained(this)),
186 base::Bind(
187 &BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError,
188 base::Unretained(this)));
189 }
190
191 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( 118 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
192 const ValueCallback& callback, 119 const ValueCallback& callback,
193 const ErrorCallback& error_callback) { 120 const ErrorCallback& error_callback) {
194 if (read_pending_ || write_pending_) { 121 if (read_pending_ || write_pending_) {
195 base::ThreadTaskRunnerHandle::Get()->PostTask( 122 base::ThreadTaskRunnerHandle::Get()->PostTask(
196 FROM_HERE, 123 FROM_HERE,
197 base::Bind(error_callback, 124 base::Bind(error_callback,
198 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); 125 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
199 return; 126 return;
200 } 127 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 167 }
241 168
242 void BluetoothRemoteGattCharacteristicAndroid::OnChanged( 169 void BluetoothRemoteGattCharacteristicAndroid::OnChanged(
243 JNIEnv* env, 170 JNIEnv* env,
244 const JavaParamRef<jobject>& jcaller, 171 const JavaParamRef<jobject>& jcaller,
245 const JavaParamRef<jbyteArray>& value) { 172 const JavaParamRef<jbyteArray>& value) {
246 base::android::JavaByteArrayToByteVector(env, value, &value_); 173 base::android::JavaByteArrayToByteVector(env, value, &value_);
247 adapter_->NotifyGattCharacteristicValueChanged(this, value_); 174 adapter_->NotifyGattCharacteristicValueChanged(this, value_);
248 } 175 }
249 176
250 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionSuccess() {
251 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks;
252 reentrant_safe_callbacks.swap(pending_start_notify_calls_);
253
254 for (const auto& callback_pair : reentrant_safe_callbacks) {
255 std::unique_ptr<device::BluetoothGattNotifySession> notify_session(
256 new BluetoothGattNotifySessionAndroid(instance_id_));
257 callback_pair.first.Run(std::move(notify_session));
258 }
259 }
260
261 void BluetoothRemoteGattCharacteristicAndroid::OnStartNotifySessionError(
262 BluetoothRemoteGattService::GattErrorCode error) {
263 std::vector<PendingStartNotifyCall> reentrant_safe_callbacks;
264 reentrant_safe_callbacks.swap(pending_start_notify_calls_);
265
266 for (auto const& callback_pair : reentrant_safe_callbacks) {
267 callback_pair.second.Run(error);
268 }
269 }
270
271 void BluetoothRemoteGattCharacteristicAndroid::OnRead( 177 void BluetoothRemoteGattCharacteristicAndroid::OnRead(
272 JNIEnv* env, 178 JNIEnv* env,
273 const JavaParamRef<jobject>& jcaller, 179 const JavaParamRef<jobject>& jcaller,
274 int32_t status, 180 int32_t status,
275 const JavaParamRef<jbyteArray>& value) { 181 const JavaParamRef<jbyteArray>& value) {
276 read_pending_ = false; 182 read_pending_ = false;
277 183
278 // Clear callbacks before calling to avoid reentrancy issues. 184 // Clear callbacks before calling to avoid reentrancy issues.
279 ValueCallback read_callback = read_callback_; 185 ValueCallback read_callback = read_callback_;
280 ErrorCallback read_error_callback = read_error_callback_; 186 ErrorCallback read_error_callback = read_error_callback_;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 base::android::ConvertJavaStringToUTF8(env, instanceId); 232 base::android::ConvertJavaStringToUTF8(env, instanceId);
327 233
328 DCHECK(!descriptors_.contains(instanceIdString)); 234 DCHECK(!descriptors_.contains(instanceIdString));
329 235
330 descriptors_.set(instanceIdString, 236 descriptors_.set(instanceIdString,
331 BluetoothRemoteGattDescriptorAndroid::Create( 237 BluetoothRemoteGattDescriptorAndroid::Create(
332 instanceIdString, bluetooth_gatt_descriptor_wrapper, 238 instanceIdString, bluetooth_gatt_descriptor_wrapper,
333 chrome_bluetooth_device)); 239 chrome_bluetooth_device));
334 } 240 }
335 241
242 void BluetoothRemoteGattCharacteristicAndroid::SubscribeToNotifications(
ortuno 2016/07/28 21:59:30 I would be OK with keeping this as NOTIMPLEMENTED
tommyt 2016/08/01 11:39:21 Would you also be OK with leaving it here? With my
243 const base::Closure& callback,
244 const ErrorCallback& error_callback) {
245 Properties properties = GetProperties();
246
247 bool hasNotify = properties & PROPERTY_NOTIFY;
248 bool hasIndicate = properties & PROPERTY_INDICATE;
249
250 if (!hasNotify && !hasIndicate) {
251 LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE";
252 base::ThreadTaskRunnerHandle::Get()->PostTask(
253 FROM_HERE,
254 base::Bind(error_callback,
255 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED));
256 return;
257 }
258
259 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor =
260 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
261 ClientCharacteristicConfigurationUuid());
262
263 if (ccc_descriptor.size() != 1u) {
ortuno 2016/07/28 21:59:30 I think we should move this to the cross platform
tommyt 2016/08/01 11:39:21 Done.
264 LOG(ERROR) << "Found " << ccc_descriptor.size()
265 << " client characteristic configuration descriptors.";
266 base::ThreadTaskRunnerHandle::Get()->PostTask(
267 FROM_HERE,
268 base::Bind(error_callback,
269 (ccc_descriptor.size() == 0)
270 ? BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED
271 : BluetoothRemoteGattService::GATT_ERROR_FAILED));
272 return;
273 }
274
275 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
276 AttachCurrentThread(), j_characteristic_.obj(), true)) {
277 LOG(ERROR) << "Error enabling characteristic notification";
278 base::ThreadTaskRunnerHandle::Get()->PostTask(
279 FROM_HERE, base::Bind(error_callback,
280 BluetoothRemoteGattService::GATT_ERROR_FAILED));
281 return;
282 }
283
284 std::vector<uint8_t> value(2);
ortuno 2016/07/28 21:59:30 optional nit: std::vector<uint8_t> value = hasNot
tommyt 2016/08/01 11:39:22 This doesn't seem to compile...
285 value[0] = hasNotify ? 1 : 2;
286
287 ccc_descriptor[0]->WriteRemoteDescriptor(value, callback, error_callback);
288 }
289
290 void BluetoothRemoteGattCharacteristicAndroid::UnsubscribeFromNotifications(
291 const base::Closure& callback,
292 const ErrorCallback& error_callback) {
293 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptor =
294 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor::
295 ClientCharacteristicConfigurationUuid());
296
297 if (ccc_descriptor.size() != 1u) {
298 LOG(ERROR) << "Found " << ccc_descriptor.size()
299 << " client characteristic configuration descriptors.";
300 base::ThreadTaskRunnerHandle::Get()->PostTask(
301 FROM_HERE,
302 base::Bind(error_callback,
303 device::BluetoothRemoteGattService::GATT_ERROR_FAILED));
304 return;
305 }
306
307 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
308 AttachCurrentThread(), j_characteristic_.obj(), false)) {
309 LOG(ERROR) << "Error disabling characteristic notification";
310 base::ThreadTaskRunnerHandle::Get()->PostTask(
311 FROM_HERE,
312 base::Bind(error_callback,
313 device::BluetoothRemoteGattService::GATT_ERROR_FAILED));
314 return;
315 }
316
317 std::vector<uint8_t> value(2);
318 value[0] = 0;
319
320 ccc_descriptor[0]->WriteRemoteDescriptor(value, callback, error_callback);
321 }
322
336 BluetoothRemoteGattCharacteristicAndroid:: 323 BluetoothRemoteGattCharacteristicAndroid::
337 BluetoothRemoteGattCharacteristicAndroid( 324 BluetoothRemoteGattCharacteristicAndroid(
338 BluetoothAdapterAndroid* adapter, 325 BluetoothAdapterAndroid* adapter,
339 BluetoothRemoteGattServiceAndroid* service, 326 BluetoothRemoteGattServiceAndroid* service,
340 const std::string& instance_id) 327 const std::string& instance_id)
341 : adapter_(adapter), service_(service), instance_id_(instance_id) {} 328 : adapter_(adapter), service_(service), instance_id_(instance_id) {}
342 329
343 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() 330 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated()
344 const { 331 const {
345 if (!descriptors_.empty()) 332 if (!descriptors_.empty())
346 return; 333 return;
347 334
348 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( 335 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors(
349 AttachCurrentThread(), j_characteristic_.obj()); 336 AttachCurrentThread(), j_characteristic_.obj());
350 } 337 }
351 338
352 } // namespace device 339 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698