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

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: changes for olivierrobin@ 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)onUpdate:(NSTimer*)timer;
Olivier 2016/10/19 10:22:54 NIT: rename. Update means there is an update. Rena
mattreynolds 2016/10/19 18:20:21 Done.
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 BOOL oldOnLostDetectionEnabled = onLostDetectionEnabled_;
Olivier 2016/10/19 10:22:54 nit: if (enabled == onLostDetectionEnabled_) ret
mattreynolds 2016/10/19 18:20:22 Done.
217 onLostDetectionEnabled_ = enabled;
218 if (started_ && oldOnLostDetectionEnabled != onLostDetectionEnabled_) {
219 [self start];
220 }
221 }
222
192 - (int)unresolvedBeaconsCount { 223 - (int)unresolvedBeaconsCount {
193 return [unresolvedDevices_ count]; 224 return [unresolvedDevices_ count];
194 } 225 }
195 226
196 - (BOOL)bluetoothEnabled { 227 - (BOOL)bluetoothEnabled {
197 // TODO(crbug.com/619982): The CBManager base class appears to still be in 228 // TODO(crbug.com/619982): The CBManager base class appears to still be in
198 // flux. Unwind this #ifdef once the APIs settle. 229 // flux. Unwind this #ifdef once the APIs settle.
199 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 230 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
200 return [centralManager_ state] == CBManagerStatePoweredOn; 231 return [centralManager_ state] == CBManagerStatePoweredOn;
201 #else 232 #else
202 return [centralManager_ state] == CBCentralManagerStatePoweredOn; 233 return [centralManager_ state] == CBCentralManagerStatePoweredOn;
203 #endif 234 #endif
204 } 235 }
205 236
206 - (void)reallyStart { 237 - (void)reallyStart {
207 pendingStart_ = NO; 238 pendingStart_ = NO;
239
240 if (updateTimer_.get()) {
241 [updateTimer_ invalidate];
242 updateTimer_.reset();
243 }
244
208 NSArray* serviceUUIDs = @[ 245 NSArray* serviceUUIDs = @[
209 [CBUUID UUIDWithString:kUriBeaconServiceUUID], 246 [CBUUID UUIDWithString:kUriBeaconServiceUUID],
210 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID] 247 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID]
211 ]; 248 ];
212 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:nil]; 249 NSDictionary* options = nil;
250 if (onLostDetectionEnabled_) {
251 // To detect lost URLs, we configure the scanner with the AllowDuplicates
252 // option enabled, which will notify us each time an advertising packet is
253 // received rather than only the first time. A URL is considered lost if the
254 // most recent sighting was more than |kLostThresholdSeconds| ago.
255 options =
256 [NSDictionary dictionaryWithObjectsAndKeys:
257 [NSNumber numberWithBool:YES],
258 CBCentralManagerScanOptionAllowDuplicatesKey, nil];
Olivier 2016/10/19 10:22:54 Question: Is this needed if we do the workaround?
mattreynolds 2016/10/19 18:20:21 I ran some tests and it seems it's not needed if w
259
260 // Register a repeating timer to periodically check for lost URLs.
261 updateTimer_.reset([NSTimer
262 scheduledTimerWithTimeInterval:kUpdateIntervalSeconds
263 target:self
264 selector:@selector(onUpdate:)
265 userInfo:nil
266 repeats:YES]);
267 }
268 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:options];
269 }
270
271 - (void)reallyStop {
272 if (updateTimer_.get()) {
273 [updateTimer_ invalidate];
274 updateTimer_.reset();
275 }
276
277 [centralManager_ stopScan];
278 }
279
280 - (void)onUpdate:(NSTimer*)timer {
281 NSDate* now = [NSDate date];
282 NSMutableArray* lostDevices = [NSMutableArray array];
283 NSMutableArray* lostUnresolvedDevices = [NSMutableArray array];
284 NSMutableArray* lostScannedUrls = [NSMutableArray array];
285
286 for (PhysicalWebDevice* device in [self devices]) {
287 NSDate* scanTimestamp = [device scanTimestamp];
288 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp];
289 if (elapsedSeconds > kLostThresholdSeconds) {
290 [lostDevices addObject:device];
291 [lostScannedUrls addObject:[device requestURL]];
292 [devicesUrls_ removeObject:[device requestURL]];
293 [finalUrls_ removeObject:[device url]];
294 }
295 }
296
297 for (PhysicalWebDevice* device in unresolvedDevices_.get()) {
298 NSDate* scanTimestamp = [device scanTimestamp];
299 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp];
300 if (elapsedSeconds > kLostThresholdSeconds) {
301 [lostUnresolvedDevices addObject:device];
302 [lostScannedUrls addObject:[device requestURL]];
303 [devicesUrls_ removeObject:[device requestURL]];
304 }
305 }
306
307 NSMutableArray* requestsToRemove = [NSMutableArray array];
308 for (PhysicalWebRequest* request in pendingRequests_.get()) {
309 if ([lostScannedUrls containsObject:[request requestURL]]) {
310 [request cancel];
311 [requestsToRemove addObject:request];
312 }
313 }
314
315 [devices_ removeObjectsInArray:lostDevices];
316 [unresolvedDevices_ removeObjectsInArray:lostUnresolvedDevices];
317 [pendingRequests_ removeObjectsInArray:requestsToRemove];
318
319 if ([lostDevices count]) {
320 [delegate_ scannerUpdatedDevices:self];
321 }
322
323 // Workaround for crbug.com/657056
Olivier 2016/10/19 10:22:54 format // TODO(crbug.com/657056): Remove this work
mattreynolds 2016/10/19 18:20:21 Done.
324 // For unknown reasons, when scanning for longer periods (on the order of
325 // minutes), the scanner is less reliable at detecting all nearby URLs. As a
326 // workaround, we restart the scanner each time we check for lost URLs.
327 NSArray* serviceUUIDs = @[
328 [CBUUID UUIDWithString:kUriBeaconServiceUUID],
329 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID]
330 ];
331 NSDictionary* options = [NSDictionary
332 dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],
333 CBCentralManagerScanOptionAllowDuplicatesKey,
334 nil];
335 [centralManager_ stopScan];
336 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:options];
213 } 337 }
214 338
215 #pragma mark - 339 #pragma mark -
216 #pragma mark CBCentralManagerDelegate methods 340 #pragma mark CBCentralManagerDelegate methods
217 341
218 - (void)centralManagerDidUpdateState:(CBCentralManager*)central { 342 - (void)centralManagerDidUpdateState:(CBCentralManager*)central {
219 if ([self bluetoothEnabled]) { 343 if ([self bluetoothEnabled]) {
220 if (pendingStart_) 344 if (pendingStart_)
221 [self reallyStart]; 345 [self reallyStart];
222 } else { 346 } else {
223 if (started_ && !pendingStart_) { 347 if (started_ && !pendingStart_) {
224 pendingStart_ = YES; 348 pendingStart_ = YES;
225 [centralManager_ stopScan]; 349 [self reallyStop];
226 } 350 }
227 } 351 }
228 [delegate_ scannerBluetoothStatusUpdated:self]; 352 [delegate_ scannerBluetoothStatusUpdated:self];
229 } 353 }
230 354
231 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData { 355 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData {
232 NSDictionary* serviceData = 356 NSDictionary* serviceData =
233 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]; 357 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey];
234 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]]) 358 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]])
235 return BEACON_TYPE_URIBEACON; 359 return BEACON_TYPE_URIBEACON;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 DCHECK(data); 391 DCHECK(data);
268 392
269 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner 393 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner
270 newDeviceFromData:data 394 newDeviceFromData:data
271 rssi:[RSSI intValue] 395 rssi:[RSSI intValue]
272 type:type]); 396 type:type]);
273 // Skip if the data couldn't be parsed. 397 // Skip if the data couldn't be parsed.
274 if (!device.get()) 398 if (!device.get())
275 return; 399 return;
276 400
401 [device setScanTimestamp:[NSDate date]];
402
277 // Skip if the URL has already been seen. 403 // Skip if the URL has already been seen.
278 if ([devicesUrls_ containsObject:[device url]]) 404 if ([devicesUrls_ containsObject:[device requestURL]])
mattreynolds 2016/10/19 18:20:21 found a bug: if the URL has already been seen, we
Olivier 2016/10/20 07:05:21 I don't get it. You update the timestamp on the l
mattreynolds 2016/10/20 22:03:28 If this is the first time we've seen the device's
279 return; 405 return;
280 [devicesUrls_ addObject:[device url]]; 406 [devicesUrls_ addObject:[device requestURL]];
281 407
282 if (networkRequestEnabled_) { 408 if (networkRequestEnabled_) {
283 [self requestMetadataForDevice:device]; 409 [self requestMetadataForDevice:device];
284 } else { 410 } else {
285 [unresolvedDevices_ addObject:device]; 411 [unresolvedDevices_ addObject:device];
286 [delegate_ scannerUpdatedDevices:self]; 412 [delegate_ scannerUpdatedDevices:self];
287 } 413 }
288 } 414 }
289 415
290 #pragma mark - 416 #pragma mark -
(...skipping 28 matching lines...) Expand all
319 std::string utf8URI; 445 std::string utf8URI;
320 device::DecodeUriBeaconUri(encodedURI, utf8URI); 446 device::DecodeUriBeaconUri(encodedURI, utf8URI);
321 NSString* uriString = base::SysUTF8ToNSString(utf8URI); 447 NSString* uriString = base::SysUTF8ToNSString(utf8URI);
322 NSURL* url = [NSURL URLWithString:uriString]; 448 NSURL* url = [NSURL URLWithString:uriString];
323 449
324 // Ensure URL is valid. 450 // Ensure URL is valid.
325 if (!url) 451 if (!url)
326 return nil; 452 return nil;
327 453
328 return [[PhysicalWebDevice alloc] initWithURL:url 454 return [[PhysicalWebDevice alloc] initWithURL:url
329 requestURL:nil 455 requestURL:url
330 icon:nil 456 icon:nil
331 title:nil 457 title:nil
332 description:nil 458 description:nil
333 transmitPower:transmitPower 459 transmitPower:transmitPower
334 rssi:rssi 460 rssi:rssi
335 rank:physical_web::kMaxRank]; 461 rank:physical_web::kMaxRank
462 scanTimestamp:[NSDate date]];
336 } 463 }
337 464
338 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device { 465 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device {
339 base::scoped_nsobject<PhysicalWebRequest> request( 466 base::scoped_nsobject<PhysicalWebRequest> request(
340 [[PhysicalWebRequest alloc] initWithDevice:device]); 467 [[PhysicalWebRequest alloc] initWithDevice:device]);
341 PhysicalWebRequest* strongRequest = request.get(); 468 PhysicalWebRequest* strongRequest = request.get();
342 [pendingRequests_ addObject:strongRequest]; 469 [pendingRequests_ addObject:strongRequest];
343 base::WeakNSObject<PhysicalWebScanner> weakSelf(self); 470 base::WeakNSObject<PhysicalWebScanner> weakSelf(self);
344 [request start:^(PhysicalWebDevice* device, NSError* error) { 471 [request start:^(PhysicalWebDevice* device, NSError* error) {
345 base::scoped_nsobject<PhysicalWebScanner> strongSelf([weakSelf retain]); 472 base::scoped_nsobject<PhysicalWebScanner> strongSelf([weakSelf retain]);
346 if (!strongSelf) { 473 if (!strongSelf) {
347 return; 474 return;
348 } 475 }
349 // ignore if there's an error. 476 // ignore if there's an error.
350 if (!error) { 477 if (!error) {
351 if (![strongSelf.get()->finalUrls_ containsObject:[device url]]) { 478 if (![strongSelf.get()->finalUrls_ containsObject:[device url]]) {
352 [strongSelf.get()->devices_ addObject:device]; 479 [strongSelf.get()->devices_ addObject:device];
353 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf]; 480 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf];
354 [strongSelf.get()->finalUrls_ addObject:[device url]]; 481 [strongSelf.get()->finalUrls_ addObject:[device url]];
355 } 482 }
356 } 483 }
357 [strongSelf.get()->pendingRequests_ removeObject:strongRequest]; 484 [strongSelf.get()->pendingRequests_ removeObject:strongRequest];
358 }]; 485 }];
359 } 486 }
360 487
361 @end 488 @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