Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / device / bluetooth / bluetooth_adapter_win.cc
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
3 // found in the LICENSE file.
4
5 #include "device/bluetooth/bluetooth_adapter_win.h"
6
7 #include <hash_set>
8 #include <string>
9 #include <utility>
10
11 #include "base/logging.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/stl_util.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "device/bluetooth/bluetooth_device_win.h"
17 #include "device/bluetooth/bluetooth_socket_thread.h"
18 #include "device/bluetooth/bluetooth_task_manager_win.h"
19
20 namespace device {
21
22 // static
23 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
24     const InitCallback& init_callback) {
25   return BluetoothAdapterWin::CreateAdapter(init_callback);
26 }
27
28 // static
29 base::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter(
30     const InitCallback& init_callback) {
31   BluetoothAdapterWin* adapter = new BluetoothAdapterWin(init_callback);
32   adapter->Init();
33   return adapter->weak_ptr_factory_.GetWeakPtr();
34 }
35
36 BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
37     : BluetoothAdapter(),
38       init_callback_(init_callback),
39       initialized_(false),
40       powered_(false),
41       discovery_status_(NOT_DISCOVERING),
42       num_discovery_listeners_(0),
43       weak_ptr_factory_(this) {
44 }
45
46 BluetoothAdapterWin::~BluetoothAdapterWin() {
47   if (task_manager_) {
48     task_manager_->RemoveObserver(this);
49     task_manager_->Shutdown();
50   }
51 }
52
53 void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
54   DCHECK(observer);
55   observers_.AddObserver(observer);
56 }
57
58 void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
59   DCHECK(observer);
60   observers_.RemoveObserver(observer);
61 }
62
63 std::string BluetoothAdapterWin::GetAddress() const {
64   return address_;
65 }
66
67 std::string BluetoothAdapterWin::GetName() const {
68   return name_;
69 }
70
71 void BluetoothAdapterWin::SetName(const std::string& name,
72                                   const base::Closure& callback,
73                                   const ErrorCallback& error_callback) {
74   NOTIMPLEMENTED();
75 }
76
77 // TODO(youngki): Return true when |task_manager_| initializes the adapter
78 // state.
79 bool BluetoothAdapterWin::IsInitialized() const {
80   return initialized_;
81 }
82
83 bool BluetoothAdapterWin::IsPresent() const {
84   return !address_.empty();
85 }
86
87 bool BluetoothAdapterWin::IsPowered() const {
88   return powered_;
89 }
90
91 void BluetoothAdapterWin::SetPowered(
92     bool powered,
93     const base::Closure& callback,
94     const ErrorCallback& error_callback) {
95   task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
96 }
97
98 bool BluetoothAdapterWin::IsDiscoverable() const {
99   NOTIMPLEMENTED();
100   return false;
101 }
102
103 void BluetoothAdapterWin::SetDiscoverable(
104     bool discoverable,
105     const base::Closure& callback,
106     const ErrorCallback& error_callback) {
107   NOTIMPLEMENTED();
108 }
109
110 bool BluetoothAdapterWin::IsDiscovering() const {
111   return discovery_status_ == DISCOVERING ||
112       discovery_status_ == DISCOVERY_STOPPING;
113 }
114
115 void BluetoothAdapterWin::DiscoveryStarted(bool success) {
116   discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
117   for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
118        iter = on_start_discovery_callbacks_.begin();
119        iter != on_start_discovery_callbacks_.end();
120        ++iter) {
121     if (success)
122       ui_task_runner_->PostTask(FROM_HERE, iter->first);
123     else
124       ui_task_runner_->PostTask(FROM_HERE, iter->second);
125   }
126   num_discovery_listeners_ = on_start_discovery_callbacks_.size();
127   on_start_discovery_callbacks_.clear();
128
129   if (success) {
130     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
131                       AdapterDiscoveringChanged(this, true));
132
133     // If there are stop discovery requests, post the stop discovery again.
134     MaybePostStopDiscoveryTask();
135   } else if (!on_stop_discovery_callbacks_.empty()) {
136     // If there are stop discovery requests but start discovery has failed,
137     // notify that stop discovery has been complete.
138     DiscoveryStopped();
139   }
140 }
141
142 void BluetoothAdapterWin::DiscoveryStopped() {
143   discovered_devices_.clear();
144   bool was_discovering = IsDiscovering();
145   discovery_status_ = NOT_DISCOVERING;
146   for (std::vector<base::Closure>::const_iterator iter =
147            on_stop_discovery_callbacks_.begin();
148        iter != on_stop_discovery_callbacks_.end();
149        ++iter) {
150     ui_task_runner_->PostTask(FROM_HERE, *iter);
151   }
152   num_discovery_listeners_ = 0;
153   on_stop_discovery_callbacks_.clear();
154   if (was_discovering)
155     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
156                       AdapterDiscoveringChanged(this, false));
157
158   // If there are start discovery requests, post the start discovery again.
159   MaybePostStartDiscoveryTask();
160 }
161
162 void BluetoothAdapterWin::ReadLocalOutOfBandPairingData(
163     const BluetoothOutOfBandPairingDataCallback& callback,
164     const ErrorCallback& error_callback) {
165   NOTIMPLEMENTED();
166 }
167
168 void BluetoothAdapterWin::RemovePairingDelegateInternal(
169     BluetoothDevice::PairingDelegate* pairing_delegate) {
170 }
171
172 void BluetoothAdapterWin::AdapterStateChanged(
173     const BluetoothTaskManagerWin::AdapterState& state) {
174   DCHECK(thread_checker_.CalledOnValidThread());
175   name_ = state.name;
176   bool was_present = IsPresent();
177   bool is_present = !state.address.empty();
178   address_ = state.address;
179   if (was_present != is_present) {
180     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
181                       AdapterPresentChanged(this, is_present));
182   }
183   if (powered_ != state.powered) {
184     powered_ = state.powered;
185     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
186                       AdapterPoweredChanged(this, powered_));
187   }
188   if (!initialized_) {
189     initialized_ = true;
190     init_callback_.Run();
191   }
192 }
193
194 void BluetoothAdapterWin::DevicesDiscovered(
195     const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
196   DCHECK(thread_checker_.CalledOnValidThread());
197   for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
198            devices.begin();
199        iter != devices.end();
200        ++iter) {
201     if (discovered_devices_.find((*iter)->address) ==
202         discovered_devices_.end()) {
203       BluetoothDeviceWin device_win(
204           **iter, ui_task_runner_, socket_thread_, NULL, net::NetLog::Source());
205       FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
206                         DeviceAdded(this, &device_win));
207       discovered_devices_.insert((*iter)->address);
208     }
209   }
210 }
211
212 void BluetoothAdapterWin::DevicesUpdated(
213     const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
214   STLDeleteValues(&devices_);
215   for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
216            devices.begin();
217        iter != devices.end();
218        ++iter) {
219     devices_[(*iter)->address] = new BluetoothDeviceWin(
220         **iter, ui_task_runner_, socket_thread_, NULL, net::NetLog::Source());
221   }
222 }
223
224 // If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
225 // starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
226 void BluetoothAdapterWin::AddDiscoverySession(
227     const base::Closure& callback,
228     const ErrorCallback& error_callback) {
229   if (discovery_status_ == DISCOVERING) {
230     num_discovery_listeners_++;
231     callback.Run();
232     return;
233   }
234   on_start_discovery_callbacks_.push_back(
235       std::make_pair(callback, error_callback));
236   MaybePostStartDiscoveryTask();
237 }
238
239 void BluetoothAdapterWin::RemoveDiscoverySession(
240     const base::Closure& callback,
241     const ErrorCallback& error_callback) {
242   if (discovery_status_ == NOT_DISCOVERING) {
243     error_callback.Run();
244     return;
245   }
246   on_stop_discovery_callbacks_.push_back(callback);
247   MaybePostStopDiscoveryTask();
248 }
249
250 void BluetoothAdapterWin::Init() {
251   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
252   socket_thread_ = BluetoothSocketThread::Get();
253   task_manager_ =
254       new BluetoothTaskManagerWin(ui_task_runner_);
255   task_manager_->AddObserver(this);
256   task_manager_->Initialize();
257 }
258
259 void BluetoothAdapterWin::InitForTest(
260     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
261     scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
262   ui_task_runner_ = ui_task_runner;
263   task_manager_ =
264       new BluetoothTaskManagerWin(ui_task_runner_);
265   task_manager_->AddObserver(this);
266   task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
267 }
268
269 void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
270   if (discovery_status_ == NOT_DISCOVERING &&
271       !on_start_discovery_callbacks_.empty()) {
272     discovery_status_ = DISCOVERY_STARTING;
273     task_manager_->PostStartDiscoveryTask();
274   }
275 }
276
277 void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
278   if (discovery_status_ != DISCOVERING)
279     return;
280
281   if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
282     for (std::vector<base::Closure>::const_iterator iter =
283              on_stop_discovery_callbacks_.begin();
284          iter != on_stop_discovery_callbacks_.end();
285          ++iter) {
286       ui_task_runner_->PostTask(FROM_HERE, *iter);
287     }
288     num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
289     on_stop_discovery_callbacks_.clear();
290     return;
291   }
292
293   discovery_status_ = DISCOVERY_STOPPING;
294   task_manager_->PostStopDiscoveryTask();
295 }
296
297 }  // namespace device