Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / bluetooth / bluetooth_apitest.cc
blob184c4c8225cd69e07efab439b71b24b60cb77391
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.
5 #include <string.h>
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_apitest.h"
10 #include "chrome/browser/extensions/extension_function_test_utils.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "device/bluetooth/bluetooth_adapter.h"
15 #include "device/bluetooth/bluetooth_uuid.h"
16 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
17 #include "device/bluetooth/test/mock_bluetooth_device.h"
18 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
19 #include "extensions/browser/api/bluetooth/bluetooth_api.h"
20 #include "extensions/browser/api/bluetooth/bluetooth_event_router.h"
21 #include "extensions/common/test_util.h"
22 #include "extensions/test/extension_test_message_listener.h"
23 #include "extensions/test/result_catcher.h"
24 #include "testing/gmock/include/gmock/gmock.h"
26 using device::BluetoothAdapter;
27 using device::BluetoothDevice;
28 using device::BluetoothDiscoverySession;
29 using device::BluetoothUUID;
30 using device::MockBluetoothAdapter;
31 using device::MockBluetoothDevice;
32 using device::MockBluetoothDiscoverySession;
33 using extensions::Extension;
34 using extensions::ResultCatcher;
36 namespace utils = extension_function_test_utils;
37 namespace api = extensions::api;
39 namespace {
41 static const char* kAdapterAddress = "A1:A2:A3:A4:A5:A6";
42 static const char* kName = "whatsinaname";
44 class BluetoothApiTest : public ExtensionApiTest {
45 public:
46 BluetoothApiTest() {}
48 void SetUpOnMainThread() override {
49 ExtensionApiTest::SetUpOnMainThread();
50 empty_extension_ = extensions::test_util::CreateEmptyExtension();
51 SetUpMockAdapter();
54 void TearDownOnMainThread() override {
55 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_));
58 void SetUpMockAdapter() {
59 // The browser will clean this up when it is torn down
60 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
61 event_router()->SetAdapterForTest(mock_adapter_);
63 device1_.reset(new testing::NiceMock<MockBluetoothDevice>(
64 mock_adapter_, 0, "d1", "11:12:13:14:15:16",
65 true /* paired */, true /* connected */));
66 device2_.reset(new testing::NiceMock<MockBluetoothDevice>(
67 mock_adapter_, 0, "d2", "21:22:23:24:25:26",
68 false /* paired */, false /* connected */));
69 device3_.reset(new testing::NiceMock<MockBluetoothDevice>(
70 mock_adapter_, 0, "d3", "31:32:33:34:35:36",
71 false /* paired */, false /* connected */));
74 void DiscoverySessionCallback(
75 const BluetoothAdapter::DiscoverySessionCallback& callback,
76 const BluetoothAdapter::ErrorCallback& error_callback) {
77 if (mock_session_.get()) {
78 callback.Run(
79 scoped_ptr<BluetoothDiscoverySession>(mock_session_.release()));
80 return;
82 error_callback.Run();
85 template <class T>
86 T* setupFunction(T* function) {
87 function->set_extension(empty_extension_.get());
88 function->set_has_callback(true);
89 return function;
92 protected:
93 testing::StrictMock<MockBluetoothAdapter>* mock_adapter_;
94 scoped_ptr<testing::NiceMock<MockBluetoothDiscoverySession> > mock_session_;
95 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device1_;
96 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device2_;
97 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device3_;
99 extensions::BluetoothEventRouter* event_router() {
100 return bluetooth_api()->event_router();
103 extensions::BluetoothAPI* bluetooth_api() {
104 return extensions::BluetoothAPI::Get(browser()->profile());
107 private:
108 scoped_refptr<Extension> empty_extension_;
111 static void StopDiscoverySessionCallback(const base::Closure& callback,
112 const base::Closure& error_callback) {
113 callback.Run();
116 } // namespace
118 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetAdapterState) {
119 EXPECT_CALL(*mock_adapter_, GetAddress())
120 .WillOnce(testing::Return(kAdapterAddress));
121 EXPECT_CALL(*mock_adapter_, GetName())
122 .WillOnce(testing::Return(kName));
123 EXPECT_CALL(*mock_adapter_, IsPresent())
124 .WillOnce(testing::Return(false));
125 EXPECT_CALL(*mock_adapter_, IsPowered())
126 .WillOnce(testing::Return(true));
127 EXPECT_CALL(*mock_adapter_, IsDiscovering())
128 .WillOnce(testing::Return(false));
130 scoped_refptr<api::BluetoothGetAdapterStateFunction> get_adapter_state;
131 get_adapter_state = setupFunction(new api::BluetoothGetAdapterStateFunction);
133 scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
134 get_adapter_state.get(), "[]", browser()));
135 ASSERT_TRUE(result.get() != NULL);
136 api::bluetooth::AdapterState state;
137 ASSERT_TRUE(api::bluetooth::AdapterState::Populate(*result, &state));
139 EXPECT_FALSE(state.available);
140 EXPECT_TRUE(state.powered);
141 EXPECT_FALSE(state.discovering);
142 EXPECT_EQ(kName, state.name);
143 EXPECT_EQ(kAdapterAddress, state.address);
146 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DeviceEvents) {
147 ResultCatcher catcher;
148 catcher.RestrictToBrowserContext(browser()->profile());
150 ASSERT_TRUE(LoadExtension(
151 test_data_dir_.AppendASCII("bluetooth/device_events")));
153 ExtensionTestMessageListener events_received("ready", true);
154 event_router()->DeviceAdded(mock_adapter_, device1_.get());
155 event_router()->DeviceAdded(mock_adapter_, device2_.get());
157 EXPECT_CALL(*device2_.get(), GetDeviceName())
158 .WillRepeatedly(testing::Return("the real d2"));
159 EXPECT_CALL(*device2_.get(), GetName())
160 .WillRepeatedly(testing::Return(base::UTF8ToUTF16("the real d2")));
161 event_router()->DeviceChanged(mock_adapter_, device2_.get());
163 event_router()->DeviceAdded(mock_adapter_, device3_.get());
164 event_router()->DeviceRemoved(mock_adapter_, device1_.get());
165 EXPECT_TRUE(events_received.WaitUntilSatisfied());
166 events_received.Reply("go");
168 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
171 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Discovery) {
172 // Try with a failure to start. This will return an error as we haven't
173 // initialied a session object.
174 EXPECT_CALL(*mock_adapter_, StartDiscoverySession(testing::_, testing::_))
175 .WillOnce(
176 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback));
178 // StartDiscovery failure will not reference the adapter.
179 scoped_refptr<api::BluetoothStartDiscoveryFunction> start_function;
180 start_function = setupFunction(new api::BluetoothStartDiscoveryFunction);
181 std::string error(
182 utils::RunFunctionAndReturnError(start_function.get(), "[]", browser()));
183 ASSERT_FALSE(error.empty());
185 // Reset the adapter and initiate a discovery session. The ownership of the
186 // mock session will be passed to the event router.
187 ASSERT_FALSE(mock_session_.get());
188 SetUpMockAdapter();
190 // Create a mock session to be returned as a result. Get a handle to it as
191 // its ownership will be passed and |mock_session_| will be reset.
192 mock_session_.reset(new testing::NiceMock<MockBluetoothDiscoverySession>());
193 MockBluetoothDiscoverySession* session = mock_session_.get();
194 EXPECT_CALL(*mock_adapter_, StartDiscoverySession(testing::_, testing::_))
195 .WillOnce(
196 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback));
197 start_function = setupFunction(new api::BluetoothStartDiscoveryFunction);
198 (void)
199 utils::RunFunctionAndReturnError(start_function.get(), "[]", browser());
201 // End the discovery session. The StopDiscovery function should succeed.
202 testing::Mock::VerifyAndClearExpectations(mock_adapter_);
203 EXPECT_CALL(*session, IsActive()).WillOnce(testing::Return(true));
204 EXPECT_CALL(*session, Stop(testing::_, testing::_))
205 .WillOnce(testing::Invoke(StopDiscoverySessionCallback));
207 // StopDiscovery success will remove the session object, unreferencing the
208 // adapter.
209 scoped_refptr<api::BluetoothStopDiscoveryFunction> stop_function;
210 stop_function = setupFunction(new api::BluetoothStopDiscoveryFunction);
211 (void) utils::RunFunctionAndReturnSingleResult(
212 stop_function.get(), "[]", browser());
214 // Reset the adapter. Simulate failure for stop discovery. The event router
215 // still owns the session. Make it appear inactive.
216 SetUpMockAdapter();
217 EXPECT_CALL(*session, IsActive()).WillOnce(testing::Return(false));
218 stop_function = setupFunction(new api::BluetoothStopDiscoveryFunction);
219 error =
220 utils::RunFunctionAndReturnError(stop_function.get(), "[]", browser());
221 ASSERT_FALSE(error.empty());
222 SetUpMockAdapter();
225 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DiscoveryCallback) {
226 mock_session_.reset(new testing::NiceMock<MockBluetoothDiscoverySession>());
227 MockBluetoothDiscoverySession* session = mock_session_.get();
228 EXPECT_CALL(*mock_adapter_, StartDiscoverySession(testing::_, testing::_))
229 .WillOnce(
230 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback));
231 EXPECT_CALL(*session, IsActive()).WillOnce(testing::Return(true));
232 EXPECT_CALL(*session, Stop(testing::_, testing::_))
233 .WillOnce(testing::Invoke(StopDiscoverySessionCallback));
235 ResultCatcher catcher;
236 catcher.RestrictToBrowserContext(browser()->profile());
238 ExtensionTestMessageListener discovery_started("ready", true);
239 ASSERT_TRUE(LoadExtension(
240 test_data_dir_.AppendASCII("bluetooth/discovery_callback")));
241 EXPECT_TRUE(discovery_started.WaitUntilSatisfied());
243 event_router()->DeviceAdded(mock_adapter_, device1_.get());
245 discovery_started.Reply("go");
246 ExtensionTestMessageListener discovery_stopped("ready", true);
247 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_));
248 EXPECT_TRUE(discovery_stopped.WaitUntilSatisfied());
250 SetUpMockAdapter();
251 event_router()->DeviceAdded(mock_adapter_, device2_.get());
252 discovery_stopped.Reply("go");
254 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
257 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DiscoveryInProgress) {
258 EXPECT_CALL(*mock_adapter_, GetAddress())
259 .WillOnce(testing::Return(kAdapterAddress));
260 EXPECT_CALL(*mock_adapter_, GetName())
261 .WillOnce(testing::Return(kName));
262 EXPECT_CALL(*mock_adapter_, IsPresent())
263 .WillOnce(testing::Return(true));
264 EXPECT_CALL(*mock_adapter_, IsPowered())
265 .WillOnce(testing::Return(true));
267 // Fake that the adapter is discovering
268 EXPECT_CALL(*mock_adapter_, IsDiscovering())
269 .WillOnce(testing::Return(true));
270 event_router()->AdapterDiscoveringChanged(mock_adapter_, true);
272 // Cache a device before the extension starts discovering
273 event_router()->DeviceAdded(mock_adapter_, device1_.get());
275 ResultCatcher catcher;
276 catcher.RestrictToBrowserContext(browser()->profile());
278 mock_session_.reset(new testing::NiceMock<MockBluetoothDiscoverySession>());
279 MockBluetoothDiscoverySession* session = mock_session_.get();
280 EXPECT_CALL(*mock_adapter_, StartDiscoverySession(testing::_, testing::_))
281 .WillOnce(
282 testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback));
283 EXPECT_CALL(*session, IsActive()).WillOnce(testing::Return(true));
284 EXPECT_CALL(*session, Stop(testing::_, testing::_))
285 .WillOnce(testing::Invoke(StopDiscoverySessionCallback));
287 ExtensionTestMessageListener discovery_started("ready", true);
288 ASSERT_TRUE(LoadExtension(
289 test_data_dir_.AppendASCII("bluetooth/discovery_in_progress")));
290 EXPECT_TRUE(discovery_started.WaitUntilSatisfied());
292 // Only this should be received. No additional notification should be sent for
293 // devices discovered before the discovery session started.
294 event_router()->DeviceAdded(mock_adapter_, device2_.get());
296 discovery_started.Reply("go");
297 ExtensionTestMessageListener discovery_stopped("ready", true);
298 EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_));
299 EXPECT_TRUE(discovery_stopped.WaitUntilSatisfied());
301 SetUpMockAdapter();
302 // This should never be received.
303 event_router()->DeviceAdded(mock_adapter_, device2_.get());
304 discovery_stopped.Reply("go");
306 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
309 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, OnAdapterStateChanged) {
310 ResultCatcher catcher;
311 catcher.RestrictToBrowserContext(browser()->profile());
313 // Load and wait for setup
314 ExtensionTestMessageListener listener("ready", true);
315 ASSERT_TRUE(
316 LoadExtension(
317 test_data_dir_.AppendASCII("bluetooth/on_adapter_state_changed")));
318 EXPECT_TRUE(listener.WaitUntilSatisfied());
320 EXPECT_CALL(*mock_adapter_, GetAddress())
321 .WillOnce(testing::Return(kAdapterAddress));
322 EXPECT_CALL(*mock_adapter_, GetName())
323 .WillOnce(testing::Return(kName));
324 EXPECT_CALL(*mock_adapter_, IsPresent())
325 .WillOnce(testing::Return(false));
326 EXPECT_CALL(*mock_adapter_, IsPowered())
327 .WillOnce(testing::Return(false));
328 EXPECT_CALL(*mock_adapter_, IsDiscovering())
329 .WillOnce(testing::Return(false));
330 event_router()->AdapterPoweredChanged(mock_adapter_, false);
332 EXPECT_CALL(*mock_adapter_, GetAddress())
333 .WillOnce(testing::Return(kAdapterAddress));
334 EXPECT_CALL(*mock_adapter_, GetName())
335 .WillOnce(testing::Return(kName));
336 EXPECT_CALL(*mock_adapter_, IsPresent())
337 .WillOnce(testing::Return(true));
338 EXPECT_CALL(*mock_adapter_, IsPowered())
339 .WillOnce(testing::Return(true));
340 EXPECT_CALL(*mock_adapter_, IsDiscovering())
341 .WillOnce(testing::Return(true));
342 event_router()->AdapterPresentChanged(mock_adapter_, true);
344 EXPECT_CALL(*mock_adapter_, GetAddress())
345 .WillOnce(testing::Return(kAdapterAddress));
346 EXPECT_CALL(*mock_adapter_, GetName())
347 .WillOnce(testing::Return(kName));
348 EXPECT_CALL(*mock_adapter_, IsPresent())
349 .WillOnce(testing::Return(true));
350 EXPECT_CALL(*mock_adapter_, IsPowered())
351 .WillOnce(testing::Return(true));
352 EXPECT_CALL(*mock_adapter_, IsDiscovering())
353 .WillOnce(testing::Return(true));
354 event_router()->AdapterDiscoveringChanged(mock_adapter_, true);
356 listener.Reply("go");
358 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
361 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevices) {
362 ResultCatcher catcher;
363 catcher.RestrictToBrowserContext(browser()->profile());
365 BluetoothAdapter::ConstDeviceList devices;
366 devices.push_back(device1_.get());
367 devices.push_back(device2_.get());
369 EXPECT_CALL(*mock_adapter_, GetDevices())
370 .Times(1)
371 .WillRepeatedly(testing::Return(devices));
373 // Load and wait for setup
374 ExtensionTestMessageListener listener("ready", true);
375 ASSERT_TRUE(
376 LoadExtension(test_data_dir_.AppendASCII("bluetooth/get_devices")));
377 EXPECT_TRUE(listener.WaitUntilSatisfied());
379 listener.Reply("go");
381 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
384 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevice) {
385 ResultCatcher catcher;
386 catcher.RestrictToBrowserContext(browser()->profile());
388 EXPECT_CALL(*mock_adapter_, GetDevice(device1_->GetAddress()))
389 .WillOnce(testing::Return(device1_.get()));
390 EXPECT_CALL(*mock_adapter_, GetDevice(device2_->GetAddress()))
391 .Times(1)
392 .WillRepeatedly(testing::Return(static_cast<BluetoothDevice*>(NULL)));
394 // Load and wait for setup
395 ExtensionTestMessageListener listener("ready", true);
396 ASSERT_TRUE(
397 LoadExtension(test_data_dir_.AppendASCII("bluetooth/get_device")));
398 EXPECT_TRUE(listener.WaitUntilSatisfied());
400 listener.Reply("go");
402 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
405 IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DeviceInfo) {
406 ResultCatcher catcher;
407 catcher.RestrictToBrowserContext(browser()->profile());
409 // Set up the first device object to reflect a real-world device.
410 BluetoothAdapter::ConstDeviceList devices;
412 EXPECT_CALL(*device1_.get(), GetAddress())
413 .WillRepeatedly(testing::Return("A4:17:31:00:00:00"));
414 EXPECT_CALL(*device1_.get(), GetDeviceName())
415 .WillRepeatedly(testing::Return("Chromebook Pixel"));
416 EXPECT_CALL(*device1_.get(), GetName())
417 .WillRepeatedly(testing::Return(base::UTF8ToUTF16("Chromebook Pixel")));
418 EXPECT_CALL(*device1_.get(), GetBluetoothClass())
419 .WillRepeatedly(testing::Return(0x080104));
420 EXPECT_CALL(*device1_.get(), GetDeviceType())
421 .WillRepeatedly(testing::Return(BluetoothDevice::DEVICE_COMPUTER));
422 EXPECT_CALL(*device1_.get(), GetVendorIDSource())
423 .WillRepeatedly(testing::Return(BluetoothDevice::VENDOR_ID_BLUETOOTH));
424 EXPECT_CALL(*device1_.get(), GetVendorID())
425 .WillRepeatedly(testing::Return(0x00E0));
426 EXPECT_CALL(*device1_.get(), GetProductID())
427 .WillRepeatedly(testing::Return(0x240A));
428 EXPECT_CALL(*device1_.get(), GetDeviceID())
429 .WillRepeatedly(testing::Return(0x0400));
431 BluetoothDevice::UUIDList uuids;
432 uuids.push_back(BluetoothUUID("1105"));
433 uuids.push_back(BluetoothUUID("1106"));
435 EXPECT_CALL(*device1_.get(), GetUUIDs())
436 .WillOnce(testing::Return(uuids));
438 devices.push_back(device1_.get());
440 // Leave the second largely empty so we can check a device without
441 // available information.
442 devices.push_back(device2_.get());
444 EXPECT_CALL(*mock_adapter_, GetDevices())
445 .Times(1)
446 .WillRepeatedly(testing::Return(devices));
448 // Load and wait for setup
449 ExtensionTestMessageListener listener("ready", true);
450 ASSERT_TRUE(
451 LoadExtension(test_data_dir_.AppendASCII("bluetooth/device_info")));
452 EXPECT_TRUE(listener.WaitUntilSatisfied());
454 listener.Reply("go");
456 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();