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