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