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/fake_bluetooth_adapter_client.h"
9 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
10 #include "chromeos/dbus/fake_bluetooth_device_client.h"
11 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
12 #include "chromeos/dbus/fake_bluetooth_input_client.h"
13 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
14 #include "chromeos/dbus/fake_dbus_thread_manager.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
<FakeDBusThreadManager
> fake_dbus_thread_manager(
54 new FakeDBusThreadManager
);
56 fake_dbus_thread_manager
->SetBluetoothAdapterClient(
57 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
58 fake_dbus_thread_manager
->SetBluetoothAgentManagerClient(
59 scoped_ptr
<BluetoothAgentManagerClient
>(
60 new FakeBluetoothAgentManagerClient
));
61 fake_dbus_thread_manager
->SetBluetoothDeviceClient(
62 scoped_ptr
<BluetoothDeviceClient
>(new FakeBluetoothDeviceClient
));
63 fake_dbus_thread_manager
->SetBluetoothGattServiceClient(
64 scoped_ptr
<BluetoothGattServiceClient
>(
65 new FakeBluetoothGattServiceClient
));
66 fake_dbus_thread_manager
->SetBluetoothInputClient(
67 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
68 fake_dbus_thread_manager
->SetBluetoothProfileManagerClient(
69 scoped_ptr
<BluetoothProfileManagerClient
>(
70 new FakeBluetoothProfileManagerClient
));
72 DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager
.release());
73 BluetoothSocketThread::Get();
75 // Grab a pointer to the adapter.
76 device::BluetoothAdapterFactory::GetAdapter(
77 base::Bind(&BluetoothSocketChromeOSTest::AdapterCallback
,
78 base::Unretained(this)));
79 ASSERT_TRUE(adapter_
.get() != NULL
);
80 ASSERT_TRUE(adapter_
->IsInitialized());
81 ASSERT_TRUE(adapter_
->IsPresent());
83 // Turn on the adapter.
86 base::Bind(&base::DoNothing
),
87 base::Bind(&base::DoNothing
));
88 ASSERT_TRUE(adapter_
->IsPowered());
91 virtual void TearDown() OVERRIDE
{
93 BluetoothSocketThread::CleanupForTesting();
94 DBusThreadManager::Shutdown();
97 void AdapterCallback(scoped_refptr
<BluetoothAdapter
> adapter
) {
101 void SuccessCallback() {
102 ++success_callback_count_
;
103 message_loop_
.Quit();
106 void ErrorCallback(const std::string
& message
) {
107 ++error_callback_count_
;
108 last_message_
= message
;
110 message_loop_
.Quit();
113 void ConnectToServiceSuccessCallback(scoped_refptr
<BluetoothSocket
> socket
) {
114 ++success_callback_count_
;
115 last_socket_
= socket
;
117 message_loop_
.Quit();
120 void SendSuccessCallback(int bytes_sent
) {
121 ++success_callback_count_
;
122 last_bytes_sent_
= bytes_sent
;
124 message_loop_
.Quit();
127 void ReceiveSuccessCallback(int bytes_received
,
128 scoped_refptr
<net::IOBuffer
> io_buffer
) {
129 ++success_callback_count_
;
130 last_bytes_received_
= bytes_received
;
131 last_io_buffer_
= io_buffer
;
133 message_loop_
.Quit();
136 void ReceiveErrorCallback(BluetoothSocket::ErrorReason reason
,
137 const std::string
& error_message
) {
138 ++error_callback_count_
;
139 last_reason_
= reason
;
140 last_message_
= error_message
;
142 message_loop_
.Quit();
145 void CreateServiceSuccessCallback(scoped_refptr
<BluetoothSocket
> socket
) {
146 ++success_callback_count_
;
147 last_socket_
= socket
;
150 void AcceptSuccessCallback(const BluetoothDevice
* device
,
151 scoped_refptr
<BluetoothSocket
> socket
) {
152 ++success_callback_count_
;
153 last_device_
= device
;
154 last_socket_
= socket
;
156 message_loop_
.Quit();
159 void ImmediateSuccessCallback() {
160 ++success_callback_count_
;
164 base::MessageLoop message_loop_
;
166 scoped_refptr
<BluetoothAdapter
> adapter_
;
168 unsigned int success_callback_count_
;
169 unsigned int error_callback_count_
;
171 std::string last_message_
;
172 scoped_refptr
<BluetoothSocket
> last_socket_
;
173 int last_bytes_sent_
;
174 int last_bytes_received_
;
175 scoped_refptr
<net::IOBuffer
> last_io_buffer_
;
176 BluetoothSocket::ErrorReason last_reason_
;
177 const BluetoothDevice
* last_device_
;
180 TEST_F(BluetoothSocketChromeOSTest
, Connect
) {
181 BluetoothDevice
* device
= adapter_
->GetDevice(
182 FakeBluetoothDeviceClient::kPairedDeviceAddress
);
183 ASSERT_TRUE(device
!= NULL
);
185 device
->ConnectToService(
186 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
187 base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback
,
188 base::Unretained(this)),
189 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
190 base::Unretained(this)));
194 EXPECT_EQ(1U, success_callback_count_
);
195 EXPECT_EQ(0U, error_callback_count_
);
196 EXPECT_TRUE(last_socket_
.get() != NULL
);
198 // Take ownership of the socket for the remainder of the test.
199 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
201 success_callback_count_
= 0;
202 error_callback_count_
= 0;
204 // Send data to the socket, expect all of the data to be sent.
205 scoped_refptr
<net::StringIOBuffer
> write_buffer(
206 new net::StringIOBuffer("test"));
208 socket
->Send(write_buffer
.get(), write_buffer
->size(),
209 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback
,
210 base::Unretained(this)),
211 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
212 base::Unretained(this)));
215 EXPECT_EQ(1U, success_callback_count_
);
216 EXPECT_EQ(0U, error_callback_count_
);
217 EXPECT_EQ(last_bytes_sent_
, write_buffer
->size());
219 success_callback_count_
= 0;
220 error_callback_count_
= 0;
222 // Receive data from the socket, and fetch the buffer from the callback; since
223 // the fake is an echo server, we expect to receive what we wrote.
226 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback
,
227 base::Unretained(this)),
228 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback
,
229 base::Unretained(this)));
232 EXPECT_EQ(1U, success_callback_count_
);
233 EXPECT_EQ(0U, error_callback_count_
);
234 EXPECT_EQ(4, last_bytes_received_
);
235 EXPECT_TRUE(last_io_buffer_
.get() != NULL
);
237 // Take ownership of the received buffer.
238 scoped_refptr
<net::IOBuffer
> read_buffer
= last_io_buffer_
;
239 last_io_buffer_
= NULL
;
240 success_callback_count_
= 0;
241 error_callback_count_
= 0;
243 std::string data
= std::string(read_buffer
->data(), last_bytes_received_
);
244 EXPECT_EQ("test", data
);
248 // Receive data again; the socket will have been closed, this should cause a
249 // disconnected error to be returned via the error callback.
252 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback
,
253 base::Unretained(this)),
254 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback
,
255 base::Unretained(this)));
258 EXPECT_EQ(0U, success_callback_count_
);
259 EXPECT_EQ(1U, error_callback_count_
);
260 EXPECT_EQ(BluetoothSocket::kDisconnected
, last_reason_
);
261 EXPECT_EQ(net::ErrorToString(net::OK
), last_message_
);
263 success_callback_count_
= 0;
264 error_callback_count_
= 0;
266 // Send data again; since the socket is closed we should get a system error
267 // equivalent to the connection reset error.
268 write_buffer
= new net::StringIOBuffer("second test");
270 socket
->Send(write_buffer
.get(), write_buffer
->size(),
271 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback
,
272 base::Unretained(this)),
273 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
274 base::Unretained(this)));
277 EXPECT_EQ(0U, success_callback_count_
);
278 EXPECT_EQ(1U, error_callback_count_
);
279 EXPECT_EQ(net::ErrorToString(net::ERR_CONNECTION_RESET
), last_message_
);
281 success_callback_count_
= 0;
282 error_callback_count_
= 0;
284 // Close our end of the socket.
285 socket
->Disconnect(base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
286 base::Unretained(this)));
289 EXPECT_EQ(1U, success_callback_count_
);
292 TEST_F(BluetoothSocketChromeOSTest
, Listen
) {
293 adapter_
->CreateRfcommService(
294 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
295 BluetoothAdapter::ServiceOptions(),
296 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
297 base::Unretained(this)),
298 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
299 base::Unretained(this)));
301 EXPECT_EQ(1U, success_callback_count_
);
302 EXPECT_EQ(0U, error_callback_count_
);
303 EXPECT_TRUE(last_socket_
.get() != NULL
);
305 // Take ownership of the socket for the remainder of the test.
306 scoped_refptr
<BluetoothSocket
> server_socket
= last_socket_
;
308 success_callback_count_
= 0;
309 error_callback_count_
= 0;
311 // Simulate an incoming connection by just calling the ConnectProfile method
312 // of the underlying fake device client (from the BlueZ point of view,
313 // outgoing and incoming look the same).
315 // This is done before the Accept() call to simulate a pending call at the
316 // point that Accept() is called.
317 FakeBluetoothDeviceClient
* fake_bluetooth_device_client
=
318 static_cast<FakeBluetoothDeviceClient
*>(
319 DBusThreadManager::Get()->GetBluetoothDeviceClient());
320 BluetoothDevice
* device
= adapter_
->GetDevice(
321 FakeBluetoothDeviceClient::kPairedDeviceAddress
);
322 ASSERT_TRUE(device
!= NULL
);
323 fake_bluetooth_device_client
->ConnectProfile(
324 static_cast<BluetoothDeviceChromeOS
*>(device
)->object_path(),
325 FakeBluetoothProfileManagerClient::kRfcommUuid
,
326 base::Bind(&base::DoNothing
),
327 base::Bind(&DoNothingDBusErrorCallback
));
329 server_socket
->Accept(
330 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback
,
331 base::Unretained(this)),
332 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
333 base::Unretained(this)));
337 EXPECT_EQ(1U, success_callback_count_
);
338 EXPECT_EQ(0U, error_callback_count_
);
339 EXPECT_TRUE(last_socket_
.get() != NULL
);
341 // Take ownership of the client socket for the remainder of the test.
342 scoped_refptr
<BluetoothSocket
> client_socket
= last_socket_
;
344 success_callback_count_
= 0;
345 error_callback_count_
= 0;
347 // Close our end of the client socket.
348 client_socket
->Disconnect(
349 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
350 base::Unretained(this)));
354 EXPECT_EQ(1U, success_callback_count_
);
355 client_socket
= NULL
;
356 success_callback_count_
= 0;
357 error_callback_count_
= 0;
359 // Run a second connection test, this time calling Accept() before the
360 // incoming connection comes in.
361 server_socket
->Accept(
362 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback
,
363 base::Unretained(this)),
364 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
365 base::Unretained(this)));
367 fake_bluetooth_device_client
->ConnectProfile(
368 static_cast<BluetoothDeviceChromeOS
*>(device
)->object_path(),
369 FakeBluetoothProfileManagerClient::kRfcommUuid
,
370 base::Bind(&base::DoNothing
),
371 base::Bind(&DoNothingDBusErrorCallback
));
375 EXPECT_EQ(1U, success_callback_count_
);
376 EXPECT_EQ(0U, error_callback_count_
);
377 EXPECT_TRUE(last_socket_
.get() != NULL
);
379 // Take ownership of the client socket for the remainder of the test.
380 client_socket
= last_socket_
;
382 success_callback_count_
= 0;
383 error_callback_count_
= 0;
385 // Close our end of the client socket.
386 client_socket
->Disconnect(
387 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback
,
388 base::Unretained(this)));
392 EXPECT_EQ(1U, success_callback_count_
);
393 client_socket
= NULL
;
394 success_callback_count_
= 0;
395 error_callback_count_
= 0;
397 // Now close the server socket.
398 server_socket
->Disconnect(
399 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
400 base::Unretained(this)));
402 EXPECT_EQ(1U, success_callback_count_
);
405 TEST_F(BluetoothSocketChromeOSTest
, ListenBeforeAdapterStart
) {
406 // Start off with an invisible adapter, register the profile, then make
407 // the adapter visible.
408 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client
=
409 static_cast<FakeBluetoothAdapterClient
*>(
410 DBusThreadManager::Get()->GetBluetoothAdapterClient());
411 fake_bluetooth_adapter_client
->SetVisible(false);
413 adapter_
->CreateRfcommService(
414 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
415 BluetoothAdapter::ServiceOptions(),
416 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
417 base::Unretained(this)),
418 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
419 base::Unretained(this)));
421 EXPECT_EQ(1U, success_callback_count_
);
422 EXPECT_EQ(0U, error_callback_count_
);
423 EXPECT_TRUE(last_socket_
.get() != NULL
);
425 // Take ownership of the socket for the remainder of the test.
426 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
428 success_callback_count_
= 0;
429 error_callback_count_
= 0;
431 // But there shouldn't be a profile registered yet.
432 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
433 static_cast<FakeBluetoothProfileManagerClient
*>(
434 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
435 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
436 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
437 FakeBluetoothProfileManagerClient::kRfcommUuid
);
438 EXPECT_TRUE(profile_service_provider
== NULL
);
440 // Make the adapter visible. This should register a profile.
441 fake_bluetooth_adapter_client
->SetVisible(true);
443 profile_service_provider
=
444 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
445 FakeBluetoothProfileManagerClient::kRfcommUuid
);
446 EXPECT_TRUE(profile_service_provider
!= NULL
);
448 // Cleanup the socket.
450 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
451 base::Unretained(this)));
453 EXPECT_EQ(1U, success_callback_count_
);
456 TEST_F(BluetoothSocketChromeOSTest
, ListenAcrossAdapterRestart
) {
457 // The fake adapter starts off visible by default.
458 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client
=
459 static_cast<FakeBluetoothAdapterClient
*>(
460 DBusThreadManager::Get()->GetBluetoothAdapterClient());
462 adapter_
->CreateRfcommService(
463 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid
),
464 BluetoothAdapter::ServiceOptions(),
465 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback
,
466 base::Unretained(this)),
467 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback
,
468 base::Unretained(this)));
470 EXPECT_EQ(1U, success_callback_count_
);
471 EXPECT_EQ(0U, error_callback_count_
);
472 EXPECT_TRUE(last_socket_
.get() != NULL
);
474 // Take ownership of the socket for the remainder of the test.
475 scoped_refptr
<BluetoothSocket
> socket
= last_socket_
;
477 success_callback_count_
= 0;
478 error_callback_count_
= 0;
480 // Make sure the profile was registered with the daemon.
481 FakeBluetoothProfileManagerClient
* fake_bluetooth_profile_manager_client
=
482 static_cast<FakeBluetoothProfileManagerClient
*>(
483 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
484 FakeBluetoothProfileServiceProvider
* profile_service_provider
=
485 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
486 FakeBluetoothProfileManagerClient::kRfcommUuid
);
487 EXPECT_TRUE(profile_service_provider
!= NULL
);
489 // Make the adapter invisible, and fiddle with the profile fake to unregister
490 // the profile since this doesn't happen automatically.
491 fake_bluetooth_adapter_client
->SetVisible(false);
492 fake_bluetooth_profile_manager_client
->UnregisterProfile(
493 static_cast<BluetoothSocketChromeOS
*>(socket
.get())->object_path(),
494 base::Bind(&base::DoNothing
),
495 base::Bind(&DoNothingDBusErrorCallback
));
497 // Then make the adapter visible again. This should re-register the profile.
498 fake_bluetooth_adapter_client
->SetVisible(true);
500 profile_service_provider
=
501 fake_bluetooth_profile_manager_client
->GetProfileServiceProvider(
502 FakeBluetoothProfileManagerClient::kRfcommUuid
);
503 EXPECT_TRUE(profile_service_provider
!= NULL
);
505 // Cleanup the socket.
507 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback
,
508 base::Unretained(this)));
510 EXPECT_EQ(1U, success_callback_count_
);
513 } // namespace chromeos