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

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

Issue 11411130: Implemented BluetoothTaskManagerWin class. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Replace naked MessageLoop pointer with SequencedTaskRunner refcounted pointer Created 8 years 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_polling_thread_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 #include "base/message_loop.h"
15 #include "base/stringprintf.h"
16 #include "base/sys_string_conversions.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "device/bluetooth/bluetooth_task_manager_win.h"
20
21 #pragma comment(lib, "Bthprops.lib")
22 #pragma comment(lib, "delayimp.lib")
23
24 namespace {
25
26 const char* kBluetoothManagerThreadName = "BluetoothPollingThreadWin";
27 const BLUETOOTH_FIND_RADIO_PARAMS adapter_param =
28 { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
29
30 // A frame-based exception handler filter functionj for a handler for exceptions
bryeung 2012/12/19 19:15:42 typo: "functionj"?
31 // generated by the Visual C++ delay loader helper function.
32 int FilterVisualCPPExceptions(DWORD exception_code) {
33 return HRESULT_FACILITY(exception_code) == FACILITY_VISUALCPP ?
34 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
35 }
36
37 // Returns true if the machine has a bluetooth stack available. The first call
38 // to this function will involve file IO, so it should be done on an
39 // appropriate thread. This function is not threadsafe.
40 //
41 // TODO(youngki): Call this function when BluetoothAdapter is initialized. We
42 // should disable Bluetooth support entirely if this function returns false.
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,
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 } // namespace
90
91 namespace device {
92
93 // static
94 const int BluetoothPollingThreadWin::kPollIntervalMs = 500;
95
96 BluetoothPollingThreadWin::BluetoothPollingThreadWin(
97 BluetoothTaskManagerWin* task_manager)
98 : Thread(kBluetoothManagerThreadName),
99 task_manager_(task_manager) {
100 }
101
102 BluetoothPollingThreadWin::~BluetoothPollingThreadWin() {
103 DCHECK(task_manager_->ui_task_runner()->RunsTasksOnCurrentThread());
104 Cancel();
105 }
106
107 void BluetoothPollingThreadWin::StartPolling() {
108 if (!message_loop()) {
109 DCHECK(task_manager_->ui_task_runner()->RunsTasksOnCurrentThread());
110 Start();
111 message_loop()->PostTask(
112 FROM_HERE,
113 base::Bind(&BluetoothPollingThreadWin::PollAdapter,
114 base::Unretained(this)));
115 }
116 }
117
118 // Cancels the pending tasks and waits until all the pending tasks in
119 // BluetoothPollingThread finish.
120 void BluetoothPollingThreadWin::Cancel() {
121 DCHECK(task_manager_->ui_task_runner()->RunsTasksOnCurrentThread());
122 cancellation_flag_.Set();
123 Stop();
124 }
125
126 void BluetoothPollingThreadWin::PollAdapter() {
127 DCHECK_EQ(message_loop(), MessageLoop::current());
128
129 if (cancellation_flag_.IsSet())
130 return;
131
132 HBLUETOOTH_RADIO_FIND adapter_handle = NULL;
133 HBLUETOOTH_RADIO_FIND handle = BluetoothFindFirstRadio(&adapter_param,
134 &adapter_handle);
135 if (handle)
136 BluetoothFindRadioClose(handle);
137
138 BluetoothTaskManagerWin::AdapterState* state =
139 new BluetoothTaskManagerWin::AdapterState();
140 GetAdapterState(adapter_handle, state);
141
142 // Notify the UI thread of the Bluetooth Adapter state.
143 task_manager_->ui_task_runner()->PostTask(
144 FROM_HERE,
145 base::Bind(&BluetoothTaskManagerWin::OnAdapterStateChanged,
146 make_scoped_refptr(task_manager_),
147 base::Owned(state)));
148
149 // Re-poll.
150 message_loop()->PostDelayedTask(
151 FROM_HERE,
152 base::Bind(&BluetoothPollingThreadWin::PollAdapter,
153 base::Unretained(this)),
154 base::TimeDelta::FromMilliseconds(kPollIntervalMs));
155 }
156
157 } // namespace device
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_polling_thread_win.h ('k') | device/bluetooth/bluetooth_task_manager_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698