Merge mozilla-central and b2g-inbound

This commit is contained in:
Ed Morley 2013-10-01 12:00:25 +01:00
Родитель 25e60eaf8c 6acdd4dc1e
Коммит 8d280b8489
17 изменённых файлов: 744 добавлений и 912 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{
"revision": "daf039f9ad0433206b3ed738f40f08a62a5eb589",
"revision": "e718a6b9243204fdc8df8877e1fe4e8d78aa98b3",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -9,7 +9,6 @@
#include "BluetoothA2dpManager.h"
#include "BluetoothCommon.h"
#include "BluetoothProfileController.h"
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_dom_bluetooth_bluetootha2dpmanager_h__
#include "BluetoothCommon.h"
#include "BluetoothProfileController.h"
#include "BluetoothProfileManagerBase.h"
BEGIN_BLUETOOTH_NAMESPACE
@ -79,7 +80,7 @@ private:
void NotifyConnectionStatusChanged();
nsString mDeviceAddress;
BluetoothProfileController* mController;
nsRefPtr<BluetoothProfileController> mController;
// A2DP data member
bool mA2dpConnected;

Просмотреть файл

@ -156,7 +156,7 @@ private:
nsTArray<Call> mCurrentCallArray;
nsAutoPtr<BluetoothRilListener> mListener;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
BluetoothProfileController* mController;
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
// If a connection has been established, mSocket will be the socket

Просмотреть файл

@ -10,7 +10,6 @@
#include "BluetoothCommon.h"
#include "BluetoothService.h"
#include "BluetoothProfileController.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"

Просмотреть файл

@ -8,12 +8,11 @@
#define mozilla_dom_bluetooth_bluetoothhidmanager_h__
#include "BluetoothCommon.h"
#include "BluetoothProfileController.h"
#include "BluetoothProfileManagerBase.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothHidManager : public BluetoothProfileManagerBase
{
public:
@ -56,7 +55,7 @@ private:
// data member
bool mConnected;
nsString mDeviceAddress;
BluetoothProfileController* mController;
nsRefPtr<BluetoothProfileController> mController;
};
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -219,7 +219,7 @@ private:
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
BluetoothProfileController* mController;
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<DeviceStorageFile> mDsFile;
// If a connection has been established, mSocket will be the socket

Просмотреть файл

@ -9,6 +9,7 @@
#include "BluetoothUuid.h"
#include "nsAutoPtr.h"
#include "mozilla/RefPtr.h"
BEGIN_BLUETOOTH_NAMESPACE
@ -54,7 +55,7 @@ class BluetoothProfileManagerBase;
class BluetoothReplyRunnable;
typedef void (*BluetoothProfileControllerCallback)();
class BluetoothProfileController
class BluetoothProfileController : public RefCounted<BluetoothProfileController>
{
public:
BluetoothProfileController(const nsAString& aDeviceAddress,
@ -78,7 +79,7 @@ public:
void OnConnect(const nsAString& aErrorStr);
void OnDisconnect(const nsAString& aErrorStr);
uint32_t GetCod()
uint32_t GetCod() const
{
return mCod;
}

Просмотреть файл

@ -177,7 +177,7 @@ static nsString sAdapterPath;
static Atomic<int32_t> sIsPairing(0);
static int sConnectedDeviceCount = 0;
static StaticAutoPtr<Monitor> sStopBluetoothMonitor;
StaticAutoPtr<BluetoothProfileController> sController;
StaticRefPtr<BluetoothProfileController> sController;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
typedef bool (*FilterFunc)(const BluetoothValue&);
@ -890,12 +890,12 @@ AppendDeviceName(BluetoothSignal& aSignal)
nsRefPtr<AppendDeviceNameReplyHandler> handler =
new AppendDeviceNameReplyHandler(nsCString(DBUS_DEVICE_IFACE),
devicePath, aSignal);
bool success = dbus_func_args_async(threadConnection->GetConnection(), 1000,
AppendDeviceNameReplyHandler::Callback,
handler.get(),
NS_ConvertUTF16toUTF8(devicePath).get(),
DBUS_DEVICE_IFACE, "GetProperties",
DBUS_TYPE_INVALID);
bool success = threadConnection->SendWithReply(
AppendDeviceNameReplyHandler::Callback, handler.get(), 1000,
NS_ConvertUTF16toUTF8(devicePath).get(), DBUS_DEVICE_IFACE,
"GetProperties", DBUS_TYPE_INVALID);
NS_ENSURE_TRUE_VOID(success);
handler.forget();
@ -1237,14 +1237,14 @@ private:
new RegisterAgentReplyHandler(aAgentVTable);
MOZ_ASSERT(handler.get());
bool success = dbus_func_args_async(threadConnection->GetConnection(), -1,
RegisterAgentReplyHandler::Callback,
handler.get(),
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "RegisterAgent",
DBUS_TYPE_OBJECT_PATH, &agentPath,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
bool success = threadConnection->SendWithReply(
RegisterAgentReplyHandler::Callback, handler.get(), -1,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "RegisterAgent",
DBUS_TYPE_OBJECT_PATH, &agentPath,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, false);
handler.forget();
@ -1286,13 +1286,13 @@ public:
const dbus_uint32_t* services = sServices;
bool success = dbus_func_args_async(threadConnection->GetConnection(), -1,
DBusReplyHandler::Callback, handler.get(),
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
&services, NS_ARRAY_LENGTH(sServices),
DBUS_TYPE_INVALID);
bool success = threadConnection->SendWithReply(
DBusReplyHandler::Callback, handler.get(), -1,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
&services, NS_ARRAY_LENGTH(sServices), DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
handler.forget();
@ -1587,14 +1587,12 @@ GetDefaultAdapterPath(BluetoothValue& aValue, nsString& aError)
DBusError err;
dbus_error_init(&err);
DBusMessage* msg = dbus_func_args_timeout(gThreadConnection->GetConnection(),
1000,
&err,
"/",
DBUS_MANAGER_IFACE,
"DefaultAdapter",
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(msg, false);
DBusMessage* msg;
bool success = gThreadConnection->SendWithError(&msg, &err, 1000, "/",
DBUS_MANAGER_IFACE,
"DefaultAdapter",
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, false);
UnpackObjectPathMessage(msg, &err, aValue, aError);
@ -1826,14 +1824,13 @@ protected:
return false;
}
bool success = dbus_func_args_async(threadConnection->GetConnection(), 1000,
DefaultAdapterPathReplyHandler::Callback,
handler.get(),
NS_ConvertUTF16toUTF8(mAdapterPath).get(),
DBUS_ADAPTER_IFACE, "GetProperties",
DBUS_TYPE_INVALID);
bool success = threadConnection->SendWithReply(
DefaultAdapterPathReplyHandler::Callback, handler.get(), 1000,
NS_ConvertUTF16toUTF8(mAdapterPath).get(),
DBUS_ADAPTER_IFACE, "GetProperties", DBUS_TYPE_INVALID);
if (!success) {
aReplyError = NS_LITERAL_STRING("dbus_func_args_async failed");
aReplyError = NS_LITERAL_STRING("SendWithReply failed");
return false;
}
@ -1887,12 +1884,12 @@ BluetoothDBusService::GetDefaultAdapterPathInternal(
nsRefPtr<DefaultAdapterPathReplyHandler> handler =
new DefaultAdapterPathReplyHandler(aRunnable);
bool success = dbus_func_args_async(mConnection, 1000,
DefaultAdapterPathReplyHandler::Callback,
handler.get(),
"/",
DBUS_MANAGER_IFACE, "DefaultAdapter",
DBUS_TYPE_INVALID);
bool success = SendWithReply(DefaultAdapterPathReplyHandler::Callback,
handler.get(), 1000,
"/", DBUS_MANAGER_IFACE, "DefaultAdapter",
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
handler.forget();
@ -1931,12 +1928,12 @@ BluetoothDBusService::SendDiscoveryMessage(const char* aMessageName,
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
bool success = dbus_func_args_async(mConnection, -1,
OnSendDiscoveryMessageReply,
static_cast<void*>(aRunnable),
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, aMessageName,
DBUS_TYPE_INVALID);
bool success = SendWithReply(OnSendDiscoveryMessageReply,
static_cast<void*>(aRunnable), -1,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, aMessageName,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
runnable.forget();
@ -1948,7 +1945,7 @@ nsresult
BluetoothDBusService::SendInputMessage(const nsAString& aDeviceAddress,
const nsAString& aMessage)
{
DBusCallback callback;
DBusReplyCallback callback;
if (aMessage.EqualsLiteral("Connect")) {
callback = InputConnectCallback;
} else if (aMessage.EqualsLiteral("Disconnect")) {
@ -1966,7 +1963,7 @@ nsresult
BluetoothDBusService::SendAsyncDBusMessage(const nsAString& aObjectPath,
const char* aInterface,
const nsAString& aMessage,
DBusCallback aCallback)
DBusReplyCallback aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mConnection);
@ -1985,14 +1982,12 @@ BluetoothDBusService::SendAsyncDBusMessage(const nsAString& aObjectPath,
return NS_ERROR_FAILURE;
}
bool ret = dbus_func_args_async(mConnection,
-1,
aCallback,
static_cast<void*>(serviceClass.forget()),
NS_ConvertUTF16toUTF8(aObjectPath).get(),
aInterface,
NS_ConvertUTF16toUTF8(aMessage).get(),
DBUS_TYPE_INVALID);
bool ret = SendWithReply(aCallback,
static_cast<void*>(serviceClass.forget()), -1,
NS_ConvertUTF16toUTF8(aObjectPath).get(),
aInterface, NS_ConvertUTF16toUTF8(aMessage).get(),
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(ret, NS_ERROR_FAILURE);
return NS_OK;
@ -2002,7 +1997,7 @@ nsresult
BluetoothDBusService::SendSinkMessage(const nsAString& aDeviceAddress,
const nsAString& aMessage)
{
DBusCallback callback;
DBusReplyCallback callback;
if (aMessage.EqualsLiteral("Connect")) {
callback = SinkConnectCallback;
} else if (aMessage.EqualsLiteral("Disconnect")) {
@ -2140,13 +2135,12 @@ protected:
nsRefPtr<BluetoothArrayOfDevicePropertiesReplyHandler> handler = this;
bool success =
dbus_func_args_async(threadConnection->GetConnection(), 1000,
BluetoothArrayOfDevicePropertiesReplyHandler::Callback,
handler.get(),
NS_ConvertUTF16toUTF8(mObjectPath).get(),
DBUS_DEVICE_IFACE, "GetProperties",
DBUS_TYPE_INVALID);
bool success = threadConnection->SendWithReply(
BluetoothArrayOfDevicePropertiesReplyHandler::Callback,
handler.get(), 1000,
NS_ConvertUTF16toUTF8(mObjectPath).get(),
DBUS_DEVICE_IFACE, "GetProperties",
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, false);
@ -2299,13 +2293,9 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
// msg is unref'd as part of dbus_func_send_async
if (!dbus_func_send_async(mConnection,
msg,
1000,
GetVoidCallback,
(void*)aRunnable)) {
BT_WARNING("Could not start async function!");
// msg is unref'd as part of SendWithReply
if (!SendWithReply(GetVoidCallback, (void*)aRunnable, 1000, msg)) {
BT_WARNING("SendWithReply failed");
return NS_ERROR_FAILURE;
}
runnable.forget();
@ -2333,17 +2323,10 @@ BluetoothDBusService::RemoveReservedServicesInternal(
const uint32_t* services = aServiceHandles.Elements();
DBusMessage* reply =
dbus_func_args(gThreadConnection->GetConnection(),
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
&services, length, DBUS_TYPE_INVALID);
if (!reply) return false;
dbus_message_unref(reply);
return true;
return gThreadConnection->SendWithError(nullptr, nullptr, -1,
NS_ConvertUTF16toUTF8(sAdapterPath).get(), DBUS_ADAPTER_IFACE,
"RemoveReservedServiceRecords", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
&services, length, DBUS_TYPE_INVALID);
}
nsresult
@ -2373,19 +2356,17 @@ BluetoothDBusService::CreatePairedDeviceInternal(
sIsPairing++;
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
// Then send CreatePairedDevice, it will register a temp device agent then
// unregister it after pairing process is over
bool ret = dbus_func_args_async(mConnection,
aTimeout,
GetObjectPathCallback,
(void*)runnable,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE,
"CreatePairedDevice",
DBUS_TYPE_STRING, &deviceAddress,
DBUS_TYPE_OBJECT_PATH, &deviceAgentPath,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
bool ret = SendWithReply(GetObjectPathCallback, (void*)runnable, aTimeout,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE,
"CreatePairedDevice",
DBUS_TYPE_STRING, &deviceAddress,
DBUS_TYPE_OBJECT_PATH, &deviceAgentPath,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
if (!ret) {
BT_WARNING("Could not start async function!");
return NS_ERROR_FAILURE;
@ -2429,13 +2410,13 @@ BluetoothDBusService::RemoveDeviceInternal(const nsAString& aDeviceAddress,
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
bool success = dbus_func_args_async(mConnection, -1,
OnRemoveDeviceReply,
static_cast<void*>(runnable.get()),
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "RemoveDevice",
DBUS_TYPE_OBJECT_PATH, &cstrDeviceObjectPath,
DBUS_TYPE_INVALID);
bool success = SendWithReply(OnRemoveDeviceReply,
static_cast<void*>(runnable.get()), -1,
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
DBUS_ADAPTER_IFACE, "RemoveDevice",
DBUS_TYPE_OBJECT_PATH, &cstrDeviceObjectPath,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
runnable.forget();
@ -2480,7 +2461,7 @@ BluetoothDBusService::SetPinCodeInternal(const nsAString& aDeviceAddress,
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
result = false;
} else {
result = dbus_func_send(mConnection, nullptr, reply);
result = Send(reply);
}
dbus_message_unref(msg);
@ -2526,7 +2507,7 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
errorStr.AssignLiteral("Couldn't append arguments to dbus message.");
result = false;
} else {
result = dbus_func_send(mConnection, nullptr, reply);
result = Send(reply);
}
dbus_message_unref(msg);
@ -2570,7 +2551,7 @@ BluetoothDBusService::SetPairingConfirmationInternal(
return false;
}
bool result = dbus_func_send(mConnection, nullptr, reply);
bool result = Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
@ -2783,13 +2764,13 @@ BluetoothDBusService::GetServiceChannel(const nsAString& aDeviceAddress,
nsRefPtr<OnGetServiceChannelReplyHandler> handler =
new OnGetServiceChannelReplyHandler(objectPath, aServiceUUID, aManager);
bool success = dbus_func_args_async(mConnection, -1,
OnGetServiceChannelReplyHandler::Callback, handler,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
DBUS_TYPE_STRING, &cstrServiceUUID,
DBUS_TYPE_UINT16, &sProtocolDescriptorList,
DBUS_TYPE_INVALID);
bool success = SendWithReply(OnGetServiceChannelReplyHandler::Callback,
handler, -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
DBUS_TYPE_STRING, &cstrServiceUUID,
DBUS_TYPE_UINT16, &sProtocolDescriptorList,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
handler.forget();
@ -2832,19 +2813,17 @@ BluetoothDBusService::UpdateSdpRecords(const nsAString& aDeviceAddress,
nsString objectPath(GetObjectPathFromAddress(sAdapterPath, aDeviceAddress));
// I choose to use raw pointer here because this is going to be passed as an
// argument into dbus_func_args_async() at once.
// argument into SendWithReply() at once.
OnUpdateSdpRecordsRunnable* callbackRunnable =
new OnUpdateSdpRecordsRunnable(objectPath, aManager);
return dbus_func_args_async(mConnection,
-1,
DiscoverServicesCallback,
(void*)callbackRunnable,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_DEVICE_IFACE,
"DiscoverServices",
DBUS_TYPE_STRING, &EmptyCString(),
DBUS_TYPE_INVALID);
return SendWithReply(DiscoverServicesCallback,
(void*)callbackRunnable, -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_DEVICE_IFACE,
"DiscoverServices",
DBUS_TYPE_STRING, &EmptyCString(),
DBUS_TYPE_INVALID);
}
nsresult
@ -3053,20 +3032,16 @@ BluetoothDBusService::SendMetaData(const nsAString& aTitle,
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
bool ret = dbus_func_args_async(mConnection,
-1,
GetVoidCallback,
(void*)runnable.get(),
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE,
"UpdateMetaData",
DBUS_TYPE_STRING, &title,
DBUS_TYPE_STRING, &artist,
DBUS_TYPE_STRING, &album,
DBUS_TYPE_STRING, &mediaNumber,
DBUS_TYPE_STRING, &totalMediaCount,
DBUS_TYPE_STRING, &duration,
DBUS_TYPE_INVALID);
bool ret = SendWithReply(GetVoidCallback, (void*)runnable.get(), -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE, "UpdateMetaData",
DBUS_TYPE_STRING, &title,
DBUS_TYPE_STRING, &artist,
DBUS_TYPE_STRING, &album,
DBUS_TYPE_STRING, &mediaNumber,
DBUS_TYPE_STRING, &totalMediaCount,
DBUS_TYPE_STRING, &duration,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE_VOID(ret);
runnable.forget();
@ -3154,17 +3129,13 @@ BluetoothDBusService::SendPlayStatus(int64_t aDuration,
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
bool ret = dbus_func_args_async(mConnection,
-1,
GetVoidCallback,
(void*)runnable.get(),
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE,
"UpdatePlayStatus",
DBUS_TYPE_UINT32, &aDuration,
DBUS_TYPE_UINT32, &aPosition,
DBUS_TYPE_UINT32, &tempPlayStatus,
DBUS_TYPE_INVALID);
bool ret = SendWithReply(GetVoidCallback, (void*)runnable.get(), -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE, "UpdatePlayStatus",
DBUS_TYPE_UINT32, &aDuration,
DBUS_TYPE_UINT32, &aPosition,
DBUS_TYPE_UINT32, &tempPlayStatus,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE_VOID(ret);
runnable.forget();
@ -3204,17 +3175,14 @@ BluetoothDBusService::UpdatePlayStatus(uint32_t aDuration,
GetObjectPathFromAddress(sAdapterPath, address);
uint32_t tempPlayStatus = aPlayStatus;
bool ret = dbus_func_args_async(mConnection,
-1,
ControlCallback,
nullptr,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE,
"UpdatePlayStatus",
DBUS_TYPE_UINT32, &aDuration,
DBUS_TYPE_UINT32, &aPosition,
DBUS_TYPE_UINT32, &tempPlayStatus,
DBUS_TYPE_INVALID);
bool ret = SendWithReply(ControlCallback, nullptr, -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE, "UpdatePlayStatus",
DBUS_TYPE_UINT32, &aDuration,
DBUS_TYPE_UINT32, &aPosition,
DBUS_TYPE_UINT32, &tempPlayStatus,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE_VOID(ret);
}
@ -3236,15 +3204,12 @@ BluetoothDBusService::UpdateNotification(ControlEventId aEventId,
GetObjectPathFromAddress(sAdapterPath, address);
uint16_t eventId = aEventId;
bool ret = dbus_func_args_async(mConnection,
-1,
ControlCallback,
nullptr,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE,
"UpdateNotification",
DBUS_TYPE_UINT16, &eventId,
DBUS_TYPE_UINT64, &aData,
DBUS_TYPE_INVALID);
bool ret = SendWithReply(ControlCallback, nullptr, -1,
NS_ConvertUTF16toUTF8(objectPath).get(),
DBUS_CTL_IFACE,
"UpdateNotification",
DBUS_TYPE_UINT16, &eventId,
DBUS_TYPE_UINT64, &aData,
DBUS_TYPE_INVALID);
NS_ENSURE_TRUE_VOID(ret);
}

Просмотреть файл

@ -203,7 +203,7 @@ private:
nsresult SendAsyncDBusMessage(const nsAString& aObjectPath,
const char* aInterface,
const nsAString& aMessage,
void (*aCallback)(DBusMessage*, void*));
mozilla::ipc::DBusReplyCallback aCallback);
};
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
SpecialPowers.addPermission("mobileconnection", true, document);

Просмотреть файл

@ -1427,9 +1427,10 @@ RILContentHelper.prototype = {
receiveMessage: function receiveMessage(msg) {
let request;
debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
let data = msg.json.data;
switch (msg.name) {
case "RIL:CardStateChanged": {
let data = msg.json.data;
case "RIL:CardStateChanged":
if (this.rilContext.cardState != data.cardState) {
this.rilContext.cardState = data.cardState;
this._deliverEvent("_iccListeners",
@ -1437,20 +1438,19 @@ RILContentHelper.prototype = {
null);
}
break;
}
case "RIL:IccInfoChanged":
this.updateIccInfo(msg.json.data);
this.updateIccInfo(data);
this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null);
break;
case "RIL:VoiceInfoChanged":
this.updateConnectionInfo(msg.json.data,
this.updateConnectionInfo(data,
this.rilContext.voiceConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
"notifyVoiceChanged",
null);
break;
case "RIL:DataInfoChanged":
this.updateConnectionInfo(msg.json.data,
this.updateConnectionInfo(data,
this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
"notifyDataChanged",
@ -1459,157 +1459,150 @@ RILContentHelper.prototype = {
case "RIL:OtaStatusChanged":
this._deliverEvent("_mobileConnectionListeners",
"notifyOtaStatusChanged",
[msg.json.data]);
[data]);
break;
case "RIL:GetAvailableNetworks":
this.handleGetAvailableNetworks(msg.json);
this.handleGetAvailableNetworks(data);
break;
case "RIL:NetworkSelectionModeChanged":
this.rilContext.networkSelectionMode = msg.json.data.mode;
this.rilContext.networkSelectionMode = data.mode;
break;
case "RIL:SelectNetwork":
this.handleSelectNetwork(msg.json,
this.handleSelectNetwork(data,
RIL.GECKO_NETWORK_SELECTION_MANUAL);
break;
case "RIL:SelectNetworkAuto":
this.handleSelectNetwork(msg.json,
this.handleSelectNetwork(data,
RIL.GECKO_NETWORK_SELECTION_AUTOMATIC);
break;
case "RIL:VoicemailNotification":
this.handleVoicemailNotification(msg.json.data);
this.handleVoicemailNotification(data);
break;
case "RIL:VoicemailInfoChanged":
this.updateInfo(msg.json.data, this.voicemailInfo);
this.updateInfo(data, this.voicemailInfo);
break;
case "RIL:CardLockResult":
if (msg.json.success) {
let result = new MobileIccCardLockResult(msg.json);
this.fireRequestSuccess(msg.json.requestId, result);
if (data.success) {
let result = new MobileIccCardLockResult(data);
this.fireRequestSuccess(data.requestId, result);
} else {
if (msg.json.rilMessageType == "iccSetCardLock" ||
msg.json.rilMessageType == "iccUnlockCardLock") {
if (data.rilMessageType == "iccSetCardLock" ||
data.rilMessageType == "iccUnlockCardLock") {
this._deliverEvent("_iccListeners",
"notifyIccCardLockError",
[msg.json.lockType, msg.json.retryCount]);
[data.lockType, data.retryCount]);
}
this.fireRequestError(msg.json.requestId, msg.json.errorMsg);
this.fireRequestError(data.requestId, data.errorMsg);
}
break;
case "RIL:CardLockRetryCount":
if (msg.json.success) {
let result = new MobileIccCardLockRetryCount(msg.json);
this.fireRequestSuccess(msg.json.requestId, result);
if (data.success) {
let result = new MobileIccCardLockRetryCount(data);
this.fireRequestSuccess(data.requestId, result);
} else {
this.fireRequestError(msg.json.requestId, msg.json.errorMsg);
this.fireRequestError(data.requestId, data.errorMsg);
}
break;
case "RIL:USSDReceived": {
let data = msg.json.data;
case "RIL:USSDReceived":
this._deliverEvent("_mobileConnectionListeners",
"notifyUssdReceived",
[data.message, data.sessionEnded]);
break;
}
case "RIL:SendMMI":
case "RIL:CancelMMI":
this.handleSendCancelMMI(msg.json);
this.handleSendCancelMMI(data);
break;
case "RIL:StkCommand":
this._deliverEvent("_iccListeners", "notifyStkCommand",
[JSON.stringify(msg.json.data)]);
[JSON.stringify(data)]);
break;
case "RIL:StkSessionEnd":
this._deliverEvent("_iccListeners", "notifyStkSessionEnd", null);
break;
case "RIL:IccOpenChannel":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
msg.json.channel);
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.channel);
break;
case "RIL:IccCloseChannel":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:IccExchangeAPDU":
this.handleIccExchangeAPDU(msg.json);
this.handleIccExchangeAPDU(data);
break;
case "RIL:ReadIccContacts":
this.handleReadIccContacts(msg.json);
this.handleReadIccContacts(data);
break;
case "RIL:UpdateIccContact":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:DataError": {
let data = msg.json.data;
case "RIL:DataError":
this.updateConnectionInfo(data, this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners", "notifyDataError",
[data.errorMsg]);
break;
}
case "RIL:GetCallForwardingOption":
this.handleGetCallForwardingOption(msg.json);
this.handleGetCallForwardingOption(data);
break;
case "RIL:SetCallForwardingOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallBarringOption":
this.handleGetCallBarringOption(msg.json);
this.handleGetCallBarringOption(data);
break;
case "RIL:SetCallBarringOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:ChangeCallBarringPassword":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallWaitingOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
msg.json.enabled);
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.enabled);
break;
case "RIL:SetCallWaitingOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:CfStateChanged": {
let data = msg.json.data;
case "RIL:CfStateChanged":
this._deliverEvent("_mobileConnectionListeners",
"notifyCFStateChange",
[data.success, data.action,
data.reason, data.number,
data.timeSeconds, data.serviceClass]);
break;
}
case "RIL:GetCallingLineIdRestriction":
this.handleGetCallingLineIdRestriction(msg.json);
this.handleGetCallingLineIdRestriction(data);
break;
case "RIL:SetCallingLineIdRestriction":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:CellBroadcastReceived": {
let message = new CellBroadcastMessage(msg.json.data);
let message = new CellBroadcastMessage(data);
this._deliverEvent("_cellBroadcastListeners",
"notifyMessageReceived",
[message]);
break;
}
case "RIL:SetRoamingPreference":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetRoamingPreference":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
msg.json.mode);
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.mode);
break;
case "RIL:ExitEmergencyCbMode":
this.handleExitEmergencyCbMode(msg.json);
this.handleExitEmergencyCbMode(data);
break;
case "RIL:EmergencyCbModeChanged":
let data = msg.json.data;
this._deliverEvent("_mobileConnectionListeners",
"notifyEmergencyCbModeChanged",
[data.active, data.timeoutMs]);
break;
case "RIL:SetVoicePrivacyMode":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetVoicePrivacyMode":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
msg.json.enabled);
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.enabled);
break;
}
},

Просмотреть файл

@ -644,11 +644,14 @@ WorkerMessenger.prototype = {
* @TODO: Bug 815526 - deprecate RILContentHelper.
*/
sendWithIPCMessage: function sendWithIPCMessage(msg, rilMessageType, ipcType) {
this.send(rilMessageType, msg.json.data, function(reply) {
this.send(rilMessageType, msg.json.data, (function(reply) {
ipcType = ipcType || msg.name;
msg.target.sendAsyncMessage(ipcType, reply);
msg.target.sendAsyncMessage(ipcType, {
clientId: this.radioInterface.clientId,
data: reply
});
return false;
});
}).bind(this));
}
};
@ -2307,7 +2310,10 @@ RadioInterface.prototype = {
this._updateCallingLineIdRestrictionPref(response.clirMode);
}
target.sendAsyncMessage("RIL:SendMMI", response);
target.sendAsyncMessage("RIL:SendMMI", {
clientId: this.clientId,
data: response
});
return false;
}).bind(this));
},
@ -2317,7 +2323,10 @@ RadioInterface.prototype = {
message.serviceClass = RIL.ICC_SERVICE_CLASS_VOICE;
this.workerMessenger.send("setCallForward", message, (function(response) {
this._sendCfStateChanged(response);
target.sendAsyncMessage("RIL:SetCallForwardingOption", response);
target.sendAsyncMessage("RIL:SetCallForwardingOption", {
clientId: this.clientId,
data: response
});
return false;
}).bind(this));
},
@ -2331,7 +2340,10 @@ RadioInterface.prototype = {
if (response.success) {
this._updateCallingLineIdRestrictionPref(response.clirMode);
}
target.sendAsyncMessage("RIL:SetCallingLineIdRestriction", response);
target.sendAsyncMessage("RIL:SetCallingLineIdRestriction", {
clientId: this.clientId,
data: response
});
return false;
}).bind(this));
},

Просмотреть файл

@ -16,13 +16,9 @@
** limitations under the License.
*/
#include "DBusUtils.h"
#include "DBusThread.h"
#include "nsThreadUtils.h"
#include "mozilla/Monitor.h"
#include <dbus/dbus.h>
#include "nsAutoPtr.h"
#include <cstdio>
#include <cstring>
#include "DBusUtils.h"
#undef LOG
#if defined(MOZ_WIDGET_GONK)
@ -32,13 +28,46 @@
#define LOG(args...) printf(args);
#endif
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
#define BLUEZ_ERROR_IFC "org.bluez.Error"
namespace mozilla {
namespace ipc {
//
// DBusMessageRefPtr
//
DBusMessageRefPtr::DBusMessageRefPtr(DBusMessage* aMsg)
: mMsg(aMsg)
{
if (mMsg) {
dbus_message_ref(mMsg);
}
}
DBusMessageRefPtr::~DBusMessageRefPtr()
{
if (mMsg) {
dbus_message_unref(mMsg);
}
}
//
// DBusReplyHandler
//
void DBusReplyHandler::Callback(DBusMessage* aReply, void* aData)
{
MOZ_ASSERT(aData);
nsRefPtr<DBusReplyHandler> handler =
already_AddRefed<DBusReplyHandler>(static_cast<DBusReplyHandler*>(aData));
handler->Handle(aReply);
}
//
// Utility functions
//
void
log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg)
{
@ -52,569 +81,6 @@ log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg)
dbus_error_free((err));
}
class DBusConnectionSendRunnableBase : public nsRunnable
{
protected:
DBusConnectionSendRunnableBase(DBusConnection* aConnection,
DBusMessage* aMessage)
: mConnection(aConnection),
mMessage(aMessage)
{
MOZ_ASSERT(mConnection);
MOZ_ASSERT(mMessage);
}
virtual ~DBusConnectionSendRunnableBase()
{ }
DBusConnection* mConnection;
DBusMessageRefPtr mMessage;
};
class DBusConnectionSendSyncRunnable : public DBusConnectionSendRunnableBase
{
public:
bool WaitForCompletion()
{
MOZ_ASSERT(!NS_IsMainThread());
MonitorAutoLock autoLock(mCompletedMonitor);
while (!mCompleted) {
mCompletedMonitor.Wait();
}
return mSuccess;
}
protected:
DBusConnectionSendSyncRunnable(DBusConnection* aConnection,
DBusMessage* aMessage)
: DBusConnectionSendRunnableBase(aConnection, aMessage),
mCompletedMonitor("DBusConnectionSendSyncRunnable.mCompleted"),
mCompleted(false),
mSuccess(false)
{ }
virtual ~DBusConnectionSendSyncRunnable()
{ }
// Call this function at the end of Run() to notify waiting
// threads.
void Completed(bool aSuccess)
{
MonitorAutoLock autoLock(mCompletedMonitor);
MOZ_ASSERT(!mCompleted);
mSuccess = aSuccess;
mCompleted = true;
mCompletedMonitor.Notify();
}
private:
Monitor mCompletedMonitor;
bool mCompleted;
bool mSuccess;
};
//
// Sends a message and returns the message's serial number to the
// disaptching thread. Only run it in DBus thread.
//
class DBusConnectionSendRunnable : public DBusConnectionSendSyncRunnable
{
public:
DBusConnectionSendRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
dbus_uint32_t* aSerial)
: DBusConnectionSendSyncRunnable(aConnection, aMessage),
mSerial(aSerial)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
dbus_bool_t success = dbus_connection_send(mConnection, mMessage, mSerial);
Completed(success == TRUE);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
return NS_OK;
}
protected:
~DBusConnectionSendRunnable()
{ }
private:
dbus_uint32_t* mSerial;
};
dbus_bool_t
dbus_func_send(DBusConnection* aConnection, dbus_uint32_t* aSerial,
DBusMessage* aMessage)
{
nsRefPtr<DBusConnectionSendRunnable> t(
new DBusConnectionSendRunnable(aConnection, aMessage, aSerial));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return FALSE;
}
if (aSerial && !t->WaitForCompletion()) {
return FALSE;
}
return TRUE;
}
static dbus_bool_t
dbus_func_args_send_valist(DBusConnection* aConnection,
dbus_uint32_t* aSerial,
const char* aPath,
const char* aInterface,
const char* aFunction,
int aFirstArgType,
va_list aArgs)
{
// Compose the command...
DBusMessage* message = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
aPath,
aInterface,
aFunction);
if (!message) {
LOG("Could not allocate D-Bus message object!");
goto done;
}
// ... and append arguments.
if (!dbus_message_append_args_valist(message, aFirstArgType, aArgs)) {
LOG("Could not append argument to method call!");
goto done;
}
return dbus_func_send(aConnection, aSerial, message);
done:
if (message) {
dbus_message_unref(message);
}
return FALSE;
}
dbus_bool_t
dbus_func_args_send(DBusConnection* aConnection,
dbus_uint32_t* aSerial,
const char* aPath,
const char* aInterface,
const char* aFunction,
int aFirstArgType, ...)
{
va_list args;
va_start(args, aFirstArgType);
dbus_bool_t success = dbus_func_args_send_valist(aConnection,
aSerial,
aPath,
aInterface,
aFunction,
aFirstArgType,
args);
va_end(args);
return success;
}
//
// Sends a message and executes a callback function for the reply. Only
// run it in DBus thread.
//
class DBusConnectionSendWithReplyRunnable : public DBusConnectionSendRunnableBase
{
private:
class NotifyData
{
public:
NotifyData(void (*aCallback)(DBusMessage*, void*), void* aData)
: mCallback(aCallback),
mData(aData)
{ }
void RunNotifyCallback(DBusMessage* aMessage)
{
if (mCallback) {
mCallback(aMessage, mData);
}
}
private:
void (*mCallback)(DBusMessage*, void*);
void* mData;
};
// Callback function for DBus replies. Only run it in DBus thread.
//
static void Notify(DBusPendingCall* aCall, void* aData)
{
MOZ_ASSERT(!NS_IsMainThread());
nsAutoPtr<NotifyData> data(static_cast<NotifyData*>(aData));
// The reply can be non-null if the timeout
// has been reached.
DBusMessage* reply = dbus_pending_call_steal_reply(aCall);
if (reply) {
data->RunNotifyCallback(reply);
dbus_message_unref(reply);
}
dbus_pending_call_cancel(aCall);
dbus_pending_call_unref(aCall);
}
public:
DBusConnectionSendWithReplyRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
int aTimeout,
void (*aCallback)(DBusMessage*, void*),
void* aData)
: DBusConnectionSendRunnableBase(aConnection, aMessage),
mCallback(aCallback),
mData(aData),
mTimeout(aTimeout)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
// Freed at end of Notify
nsAutoPtr<NotifyData> data(new NotifyData(mCallback, mData));
NS_ENSURE_TRUE(data, NS_ERROR_OUT_OF_MEMORY);
DBusPendingCall* call;
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
mMessage,
&call,
mTimeout);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
success = dbus_pending_call_set_notify(call, Notify, data, nullptr);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
data.forget();
dbus_message_unref(mMessage);
return NS_OK;
};
protected:
~DBusConnectionSendWithReplyRunnable()
{ }
private:
void (*mCallback)(DBusMessage*, void*);
void* mData;
int mTimeout;
};
dbus_bool_t dbus_func_send_async(DBusConnection* conn,
DBusMessage* msg,
int timeout_ms,
void (*user_cb)(DBusMessage*,
void*),
void* user)
{
nsRefPtr<nsIRunnable> t(new DBusConnectionSendWithReplyRunnable(conn, msg,
timeout_ms,
user_cb,
user));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (msg) {
dbus_message_unref(msg);
}
return FALSE;
}
return TRUE;
}
static dbus_bool_t dbus_func_args_async_valist(DBusConnection *conn,
int timeout_ms,
void (*user_cb)(DBusMessage*,
void*),
void *user,
const char *path,
const char *ifc,
const char *func,
int first_arg_type,
va_list args) {
DBusMessage *msg = nullptr;
/* Compose the command */
msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
if (msg == nullptr) {
LOG("Could not allocate D-Bus message object!");
goto done;
}
/* append arguments */
if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
LOG("Could not append argument to method call!");
goto done;
}
return dbus_func_send_async(conn, msg, timeout_ms, user_cb, user);
done:
if (msg) dbus_message_unref(msg);
return FALSE;
}
dbus_bool_t dbus_func_args_async(DBusConnection *conn,
int timeout_ms,
void (*reply)(DBusMessage *, void *),
void *user,
const char *path,
const char *ifc,
const char *func,
int first_arg_type,
...) {
dbus_bool_t ret;
va_list lst;
va_start(lst, first_arg_type);
ret = dbus_func_args_async_valist(conn,
timeout_ms,
reply, user,
path, ifc, func,
first_arg_type, lst);
va_end(lst);
return ret;
}
//
// Sends a message and allows the dispatching thread to wait for the
// reply. Only run it in DBus thread.
//
class DBusConnectionSendAndBlockRunnable : public DBusConnectionSendSyncRunnable
{
private:
static void Notify(DBusPendingCall* aCall, void* aData)
{
DBusConnectionSendAndBlockRunnable* runnable(
static_cast<DBusConnectionSendAndBlockRunnable*>(aData));
runnable->mReply = dbus_pending_call_steal_reply(aCall);
bool success = !!runnable->mReply;
if (runnable->mError) {
success = success && !dbus_error_is_set(runnable->mError);
if (!dbus_set_error_from_message(runnable->mError, runnable->mReply)) {
dbus_error_init(runnable->mError);
}
}
dbus_pending_call_cancel(aCall);
dbus_pending_call_unref(aCall);
runnable->Completed(success);
}
public:
DBusConnectionSendAndBlockRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
int aTimeout,
DBusError* aError)
: DBusConnectionSendSyncRunnable(aConnection, aMessage),
mError(aError),
mReply(nullptr),
mTimeout(aTimeout)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
DBusPendingCall* call = nullptr;
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
mMessage,
&call,
mTimeout);
if (!success) {
if (mError) {
if (!call) {
dbus_set_error(mError, DBUS_ERROR_DISCONNECTED, "Connection is closed");
} else {
dbus_error_init(mError);
}
}
goto done;
}
success = dbus_pending_call_set_notify(call, Notify, this, nullptr);
done:
dbus_message_unref(mMessage);
if (!success) {
Completed(false);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
}
return NS_OK;
}
DBusMessage* GetReply()
{
return mReply;
}
protected:
~DBusConnectionSendAndBlockRunnable()
{ }
private:
DBusError* mError;
DBusMessage* mReply;
int mTimeout;
};
dbus_bool_t
dbus_func_send_and_block(DBusConnection* aConnection,
int aTimeout,
DBusMessage** aReply,
DBusError* aError,
DBusMessage* aMessage)
{
nsRefPtr<DBusConnectionSendAndBlockRunnable> t(
new DBusConnectionSendAndBlockRunnable(aConnection, aMessage,
aTimeout, aError));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return FALSE;
}
if (!t->WaitForCompletion()) {
return FALSE;
}
if (aReply) {
*aReply = t->GetReply();
}
return TRUE;
}
// If err is nullptr, then any errors will be LOG'd, and free'd and the reply
// will be nullptr.
// If err is not nullptr, then it is assumed that dbus_error_init was already
// called, and error's will be returned to the caller without logging. The
// return value is nullptr iff an error was set. The client must free the
// error if set.
DBusMessage* dbus_func_args_timeout_valist(DBusConnection* conn,
int timeout_ms,
DBusError* err,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
va_list args)
{
/* Compose the command */
DBusMessage* msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
if (!msg) {
LOG("Could not allocate D-Bus message object!");
goto done;
}
/* append arguments */
if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
LOG("Could not append argument to method call!");
goto done;
}
DBusMessage* reply;
return dbus_func_send_and_block(conn, timeout_ms, &reply, err, msg) ? reply : nullptr;
done:
if (msg) {
dbus_message_unref(msg);
}
return nullptr;
}
DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
int timeout_ms,
DBusError* err,
const char *path,
const char *ifc,
const char *func,
int first_arg_type,
...) {
DBusMessage *ret;
va_list lst;
va_start(lst, first_arg_type);
ret = dbus_func_args_timeout_valist(conn, timeout_ms, err,
path, ifc, func,
first_arg_type, lst);
va_end(lst);
return ret;
}
DBusMessage * dbus_func_args(DBusConnection *conn,
const char *path,
const char *ifc,
const char *func,
int first_arg_type,
...) {
DBusMessage *ret;
va_list lst;
va_start(lst, first_arg_type);
ret = dbus_func_args_timeout_valist(conn, -1, nullptr,
path, ifc, func,
first_arg_type, lst);
va_end(lst);
return ret;
}
DBusMessage * dbus_func_args_error(DBusConnection *conn,
DBusError *err,
const char *path,
const char *ifc,
const char *func,
int first_arg_type,
...) {
DBusMessage *ret;
va_list lst;
va_start(lst, first_arg_type);
ret = dbus_func_args_timeout_valist(conn, -1, err,
path, ifc, func,
first_arg_type, lst);
va_end(lst);
return ret;
}
int dbus_returns_int32(DBusMessage *reply)
{
DBusError err;
@ -630,15 +96,5 @@ int dbus_returns_int32(DBusMessage *reply)
return ret;
}
void DBusReplyHandler::Callback(DBusMessage* aReply, void* aData)
{
MOZ_ASSERT(aData);
nsRefPtr<DBusReplyHandler> handler =
already_AddRefed<DBusReplyHandler>(static_cast<DBusReplyHandler*>(aData));
handler->Handle(aReply);
}
}
}

