Index: content/browser/geolocation/geolocation_provider_impl.cc |
=================================================================== |
--- content/browser/geolocation/geolocation_provider_impl.cc (revision 269041) |
+++ content/browser/geolocation/geolocation_provider_impl.cc (working copy) |
@@ -16,84 +16,44 @@ |
namespace content { |
-namespace { |
-void OverrideLocationForTestingOnIOThread( |
- const Geoposition& position, |
- const base::Closure& completion_callback, |
- scoped_refptr<base::MessageLoopProxy> callback_loop) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- GeolocationProviderImpl::GetInstance()->OverrideLocationForTesting(position); |
- callback_loop->PostTask(FROM_HERE, completion_callback); |
-} |
-} // namespace |
- |
GeolocationProvider* GeolocationProvider::GetInstance() { |
return GeolocationProviderImpl::GetInstance(); |
} |
-void GeolocationProvider::OverrideLocationForTesting( |
- const Geoposition& position, |
- const base::Closure& completion_callback) { |
- base::Closure closure = base::Bind(&OverrideLocationForTestingOnIOThread, |
- position, |
- completion_callback, |
- base::MessageLoopProxy::current()); |
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) |
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, closure); |
- else |
- closure.Run(); |
-} |
- |
-void GeolocationProviderImpl::AddLocationUpdateCallback( |
+scoped_ptr<GeolocationProvider::Subscription> |
+GeolocationProviderImpl::AddLocationUpdateCallback( |
const LocationUpdateCallback& callback, bool use_high_accuracy) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- bool found = false; |
- CallbackList::iterator i = callbacks_.begin(); |
- for (; i != callbacks_.end(); ++i) { |
- if (i->first.Equals(callback)) { |
- i->second = use_high_accuracy; |
- found = true; |
- break; |
- } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ scoped_ptr<GeolocationProvider::Subscription> rv; |
Michael van Ouwerkerk
2014/05/08 13:20:02
Nit: s/rv/subscription/
jam
2014/05/08 15:04:58
Done.
|
+ if (use_high_accuracy) { |
+ rv = high_accuracy_callbacks_.Add(callback); |
+ } else { |
+ rv = low_accuracy_callbacks_.Add(callback); |
} |
- if (!found) |
- callbacks_.push_back(std::make_pair(callback, use_high_accuracy)); |
OnClientsChanged(); |
if (position_.Validate() || |
position_.error_code != Geoposition::ERROR_CODE_NONE) { |
callback.Run(position_); |
} |
-} |
-bool GeolocationProviderImpl::RemoveLocationUpdateCallback( |
- const LocationUpdateCallback& callback) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- bool removed = false; |
- CallbackList::iterator i = callbacks_.begin(); |
- for (; i != callbacks_.end(); ++i) { |
- if (i->first.Equals(callback)) { |
- callbacks_.erase(i); |
- removed = true; |
- break; |
- } |
- } |
- if (removed) |
- OnClientsChanged(); |
- return removed; |
+ return rv.Pass(); |
} |
void GeolocationProviderImpl::UserDidOptIntoLocationServices() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
bool was_permission_granted = user_did_opt_into_location_services_; |
user_did_opt_into_location_services_ = true; |
if (IsRunning() && !was_permission_granted) |
InformProvidersPermissionGranted(); |
} |
-bool GeolocationProviderImpl::LocationServicesOptedIn() const { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- return user_did_opt_into_location_services_; |
+void GeolocationProviderImpl::OverrideLocationForTesting( |
+ const Geoposition& position) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ position_ = position; |
+ ignore_location_updates_ = true; |
+ NotifyClients(position); |
} |
void GeolocationProviderImpl::OnLocationUpdate(const Geoposition& position) { |
@@ -101,22 +61,14 @@ |
// Will be true only in testing. |
if (ignore_location_updates_) |
return; |
- BrowserThread::PostTask(BrowserThread::IO, |
+ BrowserThread::PostTask(BrowserThread::UI, |
FROM_HERE, |
base::Bind(&GeolocationProviderImpl::NotifyClients, |
base::Unretained(this), position)); |
} |
-void GeolocationProviderImpl::OverrideLocationForTesting( |
- const Geoposition& position) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- position_ = position; |
- ignore_location_updates_ = true; |
- NotifyClients(position); |
-} |
- |
GeolocationProviderImpl* GeolocationProviderImpl::GetInstance() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
return Singleton<GeolocationProviderImpl>::get(); |
} |
@@ -125,12 +77,16 @@ |
user_did_opt_into_location_services_(false), |
ignore_location_updates_(false), |
arbitrator_(NULL) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ high_accuracy_callbacks_.set_removal_callback( |
+ base::Bind(&GeolocationProviderImpl::OnClientsChanged, |
+ base::Unretained(this))); |
+ low_accuracy_callbacks_.set_removal_callback( |
+ base::Bind(&GeolocationProviderImpl::OnClientsChanged, |
+ base::Unretained(this))); |
} |
GeolocationProviderImpl::~GeolocationProviderImpl() { |
- // All callbacks should have unregistered before this singleton is destructed. |
- DCHECK(callbacks_.empty()); |
Stop(); |
DCHECK(!arbitrator_); |
} |
@@ -140,9 +96,9 @@ |
} |
void GeolocationProviderImpl::OnClientsChanged() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
base::Closure task; |
- if (callbacks_.empty()) { |
+ if (high_accuracy_callbacks_.empty() && low_accuracy_callbacks_.empty()) { |
DCHECK(IsRunning()); |
// We have no more observers, so we clear the cached geoposition so that |
// when the next observer is added we will not provide a stale position. |
@@ -152,18 +108,11 @@ |
} else { |
if (!IsRunning()) { |
Start(); |
- if (LocationServicesOptedIn()) |
+ if (user_did_opt_into_location_services_) |
InformProvidersPermissionGranted(); |
} |
// Determine a set of options that satisfies all clients. |
- bool use_high_accuracy = false; |
- CallbackList::iterator i = callbacks_.begin(); |
- for (; i != callbacks_.end(); ++i) { |
- if (i->second) { |
- use_high_accuracy = true; |
- break; |
- } |
- } |
+ bool use_high_accuracy = !high_accuracy_callbacks_.empty(); |
// Send the current options to the providers as they may have changed. |
task = base::Bind(&GeolocationProviderImpl::StartProviders, |
@@ -201,18 +150,12 @@ |
} |
void GeolocationProviderImpl::NotifyClients(const Geoposition& position) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(position.Validate() || |
position.error_code != Geoposition::ERROR_CODE_NONE); |
position_ = position; |
- CallbackList::const_iterator it = callbacks_.begin(); |
- while (it != callbacks_.end()) { |
- // Advance iterator before calling the observer to guard against synchronous |
- // unregister. |
- LocationUpdateCallback callback = it->first; |
- ++it; |
- callback.Run(position_); |
- } |
+ high_accuracy_callbacks_.Notify(position_); |
+ low_accuracy_callbacks_.Notify(position_); |
} |
void GeolocationProviderImpl::Init() { |