| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string.h> | 5 #include <string.h> |
| 6 | 6 |
| 7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" | 9 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" |
| 10 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" | 10 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" |
| 11 #include "chrome/browser/extensions/extension_apitest.h" | 11 #include "chrome/browser/extensions/extension_apitest.h" |
| 12 #include "chrome/browser/extensions/extension_function_test_utils.h" | 12 #include "chrome/browser/extensions/extension_function_test_utils.h" |
| 13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
| 14 #include "chrome/browser/extensions/extension_test_message_listener.h" | 14 #include "chrome/browser/extensions/extension_test_message_listener.h" |
| 15 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/test/base/ui_test_utils.h" | 16 #include "chrome/test/base/ui_test_utils.h" |
| 17 #include "device/bluetooth/bluetooth_adapter.h" | 17 #include "device/bluetooth/bluetooth_adapter.h" |
| 18 #include "device/bluetooth/bluetooth_uuid.h" | 18 #include "device/bluetooth/bluetooth_uuid.h" |
| 19 #include "device/bluetooth/test/mock_bluetooth_adapter.h" | 19 #include "device/bluetooth/test/mock_bluetooth_adapter.h" |
| 20 #include "device/bluetooth/test/mock_bluetooth_device.h" | 20 #include "device/bluetooth/test/mock_bluetooth_device.h" |
| 21 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h" | 21 #include "device/bluetooth/test/mock_bluetooth_discovery_session.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" | 22 #include "testing/gmock/include/gmock/gmock.h" |
| 25 | 23 |
| 26 using device::BluetoothAdapter; | 24 using device::BluetoothAdapter; |
| 27 using device::BluetoothDevice; | 25 using device::BluetoothDevice; |
| 28 using device::BluetoothDiscoverySession; | 26 using device::BluetoothDiscoverySession; |
| 29 using device::BluetoothProfile; | |
| 30 using device::BluetoothUUID; | 27 using device::BluetoothUUID; |
| 31 using device::MockBluetoothAdapter; | 28 using device::MockBluetoothAdapter; |
| 32 using device::MockBluetoothDevice; | 29 using device::MockBluetoothDevice; |
| 33 using device::MockBluetoothDiscoverySession; | 30 using device::MockBluetoothDiscoverySession; |
| 34 using device::MockBluetoothProfile; | |
| 35 using extensions::Extension; | 31 using extensions::Extension; |
| 36 | 32 |
| 37 namespace utils = extension_function_test_utils; | 33 namespace utils = extension_function_test_utils; |
| 38 namespace api = extensions::api; | 34 namespace api = extensions::api; |
| 39 | 35 |
| 40 namespace { | 36 namespace { |
| 41 | 37 |
| 42 static const char* kAdapterAddress = "A1:A2:A3:A4:A5:A6"; | 38 static const char* kAdapterAddress = "A1:A2:A3:A4:A5:A6"; |
| 43 static const char* kName = "whatsinaname"; | 39 static const char* kName = "whatsinaname"; |
| 44 | 40 |
| 45 class BluetoothApiTest : public ExtensionApiTest { | 41 class BluetoothApiTest : public ExtensionApiTest { |
| 46 public: | 42 public: |
| 47 BluetoothApiTest() {} | 43 BluetoothApiTest() {} |
| 48 | 44 |
| 49 virtual void SetUpOnMainThread() OVERRIDE { | 45 virtual void SetUpOnMainThread() OVERRIDE { |
| 50 ExtensionApiTest::SetUpOnMainThread(); | 46 ExtensionApiTest::SetUpOnMainThread(); |
| 51 empty_extension_ = utils::CreateEmptyExtension(); | 47 empty_extension_ = utils::CreateEmptyExtension(); |
| 52 SetUpMockAdapter(); | 48 SetUpMockAdapter(); |
| 53 profile1_.reset(new testing::NiceMock<MockBluetoothProfile>()); | |
| 54 profile2_.reset(new testing::NiceMock<MockBluetoothProfile>()); | |
| 55 } | 49 } |
| 56 | 50 |
| 57 virtual void CleanUpOnMainThread() OVERRIDE { | 51 virtual void CleanUpOnMainThread() OVERRIDE { |
| 58 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); | 52 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); |
| 59 } | 53 } |
| 60 | 54 |
| 61 void SetUpMockAdapter() { | 55 void SetUpMockAdapter() { |
| 62 // The browser will clean this up when it is torn down | 56 // The browser will clean this up when it is torn down |
| 63 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>(); | 57 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>(); |
| 64 event_router()->SetAdapterForTest(mock_adapter_); | 58 event_router()->SetAdapterForTest(mock_adapter_); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 91 function->set_has_callback(true); | 85 function->set_has_callback(true); |
| 92 return function; | 86 return function; |
| 93 } | 87 } |
| 94 | 88 |
| 95 protected: | 89 protected: |
| 96 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_; | 90 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_; |
| 97 scoped_ptr<testing::NiceMock<MockBluetoothDiscoverySession> > mock_session_; | 91 scoped_ptr<testing::NiceMock<MockBluetoothDiscoverySession> > mock_session_; |
| 98 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_; | 92 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_; |
| 99 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device2_; | 93 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device2_; |
| 100 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device3_; | 94 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device3_; |
| 101 scoped_ptr<testing::NiceMock<MockBluetoothProfile> > profile1_; | |
| 102 scoped_ptr<testing::NiceMock<MockBluetoothProfile> > profile2_; | |
| 103 | 95 |
| 104 extensions::BluetoothEventRouter* event_router() { | 96 extensions::BluetoothEventRouter* event_router() { |
| 105 return bluetooth_api()->event_router(); | 97 return bluetooth_api()->event_router(); |
| 106 } | 98 } |
| 107 | 99 |
| 108 extensions::BluetoothAPI* bluetooth_api() { | 100 extensions::BluetoothAPI* bluetooth_api() { |
| 109 return extensions::BluetoothAPI::Get(browser()->profile()); | 101 return extensions::BluetoothAPI::Get(browser()->profile()); |
| 110 } | 102 } |
| 111 | 103 |
| 112 private: | 104 private: |
| 113 scoped_refptr<Extension> empty_extension_; | 105 scoped_refptr<Extension> empty_extension_; |
| 114 }; | 106 }; |
| 115 | 107 |
| 116 class TestBluetoothAddProfileFunction | |
| 117 : public api::BluetoothAddProfileFunction { | |
| 118 public: | |
| 119 explicit TestBluetoothAddProfileFunction(BluetoothProfile* profile) | |
| 120 : BluetoothAddProfileFunction(), profile_(profile) { | |
| 121 } | |
| 122 | |
| 123 protected: | |
| 124 virtual ~TestBluetoothAddProfileFunction() { | |
| 125 } | |
| 126 | |
| 127 // BluetoothAddProfileFunction override. | |
| 128 virtual void RegisterProfile( | |
| 129 const device::BluetoothProfile::Options& options, | |
| 130 const device::BluetoothProfile::ProfileCallback& callback) OVERRIDE { | |
| 131 callback.Run(profile_); | |
| 132 } | |
| 133 | |
| 134 private: | |
| 135 // TestBluetoothAddProfileFunction does not own |profile_|. | |
| 136 BluetoothProfile* profile_; | |
| 137 }; | |
| 138 | |
| 139 static void StopDiscoverySessionCallback(const base::Closure& callback, | 108 static void StopDiscoverySessionCallback(const base::Closure& callback, |
| 140 const base::Closure& error_callback) { | 109 const base::Closure& error_callback) { |
| 141 callback.Run(); | 110 callback.Run(); |
| 142 } | 111 } |
| 143 | 112 |
| 144 } // namespace | 113 } // namespace |
| 145 | 114 |
| 146 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Profiles) { | |
| 147 // Run in context of an extension that has permissions for the profiles | |
| 148 // we intend to register. | |
| 149 scoped_refptr<const Extension> extension( | |
| 150 LoadExtension(test_data_dir_.AppendASCII("bluetooth/profiles"))); | |
| 151 ASSERT_TRUE(extension.get()); | |
| 152 | |
| 153 EXPECT_CALL(*profile1_, SetConnectionCallback(testing::_)); | |
| 154 scoped_refptr<TestBluetoothAddProfileFunction> add_profile_function; | |
| 155 add_profile_function = new TestBluetoothAddProfileFunction(profile1_.get()); | |
| 156 add_profile_function->set_extension(extension.get()); | |
| 157 add_profile_function->set_has_callback(true); | |
| 158 std::string error(utils::RunFunctionAndReturnError( | |
| 159 add_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser())); | |
| 160 ASSERT_TRUE(error.empty()); | |
| 161 | |
| 162 // Registering the profile for the same uuid again will throw an error. | |
| 163 add_profile_function = new TestBluetoothAddProfileFunction(profile2_.get()); | |
| 164 add_profile_function->set_extension(extension.get()); | |
| 165 add_profile_function->set_has_callback(true); | |
| 166 error = utils::RunFunctionAndReturnError( | |
| 167 add_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser()); | |
| 168 ASSERT_FALSE(error.empty()); | |
| 169 | |
| 170 add_profile_function = new TestBluetoothAddProfileFunction(profile2_.get()); | |
| 171 add_profile_function->set_extension(extension.get()); | |
| 172 add_profile_function->set_has_callback(true); | |
| 173 error = utils::RunFunctionAndReturnError( | |
| 174 add_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); | |
| 175 ASSERT_TRUE(error.empty()); | |
| 176 | |
| 177 scoped_refptr<api::BluetoothRemoveProfileFunction> remove_profile_function; | |
| 178 remove_profile_function = new api::BluetoothRemoveProfileFunction(); | |
| 179 remove_profile_function->set_extension(extension.get()); | |
| 180 remove_profile_function->set_has_callback(true); | |
| 181 error = utils::RunFunctionAndReturnError( | |
| 182 remove_profile_function.get(), "[{\"uuid\": \"1234\"}]", browser()); | |
| 183 ASSERT_TRUE(error.empty()); | |
| 184 | |
| 185 remove_profile_function = new api::BluetoothRemoveProfileFunction(); | |
| 186 remove_profile_function->set_extension(extension.get()); | |
| 187 remove_profile_function->set_has_callback(true); | |
| 188 error = utils::RunFunctionAndReturnError( | |
| 189 remove_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); | |
| 190 ASSERT_TRUE(error.empty()); | |
| 191 | |
| 192 // Removing the same profile again will throw an error. | |
| 193 remove_profile_function = new api::BluetoothRemoveProfileFunction(); | |
| 194 remove_profile_function->set_extension(extension.get()); | |
| 195 remove_profile_function->set_has_callback(true); | |
| 196 error = utils::RunFunctionAndReturnError( | |
| 197 remove_profile_function.get(), "[{\"uuid\": \"5678\"}]", browser()); | |
| 198 ASSERT_FALSE(error.empty()); | |
| 199 | |
| 200 // Registering a profile we don't have permission for will throw an error. | |
| 201 add_profile_function = new TestBluetoothAddProfileFunction(profile1_.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\": \"9999\"}]", browser()); | |
| 206 ASSERT_FALSE(error.empty()); | |
| 207 } | |
| 208 | |
| 209 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetAdapterState) { | 115 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetAdapterState) { |
| 210 EXPECT_CALL(*mock_adapter_, GetAddress()) | 116 EXPECT_CALL(*mock_adapter_, GetAddress()) |
| 211 .WillOnce(testing::Return(kAdapterAddress)); | 117 .WillOnce(testing::Return(kAdapterAddress)); |
| 212 EXPECT_CALL(*mock_adapter_, GetName()) | 118 EXPECT_CALL(*mock_adapter_, GetName()) |
| 213 .WillOnce(testing::Return(kName)); | 119 .WillOnce(testing::Return(kName)); |
| 214 EXPECT_CALL(*mock_adapter_, IsPresent()) | 120 EXPECT_CALL(*mock_adapter_, IsPresent()) |
| 215 .WillOnce(testing::Return(false)); | 121 .WillOnce(testing::Return(false)); |
| 216 EXPECT_CALL(*mock_adapter_, IsPowered()) | 122 EXPECT_CALL(*mock_adapter_, IsPowered()) |
| 217 .WillOnce(testing::Return(true)); | 123 .WillOnce(testing::Return(true)); |
| 218 EXPECT_CALL(*mock_adapter_, IsDiscovering()) | 124 EXPECT_CALL(*mock_adapter_, IsDiscovering()) |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 .WillOnce(testing::Return(true)); | 348 .WillOnce(testing::Return(true)); |
| 443 EXPECT_CALL(*mock_adapter_, IsDiscovering()) | 349 EXPECT_CALL(*mock_adapter_, IsDiscovering()) |
| 444 .WillOnce(testing::Return(true)); | 350 .WillOnce(testing::Return(true)); |
| 445 event_router()->AdapterDiscoveringChanged(mock_adapter_, true); | 351 event_router()->AdapterDiscoveringChanged(mock_adapter_, true); |
| 446 | 352 |
| 447 listener.Reply("go"); | 353 listener.Reply("go"); |
| 448 | 354 |
| 449 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | 355 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| 450 } | 356 } |
| 451 | 357 |
| 452 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, OnConnection) { | |
| 453 ResultCatcher catcher; | |
| 454 catcher.RestrictToProfile(browser()->profile()); | |
| 455 | |
| 456 // Load and wait for setup | |
| 457 ExtensionTestMessageListener listener("ready", true); | |
| 458 scoped_refptr<const Extension> extension( | |
| 459 LoadExtension(test_data_dir_.AppendASCII("bluetooth/on_connection"))); | |
| 460 ASSERT_TRUE(extension.get()); | |
| 461 EXPECT_TRUE(listener.WaitUntilSatisfied()); | |
| 462 | |
| 463 scoped_refptr<device::MockBluetoothSocket> socket = | |
| 464 new device::MockBluetoothSocket(); | |
| 465 | |
| 466 EXPECT_CALL(*mock_adapter_, GetDevice(device1_->GetAddress())) | |
| 467 .WillOnce(testing::Return(device1_.get())); | |
| 468 | |
| 469 event_router()->AddProfile( | |
| 470 BluetoothUUID("1234"), extension->id(), profile1_.get()); | |
| 471 bluetooth_api()->DispatchConnectionEvent( | |
| 472 extension->id(), BluetoothUUID("1234"), device1_.get(), socket); | |
| 473 // Connection events are dispatched using a couple of PostTask to the UI | |
| 474 // thread. Waiting until idle ensures the event is dispatched to the | |
| 475 // receiver(s). | |
| 476 base::RunLoop().RunUntilIdle(); | |
| 477 | |
| 478 listener.Reply("go"); | |
| 479 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | |
| 480 event_router()->RemoveProfile(BluetoothUUID("1234")); | |
| 481 } | |
| 482 | |
| 483 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevices) { | 358 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevices) { |
| 484 ResultCatcher catcher; | 359 ResultCatcher catcher; |
| 485 catcher.RestrictToProfile(browser()->profile()); | 360 catcher.RestrictToProfile(browser()->profile()); |
| 486 | 361 |
| 487 BluetoothAdapter::ConstDeviceList devices; | 362 BluetoothAdapter::ConstDeviceList devices; |
| 488 devices.push_back(device1_.get()); | 363 devices.push_back(device1_.get()); |
| 489 devices.push_back(device2_.get()); | 364 devices.push_back(device2_.get()); |
| 490 | 365 |
| 491 EXPECT_CALL(*mock_adapter_, GetDevices()) | 366 EXPECT_CALL(*mock_adapter_, GetDevices()) |
| 492 .Times(1) | 367 .Times(1) |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 // Load and wait for setup | 450 // Load and wait for setup |
| 576 ExtensionTestMessageListener listener("ready", true); | 451 ExtensionTestMessageListener listener("ready", true); |
| 577 ASSERT_TRUE( | 452 ASSERT_TRUE( |
| 578 LoadExtension(test_data_dir_.AppendASCII("bluetooth/device_info"))); | 453 LoadExtension(test_data_dir_.AppendASCII("bluetooth/device_info"))); |
| 579 EXPECT_TRUE(listener.WaitUntilSatisfied()); | 454 EXPECT_TRUE(listener.WaitUntilSatisfied()); |
| 580 | 455 |
| 581 listener.Reply("go"); | 456 listener.Reply("go"); |
| 582 | 457 |
| 583 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | 458 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| 584 } | 459 } |
| OLD | NEW |