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