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.
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h"
10 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/extensions/extension_function_test_utils.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_test_message_listener.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
19 #include "device/bluetooth/bluetooth_uuid.h"
20 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
21 #include "device/bluetooth/test/mock_bluetooth_device.h"
22 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
23 #include "device/bluetooth/test/mock_bluetooth_profile.h"
24 #include "device/bluetooth/test/mock_bluetooth_socket.h"
25 #include "testing/gmock/include/gmock/gmock.h"
27 using device::BluetoothAdapter
;
28 using device::BluetoothDevice
;
29 using device::BluetoothDiscoverySession
;
30 using device::BluetoothOutOfBandPairingData
;
31 using device::BluetoothProfile
;
32 using device::BluetoothUUID
;
33 using device::MockBluetoothAdapter
;
34 using device::MockBluetoothDevice
;
35 using device::MockBluetoothDiscoverySession
;
36 using device::MockBluetoothProfile
;
37 using extensions::Extension
;
39 namespace utils
= extension_function_test_utils
;
40 namespace api
= extensions::api
;
44 static const char* kAdapterAddress
= "A1:A2:A3:A4:A5:A6";
45 static const char* kName
= "whatsinaname";
47 class BluetoothApiTest
: public ExtensionApiTest
{
51 virtual void SetUpOnMainThread() OVERRIDE
{
52 ExtensionApiTest::SetUpOnMainThread();
53 empty_extension_
= utils::CreateEmptyExtension();
55 profile1_
.reset(new testing::NiceMock
<MockBluetoothProfile
>());
56 profile2_
.reset(new testing::NiceMock
<MockBluetoothProfile
>());
59 virtual void CleanUpOnMainThread() OVERRIDE
{
60 EXPECT_CALL(*mock_adapter_
, RemoveObserver(testing::_
));
63 void SetUpMockAdapter() {
64 // The browser will clean this up when it is torn down
65 mock_adapter_
= new testing::StrictMock
<MockBluetoothAdapter
>();
66 event_router()->SetAdapterForTest(mock_adapter_
);
68 device1_
.reset(new testing::NiceMock
<MockBluetoothDevice
>(
69 mock_adapter_
, 0, "d1", "11:12:13:14:15:16",
70 true /* paired */, true /* connected */));
71 device2_
.reset(new testing::NiceMock
<MockBluetoothDevice
>(
72 mock_adapter_
, 0, "d2", "21:22:23:24:25:26",
73 false /* paired */, false /* connected */));
74 device3_
.reset(new testing::NiceMock
<MockBluetoothDevice
>(
75 mock_adapter_
, 0, "d3", "31:32:33:34:35:36",
76 false /* paired */, false /* connected */));
79 void DiscoverySessionCallback(
80 const BluetoothAdapter::DiscoverySessionCallback
& callback
,
81 const BluetoothAdapter::ErrorCallback
& error_callback
) {
82 if (mock_session_
.get()) {
84 scoped_ptr
<BluetoothDiscoverySession
>(mock_session_
.release()));
91 T
* setupFunction(T
* function
) {
92 function
->set_extension(empty_extension_
.get());
93 function
->set_has_callback(true);
98 testing::StrictMock
<MockBluetoothAdapter
>* mock_adapter_
;
99 scoped_ptr
<testing::NiceMock
<MockBluetoothDiscoverySession
> > mock_session_
;
100 scoped_ptr
<testing::NiceMock
<MockBluetoothDevice
> > device1_
;
101 scoped_ptr
<testing::NiceMock
<MockBluetoothDevice
> > device2_
;
102 scoped_ptr
<testing::NiceMock
<MockBluetoothDevice
> > device3_
;
103 scoped_ptr
<testing::NiceMock
<MockBluetoothProfile
> > profile1_
;
104 scoped_ptr
<testing::NiceMock
<MockBluetoothProfile
> > profile2_
;
106 extensions::BluetoothEventRouter
* event_router() {
107 return bluetooth_api()->event_router();
110 extensions::BluetoothAPI
* bluetooth_api() {
111 return extensions::BluetoothAPI::Get(browser()->profile());
115 scoped_refptr
<Extension
> empty_extension_
;
118 class TestBluetoothAddProfileFunction
119 : public api::BluetoothAddProfileFunction
{
121 explicit TestBluetoothAddProfileFunction(BluetoothProfile
* profile
)
122 : BluetoothAddProfileFunction(), profile_(profile
) {
126 virtual ~TestBluetoothAddProfileFunction() {
129 // BluetoothAddProfileFunction override.
130 virtual void RegisterProfile(
131 const device::BluetoothProfile::Options
& options
,
132 const device::BluetoothProfile::ProfileCallback
& callback
) OVERRIDE
{
133 callback
.Run(profile_
);
137 // TestBluetoothAddProfileFunction does not own |profile_|.
138 BluetoothProfile
* profile_
;
141 // This is the canonical UUID for the short UUID 0010.
142 static const char kOutOfBandPairingDataHash
[] = "0123456789ABCDEh";
143 static const char kOutOfBandPairingDataRandomizer
[] = "0123456789ABCDEr";
145 static BluetoothOutOfBandPairingData
GetOutOfBandPairingData() {
146 BluetoothOutOfBandPairingData data
;
147 memcpy(&(data
.hash
), kOutOfBandPairingDataHash
,
148 device::kBluetoothOutOfBandPairingDataSize
);
149 memcpy(&(data
.randomizer
), kOutOfBandPairingDataRandomizer
,
150 device::kBluetoothOutOfBandPairingDataSize
);
154 static bool CallClosure(const base::Closure
& callback
) {
159 static bool CallErrorClosure(const BluetoothDevice::ErrorCallback
& callback
) {
164 static void StopDiscoverySessionCallback(const base::Closure
& callback
,
165 const base::Closure
& error_callback
) {
169 static void CallOutOfBandPairingDataCallback(
170 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback
& callback
,
171 const BluetoothAdapter::ErrorCallback
& error_callback
) {
172 callback
.Run(GetOutOfBandPairingData());
177 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, Profiles
) {
178 // Run in context of an extension that has permissions for the profiles
179 // we intend to register.
180 scoped_refptr
<const Extension
> extension(
181 LoadExtension(test_data_dir_
.AppendASCII("bluetooth/profiles")));
182 ASSERT_TRUE(extension
.get());
184 EXPECT_CALL(*profile1_
, SetConnectionCallback(testing::_
));
185 scoped_refptr
<TestBluetoothAddProfileFunction
> add_profile_function
;
186 add_profile_function
= new TestBluetoothAddProfileFunction(profile1_
.get());
187 add_profile_function
->set_extension(extension
.get());
188 add_profile_function
->set_has_callback(true);
189 std::string
error(utils::RunFunctionAndReturnError(
190 add_profile_function
.get(), "[{\"uuid\": \"1234\"}]", browser()));
191 ASSERT_TRUE(error
.empty());
193 // Registering the profile for the same uuid again will throw an error.
194 add_profile_function
= new TestBluetoothAddProfileFunction(profile2_
.get());
195 add_profile_function
->set_extension(extension
.get());
196 add_profile_function
->set_has_callback(true);
197 error
= utils::RunFunctionAndReturnError(
198 add_profile_function
.get(), "[{\"uuid\": \"1234\"}]", browser());
199 ASSERT_FALSE(error
.empty());
201 add_profile_function
= new TestBluetoothAddProfileFunction(profile2_
.get());
202 add_profile_function
->set_extension(extension
.get());
203 add_profile_function
->set_has_callback(true);
204 error
= utils::RunFunctionAndReturnError(
205 add_profile_function
.get(), "[{\"uuid\": \"5678\"}]", browser());
206 ASSERT_TRUE(error
.empty());
208 scoped_refptr
<api::BluetoothRemoveProfileFunction
> remove_profile_function
;
209 remove_profile_function
= new api::BluetoothRemoveProfileFunction();
210 remove_profile_function
->set_extension(extension
.get());
211 remove_profile_function
->set_has_callback(true);
212 error
= utils::RunFunctionAndReturnError(
213 remove_profile_function
.get(), "[{\"uuid\": \"1234\"}]", browser());
214 ASSERT_TRUE(error
.empty());
216 remove_profile_function
= new api::BluetoothRemoveProfileFunction();
217 remove_profile_function
->set_extension(extension
.get());
218 remove_profile_function
->set_has_callback(true);
219 error
= utils::RunFunctionAndReturnError(
220 remove_profile_function
.get(), "[{\"uuid\": \"5678\"}]", browser());
221 ASSERT_TRUE(error
.empty());
223 // Removing the same profile again will throw an error.
224 remove_profile_function
= new api::BluetoothRemoveProfileFunction();
225 remove_profile_function
->set_extension(extension
.get());
226 remove_profile_function
->set_has_callback(true);
227 error
= utils::RunFunctionAndReturnError(
228 remove_profile_function
.get(), "[{\"uuid\": \"5678\"}]", browser());
229 ASSERT_FALSE(error
.empty());
231 // Registering a profile we don't have permission for will throw an error.
232 add_profile_function
= new TestBluetoothAddProfileFunction(profile1_
.get());
233 add_profile_function
->set_extension(extension
.get());
234 add_profile_function
->set_has_callback(true);
235 error
= utils::RunFunctionAndReturnError(
236 add_profile_function
.get(), "[{\"uuid\": \"9999\"}]", browser());
237 ASSERT_FALSE(error
.empty());
240 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, GetAdapterState
) {
241 EXPECT_CALL(*mock_adapter_
, GetAddress())
242 .WillOnce(testing::Return(kAdapterAddress
));
243 EXPECT_CALL(*mock_adapter_
, GetName())
244 .WillOnce(testing::Return(kName
));
245 EXPECT_CALL(*mock_adapter_
, IsPresent())
246 .WillOnce(testing::Return(false));
247 EXPECT_CALL(*mock_adapter_
, IsPowered())
248 .WillOnce(testing::Return(true));
249 EXPECT_CALL(*mock_adapter_
, IsDiscovering())
250 .WillOnce(testing::Return(false));
252 scoped_refptr
<api::BluetoothGetAdapterStateFunction
> get_adapter_state
;
253 get_adapter_state
= setupFunction(new api::BluetoothGetAdapterStateFunction
);
255 scoped_ptr
<base::Value
> result(utils::RunFunctionAndReturnSingleResult(
256 get_adapter_state
.get(), "[]", browser()));
257 ASSERT_TRUE(result
.get() != NULL
);
258 api::bluetooth::AdapterState state
;
259 ASSERT_TRUE(api::bluetooth::AdapterState::Populate(*result
, &state
));
261 EXPECT_FALSE(state
.available
);
262 EXPECT_TRUE(state
.powered
);
263 EXPECT_FALSE(state
.discovering
);
264 EXPECT_EQ(kName
, state
.name
);
265 EXPECT_EQ(kAdapterAddress
, state
.address
);
268 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, GetLocalOutOfBandPairingData
) {
269 EXPECT_CALL(*mock_adapter_
,
270 ReadLocalOutOfBandPairingData(testing::_
, testing::_
))
271 .WillOnce(testing::Invoke(CallOutOfBandPairingDataCallback
));
273 scoped_refptr
<api::BluetoothGetLocalOutOfBandPairingDataFunction
>
274 get_oob_function(setupFunction(
275 new api::BluetoothGetLocalOutOfBandPairingDataFunction
));
277 scoped_ptr
<base::Value
> result(utils::RunFunctionAndReturnSingleResult(
278 get_oob_function
.get(), "[]", browser()));
280 base::DictionaryValue
* dict
;
281 EXPECT_TRUE(result
->GetAsDictionary(&dict
));
283 base::BinaryValue
* binary_value
;
284 EXPECT_TRUE(dict
->GetBinary("hash", &binary_value
));
285 EXPECT_STREQ(kOutOfBandPairingDataHash
,
286 std::string(binary_value
->GetBuffer(), binary_value
->GetSize()).c_str());
287 EXPECT_TRUE(dict
->GetBinary("randomizer", &binary_value
));
288 EXPECT_STREQ(kOutOfBandPairingDataRandomizer
,
289 std::string(binary_value
->GetBuffer(), binary_value
->GetSize()).c_str());
291 // Try again with an error
292 testing::Mock::VerifyAndClearExpectations(mock_adapter_
);
293 EXPECT_CALL(*mock_adapter_
,
294 ReadLocalOutOfBandPairingData(
296 testing::Truly(CallClosure
)));
299 setupFunction(new api::BluetoothGetLocalOutOfBandPairingDataFunction
);
301 std::string
error(utils::RunFunctionAndReturnError(
302 get_oob_function
.get(), "[]", browser()));
303 EXPECT_FALSE(error
.empty());
306 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, SetOutOfBandPairingData
) {
307 EXPECT_CALL(*mock_adapter_
, GetDevice(device1_
->GetAddress()))
308 .WillOnce(testing::Return(device1_
.get()));
309 EXPECT_CALL(*device1_
,
310 ClearOutOfBandPairingData(testing::Truly(CallClosure
),
313 std::string params
= base::StringPrintf(
314 "[{\"deviceAddress\":\"%s\"}]", device1_
->GetAddress().c_str());
316 scoped_refptr
<api::BluetoothSetOutOfBandPairingDataFunction
> set_oob_function
;
317 set_oob_function
= setupFunction(
318 new api::BluetoothSetOutOfBandPairingDataFunction
);
319 // There isn't actually a result.
320 (void) utils::RunFunctionAndReturnSingleResult(
321 set_oob_function
.get(), params
, browser());
323 // Try again with an error
324 testing::Mock::VerifyAndClearExpectations(mock_adapter_
);
325 testing::Mock::VerifyAndClearExpectations(device1_
.get());
326 EXPECT_CALL(*mock_adapter_
, GetDevice(device1_
->GetAddress()))
327 .WillOnce(testing::Return(device1_
.get()));
330 ClearOutOfBandPairingData(testing::_
, testing::Truly(CallErrorClosure
)));
332 set_oob_function
= setupFunction(
333 new api::BluetoothSetOutOfBandPairingDataFunction
);
334 std::string
error(utils::RunFunctionAndReturnError(
335 set_oob_function
.get(), params
, browser()));
336 EXPECT_FALSE(error
.empty());
338 // TODO(bryeung): Also test setting the data when there is support for
339 // ArrayBuffers in the arguments to the RunFunctionAnd* methods.
343 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, DeviceEvents
) {
344 ResultCatcher catcher
;
345 catcher
.RestrictToProfile(browser()->profile());
347 ASSERT_TRUE(LoadExtension(
348 test_data_dir_
.AppendASCII("bluetooth/device_events")));
350 ExtensionTestMessageListener
events_received("ready", true);
351 event_router()->DeviceAdded(mock_adapter_
, device1_
.get());
352 event_router()->DeviceAdded(mock_adapter_
, device2_
.get());
354 EXPECT_CALL(*device2_
.get(), GetDeviceName())
355 .WillRepeatedly(testing::Return("the real d2"));
356 EXPECT_CALL(*device2_
.get(), GetName())
357 .WillRepeatedly(testing::Return(base::UTF8ToUTF16("the real d2")));
358 event_router()->DeviceChanged(mock_adapter_
, device2_
.get());
360 event_router()->DeviceAdded(mock_adapter_
, device3_
.get());
361 event_router()->DeviceRemoved(mock_adapter_
, device1_
.get());
362 EXPECT_TRUE(events_received
.WaitUntilSatisfied());
363 events_received
.Reply("go");
365 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
368 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, Discovery
) {
369 // Try with a failure to start. This will return an error as we haven't
370 // initialied a session object.
371 EXPECT_CALL(*mock_adapter_
, StartDiscoverySession(testing::_
, testing::_
))
373 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback
));
375 // StartDiscovery failure will not reference the adapter.
376 scoped_refptr
<api::BluetoothStartDiscoveryFunction
> start_function
;
377 start_function
= setupFunction(new api::BluetoothStartDiscoveryFunction
);
379 utils::RunFunctionAndReturnError(start_function
.get(), "[]", browser()));
380 ASSERT_FALSE(error
.empty());
382 // Reset the adapter and initiate a discovery session. The ownership of the
383 // mock session will be passed to the event router.
384 ASSERT_FALSE(mock_session_
.get());
387 // Create a mock session to be returned as a result. Get a handle to it as
388 // its ownership will be passed and |mock_session_| will be reset.
389 mock_session_
.reset(new testing::NiceMock
<MockBluetoothDiscoverySession
>());
390 MockBluetoothDiscoverySession
* session
= mock_session_
.get();
391 EXPECT_CALL(*mock_adapter_
, StartDiscoverySession(testing::_
, testing::_
))
393 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback
));
394 start_function
= setupFunction(new api::BluetoothStartDiscoveryFunction
);
396 utils::RunFunctionAndReturnError(start_function
.get(), "[]", browser());
398 // End the discovery session. The StopDiscovery function should succeed.
399 testing::Mock::VerifyAndClearExpectations(mock_adapter_
);
400 EXPECT_CALL(*session
, IsActive()).WillOnce(testing::Return(true));
401 EXPECT_CALL(*session
, Stop(testing::_
, testing::_
))
402 .WillOnce(testing::Invoke(StopDiscoverySessionCallback
));
404 // StopDiscovery success will remove the session object, unreferencing the
406 scoped_refptr
<api::BluetoothStopDiscoveryFunction
> stop_function
;
407 stop_function
= setupFunction(new api::BluetoothStopDiscoveryFunction
);
408 (void) utils::RunFunctionAndReturnSingleResult(
409 stop_function
.get(), "[]", browser());
411 // Reset the adapter. Simulate failure for stop discovery. The event router
412 // still owns the session. Make it appear inactive.
414 EXPECT_CALL(*session
, IsActive()).WillOnce(testing::Return(false));
415 stop_function
= setupFunction(new api::BluetoothStopDiscoveryFunction
);
417 utils::RunFunctionAndReturnError(stop_function
.get(), "[]", browser());
418 ASSERT_FALSE(error
.empty());
422 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, DiscoveryCallback
) {
423 mock_session_
.reset(new testing::NiceMock
<MockBluetoothDiscoverySession
>());
424 MockBluetoothDiscoverySession
* session
= mock_session_
.get();
425 EXPECT_CALL(*mock_adapter_
, StartDiscoverySession(testing::_
, testing::_
))
427 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback
));
428 EXPECT_CALL(*session
, IsActive()).WillOnce(testing::Return(true));
429 EXPECT_CALL(*session
, Stop(testing::_
, testing::_
))
430 .WillOnce(testing::Invoke(StopDiscoverySessionCallback
));
432 ResultCatcher catcher
;
433 catcher
.RestrictToProfile(browser()->profile());
435 ExtensionTestMessageListener
discovery_started("ready", true);
436 ASSERT_TRUE(LoadExtension(
437 test_data_dir_
.AppendASCII("bluetooth/discovery_callback")));
438 EXPECT_TRUE(discovery_started
.WaitUntilSatisfied());
440 event_router()->DeviceAdded(mock_adapter_
, device1_
.get());
442 discovery_started
.Reply("go");
443 ExtensionTestMessageListener
discovery_stopped("ready", true);
444 EXPECT_CALL(*mock_adapter_
, RemoveObserver(testing::_
));
445 EXPECT_TRUE(discovery_stopped
.WaitUntilSatisfied());
448 event_router()->DeviceAdded(mock_adapter_
, device2_
.get());
449 discovery_stopped
.Reply("go");
451 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
454 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, DiscoveryInProgress
) {
455 EXPECT_CALL(*mock_adapter_
, GetAddress())
456 .WillOnce(testing::Return(kAdapterAddress
));
457 EXPECT_CALL(*mock_adapter_
, GetName())
458 .WillOnce(testing::Return(kName
));
459 EXPECT_CALL(*mock_adapter_
, IsPresent())
460 .WillOnce(testing::Return(true));
461 EXPECT_CALL(*mock_adapter_
, IsPowered())
462 .WillOnce(testing::Return(true));
464 // Fake that the adapter is discovering
465 EXPECT_CALL(*mock_adapter_
, IsDiscovering())
466 .WillOnce(testing::Return(true));
467 event_router()->AdapterDiscoveringChanged(mock_adapter_
, true);
469 // Cache a device before the extension starts discovering
470 event_router()->DeviceAdded(mock_adapter_
, device1_
.get());
472 ResultCatcher catcher
;
473 catcher
.RestrictToProfile(browser()->profile());
475 mock_session_
.reset(new testing::NiceMock
<MockBluetoothDiscoverySession
>());
476 MockBluetoothDiscoverySession
* session
= mock_session_
.get();
477 EXPECT_CALL(*mock_adapter_
, StartDiscoverySession(testing::_
, testing::_
))
479 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback
));
480 EXPECT_CALL(*session
, IsActive()).WillOnce(testing::Return(true));
481 EXPECT_CALL(*session
, Stop(testing::_
, testing::_
))
482 .WillOnce(testing::Invoke(StopDiscoverySessionCallback
));
484 ExtensionTestMessageListener
discovery_started("ready", true);
485 ASSERT_TRUE(LoadExtension(
486 test_data_dir_
.AppendASCII("bluetooth/discovery_in_progress")));
487 EXPECT_TRUE(discovery_started
.WaitUntilSatisfied());
489 // Only this should be received. No additional notification should be sent for
490 // devices discovered before the discovery session started.
491 event_router()->DeviceAdded(mock_adapter_
, device2_
.get());
493 discovery_started
.Reply("go");
494 ExtensionTestMessageListener
discovery_stopped("ready", true);
495 EXPECT_CALL(*mock_adapter_
, RemoveObserver(testing::_
));
496 EXPECT_TRUE(discovery_stopped
.WaitUntilSatisfied());
499 // This should never be received.
500 event_router()->DeviceAdded(mock_adapter_
, device2_
.get());
501 discovery_stopped
.Reply("go");
503 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
506 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, OnAdapterStateChanged
) {
507 ResultCatcher catcher
;
508 catcher
.RestrictToProfile(browser()->profile());
510 // Load and wait for setup
511 ExtensionTestMessageListener
listener("ready", true);
514 test_data_dir_
.AppendASCII("bluetooth/on_adapter_state_changed")));
515 EXPECT_TRUE(listener
.WaitUntilSatisfied());
517 EXPECT_CALL(*mock_adapter_
, GetAddress())
518 .WillOnce(testing::Return(kAdapterAddress
));
519 EXPECT_CALL(*mock_adapter_
, GetName())
520 .WillOnce(testing::Return(kName
));
521 EXPECT_CALL(*mock_adapter_
, IsPresent())
522 .WillOnce(testing::Return(false));
523 EXPECT_CALL(*mock_adapter_
, IsPowered())
524 .WillOnce(testing::Return(false));
525 EXPECT_CALL(*mock_adapter_
, IsDiscovering())
526 .WillOnce(testing::Return(false));
527 event_router()->AdapterPoweredChanged(mock_adapter_
, false);
529 EXPECT_CALL(*mock_adapter_
, GetAddress())
530 .WillOnce(testing::Return(kAdapterAddress
));
531 EXPECT_CALL(*mock_adapter_
, GetName())
532 .WillOnce(testing::Return(kName
));
533 EXPECT_CALL(*mock_adapter_
, IsPresent())
534 .WillOnce(testing::Return(true));
535 EXPECT_CALL(*mock_adapter_
, IsPowered())
536 .WillOnce(testing::Return(true));
537 EXPECT_CALL(*mock_adapter_
, IsDiscovering())
538 .WillOnce(testing::Return(true));
539 event_router()->AdapterPresentChanged(mock_adapter_
, true);
541 EXPECT_CALL(*mock_adapter_
, GetAddress())
542 .WillOnce(testing::Return(kAdapterAddress
));
543 EXPECT_CALL(*mock_adapter_
, GetName())
544 .WillOnce(testing::Return(kName
));
545 EXPECT_CALL(*mock_adapter_
, IsPresent())
546 .WillOnce(testing::Return(true));
547 EXPECT_CALL(*mock_adapter_
, IsPowered())
548 .WillOnce(testing::Return(true));
549 EXPECT_CALL(*mock_adapter_
, IsDiscovering())
550 .WillOnce(testing::Return(true));
551 event_router()->AdapterDiscoveringChanged(mock_adapter_
, true);
553 listener
.Reply("go");
555 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
558 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, OnConnection
) {
559 ResultCatcher catcher
;
560 catcher
.RestrictToProfile(browser()->profile());
562 // Load and wait for setup
563 ExtensionTestMessageListener
listener("ready", true);
564 scoped_refptr
<const Extension
> extension(
565 LoadExtension(test_data_dir_
.AppendASCII("bluetooth/on_connection")));
566 ASSERT_TRUE(extension
.get());
567 EXPECT_TRUE(listener
.WaitUntilSatisfied());
569 scoped_refptr
<device::MockBluetoothSocket
> socket
=
570 new device::MockBluetoothSocket();
572 EXPECT_CALL(*mock_adapter_
, GetDevice(device1_
->GetAddress()))
573 .WillOnce(testing::Return(device1_
.get()));
575 event_router()->AddProfile(
576 BluetoothUUID("1234"), extension
->id(), profile1_
.get());
577 bluetooth_api()->DispatchConnectionEvent(
578 extension
->id(), BluetoothUUID("1234"), device1_
.get(), socket
);
579 // Connection events are dispatched using a couple of PostTask to the UI
580 // thread. Waiting until idle ensures the event is dispatched to the
582 base::RunLoop().RunUntilIdle();
584 listener
.Reply("go");
585 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
586 event_router()->RemoveProfile(BluetoothUUID("1234"));
589 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, GetDevices
) {
590 ResultCatcher catcher
;
591 catcher
.RestrictToProfile(browser()->profile());
593 BluetoothAdapter::ConstDeviceList devices
;
594 devices
.push_back(device1_
.get());
595 devices
.push_back(device2_
.get());
597 EXPECT_CALL(*mock_adapter_
, GetDevices())
599 .WillRepeatedly(testing::Return(devices
));
601 // Load and wait for setup
602 ExtensionTestMessageListener
listener("ready", true);
604 LoadExtension(test_data_dir_
.AppendASCII("bluetooth/get_devices")));
605 EXPECT_TRUE(listener
.WaitUntilSatisfied());
607 listener
.Reply("go");
609 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
612 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, GetDevice
) {
613 ResultCatcher catcher
;
614 catcher
.RestrictToProfile(browser()->profile());
616 EXPECT_CALL(*mock_adapter_
, GetDevice(device1_
->GetAddress()))
617 .WillOnce(testing::Return(device1_
.get()));
618 EXPECT_CALL(*mock_adapter_
, GetDevice(device2_
->GetAddress()))
620 .WillRepeatedly(testing::Return(static_cast<BluetoothDevice
*>(NULL
)));
622 // Load and wait for setup
623 ExtensionTestMessageListener
listener("ready", true);
625 LoadExtension(test_data_dir_
.AppendASCII("bluetooth/get_device")));
626 EXPECT_TRUE(listener
.WaitUntilSatisfied());
628 listener
.Reply("go");
630 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();
633 IN_PROC_BROWSER_TEST_F(BluetoothApiTest
, DeviceInfo
) {
634 ResultCatcher catcher
;
635 catcher
.RestrictToProfile(browser()->profile());
637 // Set up the first device object to reflect a real-world device.
638 BluetoothAdapter::ConstDeviceList devices
;
640 EXPECT_CALL(*device1_
.get(), GetAddress())
641 .WillRepeatedly(testing::Return("A4:17:31:00:00:00"));
642 EXPECT_CALL(*device1_
.get(), GetDeviceName())
643 .WillRepeatedly(testing::Return("Chromebook Pixel"));
644 EXPECT_CALL(*device1_
.get(), GetName())
645 .WillRepeatedly(testing::Return(base::UTF8ToUTF16("Chromebook Pixel")));
646 EXPECT_CALL(*device1_
.get(), GetBluetoothClass())
647 .WillRepeatedly(testing::Return(0x080104));
648 EXPECT_CALL(*device1_
.get(), GetDeviceType())
649 .WillRepeatedly(testing::Return(BluetoothDevice::DEVICE_COMPUTER
));
650 EXPECT_CALL(*device1_
.get(), GetVendorIDSource())
651 .WillRepeatedly(testing::Return(BluetoothDevice::VENDOR_ID_BLUETOOTH
));
652 EXPECT_CALL(*device1_
.get(), GetVendorID())
653 .WillRepeatedly(testing::Return(0x00E0));
654 EXPECT_CALL(*device1_
.get(), GetProductID())
655 .WillRepeatedly(testing::Return(0x240A));
656 EXPECT_CALL(*device1_
.get(), GetDeviceID())
657 .WillRepeatedly(testing::Return(0x0400));
658 EXPECT_CALL(*device1_
, GetRSSI()).WillRepeatedly(testing::Return(-42));
659 EXPECT_CALL(*device1_
, GetCurrentHostTransmitPower())
660 .WillRepeatedly(testing::Return(-16));
661 EXPECT_CALL(*device1_
, GetMaximumHostTransmitPower())
662 .WillRepeatedly(testing::Return(10));
664 BluetoothDevice::UUIDList uuids
;
665 uuids
.push_back(BluetoothUUID("1105"));
666 uuids
.push_back(BluetoothUUID("1106"));
668 EXPECT_CALL(*device1_
.get(), GetUUIDs())
669 .WillOnce(testing::Return(uuids
));
671 devices
.push_back(device1_
.get());
673 // Leave the second largely empty so we can check a device without
674 // available information.
675 devices
.push_back(device2_
.get());
677 EXPECT_CALL(*mock_adapter_
, GetDevices())
679 .WillRepeatedly(testing::Return(devices
));
681 // Load and wait for setup
682 ExtensionTestMessageListener
listener("ready", true);
684 LoadExtension(test_data_dir_
.AppendASCII("bluetooth/device_info")));
685 EXPECT_TRUE(listener
.WaitUntilSatisfied());
687 listener
.Reply("go");
689 EXPECT_TRUE(catcher
.GetNextResult()) << catcher
.message();