Bug 756299: Patch 2 - IPC Socket Creation Functions and Type Additions; r=mrbkap

This commit is contained in:
Kyle Machulis 2012-09-05 20:06:20 -07:00
parent 879bd2bb8a
commit 9ac24e5e11
10 changed files with 346 additions and 71 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)
{ {
@ -90,7 +93,7 @@ BluetoothDevice::Unroot()
mIsRooted = false; mIsRooted = false;
} }
} }
void void
BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue) BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
{ {
@ -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;
@ -253,7 +274,18 @@ BluetoothDevice::GetUuids(JSContext* aCx, jsval* aUuids)
} else { } else {
NS_WARNING("UUIDs not yet set!\n"); NS_WARNING("UUIDs not yet set!\n");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
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; return NS_OK;
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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;

View 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

View File

@ -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:
@ -156,15 +190,15 @@ public:
if (!bs) { if (!bs) {
NS_WARNING("BluetoothService not available!"); NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return bs->DistributeSignal(mSignal); return bs->DistributeSignal(mSignal);
} }
}; };
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;
}

View File

@ -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,

View File

@ -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;