Просмотреть файл

@ -19,17 +19,15 @@
#ifndef mozilla_ipc_dbus_dbusutils_h__
#define mozilla_ipc_dbus_dbusutils_h__
#include <dbus/dbus.h>
#include "mozilla/RefPtr.h"
#include "mozilla/Scoped.h"
// LOGE and free a D-Bus error
// Using #define so that __FUNCTION__ resolves usefully
#define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) log_and_free_dbus_error(err, __FUNCTION__, msg);
#define LOG_AND_FREE_DBUS_ERROR(err) log_and_free_dbus_error(err, __FUNCTION__);
struct DBusMessage;
struct DBusError;
struct DBusMessage;
namespace mozilla {
namespace ipc {
@ -37,16 +35,19 @@ namespace ipc {
class DBusMessageRefPtr
{
public:
DBusMessageRefPtr(DBusMessage* aMsg) : mMsg(aMsg)
DBusMessageRefPtr(DBusMessage* aMsg);
~DBusMessageRefPtr();
operator DBusMessage* ()
{
if (mMsg) dbus_message_ref(mMsg);
return mMsg;
}
~DBusMessageRefPtr()
DBusMessage* get()
{
if (mMsg) dbus_message_unref(mMsg);
return mMsg;
}
operator DBusMessage*() { return mMsg; }
DBusMessage* get() { return mMsg; }
private:
DBusMessage* mMsg;
};
@ -89,78 +90,10 @@ protected:
}
};
typedef void (*DBusCallback)(DBusMessage *, void *);
void log_and_free_dbus_error(DBusError* err,
const char* function,
DBusMessage* msg = nullptr);
dbus_bool_t dbus_func_send(DBusConnection *aConnection,
dbus_uint32_t *aSerial,
DBusMessage *aMessage);
dbus_bool_t dbus_func_args_send(DBusConnection *aConnection,
dbus_uint32_t *aSerial,
const char *aPath,
const char *aInterface,
const char *aFunction,
int aFirstArgType, ...);
dbus_bool_t dbus_func_send_async(DBusConnection* conn,
DBusMessage* msg,
int timeout_ms,
DBusCallback user_cb,
void* user);
dbus_bool_t dbus_func_args_async(DBusConnection* conn,
int timeout_ms,
DBusCallback reply,
void* user,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
...);
dbus_bool_t dbus_func_send_and_block(DBusConnection* aConnection,
int aTimeout,
DBusMessage** aReply,
DBusError* aError,
DBusMessage* aMessage);
DBusMessage* dbus_func_args(DBusConnection* conn,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
...);
DBusMessage* dbus_func_args_error(DBusConnection* conn,
DBusError* err,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
...);
DBusMessage* dbus_func_args_timeout(DBusConnection* conn,
int timeout_ms,
DBusError* err,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
...);
DBusMessage* dbus_func_args_timeout_valist(DBusConnection* conn,
int timeout_ms,
DBusError* err,
const char* path,
const char* ifc,
const char* func,
int first_arg_type,
va_list args);
int dbus_returns_int32(DBusMessage *reply);
}

