import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1206596: Make random_generateSeed visible, and let it generate wider seeds. r=fitzgen (6c94fd975)
- Bug 1159552 - Clear local arrays while discovering. r=jocelyn (912dd8429)
- Bug 1179682 - Remove |mName| from BluetoothReplyRunnable, r=joliu (541e01427)
- Bug 1186317 - [cleanup] Remove unused macros and unnecessary logs, r=shuang (38908d9fc)
- Bug 1181478 - Expose BluetoothGattServer object in BluetoothAdapter. r=btian, r=mrbkap, a=me (450cdb58e)
- Bug 1188394 - Fix warning: NS_ENSURE_TRUE(aTypes.Length()) failed, r=joliu (c898e6401)
This commit is contained in:
2021-11-12 09:08:49 +08:00
parent 2b0b985a18
commit 413983e19b
24 changed files with 354 additions and 210 deletions
+4
View File
@@ -174,6 +174,10 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGattDescriptor',
},
'BluetoothGattServer': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGattServer',
},
'BluetoothGattService': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGattService',
},
+22 -26
View File
@@ -57,13 +57,13 @@ extern bool gBluetoothDebugFlag;
*/
#define BT_LOGR(msg, ...) \
__android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth", \
"%s: " msg, __FUNCTION__, ##__VA_ARGS__) \
"%s: " msg, __FUNCTION__, ##__VA_ARGS__)
/**
* Prints DEBUG build warnings, which show in DEBUG build only.
*/
#define BT_WARNING(args...) \
NS_WARNING(nsPrintfCString(args).get()) \
NS_WARNING(nsPrintfCString(args).get())
#else
#define BT_LOGD(msg, ...) \
@@ -88,11 +88,25 @@ extern bool gBluetoothDebugFlag;
/**
* Wrap literal name and value into a BluetoothNamedValue
* and insert it to the array.
*
* TODO: remove with bluetooth1
*/
#define BT_INSERT_NAMED_VALUE(array, index, name, value) \
array.InsertElementAt(index, BluetoothNamedValue(NS_LITERAL_STRING(name), \
BluetoothValue(value)))
/**
* Convert an enum value to string and append it to a fallible array.
*/
#define BT_APPEND_ENUM_STRING_FALLIBLE(array, enumType, enumValue) \
do { \
uint32_t index = uint32_t(enumValue); \
nsAutoString name; \
name.AssignASCII(enumType##Values::strings[index].value, \
enumType##Values::strings[index].length); \
array.AppendElement(name, mozilla::fallible); \
} while(0)
/**
* Ensure success of system message broadcast with void return.
*/
@@ -105,30 +119,6 @@ extern bool gBluetoothDebugFlag;
} \
} while(0)
/**
* Convert an enum value to string then append it to an array.
*/
#define BT_APPEND_ENUM_STRING(array, enumType, enumValue) \
do { \
uint32_t index = uint32_t(enumValue); \
nsAutoString name; \
name.AssignASCII(enumType##Values::strings[index].value, \
enumType##Values::strings[index].length); \
array.AppendElement(name); \
} while(0) \
/**
* Convert an enum value to string then append it to a fallible array.
*/
#define BT_APPEND_ENUM_STRING_FALLIBLE(array, enumType, enumValue) \
do { \
uint32_t index = uint32_t(enumValue); \
nsAutoString name; \
name.AssignASCII(enumType##Values::strings[index].value, \
enumType##Values::strings[index].length); \
array.AppendElement(name, mozilla::fallible); \
} while(0) \
/**
* Resolve |promise| with |ret| if |x| is false.
*/
@@ -153,6 +143,12 @@ extern bool gBluetoothDebugFlag;
} \
} while(0)
/**
* Reject |promise| with |ret| if nsresult |rv| is not successful.
*/
#define BT_ENSURE_SUCCESS_REJECT(rv, promise, ret) \
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, ret)
#define BEGIN_BLUETOOTH_NAMESPACE \
namespace mozilla { namespace dom { namespace bluetooth {
#define END_BLUETOOTH_NAMESPACE \
+1 -1
View File
@@ -412,7 +412,7 @@ BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
// Restart listening
ListenMobileConnAndIccInfo(true);
BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
BT_LOGD("%d client %d. new mClientId %d", aRegistered, aClientId,
(mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
}
+64 -60
View File
@@ -22,6 +22,7 @@
#include "mozilla/dom/bluetooth/BluetoothClassOfDevice.h"
#include "mozilla/dom/bluetooth/BluetoothDevice.h"
#include "mozilla/dom/bluetooth/BluetoothDiscoveryHandle.h"
#include "mozilla/dom/bluetooth/BluetoothGattServer.h"
#include "mozilla/dom/bluetooth/BluetoothPairingListener.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
@@ -68,8 +69,7 @@ class StartDiscoveryTask final : public BluetoothReplyRunnable
{
public:
StartDiscoveryTask(BluetoothAdapter* aAdapter, Promise* aPromise)
: BluetoothReplyRunnable(nullptr, aPromise,
NS_LITERAL_STRING("StartDiscovery"))
: BluetoothReplyRunnable(nullptr, aPromise)
, mAdapter(aAdapter)
{
MOZ_ASSERT(aPromise);
@@ -117,8 +117,7 @@ class StartLeScanTask final : public BluetoothReplyRunnable
public:
StartLeScanTask(BluetoothAdapter* aAdapter, Promise* aPromise,
const nsTArray<nsString>& aServiceUuids)
: BluetoothReplyRunnable(nullptr, aPromise,
NS_LITERAL_STRING("StartLeScan"))
: BluetoothReplyRunnable(nullptr, aPromise)
, mAdapter(aAdapter)
, mServiceUuids(aServiceUuids)
{
@@ -175,8 +174,7 @@ public:
StopLeScanTask(BluetoothAdapter* aAdapter,
Promise* aPromise,
const nsAString& aScanUuid)
: BluetoothReplyRunnable(nullptr, aPromise,
NS_LITERAL_STRING("StopLeScan"))
: BluetoothReplyRunnable(nullptr, aPromise)
, mAdapter(aAdapter)
, mScanUuid(aScanUuid)
{
@@ -364,6 +362,27 @@ BluetoothAdapter::Cleanup()
}
}
BluetoothGattServer*
BluetoothAdapter::GetGattServer()
{
/* Only expose GATT server if the adapter is enabled. It would be worth
* noting that the enabling state and the disabling state are just
* intermediate states, and the adapter would change into the enabled state
* or the disabled state sooner or later. So we invalidate and nullify the
* created GATT server object only when the adapter changes to a steady
* state, i.e., the disabled state.
*/
if (mState != BluetoothAdapterState::Enabled) {
return nullptr;
}
if (!mGattServer) {
mGattServer = new BluetoothGattServer(GetOwner());
}
return mGattServer;
}
void
BluetoothAdapter::GetPairedDeviceProperties(
const nsTArray<nsString>& aDeviceAddresses)
@@ -394,6 +413,10 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
if (mState == BluetoothAdapterState::Disabled) {
mDevices.Clear();
mLeScanHandleArray.Clear();
if (mGattServer) {
mGattServer->Invalidate();
mGattServer = nullptr;
}
}
} else if (name.EqualsLiteral("Name")) {
mName = value.get_nsString();
@@ -412,10 +435,9 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
= value.get_ArrayOfnsString();
for (uint32_t i = 0; i < pairedDeviceAddresses.Length(); i++) {
// Check whether or not the address exists in mDevices.
if (mDevices.Contains(pairedDeviceAddresses[i])) {
// If the paired device exists in mDevices, it would handle
// 'PropertyChanged' signal in BluetoothDevice::Notify().
// Existing paired devices handle 'PropertyChanged' signal
// in BluetoothDevice::Notify()
continue;
}
@@ -423,12 +445,9 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
BT_APPEND_NAMED_VALUE(props, "Address", pairedDeviceAddresses[i]);
BT_APPEND_NAMED_VALUE(props, "Paired", true);
// Create paired device with 'address' and 'paired' attributes
nsRefPtr<BluetoothDevice> pairedDevice =
BluetoothDevice::Create(GetOwner(), BluetoothValue(props));
// Append to adapter's device array
mDevices.AppendElement(pairedDevice);
// Create paired device and append to adapter's device array
mDevices.AppendElement(
BluetoothDevice::Create(GetOwner(), BluetoothValue(props)));
}
// Retrieve device properties, result will be handled by device objects.
@@ -575,9 +594,7 @@ BluetoothAdapter::StartDiscovery(ErrorResult& aRv)
}
// Return BluetoothDiscoveryHandle in StartDiscoveryTask
nsRefPtr<BluetoothReplyRunnable> result =
new StartDiscoveryTask(this, promise);
bs->StartDiscoveryInternal(result);
bs->StartDiscoveryInternal(new StartDiscoveryTask(this, promise));
return promise.forget();
}
@@ -607,11 +624,7 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("StopDiscovery"));
bs->StopDiscoveryInternal(result);
bs->StopDiscoveryInternal(new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -708,15 +721,10 @@ BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
nsString name(aName);
BluetoothNamedValue property(NS_LITERAL_STRING("Name"),
BluetoothValue(name));
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("SetName"));
BT_ENSURE_TRUE_REJECT(
NS_SUCCEEDED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
property, result)),
promise,
NS_ERROR_DOM_OPERATION_ERR);
BT_ENSURE_SUCCESS_REJECT(
bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER, property,
new BluetoothVoidReplyRunnable(nullptr, promise)),
promise, NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
@@ -751,15 +759,10 @@ BluetoothAdapter::SetDiscoverable(bool aDiscoverable, ErrorResult& aRv)
// Wrap property to set and runnable to handle result
BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"),
BluetoothValue(aDiscoverable));
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("SetDiscoverable"));
BT_ENSURE_TRUE_REJECT(
NS_SUCCEEDED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
property, result)),
promise,
NS_ERROR_DOM_OPERATION_ERR);
BT_ENSURE_SUCCESS_REJECT(
bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER, property,
new BluetoothVoidReplyRunnable(nullptr, promise)),
promise, NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
@@ -833,19 +836,12 @@ BluetoothAdapter::PairUnpair(bool aPair, const nsAString& aDeviceAddress,
nsresult rv;
if (aPair) {
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("Pair"));
rv = bs->CreatePairedDeviceInternal(aDeviceAddress,
kCreatePairedDeviceTimeout,
result);
rv = bs->CreatePairedDeviceInternal(
aDeviceAddress, kCreatePairedDeviceTimeout,
new BluetoothVoidReplyRunnable(nullptr, promise));
} else {
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("Unpair"));
rv = bs->RemoveDeviceInternal(aDeviceAddress, result);
rv = bs->RemoveDeviceInternal(aDeviceAddress,
new BluetoothVoidReplyRunnable(nullptr, promise));
}
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, NS_ERROR_DOM_OPERATION_ERR);
@@ -892,9 +888,7 @@ BluetoothAdapter::Enable(ErrorResult& aRv)
// Wrap runnable to handle result
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
promise,
NS_LITERAL_STRING("Enable"));
new BluetoothVoidReplyRunnable(nullptr, promise);
if (NS_FAILED(bs->EnableDisable(true, result))) {
// Restore adapter state and reject promise
@@ -933,9 +927,7 @@ BluetoothAdapter::Disable(ErrorResult& aRv)
// Wrap runnable to handle result
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
promise,
NS_LITERAL_STRING("Disable"));
new BluetoothVoidReplyRunnable(nullptr, promise);
if (NS_FAILED(bs->EnableDisable(false, result))) {
// Restore adapter state and reject promise
@@ -1014,6 +1006,13 @@ BluetoothAdapter::SetAdapterState(BluetoothAdapterState aState)
mState = aState;
if (mState == BluetoothAdapterState::Disabled) {
if (mGattServer) {
mGattServer->Invalidate();
mGattServer = nullptr;
}
}
// Fire BluetoothAttributeEvent for changed adapter state
Sequence<nsString> types;
BT_APPEND_ENUM_STRING_FALLIBLE(types,
@@ -1048,6 +1047,11 @@ BluetoothAdapter::HandlePropertyChanged(const BluetoothValue& aValue)
}
}
if (types.IsEmpty()) {
// No adapter attribute changed
return;
}
DispatchAttributeEvent(types);
}
@@ -1174,7 +1178,7 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue)
void
BluetoothAdapter::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
{
NS_ENSURE_TRUE_VOID(aTypes.Length());
MOZ_ASSERT(!aTypes.IsEmpty());
BluetoothAttributeEventInit init;
init.mAttrs = aTypes;
@@ -28,6 +28,7 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothDevice;
class BluetoothDiscoveryHandle;
class BluetoothGattServer;
class BluetoothNamedValue;
class BluetoothPairingListener;
class BluetoothSignal;
@@ -77,6 +78,8 @@ public:
return mPairingReqs;
}
BluetoothGattServer* GetGattServer();
/****************************************************************************
* Event Handlers
***************************************************************************/
@@ -284,6 +287,8 @@ private:
/**
* Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
*
* @param aTypes [in] Array of changed attributes. Must be non-empty.
*/
void DispatchAttributeEvent(const Sequence<nsString>& aTypes);
@@ -349,6 +354,18 @@ private:
*/
bool mDiscovering;
/**
* GATT server object of this adapter.
*
* A new GATT server object will be created at the first time when
* |GetGattServer| is called after the adapter has been enabled. If the
* adapter has been disabled later on, the created GATT server will be
* discard by the adapter, and this GATT object should stop working till the
* end of its life. When |GetGattServer| is called after the adapter has been
* enabled again, a new GATT server object will be created.
*/
nsRefPtr<BluetoothGattServer> mGattServer;
/**
* Handle to fire pairing requests of different pairing types.
*/
+12 -10
View File
@@ -54,9 +54,8 @@ class FetchUuidsTask final : public BluetoothReplyRunnable
{
public:
FetchUuidsTask(Promise* aPromise,
const nsAString& aName,
BluetoothDevice* aDevice)
: BluetoothReplyRunnable(nullptr /* DOMRequest */, aPromise, aName)
: BluetoothReplyRunnable(nullptr, aPromise)
, mDevice(aDevice)
{
MOZ_ASSERT(aPromise);
@@ -185,16 +184,14 @@ BluetoothDevice::FetchUuids(ErrorResult& aRv)
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
// Ensure BluetoothService is available
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new FetchUuidsTask(promise,
NS_LITERAL_STRING("FetchUuids"),
this);
nsresult rv = bs->FetchUuidsInternal(mAddress, result);
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, NS_ERROR_DOM_OPERATION_ERR);
BT_ENSURE_TRUE_REJECT(
NS_SUCCEEDED(
bs->FetchUuidsInternal(mAddress, new FetchUuidsTask(promise, this))),
promise, NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
@@ -296,13 +293,18 @@ BluetoothDevice::HandlePropertyChanged(const BluetoothValue& aValue)
}
}
if (types.IsEmpty()) {
// No device attribute changed
return;
}
DispatchAttributeEvent(types);
}
void
BluetoothDevice::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
{
NS_ENSURE_TRUE_VOID(aTypes.Length());
MOZ_ASSERT(!aTypes.IsEmpty());
BluetoothAttributeEventInit init;
init.mAttrs = aTypes;
+3 -1
View File
@@ -117,6 +117,8 @@ private:
/**
* Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
*
* @param aTypes [in] Array of changed attributes. Must be non-empty.
*/
void DispatchAttributeEvent(const Sequence<nsString>& aTypes);
@@ -152,7 +154,7 @@ private:
*
* @param aAdvData [in] advertising data which provided by the LeScan result.
*/
void UpdatePropertiesFromAdvData(const nsTArray<uint8_t>& aAdvData);
void UpdatePropertiesFromAdvData(const nsTArray<uint8_t>& aAdvData);
/****************************************************************************
* Variables
+13 -22
View File
@@ -121,13 +121,8 @@ BluetoothGatt::Connect(ErrorResult& aRv)
}
UpdateConnectionState(BluetoothConnectionState::Connecting);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("ConnectGattClient"));
bs->ConnectGattClientInternal(mAppUuid,
mDeviceAddr,
result);
bs->ConnectGattClientInternal(
mAppUuid, mDeviceAddr, new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -153,11 +148,8 @@ BluetoothGatt::Disconnect(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
UpdateConnectionState(BluetoothConnectionState::Disconnecting);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("DisconnectGattClient"));
bs->DisconnectGattClientInternal(mAppUuid, mDeviceAddr, result);
bs->DisconnectGattClientInternal(
mAppUuid, mDeviceAddr, new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -166,8 +158,7 @@ class ReadRemoteRssiTask final : public BluetoothReplyRunnable
{
public:
ReadRemoteRssiTask(Promise* aPromise)
: BluetoothReplyRunnable(nullptr, aPromise,
NS_LITERAL_STRING("GattClientReadRemoteRssi"))
: BluetoothReplyRunnable(nullptr, aPromise)
{
MOZ_ASSERT(aPromise);
}
@@ -205,9 +196,8 @@ BluetoothGatt::ReadRemoteRssi(ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new ReadRemoteRssiTask(promise);
bs->GattClientReadRemoteRssiInternal(mClientIf, mDeviceAddr, result);
bs->GattClientReadRemoteRssiInternal(
mClientIf, mDeviceAddr, new ReadRemoteRssiTask(promise));
return promise.forget();
}
@@ -234,11 +224,11 @@ BluetoothGatt::DiscoverServices(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
mDiscoveringServices = true;
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("DiscoverGattServices"));
bs->DiscoverGattServicesInternal(mAppUuid, result);
mServices.Clear();
BluetoothGattBinding::ClearCachedServicesValue(this);
bs->DiscoverGattServicesInternal(
mAppUuid, new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -270,6 +260,7 @@ BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
const InfallibleTArray<BluetoothGattServiceId>& serviceIds =
aValue.get_ArrayOfBluetoothGattServiceId();
mServices.Clear();
for (uint32_t i = 0; i < serviceIds.Length(); i++) {
mServices.AppendElement(new BluetoothGattService(
GetParentObject(), mAppUuid, serviceIds[i]));
@@ -98,15 +98,9 @@ BluetoothGattCharacteristic::StartNotifications(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mService, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(
nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("GattClientStartNotifications"));
bs->GattClientStartNotificationsInternal(mService->GetAppUuid(),
mService->GetServiceId(),
mCharId,
result);
bs->GattClientStartNotificationsInternal(
mService->GetAppUuid(), mService->GetServiceId(), mCharId,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -127,15 +121,9 @@ BluetoothGattCharacteristic::StopNotifications(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
BT_ENSURE_TRUE_REJECT(mService, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(
nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("GattClientStopNotifications"));
bs->GattClientStopNotificationsInternal(mService->GetAppUuid(),
mService->GetServiceId(),
mCharId,
result);
bs->GattClientStopNotificationsInternal(
mService->GetAppUuid(), mService->GetServiceId(), mCharId,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -149,6 +137,7 @@ BluetoothGattCharacteristic::HandleDescriptorsDiscovered(
const InfallibleTArray<BluetoothGattId>& descriptorIds =
aValue.get_ArrayOfBluetoothGattId();
mDescriptors.Clear();
for (uint32_t i = 0; i < descriptorIds.Length(); i++) {
mDescriptors.AppendElement(new BluetoothGattDescriptor(
GetParentObject(), this, descriptorIds[i]));
@@ -219,9 +208,7 @@ class ReadValueTask final : public BluetoothReplyRunnable
{
public:
ReadValueTask(BluetoothGattCharacteristic* aCharacteristic, Promise* aPromise)
: BluetoothReplyRunnable(
nullptr, aPromise,
NS_LITERAL_STRING("GattClientReadCharacteristicValue"))
: BluetoothReplyRunnable(nullptr, aPromise)
, mCharacteristic(aCharacteristic)
{
MOZ_ASSERT(aCharacteristic);
@@ -278,11 +265,9 @@ BluetoothGattCharacteristic::ReadValue(ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result = new ReadValueTask(this, promise);
bs->GattClientReadCharacteristicValueInternal(mService->GetAppUuid(),
mService->GetServiceId(),
mCharId,
result);
bs->GattClientReadCharacteristicValueInternal(
mService->GetAppUuid(), mService->GetServiceId(), mCharId,
new ReadValueTask(this, promise));
return promise.forget();
}
@@ -315,14 +300,10 @@ BluetoothGattCharacteristic::WriteValue(const ArrayBuffer& aValue,
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result = new BluetoothVoidReplyRunnable(
nullptr, promise, NS_LITERAL_STRING("GattClientWriteCharacteristicValue"));
bs->GattClientWriteCharacteristicValueInternal(mService->GetAppUuid(),
mService->GetServiceId(),
mCharId,
mWriteType,
value,
result);
bs->GattClientWriteCharacteristicValueInternal(
mService->GetAppUuid(), mService->GetServiceId(),
mCharId, mWriteType, value,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -123,9 +123,7 @@ class ReadValueTask final : public BluetoothReplyRunnable
{
public:
ReadValueTask(BluetoothGattDescriptor* aDescriptor, Promise* aPromise)
: BluetoothReplyRunnable(
nullptr, aPromise,
NS_LITERAL_STRING("GattClientReadDescriptorValue"))
: BluetoothReplyRunnable(nullptr, aPromise)
, mDescriptor(aDescriptor)
{
MOZ_ASSERT(aDescriptor);
@@ -178,13 +176,12 @@ BluetoothGattDescriptor::ReadValue(ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result = new ReadValueTask(this, promise);
bs->GattClientReadDescriptorValueInternal(
mCharacteristic->Service()->GetAppUuid(),
mCharacteristic->Service()->GetServiceId(),
mCharacteristic->GetCharacteristicId(),
mDescriptorId,
result);
new ReadValueTask(this, promise));
return promise.forget();
}
@@ -210,15 +207,13 @@ BluetoothGattDescriptor::WriteValue(
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result = new BluetoothVoidReplyRunnable(
nullptr, promise, NS_LITERAL_STRING("GattClientWriteDescriptorValue"));
bs->GattClientWriteDescriptorValueInternal(
mCharacteristic->Service()->GetAppUuid(),
mCharacteristic->Service()->GetServiceId(),
mCharacteristic->GetCharacteristicId(),
mDescriptorId,
value,
result);
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothGattServer.h"
using namespace mozilla;
using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothGattServer,
mOwner)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothGattServer)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothGattServer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothGattServer)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
BluetoothGattServer::BluetoothGattServer(nsPIDOMWindow* aOwner)
: mOwner(aOwner)
, mValid(true)
{
}
BluetoothGattServer::~BluetoothGattServer()
{
Invalidate();
}
JSObject*
BluetoothGattServer::WrapObject(JSContext* aContext,
JS::Handle<JSObject*> aGivenProto)
{
return BluetoothGattServerBinding::Wrap(aContext, this, aGivenProto);
}
void
BluetoothGattServer::Invalidate()
{
mValid = false;
/* TODO: add tear down stuff here */
return;
}
@@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothgattserver_h__
#define mozilla_dom_bluetooth_bluetoothgattserver_h__
#include "mozilla/dom/BluetoothGattServerBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "nsCOMPtr.h"
#include "nsPIDOMWindow.h"
#include "nsWrapperCache.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothGattServer final : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattServer)
/****************************************************************************
* Attribute Getters
***************************************************************************/
/****************************************************************************
* Event Handlers
***************************************************************************/
/****************************************************************************
* Methods (Web API Implementation)
***************************************************************************/
/****************************************************************************
* Others
***************************************************************************/
nsPIDOMWindow* GetParentObject() const
{
return mOwner;
}
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
BluetoothGattServer(nsPIDOMWindow* aOwner);
/* Invalidate the GATT server.
* If the BluetoothAdapter turns off, existing BluetoothGattServer instances
* should stop working till the end of life.
*/
void Invalidate();
private:
~BluetoothGattServer();
/****************************************************************************
* Variables
***************************************************************************/
nsCOMPtr<nsPIDOMWindow> mOwner;
bool mValid;
};
END_BLUETOOTH_NAMESPACE
#endif
@@ -85,6 +85,7 @@ BluetoothGattService::HandleIncludedServicesDiscovered(
const InfallibleTArray<BluetoothGattServiceId>& includedServIds =
aValue.get_ArrayOfBluetoothGattServiceId();
mIncludedServices.Clear();
for (uint32_t i = 0; i < includedServIds.Length(); i++) {
mIncludedServices.AppendElement(new BluetoothGattService(
GetParentObject(), mAppUuid, includedServIds[i]));
@@ -103,6 +104,7 @@ BluetoothGattService::HandleCharacteristicsDiscovered(
const InfallibleTArray<BluetoothGattCharAttribute>& characteristics =
aValue.get_ArrayOfBluetoothGattCharAttribute();
mCharacteristics.Clear();
for (uint32_t i = 0; i < characteristics.Length(); i++) {
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
GetParentObject(), this, characteristics[i]));
@@ -82,11 +82,8 @@ BluetoothPairingHandle::SetPinCode(const nsAString& aPinCode, ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("SetPinCode"));
bs->PinReplyInternal(mDeviceAddress, true /* accept */, aPinCode, result);
bs->PinReplyInternal(mDeviceAddress, true /* accept */, aPinCode,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -116,12 +113,8 @@ BluetoothPairingHandle::Accept(ErrorResult& aRv)
promise,
NS_ERROR_DOM_OPERATION_ERR);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("Accept"));
bs->SspReplyInternal(
mDeviceAddress, variant, true /* aAccept */, result);
bs->SspReplyInternal(mDeviceAddress, variant, true /* aAccept */,
new BluetoothVoidReplyRunnable(nullptr, promise));
return promise.forget();
}
@@ -141,22 +134,17 @@ BluetoothPairingHandle::Reject(ErrorResult& aRv)
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("Reject"));
if (mType.EqualsLiteral(PAIRING_REQ_TYPE_ENTERPINCODE)) { // Pin request
bs->PinReplyInternal(
mDeviceAddress, false /* aAccept */, EmptyString(), result);
bs->PinReplyInternal(mDeviceAddress, false /* aAccept */, EmptyString(),
new BluetoothVoidReplyRunnable(nullptr, promise));
} else { // Ssp request
BluetoothSspVariant variant;
BT_ENSURE_TRUE_REJECT(GetSspVariant(variant),
promise,
NS_ERROR_DOM_OPERATION_ERR);
bs->SspReplyInternal(
mDeviceAddress, variant, false /* aAccept */, result);
bs->SspReplyInternal(mDeviceAddress, variant, false /* aAccept */,
new BluetoothVoidReplyRunnable(nullptr, promise));
}
return promise.forget();
@@ -143,7 +143,7 @@ BluetoothPairingListener::TryListeningToBluetoothSignal()
!HasListenersFor(nsGkAtoms::onenterpincodereq) ||
!HasListenersFor(nsGkAtoms::onpairingconfirmationreq) ||
!HasListenersFor(nsGkAtoms::onpairingconsentreq)) {
BT_LOGR("Pairing listener is not ready to handle pairing requests!");
BT_LOGD("Pairing listener is not ready to handle pairing requests!");
return;
}
@@ -17,12 +17,10 @@ using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
BluetoothReplyRunnable::BluetoothReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise,
const nsAString& aName)
Promise* aPromise)
: mDOMRequest(aReq)
, mPromise(aPromise)
, mErrorStatus(STATUS_FAIL)
, mName(aName)
{}
void
@@ -121,9 +119,8 @@ BluetoothReplyRunnable::Run()
}
BluetoothVoidReplyRunnable::BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise,
const nsAString& aName)
: BluetoothReplyRunnable(aReq, aPromise, aName)
Promise* aPromise)
: BluetoothReplyRunnable(aReq, aPromise)
{}
BluetoothVoidReplyRunnable::~BluetoothVoidReplyRunnable()
@@ -30,8 +30,7 @@ public:
NS_DECL_NSIRUNNABLE
BluetoothReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise = nullptr,
const nsAString& aName = EmptyString());
Promise* aPromise = nullptr);
void SetReply(BluetoothReply* aReply);
@@ -71,15 +70,13 @@ private:
BluetoothStatus mErrorStatus;
nsString mErrorString;
nsString mName; // for debugging
};
class BluetoothVoidReplyRunnable : public BluetoothReplyRunnable
{
public:
BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise = nullptr,
const nsAString& aName = EmptyString());
Promise* aPromise = nullptr);
~BluetoothVoidReplyRunnable();
protected:
+2
View File
@@ -50,6 +50,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluetooth2/BluetoothGatt.cpp',
'bluetooth2/BluetoothGattCharacteristic.cpp',
'bluetooth2/BluetoothGattDescriptor.cpp',
'bluetooth2/BluetoothGattServer.cpp',
'bluetooth2/BluetoothGattService.cpp',
'bluetooth2/BluetoothLeDeviceEvent.cpp',
'bluetooth2/BluetoothManager.cpp',
@@ -188,6 +189,7 @@ else:
'bluetooth2/BluetoothGatt.h',
'bluetooth2/BluetoothGattCharacteristic.h',
'bluetooth2/BluetoothGattDescriptor.h',
'bluetooth2/BluetoothGattServer.h',
'bluetooth2/BluetoothGattService.h',
'bluetooth2/BluetoothLeDeviceEvent.h',
'bluetooth2/BluetoothManager.h',
@@ -206,6 +206,8 @@ var interfaceNamesInGlobalScope =
permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGattDescriptor", b2g: true, permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGattServer", b2g: true, permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothGattService", b2g: true, permission: ["bluetooth"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
+1
View File
@@ -40,6 +40,7 @@ interface BluetoothAdapter : EventTarget {
readonly attribute DOMString name;
readonly attribute boolean discoverable;
readonly attribute boolean discovering;
readonly attribute BluetoothGattServer? gattServer;
[AvailableIn=CertifiedApps]
readonly attribute BluetoothPairingListener pairingReqs;
+13
View File
@@ -0,0 +1,13 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[CheckAnyPermissions="bluetooth"]
interface BluetoothGattServer
{
/* The implementation of BluetoothGattServer will come later.
* (see dependent bugs of bug 933358)
*/
};
+1
View File
@@ -679,6 +679,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothGatt.webidl',
'BluetoothGattCharacteristic.webidl',
'BluetoothGattDescriptor.webidl',
'BluetoothGattServer.webidl',
'BluetoothGattService.webidl',
'BluetoothLeDeviceEvent.webidl',
'BluetoothManager2.webidl',
+39 -16
View File
@@ -734,15 +734,11 @@ js::math_pow(JSContext* cx, unsigned argc, Value* vp)
return math_pow_handle(cx, args.get(0), args.get(1), args.rval());
}
static uint64_t
random_generateSeed()
void
js::random_generateSeed(uint64_t* seedBuffer, size_t length)
{
union {
uint8_t u8[8];
uint32_t u32[2];
uint64_t u64;
} seed;
seed.u64 = 0;
if (length == 0)
return;
#if defined(XP_WIN)
/*
@@ -760,6 +756,12 @@ random_generateSeed()
if (oldWay && !newWay)
MOZ_CRASH();
union {
uint32_t u32[2];
uint64_t u64;
} seed;
seed.u64 = 0;
errno_t error = rand_s(&seed.u32[0]);
if (oldWay)
@@ -771,24 +773,44 @@ random_generateSeed()
error = rand_s(&seed.u32[1]);
MOZ_ASSERT(error == 0, "rand_s() error?!");
seedBuffer[0] = seed.u64 ^= PRMJ_Now();
for (size_t i = 1; i < length; i++) {
error = rand_s(&seed.u32[0]);
MOZ_ASSERT(error == 0, "rand_s() error?!");
error = rand_s(&seed.u32[1]);
MOZ_ASSERT(error == 0, "rand_s() error?!");
seedBuffer[i] = seed.u64 ^ PRMJ_Now();
}
#elif defined(HAVE_ARC4RANDOM)
seed.u32[0] = arc4random();
seed.u32[1] = arc4random();
union {
uint32_t u32[2];
uint64_t u64;
} seed;
seed.u64 = 0;
for (size_t i = 0; i < length; i++) {
seed.u32[0] = arc4random();
seed.u32[1] = arc4random();
seedBuffer[i] = seed.u64 ^ PRMJ_Now();
}
#elif defined(XP_UNIX)
int fd = open("/dev/urandom", O_RDONLY);
MOZ_ASSERT(fd >= 0, "Can't open /dev/urandom?!");
if (fd >= 0) {
ssize_t nread = read(fd, seed.u8, mozilla::ArrayLength(seed.u8));
MOZ_ASSERT(nread == 8, "Can't read /dev/urandom?!");
ssize_t size = length * sizeof(seedBuffer[0]);
ssize_t nread = read(fd, (char *) seedBuffer, size);
MOZ_ASSERT(nread == size, "Can't read /dev/urandom?!");
mozilla::unused << nread;
close(fd);
}
#else
# error "Platform needs to implement random_generateSeed()"
#endif
seed.u64 ^= PRMJ_Now();
return seed.u64;
}
/*
@@ -798,7 +820,8 @@ void
js::random_initState(uint64_t* rngState)
{
/* Our PRNG only uses 48 bits, so squeeze our entropy into those bits. */
uint64_t seed = random_generateSeed();
uint64_t seed;
random_generateSeed(&seed, 1);
seed ^= (seed >> 16);
*rngState = (seed ^ RNG_MULTIPLIER) & RNG_MASK;
}
+7
View File
@@ -90,6 +90,13 @@ class MathCache
extern JSObject*
InitMathClass(JSContext* cx, HandleObject obj);
/*
* Fill |seed[0]| through |seed[length-1]| with random bits, suitable for
* seeding a random number generator.
*/
extern void
random_generateSeed(uint64_t* seed, size_t length);
extern void
random_initState(uint64_t* rngState);