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 #include "content/browser/geolocation/wifi_data_provider.h"
10 WifiDataProvider
* WifiDataProvider::instance_
= NULL
;
13 WifiDataProvider::ImplFactoryFunction
WifiDataProvider::factory_function_
=
14 DefaultFactoryFunction
;
17 void WifiDataProvider::SetFactory(ImplFactoryFunction factory_function_in
) {
18 factory_function_
= factory_function_in
;
22 void WifiDataProvider::ResetFactory() {
23 factory_function_
= DefaultFactoryFunction
;
27 WifiDataProvider
* WifiDataProvider::Register(WifiDataUpdateCallback
* callback
) {
28 bool need_to_start_data_provider
= false;
30 instance_
= new WifiDataProvider();
31 need_to_start_data_provider
= true;
34 instance_
->AddCallback(callback
);
35 // Start the provider after adding the callback, to avoid any race in
37 if (need_to_start_data_provider
)
38 instance_
->StartDataProvider();
43 bool WifiDataProvider::Unregister(WifiDataUpdateCallback
* callback
) {
45 DCHECK(instance_
->has_callbacks());
46 if (!instance_
->RemoveCallback(callback
)) {
49 if (!instance_
->has_callbacks()) {
50 // Must stop the data provider (and any implementation threads) before
51 // destroying to avoid any race conditions in access to the provider in
52 // the destructor chain.
53 instance_
->StopDataProvider();
60 WifiDataProviderImplBase::WifiDataProviderImplBase()
62 client_loop_(base::MessageLoop::current()) {
66 WifiDataProviderImplBase::~WifiDataProviderImplBase() {
69 void WifiDataProviderImplBase::SetContainer(WifiDataProvider
* container
) {
70 container_
= container
;
73 void WifiDataProviderImplBase::AddCallback(WifiDataUpdateCallback
* callback
) {
74 callbacks_
.insert(callback
);
77 bool WifiDataProviderImplBase::RemoveCallback(
78 WifiDataUpdateCallback
* callback
) {
79 return callbacks_
.erase(callback
) == 1;
82 bool WifiDataProviderImplBase::has_callbacks() const {
83 return !callbacks_
.empty();
86 void WifiDataProviderImplBase::RunCallbacks() {
87 client_loop_
->PostTask(FROM_HERE
, base::Bind(
88 &WifiDataProviderImplBase::DoRunCallbacks
,
92 bool WifiDataProviderImplBase::CalledOnClientThread() const {
93 return base::MessageLoop::current() == this->client_loop_
;
96 base::MessageLoop
* WifiDataProviderImplBase::client_loop() const {
100 void WifiDataProviderImplBase::DoRunCallbacks() {
101 // It's possible that all the callbacks (and the container) went away
102 // whilst this task was pending. This is fine; the loop will be a no-op.
103 CallbackSet::const_iterator iter
= callbacks_
.begin();
104 while (iter
!= callbacks_
.end()) {
105 WifiDataUpdateCallback
* callback
= *iter
;
106 ++iter
; // Advance iter before running, in case callback unregisters.
107 callback
->Run(container_
);
111 WifiDataProvider::WifiDataProvider() {
112 DCHECK(factory_function_
);
113 impl_
= (*factory_function_
)();
115 impl_
->SetContainer(this);
118 WifiDataProvider::~WifiDataProvider() {
120 impl_
->SetContainer(NULL
);
123 bool WifiDataProvider::GetData(WifiData
* data
) {
124 return impl_
->GetData(data
);
127 void WifiDataProvider::AddCallback(WifiDataUpdateCallback
* callback
) {
128 impl_
->AddCallback(callback
);
131 bool WifiDataProvider::RemoveCallback(WifiDataUpdateCallback
* callback
) {
132 return impl_
->RemoveCallback(callback
);
135 bool WifiDataProvider::has_callbacks() const {
136 return impl_
->has_callbacks();
139 void WifiDataProvider::StartDataProvider() {
140 impl_
->StartDataProvider();
143 void WifiDataProvider::StopDataProvider() {
144 impl_
->StopDataProvider();
147 } // namespace content