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. 4 5 #include <string.h> 6 7 #include "base/strings/stringprintf.h" 8 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" 9 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" 10 #include "chrome/browser/extensions/extension_apitest.h" 11 #include "chrome/browser/extensions/extension_function_test_utils.h" 12 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_test_message_listener.h" 14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/test/base/ui_test_utils.h" 16 #include "device/bluetooth/bluetooth_adapter.h" 17 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" 18 #include "device/bluetooth/test/mock_bluetooth_adapter.h" 19 #include "device/bluetooth/test/mock_bluetooth_device.h" 20 #include "device/bluetooth/test/mock_bluetooth_profile.h" 21 #include "device/bluetooth/test/mock_bluetooth_socket.h" 22 #include "testing/gmock/include/gmock/gmock.h" 23 24 using device::BluetoothAdapter; 25 using device::BluetoothDevice; 26 using device::BluetoothOutOfBandPairingData; 27 using device::BluetoothProfile; 28 using device::MockBluetoothAdapter; 29 using device::MockBluetoothDevice; 30 using device::MockBluetoothProfile; 31 using extensions::Extension; 32 33 namespace utils = extension_function_test_utils; 34 namespace api = extensions::api; 35 36 namespace { 37 38 static const char* kAdapterAddress = "A1:A2:A3:A4:A5:A6"; 39 static const char* kName = "whatsinaname"; 40 41 class BluetoothApiTest : public ExtensionApiTest { 42 public: 43 BluetoothApiTest() : empty_extension_(utils::CreateEmptyExtension()) {} 44 45 virtual void SetUpOnMainThread() OVERRIDE { 46 SetUpMockAdapter(); 47 profile1_.reset(new testing::NiceMock<MockBluetoothProfile>()); 48 profile2_.reset(new testing::NiceMock<MockBluetoothProfile>()); 49 } 50 51 virtual void CleanUpOnMainThread() OVERRIDE { 52 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 53 } 54 55 void SetUpMockAdapter() { 56 // The browser will clean this up when it is torn down 57 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>(); 58 event_router()->SetAdapterForTest(mock_adapter_); 59 60 device1_.reset(new testing::NiceMock<MockBluetoothDevice>( 61 mock_adapter_, 0, "d1", "11:12:13:14:15:16", 62 true /* paired */, true /* connected */)); 63 device2_.reset(new testing::NiceMock<MockBluetoothDevice>( 64 mock_adapter_, 0, "d2", "21:22:23:24:25:26", 65 false /* paired */, false /* connected */)); 66 } 67 68 template <class T> 69 T* setupFunction(T* function) { 70 function->set_extension(empty_extension_.get()); 71 function->set_has_callback(true); 72 return function; 73 } 74 75 protected: 76 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_; 77 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_; 78 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device2_; 79 scoped_ptr<testing::NiceMock<MockBluetoothProfile> > profile1_; 80 scoped_ptr<testing::NiceMock<MockBluetoothProfile> > profile2_; 81 82 extensions::ExtensionBluetoothEventRouter* event_router() { 83 return extensions::BluetoothAPI::Get(browser()->profile()) 84 ->bluetooth_event_router(); 85 } 86 87 private: 88 scoped_refptr<Extension> empty_extension_; 89 }; 90 91 class TestBluetoothAddProfileFunction 92 : public api::BluetoothAddProfileFunction { 93 public: 94 explicit TestBluetoothAddProfileFunction(BluetoothProfile* profile) 95 : BluetoothAddProfileFunction(), profile_(profile) { 96 } 97 98 protected: 99 virtual ~TestBluetoothAddProfileFunction() { 100 } 101 102 // BluetoothAddProfileFunction override. 103 virtual void RegisterProfile( 104 const device::BluetoothProfile::Options& options, 105 const device::BluetoothProfile::ProfileCallback& callback) OVERRIDE { 106 callback.Run(profile_); 107 } 108 109 private: 110 // TestBluetoothAddProfileFunction does not own |profile_|. 111 BluetoothProfile* profile_; 112 }; 113 114 // This is the canonical UUID for the short UUID 0010. 115 static const char kOutOfBandPairingDataHash[] = "0123456789ABCDEh"; 116 static const char kOutOfBandPairingDataRandomizer[] = "0123456789ABCDEr"; 117 118 static BluetoothOutOfBandPairingData GetOutOfBandPairingData() { 119 BluetoothOutOfBandPairingData data; 120 memcpy(&(data.hash), kOutOfBandPairingDataHash, 121 device::kBluetoothOutOfBandPairingDataSize); 122 memcpy(&(data.randomizer), kOutOfBandPairingDataRandomizer, 123 device::kBluetoothOutOfBandPairingDataSize); 124 return data; 125 } 126 127 static bool CallClosure(const base::Closure& callback) { 128 callback.Run(); 129 return true; 130 } 131 132 static void CallDiscoveryCallback( 133 const base::Closure& callback, 134 const BluetoothAdapter::ErrorCallback& error_callback) { 135 callback.Run(); 136 } 137 138 static void CallDiscoveryErrorCallback( 139 const base::Closure& callback, 140 const BluetoothAdapter::ErrorCallback& error_callback) { 141 error_callback.Run(); 142 } 143 144 static void CallOutOfBandPairingDataCallback( 145 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, 146 const BluetoothAdapter::ErrorCallback& error_callback) { 147 callback.Run(GetOutOfBandPairingData()); 148 } 149 150 } // namespace 151 152 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Profiles) { 153 // Run in context of an extension that has permissions for the profiles 154 // we intend to register. 155 scoped_refptr<const Extension> extension( 156 LoadExtension(test_data_dir_.AppendASCII("bluetooth/profiles"))); 157 ASSERT_TRUE(extension.get()); 158 159 EXPECT_CALL(*profile1_, SetConnectionCallback(testing::_)); 160 scoped_refptr<TestBluetoothAddProfileFunction> add_profile_function; 161 add_profile_function = new TestBluetoothAddProfileFunction(profile1_.get()); 162 add_profile_function->set_extension(extension.get()); 163 add_profile_function->set_has_callback(true); 164 std::string error(utils::RunFunctionAndReturnError( 165 add_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser())); 166 ASSERT_TRUE(error.empty()); 167 168 // Registering the profile for the same uuid again will throw an error. 169 add_profile_function = new TestBluetoothAddProfileFunction(profile2_.get()); 170 add_profile_function->set_extension(extension.get()); 171 add_profile_function->set_has_callback(true); 172 error = utils::RunFunctionAndReturnError( 173 add_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser()); 174 ASSERT_FALSE(error.empty()); 175 176 add_profile_function = new TestBluetoothAddProfileFunction(profile2_.get()); 177 add_profile_function->set_extension(extension.get()); 178 add_profile_function->set_has_callback(true); 179 error = utils::RunFunctionAndReturnError( 180 add_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); 181 ASSERT_TRUE(error.empty()); 182 183 scoped_refptr<api::BluetoothRemoveProfileFunction> remove_profile_function; 184 remove_profile_function = new api::BluetoothRemoveProfileFunction(); 185 remove_profile_function->set_extension(extension.get()); 186 remove_profile_function->set_has_callback(true); 187 error = utils::RunFunctionAndReturnError( 188 remove_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser()); 189 ASSERT_TRUE(error.empty()); 190 191 remove_profile_function = new api::BluetoothRemoveProfileFunction(); 192 remove_profile_function->set_extension(extension.get()); 193 remove_profile_function->set_has_callback(true); 194 error = utils::RunFunctionAndReturnError( 195 remove_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); 196 ASSERT_TRUE(error.empty()); 197 198 // Removing the same profile again will throw an error. 199 remove_profile_function = new api::BluetoothRemoveProfileFunction(); 200 remove_profile_function->set_extension(extension.get()); 201 remove_profile_function->set_has_callback(true); 202 error = utils::RunFunctionAndReturnError( 203 remove_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); 204 ASSERT_FALSE(error.empty()); 205 206 // Registering a profile we don't have permission for will throw an error. 207 add_profile_function = new TestBluetoothAddProfileFunction(profile1_.get()); 208 add_profile_function->set_extension(extension.get()); 209 add_profile_function->set_has_callback(true); 210 error = utils::RunFunctionAndReturnError( 211 add_profile_function.get(), "[{\"uuid\": \"9999\"}]", browser()); 212 ASSERT_FALSE(error.empty()); 213 } 214 215 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetAdapterState) { 216 EXPECT_CALL(*mock_adapter_, GetAddress()) 217 .WillOnce(testing::Return(kAdapterAddress)); 218 EXPECT_CALL(*mock_adapter_, GetName()) 219 .WillOnce(testing::Return(kName)); 220 EXPECT_CALL(*mock_adapter_, IsPresent()) 221 .WillOnce(testing::Return(false)); 222 EXPECT_CALL(*mock_adapter_, IsPowered()) 223 .WillOnce(testing::Return(true)); 224 EXPECT_CALL(*mock_adapter_, IsDiscovering()) 225 .WillOnce(testing::Return(false)); 226 227 scoped_refptr<api::BluetoothGetAdapterStateFunction> get_adapter_state; 228 get_adapter_state = setupFunction(new api::BluetoothGetAdapterStateFunction); 229 230 scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult( 231 get_adapter_state.get(), "[]", browser())); 232 ASSERT_TRUE(result.get() != NULL); 233 api::bluetooth::AdapterState state; 234 ASSERT_TRUE(api::bluetooth::AdapterState::Populate(*result, &state)); 235 236 EXPECT_FALSE(state.available); 237 EXPECT_TRUE(state.powered); 238 EXPECT_FALSE(state.discovering); 239 EXPECT_EQ(kName, state.name); 240 EXPECT_EQ(kAdapterAddress, state.address); 241 } 242 243 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetLocalOutOfBandPairingData) { 244 EXPECT_CALL(*mock_adapter_, 245 ReadLocalOutOfBandPairingData(testing::_, testing::_)) 246 .WillOnce(testing::Invoke(CallOutOfBandPairingDataCallback)); 247 248 scoped_refptr<api::BluetoothGetLocalOutOfBandPairingDataFunction> 249 get_oob_function(setupFunction( 250 new api::BluetoothGetLocalOutOfBandPairingDataFunction)); 251 252 scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult( 253 get_oob_function.get(), "[]", browser())); 254 255 base::DictionaryValue* dict; 256 EXPECT_TRUE(result->GetAsDictionary(&dict)); 257 258 base::BinaryValue* binary_value; 259 EXPECT_TRUE(dict->GetBinary("hash", &binary_value)); 260 EXPECT_STREQ(kOutOfBandPairingDataHash, 261 std::string(binary_value->GetBuffer(), binary_value->GetSize()).c_str()); 262 EXPECT_TRUE(dict->GetBinary("randomizer", &binary_value)); 263 EXPECT_STREQ(kOutOfBandPairingDataRandomizer, 264 std::string(binary_value->GetBuffer(), binary_value->GetSize()).c_str()); 265 266 // Try again with an error 267 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 268 EXPECT_CALL(*mock_adapter_, 269 ReadLocalOutOfBandPairingData( 270 testing::_, 271 testing::Truly(CallClosure))); 272 273 get_oob_function = 274 setupFunction(new api::BluetoothGetLocalOutOfBandPairingDataFunction); 275 276 std::string error(utils::RunFunctionAndReturnError( 277 get_oob_function.get(), "[]", browser())); 278 EXPECT_FALSE(error.empty()); 279 } 280 281 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, SetOutOfBandPairingData) { 282 EXPECT_CALL(*mock_adapter_, GetDevice(device1_->GetAddress())) 283 .WillOnce(testing::Return(device1_.get())); 284 EXPECT_CALL(*device1_, 285 ClearOutOfBandPairingData(testing::Truly(CallClosure), 286 testing::_)); 287 288 std::string params = base::StringPrintf( 289 "[{\"deviceAddress\":\"%s\"}]", device1_->GetAddress().c_str()); 290 291 scoped_refptr<api::BluetoothSetOutOfBandPairingDataFunction> set_oob_function; 292 set_oob_function = setupFunction( 293 new api::BluetoothSetOutOfBandPairingDataFunction); 294 // There isn't actually a result. 295 (void) utils::RunFunctionAndReturnSingleResult( 296 set_oob_function.get(), params, browser()); 297 298 // Try again with an error 299 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 300 testing::Mock::VerifyAndClearExpectations(device1_.get()); 301 EXPECT_CALL(*mock_adapter_, GetDevice(device1_->GetAddress())) 302 .WillOnce(testing::Return(device1_.get())); 303 EXPECT_CALL(*device1_, 304 ClearOutOfBandPairingData(testing::_, 305 testing::Truly(CallClosure))); 306 307 set_oob_function = setupFunction( 308 new api::BluetoothSetOutOfBandPairingDataFunction); 309 std::string error(utils::RunFunctionAndReturnError( 310 set_oob_function.get(), params, browser())); 311 EXPECT_FALSE(error.empty()); 312 313 // TODO(bryeung): Also test setting the data when there is support for 314 // ArrayBuffers in the arguments to the RunFunctionAnd* methods. 315 // crbug.com/132796 316 } 317 318 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Discovery) { 319 // Try with a failure to start 320 EXPECT_CALL(*mock_adapter_, StartDiscovering(testing::_, testing::_)) 321 .WillOnce(testing::Invoke(CallDiscoveryErrorCallback)); 322 // StartDiscovery failure will remove the adapter that is no longer used. 323 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 324 scoped_refptr<api::BluetoothStartDiscoveryFunction> start_function; 325 start_function = setupFunction(new api::BluetoothStartDiscoveryFunction); 326 std::string error( 327 utils::RunFunctionAndReturnError(start_function.get(), "[]", browser())); 328 ASSERT_FALSE(error.empty()); 329 330 // Reset for a successful start 331 SetUpMockAdapter(); 332 EXPECT_CALL(*mock_adapter_, StartDiscovering(testing::_, testing::_)) 333 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 334 335 start_function = setupFunction(new api::BluetoothStartDiscoveryFunction); 336 (void) 337 utils::RunFunctionAndReturnError(start_function.get(), "[]", browser()); 338 339 // Reset to try stopping 340 testing::Mock::VerifyAndClearExpectations(mock_adapter_); 341 EXPECT_CALL(*mock_adapter_, StopDiscovering(testing::_, testing::_)) 342 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 343 // StopDiscovery success will remove the adapter that is no longer used. 344 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 345 scoped_refptr<api::BluetoothStopDiscoveryFunction> stop_function; 346 stop_function = setupFunction(new api::BluetoothStopDiscoveryFunction); 347 (void) utils::RunFunctionAndReturnSingleResult( 348 stop_function.get(), "[]", browser()); 349 350 // Reset to try stopping with an error 351 SetUpMockAdapter(); 352 EXPECT_CALL(*mock_adapter_, StopDiscovering(testing::_, testing::_)) 353 .WillOnce(testing::Invoke(CallDiscoveryErrorCallback)); 354 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 355 stop_function = setupFunction(new api::BluetoothStopDiscoveryFunction); 356 error = 357 utils::RunFunctionAndReturnError(stop_function.get(), "[]", browser()); 358 ASSERT_FALSE(error.empty()); 359 SetUpMockAdapter(); 360 } 361 362 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DiscoveryCallback) { 363 EXPECT_CALL(*mock_adapter_, StartDiscovering(testing::_, testing::_)) 364 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 365 EXPECT_CALL(*mock_adapter_, StopDiscovering(testing::_, testing::_)) 366 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 367 368 ResultCatcher catcher; 369 catcher.RestrictToProfile(browser()->profile()); 370 371 ExtensionTestMessageListener discovery_started("ready", true); 372 ASSERT_TRUE(LoadExtension( 373 test_data_dir_.AppendASCII("bluetooth/discovery_callback"))); 374 EXPECT_TRUE(discovery_started.WaitUntilSatisfied()); 375 376 event_router()->DeviceAdded(mock_adapter_, device1_.get()); 377 378 discovery_started.Reply("go"); 379 ExtensionTestMessageListener discovery_stopped("ready", true); 380 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 381 EXPECT_TRUE(discovery_stopped.WaitUntilSatisfied()); 382 383 SetUpMockAdapter(); 384 event_router()->DeviceAdded(mock_adapter_, device2_.get()); 385 discovery_stopped.Reply("go"); 386 387 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 388 } 389 390 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DiscoveryInProgress) { 391 EXPECT_CALL(*mock_adapter_, GetAddress()) 392 .WillOnce(testing::Return(kAdapterAddress)); 393 EXPECT_CALL(*mock_adapter_, GetName()) 394 .WillOnce(testing::Return(kName)); 395 EXPECT_CALL(*mock_adapter_, IsPresent()) 396 .WillOnce(testing::Return(true)); 397 EXPECT_CALL(*mock_adapter_, IsPowered()) 398 .WillOnce(testing::Return(true)); 399 400 // Fake that the adapter is discovering 401 EXPECT_CALL(*mock_adapter_, IsDiscovering()) 402 .WillOnce(testing::Return(true)); 403 event_router()->AdapterDiscoveringChanged(mock_adapter_, true); 404 405 // Cache a device before the extension starts discovering 406 event_router()->DeviceAdded(mock_adapter_, device1_.get()); 407 408 ResultCatcher catcher; 409 catcher.RestrictToProfile(browser()->profile()); 410 411 EXPECT_CALL(*mock_adapter_, StartDiscovering(testing::_, testing::_)) 412 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 413 EXPECT_CALL(*mock_adapter_, StopDiscovering(testing::_, testing::_)) 414 .WillOnce(testing::Invoke(CallDiscoveryCallback)); 415 416 ExtensionTestMessageListener discovery_started("ready", true); 417 ASSERT_TRUE(LoadExtension( 418 test_data_dir_.AppendASCII("bluetooth/discovery_in_progress"))); 419 EXPECT_TRUE(discovery_started.WaitUntilSatisfied()); 420 421 // This should be received in addition to the cached device above. 422 event_router()->DeviceAdded(mock_adapter_, device2_.get()); 423 424 discovery_started.Reply("go"); 425 ExtensionTestMessageListener discovery_stopped("ready", true); 426 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); 427 EXPECT_TRUE(discovery_stopped.WaitUntilSatisfied()); 428 429 SetUpMockAdapter(); 430 // This should never be received. 431 event_router()->DeviceAdded(mock_adapter_, device2_.get()); 432 discovery_stopped.Reply("go"); 433 434 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 435 } 436 437 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, OnAdapterStateChanged) { 438 ResultCatcher catcher; 439 catcher.RestrictToProfile(browser()->profile()); 440 441 // Load and wait for setup 442 ExtensionTestMessageListener listener("ready", true); 443 ASSERT_TRUE( 444 LoadExtension( 445 test_data_dir_.AppendASCII("bluetooth/on_adapter_state_changed"))); 446 EXPECT_TRUE(listener.WaitUntilSatisfied()); 447 448 EXPECT_CALL(*mock_adapter_, GetAddress()) 449 .WillOnce(testing::Return(kAdapterAddress)); 450 EXPECT_CALL(*mock_adapter_, GetName()) 451 .WillOnce(testing::Return(kName)); 452 EXPECT_CALL(*mock_adapter_, IsPresent()) 453 .WillOnce(testing::Return(false)); 454 EXPECT_CALL(*mock_adapter_, IsPowered()) 455 .WillOnce(testing::Return(false)); 456 EXPECT_CALL(*mock_adapter_, IsDiscovering()) 457 .WillOnce(testing::Return(false)); 458 event_router()->AdapterPoweredChanged(mock_adapter_, false); 459 460 EXPECT_CALL(*mock_adapter_, GetAddress()) 461 .WillOnce(testing::Return(kAdapterAddress)); 462 EXPECT_CALL(*mock_adapter_, GetName()) 463 .WillOnce(testing::Return(kName)); 464 EXPECT_CALL(*mock_adapter_, IsPresent()) 465 .WillOnce(testing::Return(true)); 466 EXPECT_CALL(*mock_adapter_, IsPowered()) 467 .WillOnce(testing::Return(true)); 468 EXPECT_CALL(*mock_adapter_, IsDiscovering()) 469 .WillOnce(testing::Return(true)); 470 event_router()->AdapterPresentChanged(mock_adapter_, true); 471 472 EXPECT_CALL(*mock_adapter_, GetAddress()) 473 .WillOnce(testing::Return(kAdapterAddress)); 474 EXPECT_CALL(*mock_adapter_, GetName()) 475 .WillOnce(testing::Return(kName)); 476 EXPECT_CALL(*mock_adapter_, IsPresent()) 477 .WillOnce(testing::Return(true)); 478 EXPECT_CALL(*mock_adapter_, IsPowered()) 479 .WillOnce(testing::Return(true)); 480 EXPECT_CALL(*mock_adapter_, IsDiscovering()) 481 .WillOnce(testing::Return(true)); 482 event_router()->AdapterDiscoveringChanged(mock_adapter_, true); 483 484 listener.Reply("go"); 485 486 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 487 } 488 489 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, OnConnection) { 490 ResultCatcher catcher; 491 catcher.RestrictToProfile(browser()->profile()); 492 493 // Load and wait for setup 494 ExtensionTestMessageListener listener("ready", true); 495 scoped_refptr<const Extension> extension( 496 LoadExtension(test_data_dir_.AppendASCII("bluetooth/on_connection"))); 497 ASSERT_TRUE(extension.get()); 498 EXPECT_TRUE(listener.WaitUntilSatisfied()); 499 500 scoped_refptr<device::MockBluetoothSocket> socket = 501 new device::MockBluetoothSocket(); 502 503 event_router()->AddProfile("1234", profile1_.get()); 504 event_router()->DispatchConnectionEvent( 505 extension->id(), "1234", device1_.get(), socket); 506 507 listener.Reply("go"); 508 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 509 event_router()->RemoveProfile("1234"); 510 } 511 512 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetProfiles) { 513 ResultCatcher catcher; 514 catcher.RestrictToProfile(browser()->profile()); 515 516 BluetoothDevice::ServiceList service_list; 517 service_list.push_back("1234"); 518 service_list.push_back("5678"); 519 520 EXPECT_CALL(*device1_, GetServices()) 521 .WillOnce(testing::Return(service_list)); 522 523 EXPECT_CALL(*mock_adapter_, GetDevice(device1_->GetAddress())) 524 .WillOnce(testing::Return(device1_.get())); 525 526 // Load and wait for setup 527 ExtensionTestMessageListener listener("ready", true); 528 ASSERT_TRUE( 529 LoadExtension(test_data_dir_.AppendASCII("bluetooth/get_profiles"))); 530 EXPECT_TRUE(listener.WaitUntilSatisfied()); 531 532 listener.Reply("go"); 533 534 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 535 } 536 537 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevices) { 538 ResultCatcher catcher; 539 catcher.RestrictToProfile(browser()->profile()); 540 541 BluetoothAdapter::ConstDeviceList devices; 542 devices.push_back(device1_.get()); 543 devices.push_back(device2_.get()); 544 545 EXPECT_CALL(*device1_, ProvidesServiceWithUUID(testing::_)) 546 .WillOnce(testing::Return(false)); 547 548 EXPECT_CALL(*device2_, ProvidesServiceWithUUID(testing::_)) 549 .WillOnce(testing::Return(true)); 550 551 EXPECT_CALL(*mock_adapter_, GetDevices()) 552 .Times(2) 553 .WillRepeatedly(testing::Return(devices)); 554 555 // Load and wait for setup 556 ExtensionTestMessageListener listener("ready", true); 557 ASSERT_TRUE( 558 LoadExtension(test_data_dir_.AppendASCII("bluetooth/get_devices"))); 559 EXPECT_TRUE(listener.WaitUntilSatisfied()); 560 561 listener.Reply("go"); 562 563 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 564 } 565 566 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevicesError) { 567 ResultCatcher catcher; 568 catcher.RestrictToProfile(browser()->profile()); 569 570 // Load and wait for setup 571 ExtensionTestMessageListener listener("ready", true); 572 ASSERT_TRUE(LoadExtension( 573 test_data_dir_.AppendASCII("bluetooth/get_devices_error"))); 574 EXPECT_TRUE(listener.WaitUntilSatisfied()); 575 576 listener.Reply("go"); 577 578 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 579 } 580