Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: device/bluetooth/bluetooth_task_manager_win.cc

Issue 11411130: Implemented BluetoothTaskManagerWin class. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed some style issues. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_task_manager_win.h"
6
7 #include <BluetoothAPIs.h>
8 #if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700
9 // The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h.
10 #undef FACILITY_VISUALCPP
11 #endif
12 #include <delayimp.h>
13 #include <string>
14
15 #include "base/bind.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/message_loop.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/stringprintf.h"
20 #include "base/sys_string_conversions.h"
21 #include "base/threading/sequenced_worker_pool.h"
22 #include "base/threading/thread_restrictions.h"
23
grt (UTC plus 2) 2013/01/10 04:01:47 #include "base/win/scoped_handle.h"
youngki 2013/01/11 20:00:25 Done.
24 #pragma comment(lib, "Bthprops.lib")
25
26 namespace {
27
28 const int kNumThreadsInWorkerPool = 3;
29 const char* kBluetoothThreadName = "BluetoothPollingThreadWin";
grt (UTC plus 2) 2013/01/10 04:01:47 const char kBluetoothThreadName[] = "...";
youngki 2013/01/11 20:00:25 Done.
30 const BLUETOOTH_FIND_RADIO_PARAMS adapter_param =
grt (UTC plus 2) 2013/01/10 04:01:47 since this is a constant, how about kEmptyAdapterP
youngki 2013/01/11 20:00:25 Moved it into PollAdapter.
31 { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
32
33 // A frame-based exception handler filter function for a handler for exceptions
34 // generated by the Visual C++ delay loader helper function.
35 int FilterVisualCPPExceptions(DWORD exception_code) {
36 return HRESULT_FACILITY(exception_code) == FACILITY_VISUALCPP ?
37 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
38 } // namespace
39
40 // Returns true if the machine has a bluetooth stack available. The first call
41 // to this function will involve file IO, so it should be done on an
42 // appropriate thread. This function is not threadsafe.
43 bool HasBluetoothStack() {
44 static enum {
45 HBS_UNKNOWN,
46 HBS_YES,
47 HBS_NO,
48 } has_bluetooth_stack = HBS_UNKNOWN;
49
50 if (has_bluetooth_stack == HBS_UNKNOWN) {
51 base::ThreadRestrictions::AssertIOAllowed();
52 HRESULT hr = E_FAIL;
53 __try {
54 hr = __HrLoadAllImportsForDll("bthprops.cpl");
55 } __except(FilterVisualCPPExceptions(::GetExceptionCode())) {
56 hr = E_FAIL;
57 }
58 has_bluetooth_stack = SUCCEEDED(hr) ? HBS_YES : HBS_NO;
59 }
60
61 return has_bluetooth_stack == HBS_YES;
62 }
63
64 // Populates bluetooth adapter state using adapter_handle.
65 void GetAdapterState(const HANDLE adapter_handle,
grt (UTC plus 2) 2013/01/10 04:01:47 nit: no const
youngki 2013/01/11 20:00:25 Done.
66 device::BluetoothTaskManagerWin::AdapterState* state) {
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 state->name = name;
85 state->address = address;
86 state->powered = powered;
87 }
88
89 }
90
91 namespace device {
92
93 // static
94 const int BluetoothTaskManagerWin::kPollIntervalMs = 500;
95
96 BluetoothTaskManagerWin::BluetoothTaskManagerWin()
97 : ui_task_runner_(MessageLoop::current()->message_loop_proxy()),
grt (UTC plus 2) 2013/01/10 04:01:47 i was under the impression that using ThreadTaskRu
youngki 2013/01/11 20:00:25 Done. If that's the new hotness, I want to be in t
98 worker_pool_(new base::SequencedWorkerPool(kNumThreadsInWorkerPool,
99 kBluetoothThreadName)),
100 bluetooth_task_runner_(
101 worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
102 worker_pool_->GetSequenceToken(),
103 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {
104 }
105
106 BluetoothTaskManagerWin::~BluetoothTaskManagerWin() {
107 }
108
109 void BluetoothTaskManagerWin::AddObserver(Observer* observer) {
110 CHECK(observer);
grt (UTC plus 2) 2013/01/10 04:01:47 why not DCHECK here and on line 115?
youngki 2013/01/11 20:00:25 Done.
111 observers_.AddObserver(observer);
112 }
113
114 void BluetoothTaskManagerWin::RemoveObserver(Observer* observer) {
115 CHECK(observer);
116 observers_.RemoveObserver(observer);
117 }
118
119 void BluetoothTaskManagerWin::Initialize() {
120 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
121 bluetooth_task_runner_->PostTask(
122 FROM_HERE,
123 base::Bind(&BluetoothTaskManagerWin::StartPolling,
124 this));
125 }
126
127 void BluetoothTaskManagerWin::StartPolling() {
128 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread());
129
130 // TODO(youngki): Handle this check where BluetoothAdapter is initialized.
131 if (HasBluetoothStack()) {
132 PollAdapter();
133 }
134 }
135
136 void BluetoothTaskManagerWin::Shutdown() {
137 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
138 worker_pool_->Shutdown();
139 }
140
141 void BluetoothTaskManagerWin::OnAdapterStateChanged(const AdapterState* state) {
142 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
143 FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_,
144 AdapterStateChanged(*state));
145 }
146
147 void BluetoothTaskManagerWin::PollAdapter() {
148 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread());
149
150 HBLUETOOTH_RADIO_FIND adapter_handle = NULL;
grt (UTC plus 2) 2013/01/10 04:01:47 this has the wrong type and is being leaked. you s
youngki 2013/01/11 20:00:25 Done. I never knew about ScopedHandle. Thanks for
151 HBLUETOOTH_RADIO_FIND handle = BluetoothFindFirstRadio(&adapter_param,
152 &adapter_handle);
grt (UTC plus 2) 2013/01/10 04:01:47 and change &adapter_handle to adapter_handle.Recei
youngki 2013/01/11 20:00:25 Done.
153
154 if (handle)
155 BluetoothFindRadioClose(handle);
156
157 AdapterState* state = new AdapterState();
158 GetAdapterState(adapter_handle, state);
159
160 // Notify the UI thread of the Bluetooth Adapter state.
161 ui_task_runner_->PostTask(
162 FROM_HERE,
163 base::Bind(&BluetoothTaskManagerWin::OnAdapterStateChanged,
164 this,
165 base::Owned(state)));
166
167 // Re-poll.
168 bluetooth_task_runner_->PostDelayedTask(
169 FROM_HERE,
170 base::Bind(&BluetoothTaskManagerWin::PollAdapter,
171 this),
172 base::TimeDelta::FromMilliseconds(kPollIntervalMs));
173 }
174
175 } // namespace device
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_task_manager_win.h ('k') | device/bluetooth/bluetooth_task_manager_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698