OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/geolocation/location_manager.h" |
| 6 |
| 7 #import "base/ios/weak_nsobject.h" |
| 8 #include "base/mac/scoped_nsobject.h" |
| 9 #import "ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h" |
| 10 #import "ios/chrome/browser/geolocation/location_manager+Testing.h" |
| 11 #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
| 12 #import "ios/public/provider/chrome/browser/geolocation_updater_provider.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 const CLLocationDistance kLocationDesiredAccuracy = |
| 17 kCLLocationAccuracyHundredMeters; |
| 18 // Number of seconds to wait before automatically stopping location updates. |
| 19 const NSTimeInterval kLocationStopUpdateDelay = 5.0; |
| 20 // A large value to disable automatic location updates in GeolocationUpdater. |
| 21 const NSTimeInterval kLocationUpdateInterval = 365.0 * 24.0 * 60.0 * 60.0; |
| 22 |
| 23 } // namespace |
| 24 |
| 25 @interface LocationManager () { |
| 26 base::scoped_nsprotocol<id<GeolocationUpdater>> _locationUpdater; |
| 27 base::scoped_nsobject<CLLocation> _currentLocation; |
| 28 base::WeakNSProtocol<id<LocationManagerDelegate>> _delegate; |
| 29 base::scoped_nsobject<NSDate> _startTime; |
| 30 } |
| 31 |
| 32 // Handles GeolocationUpdater notification for an updated device location. |
| 33 - (void)handleLocationUpdateNotification:(NSNotification*)notification; |
| 34 // Handles GeolocationUpdater notification for ending device location updates. |
| 35 - (void)handleLocationStopNotification:(NSNotification*)notification; |
| 36 // Handles GeolocationUpdater notification for changing authorization. |
| 37 - (void)handleAuthorizationChangeNotification:(NSNotification*)notification; |
| 38 |
| 39 @end |
| 40 |
| 41 @implementation LocationManager |
| 42 |
| 43 - (id)init { |
| 44 self = [super init]; |
| 45 if (self) { |
| 46 ios::GeolocationUpdaterProvider* provider = |
| 47 ios::GetChromeBrowserProvider()->GetGeolocationUpdaterProvider(); |
| 48 |
| 49 // |provider| may be null in tests. |
| 50 if (provider) { |
| 51 _locationUpdater.reset(provider->CreateGeolocationUpdater(false)); |
| 52 [_locationUpdater setDesiredAccuracy:kLocationDesiredAccuracy |
| 53 distanceFilter:kLocationDesiredAccuracy / 2]; |
| 54 [_locationUpdater setStopUpdateDelay:kLocationStopUpdateDelay]; |
| 55 [_locationUpdater setUpdateInterval:kLocationUpdateInterval]; |
| 56 |
| 57 NSNotificationCenter* defaultCenter = |
| 58 [NSNotificationCenter defaultCenter]; |
| 59 [defaultCenter addObserver:self |
| 60 selector:@selector(handleLocationUpdateNotification:) |
| 61 name:provider->GetUpdateNotificationName() |
| 62 object:_locationUpdater]; |
| 63 [defaultCenter addObserver:self |
| 64 selector:@selector(handleLocationStopNotification:) |
| 65 name:provider->GetStopNotificationName() |
| 66 object:_locationUpdater]; |
| 67 [defaultCenter |
| 68 addObserver:self |
| 69 selector:@selector(handleAuthorizationChangeNotification:) |
| 70 name:provider->GetAuthorizationChangeNotificationName() |
| 71 object:nil]; |
| 72 } |
| 73 } |
| 74 return self; |
| 75 } |
| 76 |
| 77 - (void)dealloc { |
| 78 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 79 [super dealloc]; |
| 80 } |
| 81 |
| 82 - (CLAuthorizationStatus)authorizationStatus { |
| 83 return [CLLocationManager authorizationStatus]; |
| 84 } |
| 85 |
| 86 - (CLLocation*)currentLocation { |
| 87 if (!_currentLocation) |
| 88 _currentLocation.reset([[_locationUpdater currentLocation] retain]); |
| 89 return _currentLocation; |
| 90 } |
| 91 |
| 92 - (id<LocationManagerDelegate>)delegate { |
| 93 return _delegate; |
| 94 } |
| 95 |
| 96 - (void)setDelegate:(id<LocationManagerDelegate>)delegate { |
| 97 _delegate.reset(delegate); |
| 98 } |
| 99 |
| 100 - (BOOL)locationServicesEnabled { |
| 101 return [CLLocationManager locationServicesEnabled]; |
| 102 } |
| 103 |
| 104 - (void)startUpdatingLocation { |
| 105 CLLocation* currentLocation = self.currentLocation; |
| 106 if (!currentLocation || [currentLocation cr_shouldRefresh]) { |
| 107 if (![_locationUpdater isEnabled]) |
| 108 _startTime.reset([[NSDate alloc] init]); |
| 109 |
| 110 [_locationUpdater requestWhenInUseAuthorization]; |
| 111 [_locationUpdater setEnabled:YES]; |
| 112 } |
| 113 } |
| 114 |
| 115 - (void)stopUpdatingLocation { |
| 116 [_locationUpdater setEnabled:NO]; |
| 117 } |
| 118 |
| 119 #pragma mark - Private |
| 120 |
| 121 - (void)handleLocationUpdateNotification:(NSNotification*)notification { |
| 122 NSString* newLocationKey = ios::GetChromeBrowserProvider() |
| 123 ->GetGeolocationUpdaterProvider() |
| 124 ->GetUpdateNewLocationKey(); |
| 125 CLLocation* location = [[notification userInfo] objectForKey:newLocationKey]; |
| 126 if (location) { |
| 127 _currentLocation.reset([location retain]); |
| 128 |
| 129 if (_startTime) { |
| 130 NSTimeInterval interval = -[_startTime timeIntervalSinceNow]; |
| 131 [_currentLocation cr_setAcquisitionInterval:interval]; |
| 132 } |
| 133 } |
| 134 } |
| 135 |
| 136 - (void)handleLocationStopNotification:(NSNotification*)notification { |
| 137 [_locationUpdater setEnabled:NO]; |
| 138 } |
| 139 |
| 140 - (void)handleAuthorizationChangeNotification:(NSNotification*)notification { |
| 141 [_delegate locationManagerDidChangeAuthorizationStatus:self]; |
| 142 } |
| 143 |
| 144 #pragma mark - LocationManager+Testing |
| 145 |
| 146 - (void)setGeolocationUpdater:(id<GeolocationUpdater>)geolocationUpdater { |
| 147 _locationUpdater.reset([geolocationUpdater retain]); |
| 148 } |
| 149 |
| 150 @end |
OLD | NEW |