Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/geolocation/geolocation_provider.h" | 5 #include "content/browser/geolocation/geolocation_provider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | |
| 10 #include "base/location.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/message_loop.h" | |
|
Joao da Silva
2012/04/23 10:19:57
Nit: order
bartfab (slow)
2012/04/23 12:21:28
Done.
| |
| 9 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 10 #include "base/threading/thread_restrictions.h" | |
| 11 #include "content/browser/geolocation/location_arbitrator.h" | 14 #include "content/browser/geolocation/location_arbitrator.h" |
| 15 #include "content/public/browser/browser_thread.h" | |
| 12 | 16 |
| 13 GeolocationProvider* GeolocationProvider::GetInstance() { | 17 GeolocationProvider* GeolocationProvider::GetInstance() { |
| 18 DCHECK(OnIOThread()); | |
| 14 return Singleton<GeolocationProvider>::get(); | 19 return Singleton<GeolocationProvider>::get(); |
| 15 } | 20 } |
| 16 | 21 |
| 17 GeolocationProvider::GeolocationProvider() | 22 GeolocationProvider::GeolocationProvider() |
| 18 : base::Thread("Geolocation"), | 23 : base::Thread("Geolocation"), |
| 19 client_loop_(base::MessageLoopProxy::current()), | |
| 20 is_permission_granted_(false), | 24 is_permission_granted_(false), |
| 21 arbitrator_(NULL) { | 25 arbitrator_(NULL) { |
| 26 DCHECK(OnIOThread()); | |
| 22 } | 27 } |
| 23 | 28 |
| 24 GeolocationProvider::~GeolocationProvider() { | 29 GeolocationProvider::~GeolocationProvider() { |
| 25 DCHECK(observers_.empty()); // observers must unregister. | 30 DCHECK(observers_.empty()); // observers must unregister. |
| 26 Stop(); | 31 Stop(); |
| 27 DCHECK(!arbitrator_); | 32 DCHECK(!arbitrator_); |
| 28 } | 33 } |
| 29 | 34 |
| 30 void GeolocationProvider::AddObserver(GeolocationObserver* observer, | 35 void GeolocationProvider::AddObserver(GeolocationObserver* observer, |
| 31 const GeolocationObserverOptions& update_options) { | 36 const GeolocationObserverOptions& update_options) { |
| 32 DCHECK(OnClientThread()); | 37 DCHECK(OnIOThread()); |
| 33 observers_[observer] = update_options; | 38 observers_[observer] = update_options; |
| 34 OnObserversChanged(); | 39 OnObserversChanged(); |
| 35 if (position_.IsInitialized()) | 40 if (position_.IsInitialized()) |
| 36 observer->OnLocationUpdate(position_); | 41 observer->OnLocationUpdate(position_); |
| 37 } | 42 } |
| 38 | 43 |
| 39 bool GeolocationProvider::RemoveObserver(GeolocationObserver* observer) { | 44 bool GeolocationProvider::RemoveObserver(GeolocationObserver* observer) { |
| 40 DCHECK(OnClientThread()); | 45 DCHECK(OnIOThread()); |
| 41 size_t remove = observers_.erase(observer); | 46 size_t remove = observers_.erase(observer); |
| 42 OnObserversChanged(); | 47 OnObserversChanged(); |
| 43 return remove > 0; | 48 return remove > 0; |
| 44 } | 49 } |
| 45 | 50 |
| 46 void GeolocationProvider::OnObserversChanged() { | 51 void GeolocationProvider::OnObserversChanged() { |
| 47 DCHECK(OnClientThread()); | 52 DCHECK(OnIOThread()); |
| 48 base::Closure task; | 53 base::Closure task; |
| 49 if (observers_.empty()) { | 54 if (observers_.empty()) { |
| 50 DCHECK(IsRunning()); | 55 DCHECK(IsRunning()); |
| 51 task = base::Bind(&GeolocationProvider::StopProviders, | 56 task = base::Bind(&GeolocationProvider::StopProviders, |
| 52 base::Unretained(this)); | 57 base::Unretained(this)); |
| 53 } else { | 58 } else { |
| 54 if (!IsRunning()) { | 59 if (!IsRunning()) { |
| 55 Start(); | 60 Start(); |
| 56 if (HasPermissionBeenGranted()) | 61 if (HasPermissionBeenGranted()) |
| 57 InformProvidersPermissionGranted(); | 62 InformProvidersPermissionGranted(); |
| 58 } | 63 } |
| 59 | 64 |
| 60 // The high accuracy requirement may have changed. | 65 // The high accuracy requirement may have changed. |
| 61 task = base::Bind(&GeolocationProvider::StartProviders, | 66 task = base::Bind(&GeolocationProvider::StartProviders, |
| 62 base::Unretained(this), | 67 base::Unretained(this), |
| 63 GeolocationObserverOptions::Collapse(observers_)); | 68 GeolocationObserverOptions::Collapse(observers_)); |
| 64 } | 69 } |
| 65 | 70 |
| 66 message_loop()->PostTask(FROM_HERE, task); | 71 message_loop()->PostTask(FROM_HERE, task); |
| 67 } | 72 } |
| 68 | 73 |
| 69 void GeolocationProvider::NotifyObservers(const Geoposition& position) { | 74 void GeolocationProvider::NotifyObservers(const Geoposition& position) { |
| 70 DCHECK(OnClientThread()); | 75 DCHECK(OnIOThread()); |
| 71 DCHECK(position.IsInitialized()); | 76 DCHECK(position.IsInitialized()); |
| 72 position_ = position; | 77 position_ = position; |
| 73 ObserverMap::const_iterator it = observers_.begin(); | 78 ObserverMap::const_iterator it = observers_.begin(); |
| 74 while (it != observers_.end()) { | 79 while (it != observers_.end()) { |
| 75 // Advance iterator before callback to guard against synchronous unregister. | 80 // Advance iterator before callback to guard against synchronous unregister. |
| 76 GeolocationObserver* observer = it->first; | 81 GeolocationObserver* observer = it->first; |
| 77 ++it; | 82 ++it; |
| 78 observer->OnLocationUpdate(position_); | 83 observer->OnLocationUpdate(position_); |
| 79 } | 84 } |
| 80 } | 85 } |
| 81 | 86 |
| 82 void GeolocationProvider::StartProviders( | 87 void GeolocationProvider::StartProviders( |
| 83 const GeolocationObserverOptions& options) { | 88 const GeolocationObserverOptions& options) { |
| 84 DCHECK(OnGeolocationThread()); | 89 DCHECK(OnGeolocationThread()); |
| 85 DCHECK(arbitrator_); | 90 DCHECK(arbitrator_); |
| 86 arbitrator_->StartProviders(options); | 91 arbitrator_->StartProviders(options); |
| 87 } | 92 } |
| 88 | 93 |
| 89 void GeolocationProvider::StopProviders() { | 94 void GeolocationProvider::StopProviders() { |
| 90 DCHECK(OnGeolocationThread()); | 95 DCHECK(OnGeolocationThread()); |
| 91 DCHECK(arbitrator_); | 96 DCHECK(arbitrator_); |
| 92 arbitrator_->StopProviders(); | 97 arbitrator_->StopProviders(); |
| 93 } | 98 } |
| 94 | 99 |
| 95 void GeolocationProvider::OnPermissionGranted() { | 100 void GeolocationProvider::OnPermissionGranted() { |
| 96 DCHECK(OnClientThread()); | 101 DCHECK(OnIOThread()); |
| 97 is_permission_granted_ = true; | 102 is_permission_granted_ = true; |
| 98 if (IsRunning()) | 103 if (IsRunning()) |
| 99 InformProvidersPermissionGranted(); | 104 InformProvidersPermissionGranted(); |
| 100 } | 105 } |
| 101 | 106 |
| 102 void GeolocationProvider::InformProvidersPermissionGranted() { | 107 void GeolocationProvider::InformProvidersPermissionGranted() { |
| 103 DCHECK(IsRunning()); | 108 DCHECK(IsRunning()); |
| 104 if (!OnGeolocationThread()) { | 109 if (!OnGeolocationThread()) { |
| 105 message_loop()->PostTask( | 110 message_loop()->PostTask( |
| 106 FROM_HERE, | 111 FROM_HERE, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 120 } | 125 } |
| 121 | 126 |
| 122 void GeolocationProvider::CleanUp() { | 127 void GeolocationProvider::CleanUp() { |
| 123 DCHECK(OnGeolocationThread()); | 128 DCHECK(OnGeolocationThread()); |
| 124 delete arbitrator_; | 129 delete arbitrator_; |
| 125 arbitrator_ = NULL; | 130 arbitrator_ = NULL; |
| 126 } | 131 } |
| 127 | 132 |
| 128 void GeolocationProvider::OnLocationUpdate(const Geoposition& position) { | 133 void GeolocationProvider::OnLocationUpdate(const Geoposition& position) { |
| 129 DCHECK(OnGeolocationThread()); | 134 DCHECK(OnGeolocationThread()); |
| 130 client_loop_->PostTask( | 135 content::BrowserThread::PostTask( |
| 136 content::BrowserThread::IO, | |
| 131 FROM_HERE, | 137 FROM_HERE, |
| 132 base::Bind(&GeolocationProvider::NotifyObservers, | 138 base::Bind(&GeolocationProvider::NotifyObservers, |
| 133 base::Unretained(this), position)); | 139 base::Unretained(this), position)); |
| 134 } | 140 } |
| 135 | 141 |
| 136 bool GeolocationProvider::HasPermissionBeenGranted() const { | 142 bool GeolocationProvider::HasPermissionBeenGranted() const { |
| 137 DCHECK(OnClientThread()); | 143 DCHECK(OnIOThread()); |
| 138 return is_permission_granted_; | 144 return is_permission_granted_; |
| 139 } | 145 } |
| 140 | 146 |
| 141 bool GeolocationProvider::OnClientThread() const { | 147 // static |
| 142 return client_loop_->BelongsToCurrentThread(); | 148 bool GeolocationProvider::OnIOThread() { |
| 149 return content::BrowserThread::CurrentlyOn(content::BrowserThread::IO); | |
|
Joao da Silva
2012/04/23 10:19:57
It's common to just
DCHECK(content::BrowserThrea
bartfab (slow)
2012/04/23 12:21:28
Done. Since you say it is common to add a using li
| |
| 143 } | 150 } |
| 144 | 151 |
| 145 bool GeolocationProvider::OnGeolocationThread() const { | 152 bool GeolocationProvider::OnGeolocationThread() const { |
| 146 return MessageLoop::current() == message_loop(); | 153 return MessageLoop::current() == message_loop(); |
| 147 } | 154 } |
| OLD | NEW |