mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 756299: Patch 2 - IPC Socket Creation Functions and Type Additions; r=mrbkap
This commit is contained in:
parent
879bd2bb8a
commit
9ac24e5e11
@ -293,7 +293,7 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
|||||||
bool dummy;
|
bool dummy;
|
||||||
DispatchEvent(event, &dummy);
|
DispatchEvent(event, &dummy);
|
||||||
} else if (aData.name().EqualsLiteral("DeviceDisappeared")) {
|
} else if (aData.name().EqualsLiteral("DeviceDisappeared")) {
|
||||||
const nsAString& deviceAddress = aData.value().get_nsString();
|
const nsAString& deviceAddress = aData.value().get_nsString();
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEvent> event;
|
nsCOMPtr<nsIDOMEvent> event;
|
||||||
NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
|
NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
|
||||||
@ -404,7 +404,7 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
|||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsCString warningMsg;
|
nsCString warningMsg;
|
||||||
warningMsg.AssignLiteral("Not handling manager signal: ");
|
warningMsg.AssignLiteral("Not handling adapter signal: ");
|
||||||
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
||||||
NS_WARNING(warningMsg.get());
|
NS_WARNING(warningMsg.get());
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,12 +24,14 @@
|
|||||||
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
|
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
|
||||||
#define BLUETOOTH_ADDRESS_LENGTH 17
|
#define BLUETOOTH_ADDRESS_LENGTH 17
|
||||||
|
|
||||||
#define DOM_BLUETOOTH_URL_PREF "dom.mozBluetooth.whitelist"
|
|
||||||
|
|
||||||
class nsCString;
|
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
|
enum BluetoothSocketType {
|
||||||
|
RFCOMM = 1,
|
||||||
|
SCO = 2,
|
||||||
|
L2CAP = 3
|
||||||
|
};
|
||||||
|
|
||||||
class BluetoothSignal;
|
class BluetoothSignal;
|
||||||
typedef mozilla::Observer<BluetoothSignal> BluetoothSignalObserver;
|
typedef mozilla::Observer<BluetoothSignal> BluetoothSignalObserver;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "BluetoothReplyRunnable.h"
|
#include "BluetoothReplyRunnable.h"
|
||||||
#include "BluetoothService.h"
|
#include "BluetoothService.h"
|
||||||
#include "BluetoothUtils.h"
|
#include "BluetoothUtils.h"
|
||||||
|
#include "BluetoothServiceUuid.h"
|
||||||
|
|
||||||
#include "nsIDOMDOMRequest.h"
|
#include "nsIDOMDOMRequest.h"
|
||||||
#include "nsDOMClassInfo.h"
|
#include "nsDOMClassInfo.h"
|
||||||
@ -25,6 +26,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothDevice)
|
|||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
|
||||||
nsDOMEventTargetHelper)
|
nsDOMEventTargetHelper)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsServices)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice,
|
||||||
@ -50,6 +52,7 @@ BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aOwner,
|
|||||||
const BluetoothValue& aValue) :
|
const BluetoothValue& aValue) :
|
||||||
BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE),
|
BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE),
|
||||||
mJsUuids(nullptr),
|
mJsUuids(nullptr),
|
||||||
|
mJsServices(nullptr),
|
||||||
mAdapterPath(aAdapterPath),
|
mAdapterPath(aAdapterPath),
|
||||||
mIsRooted(false)
|
mIsRooted(false)
|
||||||
{
|
{
|
||||||
@ -98,15 +101,17 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||||||
const BluetoothValue& value = aValue.value();
|
const BluetoothValue& value = aValue.value();
|
||||||
if (name.EqualsLiteral("Name")) {
|
if (name.EqualsLiteral("Name")) {
|
||||||
mName = value.get_nsString();
|
mName = value.get_nsString();
|
||||||
} else if (name.EqualsLiteral("Address")) {
|
} else if (name.EqualsLiteral("Path")) {
|
||||||
mAddress = value.get_nsString();
|
mPath = value.get_nsString();
|
||||||
|
NS_WARNING(NS_ConvertUTF16toUTF8(mPath).get());
|
||||||
BluetoothService* bs = BluetoothService::Get();
|
BluetoothService* bs = BluetoothService::Get();
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
NS_WARNING("BluetoothService not available!");
|
NS_WARNING("BluetoothService not available!");
|
||||||
return;
|
} else if (NS_FAILED(bs->RegisterBluetoothSignalHandler(mPath, this))) {
|
||||||
|
NS_WARNING("Failed to register object with observer!");
|
||||||
}
|
}
|
||||||
// We can't actually set up our path until we know our address
|
} else if (name.EqualsLiteral("Address")) {
|
||||||
bs->GetDevicePath(mAdapterPath, mAddress, mPath);
|
mAddress = value.get_nsString();
|
||||||
} else if (name.EqualsLiteral("Class")) {
|
} else if (name.EqualsLiteral("Class")) {
|
||||||
mClass = value.get_uint32_t();
|
mClass = value.get_uint32_t();
|
||||||
} else if (name.EqualsLiteral("Icon")) {
|
} else if (name.EqualsLiteral("Icon")) {
|
||||||
@ -131,6 +136,22 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||||||
} else {
|
} else {
|
||||||
NS_WARNING("Could not get context!");
|
NS_WARNING("Could not get context!");
|
||||||
}
|
}
|
||||||
|
} else if (name.EqualsLiteral("Services")) {
|
||||||
|
mServices = value.get_ArrayOfnsString();
|
||||||
|
nsresult rv;
|
||||||
|
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
|
||||||
|
if (sc) {
|
||||||
|
rv =
|
||||||
|
StringArrayToJSArray(sc->GetNativeContext(),
|
||||||
|
sc->GetNativeGlobal(), mServices, &mJsServices);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Cannot set JS Services object!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Root();
|
||||||
|
} else {
|
||||||
|
NS_WARNING("Could not get context!");
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
} else {
|
} else {
|
||||||
nsCString warningMsg;
|
nsCString warningMsg;
|
||||||
@ -257,6 +278,17 @@ BluetoothDevice::GetUuids(JSContext* aCx, jsval* aUuids)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BluetoothDevice::GetServices(JSContext* aCx, jsval* aServices)
|
||||||
|
{
|
||||||
|
if (mJsServices) {
|
||||||
|
aServices->setObject(*mJsServices);
|
||||||
|
} else {
|
||||||
|
NS_WARNING("Services not yet set!\n");
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_EVENT_HANDLER(BluetoothDevice, propertychanged)
|
NS_IMPL_EVENT_HANDLER(BluetoothDevice, propertychanged)
|
||||||
NS_IMPL_EVENT_HANDLER(BluetoothDevice, connected)
|
NS_IMPL_EVENT_HANDLER(BluetoothDevice, connected)
|
||||||
NS_IMPL_EVENT_HANDLER(BluetoothDevice, disconnected)
|
NS_IMPL_EVENT_HANDLER(BluetoothDevice, disconnected)
|
||||||
|
@ -20,6 +20,7 @@ BEGIN_BLUETOOTH_NAMESPACE
|
|||||||
class BluetoothNamedValue;
|
class BluetoothNamedValue;
|
||||||
class BluetoothValue;
|
class BluetoothValue;
|
||||||
class BluetoothSignal;
|
class BluetoothSignal;
|
||||||
|
class BluetoothSocket;
|
||||||
|
|
||||||
class BluetoothDevice : public nsDOMEventTargetHelper
|
class BluetoothDevice : public nsDOMEventTargetHelper
|
||||||
, public nsIDOMBluetoothDevice
|
, public nsIDOMBluetoothDevice
|
||||||
@ -64,6 +65,7 @@ private:
|
|||||||
void Root();
|
void Root();
|
||||||
|
|
||||||
JSObject* mJsUuids;
|
JSObject* mJsUuids;
|
||||||
|
JSObject* mJsServices;
|
||||||
|
|
||||||
nsString mAdapterPath;
|
nsString mAdapterPath;
|
||||||
nsString mAddress;
|
nsString mAddress;
|
||||||
@ -74,6 +76,8 @@ private:
|
|||||||
bool mPaired;
|
bool mPaired;
|
||||||
bool mIsRooted;
|
bool mIsRooted;
|
||||||
nsTArray<nsString> mUuids;
|
nsTArray<nsString> mUuids;
|
||||||
|
nsTArray<nsString> mServices;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
@ -145,8 +145,19 @@ BluetoothService::DistributeSignal(const BluetoothSignal& signal)
|
|||||||
// Notify observers that a message has been sent
|
// Notify observers that a message has been sent
|
||||||
BluetoothSignalObserverList* ol;
|
BluetoothSignalObserverList* ol;
|
||||||
if (!mBluetoothSignalObserverTable.Get(signal.path(), &ol)) {
|
if (!mBluetoothSignalObserverTable.Get(signal.path(), &ol)) {
|
||||||
|
#if DEBUG
|
||||||
|
nsString msg;
|
||||||
|
msg.AssignLiteral("No observer registered for path");
|
||||||
|
msg.Append(signal.path());
|
||||||
|
NS_WARNING(NS_ConvertUTF16toUTF8(msg).get());
|
||||||
|
#endif
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
if (ol->Length() == 0) {
|
||||||
|
NS_WARNING("Distributing to observer list of 0");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ol->Broadcast(signal);
|
ol->Broadcast(signal);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -197,12 +197,7 @@ public:
|
|||||||
const nsAString& aDeviceAddress,
|
const nsAString& aDeviceAddress,
|
||||||
nsAString& aDevicePath) = 0;
|
nsAString& aDevicePath) = 0;
|
||||||
|
|
||||||
virtual int
|
virtual nsTArray<PRUint32>
|
||||||
GetDeviceServiceChannelInternal(const nsAString& aObjectPath,
|
|
||||||
const nsAString& aPattern,
|
|
||||||
int aAttributeId) = 0;
|
|
||||||
|
|
||||||
virtual nsTArray<uint32_t>
|
|
||||||
AddReservedServicesInternal(const nsAString& aAdapterPath,
|
AddReservedServicesInternal(const nsAString& aAdapterPath,
|
||||||
const nsTArray<uint32_t>& aServices) = 0;
|
const nsTArray<uint32_t>& aServices) = 0;
|
||||||
|
|
||||||
@ -221,6 +216,17 @@ public:
|
|||||||
const nsAString& aObjectPath,
|
const nsAString& aObjectPath,
|
||||||
BluetoothReplyRunnable* aRunnable) = 0;
|
BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
|
virtual nsresult
|
||||||
|
GetSocketViaService(const nsAString& aObjectPath,
|
||||||
|
const nsAString& aService,
|
||||||
|
int aType,
|
||||||
|
bool aAuth,
|
||||||
|
bool aEncrypt,
|
||||||
|
BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
virtual bool SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode) = 0;
|
virtual bool SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode) = 0;
|
||||||
virtual bool SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey) = 0;
|
virtual bool SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey) = 0;
|
||||||
virtual bool SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm) = 0;
|
virtual bool SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm) = 0;
|
||||||
|
39
dom/bluetooth/BluetoothServiceUuid.h
Normal file
39
dom/bluetooth/BluetoothServiceUuid.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* vim: set ts=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_bluetoothuuid_h__
|
||||||
|
#define mozilla_dom_bluetooth_bluetoothuuid_h__
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace bluetooth {
|
||||||
|
|
||||||
|
namespace BluetoothServiceUuid {
|
||||||
|
static unsigned long long AudioSink = 0x0000110B00000000;
|
||||||
|
static unsigned long long AudioSource = 0x0000110A00000000;
|
||||||
|
static unsigned long long AdvAudioDist = 0x0000110D00000000;
|
||||||
|
static unsigned long long Headset = 0x0000110800000000;
|
||||||
|
static unsigned long long HandsfreeAG = 0x0000111F00000000;
|
||||||
|
|
||||||
|
static unsigned long long BaseMSB = 0x0000000000001000;
|
||||||
|
static unsigned long long BaseLSB = 0x800000805F9B34FB;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BluetoothServiceUuidStr {
|
||||||
|
static const char* AudioSink = "0000110B-0000-1000-8000-00805F9B34FB";
|
||||||
|
static const char* AudioSource = "0000110A-0000-1000-8000-00805F9B34FB";
|
||||||
|
static const char* AdvAudioDist = "0000110D-0000-1000-8000-00805F9B34FB";
|
||||||
|
static const char* Headset = "00001108-0000-1000-8000-00805F9B34FB";
|
||||||
|
static const char* Handsfree = "0000111E-0000-1000-8000-00805F9B34FB";
|
||||||
|
static const char* HandsfreeAG = "0000111F-0000-1000-8000-00805F9B34FB";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -29,6 +29,7 @@
|
|||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
|
#include "mozilla/ipc/Socket.h"
|
||||||
#include "mozilla/ipc/DBusThread.h"
|
#include "mozilla/ipc/DBusThread.h"
|
||||||
#include "mozilla/ipc/DBusUtils.h"
|
#include "mozilla/ipc/DBusUtils.h"
|
||||||
#include "mozilla/ipc/RawDBusConnection.h"
|
#include "mozilla/ipc/RawDBusConnection.h"
|
||||||
@ -140,6 +141,39 @@ static nsAutoPtr<RawDBusConnection> gThreadConnection;
|
|||||||
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
|
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
|
||||||
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
|
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
|
||||||
|
|
||||||
|
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
|
||||||
|
|
||||||
|
static nsString
|
||||||
|
GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
||||||
|
const nsAString& aDeviceAddress)
|
||||||
|
{
|
||||||
|
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||||
|
// and the adapter path would be the first part of the object path, according
|
||||||
|
// to the example above, it's /org/bluez/2906/hci0.
|
||||||
|
nsString devicePath(aAdapterPath);
|
||||||
|
devicePath.AppendLiteral("/dev_");
|
||||||
|
devicePath.Append(aDeviceAddress);
|
||||||
|
devicePath.ReplaceChar(':', '_');
|
||||||
|
return devicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsString
|
||||||
|
GetAddressFromObjectPath(const nsAString& aObjectPath)
|
||||||
|
{
|
||||||
|
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||||
|
// and the adapter path would be the first part of the object path, according
|
||||||
|
// to the example above, it's /org/bluez/2906/hci0.
|
||||||
|
nsString address(aObjectPath);
|
||||||
|
int addressHead = address.RFind("/") + 5;
|
||||||
|
|
||||||
|
MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == address.Length());
|
||||||
|
|
||||||
|
address.Cut(0, addressHead);
|
||||||
|
address.ReplaceChar('_', ':');
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
class DistributeBluetoothSignalTask : public nsRunnable {
|
class DistributeBluetoothSignalTask : public nsRunnable {
|
||||||
BluetoothSignal mSignal;
|
BluetoothSignal mSignal;
|
||||||
public:
|
public:
|
||||||
@ -164,7 +198,7 @@ public:
|
|||||||
static bool
|
static bool
|
||||||
IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
||||||
{
|
{
|
||||||
if(aErr && dbus_error_is_set(aErr)) {
|
if (aErr && dbus_error_is_set(aErr)) {
|
||||||
aErrorStr = NS_ConvertUTF8toUTF16(aErr->message);
|
aErrorStr = NS_ConvertUTF8toUTF16(aErr->message);
|
||||||
LOG_AND_FREE_DBUS_ERROR(aErr);
|
LOG_AND_FREE_DBUS_ERROR(aErr);
|
||||||
return true;
|
return true;
|
||||||
@ -212,6 +246,28 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
UnpackIntMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||||
|
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||||
|
{
|
||||||
|
DBusError err;
|
||||||
|
dbus_error_init(&err);
|
||||||
|
if (!IsDBusMessageError(aMsg, aErr, aErrorStr)) {
|
||||||
|
NS_ASSERTION(dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN,
|
||||||
|
"Got dbus callback that's not a METHOD_RETURN!");
|
||||||
|
int i;
|
||||||
|
if (!dbus_message_get_args(aMsg, &err, DBUS_TYPE_INT32,
|
||||||
|
&i, DBUS_TYPE_INVALID)) {
|
||||||
|
if (dbus_error_is_set(&err)) {
|
||||||
|
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
|
||||||
|
LOG_AND_FREE_DBUS_ERROR(&err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aValue = (uint32_t)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||||
BluetoothValue& aValue, nsAString& aErrorStr)
|
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||||
@ -235,39 +291,6 @@ UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
|
|
||||||
|
|
||||||
static nsString
|
|
||||||
GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
|
||||||
const nsAString& aDeviceAddress)
|
|
||||||
{
|
|
||||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
|
||||||
// and the adapter path would be the first part of the object path, accoring
|
|
||||||
// to the example above, it's /org/bluez/2906/hci0.
|
|
||||||
nsString devicePath(aAdapterPath);
|
|
||||||
devicePath.AppendLiteral("/dev_");
|
|
||||||
devicePath.Append(aDeviceAddress);
|
|
||||||
devicePath.ReplaceChar(':', '_');
|
|
||||||
return devicePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsString
|
|
||||||
GetAddressFromObjectPath(const nsAString& aObjectPath)
|
|
||||||
{
|
|
||||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
|
||||||
// and the adapter path would be the first part of the object path, accoring
|
|
||||||
// to the example above, it's /org/bluez/2906/hci0.
|
|
||||||
nsString address(aObjectPath);
|
|
||||||
int addressHead = address.RFind("/") + 5;
|
|
||||||
|
|
||||||
MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == address.Length());
|
|
||||||
|
|
||||||
address.Cut(0, addressHead);
|
|
||||||
address.ReplaceChar('_', ':');
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
KeepDBusPairingMessage(const nsString& aDeviceAddress, DBusMessage* aMsg)
|
KeepDBusPairingMessage(const nsString& aDeviceAddress, DBusMessage* aMsg)
|
||||||
{
|
{
|
||||||
@ -485,7 +508,7 @@ RegisterLocalAgent(const char* adapterPath,
|
|||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
if (dbus_error_is_set(&err)) {
|
if (dbus_error_is_set(&err)) {
|
||||||
if(!strcmp(err.name, "org.bluez.Error.AlreadyExists")) {
|
if (!strcmp(err.name, "org.bluez.Error.AlreadyExists")) {
|
||||||
LOG_AND_FREE_DBUS_ERROR(&err);
|
LOG_AND_FREE_DBUS_ERROR(&err);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG("Agent already registered, still returning true");
|
LOG("Agent already registered, still returning true");
|
||||||
@ -577,6 +600,13 @@ GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
|||||||
UnpackVoidMessage);
|
UnpackVoidMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GetIntCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||||
|
{
|
||||||
|
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||||
|
UnpackIntMessage);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
|
GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
|
||||||
int aPropertyTypeLen, int* aPropIndex,
|
int aPropertyTypeLen, int* aPropIndex,
|
||||||
@ -789,7 +819,7 @@ ParsePropertyChange(DBusMessage* aMsg, BluetoothValue& aValue,
|
|||||||
|
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
if (!dbus_message_iter_init(aMsg, &iter)) {
|
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||||
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
NS_WARNING("Can't create iterator!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,7 +841,8 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||||||
NS_ASSERTION(!NS_IsMainThread(), "Shouldn't be called from Main Thread!");
|
NS_ASSERTION(!NS_IsMainThread(), "Shouldn't be called from Main Thread!");
|
||||||
|
|
||||||
if (dbus_message_get_type(aMsg) != DBUS_MESSAGE_TYPE_SIGNAL) {
|
if (dbus_message_get_type(aMsg) != DBUS_MESSAGE_TYPE_SIGNAL) {
|
||||||
LOG("%s: not interested (not a signal).\n", __FUNCTION__);
|
LOG("%s: event handler not interested in %s (not a signal).\n",
|
||||||
|
__FUNCTION__, dbus_message_get_member(aMsg));
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,8 +899,9 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||||||
DBUS_TYPE_INVALID)) {
|
DBUS_TYPE_INVALID)) {
|
||||||
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
||||||
errorStr.AssignLiteral("Cannot parse device address!");
|
errorStr.AssignLiteral("Cannot parse device address!");
|
||||||
|
} else {
|
||||||
|
v = NS_ConvertUTF8toUTF16(str);
|
||||||
}
|
}
|
||||||
v = NS_ConvertUTF8toUTF16(str);
|
|
||||||
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceCreated")) {
|
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceCreated")) {
|
||||||
const char* str;
|
const char* str;
|
||||||
if (!dbus_message_get_args(aMsg, &err,
|
if (!dbus_message_get_args(aMsg, &err,
|
||||||
@ -877,8 +909,19 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||||||
DBUS_TYPE_INVALID)) {
|
DBUS_TYPE_INVALID)) {
|
||||||
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
||||||
errorStr.AssignLiteral("Cannot parse device path!");
|
errorStr.AssignLiteral("Cannot parse device path!");
|
||||||
|
} else {
|
||||||
|
v = NS_ConvertUTF8toUTF16(str);
|
||||||
|
}
|
||||||
|
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceRemoved")) {
|
||||||
|
const char* str;
|
||||||
|
if (!dbus_message_get_args(aMsg, &err,
|
||||||
|
DBUS_TYPE_OBJECT_PATH, &str,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
|
||||||
|
errorStr.AssignLiteral("Cannot parse device path!");
|
||||||
|
} else {
|
||||||
|
v = NS_ConvertUTF8toUTF16(str);
|
||||||
}
|
}
|
||||||
v = NS_ConvertUTF8toUTF16(str);
|
|
||||||
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "PropertyChanged")) {
|
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "PropertyChanged")) {
|
||||||
ParsePropertyChange(aMsg,
|
ParsePropertyChange(aMsg,
|
||||||
v,
|
v,
|
||||||
@ -1071,10 +1114,10 @@ public:
|
|||||||
"DefaultAdapter",
|
"DefaultAdapter",
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
UnpackObjectPathMessage(msg, &err, v, replyError);
|
UnpackObjectPathMessage(msg, &err, v, replyError);
|
||||||
if(msg) {
|
if (msg) {
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
}
|
}
|
||||||
if(!replyError.IsEmpty()) {
|
if (!replyError.IsEmpty()) {
|
||||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
@ -1093,11 +1136,11 @@ public:
|
|||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
UnpackAdapterPropertiesMessage(msg, &err, v, replyError);
|
UnpackAdapterPropertiesMessage(msg, &err, v, replyError);
|
||||||
|
|
||||||
if(!replyError.IsEmpty()) {
|
if (!replyError.IsEmpty()) {
|
||||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
if(msg) {
|
if (msg) {
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
}
|
}
|
||||||
// We have to manually attach the path to the rest of the elements
|
// We have to manually attach the path to the rest of the elements
|
||||||
@ -1145,6 +1188,7 @@ BluetoothDBusService::SendDiscoveryMessage(const nsAString& aAdapterPath,
|
|||||||
NS_WARNING("Bluetooth service not started yet!");
|
NS_WARNING("Bluetooth service not started yet!");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||||
@ -1385,9 +1429,9 @@ BluetoothDBusService::GetDevicePath(const nsAString& aAdapterPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
BluetoothDBusService::GetDeviceServiceChannelInternal(const nsAString& aObjectPath,
|
GetDeviceServiceChannel(const nsAString& aObjectPath,
|
||||||
const nsAString& aPattern,
|
const nsAString& aPattern,
|
||||||
int aAttributeId)
|
int aAttributeId)
|
||||||
{
|
{
|
||||||
// This is a blocking call, should not be run on main thread.
|
// This is a blocking call, should not be run on main thread.
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
@ -1690,3 +1734,133 @@ BluetoothDBusService::SetAuthorizationInternal(const nsAString& aDeviceAddress,
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CreateBluetoothSocketRunnable : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CreateBluetoothSocketRunnable(BluetoothReplyRunnable* aRunnable,
|
||||||
|
const nsAString& aObjectPath,
|
||||||
|
const nsAString& aServiceUUID,
|
||||||
|
int aType,
|
||||||
|
bool aAuth,
|
||||||
|
bool aEncrypt)
|
||||||
|
: mRunnable(dont_AddRef(aRunnable)),
|
||||||
|
mObjectPath(aObjectPath),
|
||||||
|
mServiceUUID(aServiceUUID),
|
||||||
|
mType(aType),
|
||||||
|
mAuth(aAuth),
|
||||||
|
mEncrypt(aEncrypt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Run()
|
||||||
|
{
|
||||||
|
NS_WARNING("Running create socket!\n");
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
|
nsString address = GetAddressFromObjectPath(mObjectPath);
|
||||||
|
int channel = GetDeviceServiceChannel(mObjectPath, mServiceUUID, 0x0004);
|
||||||
|
int fd = mozilla::ipc::GetNewSocket(mType, NS_ConvertUTF16toUTF8(address).get(),
|
||||||
|
channel, mAuth, mEncrypt);
|
||||||
|
BluetoothValue v;
|
||||||
|
nsString replyError;
|
||||||
|
if (fd < 0) {
|
||||||
|
replyError.AssignLiteral("SocketConnectionError");
|
||||||
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = (uint32_t)fd;
|
||||||
|
|
||||||
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||||
|
nsString mObjectPath;
|
||||||
|
nsString mServiceUUID;
|
||||||
|
int mType;
|
||||||
|
bool mAuth;
|
||||||
|
bool mEncrypt;
|
||||||
|
};
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BluetoothDBusService::GetSocketViaService(const nsAString& aObjectPath,
|
||||||
|
const nsAString& aService,
|
||||||
|
int aType,
|
||||||
|
bool aAuth,
|
||||||
|
bool aEncrypt,
|
||||||
|
BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
|
||||||
|
if (!mConnection || !gThreadConnection) {
|
||||||
|
NS_ERROR("Bluetooth service not started yet!");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||||
|
|
||||||
|
nsRefPtr<nsRunnable> func(new CreateBluetoothSocketRunnable(runnable, aObjectPath,
|
||||||
|
aService, aType,
|
||||||
|
aAuth, aEncrypt));
|
||||||
|
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
|
||||||
|
NS_WARNING("Cannot dispatch firmware loading task!");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
runnable.forget();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CloseBluetoothSocketRunnable : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CloseBluetoothSocketRunnable(BluetoothReplyRunnable* aRunnable,
|
||||||
|
int aFd)
|
||||||
|
: mRunnable(dont_AddRef(aRunnable)),
|
||||||
|
mFd(aFd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Run()
|
||||||
|
{
|
||||||
|
BluetoothValue v;
|
||||||
|
nsString replyError;
|
||||||
|
if (mozilla::ipc::CloseSocket(mFd) != 0) {
|
||||||
|
replyError.AssignLiteral("SocketConnectionError");
|
||||||
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||||
|
int mFd;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
BluetoothDBusService::CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
|
||||||
|
if (!mConnection || !gThreadConnection) {
|
||||||
|
NS_ERROR("Bluetooth service not started yet!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||||
|
|
||||||
|
nsRefPtr<nsRunnable> func(new CloseBluetoothSocketRunnable(runnable, aFd));
|
||||||
|
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
|
||||||
|
NS_WARNING("Cannot dispatch firmware loading task!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
runnable.forget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -46,10 +46,6 @@ public:
|
|||||||
GetDevicePath(const nsAString& aAdapterPath,
|
GetDevicePath(const nsAString& aAdapterPath,
|
||||||
const nsAString& aDeviceAddress,
|
const nsAString& aDeviceAddress,
|
||||||
nsAString& aDevicePath);
|
nsAString& aDevicePath);
|
||||||
virtual int
|
|
||||||
GetDeviceServiceChannelInternal(const nsAString& aObjectPath,
|
|
||||||
const nsAString& aPattern,
|
|
||||||
int aAttributeId);
|
|
||||||
|
|
||||||
virtual nsTArray<uint32_t>
|
virtual nsTArray<uint32_t>
|
||||||
AddReservedServicesInternal(const nsAString& aAdapterPath,
|
AddReservedServicesInternal(const nsAString& aAdapterPath,
|
||||||
@ -59,6 +55,16 @@ public:
|
|||||||
RemoveReservedServicesInternal(const nsAString& aAdapterPath,
|
RemoveReservedServicesInternal(const nsAString& aAdapterPath,
|
||||||
const nsTArray<uint32_t>& aServiceHandles);
|
const nsTArray<uint32_t>& aServiceHandles);
|
||||||
|
|
||||||
|
virtual nsresult
|
||||||
|
GetSocketViaService(const nsAString& aObjectPath,
|
||||||
|
const nsAString& aService,
|
||||||
|
int aType,
|
||||||
|
bool aAuth,
|
||||||
|
bool aEncrypt,
|
||||||
|
BluetoothReplyRunnable* aRunnable);
|
||||||
|
|
||||||
|
virtual bool CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable);
|
||||||
|
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
CreatePairedDeviceInternal(const nsAString& aAdapterPath,
|
CreatePairedDeviceInternal(const nsAString& aAdapterPath,
|
||||||
const nsAString& aDeviceAddress,
|
const nsAString& aDeviceAddress,
|
||||||
|
@ -14,6 +14,7 @@ interface nsIDOMBluetoothDevice : nsIDOMEventTarget
|
|||||||
readonly attribute DOMString icon;
|
readonly attribute DOMString icon;
|
||||||
[binaryname(DeviceClass)] readonly attribute unsigned long class;
|
[binaryname(DeviceClass)] readonly attribute unsigned long class;
|
||||||
[implicit_jscontext] readonly attribute jsval uuids;
|
[implicit_jscontext] readonly attribute jsval uuids;
|
||||||
|
[implicit_jscontext] readonly attribute jsval services;
|
||||||
readonly attribute bool connected;
|
readonly attribute bool connected;
|
||||||
readonly attribute bool paired;
|
readonly attribute bool paired;
|
||||||
[implicit_jscontext] attribute jsval onpropertychanged;
|
[implicit_jscontext] attribute jsval onpropertychanged;
|
||||||
|
Loading…
Reference in New Issue
Block a user