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

Side by Side Diff: chrome/browser/geolocation/core_location_data_provider_mac.mm

Issue 6037016: Fix incorrect assertion following the move of Geolocation provider in to its own thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nits. Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // This file contains the class definitions for the CoreLocation data provider 5 // This file contains the class definitions for the CoreLocation data provider
6 // class and the accompanying Objective C wrapper class. This data provider 6 // class and the accompanying Objective C wrapper class. This data provider
7 // is used to allow the CoreLocation wrapper to run on the UI thread, since 7 // is used to allow the CoreLocation wrapper to run on the UI thread, since
8 // CLLocationManager's start and stop updating methods must be called from a 8 // CLLocationManager's start and stop updating methods must be called from a
9 // thread with an active NSRunLoop. Currently only the UI thread appears to 9 // thread with an active NSRunLoop. Currently only the UI thread appears to
10 // fill that requirement. 10 // fill that requirement.
11 11
12 #include "chrome/browser/geolocation/core_location_data_provider_mac.h" 12 #include "chrome/browser/geolocation/core_location_data_provider_mac.h"
13 #include "chrome/browser/geolocation/core_location_provider_mac.h" 13 #include "chrome/browser/geolocation/core_location_provider_mac.h"
14 #include "chrome/browser/geolocation/geolocation_provider.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/time.h" 16 #include "base/time.h"
16 17
17 // A few required declarations since the CoreLocation headers are not available 18 // A few required declarations since the CoreLocation headers are not available
18 // with the Mac OS X 10.5 SDK. 19 // with the Mac OS X 10.5 SDK.
19 // TODO(jorgevillatoro): Remove these declarations when we build against 10.6 20 // TODO(jorgevillatoro): Remove these declarations when we build against 10.6
20 21
21 // This idea was borrowed from wifi_data_provider_corewlan_mac.mm 22 // This idea was borrowed from wifi_data_provider_corewlan_mac.mm
22 typedef double CLLocationDegrees; 23 typedef double CLLocationDegrees;
23 typedef double CLLocationAccuracy; 24 typedef double CLLocationAccuracy;
(...skipping 10 matching lines...) Expand all
34 kCLErrorDenied 35 kCLErrorDenied
35 }; 36 };
36 37
37 @interface CLLocationManager : NSObject 38 @interface CLLocationManager : NSObject
38 + (BOOL)locationServicesEnabled; 39 + (BOOL)locationServicesEnabled;
39 @property(assign) id delegate; 40 @property(assign) id delegate;
40 - (void)startUpdatingLocation; 41 - (void)startUpdatingLocation;
41 - (void)stopUpdatingLocation; 42 - (void)stopUpdatingLocation;
42 @end 43 @end
43 44
44 @interface CLLocation : NSObject <NSCopying, NSCoding> 45 @interface CLLocation : NSObject<NSCopying, NSCoding>
45 @property(readonly) CLLocationCoordinate2D coordinate; 46 @property(readonly) CLLocationCoordinate2D coordinate;
46 @property(readonly) CLLocationDistance altitude; 47 @property(readonly) CLLocationDistance altitude;
47 @property(readonly) CLLocationAccuracy horizontalAccuracy; 48 @property(readonly) CLLocationAccuracy horizontalAccuracy;
48 @property(readonly) CLLocationAccuracy verticalAccuracy; 49 @property(readonly) CLLocationAccuracy verticalAccuracy;
49 @property(readonly) CLLocationDirection course; 50 @property(readonly) CLLocationDirection course;
50 @property(readonly) CLLocationSpeed speed; 51 @property(readonly) CLLocationSpeed speed;
51 @end 52 @end
52 53
53 @protocol CLLocationManagerDelegate 54 @protocol CLLocationManagerDelegate
54 - (void)locationManager:(CLLocationManager*)manager 55 - (void)locationManager:(CLLocationManager*)manager
55 didUpdateToLocation:(CLLocation*)newLocation 56 didUpdateToLocation:(CLLocation*)newLocation
56 fromLocation:(CLLocation*)oldLocation; 57 fromLocation:(CLLocation*)oldLocation;
57 - (void)locationManager:(CLLocationManager*)manager 58 - (void)locationManager:(CLLocationManager*)manager
58 didFailWithError:(NSError*)error; 59 didFailWithError:(NSError*)error;
59 @end 60 @end
60 61
61 // This wrapper class receives CLLocation objects from CoreLocation, converts 62 // This wrapper class receives CLLocation objects from CoreLocation, converts
62 // them to Geoposition objects, and passes them on to the data provider class 63 // them to Geoposition objects, and passes them on to the data provider class
63 // Note: This class has some specific threading requirements, inherited from 64 // Note: This class has some specific threading requirements, inherited from
64 // CLLocationManager. The location manaager's start and stop updating 65 // CLLocationManager. The location manaager's start and stop updating
65 // methods must be called from a thread that has an active run loop (which 66 // methods must be called from a thread that has an active run loop (which
66 // seems to only be the UI thread) 67 // seems to only be the UI thread)
67 @interface CoreLocationWrapperMac : NSObject <CLLocationManagerDelegate> 68 @interface CoreLocationWrapperMac : NSObject<CLLocationManagerDelegate>
68 { 69 {
69 @private 70 @private
70 NSBundle* bundle_; 71 NSBundle* bundle_;
71 Class locationManagerClass_; 72 Class locationManagerClass_;
72 id locationManager_; 73 id locationManager_;
73 CoreLocationDataProviderMac* dataProvider_; 74 CoreLocationDataProviderMac* dataProvider_;
74 } 75 }
75 76
76 - (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider; 77 - (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider;
77 - (void)dealloc; 78 - (void)dealloc;
78 79
79 // Can be called from any thread since it does not require an NSRunLoop. However 80 // Can be called from any thread since it does not require an NSRunLoop. However
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } 113 }
113 114
114 // Load the bundle and check to see if location services are enabled 115 // Load the bundle and check to see if location services are enabled
115 // but don't do anything else 116 // but don't do anything else
116 - (BOOL)locationDataAvailable { 117 - (BOOL)locationDataAvailable {
117 return ([self loadCoreLocationBundle] && 118 return ([self loadCoreLocationBundle] &&
118 [locationManagerClass_ locationServicesEnabled]); 119 [locationManagerClass_ locationServicesEnabled]);
119 } 120 }
120 121
121 - (void)startLocation { 122 - (void)startLocation {
122 if([self locationDataAvailable]) { 123 if ([self locationDataAvailable]) {
123 if(!locationManager_) { 124 if (!locationManager_) {
124 locationManager_ = [[locationManagerClass_ alloc] init]; 125 locationManager_ = [[locationManagerClass_ alloc] init];
125 [locationManager_ setDelegate:self]; 126 [locationManager_ setDelegate:self];
126 } 127 }
127 [locationManager_ startUpdatingLocation]; 128 [locationManager_ startUpdatingLocation];
128 } 129 }
129 } 130 }
130 131
131 - (void)stopLocation { 132 - (void)stopLocation {
132 [locationManager_ stopUpdatingLocation]; 133 [locationManager_ stopUpdatingLocation];
133 } 134 }
(...skipping 10 matching lines...) Expand all
144 position.speed = [newLocation speed]; 145 position.speed = [newLocation speed];
145 position.heading = [newLocation course]; 146 position.heading = [newLocation course];
146 position.timestamp = base::Time::Now(); 147 position.timestamp = base::Time::Now();
147 position.error_code = Geoposition::ERROR_CODE_NONE; 148 position.error_code = Geoposition::ERROR_CODE_NONE;
148 dataProvider_->UpdatePosition(&position); 149 dataProvider_->UpdatePosition(&position);
149 } 150 }
150 151
151 - (void)locationManager:(CLLocationManager*)manager 152 - (void)locationManager:(CLLocationManager*)manager
152 didFailWithError:(NSError*)error { 153 didFailWithError:(NSError*)error {
153 Geoposition position; 154 Geoposition position;
154 switch([error code]) { 155 switch ([error code]) {
155 case kCLErrorLocationUnknown: 156 case kCLErrorLocationUnknown:
156 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; 157 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
157 break; 158 break;
158 case kCLErrorDenied: 159 case kCLErrorDenied:
159 position.error_code = Geoposition::ERROR_CODE_PERMISSION_DENIED; 160 position.error_code = Geoposition::ERROR_CODE_PERMISSION_DENIED;
160 break; 161 break;
161 default: 162 default:
162 NOTREACHED() << "Unknown CoreLocation error: " << [error code]; 163 NOTREACHED() << "Unknown CoreLocation error: " << [error code];
163 return; 164 return;
164 } 165 }
165 dataProvider_->UpdatePosition(&position); 166 dataProvider_->UpdatePosition(&position);
166 } 167 }
167 168
168 - (BOOL)loadCoreLocationBundle { 169 - (BOOL)loadCoreLocationBundle {
169 if(!bundle_) { 170 if (!bundle_) {
170 bundle_ = [[NSBundle alloc] 171 bundle_ = [[NSBundle alloc]
171 initWithPath:@"/System/Library/Frameworks/CoreLocation.framework"]; 172 initWithPath:@"/System/Library/Frameworks/CoreLocation.framework"];
172 if(!bundle_) { 173 if (!bundle_) {
173 DLOG(WARNING) << "Couldn't load CoreLocation Framework"; 174 DLOG(WARNING) << "Couldn't load CoreLocation Framework";
174 return NO; 175 return NO;
175 } 176 }
176 177
177 locationManagerClass_ = [bundle_ classNamed:@"CLLocationManager"]; 178 locationManagerClass_ = [bundle_ classNamed:@"CLLocationManager"];
178 } 179 }
179 180
180 return YES; 181 return YES;
181 } 182 }
182 183
183 @end 184 @end
184 185
185 CoreLocationDataProviderMac::CoreLocationDataProviderMac() { 186 CoreLocationDataProviderMac::CoreLocationDataProviderMac() {
186 if(!BrowserThread::GetCurrentThreadIdentifier(&origin_thread_id_)) 187 if (MessageLoop::current() !=
187 NOTREACHED() << 188 GeolocationProvider::GetInstance()->message_loop()) {
188 "CoreLocation data provider must be created in a valid BrowserThread."; 189 NOTREACHED() << "CoreLocation data provider must be created on "
190 "the Geolocation thread.";
191 }
189 provider_ = NULL; 192 provider_ = NULL;
190 wrapper_.reset([[CoreLocationWrapperMac alloc] initWithDataProvider:this]); 193 wrapper_.reset([[CoreLocationWrapperMac alloc] initWithDataProvider:this]);
191 } 194 }
192 195
193 CoreLocationDataProviderMac::~CoreLocationDataProviderMac() { 196 CoreLocationDataProviderMac::~CoreLocationDataProviderMac() {
194 } 197 }
195 198
196 // Returns true if the CoreLocation wrapper can load the framework and 199 // Returns true if the CoreLocation wrapper can load the framework and
197 // location services are enabled. The pointer argument will only be accessed 200 // location services are enabled. The pointer argument will only be accessed
198 // in the origin thread. 201 // in the origin thread.
199 bool CoreLocationDataProviderMac:: 202 bool CoreLocationDataProviderMac::
200 StartUpdating(CoreLocationProviderMac* provider) { 203 StartUpdating(CoreLocationProviderMac* provider) {
201 DCHECK(provider); 204 DCHECK(provider);
202 DCHECK(!provider_) << "StartUpdating called twice"; 205 DCHECK(!provider_) << "StartUpdating called twice";
203 if(![wrapper_ locationDataAvailable]) return false; 206 if (![wrapper_ locationDataAvailable]) return false;
204 provider_ = provider; 207 provider_ = provider;
205 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 208 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
206 NewRunnableMethod(this, &CoreLocationDataProviderMac::StartUpdatingTask)); 209 NewRunnableMethod(this, &CoreLocationDataProviderMac::StartUpdatingTask));
207 return true; 210 return true;
208 } 211 }
209 212
210 // Clears provider_ so that any leftover messages from CoreLocation get ignored 213 // Clears provider_ so that any leftover messages from CoreLocation get ignored
211 void CoreLocationDataProviderMac::StopUpdating() { 214 void CoreLocationDataProviderMac::StopUpdating() {
212 provider_ = NULL; 215 provider_ = NULL;
213 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 216 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
214 NewRunnableMethod(this, 217 NewRunnableMethod(this,
215 &CoreLocationDataProviderMac::StopUpdatingTask)); 218 &CoreLocationDataProviderMac::StopUpdatingTask));
216 } 219 }
217 220
218 void CoreLocationDataProviderMac::UpdatePosition(Geoposition *position) { 221 void CoreLocationDataProviderMac::UpdatePosition(Geoposition *position) {
219 BrowserThread::PostTask(origin_thread_id_, FROM_HERE, 222 GeolocationProvider::GetInstance()->message_loop()->PostTask(FROM_HERE,
220 NewRunnableMethod(this, 223 NewRunnableMethod(this,
221 &CoreLocationDataProviderMac::PositionUpdated, 224 &CoreLocationDataProviderMac::PositionUpdated,
222 *position)); 225 *position));
223 } 226 }
224 227
225 // Runs in BrowserThread::UI 228 // Runs in BrowserThread::UI
226 void CoreLocationDataProviderMac::StartUpdatingTask() { 229 void CoreLocationDataProviderMac::StartUpdatingTask() {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
228 [wrapper_ startLocation]; 231 [wrapper_ startLocation];
229 } 232 }
230 233
231 // Runs in BrowserThread::UI 234 // Runs in BrowserThread::UI
232 void CoreLocationDataProviderMac::StopUpdatingTask() { 235 void CoreLocationDataProviderMac::StopUpdatingTask() {
233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
234 [wrapper_ stopLocation]; 237 [wrapper_ stopLocation];
235 } 238 }
236 239
237 void CoreLocationDataProviderMac::PositionUpdated(Geoposition position) { 240 void CoreLocationDataProviderMac::PositionUpdated(Geoposition position) {
238 DCHECK(BrowserThread::CurrentlyOn(origin_thread_id_)); 241 DCHECK(MessageLoop::current() ==
239 if(provider_) 242 GeolocationProvider::GetInstance()->message_loop());
243 if (provider_)
240 provider_->SetPosition(&position); 244 provider_->SetPosition(&position);
241 } 245 }
OLDNEW
« no previous file with comments | « chrome/browser/geolocation/core_location_data_provider_mac.h ('k') | chrome/browser/geolocation/core_location_provider_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698