1 // Copyright 2014 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.
6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop/message_loop.h"
8 #include "chromeos/dbus/dbus_thread_manager.h"
9 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
10 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
11 #include "chromeos/dbus/fake_bluetooth_device_client.h"
12 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
13 #include "chromeos/dbus/fake_bluetooth_input_client.h"
14 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
15 #include "device/bluetooth/bluetooth_adapter.h"
16 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
17 #include "device/bluetooth/bluetooth_adapter_factory.h"
18 #include "device/bluetooth/bluetooth_device.h"
19 #include "device/bluetooth/bluetooth_device_chromeos.h"
20 #include "device/bluetooth/bluetooth_socket.h"
21 #include "device/bluetooth/bluetooth_socket_chromeos.h"
22 #include "device/bluetooth/bluetooth_socket_thread.h"
23 #include "device/bluetooth/bluetooth_uuid.h"
24 #include "net/base/io_buffer.h"
25 #include "net/base/net_errors.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 using device::BluetoothAdapter
;
29 using device::BluetoothDevice
;
30 using device::BluetoothSocket
;
31 using device::BluetoothSocketThread
;
32 using device::BluetoothUUID
;
36 void DoNothingDBusErrorCallback(const std::string
& error_name
,
37 const std::string
& error_message
) {}
43 class BluetoothSocketChromeOSTest
: public testing::Test
{
45 BluetoothSocketChromeOSTest()
46 : success_callback_count_(0),
47 error_callback_count_(0),
49 last_bytes_received_(0),
50 last_reason_(BluetoothSocket::kSystemError
) {}
52 virtual void SetUp() OVERRIDE
{
53 scoped_ptr
<DBusThreadManagerSetter
> dbus_setter
=
54 DBusThreadManager::GetSetterForTesting();
56 dbus_setter
->SetBluetoothAdapterClient(
57 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
58 dbus_setter
->SetBluetoothAgentManagerClient(
59 scoped_ptr
<BluetoothAgentManagerClient
>(
60 new FakeBluetoothAgentManagerClient
));
61 dbus_setter
->SetBluetoothDeviceClient(
62 scoped_ptr
<BluetoothDeviceClient
>(new FakeBluetoothDeviceClient
));
63 dbus_setter
->SetBluetoothGattServiceClient(
64 scoped_ptr
<BluetoothGattServiceClient
>(
65 new FakeBluetoothGattServiceClient
));
66 dbus_setter
->SetBluetoothInputClient(
67 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
68 dbus_setter
->SetBluetoothProfileManagerClient(
69 scoped_ptr
<BluetoothProfileManagerClient
>(
70 new FakeBluetoothProfileManagerClient
));
72 BluetoothSocketThread::Get();
74 // Grab a pointer to the adapter.
75 device::BluetoothAdapterFactory::GetAdapter(
76 base::Bind(&BluetoothSocketChromeOSTest::AdapterCallback
,
77 base::Unretained(this)));
78 ASSERT_TRUE(adapter_
.get() != NULL
);
79 ASSERT_TRUE(adapter_
->IsInitialized());
80 ASSERT_TRUE(adapter_
->IsPresent());
82 // Turn on the adapter.
85 base::Bind(&base::DoNothing
),
86 base::Bind(&base::DoNothing
));
87 ASSERT_TRUE(adapter_
->IsPowered());
90 virtual void TearDown() OVERRIDE
{
92 BluetoothSocketThread::CleanupForTesting();
93 DBusThreadManager::Shutdown();
96 void AdapterCallback(scoped_refptr
<BluetoothAdapter
> adapter
) {
100 void SuccessCallback() {
101 ++success_callback_count_
;
102 message_loop_
.Quit();
105 void ErrorCallback(const std::string
& message
) {
106 ++error_callback_count_
;
107 last_message_
= message
;
109 message_loop_
.Quit();
112 void ConnectToServiceSuccessCallback(scoped_refptr
<BluetoothSocket
> socket
) {
113 ++success_callback_count_
;
114 last_socket_
= socket
;
116 message_loop_
.Quit();
119 void SendSuccessCallback(int bytes_sent
) {
120 ++success_callback_count_
;
121 last_bytes_sent_
= bytes_sent
;
123 message_loop_
.Quit();
126 void ReceiveSuccessCallback(int bytes_received
,
127 scoped_refptr
<net::IOBuffer
> io_buffer
) {
128 ++success_callback_count_
;
129 last_bytes_received_
= bytes_received
;
130 last_io_buffer_
= io_buffer
;
132 message_loop_
.Quit();
135 void ReceiveErrorCallback(BluetoothSocket::ErrorReason reason
,
136 const std::string
& error_message
) {
137 ++error_callback_count_
;
138 last_reason_
= reason
;
139 last_message_
= error_message
;
141 message_loop_
.Quit();
144 void CreateServiceSuccessCallback(scoped_refptr
<BluetoothSocket
> socket
) {
145 ++success_callback_count_
;
146 last_socket_
= socket
;
149 void AcceptSuccessCallback(const BluetoothDevice
* device
,
150 scoped_refptr
<BluetoothSocket
> socket
) {
151 ++success_callback_count_
;
152 last_device_
= device
;
153 last_socket_
= socket
;
155 message_loop_
.Quit();
158 void ImmediateSuccessCallback() {
159 ++success_callback_count_
;
163 base::MessageLoop message_loop_
;
165 scoped_refptr
<BluetoothAdapter
> adapter_
;
167 unsigned int success_callback_count_
;
168 unsigned int error_callback_count_
;
170 std::string last_message_
;
171 scoped_refptr
<BluetoothSocket
> last_socket_
;
172 int last_bytes_sent_
;
173 int last_bytes_received_
;
174 scoped_refptr
<net::IOBuffer
> last_io_buffer_
;
175 BluetoothSocket::ErrorReason last_reason_
;
176 const BluetoothDevice
* last_device_
;
179 TEST_F(BluetoothSocketChromeOSTest
, Connect
) {
180 BluetoothDevice
* device
= adapter_
->GetDevice(
181 FakeBluetoothDeviceClient::kPairedDeviceAddress
);
182 ASSERT_TRUE(device
!= NULL
);
184 device
->ConnectToService(
185 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
186 base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback
,
187 base::Unretained(this)),
188 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
189 base::Unretained(this)));
193 EXPECT_EQ(1U, success_callback_count_
);
194 EXPECT_EQ(0U, error_callback_count_
);
195 EXPECT_TRUE(last_socket_
.get() != NULL
);
197 // Take ownership of the socket for the remainder of the test.
198 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
200 success_callback_count_
= 0;
201 error_callback_count_
= 0;
203 // Send data to the socket, expect all of the data to be sent.
204 scoped_refptr
<net::StringIOBuffer
> write_buffer(
205 new net::StringIOBuffer("test"));
207 socket
->Send(write_buffer
.get(), write_buffer
->size(),
208 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback
,
209 base::Unretained(this)),
210 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
211 base::Unretained(this)));
214 EXPECT_EQ(1U, success_callback_count_
);
215 EXPECT_EQ(0U, error_callback_count_
);
216 EXPECT_EQ(last_bytes_sent_
, write_buffer
->size());
218 success_callback_count_
= 0;
219 error_callback_count_
= 0;
221 // Receive data from the socket, and fetch the buffer from the callback; since
222 // the fake is an echo server, we expect to receive what we wrote.
225 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback
,
226 base::Unretained(this)),
227 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback
,
228 base::Unretained(this)));
231 EXPECT_EQ(1U, success_callback_count_
);
232 EXPECT_EQ(0U, error_callback_count_
);
233 EXPECT_EQ(4, last_bytes_received_
);
234 EXPECT_TRUE(last_io_buffer_
.get() != NULL
);
236 // Take ownership of the received buffer.
237 scoped_refptr
<net::IOBuffer
> read_buffer
= last_io_buffer_
;
238 last_io_buffer_
= NULL
;
239 success_callback_count_
= 0;
240 error_callback_count_
= 0;
242 std::string data
= std::string(read_buffer
->data(), last_bytes_received_
);
243 EXPECT_EQ("test", data
);
247 // Receive data again; the socket will have been closed, this should cause a
248 // disconnected error to be returned via the error callback.
251 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback
,
252 base::Unretained(this)),
253 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback
,
254 base::Unretained(this)));
257 EXPECT_EQ(0U, success_callback_count_
);
258 EXPECT_EQ(1U, error_callback_count_
);
259 EXPECT_EQ(BluetoothSocket::kDisconnected
, last_reason_
);
260 EXPECT_EQ(net::ErrorToString(net::OK
), last_message_
);
262 success_callback_count_
= 0;
263 error_callback_count_
= 0;
265 // Send data again; since the socket is closed we should get a system error
266 // equivalent to the connection reset error.
267 write_buffer
= new net::StringIOBuffer("second test");
269 socket
->Send(write_buffer
.get(), write_buffer
->size(),
270 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback
,
271 base::Unretained(this)),
272 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
273 base::Unretained(this)));
276 EXPECT_EQ(0U, success_callback_count_
);
277 EXPECT_EQ(1U, error_callback_count_
);
278 EXPECT_EQ(net::ErrorToString(net::ERR_CONNECTION_RESET
), last_message_
);
280 success_callback_count_
= 0;
281 error_callback_count_
= 0;
283 // Close our end of the socket.
284 socket
->Disconnect(base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
285 base::Unretained(this)));
288 EXPECT_EQ(1U, success_callback_count_
);
291 TEST_F(BluetoothSocketChromeOSTest
, Listen
) {
292 adapter_
->CreateRfcommService(
293 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
294 BluetoothAdapter::ServiceOptions(),
295 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
296 base::Unretained(this)),
297 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
298 base::Unretained(this)));
300 EXPECT_EQ(1U, success_callback_count_
);
301 EXPECT_EQ(0U, error_callback_count_
);
302 EXPECT_TRUE(last_socket_
.get() != NULL
);
304 // Take ownership of the socket for the remainder of the test.
305 scoped_refptr
<BluetoothSocket
> server_socket
= last_socket_
;
307 success_callback_count_
= 0;
308 error_callback_count_
= 0;
310 // Simulate an incoming connection by just calling the ConnectProfile method
311 // of the underlying fake device client (from the BlueZ point of view,
312 // outgoing and incoming look the same).
314 // This is done before the Accept() call to simulate a pending call at the
315 // point that Accept() is called.
316 FakeBluetoothDeviceClient
* fake_bluetooth_device_client
=
317 static_cast<FakeBluetoothDeviceClient
*>(
318 DBusThreadManager::Get()->GetBluetoothDeviceClient());
319 BluetoothDevice
* device
= adapter_
->GetDevice(
320 FakeBluetoothDeviceClient::kPairedDeviceAddress
);
321 ASSERT_TRUE(device
!= NULL
);
322 fake_bluetooth_device_client
->ConnectProfile(
323 static_cast<BluetoothDeviceChromeOS
*>(device
)->object_path(),
324 FakeBluetoothProfileManagerClient::kRfcommUuid
,
325 base::Bind(&base::DoNothing
),
326 base::Bind(&DoNothingDBusErrorCallback
));
328 server_socket
->Accept(
329 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback
,
330 base::Unretained(this)),
331 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
332 base::Unretained(this)));
336 EXPECT_EQ(1U, success_callback_count_
);
337 EXPECT_EQ(0U, error_callback_count_
);
338 EXPECT_TRUE(last_socket_
.get() != NULL
);
340 // Take ownership of the client socket for the remainder of the test.
341 scoped_refptr
<BluetoothSocket
> client_socket
= last_socket_
;
343 success_callback_count_
= 0;
344 error_callback_count_
= 0;
346 // Close our end of the client socket.
347 client_socket
->Disconnect(
348 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
349 base::Unretained(this)));
353 EXPECT_EQ(1U, success_callback_count_
);
354 client_socket
= NULL
;
355 success_callback_count_
= 0;
356 error_callback_count_
= 0;
358 // Run a second connection test, this time calling Accept() before the
359 // incoming connection comes in.
360 server_socket
->Accept(
361 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback
,
362 base::Unretained(this)),
363 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
364 base::Unretained(this)));
366 fake_bluetooth_device_client
->ConnectProfile(
367 static_cast<BluetoothDeviceChromeOS
*>(device
)->object_path(),
368 FakeBluetoothProfileManagerClient::kRfcommUuid
,
369 base::Bind(&base::DoNothing
),
370 base::Bind(&DoNothingDBusErrorCallback
));
374 EXPECT_EQ(1U, success_callback_count_
);
375 EXPECT_EQ(0U, error_callback_count_
);
376 EXPECT_TRUE(last_socket_
.get() != NULL
);
378 // Take ownership of the client socket for the remainder of the test.
379 client_socket
= last_socket_
;
381 success_callback_count_
= 0;
382 error_callback_count_
= 0;
384 // Close our end of the client socket.
385 client_socket
->Disconnect(
386 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
387 base::Unretained(this)));
391 EXPECT_EQ(1U, success_callback_count_
);
392 client_socket
= NULL
;
393 success_callback_count_
= 0;
394 error_callback_count_
= 0;
396 // Now close the server socket.
397 server_socket
->Disconnect(
398 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
399 base::Unretained(this)));
401 EXPECT_EQ(1U, success_callback_count_
);
404 TEST_F(BluetoothSocketChromeOSTest
, ListenBeforeAdapterStart
) {
405 // Start off with an invisible adapter, register the profile, then make
406 // the adapter visible.
407 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client
=
408 static_cast<FakeBluetoothAdapterClient
*>(
409 DBusThreadManager::Get()->GetBluetoothAdapterClient());
410 fake_bluetooth_adapter_client
->SetVisible(false);
412 adapter_
->CreateRfcommService(
413 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
414 BluetoothAdapter::ServiceOptions(),
415 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
416 base::Unretained(this)),
417 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
418 base::Unretained(this)));
420 EXPECT_EQ(1U, success_callback_count_
);
421 EXPECT_EQ(0U, error_callback_count_
);
422 EXPECT_TRUE(last_socket_
.get() != NULL
);
424 // Take ownership of the socket for the remainder of the test.
425 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
427 success_callback_count_
= 0;
428 error_callback_count_
= 0;
430 // But there shouldn't be a profile registered yet.
431 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
432 static_cast<FakeBluetoothProfileManagerClient
*>(
433 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
434 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
435 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
436 FakeBluetoothProfileManagerClient::kRfcommUuid
);
437 EXPECT_TRUE(profile_service_provider
== NULL
);
439 // Make the adapter visible. This should register a profile.
440 fake_bluetooth_adapter_client
->SetVisible(true);
442 profile_service_provider
=
443 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
444 FakeBluetoothProfileManagerClient::kRfcommUuid
);
445 EXPECT_TRUE(profile_service_provider
!= NULL
);
447 // Cleanup the socket.
449 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
450 base::Unretained(this)));
452 EXPECT_EQ(1U, success_callback_count_
);
455 TEST_F(BluetoothSocketChromeOSTest
, ListenAcrossAdapterRestart
) {
456 // The fake adapter starts off visible by default.
457 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client
=
458 static_cast<FakeBluetoothAdapterClient
*>(
459 DBusThreadManager::Get()->GetBluetoothAdapterClient());
461 adapter_
->CreateRfcommService(
462 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
463 BluetoothAdapter::ServiceOptions(),
464 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
465 base::Unretained(this)),
466 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
467 base::Unretained(this)));
469 EXPECT_EQ(1U, success_callback_count_
);
470 EXPECT_EQ(0U, error_callback_count_
);
471 EXPECT_TRUE(last_socket_
.get() != NULL
);
473 // Take ownership of the socket for the remainder of the test.
474 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
476 success_callback_count_
= 0;
477 error_callback_count_
= 0;
479 // Make sure the profile was registered with the daemon.
480 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
481 static_cast<FakeBluetoothProfileManagerClient
*>(
482 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
483 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
484 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
485 FakeBluetoothProfileManagerClient::kRfcommUuid
);
486 EXPECT_TRUE(profile_service_provider
!= NULL
);
488 // Make the adapter invisible, and fiddle with the profile fake to unregister
489 // the profile since this doesn't happen automatically.
490 fake_bluetooth_adapter_client
->SetVisible(false);
491 fake_bluetooth_profile_manager_client
->UnregisterProfile(
492 static_cast<BluetoothSocketChromeOS
*>(socket
.get())->object_path(),
493 base::Bind(&base::DoNothing
),
494 base::Bind(&DoNothingDBusErrorCallback
));
496 // Then make the adapter visible again. This should re-register the profile.
497 fake_bluetooth_adapter_client
->SetVisible(true);
499 profile_service_provider
=
500 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
501 FakeBluetoothProfileManagerClient::kRfcommUuid
);
502 EXPECT_TRUE(profile_service_provider
!= NULL
);
504 // Cleanup the socket.
506 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
507 base::Unretained(this)));
509 EXPECT_EQ(1U, success_callback_count_
);
512 } // namespace chromeos