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

Side by Side Diff: ios/chrome/common/physical_web/physical_web_scanner.mm

Issue 2413923002: Enable lost URL detection in the Physical Web scanner (Closed)
Patch Set: fixes Created 4 years, 2 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
« no previous file with comments | « ios/chrome/common/physical_web/physical_web_scanner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #import "ios/chrome/common/physical_web/physical_web_scanner.h" 5 #import "ios/chrome/common/physical_web/physical_web_scanner.h"
6 6
7 #import <CoreBluetooth/CoreBluetooth.h> 7 #import <CoreBluetooth/CoreBluetooth.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #import "base/ios/weak_nsobject.h" 12 #import "base/ios/weak_nsobject.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #import "base/mac/scoped_nsobject.h" 14 #import "base/mac/scoped_nsobject.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
17 #include "base/values.h" 17 #include "base/values.h"
18 #include "device/bluetooth/uribeacon/uri_encoder.h" 18 #include "device/bluetooth/uribeacon/uri_encoder.h"
19 #import "ios/chrome/common/physical_web/physical_web_device.h" 19 #import "ios/chrome/common/physical_web/physical_web_device.h"
20 #import "ios/chrome/common/physical_web/physical_web_request.h" 20 #import "ios/chrome/common/physical_web/physical_web_request.h"
21 #import "ios/chrome/common/physical_web/physical_web_types.h" 21 #import "ios/chrome/common/physical_web/physical_web_types.h"
22 22
23 namespace { 23 namespace {
24 24
25 NSString* const kUriBeaconServiceUUID = @"FED8"; 25 NSString* const kUriBeaconServiceUUID = @"FED8";
26 NSString* const kEddystoneBeaconServiceUUID = @"FEAA"; 26 NSString* const kEddystoneBeaconServiceUUID = @"FEAA";
27 27
28 // The length of time in seconds since a URL was last seen before it should be
29 // considered lost (ie, no longer nearby).
30 const NSTimeInterval kLostThresholdSeconds = 15.0;
31 // The time interval in seconds between checks for lost URLs.
32 const NSTimeInterval kUpdateIntervalSeconds = 6.0;
33
28 enum BeaconType { 34 enum BeaconType {
29 BEACON_TYPE_NONE, 35 BEACON_TYPE_NONE,
30 BEACON_TYPE_URIBEACON, 36 BEACON_TYPE_URIBEACON,
31 BEACON_TYPE_EDDYSTONE, 37 BEACON_TYPE_EDDYSTONE,
32 }; 38 };
33 39
34 } // namespace 40 } // namespace
35 41
36 @interface PhysicalWebScanner ()<CBCentralManagerDelegate> 42 @interface PhysicalWebScanner ()<CBCentralManagerDelegate>
37 43
38 // Decodes the UriBeacon information in the given |data| and a beacon |type| to 44 // Decodes the UriBeacon information in the given |data| and a beacon |type| to
39 // return an unresolved PhysicalWebDevice instance. It also stores the given 45 // return an unresolved PhysicalWebDevice instance. It also stores the given
40 // |rssi| in the result. 46 // |rssi| in the result.
41 + (PhysicalWebDevice*)newDeviceFromData:(NSData*)data 47 + (PhysicalWebDevice*)newDeviceFromData:(NSData*)data
42 rssi:(int)rssi 48 rssi:(int)rssi
43 type:(BeaconType)type; 49 type:(BeaconType)type;
44 // Starts the CoreBluetooth scanner when the bluetooth is powered on. 50 // Starts the CoreBluetooth scanner when the bluetooth is powered on and starts
51 // the update timer.
45 - (void)reallyStart; 52 - (void)reallyStart;
53 // Stops the CoreBluetooth scanner and update timer.
54 - (void)reallyStop;
55 // Timer callback to check for lost URLs based on the elapsed time since they
56 // were last seen.
57 - (void)onUpdateTimeElapsed:(NSTimer*)timer;
46 // Requests metadata of a device if the same URL has not been requested before. 58 // Requests metadata of a device if the same URL has not been requested before.
47 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device; 59 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device;
48 // Returns the beacon type given the advertisement data. 60 // Returns the beacon type given the advertisement data.
49 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData; 61 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData;
50 62
51 @end 63 @end
52 64
53 @implementation PhysicalWebScanner { 65 @implementation PhysicalWebScanner {
54 // Delegate that will be notified when the list of devices change. 66 // Delegate that will be notified when the list of devices change.
55 id<PhysicalWebScannerDelegate> delegate_; 67 id<PhysicalWebScannerDelegate> delegate_;
56 // The value of |started_| is YES when the scanner has been started and NO 68 // The value of |started_| is YES when the scanner has been started and NO
57 // when it's been stopped. The initial value is NO. 69 // when it's been stopped. The initial value is NO.
58 BOOL started_; 70 BOOL started_;
59 // The value is valid when the scanner has been started. If bluetooth is not 71 // The value is valid when the scanner has been started. If bluetooth is not
60 // powered on, the value is YES, if it's powered on and the CoreBluetooth 72 // powered on, the value is YES, if it's powered on and the CoreBluetooth
61 // scanner has started, the value is NO. 73 // scanner has started, the value is NO.
62 BOOL pendingStart_; 74 BOOL pendingStart_;
63 // List of PhysicalWebRequest that we're waiting the response from. 75 // List of PhysicalWebRequest that we're waiting the response from.
64 base::scoped_nsobject<NSMutableArray> pendingRequests_; 76 base::scoped_nsobject<NSMutableArray> pendingRequests_;
65 // List of resolved PhysicalWebDevice. 77 // List of resolved PhysicalWebDevice.
66 base::scoped_nsobject<NSMutableArray> devices_; 78 base::scoped_nsobject<NSMutableArray> devices_;
67 // List of URLs that have been resolved or have a pending resolution from a 79 // List of URLs that have been resolved or have a pending resolution from a
68 // PhysicalWebRequest. 80 // PhysicalWebRequest.
69 base::scoped_nsobject<NSMutableSet> devicesUrls_; 81 base::scoped_nsobject<NSMutableSet> devicesUrls_;
70 // List of final URLs that have been resolved. This set will help us 82 // List of final URLs that have been resolved. This set will help us
71 // deduplicate the final URLs. 83 // deduplicate the final URLs.
72 base::scoped_nsobject<NSMutableSet> finalUrls_; 84 base::scoped_nsobject<NSMutableSet> finalUrls_;
73 // CoreBluetooth scanner. 85 // CoreBluetooth scanner.
74 base::scoped_nsobject<CBCentralManager> centralManager_; 86 base::scoped_nsobject<CBCentralManager> centralManager_;
87 // When YES, we will notify the delegate if a previously nearby URL is lost
88 // and remove it from the list of nearby devices.
89 BOOL onLostDetectionEnabled_;
75 // The value is YES if network requests can be sent. 90 // The value is YES if network requests can be sent.
76 BOOL networkRequestEnabled_; 91 BOOL networkRequestEnabled_;
77 // List of unresolved PhysicalWebDevice when network requests are not enabled. 92 // List of unresolved PhysicalWebDevice when network requests are not enabled.
78 base::scoped_nsobject<NSMutableArray> unresolvedDevices_; 93 base::scoped_nsobject<NSMutableArray> unresolvedDevices_;
94 // A repeating timer to check for lost URLs. If the elapsed time since an URL
95 // was last seen exceeds a threshold, the URL is considered lost.
96 base::scoped_nsobject<NSTimer> updateTimer_;
79 } 97 }
80 98
99 @synthesize onLostDetectionEnabled = onLostDetectionEnabled_;
81 @synthesize networkRequestEnabled = networkRequestEnabled_; 100 @synthesize networkRequestEnabled = networkRequestEnabled_;
82 101
83 - (instancetype)initWithDelegate:(id<PhysicalWebScannerDelegate>)delegate { 102 - (instancetype)initWithDelegate:(id<PhysicalWebScannerDelegate>)delegate {
84 self = [super init]; 103 self = [super init];
85 if (self) { 104 if (self) {
86 delegate_ = delegate; 105 delegate_ = delegate;
87 devices_.reset([[NSMutableArray alloc] init]); 106 devices_.reset([[NSMutableArray alloc] init]);
88 devicesUrls_.reset([[NSMutableSet alloc] init]); 107 devicesUrls_.reset([[NSMutableSet alloc] init]);
89 finalUrls_.reset([[NSMutableSet alloc] init]); 108 finalUrls_.reset([[NSMutableSet alloc] init]);
90 pendingRequests_.reset([[NSMutableArray alloc] init]); 109 pendingRequests_.reset([[NSMutableArray alloc] init]);
91 centralManager_.reset([[CBCentralManager alloc] 110 centralManager_.reset([[CBCentralManager alloc]
92 initWithDelegate:self 111 initWithDelegate:self
93 queue:dispatch_get_main_queue()]); 112 queue:dispatch_get_main_queue()]);
94 unresolvedDevices_.reset([[NSMutableArray alloc] init]); 113 unresolvedDevices_.reset([[NSMutableArray alloc] init]);
95 [[NSHTTPCookieStorage sharedHTTPCookieStorage] 114 [[NSHTTPCookieStorage sharedHTTPCookieStorage]
96 setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever]; 115 setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
97 } 116 }
98 return self; 117 return self;
99 } 118 }
100 119
101 - (instancetype)init { 120 - (instancetype)init {
102 NOTREACHED(); 121 NOTREACHED();
103 return nil; 122 return nil;
104 } 123 }
105 124
106 - (void)dealloc { 125 - (void)dealloc {
107 [centralManager_ setDelegate:nil]; 126 [centralManager_ setDelegate:nil];
108 centralManager_.reset(); 127 centralManager_.reset();
128 if (updateTimer_.get()) {
129 [updateTimer_ invalidate];
130 updateTimer_.reset();
131 }
109 [super dealloc]; 132 [super dealloc];
110 } 133 }
111 134
112 - (void)start { 135 - (void)start {
113 [self stop]; 136 [self stop];
114 [finalUrls_ removeAllObjects]; 137 [finalUrls_ removeAllObjects];
115 [devicesUrls_ removeAllObjects]; 138 [devicesUrls_ removeAllObjects];
116 [devices_ removeAllObjects]; 139 [devices_ removeAllObjects];
117 started_ = YES; 140 started_ = YES;
118 if ([self bluetoothEnabled]) 141 if ([self bluetoothEnabled])
119 [self reallyStart]; 142 [self reallyStart];
120 else 143 else
121 pendingStart_ = YES; 144 pendingStart_ = YES;
122 } 145 }
123 146
124 - (void)stop { 147 - (void)stop {
125 if (!started_) 148 if (!started_)
126 return; 149 return;
127 for (PhysicalWebRequest* request in pendingRequests_.get()) { 150 for (PhysicalWebRequest* request in pendingRequests_.get()) {
128 [request cancel]; 151 [request cancel];
129 } 152 }
130 [pendingRequests_ removeAllObjects]; 153 [pendingRequests_ removeAllObjects];
131 if (!pendingStart_ && [self bluetoothEnabled]) { 154 if (!pendingStart_ && [self bluetoothEnabled]) {
132 [centralManager_ stopScan]; 155 [self reallyStop];
133 } 156 }
134 pendingStart_ = NO; 157 pendingStart_ = NO;
135 started_ = NO; 158 started_ = NO;
136 } 159 }
137 160
138 - (NSArray*)devices { 161 - (NSArray*)devices {
139 return [devices_ sortedArrayUsingComparator:^(id obj1, id obj2) { 162 return [devices_ sortedArrayUsingComparator:^(id obj1, id obj2) {
140 PhysicalWebDevice* device1 = obj1; 163 PhysicalWebDevice* device1 = obj1;
141 PhysicalWebDevice* device2 = obj2; 164 PhysicalWebDevice* device2 = obj2;
142 // Sorts in ascending order. 165 // Sorts in ascending order.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 if (!networkRequestEnabled_) 205 if (!networkRequestEnabled_)
183 return; 206 return;
184 207
185 // Sends the pending requests. 208 // Sends the pending requests.
186 for (PhysicalWebDevice* device in unresolvedDevices_.get()) { 209 for (PhysicalWebDevice* device in unresolvedDevices_.get()) {
187 [self requestMetadataForDevice:device]; 210 [self requestMetadataForDevice:device];
188 } 211 }
189 [unresolvedDevices_ removeAllObjects]; 212 [unresolvedDevices_ removeAllObjects];
190 } 213 }
191 214
215 - (void)setOnLostDetectionEnabled:(BOOL)enabled {
216 if (enabled == onLostDetectionEnabled_) {
217 return;
218 }
219 onLostDetectionEnabled_ = enabled;
220 if (started_) {
221 [self start];
222 }
223 }
224
192 - (int)unresolvedBeaconsCount { 225 - (int)unresolvedBeaconsCount {
193 return [unresolvedDevices_ count]; 226 return [unresolvedDevices_ count];
194 } 227 }
195 228
196 - (BOOL)bluetoothEnabled { 229 - (BOOL)bluetoothEnabled {
197 // TODO(crbug.com/619982): The CBManager base class appears to still be in 230 // TODO(crbug.com/619982): The CBManager base class appears to still be in
198 // flux. Unwind this #ifdef once the APIs settle. 231 // flux. Unwind this #ifdef once the APIs settle.
199 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 232 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
200 return [centralManager_ state] == CBManagerStatePoweredOn; 233 return [centralManager_ state] == CBManagerStatePoweredOn;
201 #else 234 #else
202 return [centralManager_ state] == CBCentralManagerStatePoweredOn; 235 return [centralManager_ state] == CBCentralManagerStatePoweredOn;
203 #endif 236 #endif
204 } 237 }
205 238
206 - (void)reallyStart { 239 - (void)reallyStart {
207 pendingStart_ = NO; 240 pendingStart_ = NO;
241
242 if (updateTimer_.get()) {
243 [updateTimer_ invalidate];
244 updateTimer_.reset();
245 }
246
208 NSArray* serviceUUIDs = @[ 247 NSArray* serviceUUIDs = @[
209 [CBUUID UUIDWithString:kUriBeaconServiceUUID], 248 [CBUUID UUIDWithString:kUriBeaconServiceUUID],
210 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID] 249 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID]
211 ]; 250 ];
251 if (onLostDetectionEnabled_) {
252 // Register a repeating timer to periodically check for lost URLs.
253 updateTimer_.reset([NSTimer
254 scheduledTimerWithTimeInterval:kUpdateIntervalSeconds
255 target:self
256 selector:@selector(onUpdateTimeElapsed:)
257 userInfo:nil
258 repeats:YES]);
259 }
212 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:nil]; 260 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:nil];
213 } 261 }
214 262
263 - (void)reallyStop {
264 if (updateTimer_.get()) {
265 [updateTimer_ invalidate];
266 updateTimer_.reset();
267 }
268
269 [centralManager_ stopScan];
270 }
271
272 - (void)onUpdateTimeElapsed:(NSTimer*)timer {
273 NSDate* now = [NSDate date];
274 NSMutableArray* lostDevices = [NSMutableArray array];
275 NSMutableArray* lostUnresolvedDevices = [NSMutableArray array];
276 NSMutableArray* lostScannedUrls = [NSMutableArray array];
277
278 for (PhysicalWebDevice* device in devices_.get()) {
279 NSDate* scanTimestamp = [device scanTimestamp];
280 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp];
281 if (elapsedSeconds > kLostThresholdSeconds) {
282 [lostDevices addObject:device];
283 [lostScannedUrls addObject:[device requestURL]];
284 [devicesUrls_ removeObject:[device requestURL]];
285 [finalUrls_ removeObject:[device url]];
286 }
287 }
288
289 for (PhysicalWebDevice* device in unresolvedDevices_.get()) {
290 NSDate* scanTimestamp = [device scanTimestamp];
291 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp];
292 if (elapsedSeconds > kLostThresholdSeconds) {
293 [lostUnresolvedDevices addObject:device];
294 [lostScannedUrls addObject:[device requestURL]];
295 [devicesUrls_ removeObject:[device requestURL]];
296 }
297 }
298
299 NSMutableArray* requestsToRemove = [NSMutableArray array];
300 for (PhysicalWebRequest* request in pendingRequests_.get()) {
301 if ([lostScannedUrls containsObject:[request requestURL]]) {
302 [request cancel];
303 [requestsToRemove addObject:request];
304 }
305 }
306
307 [devices_ removeObjectsInArray:lostDevices];
308 [unresolvedDevices_ removeObjectsInArray:lostUnresolvedDevices];
309 [pendingRequests_ removeObjectsInArray:requestsToRemove];
310
311 if ([lostDevices count]) {
312 [delegate_ scannerUpdatedDevices:self];
313 }
314
315 // TODO(crbug.com/657056): Remove this workaround when radar is fixed.
316 // For unknown reasons, when scanning for longer periods (on the order of
317 // minutes), the scanner is less reliable at detecting all nearby URLs. As a
318 // workaround, we restart the scanner each time we check for lost URLs.
319 NSArray* serviceUUIDs = @[
320 [CBUUID UUIDWithString:kUriBeaconServiceUUID],
321 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID]
322 ];
323 [centralManager_ stopScan];
324 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:nil];
325 }
326
215 #pragma mark - 327 #pragma mark -
216 #pragma mark CBCentralManagerDelegate methods 328 #pragma mark CBCentralManagerDelegate methods
217 329
218 - (void)centralManagerDidUpdateState:(CBCentralManager*)central { 330 - (void)centralManagerDidUpdateState:(CBCentralManager*)central {
219 if ([self bluetoothEnabled]) { 331 if ([self bluetoothEnabled]) {
220 if (pendingStart_) 332 if (pendingStart_)
221 [self reallyStart]; 333 [self reallyStart];
222 } else { 334 } else {
223 if (started_ && !pendingStart_) { 335 if (started_ && !pendingStart_) {
224 pendingStart_ = YES; 336 pendingStart_ = YES;
225 [centralManager_ stopScan]; 337 [self reallyStop];
226 } 338 }
227 } 339 }
228 [delegate_ scannerBluetoothStatusUpdated:self]; 340 [delegate_ scannerBluetoothStatusUpdated:self];
229 } 341 }
230 342
231 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData { 343 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData {
232 NSDictionary* serviceData = 344 NSDictionary* serviceData =
233 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]; 345 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey];
234 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]]) 346 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]])
235 return BEACON_TYPE_URIBEACON; 347 return BEACON_TYPE_URIBEACON;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 DCHECK(data); 379 DCHECK(data);
268 380
269 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner 381 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner
270 newDeviceFromData:data 382 newDeviceFromData:data
271 rssi:[RSSI intValue] 383 rssi:[RSSI intValue]
272 type:type]); 384 type:type]);
273 // Skip if the data couldn't be parsed. 385 // Skip if the data couldn't be parsed.
274 if (!device.get()) 386 if (!device.get())
275 return; 387 return;
276 388
277 // Skip if the URL has already been seen. 389 // If the URL has already been seen, update its timestamp.
278 if ([devicesUrls_ containsObject:[device url]]) 390 if ([devicesUrls_ containsObject:[device requestURL]]) {
391 for (PhysicalWebDevice* unresolvedDevice in unresolvedDevices_.get()) {
392 if ([[unresolvedDevice requestURL] isEqual:[device requestURL]]) {
393 [unresolvedDevice setScanTimestamp:[NSDate date]];
394 return;
395 }
396 }
397 for (PhysicalWebDevice* resolvedDevice in devices_.get()) {
398 if ([[resolvedDevice requestURL] isEqual:[device requestURL]]) {
399 [resolvedDevice setScanTimestamp:[NSDate date]];
400 break;
401 }
402 }
279 return; 403 return;
280 [devicesUrls_ addObject:[device url]]; 404 }
405
406 [device setScanTimestamp:[NSDate date]];
407 [devicesUrls_ addObject:[device requestURL]];
281 408
282 if (networkRequestEnabled_) { 409 if (networkRequestEnabled_) {
283 [self requestMetadataForDevice:device]; 410 [self requestMetadataForDevice:device];
284 } else { 411 } else {
285 [unresolvedDevices_ addObject:device]; 412 [unresolvedDevices_ addObject:device];
286 [delegate_ scannerUpdatedDevices:self]; 413 [delegate_ scannerUpdatedDevices:self];
287 } 414 }
288 } 415 }
289 416
290 #pragma mark - 417 #pragma mark -
(...skipping 28 matching lines...) Expand all
319 std::string utf8URI; 446 std::string utf8URI;
320 device::DecodeUriBeaconUri(encodedURI, utf8URI); 447 device::DecodeUriBeaconUri(encodedURI, utf8URI);
321 NSString* uriString = base::SysUTF8ToNSString(utf8URI); 448 NSString* uriString = base::SysUTF8ToNSString(utf8URI);
322 NSURL* url = [NSURL URLWithString:uriString]; 449 NSURL* url = [NSURL URLWithString:uriString];
323 450
324 // Ensure URL is valid. 451 // Ensure URL is valid.
325 if (!url) 452 if (!url)
326 return nil; 453 return nil;
327 454
328 return [[PhysicalWebDevice alloc] initWithURL:url 455 return [[PhysicalWebDevice alloc] initWithURL:url
329 requestURL:nil 456 requestURL:url
330 icon:nil 457 icon:nil
331 title:nil 458 title:nil
332 description:nil 459 description:nil
333 transmitPower:transmitPower 460 transmitPower:transmitPower
334 rssi:rssi 461 rssi:rssi
335 rank:physical_web::kMaxRank]; 462 rank:physical_web::kMaxRank
463 scanTimestamp:[NSDate date]];
336 } 464 }
337 465
338 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device { 466 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device {
339 base::scoped_nsobject<PhysicalWebRequest> request( 467 base::scoped_nsobject<PhysicalWebRequest> request(
340 [[PhysicalWebRequest alloc] initWithDevice:device]); 468 [[PhysicalWebRequest alloc] initWithDevice:device]);
341 PhysicalWebRequest* strongRequest = request.get(); 469 PhysicalWebRequest* strongRequest = request.get();
342 [pendingRequests_ addObject:strongRequest]; 470 [pendingRequests_ addObject:strongRequest];
343 base::WeakNSObject<PhysicalWebScanner> weakSelf(self); 471 base::WeakNSObject<PhysicalWebScanner> weakSelf(self);
344 [request start:^(PhysicalWebDevice* device, NSError* error) { 472 [request start:^(PhysicalWebDevice* device, NSError* error) {
345 base::scoped_nsobject<PhysicalWebScanner> strongSelf([weakSelf retain]); 473 base::scoped_nsobject<PhysicalWebScanner> strongSelf([weakSelf retain]);
346 if (!strongSelf) { 474 if (!strongSelf) {
347 return; 475 return;
348 } 476 }
349 // ignore if there's an error. 477 // ignore if there's an error.
350 if (!error) { 478 if (!error) {
351 if (![strongSelf.get()->finalUrls_ containsObject:[device url]]) { 479 if (![strongSelf.get()->finalUrls_ containsObject:[device url]]) {
352 [strongSelf.get()->devices_ addObject:device]; 480 [strongSelf.get()->devices_ addObject:device];
353 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf]; 481 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf];
354 [strongSelf.get()->finalUrls_ addObject:[device url]]; 482 [strongSelf.get()->finalUrls_ addObject:[device url]];
355 } 483 }
356 } 484 }
357 [strongSelf.get()->pendingRequests_ removeObject:strongRequest]; 485 [strongSelf.get()->pendingRequests_ removeObject:strongRequest];
358 }]; 486 }];
359 } 487 }
360 488
361 @end 489 @end
OLDNEW
« no previous file with comments | « ios/chrome/common/physical_web/physical_web_scanner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698