Bug 997626 - [bluez] Handle RequestPairingConsent event and reply pairing confirmation directly. r=echou, f=btian

Consent pairing event raises under the following conditions:
1. Local IO capabilities are DisplayYesNo and remote IO capabiltiies are DisplayOnly or NoInputNoOutput.
2. Call PairingConsent callback for "incoming" request.
This patch is try to directly reply pairing confirmation for consent cases.

How to test:
1. Initialize pairing request with IO capabilities-NoInputNoOutput as
headset role to b2g phone
2. Check pairing status of bluetooth headset
This commit is contained in:
Shawn Huang 2014-04-22 08:37:01 -04:00
parent d38d849cd5
commit 4bc3688ef5

View File

@ -1162,6 +1162,74 @@ AppendDeviceName(BluetoothSignal& aSignal)
unused << handler.forget(); // picked up by callback handler
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg) && mRunnable) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
static DBusHandlerResult
AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
@ -1331,7 +1399,25 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
dbus_connection_send(conn, reply, nullptr);
dbus_message_unref(reply);
// Do not send an notification to upper layer, too annoying.
// Do not send a notification to upper layer, too annoying.
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, DBUS_AGENT_IFACE, "RequestPairingConsent")) {
// Directly SetPairingconfirmation for RequestPairingConsent here
if (!dbus_message_get_args(msg, nullptr,
DBUS_TYPE_OBJECT_PATH, &objectPath,
DBUS_TYPE_INVALID)) {
errorStr.AssignLiteral("Invalid arguments: RequestPairingConsent()");
goto handle_error;
}
nsString address = GetAddressFromObjectPath(NS_ConvertUTF8toUTF16(objectPath));
sPairingReqTable->Put(address, msg);
Task* task = new SetPairingConfirmationTask(address, true, nullptr);
DispatchToDBusThread(task);
// Increase dbus message reference counts, it will be decreased in
// SetPairingConfirmationTask
dbus_message_ref(msg);
// Do not send a notification to upper layer
return DBUS_HANDLER_RESULT_HANDLED;
} else {
#ifdef DEBUG
@ -3182,68 +3268,6 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
return true;
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mRunnable);
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
DispatchBluetoothReply(mRunnable, v, errorStr);
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
bool
BluetoothDBusService::SetPairingConfirmationInternal(