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

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

Issue 14487002: Bluetooth: Profile support for Chrome OS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Transfer out ownership of fd. Fix socket code Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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_profile_experimental_chromeos.h"
6
7 #include <string>
8
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/logging.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop.h"
15 #include "base/string_util.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "base/threading/worker_pool.h"
18 #include "chromeos/dbus/dbus_thread_manager.h"
19 #include "chromeos/dbus/experimental_bluetooth_profile_manager_client.h"
20 #include "chromeos/dbus/experimental_bluetooth_profile_service_provider.h"
21 #include "dbus/bus.h"
22 #include "dbus/file_descriptor.h"
23 #include "dbus/object_path.h"
24 #include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h"
25 #include "device/bluetooth/bluetooth_adapter_factory.h"
26 #include "device/bluetooth/bluetooth_device.h"
27 #include "device/bluetooth/bluetooth_device_experimental_chromeos.h"
28 #include "device/bluetooth/bluetooth_profile.h"
29 #include "device/bluetooth/bluetooth_socket.h"
30 #include "device/bluetooth/bluetooth_socket_experimental_chromeos.h"
31
32 using device::BluetoothAdapter;
33 using device::BluetoothAdapterFactory;
34 using device::BluetoothDevice;
35 using device::BluetoothProfile;
36 using device::BluetoothSocket;
37
38 namespace chromeos {
39
40 BluetoothProfileExperimentalChromeOS::BluetoothProfileExperimentalChromeOS()
41 : weak_ptr_factory_(this) {
42 }
43
44 BluetoothProfileExperimentalChromeOS::~BluetoothProfileExperimentalChromeOS() {
45 DCHECK(object_path_.value().empty());
46 DCHECK(profile_.get() == NULL);
47 }
48
49 void BluetoothProfileExperimentalChromeOS::Init(
50 const std::string& uuid,
51 const device::BluetoothProfile::Options& options,
52 const ProfileCallback& callback) {
53 DCHECK(object_path_.value().empty());
54 DCHECK(profile_.get() == NULL);
55
56 if (!BluetoothDevice::IsUUIDValid(uuid)) {
57 callback.Run(NULL);
58 return;
59 }
60
61 uuid_ = uuid;
62
63 ExperimentalBluetoothProfileManagerClient::Options bluetooth_options;
64 bluetooth_options.name = options.name;
65 bluetooth_options.service = uuid;
66 bluetooth_options.channel = options.channel;
67 bluetooth_options.psm = options.psm;
68 bluetooth_options.require_authentication = options.require_authentication;
69 bluetooth_options.require_authorization = options.require_authorization;
70 bluetooth_options.auto_connect = options.auto_connect;
71 bluetooth_options.version = options.version;
72 bluetooth_options.features = options.features;
73
74 // The object path is relatively meaningless, but has to be unique, so we
75 // use the UUID of the profile.
76 std::string uuid_path;
77 ReplaceChars(uuid, ":-", "_", &uuid_path);
78
79 object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" +
80 uuid_path);
81
82 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
83 profile_.reset(ExperimentalBluetoothProfileServiceProvider::Create(
84 system_bus, object_path_, this));
85 DCHECK(profile_.get());
86
87 VLOG(1) << object_path_.value() << ": Register profile";
88 DBusThreadManager::Get()->GetExperimentalBluetoothProfileManagerClient()->
89 RegisterProfile(
90 object_path_,
91 uuid,
92 bluetooth_options,
93 base::Bind(
94 &BluetoothProfileExperimentalChromeOS::OnRegisterProfile,
95 weak_ptr_factory_.GetWeakPtr(),
96 callback),
97 base::Bind(
98 &BluetoothProfileExperimentalChromeOS::OnRegisterProfileError,
99 weak_ptr_factory_.GetWeakPtr(),
100 callback));
101 }
102
103 void BluetoothProfileExperimentalChromeOS::Unregister() {
104 DCHECK(!object_path_.value().empty());
105 DCHECK(profile_.get());
106
107 profile_.reset();
108
109 VLOG(1) << object_path_.value() << ": Unregister profile";
110 DBusThreadManager::Get()->GetExperimentalBluetoothProfileManagerClient()->
111 UnregisterProfile(
112 object_path_,
113 base::Bind(
114 &BluetoothProfileExperimentalChromeOS::OnUnregisterProfile,
115 weak_ptr_factory_.GetWeakPtr()),
116 base::Bind(
117 &BluetoothProfileExperimentalChromeOS::OnUnregisterProfileError,
118 weak_ptr_factory_.GetWeakPtr()));
119 }
120
121 void BluetoothProfileExperimentalChromeOS::SetConnectionCallback(
122 const ConnectionCallback& callback) {
123 connection_callback_ = callback;
124 }
125
126 void BluetoothProfileExperimentalChromeOS::Release() {
127 VLOG(1) << object_path_.value() << ": Release";
128 }
129
130 void BluetoothProfileExperimentalChromeOS::NewConnection(
131 const dbus::ObjectPath& device_path,
132 dbus::FileDescriptor* fd,
133 const ExperimentalBluetoothProfileServiceProvider::Delegate::Options&
134 options,
135 const ConfirmationCallback& callback) {
136 VLOG(1) << object_path_.value() << ": New connection from device: "
137 << device_path.value();;
138 if (connection_callback_.is_null()) {
139 callback.Run(REJECTED);
140 delete fd;
141 return;
142 }
143
144 // Punt descriptor validity check to a worker thread where i/o is permitted;
145 // on return we'll fetch the adapter and then call the connection callback.
146 //
147 // base::Owned is used to take ownership of the file descriptor so it would
148 // be freed after completion of the bottom half, or if the weak ptr is freed
149 // in the meantime.
150 base::WorkerPool::PostTaskAndReply(
151 FROM_HERE,
152 base::Bind(&BluetoothProfileExperimentalChromeOS::CheckValidity,
153 weak_ptr_factory_.GetWeakPtr(),
154 fd),
155 base::Bind(&BluetoothProfileExperimentalChromeOS::OnCheckValidity,
156 weak_ptr_factory_.GetWeakPtr(),
157 device_path,
158 base::Owned(fd),
satorux1 2013/05/02 01:33:01 Instead of base::Owned(), you can probably make fd
keybuk 2013/05/02 20:17:14 Awesome! This was exactly the kind of advice I was
159 options,
160 callback),
161 false);
162 }
163
164 void BluetoothProfileExperimentalChromeOS::RequestDisconnection(
165 const dbus::ObjectPath& device_path,
166 const ConfirmationCallback& callback) {
167 VLOG(1) << object_path_.value() << ": Request disconnection";
168 callback.Run(SUCCESS);
169 }
170
171 void BluetoothProfileExperimentalChromeOS::Cancel() {
172 VLOG(1) << object_path_.value() << ": Cancel";
173 }
174
175 void BluetoothProfileExperimentalChromeOS::OnRegisterProfile(
176 const ProfileCallback& callback) {
177 VLOG(1) << object_path_.value() << ": Profile registered";
178 callback.Run(this);
179 }
180
181 void BluetoothProfileExperimentalChromeOS::OnRegisterProfileError(
182 const ProfileCallback& callback,
183 const std::string& error_name,
184 const std::string& error_message) {
185 LOG(WARNING) << object_path_.value() << ": Failed to register profile: "
186 << error_name << ": " << error_message;
187 callback.Run(NULL);
188
189 Unregister();
190 }
191
192 void BluetoothProfileExperimentalChromeOS::OnUnregisterProfile() {
193 VLOG(1) << object_path_.value() << ": Profile unregistered";
194 object_path_ = dbus::ObjectPath("");
195 delete this;
196 }
197
198 void BluetoothProfileExperimentalChromeOS::OnUnregisterProfileError(
199 const std::string& error_name,
200 const std::string& error_message) {
201 LOG(WARNING) << object_path_.value() << ": Failed to unregister profile: "
202 << error_name << ": " << error_message;
203 object_path_ = dbus::ObjectPath("");
204 delete this;
205 }
206
207 void BluetoothProfileExperimentalChromeOS::CheckValidity(
208 dbus::FileDescriptor* fd) {
209 base::ThreadRestrictions::AssertIOAllowed();
210 fd->CheckValidity();
211 }
satorux1 2013/05/02 01:33:01 you might want to make this a free function in ano
keybuk 2013/05/02 20:17:14 Done.
212
213 void BluetoothProfileExperimentalChromeOS::OnCheckValidity(
214 const dbus::ObjectPath& device_path,
215 dbus::FileDescriptor* fd,
216 const ExperimentalBluetoothProfileServiceProvider::Delegate::Options&
217 options,
218 const ConfirmationCallback& callback) {
219 VLOG(1) << object_path_.value() << ": Validity check complete";
220 if (!fd->is_valid()) {
221 callback.Run(REJECTED);
222 return;
223 }
224
225 // Obtain the adapter instance; despite the callback call style, this is
226 // actually synchronous on Chrome OS - so we know the fd object isn't about
227 // to get thrown away.
228 BluetoothAdapterFactory::GetAdapter(
229 base::Bind(&BluetoothProfileExperimentalChromeOS::OnGetAdapter,
230 weak_ptr_factory_.GetWeakPtr(),
231 device_path,
232 fd,
233 options,
234 callback));
235 }
236
237 void BluetoothProfileExperimentalChromeOS::OnGetAdapter(
238 const dbus::ObjectPath& device_path,
239 dbus::FileDescriptor* fd,
240 const ExperimentalBluetoothProfileServiceProvider::Delegate::Options&
241 options,
242 const ConfirmationCallback& callback,
243 scoped_refptr<BluetoothAdapter> adapter) {
244 VLOG(1) << object_path_.value() << ": Obtained adapter reference";
245 callback.Run(SUCCESS);
246
247 BluetoothDeviceExperimentalChromeOS* device =
248 static_cast<BluetoothAdapterExperimentalChromeOS*>(adapter.get())->
249 GetDeviceWithPath(device_path);
250 DCHECK(device);
251
252 scoped_refptr<BluetoothSocket> socket((
253 BluetoothSocketExperimentalChromeOS::Create(fd)));
254 connection_callback_.Run(device, socket);
255 }
256
257 } // namespace chromeos
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_profile_experimental_chromeos.h ('k') | device/bluetooth/bluetooth_profile_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698