mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1246931: Add DBus I/O helpers, r=shuang
The I/O helpers for DBus are based on |RawDBusConnection|'s |Send*| and |Watch| methods. Moving them out of this class will make them available to other modules.
This commit is contained in:
parent
a782f3ba54
commit
8f74b7274d
246
ipc/dbus/DBusHelpers.cpp
Normal file
246
ipc/dbus/DBusHelpers.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "DBusHelpers.h"
|
||||
#include "mozilla/ipc/DBusMessageRefPtr.h"
|
||||
#include "mozilla/ipc/DBusPendingCallRefPtr.h"
|
||||
#include "mozilla/ipc/DBusWatcher.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#undef CHROMIUM_LOG
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args);
|
||||
#else
|
||||
#define CHROMIUM_LOG(args...) printf(args);
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// DBus I/O
|
||||
//
|
||||
|
||||
namespace {
|
||||
|
||||
class Notification final
|
||||
{
|
||||
public:
|
||||
Notification(DBusReplyCallback aCallback, void* aData)
|
||||
: mCallback(aCallback)
|
||||
, mData(aData)
|
||||
{ }
|
||||
|
||||
// Callback function for DBus replies. Only run it on I/O thread.
|
||||
//
|
||||
static void Handle(DBusPendingCall* aCall, void* aData)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
RefPtr<DBusPendingCall> call = already_AddRefed<DBusPendingCall>(aCall);
|
||||
|
||||
UniquePtr<Notification> ntfn(static_cast<Notification*>(aData));
|
||||
|
||||
RefPtr<DBusMessage> reply = already_AddRefed<DBusMessage>(
|
||||
dbus_pending_call_steal_reply(call));
|
||||
|
||||
// The reply can be null if the timeout has been reached.
|
||||
if (reply) {
|
||||
ntfn->RunCallback(reply);
|
||||
}
|
||||
|
||||
dbus_pending_call_cancel(call);
|
||||
}
|
||||
|
||||
private:
|
||||
void RunCallback(DBusMessage* aMessage)
|
||||
{
|
||||
if (mCallback) {
|
||||
mCallback(aMessage, mData);
|
||||
}
|
||||
}
|
||||
|
||||
DBusReplyCallback mCallback;
|
||||
void* mData;
|
||||
};
|
||||
|
||||
static already_AddRefed<DBusMessage>
|
||||
BuildDBusMessage(const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
va_list aArgs)
|
||||
{
|
||||
RefPtr<DBusMessage> msg = already_AddRefed<DBusMessage>(
|
||||
dbus_message_new_method_call(aDestination, aPath, aIntf, aFunc));
|
||||
|
||||
if (!msg) {
|
||||
CHROMIUM_LOG("dbus_message_new_method_call failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto success = dbus_message_append_args_valist(msg, aFirstArgType, aArgs);
|
||||
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_message_append_args_valist failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return msg.forget();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
DBusWatchConnection(DBusConnection* aConnection)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
|
||||
auto success =
|
||||
dbus_connection_set_watch_functions(aConnection,
|
||||
DBusWatcher::AddWatchFunction,
|
||||
DBusWatcher::RemoveWatchFunction,
|
||||
DBusWatcher::ToggleWatchFunction,
|
||||
aConnection, nullptr);
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_connection_set_watch_functions failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DBusUnwatchConnection(DBusConnection* aConnection)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
|
||||
auto success = dbus_connection_set_watch_functions(aConnection,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_connection_set_watch_functions failed");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
DBusSendMessage(DBusConnection* aConnection, DBusMessage* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
MOZ_ASSERT(aMessage);
|
||||
|
||||
auto success = dbus_connection_send(aConnection, aMessage, nullptr);
|
||||
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_connection_send failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback, void* aData,
|
||||
int aTimeout,
|
||||
DBusMessage* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
MOZ_ASSERT(aMessage);
|
||||
|
||||
UniquePtr<Notification> ntfn = MakeUnique<Notification>(aCallback, aData);
|
||||
|
||||
auto call = static_cast<DBusPendingCall*>(nullptr);
|
||||
|
||||
auto success = dbus_connection_send_with_reply(aConnection,
|
||||
aMessage,
|
||||
&call,
|
||||
aTimeout);
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_connection_send_with_reply failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
success = dbus_pending_call_set_notify(call, Notification::Handle,
|
||||
ntfn.get(), nullptr);
|
||||
if (!success) {
|
||||
CHROMIUM_LOG("dbus_pending_call_set_notify failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
Unused << ntfn.release(); // Picked up in |Notification::Handle|
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback,
|
||||
void* aData,
|
||||
int aTimeout,
|
||||
const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
va_list aArgs)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
|
||||
RefPtr<DBusMessage> msg =
|
||||
BuildDBusMessage(aDestination, aPath, aIntf, aFunc, aFirstArgType, aArgs);
|
||||
|
||||
if (!msg) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return DBusSendMessageWithReply(aConnection, aCallback, aData, aTimeout, msg);
|
||||
}
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback,
|
||||
void* aData,
|
||||
int aTimeout,
|
||||
const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
...)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnection);
|
||||
|
||||
va_list args;
|
||||
va_start(args, aFirstArgType);
|
||||
|
||||
auto rv = DBusSendMessageWithReply(aConnection,
|
||||
aCallback, aData,
|
||||
aTimeout,
|
||||
aDestination, aPath, aIntf, aFunc,
|
||||
aFirstArgType, args);
|
||||
va_end(args);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
65
ipc/dbus/DBusHelpers.h
Normal file
65
ipc/dbus/DBusHelpers.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- 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_ipc_DBusHelpers_h
|
||||
#define mozilla_ipc_DBusHelpers_h
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <stdarg.h>
|
||||
#include "nsError.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// DBus I/O
|
||||
//
|
||||
|
||||
typedef void (*DBusReplyCallback)(DBusMessage*, void*);
|
||||
|
||||
nsresult
|
||||
DBusWatchConnection(DBusConnection* aConnection);
|
||||
|
||||
void
|
||||
DBusUnwatchConnection(DBusConnection* aConnection);
|
||||
|
||||
nsresult
|
||||
DBusSendMessage(DBusConnection* aConnection, DBusMessage* aMessage);
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback, void* aData,
|
||||
int aTimeout,
|
||||
DBusMessage* aMessage);
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback,
|
||||
void* aData,
|
||||
int aTimeout,
|
||||
const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
va_list aArgs);
|
||||
|
||||
nsresult
|
||||
DBusSendMessageWithReply(DBusConnection* aConnection,
|
||||
DBusReplyCallback aCallback,
|
||||
void* aData,
|
||||
int aTimeout,
|
||||
const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
...);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ipc_DBusHelpers_h
|
@ -4,70 +4,14 @@
|
||||
* 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 "base/message_loop.h"
|
||||
#include "mozilla/ipc/DBusWatcher.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "RawDBusConnection.h"
|
||||
|
||||
#ifdef CHROMIUM_LOG
|
||||
#undef CHROMIUM_LOG
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args);
|
||||
#else
|
||||
#define CHROMIUM_LOG(args...) printf(args);
|
||||
#endif
|
||||
#include "base/message_loop.h"
|
||||
#include "mozilla/ipc/DBusHelpers.h"
|
||||
#include "mozilla/ipc/DBusWatcher.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// Notification
|
||||
//
|
||||
|
||||
class Notification
|
||||
{
|
||||
public:
|
||||
Notification(DBusReplyCallback aCallback, void* aData)
|
||||
: mCallback(aCallback),
|
||||
mData(aData)
|
||||
{ }
|
||||
|
||||
// Callback function for DBus replies. Only run it on I/O thread.
|
||||
//
|
||||
static void Handle(DBusPendingCall* aCall, void* aData)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(MessageLoop::current());
|
||||
|
||||
nsAutoPtr<Notification> ntfn(static_cast<Notification*>(aData));
|
||||
|
||||
// The reply can be non-null if the timeout has been reached.
|
||||
DBusMessage* reply = dbus_pending_call_steal_reply(aCall);
|
||||
|
||||
if (reply) {
|
||||
ntfn->RunCallback(reply);
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
dbus_pending_call_cancel(aCall);
|
||||
dbus_pending_call_unref(aCall);
|
||||
}
|
||||
|
||||
private:
|
||||
void RunCallback(DBusMessage* aMessage)
|
||||
{
|
||||
if (mCallback) {
|
||||
mCallback(aMessage, mData);
|
||||
}
|
||||
}
|
||||
|
||||
DBusReplyCallback mCallback;
|
||||
void* mData;
|
||||
};
|
||||
|
||||
//
|
||||
// RawDBusConnection
|
||||
//
|
||||
@ -108,33 +52,22 @@ nsresult RawDBusConnection::EstablishDBusConnection()
|
||||
|
||||
bool RawDBusConnection::Watch()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(MessageLoop::current());
|
||||
|
||||
dbus_bool_t success =
|
||||
dbus_connection_set_watch_functions(mConnection,
|
||||
DBusWatcher::AddWatchFunction,
|
||||
DBusWatcher::RemoveWatchFunction,
|
||||
DBusWatcher::ToggleWatchFunction,
|
||||
this->GetConnection(), nullptr);
|
||||
NS_ENSURE_TRUE(success == TRUE, false);
|
||||
|
||||
return true;
|
||||
return NS_SUCCEEDED(DBusWatchConnection(mConnection));
|
||||
}
|
||||
|
||||
bool RawDBusConnection::Send(DBusMessage* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(aMessage);
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(MessageLoop::current());
|
||||
|
||||
dbus_bool_t success = dbus_connection_send(mConnection,
|
||||
aMessage,
|
||||
nullptr);
|
||||
if (success != TRUE) {
|
||||
auto rv = DBusSendMessage(mConnection, aMessage);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
dbus_message_unref(aMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -143,26 +76,14 @@ bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
|
||||
int aTimeout,
|
||||
DBusMessage* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(aMessage);
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(MessageLoop::current());
|
||||
|
||||
nsAutoPtr<Notification> ntfn(new Notification(aCallback, aData));
|
||||
NS_ENSURE_TRUE(ntfn, false);
|
||||
auto rv = DBusSendMessageWithReply(mConnection, aCallback, aData, aTimeout,
|
||||
aMessage);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusPendingCall* call;
|
||||
|
||||
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
|
||||
aMessage,
|
||||
&call,
|
||||
aTimeout);
|
||||
NS_ENSURE_TRUE(success == TRUE, false);
|
||||
|
||||
success = dbus_pending_call_set_notify(call, Notification::Handle,
|
||||
ntfn, nullptr);
|
||||
NS_ENSURE_TRUE(success == TRUE, false);
|
||||
|
||||
ntfn.forget();
|
||||
dbus_message_unref(aMessage);
|
||||
|
||||
return true;
|
||||
@ -178,44 +99,15 @@ bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
|
||||
int aFirstArgType,
|
||||
...)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFirstArgType);
|
||||
DBusMessage* msg = BuildDBusMessage(aDestination, aPath, aIntf, aFunc,
|
||||
aFirstArgType, args);
|
||||
|
||||
auto rv = DBusSendMessageWithReply(mConnection, aCallback, aData,
|
||||
aTimeout, aDestination, aPath, aIntf,
|
||||
aFunc, aFirstArgType, args);
|
||||
va_end(args);
|
||||
|
||||
if (!msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return SendWithReply(aCallback, aData, aTimeout, msg);
|
||||
}
|
||||
|
||||
DBusMessage* RawDBusConnection::BuildDBusMessage(const char* aDestination,
|
||||
const char* aPath,
|
||||
const char* aIntf,
|
||||
const char* aFunc,
|
||||
int aFirstArgType,
|
||||
va_list aArgs)
|
||||
{
|
||||
DBusMessage* msg = dbus_message_new_method_call(aDestination,
|
||||
aPath, aIntf,
|
||||
aFunc);
|
||||
if (!msg) {
|
||||
CHROMIUM_LOG("Could not allocate D-Bus message object!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* append arguments */
|
||||
if (!dbus_message_append_args_valist(msg, aFirstArgType, aArgs)) {
|
||||
CHROMIUM_LOG("Could not append argument to method call!");
|
||||
dbus_message_unref(msg);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return msg;
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,11 +42,6 @@ public:
|
||||
const char *aFunc, int aFirstArgType, ...);
|
||||
|
||||
protected:
|
||||
DBusMessage* BuildDBusMessage(const char* aDestination,
|
||||
const char* aPath, const char* aIntf,
|
||||
const char* aFunc, int aFirstArgType,
|
||||
va_list args);
|
||||
|
||||
RefPtr<DBusConnection> mConnection;
|
||||
|
||||
private:
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
EXPORTS.mozilla.ipc += [
|
||||
'DBusConnectionRefPtr.h',
|
||||
'DBusHelpers.h',
|
||||
'DBusMessageRefPtr.h',
|
||||
'DBusPendingCallRefPtr.h',
|
||||
'DBusUtils.h',
|
||||
@ -14,6 +15,7 @@ EXPORTS.mozilla.ipc += [
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'DBusHelpers.cpp',
|
||||
'DBusUtils.cpp',
|
||||
'DBusWatcher.cpp',
|
||||
'RawDBusConnection.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user