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

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

Issue 1842223003: Remove outdated devices from Android device chooser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't purge devices continuously. Added more tests. Created 4 years, 6 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_adapter_android.h" 5 #include "device/bluetooth/bluetooth_adapter_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_string.h" 10 #include "base/android/jni_string.h"
11 #include "base/bind.h"
12 #include "base/location.h"
11 #include "base/sequenced_task_runner.h" 13 #include "base/sequenced_task_runner.h"
12 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
14 #include "device/bluetooth/android/wrappers.h" 16 #include "device/bluetooth/android/wrappers.h"
15 #include "device/bluetooth/bluetooth_advertisement.h" 17 #include "device/bluetooth/bluetooth_advertisement.h"
16 #include "device/bluetooth/bluetooth_device_android.h" 18 #include "device/bluetooth/bluetooth_device_android.h"
17 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" 19 #include "device/bluetooth/bluetooth_discovery_session_outcome.h"
18 #include "jni/ChromeBluetoothAdapter_jni.h" 20 #include "jni/ChromeBluetoothAdapter_jni.h"
19 21
20 using base::android::AttachCurrentThread; 22 using base::android::AttachCurrentThread;
21 using base::android::ConvertJavaStringToUTF8; 23 using base::android::ConvertJavaStringToUTF8;
22 24
25 namespace {
26 // The poll interval in ms when there is no active discovery. This
27 // matches the max allowed advertisting interval for connectable
28 // devices.
29 enum { kPassivePollInterval = 11000 };
30 // The poll interval in ms when there is an active discovery.
31 enum { kActivePollInterval = 1000 };
32 }
33
23 namespace device { 34 namespace device {
24 35
25 // static 36 // static
26 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( 37 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
27 const InitCallback& init_callback) { 38 const InitCallback& init_callback) {
28 return BluetoothAdapterAndroid::Create( 39 return BluetoothAdapterAndroid::Create(
29 BluetoothAdapterWrapper_CreateWithDefaultAdapter().obj()); 40 BluetoothAdapterWrapper_CreateWithDefaultAdapter().obj());
30 } 41 }
31 42
32 // static 43 // static
33 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create( 44 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create(
34 jobject bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper 45 jobject bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper
35 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); 46 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid();
36 47
37 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( 48 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create(
38 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter), 49 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter),
39 bluetooth_adapter_wrapper)); 50 bluetooth_adapter_wrapper));
40 51
52 adapter->ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
53
41 return adapter->weak_ptr_factory_.GetWeakPtr(); 54 return adapter->weak_ptr_factory_.GetWeakPtr();
42 } 55 }
43 56
44 // static 57 // static
45 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { 58 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) {
46 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h 59 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h
47 } 60 }
48 61
49 std::string BluetoothAdapterAndroid::GetAddress() const { 62 std::string BluetoothAdapterAndroid::GetAddress() const {
50 return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getAddress( 63 return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getAddress(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 void BluetoothAdapterAndroid::OnAdapterStateChanged( 162 void BluetoothAdapterAndroid::OnAdapterStateChanged(
150 JNIEnv* env, 163 JNIEnv* env,
151 const JavaParamRef<jobject>& caller, 164 const JavaParamRef<jobject>& caller,
152 const bool powered) { 165 const bool powered) {
153 NotifyAdapterPoweredChanged(powered); 166 NotifyAdapterPoweredChanged(powered);
154 } 167 }
155 168
156 void BluetoothAdapterAndroid::OnScanFailed( 169 void BluetoothAdapterAndroid::OnScanFailed(
157 JNIEnv* env, 170 JNIEnv* env,
158 const JavaParamRef<jobject>& caller) { 171 const JavaParamRef<jobject>& caller) {
172 numDiscoverySessions = 0;
159 MarkDiscoverySessionsAsInactive(); 173 MarkDiscoverySessionsAsInactive();
160 } 174 }
161 175
162 void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan( 176 void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan(
163 JNIEnv* env, 177 JNIEnv* env,
164 const JavaParamRef<jobject>& caller, 178 const JavaParamRef<jobject>& caller,
165 const JavaParamRef<jstring>& address, 179 const JavaParamRef<jstring>& address,
166 const JavaParamRef<jobject>& 180 const JavaParamRef<jobject>&
167 bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper 181 bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper
168 const JavaParamRef<jobject>& 182 const JavaParamRef<jobject>&
169 advertised_uuids) { // Java Type: List<ParcelUuid> 183 advertised_uuids) { // Java Type: List<ParcelUuid>
170 std::string device_address = ConvertJavaStringToUTF8(env, address); 184 std::string device_address = ConvertJavaStringToUTF8(env, address);
171 DevicesMap::const_iterator iter = devices_.find(device_address); 185 DevicesMap::const_iterator iter = devices_.find(device_address);
172 186
173 if (iter == devices_.end()) { 187 if (iter == devices_.end()) {
174 // New device. 188 // New device.
175 BluetoothDeviceAndroid* device_android = 189 BluetoothDeviceAndroid* device_android =
176 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper); 190 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper);
177 device_android->UpdateAdvertisedUUIDs(advertised_uuids); 191 device_android->UpdateAdvertisedUUIDs(advertised_uuids);
192 device_android->UpdateTimestamp();
178 devices_.add(device_address, 193 devices_.add(device_address,
179 std::unique_ptr<BluetoothDevice>(device_android)); 194 std::unique_ptr<BluetoothDevice>(device_android));
180 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 195 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
181 DeviceAdded(this, device_android)); 196 DeviceAdded(this, device_android));
182 } else { 197 } else {
183 // Existing device. 198 // Existing device.
184 BluetoothDeviceAndroid* device_android = 199 BluetoothDeviceAndroid* device_android =
185 static_cast<BluetoothDeviceAndroid*>(iter->second); 200 static_cast<BluetoothDeviceAndroid*>(iter->second);
201 device_android->UpdateTimestamp();
186 if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) { 202 if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) {
187 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 203 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
188 DeviceChanged(this, device_android)); 204 DeviceChanged(this, device_android));
189 } 205 }
190 } 206 }
191 } 207 }
192 208
193 BluetoothAdapterAndroid::BluetoothAdapterAndroid() : weak_ptr_factory_(this) { 209 BluetoothAdapterAndroid::BluetoothAdapterAndroid() : weak_ptr_factory_(this) {
194 } 210 }
195 211
196 BluetoothAdapterAndroid::~BluetoothAdapterAndroid() { 212 BluetoothAdapterAndroid::~BluetoothAdapterAndroid() {
197 Java_ChromeBluetoothAdapter_onBluetoothAdapterAndroidDestruction( 213 Java_ChromeBluetoothAdapter_onBluetoothAdapterAndroidDestruction(
198 AttachCurrentThread(), j_adapter_.obj()); 214 AttachCurrentThread(), j_adapter_.obj());
199 } 215 }
200 216
217 void BluetoothAdapterAndroid::PurgeTimedOutDevices() {
ortuno 2016/06/15 17:20:16 I'm wondering if we should post a delayed task to
perja 2016/06/17 13:39:27 Not sure I see why. It will be kept or purged duri
218 if (IsDiscovering()) {
219 RemoveTimedOutDevices();
220 ui_task_runner_->PostDelayedTask(
221 FROM_HERE, base::Bind(&BluetoothAdapterAndroid::PurgeTimedOutDevices,
222 weak_ptr_factory_.GetWeakPtr()),
223 base::TimeDelta::FromMilliseconds(kActivePollInterval));
224 } else {
225 ui_task_runner_->PostDelayedTask(
226 FROM_HERE, base::Bind(&BluetoothAdapterAndroid::RemoveTimedOutDevices,
227 weak_ptr_factory_.GetWeakPtr()),
228 base::TimeDelta::FromMilliseconds(kPassivePollInterval));
229 }
230 }
231
201 void BluetoothAdapterAndroid::AddDiscoverySession( 232 void BluetoothAdapterAndroid::AddDiscoverySession(
202 BluetoothDiscoveryFilter* discovery_filter, 233 BluetoothDiscoveryFilter* discovery_filter,
203 const base::Closure& callback, 234 const base::Closure& callback,
204 const DiscoverySessionErrorCallback& error_callback) { 235 const DiscoverySessionErrorCallback& error_callback) {
205 // TODO(scheib): Support filters crbug.com/490401 236 // TODO(scheib): Support filters crbug.com/490401
206 if (Java_ChromeBluetoothAdapter_addDiscoverySession(AttachCurrentThread(), 237 if (AddDiscoverySessionInternal()) {
207 j_adapter_.obj())) {
208 callback.Run(); 238 callback.Run();
209 } else { 239 } else {
210 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. 240 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here.
211 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); 241 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN);
212 } 242 }
213 } 243 }
214 244
245 bool BluetoothAdapterAndroid::AddDiscoverySessionInternal() {
ortuno 2016/06/15 17:20:16 optional: I think this could be moved to AddDiscov
perja 2016/06/17 13:39:27 Done.
246 if (!IsPowered()) {
247 VLOG(1) << "AddDiscoverySession: Fails: !isPowered";
248 return false;
249 }
250
251 numDiscoverySessions++;
252 VLOG(1) << "AddDiscoverySession: Now " << unsigned(numDiscoverySessions)
253 << " sessions.";
254 if (numDiscoverySessions > 1) {
255 return true;
256 }
257
258 if (!Java_ChromeBluetoothAdapter_addDiscoverySession(AttachCurrentThread(),
259 j_adapter_.obj())) {
260 numDiscoverySessions--;
261 return false;
262 } else {
263 PurgeTimedOutDevices();
ortuno 2016/06/15 17:20:16 This results in mAdapter.isDiscovering() being cal
perja 2016/06/17 13:39:27 Yeah, that sounds like a good idea. I guess we can
264 }
265 return true;
266 }
267
215 void BluetoothAdapterAndroid::RemoveDiscoverySession( 268 void BluetoothAdapterAndroid::RemoveDiscoverySession(
216 BluetoothDiscoveryFilter* discovery_filter, 269 BluetoothDiscoveryFilter* discovery_filter,
217 const base::Closure& callback, 270 const base::Closure& callback,
218 const DiscoverySessionErrorCallback& error_callback) { 271 const DiscoverySessionErrorCallback& error_callback) {
219 if (Java_ChromeBluetoothAdapter_removeDiscoverySession(AttachCurrentThread(), 272 if (RemoveDiscoverySessionInternal()) {
220 j_adapter_.obj())) {
221 callback.Run(); 273 callback.Run();
222 } else { 274 } else {
223 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. 275 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here.
224 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); 276 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN);
225 } 277 }
226 } 278 }
227 279
280 bool BluetoothAdapterAndroid::RemoveDiscoverySessionInternal() {
281 if (numDiscoverySessions == 0) {
282 DCHECK(false);
283 VLOG(1) << "RemoveDiscoverySession: No scan in progress.";
284 return false;
285 }
286
287 --numDiscoverySessions;
288
289 if (numDiscoverySessions == 0) {
290 VLOG(1) << "RemoveDiscoverySession: Now 0 sessions. Stopping scan.";
291 return Java_ChromeBluetoothAdapter_removeDiscoverySession(
292 AttachCurrentThread(), j_adapter_.obj());
293 }
294
295 VLOG(1) << "RemoveDiscoverySession: Now " << unsigned(numDiscoverySessions)
296 << " sessions.";
297 return true;
298 }
299
228 void BluetoothAdapterAndroid::SetDiscoveryFilter( 300 void BluetoothAdapterAndroid::SetDiscoveryFilter(
229 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter, 301 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
230 const base::Closure& callback, 302 const base::Closure& callback,
231 const DiscoverySessionErrorCallback& error_callback) { 303 const DiscoverySessionErrorCallback& error_callback) {
232 // TODO(scheib): Support filters crbug.com/490401 304 // TODO(scheib): Support filters crbug.com/490401
233 NOTIMPLEMENTED(); 305 NOTIMPLEMENTED();
234 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); 306 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED);
235 } 307 }
236 308
237 void BluetoothAdapterAndroid::RemovePairingDelegateInternal( 309 void BluetoothAdapterAndroid::RemovePairingDelegateInternal(
238 device::BluetoothDevice::PairingDelegate* pairing_delegate) { 310 device::BluetoothDevice::PairingDelegate* pairing_delegate) {
239 } 311 }
240 312
241 } // namespace device 313 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698