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.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_device.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_discovery_session.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace device {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14116680a4aac90f2aa7413d9095a592090648e557Ben MurdochBluetoothAdapter::ServiceOptions::ServiceOptions() {
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
16116680a4aac90f2aa7413d9095a592090648e557Ben MurdochBluetoothAdapter::ServiceOptions::~ServiceOptions() {
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch//static
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const InitCallback& init_callback) {
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return base::WeakPtr<BluetoothAdapter>();
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // !defined(OS_CHROMEOS) && !defined(OS_WIN) && !defined(OS_MACOSX)
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothAdapter::BluetoothAdapter()
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : weak_ptr_factory_(this) {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothAdapter::~BluetoothAdapter() {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteValues(&devices_);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::WeakPtr<BluetoothAdapter> BluetoothAdapter::GetWeakPtrForTesting() {
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::StartDiscoverySession(
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const DiscoverySessionCallback& callback,
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ErrorCallback& error_callback) {
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AddDiscoverySession(
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothAdapter::OnStartDiscoverySession,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback),
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      error_callback);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothAdapter::DeviceList BluetoothAdapter::GetDevices() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConstDeviceList const_devices =
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const_cast<const BluetoothAdapter *>(this)->GetDevices();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceList devices;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ConstDeviceList::const_iterator i = const_devices.begin();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != const_devices.end(); ++i)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    devices.push_back(const_cast<BluetoothDevice *>(*i));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return devices;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BluetoothAdapter::ConstDeviceList BluetoothAdapter::GetDevices() const {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConstDeviceList devices;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (DevicesMap::const_iterator iter = devices_.begin();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != devices_.end();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    devices.push_back(iter->second);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return devices;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BluetoothDevice* BluetoothAdapter::GetDevice(const std::string& address) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return const_cast<BluetoothDevice *>(
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const_cast<const BluetoothAdapter *>(this)->GetDevice(address));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const BluetoothDevice* BluetoothAdapter::GetDevice(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& address) const {
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string canonicalized_address =
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      BluetoothDevice::CanonicalizeAddress(address);
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (canonicalized_address.empty())
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DevicesMap::const_iterator iter = devices_.find(canonicalized_address);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != devices_.end())
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return iter->second;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::AddPairingDelegate(
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BluetoothDevice::PairingDelegate* pairing_delegate,
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PairingDelegatePriority priority) {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Remove the delegate, if it already exists, before inserting to allow a
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // change of priority.
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RemovePairingDelegate(pairing_delegate);
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Find the first point with a lower priority, or the end of the list.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::list<PairingDelegatePair>::iterator iter = pairing_delegates_.begin();
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  while (iter != pairing_delegates_.end() && iter->second >= priority)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++iter;
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pairing_delegates_.insert(iter, std::make_pair(pairing_delegate, priority));
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::RemovePairingDelegate(
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BluetoothDevice::PairingDelegate* pairing_delegate) {
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::list<PairingDelegatePair>::iterator iter =
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       pairing_delegates_.begin(); iter != pairing_delegates_.end(); ++iter) {
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (iter->first == pairing_delegate) {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RemovePairingDelegateInternal(pairing_delegate);
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pairing_delegates_.erase(iter);
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothDevice::PairingDelegate* BluetoothAdapter::DefaultPairingDelegate() {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (pairing_delegates_.empty())
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return NULL;
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pairing_delegates_.front().first;
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::OnStartDiscoverySession(
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const DiscoverySessionCallback& callback) {
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  VLOG(1) << "Discovery session started!";
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<BluetoothDiscoverySession> discovery_session(
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new BluetoothDiscoverySession(scoped_refptr<BluetoothAdapter>(this)));
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.insert(discovery_session.get());
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback.Run(discovery_session.Pass());
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::MarkDiscoverySessionsAsInactive() {
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // As sessions are marked as inactive they will notify the adapter that they
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // have become inactive, upon which the adapter will remove them from
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |discovery_sessions_|. To avoid invalidating the iterator, make a copy
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // here.
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::set<BluetoothDiscoverySession*> temp(discovery_sessions_);
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::set<BluetoothDiscoverySession*>::iterator
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          iter = temp.begin();
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != temp.end(); ++iter) {
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    (*iter)->MarkAsInactive();
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapter::DiscoverySessionBecameInactive(
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BluetoothDiscoverySession* discovery_session) {
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!discovery_session->IsActive());
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.erase(discovery_session);
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace device
153