OLD | NEW |
(Empty) | |
| 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_polling_thread_win.h" |
| 6 |
| 7 #include <BluetoothAPIs.h> |
| 8 #include "base/message_loop.h" |
| 9 #include "base/stringprintf.h" |
| 10 #include "base/synchronization/cancellation_flag.h" |
| 11 #include "base/sys_string_conversions.h" |
| 12 #include "base/threading/thread_checker.h" |
| 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "device/bluetooth/bluetooth_adapter_win.h" |
| 15 |
| 16 # pragma comment(lib, "Bthprops.lib") |
| 17 |
| 18 namespace { |
| 19 |
| 20 const char* kBluetoothManagerThreadName = "BluetoothPollingThreadWin"; |
| 21 const BLUETOOTH_FIND_RADIO_PARAMS adapter_param = |
| 22 { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; |
| 23 |
| 24 } // namespace |
| 25 |
| 26 namespace device { |
| 27 |
| 28 // static |
| 29 const int BluetoothPollingThreadWin::kPollIntervalMs = 500; |
| 30 |
| 31 BluetoothPollingThreadWin::BluetoothPollingThreadWin() |
| 32 : Thread(kBluetoothManagerThreadName), |
| 33 cancellation_flag_(new base::CancellationFlag()), |
| 34 thread_checker_(NULL), |
| 35 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 36 } |
| 37 |
| 38 BluetoothPollingThreadWin::~BluetoothPollingThreadWin() { |
| 39 cancellation_flag_->Set(); |
| 40 Stop(); |
| 41 } |
| 42 |
| 43 void BluetoothPollingThreadWin::AddObserver(Observer* observer) { |
| 44 DCHECK(observer); |
| 45 observers_.AddObserver(observer); |
| 46 } |
| 47 |
| 48 void BluetoothPollingThreadWin::RemoveObserver(Observer* observer) { |
| 49 DCHECK(observer); |
| 50 observers_.RemoveObserver(observer); |
| 51 } |
| 52 |
| 53 void BluetoothPollingThreadWin::Init() { |
| 54 if (!message_loop()) { |
| 55 Start(); |
| 56 message_loop()->PostTask( |
| 57 FROM_HERE, |
| 58 base::Bind(&BluetoothPollingThreadWin::PollAdapter, |
| 59 base::Unretained(this), |
| 60 weak_ptr_factory_.GetWeakPtr())); |
| 61 } |
| 62 } |
| 63 |
| 64 // static |
| 65 void BluetoothPollingThreadWin::GetAdapterProperties( |
| 66 const HANDLE adapter_handle, Properties* properties) { |
| 67 std::string name; |
| 68 std::string address; |
| 69 bool powered = false; |
| 70 BLUETOOTH_RADIO_INFO adapter_info = { sizeof(BLUETOOTH_RADIO_INFO), 0 }; |
| 71 if (adapter_handle && |
| 72 ERROR_SUCCESS == BluetoothGetRadioInfo(adapter_handle, |
| 73 &adapter_info)) { |
| 74 name = base::SysWideToUTF8(adapter_info.szName); |
| 75 address = base::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X", |
| 76 adapter_info.address.rgBytes[5], |
| 77 adapter_info.address.rgBytes[4], |
| 78 adapter_info.address.rgBytes[3], |
| 79 adapter_info.address.rgBytes[2], |
| 80 adapter_info.address.rgBytes[1], |
| 81 adapter_info.address.rgBytes[0]); |
| 82 powered = !!BluetoothIsConnectable(adapter_handle); |
| 83 } |
| 84 properties->name = name; |
| 85 properties->address = address; |
| 86 properties->powered = powered; |
| 87 } |
| 88 |
| 89 void BluetoothPollingThreadWin::PollAdapter( |
| 90 base::WeakPtr<BluetoothPollingThreadWin> weak_ptr) { |
| 91 if (cancellation_flag_->IsSet()) |
| 92 return; |
| 93 |
| 94 if (!thread_checker_) { |
| 95 thread_checker_.reset(new base::ThreadChecker()); |
| 96 } |
| 97 DCHECK(thread_checker_->CalledOnValidThread()); |
| 98 |
| 99 HBLUETOOTH_RADIO_FIND adapter_handle = NULL; |
| 100 HBLUETOOTH_RADIO_FIND handle = BluetoothFindFirstRadio(&adapter_param, |
| 101 &adapter_handle); |
| 102 if (handle) |
| 103 BluetoothFindRadioClose(handle); |
| 104 |
| 105 Properties* properties = new Properties(); |
| 106 GetAdapterProperties(adapter_handle, properties); |
| 107 |
| 108 content::BrowserThread::PostTask( |
| 109 content::BrowserThread::UI, |
| 110 FROM_HERE, |
| 111 base::Bind(&BluetoothPollingThreadWin::OnAdapterPropertyChanged, |
| 112 weak_ptr, |
| 113 base::Owned(properties))); |
| 114 |
| 115 // Re-poll. |
| 116 MessageLoop::current()->PostDelayedTask( |
| 117 FROM_HERE, |
| 118 base::Bind(&BluetoothPollingThreadWin::PollAdapter, |
| 119 base::Unretained(this), |
| 120 weak_ptr), |
| 121 base::TimeDelta::FromMilliseconds(kPollIntervalMs)); |
| 122 } |
| 123 |
| 124 void BluetoothPollingThreadWin::OnAdapterPropertyChanged( |
| 125 const Properties* properties) { |
| 126 FOR_EACH_OBSERVER(BluetoothPollingThreadWin::Observer, observers_, |
| 127 AdapterPropertyChanged(*properties)); |
| 128 } |
| 129 |
| 130 } // namespace device |
OLD | NEW |