blob: c15d26a514b3082a1fe5c89649e88d70dbfedeba [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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_factory.h"
6
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007#include <vector>
8
9#include "base/bind.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include "base/lazy_instance.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/weak_ptr.h"
13#include "device/bluetooth/bluetooth_adapter.h"
14
15#if defined(OS_CHROMEOS)
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010016#include "device/bluetooth/bluetooth_adapter_chromeos.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000017#elif defined(OS_WIN)
18#include "device/bluetooth/bluetooth_adapter_win.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010019#elif defined(OS_MACOSX)
20#include "base/mac/mac_util.h"
21#include "device/bluetooth/bluetooth_adapter_mac.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022#endif
23
24namespace {
25
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000026using device::BluetoothAdapter;
27using device::BluetoothAdapterFactory;
28
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029// Shared default adapter instance, we don't want to keep this class around
30// if nobody is using it so use a WeakPtr and create the object when needed;
31// since Google C++ Style (and clang's static analyzer) forbids us having
32// exit-time destructors we use a leaky lazy instance for it.
33base::LazyInstance<base::WeakPtr<device::BluetoothAdapter> >::Leaky
34 default_adapter = LAZY_INSTANCE_INITIALIZER;
35
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036typedef std::vector<BluetoothAdapterFactory::AdapterCallback>
37 AdapterCallbackList;
38
39// List of adapter callbacks to be called once the adapter is initialized.
40// Since Google C++ Style (and clang's static analyzer) forbids us having
41// exit-time destructors we use a lazy instance for it.
42base::LazyInstance<AdapterCallbackList> adapter_callbacks =
43 LAZY_INSTANCE_INITIALIZER;
44
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000045#if defined(OS_WIN)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000046void RunAdapterCallbacks() {
47 CHECK(default_adapter.Get().get());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010048 scoped_refptr<BluetoothAdapter> adapter(default_adapter.Get().get());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049 for (std::vector<BluetoothAdapterFactory::AdapterCallback>::const_iterator
50 iter = adapter_callbacks.Get().begin();
51 iter != adapter_callbacks.Get().end();
52 ++iter) {
53 iter->Run(adapter);
54 }
55 adapter_callbacks.Get().clear();
56}
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000057#endif // defined(OS_WIN)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000058
Torne (Richard Coles)58218062012-11-14 11:43:16 +000059} // namespace
60
61namespace device {
62
63// static
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000064bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() {
65#if defined(OS_CHROMEOS)
66 return true;
67#elif defined(OS_WIN)
68 return true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010069#elif defined(OS_MACOSX)
70 return base::mac::IsOSLionOrLater();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000071#endif
72 return false;
73}
74
75// static
76void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000077 if (!default_adapter.Get().get()) {
78#if defined(OS_CHROMEOS)
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010079 chromeos::BluetoothAdapterChromeOS* new_adapter =
80 new chromeos::BluetoothAdapterChromeOS();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010081 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000082#elif defined(OS_WIN)
83 BluetoothAdapterWin* new_adapter = new BluetoothAdapterWin(
84 base::Bind(&RunAdapterCallbacks));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010085 new_adapter->Init();
86 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr();
87#elif defined(OS_MACOSX)
88 BluetoothAdapterMac* new_adapter = new BluetoothAdapterMac();
89 new_adapter->Init();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000090 default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr();
91#endif
92 }
93
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000094 if (default_adapter.Get()->IsInitialized()) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010095 callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000096 } else {
97 adapter_callbacks.Get().push_back(callback);
98 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099}
100
101// static
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::MaybeGetAdapter() {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100103 return scoped_refptr<BluetoothAdapter>(default_adapter.Get().get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104}
105
106} // namespace device