Просмотреть файл

@ -4,11 +4,318 @@
* 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 "RawDBusConnection.h"
#include <dbus/dbus.h>
#include "mozilla/Monitor.h"
#include "nsThreadUtils.h"
#include "DBusThread.h"
#include "DBusUtils.h"
#include "RawDBusConnection.h"
#ifdef LOG
#undef LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args);
#else
#define LOG(args...) printf(args);
#endif
/* TODO: Remove BlueZ constant */
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
using namespace mozilla::ipc;
//
// Runnables
//
namespace mozilla {
namespace ipc {
class DBusConnectionSendRunnableBase : public nsRunnable
{
protected:
DBusConnectionSendRunnableBase(DBusConnection* aConnection,
DBusMessage* aMessage)
: mConnection(aConnection),
mMessage(aMessage)
{
MOZ_ASSERT(mConnection);
MOZ_ASSERT(mMessage);
}
virtual ~DBusConnectionSendRunnableBase()
{ }
DBusConnection* mConnection;
DBusMessageRefPtr mMessage;
};
class DBusConnectionSendSyncRunnable : public DBusConnectionSendRunnableBase
{
public:
bool WaitForCompletion()
{
MOZ_ASSERT(!NS_IsMainThread());
MonitorAutoLock autoLock(mCompletedMonitor);
while (!mCompleted) {
mCompletedMonitor.Wait();
}
return mSuccess;
}
protected:
DBusConnectionSendSyncRunnable(DBusConnection* aConnection,
DBusMessage* aMessage)
: DBusConnectionSendRunnableBase(aConnection, aMessage),
mCompletedMonitor("DBusConnectionSendSyncRunnable.mCompleted"),
mCompleted(false),
mSuccess(false)
{ }
virtual ~DBusConnectionSendSyncRunnable()
{ }
// Call this function at the end of Run() to notify waiting
// threads.
void Completed(bool aSuccess)
{
MonitorAutoLock autoLock(mCompletedMonitor);
MOZ_ASSERT(!mCompleted);
mSuccess = aSuccess;
mCompleted = true;
mCompletedMonitor.Notify();
}
private:
Monitor mCompletedMonitor;
bool mCompleted;
bool mSuccess;
};
//
// Sends a message and returns the message's serial number to the
// disaptching thread. Only run it in DBus thread.
//
class DBusConnectionSendRunnable : public DBusConnectionSendSyncRunnable
{
public:
DBusConnectionSendRunnable(DBusConnection* aConnection,
DBusMessage* aMessage)
: DBusConnectionSendSyncRunnable(aConnection, aMessage)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
dbus_bool_t success = dbus_connection_send(mConnection, mMessage, nullptr);
Completed(success == TRUE);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
return NS_OK;
}
protected:
~DBusConnectionSendRunnable()
{ }
};
//
// Sends a message and executes a callback function for the reply. Only
// run it in DBus thread.
//
class DBusConnectionSendWithReplyRunnable : public DBusConnectionSendRunnableBase
{
private:
class NotifyData
{
public:
NotifyData(DBusReplyCallback aCallback, void* aData)
: mCallback(aCallback),
mData(aData)
{ }
void RunNotifyCallback(DBusMessage* aMessage)
{
if (mCallback) {
mCallback(aMessage, mData);
}
}
private:
DBusReplyCallback mCallback;
void* mData;
};
// Callback function for DBus replies. Only run it in DBus thread.
//
static void Notify(DBusPendingCall* aCall, void* aData)
{
MOZ_ASSERT(!NS_IsMainThread());
nsAutoPtr<NotifyData> data(static_cast<NotifyData*>(aData));
// The reply can be non-null if the timeout
// has been reached.
DBusMessage* reply = dbus_pending_call_steal_reply(aCall);
if (reply) {
data->RunNotifyCallback(reply);
dbus_message_unref(reply);
}
dbus_pending_call_cancel(aCall);
dbus_pending_call_unref(aCall);
}
public:
DBusConnectionSendWithReplyRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
int aTimeout,
DBusReplyCallback aCallback,
void* aData)
: DBusConnectionSendRunnableBase(aConnection, aMessage),
mCallback(aCallback),
mData(aData),
mTimeout(aTimeout)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
// Freed at end of Notify
nsAutoPtr<NotifyData> data(new NotifyData(mCallback, mData));
NS_ENSURE_TRUE(data, NS_ERROR_OUT_OF_MEMORY);
DBusPendingCall* call;
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
mMessage,
&call,
mTimeout);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
success = dbus_pending_call_set_notify(call, Notify, data, nullptr);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
data.forget();
dbus_message_unref(mMessage);
return NS_OK;
};
protected:
~DBusConnectionSendWithReplyRunnable()
{ }
private:
DBusReplyCallback mCallback;
void* mData;
int mTimeout;
};
//
// Legacy interface, don't use in new code
//
// Sends a message and waits for the reply. Only run it in DBus thread.
//
class DBusConnectionSendAndBlockRunnable : public DBusConnectionSendSyncRunnable
{
private:
static void Notify(DBusPendingCall* aCall, void* aData)
{
DBusConnectionSendAndBlockRunnable* runnable(
static_cast<DBusConnectionSendAndBlockRunnable*>(aData));
runnable->mReply = dbus_pending_call_steal_reply(aCall);
bool success = !!runnable->mReply;
if (runnable->mError) {
success = success && !dbus_error_is_set(runnable->mError);
if (!dbus_set_error_from_message(runnable->mError, runnable->mReply)) {
dbus_error_init(runnable->mError);
}
}
dbus_pending_call_cancel(aCall);
dbus_pending_call_unref(aCall);
runnable->Completed(success);
}
public:
DBusConnectionSendAndBlockRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
int aTimeout,
DBusError* aError)
: DBusConnectionSendSyncRunnable(aConnection, aMessage),
mError(aError),
mReply(nullptr),
mTimeout(aTimeout)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
DBusPendingCall* call = nullptr;
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
mMessage,
&call,
mTimeout);
if (success == TRUE) {
success = dbus_pending_call_set_notify(call, Notify, this, nullptr);
} else {
if (mError) {
if (!call) {
dbus_set_error(mError, DBUS_ERROR_DISCONNECTED, "Connection is closed");
} else {
dbus_error_init(mError);
}
}
}
dbus_message_unref(mMessage);
if (!success) {
Completed(false);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
}
return NS_OK;
}
DBusMessage* GetReply()
{
return mReply;
}
protected:
~DBusConnectionSendAndBlockRunnable()
{ }
private:
DBusError* mError;
DBusMessage* mReply;
int mTimeout;
};
}
}
//
// RawDBusConnection
//
bool RawDBusConnection::sDBusIsInit(false);
RawDBusConnection::RawDBusConnection()
@ -43,3 +350,141 @@ void RawDBusConnection::ScopedDBusConnectionPtrTraits::release(DBusConnection* p
dbus_connection_unref(ptr);
}
}
bool RawDBusConnection::Send(DBusMessage* aMessage)
{
nsRefPtr<DBusConnectionSendRunnable> t(
new DBusConnectionSendRunnable(mConnection, aMessage));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return false;
}
return true;
}
bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
void* aData,
int aTimeout,
DBusMessage* aMessage)
{
nsRefPtr<nsIRunnable> t(
new DBusConnectionSendWithReplyRunnable(mConnection, aMessage,
aTimeout, aCallback, aData));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return false;
}
return true;
}
bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
void* aData,
int aTimeout,
const char* aPath,
const char* aIntf,
const char* aFunc,
int aFirstArgType,
...)
{
va_list args;
va_start(args, aFirstArgType);
DBusMessage* msg = BuildDBusMessage(aPath, aIntf, aFunc,
aFirstArgType, args);
va_end(args);
if (!msg) {
return false;
}
return SendWithReply(aCallback, aData, aTimeout, msg);
}
bool RawDBusConnection::SendWithError(DBusMessage** aReply,
DBusError* aError,
int aTimeout,
DBusMessage* aMessage)
{
nsRefPtr<DBusConnectionSendAndBlockRunnable> t(
new DBusConnectionSendAndBlockRunnable(mConnection, aMessage,
aTimeout, aError));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return false;
}
if (!t->WaitForCompletion()) {
return false;
}
if (aReply) {
*aReply = t->GetReply();
}
return false;
}
bool RawDBusConnection::SendWithError(DBusMessage** aReply,
DBusError* aError,
int aTimeout,
const char* aPath,
const char* aIntf,
const char* aFunc,
int aFirstArgType, ...)
{
va_list args;
va_start(args, aFirstArgType);
DBusMessage* msg = BuildDBusMessage(aPath, aIntf, aFunc,
aFirstArgType, args);
va_end(args);
if (!msg) {
return false;
}
return SendWithError(aReply, aError, aTimeout, msg);
}
DBusMessage* RawDBusConnection::BuildDBusMessage(const char* aPath,
const char* aIntf,
const char* aFunc,
int aFirstArgType,
va_list aArgs)
{
DBusMessage* msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
aPath, aIntf, aFunc);
if (!msg) {
LOG("Could not allocate D-Bus message object!");
return nullptr;
}
/* append arguments */
if (!dbus_message_append_args_valist(msg, aFirstArgType, aArgs)) {
LOG("Could not append argument to method call!");
dbus_message_unref(msg);
return nullptr;
}
return msg;
}

