bluetooth: browser-side implementation of writeValue.
[chromium-blink-merge.git] / content / shell / browser / layout_test / layout_test_bluetooth_adapter_provider.cc
blobaad6fe5f25b66b485fecd18dd64f7a7537ff2367
1 // Copyright 2015 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 "content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h"
7 #include "device/bluetooth/bluetooth_adapter.h"
8 #include "device/bluetooth/bluetooth_device.h"
9 #include "device/bluetooth/bluetooth_discovery_session.h"
10 #include "device/bluetooth/bluetooth_uuid.h"
11 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
12 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
13 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
14 #include "testing/gmock/include/gmock/gmock.h"
16 using device::BluetoothAdapter;
17 using device::BluetoothAdapterFactory;
18 using device::BluetoothDevice;
19 using device::BluetoothDiscoverySession;
20 using device::BluetoothGattConnection;
21 using device::BluetoothGattService;
22 using device::BluetoothUUID;
23 using device::MockBluetoothAdapter;
24 using device::MockBluetoothDevice;
25 using device::MockBluetoothDiscoverySession;
26 using device::MockBluetoothGattCharacteristic;
27 using device::MockBluetoothGattConnection;
28 using device::MockBluetoothGattService;
29 using testing::Between;
30 using testing::ElementsAre;
31 using testing::Invoke;
32 using testing::NiceMock;
33 using testing::ResultOf;
34 using testing::Return;
35 using testing::WithArgs;
36 using testing::_;
38 namespace {
39 // Bluetooth UUIDs suitable to pass to BluetoothUUID().
40 const char kBatteryServiceUUID[] = "180f";
41 const char kGenericAccessServiceUUID[] = "1800";
42 const char kGenericAttributeServiceUUID[] = "1801";
43 const char kGlucoseServiceUUID[] = "1808";
44 const char kHeartRateServiceUUID[] = "180d";
46 // Invokes Run() on the k-th argument of the function with no arguments.
47 ACTION_TEMPLATE(RunCallback,
48 HAS_1_TEMPLATE_PARAMS(int, k),
49 AND_0_VALUE_PARAMS()) {
50 return ::testing::get<k>(args).Run();
53 // Invokes Run() on the k-th argument of the function with 1 argument.
54 ACTION_TEMPLATE(RunCallback,
55 HAS_1_TEMPLATE_PARAMS(int, k),
56 AND_1_VALUE_PARAMS(p0)) {
57 return ::testing::get<k>(args).Run(p0);
60 // Invokes Run() on the k-th argument of the function with the result
61 // of |func| as an argument.
62 ACTION_TEMPLATE(RunCallbackWithResult,
63 HAS_1_TEMPLATE_PARAMS(int, k),
64 AND_1_VALUE_PARAMS(func)) {
65 return ::testing::get<k>(args).Run(func());
68 // Function to iterate over the adapter's devices and return the one
69 // that matches the address.
70 ACTION_P(GetMockDevice, adapter) {
71 std::string address = arg0;
72 for (BluetoothDevice* device : adapter->GetMockDevices()) {
73 if (device->GetAddress() == address)
74 return device;
76 return NULL;
79 std::set<BluetoothUUID> GetUUIDs(
80 const device::BluetoothDiscoveryFilter* filter) {
81 std::set<BluetoothUUID> result;
82 filter->GetUUIDs(result);
83 return result;
86 } // namespace
88 namespace content {
90 // static
91 scoped_refptr<BluetoothAdapter>
92 LayoutTestBluetoothAdapterProvider::GetBluetoothAdapter(
93 const std::string& fake_adapter_name) {
94 if (fake_adapter_name == "EmptyAdapter")
95 return GetEmptyAdapter();
96 else if (fake_adapter_name == "SingleEmptyDeviceAdapter")
97 return GetSingleEmptyDeviceAdapter();
98 else if (fake_adapter_name == "ConnectableDeviceAdapter")
99 return GetConnectableDeviceAdapter();
100 else if (fake_adapter_name == "UnconnectableDeviceAdapter")
101 return GetUnconnectableDeviceAdapter();
102 else if (fake_adapter_name == "ScanFilterCheckingAdapter")
103 return GetScanFilterCheckingAdapter();
104 else if (fake_adapter_name == "MultiDeviceAdapter")
105 return GetMultiDeviceAdapter();
106 else if (fake_adapter_name == "")
107 return NULL;
109 NOTREACHED() << fake_adapter_name;
110 return NULL;
113 // static
114 scoped_refptr<NiceMock<MockBluetoothAdapter>>
115 LayoutTestBluetoothAdapterProvider::GetEmptyAdapter() {
116 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(
117 new NiceMock<MockBluetoothAdapter>());
119 ON_CALL(*adapter, StartDiscoverySessionWithFilterRaw(_, _, _))
120 .WillByDefault(RunCallbackWithResult<1 /* success_callback */>(
121 []() { return GetDiscoverySession(); }));
123 // Using Invoke allows the adapter returned from this method to be futher
124 // modified and have devices added to it. The call to ::GetDevices will
125 // invoke ::GetConstMockDevices, returning all devices added up to that time.
126 ON_CALL(*adapter, GetDevices())
127 .WillByDefault(
128 Invoke(adapter.get(), &MockBluetoothAdapter::GetConstMockDevices));
130 // The call to ::GetDevice will invoke GetMockDevice which returns a device
131 // matching the address provided if the device was added to the mock.
132 ON_CALL(*adapter, GetDevice(_)).WillByDefault(GetMockDevice(adapter.get()));
134 return adapter.Pass();
137 // static
138 scoped_refptr<NiceMock<MockBluetoothAdapter>>
139 LayoutTestBluetoothAdapterProvider::GetScanFilterCheckingAdapter() {
140 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(
141 new NiceMock<MockBluetoothAdapter>());
143 // This fails the test with an error message listing actual and expected UUIDs
144 // if StartDiscoverySessionWithFilter() is called with the wrong argument.
145 EXPECT_CALL(
146 *adapter,
147 StartDiscoverySessionWithFilterRaw(
148 ResultOf(&GetUUIDs, ElementsAre(BluetoothUUID(kGlucoseServiceUUID),
149 BluetoothUUID(kHeartRateServiceUUID),
150 BluetoothUUID(kBatteryServiceUUID))),
151 _, _))
152 .WillRepeatedly(RunCallbackWithResult<1 /* success_callback */>(
153 []() { return GetDiscoverySession(); }));
155 // Any unexpected call results in the failure callback.
156 ON_CALL(*adapter, StartDiscoverySessionWithFilterRaw(_, _, _))
157 .WillByDefault(RunCallback<2 /* failure_callback */>());
159 scoped_ptr<NiceMock<MockBluetoothDevice>> battery_device =
160 GetEmptyDevice(adapter.get(), "Battery Device");
161 BluetoothDevice::UUIDList battery_uuid_list;
162 battery_uuid_list.push_back(BluetoothUUID(kBatteryServiceUUID));
163 ON_CALL(*battery_device, GetUUIDs()).WillByDefault(Return(battery_uuid_list));
164 adapter->AddMockDevice(battery_device.Pass());
166 // This adapter isn't modified further, so we just return a hard-coded list.
167 ON_CALL(*adapter, GetDevices())
168 .WillByDefault(Return(adapter->GetConstMockDevices()));
170 return adapter.Pass();
173 // static
174 scoped_refptr<NiceMock<MockBluetoothAdapter>>
175 LayoutTestBluetoothAdapterProvider::GetSingleEmptyDeviceAdapter() {
176 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(GetEmptyAdapter());
178 adapter->AddMockDevice(GetEmptyDevice(adapter.get()));
180 return adapter.Pass();
183 // static
184 scoped_refptr<NiceMock<MockBluetoothAdapter>>
185 LayoutTestBluetoothAdapterProvider::GetMultiDeviceAdapter() {
186 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(GetEmptyAdapter());
188 scoped_ptr<NiceMock<MockBluetoothDevice>> heart_rate_device =
189 GetEmptyDevice(adapter.get(), "Heart Rate Device");
190 BluetoothDevice::UUIDList heart_rate_uuid_list;
191 heart_rate_uuid_list.push_back(BluetoothUUID(kHeartRateServiceUUID));
192 heart_rate_uuid_list.push_back(BluetoothUUID(kGenericAccessServiceUUID));
193 heart_rate_uuid_list.push_back(BluetoothUUID(kGenericAttributeServiceUUID));
194 ON_CALL(*heart_rate_device, GetUUIDs())
195 .WillByDefault(Return(heart_rate_uuid_list));
196 adapter->AddMockDevice(heart_rate_device.Pass());
198 scoped_ptr<NiceMock<MockBluetoothDevice>> glucose_device =
199 GetEmptyDevice(adapter.get(), "Glucose Device");
200 BluetoothDevice::UUIDList glucose_uuid_list;
201 glucose_uuid_list.push_back(BluetoothUUID(kGlucoseServiceUUID));
202 glucose_uuid_list.push_back(BluetoothUUID(kGenericAccessServiceUUID));
203 glucose_uuid_list.push_back(BluetoothUUID(kGenericAttributeServiceUUID));
204 ON_CALL(*glucose_device, GetUUIDs()).WillByDefault(Return(glucose_uuid_list));
205 adapter->AddMockDevice(glucose_device.Pass());
207 return adapter.Pass();
210 // static
211 scoped_refptr<NiceMock<MockBluetoothAdapter>>
212 LayoutTestBluetoothAdapterProvider::GetConnectableDeviceAdapter() {
213 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(GetEmptyAdapter());
215 adapter->AddMockDevice(GetConnectableDevice(adapter.get()));
217 return adapter.Pass();
220 // static
221 scoped_refptr<NiceMock<MockBluetoothAdapter>>
222 LayoutTestBluetoothAdapterProvider::GetUnconnectableDeviceAdapter() {
223 scoped_refptr<NiceMock<MockBluetoothAdapter>> adapter(GetEmptyAdapter());
225 adapter->AddMockDevice(GetUnconnectableDevice(adapter.get()));
227 return adapter.Pass();
230 // static
231 scoped_ptr<NiceMock<MockBluetoothDiscoverySession>>
232 LayoutTestBluetoothAdapterProvider::GetDiscoverySession() {
233 scoped_ptr<NiceMock<MockBluetoothDiscoverySession>> discovery_session(
234 new NiceMock<MockBluetoothDiscoverySession>());
236 ON_CALL(*discovery_session, Stop(_, _))
237 .WillByDefault(RunCallback<0 /* success_callback */>());
239 return discovery_session.Pass();
242 // static
243 scoped_ptr<NiceMock<MockBluetoothDevice>>
244 LayoutTestBluetoothAdapterProvider::GetEmptyDevice(
245 MockBluetoothAdapter* adapter,
246 const std::string& device_name) {
247 scoped_ptr<NiceMock<MockBluetoothDevice>> empty_device(
248 new NiceMock<MockBluetoothDevice>(
249 adapter, 0x1F00 /* Bluetooth Class */, device_name,
250 device_name + " instanceID", true /* Paired */,
251 true /* Connected */));
253 ON_CALL(*empty_device, GetVendorIDSource())
254 .WillByDefault(Return(BluetoothDevice::VENDOR_ID_BLUETOOTH));
255 ON_CALL(*empty_device, GetVendorID()).WillByDefault(Return(0xFFFF));
256 ON_CALL(*empty_device, GetProductID()).WillByDefault(Return(1));
257 ON_CALL(*empty_device, GetDeviceID()).WillByDefault(Return(2));
259 BluetoothDevice::UUIDList list;
260 list.push_back(BluetoothUUID(kGenericAccessServiceUUID));
261 list.push_back(BluetoothUUID(kGenericAttributeServiceUUID));
262 ON_CALL(*empty_device, GetUUIDs()).WillByDefault(Return(list));
264 scoped_ptr<NiceMock<MockBluetoothGattService>> generic_access(
265 GetGattService(empty_device.get(), kGenericAccessServiceUUID));
266 scoped_ptr<NiceMock<MockBluetoothGattCharacteristic>>
267 device_name_characteristic(GetGattCharacteristic(
268 generic_access.get(), "2A00" /* Device Name */));
270 std::vector<uint8_t> device_name_value(device_name.begin(),
271 device_name.end());
272 ON_CALL(*device_name_characteristic, ReadRemoteCharacteristic(_, _))
273 .WillByDefault(RunCallback<0>(device_name_value));
275 ON_CALL(*device_name_characteristic, WriteRemoteCharacteristic(_, _, _))
276 .WillByDefault(RunCallback<2 /* error callback */>(
277 BluetoothGattService::GATT_ERROR_NOT_PERMITTED));
279 generic_access->AddMockCharacteristic(device_name_characteristic.Pass());
281 scoped_ptr<NiceMock<MockBluetoothGattCharacteristic>> reconnection_address(
282 GetGattCharacteristic(generic_access.get(),
283 "2A03" /* Reconnection Address */));
285 ON_CALL(*reconnection_address, ReadRemoteCharacteristic(_, _))
286 .WillByDefault(
287 RunCallback<1>(BluetoothGattService::GATT_ERROR_NOT_PERMITTED));
289 ON_CALL(*reconnection_address, WriteRemoteCharacteristic(_, _, _))
290 .WillByDefault(RunCallback<1 /* success callback */>());
292 generic_access->AddMockCharacteristic(reconnection_address.Pass());
294 empty_device->AddMockService(generic_access.Pass());
296 // Using Invoke allows the device returned from this method to be futher
297 // modified and have more services added to it. The call to ::GetGattServices
298 // will invoke ::GetMockServices, returning all services added up to that
299 // time.
300 ON_CALL(*empty_device, GetGattServices())
301 .WillByDefault(
302 Invoke(empty_device.get(), &MockBluetoothDevice::GetMockServices));
304 // The call to BluetoothDevice::GetGattService will invoke ::GetMockService
305 // which returns a service matching the identifier provided if the service
306 // was added to the mock.
307 ON_CALL(*empty_device, GetGattService(_))
308 .WillByDefault(
309 Invoke(empty_device.get(), &MockBluetoothDevice::GetMockService));
311 return empty_device.Pass();
314 // static
315 scoped_ptr<NiceMock<MockBluetoothDevice>>
316 LayoutTestBluetoothAdapterProvider::GetConnectableDevice(
317 MockBluetoothAdapter* adapter) {
318 scoped_ptr<NiceMock<MockBluetoothDevice>> device(GetEmptyDevice(adapter));
320 BluetoothDevice* device_ptr = device.get();
322 ON_CALL(*device, CreateGattConnection(_, _))
323 .WillByDefault(
324 RunCallbackWithResult<0 /* success_callback */>([device_ptr]() {
325 return make_scoped_ptr(new NiceMock<MockBluetoothGattConnection>(
326 device_ptr->GetAddress()));
327 }));
329 return device.Pass();
332 // static
333 scoped_ptr<NiceMock<MockBluetoothDevice>>
334 LayoutTestBluetoothAdapterProvider::GetUnconnectableDevice(
335 MockBluetoothAdapter* adapter) {
336 scoped_ptr<NiceMock<MockBluetoothDevice>> device(GetEmptyDevice(adapter));
338 ON_CALL(*device, CreateGattConnection(_, _))
339 .WillByDefault(
340 RunCallback<1 /* error_callback */>(BluetoothDevice::ERROR_FAILED));
342 return device.Pass();
345 // static
346 scoped_ptr<NiceMock<MockBluetoothGattService>>
347 LayoutTestBluetoothAdapterProvider::GetGattService(MockBluetoothDevice* device,
348 const std::string& uuid) {
349 scoped_ptr<NiceMock<MockBluetoothGattService>> service(
350 new NiceMock<MockBluetoothGattService>(
351 device, uuid /* identifier */, BluetoothUUID(uuid),
352 true /* is_primary */, false /* is_local */));
354 ON_CALL(*service, GetCharacteristics())
355 .WillByDefault(Invoke(service.get(),
356 &MockBluetoothGattService::GetMockCharacteristics));
358 ON_CALL(*service, GetCharacteristic(_))
359 .WillByDefault(Invoke(service.get(),
360 &MockBluetoothGattService::GetMockCharacteristic));
362 return service.Pass();
365 // static
366 scoped_ptr<NiceMock<MockBluetoothGattCharacteristic>>
367 LayoutTestBluetoothAdapterProvider::GetGattCharacteristic(
368 MockBluetoothGattService* service,
369 const std::string& uuid) {
370 return make_scoped_ptr(new NiceMock<MockBluetoothGattCharacteristic>(
371 service, uuid /* identifier */, BluetoothUUID(uuid), false /* is_local */,
372 NULL /* properties */, NULL /* permissions */));
375 } // namespace content