Home | History | Annotate | Download | only in bluetooth
      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