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

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 Giovanni's 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 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(
243 BluetoothRemoteGattDescriptor* ccc_descriptor,
244 const base::Closure& callback,
245 const ErrorCallback& error_callback) {
246 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
247 AttachCurrentThread(), j_characteristic_.obj(), true)) {
248 LOG(ERROR) << "Error enabling characteristic notification";
249 base::ThreadTaskRunnerHandle::Get()->PostTask(
250 FROM_HERE, base::Bind(error_callback,
251 BluetoothRemoteGattService::GATT_ERROR_FAILED));
252 return;
253 }
254
255 bool hasNotify = GetProperties() & PROPERTY_NOTIFY;
256 std::vector<uint8_t> value(2);
257 value[0] = hasNotify ? 1 : 2;
258
259 ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback);
260 }
261
262 void BluetoothRemoteGattCharacteristicAndroid::UnsubscribeFromNotifications(
263 BluetoothRemoteGattDescriptor* ccc_descriptor,
264 const base::Closure& callback,
265 const ErrorCallback& error_callback) {
266 if (!Java_ChromeBluetoothRemoteGattCharacteristic_setCharacteristicNotificatio n(
267 AttachCurrentThread(), j_characteristic_.obj(), false)) {
268 LOG(ERROR) << "Error disabling characteristic notification";
269 base::ThreadTaskRunnerHandle::Get()->PostTask(
270 FROM_HERE,
271 base::Bind(error_callback,
272 device::BluetoothRemoteGattService::GATT_ERROR_FAILED));
273 return;
274 }
275
276 std::vector<uint8_t> value(2);
277 value[0] = 0;
278
279 ccc_descriptor->WriteRemoteDescriptor(value, callback, error_callback);
280 }
281
336 BluetoothRemoteGattCharacteristicAndroid:: 282 BluetoothRemoteGattCharacteristicAndroid::
337 BluetoothRemoteGattCharacteristicAndroid( 283 BluetoothRemoteGattCharacteristicAndroid(
338 BluetoothAdapterAndroid* adapter, 284 BluetoothAdapterAndroid* adapter,
339 BluetoothRemoteGattServiceAndroid* service, 285 BluetoothRemoteGattServiceAndroid* service,
340 const std::string& instance_id) 286 const std::string& instance_id)
341 : adapter_(adapter), service_(service), instance_id_(instance_id) {} 287 : adapter_(adapter), service_(service), instance_id_(instance_id) {}
342 288
343 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated() 289 void BluetoothRemoteGattCharacteristicAndroid::EnsureDescriptorsCreated()
344 const { 290 const {
345 if (!descriptors_.empty()) 291 if (!descriptors_.empty())
346 return; 292 return;
347 293
348 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors( 294 Java_ChromeBluetoothRemoteGattCharacteristic_createDescriptors(
349 AttachCurrentThread(), j_characteristic_.obj()); 295 AttachCurrentThread(), j_characteristic_.obj());
350 } 296 }
351 297
352 } // namespace device 298 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698