Chromium Code Reviews| OLD | NEW |
|---|---|
| 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; | |
| 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 // Map from URLs to timestamps of the last time the URL was nearby. | |
| 95 base::scoped_nsobject<NSMutableDictionary> scanTimestamps_; | |
| 96 // A repeating timer to check for lost URLs. If the elapsed time since an URL | |
| 97 // was last seen exceeds a threshold, the URL is considered lost. | |
| 98 base::scoped_nsobject<NSTimer> updateTimer_; | |
| 79 } | 99 } |
| 80 | 100 |
| 101 @synthesize onLostDetectionEnabled = onLostDetectionEnabled_; | |
| 81 @synthesize networkRequestEnabled = networkRequestEnabled_; | 102 @synthesize networkRequestEnabled = networkRequestEnabled_; |
| 82 | 103 |
| 83 - (instancetype)initWithDelegate:(id<PhysicalWebScannerDelegate>)delegate { | 104 - (instancetype)initWithDelegate:(id<PhysicalWebScannerDelegate>)delegate { |
| 84 self = [super init]; | 105 self = [super init]; |
| 85 if (self) { | 106 if (self) { |
| 86 delegate_ = delegate; | 107 delegate_ = delegate; |
| 87 devices_.reset([[NSMutableArray alloc] init]); | 108 devices_.reset([[NSMutableArray alloc] init]); |
| 88 devicesUrls_.reset([[NSMutableSet alloc] init]); | 109 devicesUrls_.reset([[NSMutableSet alloc] init]); |
| 89 finalUrls_.reset([[NSMutableSet alloc] init]); | 110 finalUrls_.reset([[NSMutableSet alloc] init]); |
| 90 pendingRequests_.reset([[NSMutableArray alloc] init]); | 111 pendingRequests_.reset([[NSMutableArray alloc] init]); |
| 91 centralManager_.reset([[CBCentralManager alloc] | 112 centralManager_.reset([[CBCentralManager alloc] |
| 92 initWithDelegate:self | 113 initWithDelegate:self |
| 93 queue:dispatch_get_main_queue()]); | 114 queue:dispatch_get_main_queue()]); |
| 94 unresolvedDevices_.reset([[NSMutableArray alloc] init]); | 115 unresolvedDevices_.reset([[NSMutableArray alloc] init]); |
| 116 scanTimestamps_.reset([[NSMutableDictionary alloc] init]); | |
| 95 [[NSHTTPCookieStorage sharedHTTPCookieStorage] | 117 [[NSHTTPCookieStorage sharedHTTPCookieStorage] |
| 96 setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever]; | 118 setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever]; |
| 97 } | 119 } |
| 98 return self; | 120 return self; |
| 99 } | 121 } |
| 100 | 122 |
| 101 - (instancetype)init { | 123 - (instancetype)init { |
| 102 NOTREACHED(); | 124 NOTREACHED(); |
| 103 return nil; | 125 return nil; |
| 104 } | 126 } |
| 105 | 127 |
| 106 - (void)dealloc { | 128 - (void)dealloc { |
| 107 [centralManager_ setDelegate:nil]; | 129 [centralManager_ setDelegate:nil]; |
| 108 centralManager_.reset(); | 130 centralManager_.reset(); |
| 131 if (updateTimer_.get()) { | |
| 132 [updateTimer_ invalidate]; | |
| 133 updateTimer_.reset(); | |
| 134 } | |
| 109 [super dealloc]; | 135 [super dealloc]; |
| 110 } | 136 } |
| 111 | 137 |
| 112 - (void)start { | 138 - (void)start { |
| 113 [self stop]; | 139 [self stop]; |
| 114 [finalUrls_ removeAllObjects]; | 140 [finalUrls_ removeAllObjects]; |
| 115 [devicesUrls_ removeAllObjects]; | 141 [devicesUrls_ removeAllObjects]; |
| 116 [devices_ removeAllObjects]; | 142 [devices_ removeAllObjects]; |
| 143 [scanTimestamps_ removeAllObjects]; | |
| 117 started_ = YES; | 144 started_ = YES; |
| 118 if ([self bluetoothEnabled]) | 145 if ([self bluetoothEnabled]) |
| 119 [self reallyStart]; | 146 [self reallyStart]; |
| 120 else | 147 else |
| 121 pendingStart_ = YES; | 148 pendingStart_ = YES; |
| 122 } | 149 } |
| 123 | 150 |
| 124 - (void)stop { | 151 - (void)stop { |
| 125 if (!started_) | 152 if (!started_) |
| 126 return; | 153 return; |
| 127 for (PhysicalWebRequest* request in pendingRequests_.get()) { | 154 for (PhysicalWebRequest* request in pendingRequests_.get()) { |
| 128 [request cancel]; | 155 [request cancel]; |
| 129 } | 156 } |
| 130 [pendingRequests_ removeAllObjects]; | 157 [pendingRequests_ removeAllObjects]; |
| 131 if (!pendingStart_ && [self bluetoothEnabled]) { | 158 if (!pendingStart_ && [self bluetoothEnabled]) { |
| 132 [centralManager_ stopScan]; | 159 [self reallyStop]; |
| 133 } | 160 } |
| 134 pendingStart_ = NO; | 161 pendingStart_ = NO; |
| 135 started_ = NO; | 162 started_ = NO; |
| 136 } | 163 } |
| 137 | 164 |
| 138 - (NSArray*)devices { | 165 - (NSArray*)devices { |
| 139 return [devices_ sortedArrayUsingComparator:^(id obj1, id obj2) { | 166 return [devices_ sortedArrayUsingComparator:^(id obj1, id obj2) { |
| 140 PhysicalWebDevice* device1 = obj1; | 167 PhysicalWebDevice* device1 = obj1; |
| 141 PhysicalWebDevice* device2 = obj2; | 168 PhysicalWebDevice* device2 = obj2; |
| 142 // Sorts in ascending order. | 169 // Sorts in ascending order. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 if (!networkRequestEnabled_) | 209 if (!networkRequestEnabled_) |
| 183 return; | 210 return; |
| 184 | 211 |
| 185 // Sends the pending requests. | 212 // Sends the pending requests. |
| 186 for (PhysicalWebDevice* device in unresolvedDevices_.get()) { | 213 for (PhysicalWebDevice* device in unresolvedDevices_.get()) { |
| 187 [self requestMetadataForDevice:device]; | 214 [self requestMetadataForDevice:device]; |
| 188 } | 215 } |
| 189 [unresolvedDevices_ removeAllObjects]; | 216 [unresolvedDevices_ removeAllObjects]; |
| 190 } | 217 } |
| 191 | 218 |
| 219 - (void)setOnLostDetectionEnabled:(BOOL)enabled { | |
| 220 BOOL oldOnLostDetectionEnabled = onLostDetectionEnabled_; | |
| 221 onLostDetectionEnabled_ = enabled; | |
| 222 if (started_ && oldOnLostDetectionEnabled != onLostDetectionEnabled_) { | |
| 223 [self start]; | |
|
Olivier
2016/10/13 13:00:19
This will reset all the lists. Is that expected?
S
mattreynolds
2016/10/18 18:56:47
I added a comment documenting the behavior
| |
| 224 } | |
| 225 } | |
| 226 | |
| 192 - (int)unresolvedBeaconsCount { | 227 - (int)unresolvedBeaconsCount { |
| 193 return [unresolvedDevices_ count]; | 228 return [unresolvedDevices_ count]; |
| 194 } | 229 } |
| 195 | 230 |
| 196 - (BOOL)bluetoothEnabled { | 231 - (BOOL)bluetoothEnabled { |
| 197 // TODO(crbug.com/619982): The CBManager base class appears to still be in | 232 // TODO(crbug.com/619982): The CBManager base class appears to still be in |
| 198 // flux. Unwind this #ifdef once the APIs settle. | 233 // flux. Unwind this #ifdef once the APIs settle. |
| 199 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 | 234 #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 |
| 200 return [centralManager_ state] == CBManagerStatePoweredOn; | 235 return [centralManager_ state] == CBManagerStatePoweredOn; |
| 201 #else | 236 #else |
| 202 return [centralManager_ state] == CBCentralManagerStatePoweredOn; | 237 return [centralManager_ state] == CBCentralManagerStatePoweredOn; |
| 203 #endif | 238 #endif |
| 204 } | 239 } |
| 205 | 240 |
| 206 - (void)reallyStart { | 241 - (void)reallyStart { |
| 207 pendingStart_ = NO; | 242 pendingStart_ = NO; |
| 243 | |
| 244 if (updateTimer_.get()) { | |
| 245 [updateTimer_ invalidate]; | |
| 246 updateTimer_.reset(); | |
| 247 } | |
| 248 | |
| 208 NSArray* serviceUUIDs = @[ | 249 NSArray* serviceUUIDs = @[ |
| 209 [CBUUID UUIDWithString:kUriBeaconServiceUUID], | 250 [CBUUID UUIDWithString:kUriBeaconServiceUUID], |
| 210 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID] | 251 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID] |
| 211 ]; | 252 ]; |
| 212 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:nil]; | 253 NSDictionary* options = nil; |
| 254 if (onLostDetectionEnabled_) { | |
| 255 // To detect lost URLs, we configure the scanner with the AllowDuplicates | |
| 256 // option enabled, which will notify us each time an advertising packet is | |
| 257 // received rather than only the first time. A URL is considered lost if the | |
| 258 // most recent sighting was more than |kLostThresholdSeconds| ago. | |
| 259 options = | |
| 260 [NSDictionary dictionaryWithObjectsAndKeys: | |
| 261 [NSNumber numberWithBool:YES], | |
| 262 CBCentralManagerScanOptionAllowDuplicatesKey, nil]; | |
| 263 | |
| 264 // Register a repeating timer to periodically check for lost URLs. | |
| 265 updateTimer_.reset([NSTimer | |
| 266 scheduledTimerWithTimeInterval:kUpdateIntervalSeconds | |
| 267 target:self | |
| 268 selector:@selector(onUpdate:) | |
| 269 userInfo:nil | |
| 270 repeats:YES]); | |
| 271 } | |
| 272 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:options]; | |
| 273 } | |
| 274 | |
| 275 - (void)reallyStop { | |
| 276 if (updateTimer_.get()) { | |
| 277 [updateTimer_ invalidate]; | |
| 278 updateTimer_.reset(); | |
| 279 } | |
| 280 | |
| 281 [centralManager_ stopScan]; | |
| 282 } | |
| 283 | |
| 284 - (void)onUpdate:(NSTimer*)timer { | |
| 285 NSDate* now = [NSDate date]; | |
| 286 NSMutableArray* lostDevices = [NSMutableArray array]; | |
| 287 NSMutableArray* lostUnresolvedDevices = [NSMutableArray array]; | |
| 288 NSMutableArray* lostScannedUrls = [NSMutableArray array]; | |
| 289 NSMutableArray* lostResolvedUrls = [NSMutableArray array]; | |
| 290 | |
| 291 for (PhysicalWebDevice* device in [self devices]) { | |
| 292 NSDate* scanTimestamp = [scanTimestamps_ objectForKey:[device requestURL]]; | |
| 293 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp]; | |
| 294 if (elapsedSeconds > kLostThresholdSeconds) { | |
| 295 [lostDevices addObject:device]; | |
| 296 [lostScannedUrls addObject:[device requestURL]]; | |
| 297 [lostResolvedUrls addObject:[device url]]; | |
| 298 [devicesUrls_ removeObject:[device requestURL]]; | |
| 299 [finalUrls_ removeObject:[device url]]; | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 for (PhysicalWebDevice* device in unresolvedDevices_.get()) { | |
| 304 NSDate* scanTimestamp = [scanTimestamps_ objectForKey:[device requestURL]]; | |
| 305 NSTimeInterval elapsedSeconds = [now timeIntervalSinceDate:scanTimestamp]; | |
| 306 if (elapsedSeconds > kLostThresholdSeconds) { | |
| 307 [lostUnresolvedDevices addObject:device]; | |
| 308 [lostScannedUrls addObject:[device requestURL]]; | |
| 309 [devicesUrls_ removeObject:[device requestURL]]; | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 [devices_ removeObjectsInArray:lostDevices]; | |
| 314 [unresolvedDevices_ removeObjectsInArray:lostUnresolvedDevices]; | |
|
Olivier
2016/10/13 13:00:19
should we cancel the resolve URL query?
mattreynolds
2016/10/18 18:56:47
Done.
| |
| 315 [scanTimestamps_ removeObjectsForKeys:lostScannedUrls]; | |
| 316 | |
| 317 if ([lostDevices count]) { | |
| 318 [delegate_ scannerUpdatedDevices:self]; | |
| 319 } | |
| 320 | |
| 321 // For unknown reasons, when scanning for longer periods (on the order of | |
|
Olivier
2016/10/13 13:00:19
Can you file a radar on this, file a crbug that re
mattreynolds
2016/10/18 18:56:47
Done.
| |
| 322 // minutes), the scanner is less reliable at detecting all nearby URLs. As a | |
| 323 // workaround, we restart the scanner each time we check for lost URLs. | |
| 324 NSArray* serviceUUIDs = @[ | |
| 325 [CBUUID UUIDWithString:kUriBeaconServiceUUID], | |
| 326 [CBUUID UUIDWithString:kEddystoneBeaconServiceUUID] | |
| 327 ]; | |
| 328 NSDictionary* options = [NSDictionary | |
| 329 dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], | |
| 330 CBCentralManagerScanOptionAllowDuplicatesKey, | |
| 331 nil]; | |
| 332 [centralManager_ stopScan]; | |
| 333 [centralManager_ scanForPeripheralsWithServices:serviceUUIDs options:options]; | |
| 213 } | 334 } |
| 214 | 335 |
| 215 #pragma mark - | 336 #pragma mark - |
| 216 #pragma mark CBCentralManagerDelegate methods | 337 #pragma mark CBCentralManagerDelegate methods |
| 217 | 338 |
| 218 - (void)centralManagerDidUpdateState:(CBCentralManager*)central { | 339 - (void)centralManagerDidUpdateState:(CBCentralManager*)central { |
| 219 if ([self bluetoothEnabled]) { | 340 if ([self bluetoothEnabled]) { |
| 220 if (pendingStart_) | 341 if (pendingStart_) |
| 221 [self reallyStart]; | 342 [self reallyStart]; |
| 222 } else { | 343 } else { |
| 223 if (started_ && !pendingStart_) { | 344 if (started_ && !pendingStart_) { |
| 224 pendingStart_ = YES; | 345 pendingStart_ = YES; |
| 225 [centralManager_ stopScan]; | 346 [self reallyStop]; |
| 226 } | 347 } |
| 227 } | 348 } |
| 228 [delegate_ scannerBluetoothStatusUpdated:self]; | 349 [delegate_ scannerBluetoothStatusUpdated:self]; |
| 229 } | 350 } |
| 230 | 351 |
| 231 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData { | 352 + (BeaconType)beaconTypeForAdvertisementData:(NSDictionary*)advertisementData { |
| 232 NSDictionary* serviceData = | 353 NSDictionary* serviceData = |
| 233 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]; | 354 [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]; |
| 234 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]]) | 355 if ([serviceData objectForKey:[CBUUID UUIDWithString:kUriBeaconServiceUUID]]) |
| 235 return BEACON_TYPE_URIBEACON; | 356 return BEACON_TYPE_URIBEACON; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 DCHECK(data); | 388 DCHECK(data); |
| 268 | 389 |
| 269 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner | 390 base::scoped_nsobject<PhysicalWebDevice> device([PhysicalWebScanner |
| 270 newDeviceFromData:data | 391 newDeviceFromData:data |
| 271 rssi:[RSSI intValue] | 392 rssi:[RSSI intValue] |
| 272 type:type]); | 393 type:type]); |
| 273 // Skip if the data couldn't be parsed. | 394 // Skip if the data couldn't be parsed. |
| 274 if (!device.get()) | 395 if (!device.get()) |
| 275 return; | 396 return; |
| 276 | 397 |
| 398 [scanTimestamps_ setObject:[NSDate date] forKey:[device requestURL]]; | |
|
Olivier
2016/10/13 13:00:19
Would it make sense to add this to the device obje
mattreynolds
2016/10/18 18:56:47
Done.
| |
| 399 | |
| 277 // Skip if the URL has already been seen. | 400 // Skip if the URL has already been seen. |
| 278 if ([devicesUrls_ containsObject:[device url]]) | 401 if ([devicesUrls_ containsObject:[device requestURL]]) |
| 279 return; | 402 return; |
| 280 [devicesUrls_ addObject:[device url]]; | 403 [devicesUrls_ addObject:[device requestURL]]; |
| 281 | 404 |
| 282 if (networkRequestEnabled_) { | 405 if (networkRequestEnabled_) { |
| 283 [self requestMetadataForDevice:device]; | 406 [self requestMetadataForDevice:device]; |
| 284 } else { | 407 } else { |
| 285 [unresolvedDevices_ addObject:device]; | 408 [unresolvedDevices_ addObject:device]; |
| 286 [delegate_ scannerUpdatedDevices:self]; | 409 [delegate_ scannerUpdatedDevices:self]; |
| 287 } | 410 } |
| 288 } | 411 } |
| 289 | 412 |
| 290 #pragma mark - | 413 #pragma mark - |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 319 std::string utf8URI; | 442 std::string utf8URI; |
| 320 device::DecodeUriBeaconUri(encodedURI, utf8URI); | 443 device::DecodeUriBeaconUri(encodedURI, utf8URI); |
| 321 NSString* uriString = base::SysUTF8ToNSString(utf8URI); | 444 NSString* uriString = base::SysUTF8ToNSString(utf8URI); |
| 322 NSURL* url = [NSURL URLWithString:uriString]; | 445 NSURL* url = [NSURL URLWithString:uriString]; |
| 323 | 446 |
| 324 // Ensure URL is valid. | 447 // Ensure URL is valid. |
| 325 if (!url) | 448 if (!url) |
| 326 return nil; | 449 return nil; |
| 327 | 450 |
| 328 return [[PhysicalWebDevice alloc] initWithURL:url | 451 return [[PhysicalWebDevice alloc] initWithURL:url |
| 329 requestURL:nil | 452 requestURL:url |
| 330 icon:nil | 453 icon:nil |
| 331 title:nil | 454 title:nil |
| 332 description:nil | 455 description:nil |
| 333 transmitPower:transmitPower | 456 transmitPower:transmitPower |
| 334 rssi:rssi | 457 rssi:rssi |
| 335 rank:physical_web::kMaxRank]; | 458 rank:physical_web::kMaxRank]; |
| 336 } | 459 } |
| 337 | 460 |
| 338 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device { | 461 - (void)requestMetadataForDevice:(PhysicalWebDevice*)device { |
| 339 base::scoped_nsobject<PhysicalWebRequest> request( | 462 base::scoped_nsobject<PhysicalWebRequest> request( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 352 [strongSelf.get()->devices_ addObject:device]; | 475 [strongSelf.get()->devices_ addObject:device]; |
| 353 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf]; | 476 [strongSelf.get()->delegate_ scannerUpdatedDevices:weakSelf]; |
| 354 [strongSelf.get()->finalUrls_ addObject:[device url]]; | 477 [strongSelf.get()->finalUrls_ addObject:[device url]]; |
| 355 } | 478 } |
| 356 } | 479 } |
| 357 [strongSelf.get()->pendingRequests_ removeObject:strongRequest]; | 480 [strongSelf.get()->pendingRequests_ removeObject:strongRequest]; |
| 358 }]; | 481 }]; |
| 359 } | 482 } |
| 360 | 483 |
| 361 @end | 484 @end |
| OLD | NEW |