Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / device / bluetooth / bluetooth_socket_chromeos_unittest.cc
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.
4
5 #include "base/bind.h"
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"
27
28 using device::BluetoothAdapter;
29 using device::BluetoothDevice;
30 using device::BluetoothSocket;
31 using device::BluetoothSocketThread;
32 using device::BluetoothUUID;
33
34 namespace {
35
36 void DoNothingDBusErrorCallback(const std::string& error_name,
37                                 const std::string& error_message) {}
38
39 }  // namespace
40
41 namespace chromeos {
42
43 class BluetoothSocketChromeOSTest : public testing::Test {
44  public:
45   BluetoothSocketChromeOSTest()
46       : success_callback_count_(0),
47         error_callback_count_(0),
48         last_bytes_sent_(0),
49         last_bytes_received_(0),
50         last_reason_(BluetoothSocket::kSystemError) {}
51
52   virtual void SetUp() OVERRIDE {
53     scoped_ptr<DBusThreadManagerSetter> dbus_setter =
54         DBusThreadManager::GetSetterForTesting();
55
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));
71
72     BluetoothSocketThread::Get();
73
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());
81
82     // Turn on the adapter.
83     adapter_->SetPowered(
84         true,
85         base::Bind(&base::DoNothing),
86         base::Bind(&base::DoNothing));
87     ASSERT_TRUE(adapter_->IsPowered());
88   }
89
90   virtual void TearDown() OVERRIDE {
91     adapter_ = NULL;
92     BluetoothSocketThread::CleanupForTesting();
93     DBusThreadManager::Shutdown();
94   }
95
96   void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
97     adapter_ = adapter;
98   }
99
100   void SuccessCallback() {
101     ++success_callback_count_;
102     message_loop_.Quit();
103   }
104
105   void ErrorCallback(const std::string& message) {
106     ++error_callback_count_;
107     last_message_ = message;
108
109     message_loop_.Quit();
110   }
111
112   void ConnectToServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
113     ++success_callback_count_;
114     last_socket_ = socket;
115
116     message_loop_.Quit();
117   }
118
119   void SendSuccessCallback(int bytes_sent) {
120     ++success_callback_count_;
121     last_bytes_sent_ = bytes_sent;
122
123     message_loop_.Quit();
124   }
125
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;
131
132     message_loop_.Quit();
133   }
134
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;
140
141     message_loop_.Quit();
142   }
143
144   void CreateServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
145     ++success_callback_count_;
146     last_socket_ = socket;
147   }
148
149   void AcceptSuccessCallback(const BluetoothDevice* device,
150                              scoped_refptr<BluetoothSocket> socket) {
151     ++success_callback_count_;
152     last_device_ = device;
153     last_socket_ = socket;
154
155     message_loop_.Quit();
156   }
157
158   void ImmediateSuccessCallback() {
159     ++success_callback_count_;
160   }
161
162  protected:
163   base::MessageLoop message_loop_;
164
165   scoped_refptr<BluetoothAdapter> adapter_;
166
167   unsigned int success_callback_count_;
168   unsigned int error_callback_count_;
169
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_;
177 };
178
179 TEST_F(BluetoothSocketChromeOSTest, Connect) {
180   BluetoothDevice* device = adapter_->GetDevice(
181       FakeBluetoothDeviceClient::kPairedDeviceAddress);
182   ASSERT_TRUE(device != NULL);
183
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)));
190
191   message_loop_.Run();
192
193   EXPECT_EQ(1U, success_callback_count_);
194   EXPECT_EQ(0U, error_callback_count_);
195   EXPECT_TRUE(last_socket_.get() != NULL);
196
197   // Take ownership of the socket for the remainder of the test.
198   scoped_refptr<BluetoothSocket> socket = last_socket_;
199   last_socket_ = NULL;
200   success_callback_count_ = 0;
201   error_callback_count_ = 0;
202
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"));
206
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)));
212   message_loop_.Run();
213
214   EXPECT_EQ(1U, success_callback_count_);
215   EXPECT_EQ(0U, error_callback_count_);
216   EXPECT_EQ(last_bytes_sent_, write_buffer->size());
217
218   success_callback_count_ = 0;
219   error_callback_count_ = 0;
220
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.
223   socket->Receive(
224       4096,
225       base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
226                  base::Unretained(this)),
227       base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
228                  base::Unretained(this)));
229   message_loop_.Run();
230
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);
235
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;
241
242   std::string data = std::string(read_buffer->data(), last_bytes_received_);
243   EXPECT_EQ("test", data);
244
245   read_buffer = NULL;
246
247   // Receive data again; the socket will have been closed, this should cause a
248   // disconnected error to be returned via the error callback.
249   socket->Receive(
250       4096,
251       base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
252                  base::Unretained(this)),
253       base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
254                  base::Unretained(this)));
255   message_loop_.Run();
256
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_);
261
262   success_callback_count_ = 0;
263   error_callback_count_ = 0;
264
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");
268
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)));
274   message_loop_.Run();
275
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_);
279
280   success_callback_count_ = 0;
281   error_callback_count_ = 0;
282
283   // Close our end of the socket.
284   socket->Disconnect(base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
285                                 base::Unretained(this)));
286
287   message_loop_.Run();
288   EXPECT_EQ(1U, success_callback_count_);
289 }
290
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)));
299
300   EXPECT_EQ(1U, success_callback_count_);
301   EXPECT_EQ(0U, error_callback_count_);
302   EXPECT_TRUE(last_socket_.get() != NULL);
303
304   // Take ownership of the socket for the remainder of the test.
305   scoped_refptr<BluetoothSocket> server_socket = last_socket_;
306   last_socket_ = NULL;
307   success_callback_count_ = 0;
308   error_callback_count_ = 0;
309
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).
313   //
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));
327
328   server_socket->Accept(
329       base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
330                  base::Unretained(this)),
331       base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
332                  base::Unretained(this)));
333
334   message_loop_.Run();
335
336   EXPECT_EQ(1U, success_callback_count_);
337   EXPECT_EQ(0U, error_callback_count_);
338   EXPECT_TRUE(last_socket_.get() != NULL);
339
340   // Take ownership of the client socket for the remainder of the test.
341   scoped_refptr<BluetoothSocket> client_socket = last_socket_;
342   last_socket_ = NULL;
343   success_callback_count_ = 0;
344   error_callback_count_ = 0;
345
346   // Close our end of the client socket.
347   client_socket->Disconnect(
348       base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
349                  base::Unretained(this)));
350
351   message_loop_.Run();
352
353   EXPECT_EQ(1U, success_callback_count_);
354   client_socket = NULL;
355   success_callback_count_ = 0;
356   error_callback_count_ = 0;
357
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)));
365
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));
371
372   message_loop_.Run();
373
374   EXPECT_EQ(1U, success_callback_count_);
375   EXPECT_EQ(0U, error_callback_count_);
376   EXPECT_TRUE(last_socket_.get() != NULL);
377
378   // Take ownership of the client socket for the remainder of the test.
379   client_socket = last_socket_;
380   last_socket_ = NULL;
381   success_callback_count_ = 0;
382   error_callback_count_ = 0;
383
384   // Close our end of the client socket.
385   client_socket->Disconnect(
386       base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
387                  base::Unretained(this)));
388
389   message_loop_.Run();
390
391   EXPECT_EQ(1U, success_callback_count_);
392   client_socket = NULL;
393   success_callback_count_ = 0;
394   error_callback_count_ = 0;
395
396   // Now close the server socket.
397   server_socket->Disconnect(
398       base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
399                  base::Unretained(this)));
400
401   EXPECT_EQ(1U, success_callback_count_);
402 }
403
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);
411
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)));
419
420   EXPECT_EQ(1U, success_callback_count_);
421   EXPECT_EQ(0U, error_callback_count_);
422   EXPECT_TRUE(last_socket_.get() != NULL);
423
424   // Take ownership of the socket for the remainder of the test.
425   scoped_refptr<BluetoothSocket> socket = last_socket_;
426   last_socket_ = NULL;
427   success_callback_count_ = 0;
428   error_callback_count_ = 0;
429
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);
438
439   // Make the adapter visible. This should register a profile.
440   fake_bluetooth_adapter_client->SetVisible(true);
441
442   profile_service_provider =
443       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
444           FakeBluetoothProfileManagerClient::kRfcommUuid);
445   EXPECT_TRUE(profile_service_provider != NULL);
446
447   // Cleanup the socket.
448   socket->Disconnect(
449       base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
450                  base::Unretained(this)));
451
452   EXPECT_EQ(1U, success_callback_count_);
453 }
454
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());
460
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)));
468
469   EXPECT_EQ(1U, success_callback_count_);
470   EXPECT_EQ(0U, error_callback_count_);
471   EXPECT_TRUE(last_socket_.get() != NULL);
472
473   // Take ownership of the socket for the remainder of the test.
474   scoped_refptr<BluetoothSocket> socket = last_socket_;
475   last_socket_ = NULL;
476   success_callback_count_ = 0;
477   error_callback_count_ = 0;
478
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);
487
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));
495
496   // Then make the adapter visible again. This should re-register the profile.
497   fake_bluetooth_adapter_client->SetVisible(true);
498
499   profile_service_provider =
500       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
501           FakeBluetoothProfileManagerClient::kRfcommUuid);
502   EXPECT_TRUE(profile_service_provider != NULL);
503
504   // Cleanup the socket.
505   socket->Disconnect(
506       base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
507                  base::Unretained(this)));
508
509   EXPECT_EQ(1U, success_callback_count_);
510 }
511
512 }  // namespace chromeos