15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <hash_set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/thread_task_runner_handle.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "device/bluetooth/bluetooth_device_win.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_thread.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "device/bluetooth/bluetooth_socket_win.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "device/bluetooth/bluetooth_task_manager_win.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "device/bluetooth/bluetooth_uuid.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace device {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const InitCallback& init_callback) {
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return BluetoothAdapterWin::CreateAdapter(init_callback);
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter(
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const InitCallback& init_callback) {
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BluetoothAdapterWin* adapter = new BluetoothAdapterWin(init_callback);
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  adapter->Init();
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return adapter->weak_ptr_factory_.GetWeakPtr();
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BluetoothAdapterWin::BluetoothAdapterWin(const InitCallback& init_callback)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : BluetoothAdapter(),
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      init_callback_(init_callback),
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initialized_(false),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      powered_(false),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      discovery_status_(NOT_DISCOVERING),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      num_discovery_listeners_(0),
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothAdapterWin::~BluetoothAdapterWin() {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (task_manager_) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    task_manager_->RemoveObserver(this);
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    task_manager_->Shutdown();
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothAdapterWin::AddObserver(BluetoothAdapter::Observer* observer) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(observer);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothAdapterWin::RemoveObserver(BluetoothAdapter::Observer* observer) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(observer);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string BluetoothAdapterWin::GetAddress() const {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return address_;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string BluetoothAdapterWin::GetName() const {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return name_;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterWin::SetName(const std::string& name,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const base::Closure& callback,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const ErrorCallback& error_callback) {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NOTIMPLEMENTED();
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(youngki): Return true when |task_manager_| initializes the adapter
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// state.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BluetoothAdapterWin::IsInitialized() const {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return initialized_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BluetoothAdapterWin::IsPresent() const {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !address_.empty();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BluetoothAdapterWin::IsPowered() const {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return powered_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BluetoothAdapterWin::SetPowered(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool powered,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& callback,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ErrorCallback& error_callback) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->PostSetPoweredBluetoothTask(powered, callback, error_callback);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BluetoothAdapterWin::IsDiscoverable() const {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NOTIMPLEMENTED();
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterWin::SetDiscoverable(
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool discoverable,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& callback,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ErrorCallback& error_callback) {
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NOTIMPLEMENTED();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BluetoothAdapterWin::IsDiscovering() const {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return discovery_status_ == DISCOVERING ||
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      discovery_status_ == DISCOVERY_STOPPING;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterWin::DiscoveryStarted(bool success) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<std::pair<base::Closure, ErrorCallback> >::const_iterator
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter = on_start_discovery_callbacks_.begin();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != on_start_discovery_callbacks_.end();
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (success)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_task_runner_->PostTask(FROM_HERE, iter->first);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_task_runner_->PostTask(FROM_HERE, iter->second);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  num_discovery_listeners_ = on_start_discovery_callbacks_.size();
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  on_start_discovery_callbacks_.clear();
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (success) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      AdapterDiscoveringChanged(this, true));
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If there are stop discovery requests, post the stop discovery again.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MaybePostStopDiscoveryTask();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!on_stop_discovery_callbacks_.empty()) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If there are stop discovery requests but start discovery has failed,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // notify that stop discovery has been complete.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DiscoveryStopped();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterWin::DiscoveryStopped() {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  discovered_devices_.clear();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool was_discovering = IsDiscovering();
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  discovery_status_ = NOT_DISCOVERING;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<base::Closure>::const_iterator iter =
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           on_stop_discovery_callbacks_.begin();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != on_stop_discovery_callbacks_.end();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_task_runner_->PostTask(FROM_HERE, *iter);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  num_discovery_listeners_ = 0;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  on_stop_discovery_callbacks_.clear();
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (was_discovering)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      AdapterDiscoveringChanged(this, false));
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are start discovery requests, post the start discovery again.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaybePostStartDiscoveryTask();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothAdapterWin::CreateRfcommService(
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const BluetoothUUID& uuid,
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ServiceOptions& options,
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const CreateServiceCallback& callback,
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const CreateServiceErrorCallback& error_callback) {
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<BluetoothSocketWin> socket =
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      BluetoothSocketWin::CreateBluetoothSocket(
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ui_task_runner_, socket_thread_);
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  socket->Listen(this, uuid, options,
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Bind(callback, socket),
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 error_callback);
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothAdapterWin::CreateL2capService(
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const BluetoothUUID& uuid,
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ServiceOptions& options,
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const CreateServiceCallback& callback,
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const CreateServiceErrorCallback& error_callback) {
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(keybuk): implement.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterWin::RemovePairingDelegateInternal(
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BluetoothDevice::PairingDelegate* pairing_delegate) {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterWin::AdapterStateChanged(
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BluetoothTaskManagerWin::AdapterState& state) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  name_ = state.name;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool was_present = IsPresent();
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_present = !state.address.empty();
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  address_ = BluetoothDevice::CanonicalizeAddress(state.address);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (was_present != is_present) {
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      AdapterPresentChanged(this, is_present));
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (powered_ != state.powered) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    powered_ = state.powered;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      AdapterPoweredChanged(this, powered_));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!initialized_) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    initialized_ = true;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_callback_.Run();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterWin::DevicesPolled(
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ScopedVector<BluetoothTaskManagerWin::DeviceState>& devices) {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We are receiving a new list of all devices known to the system. Merge this
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // new list with the list we know of (|devices_|) and raise corresponding
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // DeviceAdded, DeviceRemoved and DeviceChanged events.
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef std::set<std::string> DeviceAddressSet;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeviceAddressSet known_devices;
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (DevicesMap::const_iterator iter = devices_.begin();
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       iter != devices_.end();
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++iter) {
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    known_devices.insert((*iter).first);
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeviceAddressSet new_devices;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           devices.begin();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != devices.end();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter) {
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    new_devices.insert((*iter)->address);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Process device removal first
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeviceAddressSet removed_devices =
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::STLSetDifference<DeviceAddressSet>(known_devices, new_devices);
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (DeviceAddressSet::const_iterator iter = removed_devices.begin();
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       iter != removed_devices.end();
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++iter) {
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BluetoothDevice* device_win = devices_[(*iter)];
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    devices_.erase(*iter);
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      observers_,
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      DeviceRemoved(this, device_win));
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    delete device_win;
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Process added and (maybe) changed devices in one pass
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeviceAddressSet added_devices =
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::STLSetDifference<DeviceAddressSet>(new_devices, known_devices);
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeviceAddressSet changed_devices =
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::STLSetIntersection<DeviceAddressSet>(known_devices, new_devices);
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (ScopedVector<BluetoothTaskManagerWin::DeviceState>::const_iterator iter =
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           devices.begin();
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       iter != devices.end();
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ++iter) {
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BluetoothTaskManagerWin::DeviceState* device_state = (*iter);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (added_devices.find(device_state->address) != added_devices.end()) {
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BluetoothDeviceWin* device_win =
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new BluetoothDeviceWin(*device_state,
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 ui_task_runner_,
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 socket_thread_,
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 NULL,
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 net::NetLog::Source());
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      devices_[device_state->address] = device_win;
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        observers_,
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        DeviceAdded(this, device_win));
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (changed_devices.find(device_state->address) !=
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               changed_devices.end()) {
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BluetoothDeviceWin* device_win =
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          static_cast<BluetoothDeviceWin*>(devices_[device_state->address]);
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (!device_win->IsEqual(*device_state)) {
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        device_win->Update(*device_state);
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          observers_,
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          DeviceChanged(this, device_win));
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterWin::AddDiscoverySession(
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::Closure& callback,
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ErrorCallback& error_callback) {
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (discovery_status_ == DISCOVERING) {
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_discovery_listeners_++;
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    callback.Run();
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  on_start_discovery_callbacks_.push_back(
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::make_pair(callback, error_callback));
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaybePostStartDiscoveryTask();
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterWin::RemoveDiscoverySession(
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::Closure& callback,
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ErrorCallback& error_callback) {
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (discovery_status_ == NOT_DISCOVERING) {
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    error_callback.Run();
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  on_stop_discovery_callbacks_.push_back(callback);
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaybePostStopDiscoveryTask();
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BluetoothAdapterWin::Init() {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  socket_thread_ = BluetoothSocketThread::Get();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_ =
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BluetoothTaskManagerWin(ui_task_runner_);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->AddObserver(this);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->Initialize();
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BluetoothAdapterWin::InitForTest(
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_task_runner_ = ui_task_runner;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_ =
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BluetoothTaskManagerWin(ui_task_runner_);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->AddObserver(this);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (discovery_status_ == NOT_DISCOVERING &&
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !on_start_discovery_callbacks_.empty()) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    discovery_status_ = DISCOVERY_STARTING;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    task_manager_->PostStartDiscoveryTask();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (discovery_status_ != DISCOVERING)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (std::vector<base::Closure>::const_iterator iter =
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             on_stop_discovery_callbacks_.begin();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         iter != on_stop_discovery_callbacks_.end();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++iter) {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_task_runner_->PostTask(FROM_HERE, *iter);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    num_discovery_listeners_ -= on_stop_discovery_callbacks_.size();
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    on_stop_discovery_callbacks_.clear();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  discovery_status_ = DISCOVERY_STOPPING;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_manager_->PostStopDiscoveryTask();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace device
359