- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / geolocation / wifi_data_provider.cc
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.
4
5 #include "content/browser/geolocation/wifi_data_provider.h"
6
7 namespace content {
8
9 // static
10 WifiDataProvider* WifiDataProvider::instance_ = NULL;
11
12 // static
13 WifiDataProvider::ImplFactoryFunction WifiDataProvider::factory_function_ =
14     DefaultFactoryFunction;
15
16 // static
17 void WifiDataProvider::SetFactory(ImplFactoryFunction factory_function_in) {
18   factory_function_ = factory_function_in;
19 }
20
21 // static
22 void WifiDataProvider::ResetFactory() {
23   factory_function_ = DefaultFactoryFunction;
24 }
25
26 // static
27 WifiDataProvider* WifiDataProvider::Register(WifiDataUpdateCallback* callback) {
28   bool need_to_start_data_provider = false;
29   if (!instance_) {
30     instance_ = new WifiDataProvider();
31     need_to_start_data_provider = true;
32   }
33   DCHECK(instance_);
34   instance_->AddCallback(callback);
35   // Start the provider after adding the callback, to avoid any race in
36   // it running early.
37   if (need_to_start_data_provider)
38     instance_->StartDataProvider();
39   return instance_;
40 }
41
42 // static
43 bool WifiDataProvider::Unregister(WifiDataUpdateCallback* callback) {
44   DCHECK(instance_);
45   DCHECK(instance_->has_callbacks());
46   if (!instance_->RemoveCallback(callback)) {
47     return false;
48   }
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();
54     delete instance_;
55     instance_ = NULL;
56   }
57   return true;
58 }
59
60 WifiDataProviderImplBase::WifiDataProviderImplBase()
61     : container_(NULL),
62       client_loop_(base::MessageLoop::current()) {
63   DCHECK(client_loop_);
64 }
65
66 WifiDataProviderImplBase::~WifiDataProviderImplBase() {
67 }
68
69 void WifiDataProviderImplBase::SetContainer(WifiDataProvider* container) {
70   container_ = container;
71 }
72
73 void WifiDataProviderImplBase::AddCallback(WifiDataUpdateCallback* callback) {
74   callbacks_.insert(callback);
75 }
76
77 bool WifiDataProviderImplBase::RemoveCallback(
78     WifiDataUpdateCallback* callback) {
79   return callbacks_.erase(callback) == 1;
80 }
81
82 bool WifiDataProviderImplBase::has_callbacks() const {
83   return !callbacks_.empty();
84 }
85
86 void WifiDataProviderImplBase::RunCallbacks() {
87   client_loop_->PostTask(FROM_HERE, base::Bind(
88       &WifiDataProviderImplBase::DoRunCallbacks,
89       this));
90 }
91
92 bool WifiDataProviderImplBase::CalledOnClientThread() const {
93   return base::MessageLoop::current() == this->client_loop_;
94 }
95
96 base::MessageLoop* WifiDataProviderImplBase::client_loop() const {
97   return client_loop_;
98 }
99
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_);
108   }
109 }
110
111 WifiDataProvider::WifiDataProvider() {
112   DCHECK(factory_function_);
113   impl_ = (*factory_function_)();
114   DCHECK(impl_.get());
115   impl_->SetContainer(this);
116 }
117
118 WifiDataProvider::~WifiDataProvider() {
119   DCHECK(impl_.get());
120   impl_->SetContainer(NULL);
121 }
122
123 bool WifiDataProvider::GetData(WifiData* data) {
124   return impl_->GetData(data);
125 }
126
127 void WifiDataProvider::AddCallback(WifiDataUpdateCallback* callback) {
128   impl_->AddCallback(callback);
129 }
130
131 bool WifiDataProvider::RemoveCallback(WifiDataUpdateCallback* callback) {
132   return impl_->RemoveCallback(callback);
133 }
134
135 bool WifiDataProvider::has_callbacks() const {
136   return impl_->has_callbacks();
137 }
138
139 void WifiDataProvider::StartDataProvider() {
140   impl_->StartDataProvider();
141 }
142
143 void WifiDataProvider::StopDataProvider() {
144   impl_->StopDataProvider();
145 }
146
147 }  // namespace content