| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #include "chrome/browser/extensions/api/location/location_manager.h" | 5 #include "chrome/browser/extensions/api/location/location_manager.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 LocationRequest::LocationRequest( | 206 LocationRequest::LocationRequest( |
| 207 const base::WeakPtr<LocationManager>& location_manager, | 207 const base::WeakPtr<LocationManager>& location_manager, |
| 208 const std::string& extension_id, | 208 const std::string& extension_id, |
| 209 const std::string& request_name, | 209 const std::string& request_name, |
| 210 const double* distance_update_threshold_meters, | 210 const double* distance_update_threshold_meters, |
| 211 const double* time_between_updates_ms) | 211 const double* time_between_updates_ms) |
| 212 : request_name_(request_name), | 212 : request_name_(request_name), |
| 213 extension_id_(extension_id), | 213 extension_id_(extension_id), |
| 214 location_manager_(location_manager) { | 214 location_manager_(location_manager) { |
| 215 // TODO(vadimt): use request_info. | 215 // TODO(vadimt): use request_info. |
| 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 216 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 217 | 217 |
| 218 if (time_between_updates_ms) { | 218 if (time_between_updates_ms) { |
| 219 update_policies_.push_back( | 219 update_policies_.push_back( |
| 220 new updatepolicy::TimeBasedUpdatePolicy( | 220 new updatepolicy::TimeBasedUpdatePolicy( |
| 221 *time_between_updates_ms)); | 221 *time_between_updates_ms)); |
| 222 } | 222 } |
| 223 | 223 |
| 224 if (distance_update_threshold_meters) { | 224 if (distance_update_threshold_meters) { |
| 225 update_policies_.push_back( | 225 update_policies_.push_back( |
| 226 new updatepolicy::DistanceBasedUpdatePolicy( | 226 new updatepolicy::DistanceBasedUpdatePolicy( |
| 227 *distance_update_threshold_meters)); | 227 *distance_update_threshold_meters)); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 | 230 |
| 231 void LocationRequest::Initialize() { | 231 void LocationRequest::Initialize() { |
| 232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 232 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 233 callback_ = base::Bind(&LocationRequest::OnLocationUpdate, | 233 callback_ = base::Bind(&LocationRequest::OnLocationUpdate, |
| 234 base::Unretained(this)); | 234 base::Unretained(this)); |
| 235 | 235 |
| 236 BrowserThread::PostTask( | 236 BrowserThread::PostTask( |
| 237 BrowserThread::IO, | 237 BrowserThread::IO, |
| 238 FROM_HERE, | 238 FROM_HERE, |
| 239 base::Bind(&LocationRequest::AddObserverOnIOThread, | 239 base::Bind(&LocationRequest::AddObserverOnIOThread, |
| 240 this)); | 240 this)); |
| 241 } | 241 } |
| 242 | 242 |
| 243 void LocationRequest::GrantPermission() { | 243 void LocationRequest::GrantPermission() { |
| 244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 244 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 245 content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices(); | 245 content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 LocationRequest::~LocationRequest() { | 248 LocationRequest::~LocationRequest() { |
| 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 249 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 250 content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback( | 250 content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback( |
| 251 callback_); | 251 callback_); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void LocationRequest::AddObserverOnIOThread() { | 254 void LocationRequest::AddObserverOnIOThread() { |
| 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 255 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 256 | 256 |
| 257 // TODO(vadimt): This can get a location cached by GeolocationProvider, | 257 // TODO(vadimt): This can get a location cached by GeolocationProvider, |
| 258 // contrary to the API definition which says that creating a location watch | 258 // contrary to the API definition which says that creating a location watch |
| 259 // will get new location. | 259 // will get new location. |
| 260 content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback( | 260 content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback( |
| 261 callback_, true); | 261 callback_, true); |
| 262 } | 262 } |
| 263 | 263 |
| 264 void LocationRequest::OnLocationUpdate(const content::Geoposition& position) { | 264 void LocationRequest::OnLocationUpdate(const content::Geoposition& position) { |
| 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 266 if (ShouldSendUpdate(position)) { | 266 if (ShouldSendUpdate(position)) { |
| 267 OnPositionReported(position); | 267 OnPositionReported(position); |
| 268 BrowserThread::PostTask( | 268 BrowserThread::PostTask( |
| 269 BrowserThread::UI, | 269 BrowserThread::UI, |
| 270 FROM_HERE, | 270 FROM_HERE, |
| 271 base::Bind(&LocationManager::SendLocationUpdate, | 271 base::Bind(&LocationManager::SendLocationUpdate, |
| 272 location_manager_, | 272 location_manager_, |
| 273 extension_id_, | 273 extension_id_, |
| 274 request_name_, | 274 request_name_, |
| 275 position)); | 275 position)); |
| 276 } | 276 } |
| 277 } | 277 } |
| 278 | 278 |
| 279 bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) { | 279 bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) { |
| 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 281 for (UpdatePolicyVector::iterator it = update_policies_.begin(); | 281 for (UpdatePolicyVector::iterator it = update_policies_.begin(); |
| 282 it != update_policies_.end(); | 282 it != update_policies_.end(); |
| 283 ++it) { | 283 ++it) { |
| 284 if (!((*it)->ShouldSendUpdate(position))) { | 284 if (!((*it)->ShouldSendUpdate(position))) { |
| 285 return false; | 285 return false; |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 return true; | 288 return true; |
| 289 } | 289 } |
| 290 | 290 |
| 291 void LocationRequest::OnPositionReported(const content::Geoposition& position) { | 291 void LocationRequest::OnPositionReported(const content::Geoposition& position) { |
| 292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 292 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 293 for (UpdatePolicyVector::iterator it = update_policies_.begin(); | 293 for (UpdatePolicyVector::iterator it = update_policies_.begin(); |
| 294 it != update_policies_.end(); | 294 it != update_policies_.end(); |
| 295 ++it) { | 295 ++it) { |
| 296 (*it)->OnPositionReported(position); | 296 (*it)->OnPositionReported(position); |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| 300 LocationManager::LocationManager(content::BrowserContext* context) | 300 LocationManager::LocationManager(content::BrowserContext* context) |
| 301 : profile_(Profile::FromBrowserContext(context)) { | 301 : profile_(Profile::FromBrowserContext(context)) { |
| 302 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 302 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 303 content::Source<Profile>(profile_)); | 303 content::Source<Profile>(profile_)); |
| 304 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | 304 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
| 305 content::Source<Profile>(profile_)); | 305 content::Source<Profile>(profile_)); |
| 306 } | 306 } |
| 307 | 307 |
| 308 void LocationManager::AddLocationRequest( | 308 void LocationManager::AddLocationRequest( |
| 309 const std::string& extension_id, | 309 const std::string& extension_id, |
| 310 const std::string& request_name, | 310 const std::string& request_name, |
| 311 const double* distance_update_threshold_meters, | 311 const double* distance_update_threshold_meters, |
| 312 const double* time_between_updates_ms) { | 312 const double* time_between_updates_ms) { |
| 313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 313 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 314 // TODO(vadimt): Consider resuming requests after restarting the browser. | 314 // TODO(vadimt): Consider resuming requests after restarting the browser. |
| 315 | 315 |
| 316 // Override any old request with the same name. | 316 // Override any old request with the same name. |
| 317 RemoveLocationRequest(extension_id, request_name); | 317 RemoveLocationRequest(extension_id, request_name); |
| 318 | 318 |
| 319 LocationRequestPointer location_request = | 319 LocationRequestPointer location_request = |
| 320 new LocationRequest(AsWeakPtr(), | 320 new LocationRequest(AsWeakPtr(), |
| 321 extension_id, | 321 extension_id, |
| 322 request_name, | 322 request_name, |
| 323 distance_update_threshold_meters, | 323 distance_update_threshold_meters, |
| 324 time_between_updates_ms); | 324 time_between_updates_ms); |
| 325 location_request->Initialize(); | 325 location_request->Initialize(); |
| 326 location_requests_.insert( | 326 location_requests_.insert( |
| 327 LocationRequestMap::value_type(extension_id, location_request)); | 327 LocationRequestMap::value_type(extension_id, location_request)); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void LocationManager::RemoveLocationRequest(const std::string& extension_id, | 330 void LocationManager::RemoveLocationRequest(const std::string& extension_id, |
| 331 const std::string& name) { | 331 const std::string& name) { |
| 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 332 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 333 | 333 |
| 334 std::pair<LocationRequestMap::iterator, LocationRequestMap::iterator> | 334 std::pair<LocationRequestMap::iterator, LocationRequestMap::iterator> |
| 335 extension_range = location_requests_.equal_range(extension_id); | 335 extension_range = location_requests_.equal_range(extension_id); |
| 336 | 336 |
| 337 for (LocationRequestMap::iterator it = extension_range.first; | 337 for (LocationRequestMap::iterator it = extension_range.first; |
| 338 it != extension_range.second; | 338 it != extension_range.second; |
| 339 ++it) { | 339 ++it) { |
| 340 if (it->second->request_name() == name) { | 340 if (it->second->request_name() == name) { |
| 341 location_requests_.erase(it); | 341 location_requests_.erase(it); |
| 342 return; | 342 return; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 362 if (position.heading >= 0. && position.heading <= 360.) | 362 if (position.heading >= 0. && position.heading <= 360.) |
| 363 coordinates->heading.reset(new double(position.heading)); | 363 coordinates->heading.reset(new double(position.heading)); |
| 364 if (position.speed >= 0.) | 364 if (position.speed >= 0.) |
| 365 coordinates->speed.reset(new double(position.speed)); | 365 coordinates->speed.reset(new double(position.speed)); |
| 366 } | 366 } |
| 367 | 367 |
| 368 void LocationManager::SendLocationUpdate( | 368 void LocationManager::SendLocationUpdate( |
| 369 const std::string& extension_id, | 369 const std::string& extension_id, |
| 370 const std::string& request_name, | 370 const std::string& request_name, |
| 371 const content::Geoposition& position) { | 371 const content::Geoposition& position) { |
| 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 372 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 373 | 373 |
| 374 scoped_ptr<base::ListValue> args(new base::ListValue()); | 374 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 375 std::string event_name; | 375 std::string event_name; |
| 376 | 376 |
| 377 if (position.Validate() && | 377 if (position.Validate() && |
| 378 position.error_code == content::Geoposition::ERROR_CODE_NONE) { | 378 position.error_code == content::Geoposition::ERROR_CODE_NONE) { |
| 379 // Set data for onLocationUpdate event. | 379 // Set data for onLocationUpdate event. |
| 380 location::Location location; | 380 location::Location location; |
| 381 location.name = request_name; | 381 location.name = request_name; |
| 382 GeopositionToApiCoordinates(position, &location.coords); | 382 GeopositionToApiCoordinates(position, &location.coords); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 393 | 393 |
| 394 scoped_ptr<Event> event(new Event(event_name, args.Pass())); | 394 scoped_ptr<Event> event(new Event(event_name, args.Pass())); |
| 395 | 395 |
| 396 ExtensionSystem::Get(profile_)->event_router()-> | 396 ExtensionSystem::Get(profile_)->event_router()-> |
| 397 DispatchEventToExtension(extension_id, event.Pass()); | 397 DispatchEventToExtension(extension_id, event.Pass()); |
| 398 } | 398 } |
| 399 | 399 |
| 400 void LocationManager::Observe(int type, | 400 void LocationManager::Observe(int type, |
| 401 const content::NotificationSource& source, | 401 const content::NotificationSource& source, |
| 402 const content::NotificationDetails& details) { | 402 const content::NotificationDetails& details) { |
| 403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 403 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 404 | 404 |
| 405 switch (type) { | 405 switch (type) { |
| 406 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 406 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 407 // Grants permission to use geolocation once an extension with "location" | 407 // Grants permission to use geolocation once an extension with "location" |
| 408 // permission is loaded. | 408 // permission is loaded. |
| 409 const Extension* extension = | 409 const Extension* extension = |
| 410 content::Details<const Extension>(details).ptr(); | 410 content::Details<const Extension>(details).ptr(); |
| 411 | 411 |
| 412 if (extension->HasAPIPermission(APIPermission::kLocation)) { | 412 if (extension->HasAPIPermission(APIPermission::kLocation)) { |
| 413 BrowserThread::PostTask( | 413 BrowserThread::PostTask( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 438 LocationManager::GetFactoryInstance() { | 438 LocationManager::GetFactoryInstance() { |
| 439 return g_factory.Pointer(); | 439 return g_factory.Pointer(); |
| 440 } | 440 } |
| 441 | 441 |
| 442 // static | 442 // static |
| 443 LocationManager* LocationManager::Get(content::BrowserContext* context) { | 443 LocationManager* LocationManager::Get(content::BrowserContext* context) { |
| 444 return BrowserContextKeyedAPIFactory<LocationManager>::Get(context); | 444 return BrowserContextKeyedAPIFactory<LocationManager>::Get(context); |
| 445 } | 445 } |
| 446 | 446 |
| 447 } // namespace extensions | 447 } // namespace extensions |
| OLD | NEW |