Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / ios / chrome / browser / geolocation / location_manager.mm
blobcab3ea7f1d571affde0f366e4605a8143cc64663
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.
5 #import "ios/chrome/browser/geolocation/location_manager.h"
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"
14 namespace {
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;
23 }  // namespace
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;
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;
39 @end
41 @implementation LocationManager
43 - (id)init {
44   self = [super init];
45   if (self) {
46     ios::GeolocationUpdaterProvider* provider =
47         ios::GetChromeBrowserProvider()->GetGeolocationUpdaterProvider();
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];
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;
77 - (void)dealloc {
78   [[NSNotificationCenter defaultCenter] removeObserver:self];
79   [super dealloc];
82 - (CLAuthorizationStatus)authorizationStatus {
83   return [CLLocationManager authorizationStatus];
86 - (CLLocation*)currentLocation {
87   if (!_currentLocation)
88     _currentLocation.reset([[_locationUpdater currentLocation] retain]);
89   return _currentLocation;
92 - (id<LocationManagerDelegate>)delegate {
93   return _delegate;
96 - (void)setDelegate:(id<LocationManagerDelegate>)delegate {
97   _delegate.reset(delegate);
100 - (BOOL)locationServicesEnabled {
101   return [CLLocationManager locationServicesEnabled];
104 - (void)startUpdatingLocation {
105   CLLocation* currentLocation = self.currentLocation;
106   if (!currentLocation || [currentLocation cr_shouldRefresh]) {
107     if (![_locationUpdater isEnabled])
108       _startTime.reset([[NSDate alloc] init]);
110     [_locationUpdater requestWhenInUseAuthorization];
111     [_locationUpdater setEnabled:YES];
112   }
115 - (void)stopUpdatingLocation {
116   [_locationUpdater setEnabled:NO];
119 #pragma mark - Private
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]);
129     if (_startTime) {
130       NSTimeInterval interval = -[_startTime timeIntervalSinceNow];
131       [_currentLocation cr_setAcquisitionInterval:interval];
132     }
133   }
136 - (void)handleLocationStopNotification:(NSNotification*)notification {
137   [_locationUpdater setEnabled:NO];
140 - (void)handleAuthorizationChangeNotification:(NSNotification*)notification {
141   [_delegate locationManagerDidChangeAuthorizationStatus:self];
144 #pragma mark - LocationManager+Testing
146 - (void)setGeolocationUpdater:(id<GeolocationUpdater>)geolocationUpdater {
147   _locationUpdater.reset([geolocationUpdater retain]);
150 @end