|
| 1 | +'use strict' |
| 2 | + |
| 3 | +// Convert `manufacturerData` to an array of bluetooth.BluetoothManufacturerData |
| 4 | +// defined in |
| 5 | +// https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-bidi-definitions. |
| 6 | +function convertToBidiManufacturerData(manufacturerData) { |
| 7 | + const bidiManufacturerData = []; |
| 8 | + for (const key in manufacturerData) { |
| 9 | + bidiManufacturerData.push( |
| 10 | + {key: parseInt(key), data: btoa(manufacturerData[key].buffer)}) |
| 11 | + } |
| 12 | + return bidiManufacturerData; |
| 13 | +} |
| 14 | + |
| 15 | +class FakeBluetooth { |
| 16 | + constructor() { |
| 17 | + this.fake_central_ = null; |
| 18 | + } |
| 19 | + |
| 20 | + // Returns a promise that resolves with a FakeCentral that clients can use |
| 21 | + // to simulate events that a device in the Central/Observer role would |
| 22 | + // receive as well as monitor the operations performed by the device in the |
| 23 | + // Central/Observer role. |
| 24 | + // |
| 25 | + // A "Central" object would allow its clients to receive advertising events |
| 26 | + // and initiate connections to peripherals i.e. operations of two roles |
| 27 | + // defined by the Bluetooth Spec: Observer and Central. |
| 28 | + // See Bluetooth 4.2 Vol 3 Part C 2.2.2 "Roles when Operating over an |
| 29 | + // LE Physical Transport". |
| 30 | + async simulateCentral({state}) { |
| 31 | + if (this.fake_central_) { |
| 32 | + throw 'simulateCentral() should only be called once'; |
| 33 | + } |
| 34 | + |
| 35 | + await test_driver.bidi.bluetooth.simulate_adapter({state: state}); |
| 36 | + this.fake_central_ = new FakeCentral(); |
| 37 | + return this.fake_central_; |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +// FakeCentral allows clients to simulate events that a device in the |
| 42 | +// Central/Observer role would receive as well as monitor the operations |
| 43 | +// performed by the device in the Central/Observer role. |
| 44 | +class FakeCentral { |
| 45 | + constructor() { |
| 46 | + this.peripherals_ = new Map(); |
| 47 | + } |
| 48 | + |
| 49 | + // Simulates a peripheral with |address|, |name|, |manufacturerData| and |
| 50 | + // |known_service_uuids| that has already been connected to the system. If the |
| 51 | + // peripheral existed already it updates its name, manufacturer data, and |
| 52 | + // known UUIDs. |known_service_uuids| should be an array of |
| 53 | + // BluetoothServiceUUIDs |
| 54 | + // https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid |
| 55 | + // |
| 56 | + // Platforms offer methods to retrieve devices that have already been |
| 57 | + // connected to the system or weren't connected through the UA e.g. a user |
| 58 | + // connected a peripheral through the system's settings. This method is |
| 59 | + // intended to simulate peripherals that those methods would return. |
| 60 | + async simulatePreconnectedPeripheral( |
| 61 | + {address, name, manufacturerData = {}, knownServiceUUIDs = []}) { |
| 62 | + await test_driver.bidi.bluetooth.simulate_preconnected_peripheral({ |
| 63 | + address: address, |
| 64 | + name: name, |
| 65 | + manufacturerData: convertToBidiManufacturerData(manufacturerData), |
| 66 | + knownServiceUuids: knownServiceUUIDs |
| 67 | + }); |
| 68 | + |
| 69 | + return this.fetchOrCreatePeripheral_(address); |
| 70 | + } |
| 71 | + |
| 72 | + // Create a fake_peripheral object from the given address. |
| 73 | + fetchOrCreatePeripheral_(address) { |
| 74 | + let peripheral = this.peripherals_.get(address); |
| 75 | + if (peripheral === undefined) { |
| 76 | + peripheral = new FakePeripheral(address); |
| 77 | + this.peripherals_.set(address, peripheral); |
| 78 | + } |
| 79 | + return peripheral; |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +class FakePeripheral { |
| 84 | + constructor(address) { |
| 85 | + this.address = address; |
| 86 | + } |
| 87 | +} |
| 88 | + |
| 89 | +function initializeBluetoothBidiResources() { |
| 90 | + navigator.bluetooth.test = new FakeBluetooth(); |
| 91 | +} |
0 commit comments