Просмотреть файл

@ -7,21 +7,25 @@
#ifndef mozilla_ipc_dbus_gonk_rawdbusconnection_h__
#define mozilla_ipc_dbus_gonk_rawdbusconnection_h__
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <string>
#include "nscore.h"
#include "mozilla/Scoped.h"
#include <mozilla/RefPtr.h>
#include <mozilla/Mutex.h>
struct DBusConnection;
struct DBusError;
struct DBusMessage;
namespace mozilla {
namespace ipc {
typedef void (*DBusReplyCallback)(DBusMessage*, void*);
class RawDBusConnection : public AtomicRefCounted<RawDBusConnection>
{
struct ScopedDBusConnectionPtrTraits : ScopedFreePtrTraits<DBusConnection>
@ -32,12 +36,37 @@ class RawDBusConnection : public AtomicRefCounted<RawDBusConnection>
public:
RawDBusConnection();
virtual ~RawDBusConnection();
nsresult EstablishDBusConnection();
DBusConnection* GetConnection() {
DBusConnection* GetConnection()
{
return mConnection;
}
bool Send(DBusMessage* aMessage);
bool SendWithReply(DBusReplyCallback aCallback, void* aData,
int aTimeout, DBusMessage* aMessage);
bool SendWithReply(DBusReplyCallback aCallback, void* aData,
int aTimeout, const char* aPath, const char* aIntf,
const char *aFunc, int aFirstArgType, ...);
/* Legacy interface, don't use in new code */
bool SendWithError(DBusMessage** aReply, DBusError* aError, int aTimeout,
DBusMessage* aMessage);
/* Legacy interface, don't use in new code */
bool SendWithError(DBusMessage** aReply, DBusError* aError, int aTimeout,
const char* aPath, const char* aIntf, const char* aFunc,
int aFirstArgType, ...);
protected:
DBusMessage* BuildDBusMessage(const char* aPath, const char* aIntf,
const char* aFunc, int aFirstArgType,
va_list args);
Scoped<ScopedDBusConnectionPtrTraits> mConnection;
private: