Index: ios/chrome/browser/geolocation/location_manager.mm |
diff --git a/ios/chrome/browser/geolocation/location_manager.mm b/ios/chrome/browser/geolocation/location_manager.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cab3ea7f1d571affde0f366e4605a8143cc64663 |
--- /dev/null |
+++ b/ios/chrome/browser/geolocation/location_manager.mm |
@@ -0,0 +1,150 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "ios/chrome/browser/geolocation/location_manager.h" |
+ |
+#import "base/ios/weak_nsobject.h" |
+#include "base/mac/scoped_nsobject.h" |
+#import "ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h" |
+#import "ios/chrome/browser/geolocation/location_manager+Testing.h" |
+#import "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
+#import "ios/public/provider/chrome/browser/geolocation_updater_provider.h" |
+ |
+namespace { |
+ |
+const CLLocationDistance kLocationDesiredAccuracy = |
+ kCLLocationAccuracyHundredMeters; |
+// Number of seconds to wait before automatically stopping location updates. |
+const NSTimeInterval kLocationStopUpdateDelay = 5.0; |
+// A large value to disable automatic location updates in GeolocationUpdater. |
+const NSTimeInterval kLocationUpdateInterval = 365.0 * 24.0 * 60.0 * 60.0; |
+ |
+} // namespace |
+ |
+@interface LocationManager () { |
+ base::scoped_nsprotocol<id<GeolocationUpdater>> _locationUpdater; |
+ base::scoped_nsobject<CLLocation> _currentLocation; |
+ base::WeakNSProtocol<id<LocationManagerDelegate>> _delegate; |
+ base::scoped_nsobject<NSDate> _startTime; |
+} |
+ |
+// Handles GeolocationUpdater notification for an updated device location. |
+- (void)handleLocationUpdateNotification:(NSNotification*)notification; |
+// Handles GeolocationUpdater notification for ending device location updates. |
+- (void)handleLocationStopNotification:(NSNotification*)notification; |
+// Handles GeolocationUpdater notification for changing authorization. |
+- (void)handleAuthorizationChangeNotification:(NSNotification*)notification; |
+ |
+@end |
+ |
+@implementation LocationManager |
+ |
+- (id)init { |
+ self = [super init]; |
+ if (self) { |
+ ios::GeolocationUpdaterProvider* provider = |
+ ios::GetChromeBrowserProvider()->GetGeolocationUpdaterProvider(); |
+ |
+ // |provider| may be null in tests. |
+ if (provider) { |
+ _locationUpdater.reset(provider->CreateGeolocationUpdater(false)); |
+ [_locationUpdater setDesiredAccuracy:kLocationDesiredAccuracy |
+ distanceFilter:kLocationDesiredAccuracy / 2]; |
+ [_locationUpdater setStopUpdateDelay:kLocationStopUpdateDelay]; |
+ [_locationUpdater setUpdateInterval:kLocationUpdateInterval]; |
+ |
+ NSNotificationCenter* defaultCenter = |
+ [NSNotificationCenter defaultCenter]; |
+ [defaultCenter addObserver:self |
+ selector:@selector(handleLocationUpdateNotification:) |
+ name:provider->GetUpdateNotificationName() |
+ object:_locationUpdater]; |
+ [defaultCenter addObserver:self |
+ selector:@selector(handleLocationStopNotification:) |
+ name:provider->GetStopNotificationName() |
+ object:_locationUpdater]; |
+ [defaultCenter |
+ addObserver:self |
+ selector:@selector(handleAuthorizationChangeNotification:) |
+ name:provider->GetAuthorizationChangeNotificationName() |
+ object:nil]; |
+ } |
+ } |
+ return self; |
+} |
+ |
+- (void)dealloc { |
+ [[NSNotificationCenter defaultCenter] removeObserver:self]; |
+ [super dealloc]; |
+} |
+ |
+- (CLAuthorizationStatus)authorizationStatus { |
+ return [CLLocationManager authorizationStatus]; |
+} |
+ |
+- (CLLocation*)currentLocation { |
+ if (!_currentLocation) |
+ _currentLocation.reset([[_locationUpdater currentLocation] retain]); |
+ return _currentLocation; |
+} |
+ |
+- (id<LocationManagerDelegate>)delegate { |
+ return _delegate; |
+} |
+ |
+- (void)setDelegate:(id<LocationManagerDelegate>)delegate { |
+ _delegate.reset(delegate); |
+} |
+ |
+- (BOOL)locationServicesEnabled { |
+ return [CLLocationManager locationServicesEnabled]; |
+} |
+ |
+- (void)startUpdatingLocation { |
+ CLLocation* currentLocation = self.currentLocation; |
+ if (!currentLocation || [currentLocation cr_shouldRefresh]) { |
+ if (![_locationUpdater isEnabled]) |
+ _startTime.reset([[NSDate alloc] init]); |
+ |
+ [_locationUpdater requestWhenInUseAuthorization]; |
+ [_locationUpdater setEnabled:YES]; |
+ } |
+} |
+ |
+- (void)stopUpdatingLocation { |
+ [_locationUpdater setEnabled:NO]; |
+} |
+ |
+#pragma mark - Private |
+ |
+- (void)handleLocationUpdateNotification:(NSNotification*)notification { |
+ NSString* newLocationKey = ios::GetChromeBrowserProvider() |
+ ->GetGeolocationUpdaterProvider() |
+ ->GetUpdateNewLocationKey(); |
+ CLLocation* location = [[notification userInfo] objectForKey:newLocationKey]; |
+ if (location) { |
+ _currentLocation.reset([location retain]); |
+ |
+ if (_startTime) { |
+ NSTimeInterval interval = -[_startTime timeIntervalSinceNow]; |
+ [_currentLocation cr_setAcquisitionInterval:interval]; |
+ } |
+ } |
+} |
+ |
+- (void)handleLocationStopNotification:(NSNotification*)notification { |
+ [_locationUpdater setEnabled:NO]; |
+} |
+ |
+- (void)handleAuthorizationChangeNotification:(NSNotification*)notification { |
+ [_delegate locationManagerDidChangeAuthorizationStatus:self]; |
+} |
+ |
+#pragma mark - LocationManager+Testing |
+ |
+- (void)setGeolocationUpdater:(id<GeolocationUpdater>)geolocationUpdater { |
+ _locationUpdater.reset([geolocationUpdater retain]); |
+} |
+ |
+@end |