mirror of
https://github.com/servo/servo.git
synced 2025-09-07 21:48:21 +01:00
Update web-platform-tests to revision be5419e845d39089ba6dc338c1bd0fa279108317
This commit is contained in:
parent
aa199307c8
commit
2b6f573eb5
3440 changed files with 109438 additions and 41750 deletions
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1 @@
|
|||
Content-Type: text/javascript; charset=utf-8
|
|
@ -0,0 +1,264 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var mojomId = 'content/test/data/mojo_layouttest_test.mojom';
|
||||
if (mojo.internal.isMojomLoaded(mojomId)) {
|
||||
console.warn('The following mojom is loaded multiple times: ' + mojomId);
|
||||
return;
|
||||
}
|
||||
mojo.internal.markMojomLoaded(mojomId);
|
||||
|
||||
// TODO(yzshen): Define these aliases to minimize the differences between the
|
||||
// old/new modes. Remove them when the old mode goes away.
|
||||
var bindings = mojo;
|
||||
var associatedBindings = mojo;
|
||||
var codec = mojo.internal;
|
||||
var validator = mojo.internal;
|
||||
|
||||
var exports = mojo.internal.exposeNamespace('content.mojom');
|
||||
|
||||
|
||||
|
||||
function MojoLayoutTestHelper_Reverse_Params(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
MojoLayoutTestHelper_Reverse_Params.prototype.initDefaults_ = function() {
|
||||
this.message = null;
|
||||
};
|
||||
MojoLayoutTestHelper_Reverse_Params.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_Params.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate MojoLayoutTestHelper_Reverse_Params.message
|
||||
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_Params.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
MojoLayoutTestHelper_Reverse_Params.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new MojoLayoutTestHelper_Reverse_Params();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.message = decoder.decodeStruct(codec.String);
|
||||
return val;
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_Params.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(MojoLayoutTestHelper_Reverse_Params.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeStruct(codec.String, val.message);
|
||||
};
|
||||
function MojoLayoutTestHelper_Reverse_ResponseParams(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initDefaults_ = function() {
|
||||
this.reversed = null;
|
||||
};
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate MojoLayoutTestHelper_Reverse_ResponseParams.reversed
|
||||
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new MojoLayoutTestHelper_Reverse_ResponseParams();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.reversed = decoder.decodeStruct(codec.String);
|
||||
return val;
|
||||
};
|
||||
|
||||
MojoLayoutTestHelper_Reverse_ResponseParams.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeStruct(codec.String, val.reversed);
|
||||
};
|
||||
var kMojoLayoutTestHelper_Reverse_Name = 0;
|
||||
|
||||
function MojoLayoutTestHelperPtr(handleOrPtrInfo) {
|
||||
this.ptr = new bindings.InterfacePtrController(MojoLayoutTestHelper,
|
||||
handleOrPtrInfo);
|
||||
}
|
||||
|
||||
function MojoLayoutTestHelperAssociatedPtr(associatedInterfacePtrInfo) {
|
||||
this.ptr = new associatedBindings.AssociatedInterfacePtrController(
|
||||
MojoLayoutTestHelper, associatedInterfacePtrInfo);
|
||||
}
|
||||
|
||||
MojoLayoutTestHelperAssociatedPtr.prototype =
|
||||
Object.create(MojoLayoutTestHelperPtr.prototype);
|
||||
MojoLayoutTestHelperAssociatedPtr.prototype.constructor =
|
||||
MojoLayoutTestHelperAssociatedPtr;
|
||||
|
||||
function MojoLayoutTestHelperProxy(receiver) {
|
||||
this.receiver_ = receiver;
|
||||
}
|
||||
MojoLayoutTestHelperPtr.prototype.reverse = function() {
|
||||
return MojoLayoutTestHelperProxy.prototype.reverse
|
||||
.apply(this.ptr.getProxy(), arguments);
|
||||
};
|
||||
|
||||
MojoLayoutTestHelperProxy.prototype.reverse = function(message) {
|
||||
var params = new MojoLayoutTestHelper_Reverse_Params();
|
||||
params.message = message;
|
||||
return new Promise(function(resolve, reject) {
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kMojoLayoutTestHelper_Reverse_Name,
|
||||
codec.align(MojoLayoutTestHelper_Reverse_Params.encodedSize),
|
||||
codec.kMessageExpectsResponse, 0);
|
||||
builder.encodeStruct(MojoLayoutTestHelper_Reverse_Params, params);
|
||||
var message = builder.finish();
|
||||
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
var responseParams =
|
||||
reader.decodeStruct(MojoLayoutTestHelper_Reverse_ResponseParams);
|
||||
resolve(responseParams);
|
||||
}).catch(function(result) {
|
||||
reject(Error("Connection error: " + result));
|
||||
});
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
function MojoLayoutTestHelperStub(delegate) {
|
||||
this.delegate_ = delegate;
|
||||
}
|
||||
MojoLayoutTestHelperStub.prototype.reverse = function(message) {
|
||||
return this.delegate_ && this.delegate_.reverse && this.delegate_.reverse(message);
|
||||
}
|
||||
|
||||
MojoLayoutTestHelperStub.prototype.accept = function(message) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
switch (reader.messageName) {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
MojoLayoutTestHelperStub.prototype.acceptWithResponder =
|
||||
function(message, responder) {
|
||||
var reader = new codec.MessageReader(message);
|
||||
switch (reader.messageName) {
|
||||
case kMojoLayoutTestHelper_Reverse_Name:
|
||||
var params = reader.decodeStruct(MojoLayoutTestHelper_Reverse_Params);
|
||||
this.reverse(params.message).then(function(response) {
|
||||
var responseParams =
|
||||
new MojoLayoutTestHelper_Reverse_ResponseParams();
|
||||
responseParams.reversed = response.reversed;
|
||||
var builder = new codec.MessageV1Builder(
|
||||
kMojoLayoutTestHelper_Reverse_Name,
|
||||
codec.align(MojoLayoutTestHelper_Reverse_ResponseParams.encodedSize),
|
||||
codec.kMessageIsResponse, reader.requestID);
|
||||
builder.encodeStruct(MojoLayoutTestHelper_Reverse_ResponseParams,
|
||||
responseParams);
|
||||
var message = builder.finish();
|
||||
responder.accept(message);
|
||||
});
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function validateMojoLayoutTestHelperRequest(messageValidator) {
|
||||
var message = messageValidator.message;
|
||||
var paramsClass = null;
|
||||
switch (message.getName()) {
|
||||
case kMojoLayoutTestHelper_Reverse_Name:
|
||||
if (message.expectsResponse())
|
||||
paramsClass = MojoLayoutTestHelper_Reverse_Params;
|
||||
break;
|
||||
}
|
||||
if (paramsClass === null)
|
||||
return validator.validationError.NONE;
|
||||
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
|
||||
}
|
||||
|
||||
function validateMojoLayoutTestHelperResponse(messageValidator) {
|
||||
var message = messageValidator.message;
|
||||
var paramsClass = null;
|
||||
switch (message.getName()) {
|
||||
case kMojoLayoutTestHelper_Reverse_Name:
|
||||
if (message.isResponse())
|
||||
paramsClass = MojoLayoutTestHelper_Reverse_ResponseParams;
|
||||
break;
|
||||
}
|
||||
if (paramsClass === null)
|
||||
return validator.validationError.NONE;
|
||||
return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
|
||||
}
|
||||
|
||||
var MojoLayoutTestHelper = {
|
||||
name: 'content::mojom::MojoLayoutTestHelper',
|
||||
kVersion: 0,
|
||||
ptrClass: MojoLayoutTestHelperPtr,
|
||||
proxyClass: MojoLayoutTestHelperProxy,
|
||||
stubClass: MojoLayoutTestHelperStub,
|
||||
validateRequest: validateMojoLayoutTestHelperRequest,
|
||||
validateResponse: validateMojoLayoutTestHelperResponse,
|
||||
};
|
||||
MojoLayoutTestHelperStub.prototype.validator = validateMojoLayoutTestHelperRequest;
|
||||
MojoLayoutTestHelperProxy.prototype.validator = validateMojoLayoutTestHelperResponse;
|
||||
exports.MojoLayoutTestHelper = MojoLayoutTestHelper;
|
||||
exports.MojoLayoutTestHelperPtr = MojoLayoutTestHelperPtr;
|
||||
exports.MojoLayoutTestHelperAssociatedPtr = MojoLayoutTestHelperAssociatedPtr;
|
||||
})();
|
|
@ -0,0 +1 @@
|
|||
Content-Type: text/javascript; charset=utf-8
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var mojomId = 'device/bluetooth/public/interfaces/uuid.mojom';
|
||||
if (mojo.internal.isMojomLoaded(mojomId)) {
|
||||
console.warn('The following mojom is loaded multiple times: ' + mojomId);
|
||||
return;
|
||||
}
|
||||
mojo.internal.markMojomLoaded(mojomId);
|
||||
|
||||
// TODO(yzshen): Define these aliases to minimize the differences between the
|
||||
// old/new modes. Remove them when the old mode goes away.
|
||||
var bindings = mojo;
|
||||
var associatedBindings = mojo;
|
||||
var codec = mojo.internal;
|
||||
var validator = mojo.internal;
|
||||
|
||||
var exports = mojo.internal.exposeNamespace('bluetooth.mojom');
|
||||
|
||||
|
||||
|
||||
function UUID(values) {
|
||||
this.initDefaults_();
|
||||
this.initFields_(values);
|
||||
}
|
||||
|
||||
|
||||
UUID.prototype.initDefaults_ = function() {
|
||||
this.uuid = null;
|
||||
};
|
||||
UUID.prototype.initFields_ = function(fields) {
|
||||
for(var field in fields) {
|
||||
if (this.hasOwnProperty(field))
|
||||
this[field] = fields[field];
|
||||
}
|
||||
};
|
||||
|
||||
UUID.validate = function(messageValidator, offset) {
|
||||
var err;
|
||||
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
var kVersionSizes = [
|
||||
{version: 0, numBytes: 16}
|
||||
];
|
||||
err = messageValidator.validateStructVersion(offset, kVersionSizes);
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
|
||||
// validate UUID.uuid
|
||||
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
|
||||
if (err !== validator.validationError.NONE)
|
||||
return err;
|
||||
|
||||
return validator.validationError.NONE;
|
||||
};
|
||||
|
||||
UUID.encodedSize = codec.kStructHeaderSize + 8;
|
||||
|
||||
UUID.decode = function(decoder) {
|
||||
var packed;
|
||||
var val = new UUID();
|
||||
var numberOfBytes = decoder.readUint32();
|
||||
var version = decoder.readUint32();
|
||||
val.uuid = decoder.decodeStruct(codec.String);
|
||||
return val;
|
||||
};
|
||||
|
||||
UUID.encode = function(encoder, val) {
|
||||
var packed;
|
||||
encoder.writeUint32(UUID.encodedSize);
|
||||
encoder.writeUint32(0);
|
||||
encoder.encodeStruct(codec.String, val.uuid);
|
||||
};
|
||||
exports.UUID = UUID;
|
||||
})();
|
|
@ -0,0 +1 @@
|
|||
Content-Type: text/javascript; charset=utf-8
|
|
@ -0,0 +1,370 @@
|
|||
'use strict';
|
||||
|
||||
function toMojoCentralState(state) {
|
||||
switch (state) {
|
||||
case 'absent':
|
||||
return bluetooth.mojom.CentralState.ABSENT;
|
||||
case 'powered-off':
|
||||
return bluetooth.mojom.CentralState.POWERED_OFF;
|
||||
case 'powered-on':
|
||||
return bluetooth.mojom.CentralState.POWERED_ON;
|
||||
default:
|
||||
throw `Unsupported value ${state} for state.`;
|
||||
}
|
||||
}
|
||||
|
||||
// Mapping of the property names of
|
||||
// BluetoothCharacteristicProperties defined in
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#characteristicproperties
|
||||
// to property names of the CharacteristicProperties mojo struct.
|
||||
const CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO = {
|
||||
broadcast: 'broadcast',
|
||||
read: 'read',
|
||||
write_without_response: 'write_without_response',
|
||||
write: 'write',
|
||||
notify: 'notify',
|
||||
indicate: 'indicate',
|
||||
authenticatedSignedWrites: 'authenticated_signed_writes',
|
||||
extended_properties: 'extended_properties',
|
||||
};
|
||||
|
||||
function ArrayToMojoCharacteristicProperties(arr) {
|
||||
let struct = new bluetooth.mojom.CharacteristicProperties();
|
||||
|
||||
arr.forEach(val => {
|
||||
let mojo_property =
|
||||
CHARACTERISTIC_PROPERTIES_WEB_TO_MOJO[val];
|
||||
|
||||
if (struct.hasOwnProperty(mojo_property))
|
||||
struct[mojo_property] = true;
|
||||
else
|
||||
throw `Invalid member '${val}' for CharacteristicProperties`;
|
||||
});
|
||||
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
class FakeBluetooth {
|
||||
constructor() {
|
||||
this.fake_bluetooth_ptr_ = new bluetooth.mojom.FakeBluetoothPtr();
|
||||
Mojo.bindInterface(bluetooth.mojom.FakeBluetooth.name,
|
||||
mojo.makeRequest(this.fake_bluetooth_ptr_).handle, "process");
|
||||
}
|
||||
|
||||
// Set it to indicate whether the platform supports BLE. For example,
|
||||
// Windows 7 is a platform that doesn't support Low Energy. On the other
|
||||
// hand Windows 10 is a platform that does support LE, even if there is no
|
||||
// Bluetooth radio present.
|
||||
async setLESupported(supported) {
|
||||
if (typeof supported !== 'boolean') throw 'Type Not Supported';
|
||||
await this.fake_bluetooth_ptr_.setLESupported(supported);
|
||||
}
|
||||
|
||||
// Returns a promise that resolves with a FakeCentral that clients can use
|
||||
// to simulate events that a device in the Central/Observer role would
|
||||
// receive as well as monitor the operations performed by the device in the
|
||||
// Central/Observer role.
|
||||
// Calls sets LE as supported.
|
||||
//
|
||||
// A "Central" object would allow its clients to receive advertising events
|
||||
// and initiate connections to peripherals i.e. operations of two roles
|
||||
// defined by the Bluetooth Spec: Observer and Central.
|
||||
// See Bluetooth 4.2 Vol 3 Part C 2.2.2 "Roles when Operating over an
|
||||
// LE Physical Transport".
|
||||
async simulateCentral({state}) {
|
||||
await this.setLESupported(true);
|
||||
|
||||
let {fakeCentral: fake_central_ptr} =
|
||||
await this.fake_bluetooth_ptr_.simulateCentral(
|
||||
toMojoCentralState(state));
|
||||
return new FakeCentral(fake_central_ptr);
|
||||
}
|
||||
|
||||
// Returns true if there are no pending responses.
|
||||
async allResponsesConsumed() {
|
||||
let {consumed} = await this.fake_bluetooth_ptr_.allResponsesConsumed();
|
||||
return consumed;
|
||||
}
|
||||
}
|
||||
|
||||
// FakeCentral allows clients to simulate events that a device in the
|
||||
// Central/Observer role would receive as well as monitor the operations
|
||||
// performed by the device in the Central/Observer role.
|
||||
class FakeCentral {
|
||||
constructor(fake_central_ptr) {
|
||||
this.fake_central_ptr_ = fake_central_ptr;
|
||||
this.peripherals_ = new Map();
|
||||
}
|
||||
|
||||
// Simulates a peripheral with |address|, |name| and |known_service_uuids|
|
||||
// that has already been connected to the system. If the peripheral existed
|
||||
// already it updates its name and known UUIDs. |known_service_uuids| should
|
||||
// be an array of BluetoothServiceUUIDs
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid
|
||||
//
|
||||
// Platforms offer methods to retrieve devices that have already been
|
||||
// connected to the system or weren't connected through the UA e.g. a user
|
||||
// connected a peripheral through the system's settings. This method is
|
||||
// intended to simulate peripherals that those methods would return.
|
||||
async simulatePreconnectedPeripheral({
|
||||
address, name, knownServiceUUIDs = []}) {
|
||||
|
||||
// Canonicalize and convert to mojo UUIDs.
|
||||
knownServiceUUIDs.forEach((val, i, arr) => {
|
||||
knownServiceUUIDs[i] = {uuid: BluetoothUUID.getService(val)};
|
||||
});
|
||||
|
||||
await this.fake_central_ptr_.simulatePreconnectedPeripheral(
|
||||
address, name, knownServiceUUIDs);
|
||||
|
||||
let peripheral = this.peripherals_.get(address);
|
||||
if (peripheral === undefined) {
|
||||
peripheral = new FakePeripheral(address, this.fake_central_ptr_);
|
||||
this.peripherals_.set(address, peripheral);
|
||||
}
|
||||
|
||||
return peripheral;
|
||||
}
|
||||
}
|
||||
|
||||
class FakePeripheral {
|
||||
constructor(address, fake_central_ptr) {
|
||||
this.address = address;
|
||||
this.fake_central_ptr_ = fake_central_ptr;
|
||||
}
|
||||
|
||||
// Adds a fake GATT Service with |uuid| to be discovered when discovering
|
||||
// the peripheral's GATT Attributes. Returns a FakeRemoteGATTService
|
||||
// corresponding to this service. |uuid| should be a BluetoothServiceUUIDs
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid
|
||||
async addFakeService({uuid}) {
|
||||
let {serviceId: service_id} = await this.fake_central_ptr_.addFakeService(
|
||||
this.address, {uuid: BluetoothUUID.getService(uuid)});
|
||||
|
||||
if (service_id === null) throw 'addFakeService failed';
|
||||
|
||||
return new FakeRemoteGATTService(
|
||||
service_id, this.address, this.fake_central_ptr_);
|
||||
}
|
||||
|
||||
// Sets the next GATT Connection request response to |code|. |code| could be
|
||||
// an HCI Error Code from BT 4.2 Vol 2 Part D 1.3 List Of Error Codes or a
|
||||
// number outside that range returned by specific platforms e.g. Android
|
||||
// returns 0x101 to signal a GATT failure
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE
|
||||
async setNextGATTConnectionResponse({code}) {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextGATTConnectionResponse(
|
||||
this.address, code);
|
||||
|
||||
if (success !== true) throw 'setNextGATTConnectionResponse failed.';
|
||||
}
|
||||
|
||||
// Sets the next GATT Discovery request response for peripheral with
|
||||
// |address| to |code|. |code| could be an HCI Error Code from
|
||||
// BT 4.2 Vol 2 Part D 1.3 List Of Error Codes or a number outside that
|
||||
// range returned by specific platforms e.g. Android returns 0x101 to signal
|
||||
// a GATT failure
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE
|
||||
//
|
||||
// The following procedures defined at BT 4.2 Vol 3 Part G Section 4.
|
||||
// "GATT Feature Requirements" are used to discover attributes of the
|
||||
// GATT Server:
|
||||
// - Primary Service Discovery
|
||||
// - Relationship Discovery
|
||||
// - Characteristic Discovery
|
||||
// - Characteristic Descriptor Discovery
|
||||
// This method aims to simulate the response once all of these procedures
|
||||
// have completed or if there was an error during any of them.
|
||||
async setNextGATTDiscoveryResponse({code}) {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextGATTDiscoveryResponse(
|
||||
this.address, code);
|
||||
|
||||
if (success !== true) throw 'setNextGATTDiscoveryResponse failed.';
|
||||
}
|
||||
|
||||
// Simulates a GATT disconnection from the peripheral with |address|.
|
||||
async simulateGATTDisconnection() {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.simulateGATTDisconnection(this.address);
|
||||
|
||||
if (success !== true) throw 'simulateGATTDisconnection failed.';
|
||||
}
|
||||
|
||||
// Simulates an Indication from the peripheral's GATT `Service Changed`
|
||||
// Characteristic from BT 4.2 Vol 3 Part G 7.1. This Indication is signaled
|
||||
// when services, characteristics, or descriptors are changed, added, or
|
||||
// removed.
|
||||
//
|
||||
// The value for `Service Changed` is a range of attribute handles that have
|
||||
// changed. However, this testing specification works at an abstracted
|
||||
// level and does not expose setting attribute handles when adding
|
||||
// attributes. Consequently, this simulate method should include the full
|
||||
// range of all the peripheral's attribute handle values.
|
||||
async simulateGATTServicesChanged() {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.simulateGATTServicesChanged(this.address);
|
||||
|
||||
if (success !== true) throw 'simulateGATTServicesChanged failed.';
|
||||
}
|
||||
}
|
||||
|
||||
class FakeRemoteGATTService {
|
||||
constructor(service_id, peripheral_address, fake_central_ptr) {
|
||||
this.service_id_ = service_id;
|
||||
this.peripheral_address_ = peripheral_address;
|
||||
this.fake_central_ptr_ = fake_central_ptr;
|
||||
}
|
||||
|
||||
// Adds a fake GATT Characteristic with |uuid| and |properties|
|
||||
// to this fake service. The characteristic will be found when discovering
|
||||
// the peripheral's GATT Attributes. Returns a FakeRemoteGATTCharacteristic
|
||||
// corresponding to the added characteristic.
|
||||
async addFakeCharacteristic({uuid, properties}) {
|
||||
let {characteristicId: characteristic_id} =
|
||||
await this.fake_central_ptr_.addFakeCharacteristic(
|
||||
{uuid: BluetoothUUID.getCharacteristic(uuid)},
|
||||
ArrayToMojoCharacteristicProperties(properties),
|
||||
this.service_id_,
|
||||
this.peripheral_address_);
|
||||
|
||||
if (characteristic_id === null) throw 'addFakeCharacteristic failed';
|
||||
|
||||
return new FakeRemoteGATTCharacteristic(
|
||||
characteristic_id, this.service_id_,
|
||||
this.peripheral_address_, this.fake_central_ptr_);
|
||||
}
|
||||
}
|
||||
|
||||
class FakeRemoteGATTCharacteristic {
|
||||
constructor(characteristic_id, service_id, peripheral_address,
|
||||
fake_central_ptr) {
|
||||
this.ids_ = [characteristic_id, service_id, peripheral_address];
|
||||
this.descriptors_ = [];
|
||||
this.fake_central_ptr_ = fake_central_ptr;
|
||||
}
|
||||
|
||||
// Adds a fake GATT Descriptor with |uuid| to be discovered when
|
||||
// discovering the peripheral's GATT Attributes. Returns a
|
||||
// FakeRemoteGATTDescriptor corresponding to this descriptor. |uuid| should
|
||||
// be a BluetoothDescriptorUUID
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothdescriptoruuid
|
||||
async addFakeDescriptor({uuid}) {
|
||||
let {descriptorId: descriptor_id} =
|
||||
await this.fake_central_ptr_.addFakeDescriptor(
|
||||
{uuid: BluetoothUUID.getDescriptor(uuid)}, ...this.ids_);
|
||||
|
||||
if (descriptor_id === null) throw 'addFakeDescriptor failed';
|
||||
|
||||
let fake_descriptor = new FakeRemoteGATTDescriptor(
|
||||
descriptor_id, ...this.ids_, this.fake_central_ptr_);
|
||||
this.descriptors_.push(fake_descriptor);
|
||||
|
||||
return fake_descriptor;
|
||||
}
|
||||
|
||||
// Sets the next read response for characteristic to |code| and |value|.
|
||||
// |code| could be a GATT Error Response from
|
||||
// BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range
|
||||
// returned by specific platforms e.g. Android returns 0x101 to signal a GATT
|
||||
// failure.
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE
|
||||
async setNextReadResponse(gatt_code, value=null) {
|
||||
if (gatt_code === 0 && value === null) {
|
||||
throw '|value| can\'t be null if read should success.';
|
||||
}
|
||||
if (gatt_code !== 0 && value !== null) {
|
||||
throw '|value| must be null if read should fail.';
|
||||
}
|
||||
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextReadCharacteristicResponse(
|
||||
gatt_code, value, ...this.ids_);
|
||||
|
||||
if (!success) throw 'setNextReadCharacteristicResponse failed';
|
||||
}
|
||||
|
||||
// Sets the next write response for this characteristic to |code|. If
|
||||
// writing to a characteristic that only supports 'write_without_response'
|
||||
// the set response will be ignored.
|
||||
// |code| could be a GATT Error Response from
|
||||
// BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range
|
||||
// returned by specific platforms e.g. Android returns 0x101 to signal a GATT
|
||||
// failure.
|
||||
async setNextWriteResponse(gatt_code) {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextWriteCharacteristicResponse(
|
||||
gatt_code, ...this.ids_);
|
||||
|
||||
if (!success) throw 'setNextWriteResponse failed';
|
||||
}
|
||||
|
||||
// Sets the next subscribe to notifications response for characteristic with
|
||||
// |characteristic_id| in |service_id| and in |peripheral_address| to
|
||||
// |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 Part F
|
||||
// 3.4.1.1 Error Response or a number outside that range returned by
|
||||
// specific platforms e.g. Android returns 0x101 to signal a GATT failure.
|
||||
async setNextSubscribeToNotificationsResponse(gatt_code) {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextSubscribeToNotificationsResponse(
|
||||
gatt_code, ...this.ids_);
|
||||
|
||||
if (!success) throw 'setNextSubscribeToNotificationsResponse failed';
|
||||
}
|
||||
|
||||
// Gets the last successfully written value to the characteristic.
|
||||
// Returns null if no value has yet been written to the characteristic.
|
||||
async getLastWrittenValue() {
|
||||
let {success, value} =
|
||||
await this.fake_central_ptr_.getLastWrittenValue(...this.ids_);
|
||||
|
||||
if (!success) throw 'getLastWrittenValue failed';
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Removes the fake GATT Characteristic from its fake service.
|
||||
async remove() {
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.removeFakeCharacteristic(...this.ids_);
|
||||
|
||||
if (!success) throw 'remove failed';
|
||||
}
|
||||
}
|
||||
|
||||
class FakeRemoteGATTDescriptor {
|
||||
constructor(descriptor_id,
|
||||
characteristic_id,
|
||||
service_id,
|
||||
peripheral_address,
|
||||
fake_central_ptr) {
|
||||
this.ids_ = [
|
||||
descriptor_id, characteristic_id, service_id, peripheral_address];
|
||||
this.fake_central_ptr_ = fake_central_ptr;
|
||||
}
|
||||
|
||||
// Sets the next read response for descriptor to |code| and |value|.
|
||||
// |code| could be a GATT Error Response from
|
||||
// BT 4.2 Vol 3 Part F 3.4.1.1 Error Response or a number outside that range
|
||||
// returned by specific platforms e.g. Android returns 0x101 to signal a GATT
|
||||
// failure.
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE
|
||||
async setNextReadResponse(gatt_code, value=null) {
|
||||
if (gatt_code === 0 && value === null) {
|
||||
throw '|value| cannot be null if read should succeed.';
|
||||
}
|
||||
if (gatt_code !== 0 && value !== null) {
|
||||
throw '|value| must be null if read should fail.';
|
||||
}
|
||||
|
||||
let {success} =
|
||||
await this.fake_central_ptr_.setNextReadDescriptorResponse(
|
||||
gatt_code, value, ...this.ids_);
|
||||
|
||||
if (!success) throw 'setNextReadDescriptorResponse failed';
|
||||
}
|
||||
}
|
||||
|
||||
navigator.bluetooth.test = new FakeBluetooth();
|
|
@ -0,0 +1 @@
|
|||
Content-Type: text/javascript; charset=utf-8
|
Loading…
Add table
Add a link
Reference in a new issue