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