mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 744349 - Create message distribution mechanism for DBus Bluetooth Signals; r=cjones
This commit is contained in:
parent
2cbd830416
commit
8b8e15f423
@ -5,7 +5,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BluetoothAdapter.h"
|
||||
#include "BluetoothFirmware.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMEvent.h"
|
||||
@ -36,3 +36,29 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothAdapter::BluetoothAdapter(const nsCString& name) :
|
||||
mName(name)
|
||||
{
|
||||
}
|
||||
|
||||
BluetoothAdapter::~BluetoothAdapter()
|
||||
{
|
||||
if (NS_FAILED(UnregisterBluetoothEventHandler(mName, this))) {
|
||||
NS_WARNING("Failed to unregister object with observer!");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<BluetoothAdapter>
|
||||
BluetoothAdapter::Create(const nsCString& name) {
|
||||
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(name);
|
||||
if (NS_FAILED(RegisterBluetoothEventHandler(name, adapter))) {
|
||||
NS_WARNING("Failed to register object with observer!");
|
||||
return NULL;
|
||||
}
|
||||
return adapter.forget();
|
||||
}
|
||||
|
||||
void BluetoothAdapter::Notify(const BluetoothEvent& aData) {
|
||||
printf("Got an adapter message!\n");
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIDOMBluetoothAdapter.h"
|
||||
#include "nsIDOMDOMRequest.h"
|
||||
#include "mozilla/Observer.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
@ -18,6 +19,7 @@ BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothAdapter : public nsDOMEventTargetHelper
|
||||
, public nsIDOMBluetoothAdapter
|
||||
, public BluetoothEventObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -28,6 +30,16 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
|
||||
static already_AddRefed<BluetoothAdapter>
|
||||
Create(const nsCString& name);
|
||||
|
||||
void Notify(const BluetoothEvent& aParam);
|
||||
protected:
|
||||
nsCString mName;
|
||||
private:
|
||||
BluetoothAdapter() {}
|
||||
BluetoothAdapter(const nsCString& name);
|
||||
~BluetoothAdapter();
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -7,6 +7,10 @@
|
||||
#ifndef mozilla_dom_bluetooth_bluetoothcommon_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothcommon_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Observer.h"
|
||||
|
||||
#define BEGIN_BLUETOOTH_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace bluetooth {
|
||||
#define END_BLUETOOTH_NAMESPACE \
|
||||
@ -14,6 +18,48 @@
|
||||
#define USING_BLUETOOTH_NAMESPACE \
|
||||
using namespace mozilla::dom::bluetooth;
|
||||
|
||||
class nsIDOMBluetooth;
|
||||
class nsCString;
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
/**
|
||||
* BluetoothEvents usually hand back one of 3 types:
|
||||
*
|
||||
* - 32-bit Int
|
||||
* - String
|
||||
* - Bool
|
||||
*
|
||||
* BluetoothVariant encases the types into a single structure.
|
||||
*/
|
||||
struct BluetoothVariant
|
||||
{
|
||||
uint32_t mUint32;
|
||||
nsCString mString;
|
||||
};
|
||||
|
||||
/**
|
||||
* BluetoothNamedVariant is a variant with a name value, for passing around
|
||||
* things like properties with variant values.
|
||||
*/
|
||||
struct BluetoothNamedVariant
|
||||
{
|
||||
nsCString mName;
|
||||
BluetoothVariant mValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* BluetoothEvent holds a variant value and the name of an event, such as
|
||||
* PropertyChanged or DeviceFound.
|
||||
*/
|
||||
struct BluetoothEvent
|
||||
{
|
||||
nsCString mEventName;
|
||||
nsTArray<BluetoothNamedVariant> mValues;
|
||||
};
|
||||
|
||||
typedef mozilla::Observer<BluetoothEvent> BluetoothEventObserver;
|
||||
typedef mozilla::ObserverList<BluetoothEvent> BluetoothEventObserverList;
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "BluetoothCommon.h"
|
||||
#include "BluetoothFirmware.h"
|
||||
#include "BluetoothAdapter.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIURI.h"
|
||||
@ -30,6 +31,7 @@
|
||||
|
||||
#define DOM_BLUETOOTH_URL_PREF "dom.mozBluetooth.whitelist"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::Preferences;
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
@ -37,17 +39,19 @@ USING_BLUETOOTH_NAMESPACE
|
||||
static void
|
||||
FireEnabled(bool aResult, nsIDOMDOMRequest* aDomRequest)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
|
||||
nsCOMPtr<nsIDOMRequestService> rs =
|
||||
do_GetService("@mozilla.org/dom/dom-request-service;1");
|
||||
|
||||
if (!rs) {
|
||||
NS_WARNING("No DOMRequest Service!");
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::DebugOnly<nsresult> rv = aResult ?
|
||||
rs->FireSuccess(aDomRequest, JSVAL_VOID) :
|
||||
rs->FireError(aDomRequest,
|
||||
NS_LITERAL_STRING("Bluetooth firmware loading failed"));
|
||||
DebugOnly<nsresult> rv =
|
||||
aResult ?
|
||||
rs->FireSuccess(aDomRequest, JSVAL_VOID) :
|
||||
rs->FireError(aDomRequest,
|
||||
NS_LITERAL_STRING("Bluetooth firmware loading failed"));
|
||||
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Bluetooth firmware loading failed");
|
||||
}
|
||||
@ -120,7 +124,8 @@ class ToggleBtResultTask : public nsRunnable
|
||||
class ToggleBtTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtTask(bool aEnabled, nsIDOMDOMRequest* aReq, BluetoothManager* aManager)
|
||||
ToggleBtTask(bool aEnabled, nsIDOMDOMRequest* aReq,
|
||||
BluetoothManager* aManager)
|
||||
: mEnabled(aEnabled),
|
||||
mManagerPtr(aManager),
|
||||
mDOMRequest(aReq)
|
||||
@ -177,11 +182,19 @@ class ToggleBtTask : public nsRunnable
|
||||
};
|
||||
|
||||
BluetoothManager::BluetoothManager(nsPIDOMWindow *aWindow) :
|
||||
mEnabled(false)
|
||||
mEnabled(false),
|
||||
mName(nsDependentCString("/"))
|
||||
{
|
||||
BindToOwner(aWindow);
|
||||
}
|
||||
|
||||
BluetoothManager::~BluetoothManager()
|
||||
{
|
||||
if(NS_FAILED(UnregisterBluetoothEventHandler(mName, this))) {
|
||||
NS_WARNING("Failed to unregister object with observer!");
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothManager::SetEnabled(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
|
||||
{
|
||||
@ -220,12 +233,32 @@ BluetoothManager::GetEnabled(bool* aEnabled)
|
||||
NS_IMETHODIMP
|
||||
BluetoothManager::GetDefaultAdapter(nsIDOMBluetoothAdapter** aAdapter)
|
||||
{
|
||||
//TODO: Implement adapter fetching
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCString path;
|
||||
nsresult rv = GetDefaultAdapterPathInternal(path);
|
||||
if(NS_FAILED(rv)) {
|
||||
NS_WARNING("Cannot fetch adapter path!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr<BluetoothAdapter> adapter = BluetoothAdapter::Create(path);
|
||||
adapter.forget(aAdapter);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<BluetoothManager>
|
||||
BluetoothManager::Create(nsPIDOMWindow* aWindow) {
|
||||
nsRefPtr<BluetoothManager> manager = new BluetoothManager(aWindow);
|
||||
nsDependentCString name("/");
|
||||
if(NS_FAILED(RegisterBluetoothEventHandler(name, manager))) {
|
||||
NS_WARNING("Failed to register object with observer!");
|
||||
return NULL;
|
||||
}
|
||||
return manager.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewBluetoothManager(nsPIDOMWindow* aWindow, nsIDOMBluetoothManager** aBluetoothManager)
|
||||
NS_NewBluetoothManager(nsPIDOMWindow* aWindow,
|
||||
nsIDOMBluetoothManager** aBluetoothManager)
|
||||
{
|
||||
NS_ASSERTION(aWindow, "Null pointer!");
|
||||
|
||||
@ -238,8 +271,12 @@ NS_NewBluetoothManager(nsPIDOMWindow* aWindow, nsIDOMBluetoothManager** aBluetoo
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothManager> bluetoothManager = new BluetoothManager(aWindow);
|
||||
nsRefPtr<BluetoothManager> bluetoothManager = BluetoothManager::Create(aWindow);
|
||||
|
||||
bluetoothManager.forget(aBluetoothManager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void BluetoothManager::Notify(const BluetoothEvent& aData) {
|
||||
printf("Received an manager message!\n");
|
||||
}
|
||||
|
@ -10,13 +10,14 @@
|
||||
#include "BluetoothCommon.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIDOMBluetoothManager.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/Observer.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothAdapter;
|
||||
|
||||
class BluetoothManager : public nsDOMEventTargetHelper
|
||||
, public nsIDOMBluetoothManager
|
||||
, public nsIDOMBluetoothManager
|
||||
, public BluetoothEventObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -27,11 +28,18 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothManager,
|
||||
nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothManager(nsPIDOMWindow*);
|
||||
|
||||
inline void SetEnabledInternal(bool aEnabled) {mEnabled = aEnabled;}
|
||||
|
||||
|
||||
static already_AddRefed<BluetoothManager>
|
||||
Create(nsPIDOMWindow* aWindow);
|
||||
void Notify(const BluetoothEvent& aData);
|
||||
private:
|
||||
BluetoothManager() {}
|
||||
BluetoothManager(nsPIDOMWindow* aWindow);
|
||||
~BluetoothManager();
|
||||
bool mEnabled;
|
||||
nsCString mName;
|
||||
|
||||
NS_DECL_EVENT_HANDLER(enabled)
|
||||
|
||||
@ -40,6 +48,7 @@ private:
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
nsresult NS_NewBluetoothManager(nsPIDOMWindow* aWindow, nsIDOMBluetoothManager** aBluetoothManager);
|
||||
nsresult NS_NewBluetoothManager(nsPIDOMWindow* aWindow,
|
||||
nsIDOMBluetoothManager** aBluetoothManager);
|
||||
|
||||
#endif
|
||||
|
77
dom/bluetooth/BluetoothUtils.h
Normal file
77
dom/bluetooth/BluetoothUtils.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=40: */
|
||||
/* 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_bluetoothutils_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothutils_h__
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
/**
|
||||
* BluetoothUtil functions are used to dispatch messages to Bluetooth DOM
|
||||
* objects on the main thread, as well as provide platform indenpendent access
|
||||
* to BT functionality. Tasks for polling for outside messages will usually
|
||||
* happen on the IO Thread (see ipc/dbus for instance), and these messages will
|
||||
* be encased in runnables that will then be distributed via observers managed
|
||||
* here.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a message handler object from message distribution observer.
|
||||
* Must be called from the main thread.
|
||||
*
|
||||
* @param aNodeName Node name of the object
|
||||
* @param aMsgHandler Weak pointer to the object
|
||||
*
|
||||
* @return NS_OK on successful addition to observer, NS_ERROR_FAILED
|
||||
* otherwise
|
||||
*/
|
||||
nsresult RegisterBluetoothEventHandler(const nsCString& aNodeName,
|
||||
BluetoothEventObserver *aMsgHandler);
|
||||
|
||||
/**
|
||||
* Remove a message handler object from message distribution observer.
|
||||
* Must be called from the main thread.
|
||||
*
|
||||
* @param aNodeName Node name of the object
|
||||
* @param aMsgHandler Weak pointer to the object
|
||||
*
|
||||
* @return NS_OK on successful removal from observer service,
|
||||
* NS_ERROR_FAILED otherwise
|
||||
*/
|
||||
nsresult UnregisterBluetoothEventHandler(const nsCString& aNodeName,
|
||||
BluetoothEventObserver *aMsgHandler);
|
||||
|
||||
/**
|
||||
* Returns the path of the default adapter, implemented via a platform
|
||||
* specific method.
|
||||
*
|
||||
* @return Default adapter path/name on success, NULL otherwise
|
||||
*/
|
||||
nsresult GetDefaultAdapterPathInternal(nsCString& aAdapterPath);
|
||||
|
||||
/**
|
||||
* Set up variables and start the platform specific connection. Must
|
||||
* be called from main thread.
|
||||
*
|
||||
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
|
||||
* otherwise
|
||||
*/
|
||||
nsresult StartBluetoothConnection();
|
||||
|
||||
/**
|
||||
* Stop the platform specific connection. Must be called from main
|
||||
* thread.
|
||||
*
|
||||
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
|
||||
* otherwise
|
||||
*/
|
||||
nsresult StopBluetoothConnection();
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
@ -15,6 +15,16 @@ XPIDL_MODULE = dom_bluetooth
|
||||
LIBXUL_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
VPATH += $(srcdir)/linux
|
||||
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_DBUS
|
||||
VPATH += $(srcdir)/linux
|
||||
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
|
||||
CPPSRCS = \
|
||||
@ -23,23 +33,23 @@ CPPSRCS = \
|
||||
BluetoothFirmware.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_DBUS
|
||||
CPPSRCS += BluetoothDBusUtils.cpp
|
||||
endif
|
||||
|
||||
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += BluetoothDBusUtils.cpp
|
||||
endif
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIDOMNavigatorBluetooth.idl \
|
||||
nsIDOMBluetoothManager.idl \
|
||||
nsIDOMBluetoothAdapter.idl \
|
||||
$(NULL)
|
||||
|
||||
ifneq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
CFLAGS += $(MOZ_DBUS_CFLAGS)
|
||||
CXXFLAGS += $(MOZ_DBUS_CFLAGS) -DHAVE_PTHREADS
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq (Linux,$(OS_TARGET))
|
||||
ifdef MOZ_ENABLE_DBUS
|
||||
CFLAGS += $(MOZ_DBUS_GLIB_CFLAGS)
|
||||
CXXFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) -DHAVE_PTHREADS
|
||||
endif
|
||||
endif
|
||||
|
||||
|
270
dom/bluetooth/linux/BluetoothDBusUtils.cpp
Normal file
270
dom/bluetooth/linux/BluetoothDBusUtils.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=40: */
|
||||
/*
|
||||
** Copyright 2006, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "mozilla/ipc/DBusUtils.h"
|
||||
#include "mozilla/ipc/RawDBusConnection.h"
|
||||
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace bluetooth {
|
||||
|
||||
static nsAutoPtr<RawDBusConnection> sDBusConnection;
|
||||
|
||||
#undef LOG
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkDBus", args);
|
||||
#else
|
||||
#define BTDEBUG true
|
||||
#define LOG(args...) if (BTDEBUG) printf(args);
|
||||
#endif
|
||||
|
||||
#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
|
||||
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
|
||||
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
|
||||
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
|
||||
#define BLUEZ_ERROR_IFC "org.bluez.Error"
|
||||
|
||||
static const char* BLUETOOTH_DBUS_SIGNALS[] =
|
||||
{
|
||||
"type='signal',interface='org.freedesktop.DBus'",
|
||||
"type='signal',interface='org.bluez.Adapter'",
|
||||
"type='signal',interface='org.bluez.Manager'",
|
||||
"type='signal',interface='org.bluez.Device'",
|
||||
"type='signal',interface='org.bluez.Input'",
|
||||
"type='signal',interface='org.bluez.Network'",
|
||||
"type='signal',interface='org.bluez.NetworkServer'",
|
||||
"type='signal',interface='org.bluez.HealthDevice'",
|
||||
"type='signal',interface='org.bluez.AudioSink'"
|
||||
};
|
||||
|
||||
typedef nsClassHashtable<nsCStringHashKey, BluetoothEventObserverList >
|
||||
BluetoothEventObserverTable;
|
||||
static nsAutoPtr<BluetoothEventObserverTable> sBluetoothEventObserverTable;
|
||||
|
||||
nsresult
|
||||
RegisterBluetoothEventHandler(const nsCString& aNodeName,
|
||||
BluetoothEventObserver* aHandler)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BluetoothEventObserverList *ol;
|
||||
if (!sBluetoothEventObserverTable->Get(aNodeName, &ol)) {
|
||||
sBluetoothEventObserverTable->Put(aNodeName,
|
||||
new BluetoothEventObserverList());
|
||||
}
|
||||
sBluetoothEventObserverTable->Get(aNodeName, &ol);
|
||||
ol->AddObserver(aHandler);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnregisterBluetoothEventHandler(const nsCString& aNodeName,
|
||||
BluetoothEventObserver* aHandler)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BluetoothEventObserverList *ol;
|
||||
if (!sBluetoothEventObserverTable->Get(aNodeName, &ol)) {
|
||||
NS_WARNING("Node does not exist to remove BluetoothEventListener from!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
sBluetoothEventObserverTable->Get(aNodeName, &ol);
|
||||
ol->RemoveObserver(aHandler);
|
||||
if (ol->Length() == 0) {
|
||||
sBluetoothEventObserverTable->Remove(aNodeName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct DistributeDBusMessageTask : public nsRunnable {
|
||||
|
||||
DistributeDBusMessageTask(DBusMessage* aMsg) : mMsg(aMsg)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (dbus_message_get_path(mMsg.get()) == NULL) {
|
||||
return NS_OK;
|
||||
}
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Notify observers that a message has been sent
|
||||
nsDependentCString path(dbus_message_get_path(mMsg.get()));
|
||||
nsDependentCString member(dbus_message_get_member(mMsg.get()));
|
||||
BluetoothEventObserverList *ol;
|
||||
if (!sBluetoothEventObserverTable->Get(path, &ol)) {
|
||||
LOG("No objects registered for %s, returning\n",
|
||||
dbus_message_get_path(mMsg.get()));
|
||||
return NS_OK;
|
||||
}
|
||||
BluetoothEvent e;
|
||||
e.mEventName = member;
|
||||
ol->Broadcast(e);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DBusMessageRefPtr mMsg;
|
||||
};
|
||||
|
||||
// Called by dbus during WaitForAndDispatchEventNative()
|
||||
// This function is called on the IOThread
|
||||
static DBusHandlerResult
|
||||
EventFilter(DBusConnection *aConn, DBusMessage *aMsg,
|
||||
void *aData)
|
||||
{
|
||||
DBusError err;
|
||||
|
||||
dbus_error_init(&err);
|
||||
|
||||
if (dbus_message_get_type(aMsg) != DBUS_MESSAGE_TYPE_SIGNAL) {
|
||||
LOG("%s: not interested (not a signal).\n", __FUNCTION__);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
LOG("%s: Received signal %s:%s from %s\n", __FUNCTION__,
|
||||
dbus_message_get_interface(aMsg), dbus_message_get_member(aMsg),
|
||||
dbus_message_get_path(aMsg));
|
||||
|
||||
// TODO: Parse DBusMessage* on the IOThread and return as a BluetoothEvent so
|
||||
// we aren't passing the pointer at all, as well as offloading parsing (not
|
||||
// that it's that heavy.)
|
||||
nsCOMPtr<DistributeDBusMessageTask> t(new DistributeDBusMessageTask(aMsg));
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
StartBluetoothConnection()
|
||||
{
|
||||
if(sDBusConnection) {
|
||||
NS_WARNING("DBusConnection already established, skipping");
|
||||
return NS_OK;
|
||||
}
|
||||
sBluetoothEventObserverTable = new BluetoothEventObserverTable();
|
||||
sBluetoothEventObserverTable->Init(100);
|
||||
|
||||
sDBusConnection = new RawDBusConnection();
|
||||
sDBusConnection->EstablishDBusConnection();
|
||||
|
||||
// Add a filter for all incoming messages_base
|
||||
if (!dbus_connection_add_filter(sDBusConnection->mConnection, EventFilter,
|
||||
NULL, NULL)) {
|
||||
NS_WARNING("Cannot create DBus Event Filter for DBus Thread!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
StopBluetoothConnection()
|
||||
{
|
||||
if(!sDBusConnection) {
|
||||
NS_WARNING("DBusConnection does not exist, nothing to stop, skipping.");
|
||||
return NS_OK;
|
||||
}
|
||||
dbus_connection_remove_filter(sDBusConnection->mConnection, EventFilter, NULL);
|
||||
sDBusConnection = NULL;
|
||||
sBluetoothEventObserverTable->Clear();
|
||||
sBluetoothEventObserverTable = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetDefaultAdapterPathInternal(nsCString& aAdapterPath)
|
||||
{
|
||||
DBusMessage *msg = NULL, *reply = NULL;
|
||||
DBusError err;
|
||||
const char *device_path = NULL;
|
||||
int attempt = 0;
|
||||
|
||||
for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
|
||||
msg = dbus_message_new_method_call("org.bluez", "/",
|
||||
"org.bluez.Manager", "DefaultAdapter");
|
||||
if (!msg) {
|
||||
LOG("%s: Can't allocate new method call for get_adapter_path!",
|
||||
__FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
dbus_message_append_args(msg, DBUS_TYPE_INVALID);
|
||||
dbus_error_init(&err);
|
||||
reply = dbus_connection_send_with_reply_and_block(
|
||||
sDBusConnection->mConnection, msg, -1, &err);
|
||||
|
||||
if (!reply) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
if (dbus_error_has_name(&err,
|
||||
"org.freedesktop.DBus.Error.ServiceUnknown")) {
|
||||
// bluetoothd is still down, retry
|
||||
LOG("Service unknown\n");
|
||||
dbus_error_free(&err);
|
||||
//usleep(10000); // 10 ms
|
||||
continue;
|
||||
} else if (dbus_error_has_name(&err,
|
||||
"org.bluez.Error.NoSuchAdapter")) {
|
||||
LOG("No adapter found\n");
|
||||
dbus_error_free(&err);
|
||||
goto failed;
|
||||
} else {
|
||||
// Some other error we weren't expecting
|
||||
LOG("other error\n");
|
||||
dbus_error_free(&err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (attempt == 1000) {
|
||||
LOG("timeout\n");
|
||||
//printfE("Time out while trying to get Adapter path, is bluetoothd up ?");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
|
||||
&device_path, DBUS_TYPE_INVALID)
|
||||
|| !device_path) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
dbus_error_free(&err);
|
||||
}
|
||||
goto failed;
|
||||
}
|
||||
dbus_message_unref(msg);
|
||||
aAdapterPath = nsDependentCString(device_path);
|
||||
return NS_OK;
|
||||
failed:
|
||||
dbus_message_unref(msg);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
#ifdef MOZ_B2G_BT
|
||||
#include "mozilla/ipc/DBusThread.h"
|
||||
#include "BluetoothFirmware.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#endif
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
@ -234,6 +235,7 @@ SystemWorkerManager::Init()
|
||||
NS_WARNING("Failed to initialize Bluetooth!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -395,6 +397,7 @@ SystemWorkerManager::InitBluetooth(JSContext *cx)
|
||||
if(EnsureBluetoothInit()) {
|
||||
#endif
|
||||
StartDBus();
|
||||
StartBluetoothConnection();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
}
|
||||
else {
|
||||
|
@ -45,18 +45,21 @@
|
||||
#include "base/eintr_wrapper.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#undef LOG
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkBluetooth", args);
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkDBus", args);
|
||||
#else
|
||||
#define BTDEBUG true
|
||||
#define LOG(args...) if(BTDEBUG) printf(args);
|
||||
@ -82,6 +85,7 @@ static const char* DBUS_SIGNALS[] =
|
||||
{
|
||||
"type='signal',interface='org.freedesktop.DBus'",
|
||||
"type='signal',interface='org.bluez.Adapter'",
|
||||
"type='signal',interface='org.bluez.Manager'",
|
||||
"type='signal',interface='org.bluez.Device'",
|
||||
"type='signal',interface='org.bluez.Input'",
|
||||
"type='signal',interface='org.bluez.Network'",
|
||||
@ -291,27 +295,6 @@ static void HandleWatchRemove(DBusThread* aDbt) {
|
||||
aDbt->mWatchData.RemoveElementAt(index);
|
||||
}
|
||||
|
||||
// Called by dbus during WaitForAndDispatchEventNative()
|
||||
static DBusHandlerResult
|
||||
EventFilter(DBusConnection *aConn, DBusMessage *aMsg,
|
||||
void *aData)
|
||||
{
|
||||
DBusError err;
|
||||
|
||||
dbus_error_init(&err);
|
||||
|
||||
if (dbus_message_get_type(aMsg) != DBUS_MESSAGE_TYPE_SIGNAL) {
|
||||
LOG("%s: not interested (not a signal).\n", __FUNCTION__);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
LOG("%s: Received signal %s:%s from %s\n", __FUNCTION__,
|
||||
dbus_message_get_interface(aMsg), dbus_message_get_member(aMsg),
|
||||
dbus_message_get_path(aMsg));
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
// DBus Thread Implementation
|
||||
|
||||
DBusThread::DBusThread() : mMutex("DBusGonk.mMutex")
|
||||
@ -337,12 +320,9 @@ DBusThread::SetUpEventLoop()
|
||||
dbus_error_init(&err);
|
||||
|
||||
// If we can't establish a connection to dbus, nothing else will work
|
||||
if(!Create()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add a filter for all incoming messages_base
|
||||
if (!dbus_connection_add_filter(mConnection, EventFilter, this, NULL)){
|
||||
nsresult rv = EstablishDBusConnection();
|
||||
if(NS_FAILED(rv)) {
|
||||
NS_WARNING("Cannot create DBus Connection for DBus Thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -365,7 +345,7 @@ DBusThread::SetUpEventLoop()
|
||||
bool
|
||||
DBusThread::TearDownData()
|
||||
{
|
||||
LOG("Removing DBus Bluetooth Sockets\n");
|
||||
LOG("Removing DBus Sockets\n");
|
||||
if (mControlFdW.get()) {
|
||||
mControlFdW.dispose();
|
||||
}
|
||||
@ -397,7 +377,6 @@ DBusThread::TearDownEventLoop()
|
||||
}
|
||||
}
|
||||
|
||||
dbus_connection_remove_filter(mConnection, EventFilter, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -411,7 +390,7 @@ DBusThread::EventLoop(void *aPtr)
|
||||
RemoveWatch, ToggleWatch, aPtr, NULL);
|
||||
|
||||
dbt->mIsRunning = true;
|
||||
LOG("DBus Bluetooth Event Loop Starting\n");
|
||||
LOG("DBus Event Loop Starting\n");
|
||||
while (1) {
|
||||
poll(dbt->mPollData.Elements(), dbt->mPollData.Length(), -1);
|
||||
|
||||
@ -427,7 +406,7 @@ DBusThread::EventLoop(void *aPtr)
|
||||
switch (data) {
|
||||
case DBUS_EVENT_LOOP_EXIT:
|
||||
{
|
||||
LOG("DBus Bluetooth Event Loop Exiting\n");
|
||||
LOG("DBus Event Loop Exiting\n");
|
||||
dbus_connection_set_watch_functions(dbt->mConnection,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
dbt->TearDownEventLoop();
|
||||
@ -495,7 +474,7 @@ DBusThread::StartEventLoop()
|
||||
TearDownData();
|
||||
return false;
|
||||
}
|
||||
LOG("DBus Bluetooth Thread Starting\n");
|
||||
LOG("DBus Thread Starting\n");
|
||||
pthread_create(&(mThread), NULL, DBusThread::EventLoop, this);
|
||||
return true;
|
||||
}
|
||||
@ -508,12 +487,12 @@ DBusThread::StopEventLoop()
|
||||
char data = DBUS_EVENT_LOOP_EXIT;
|
||||
ssize_t wret = write(mControlFdW.get(), &data, sizeof(char));
|
||||
if(wret < 0) {
|
||||
LOG("Cannot write exit bit to DBus Bluetooth Thread!\n");
|
||||
LOG("Cannot write exit bit to DBus Thread!\n");
|
||||
}
|
||||
void *ret;
|
||||
LOG("DBus Bluetooth Thread Joining\n");
|
||||
LOG("DBus Thread Joining\n");
|
||||
pthread_join(mThread, &ret);
|
||||
LOG("DBus Bluetooth Thread Joined\n");
|
||||
LOG("DBus Thread Joined\n");
|
||||
TearDownData();
|
||||
}
|
||||
mIsRunning = false;
|
||||
@ -535,6 +514,7 @@ ConnectDBus(Monitor* aMonitor, bool* aSuccess)
|
||||
NS_WARNING("Trying to start DBus Thread that is already currently running, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
sDBusThread = new DBusThread();
|
||||
*aSuccess = true;
|
||||
if(!sDBusThread->StartEventLoop())
|
||||
@ -554,6 +534,7 @@ DisconnectDBus(Monitor* aMonitor, bool* aSuccess)
|
||||
NS_WARNING("Trying to shutdown DBus Thread that is not currently running, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
*aSuccess = true;
|
||||
sDBusThread->StopEventLoop();
|
||||
sDBusThread = NULL;
|
||||
|
@ -7,18 +7,30 @@
|
||||
#ifndef mozilla_ipc_dbus_gonk_dbusthread_h__
|
||||
#define mozilla_ipc_dbus_gonk_dbusthread_h__
|
||||
|
||||
struct DBusMessage;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class nsCString;
|
||||
|
||||
// Starts the DBus thread, which handles returning signals to objects
|
||||
// that call asynchronous functions. This should be called from the
|
||||
// main thread at startup.
|
||||
/**
|
||||
* Starts the DBus thread, which handles returning signals to objects
|
||||
* that call asynchronous functions. This should be called from the
|
||||
* main thread at startup.
|
||||
*
|
||||
* @return True on thread starting correctly, false otherwise
|
||||
*/
|
||||
bool StartDBus();
|
||||
|
||||
// Stop the DBus thread, assuming it's currently running. Should be
|
||||
// called from main thread.
|
||||
/**
|
||||
* Stop the DBus thread, assuming it's currently running. Should be
|
||||
* called from main thread.
|
||||
*
|
||||
* @return True on thread stopping correctly, false otherwise
|
||||
*/
|
||||
bool StopDBus();
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -16,8 +16,9 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dbus/dbus.h"
|
||||
#include "DBusUtils.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#undef LOG
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
@ -27,6 +28,10 @@
|
||||
#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 {
|
||||
|
||||
@ -43,5 +48,216 @@ log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg)
|
||||
dbus_error_free((err));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
void (*user_cb)(DBusMessage *, void *, void *);
|
||||
void *user;
|
||||
void *nat;
|
||||
} dbus_async_call_t;
|
||||
|
||||
void dbus_func_args_async_callback(DBusPendingCall *call, void *data) {
|
||||
|
||||
dbus_async_call_t *req = (dbus_async_call_t *)data;
|
||||
DBusMessage *msg;
|
||||
|
||||
/* This is guaranteed to be non-NULL, because this function is called only
|
||||
when once the remote method invokation returns. */
|
||||
msg = dbus_pending_call_steal_reply(call);
|
||||
|
||||
if (msg) {
|
||||
if (req->user_cb) {
|
||||
// The user may not deref the message object.
|
||||
req->user_cb(msg, req->user, req->nat);
|
||||
}
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
//dbus_message_unref(req->method);
|
||||
dbus_pending_call_cancel(call);
|
||||
dbus_pending_call_unref(call);
|
||||
free(req);
|
||||
}
|
||||
|
||||
static dbus_bool_t dbus_func_args_async_valist(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
void (*user_cb)(DBusMessage *,
|
||||
void *,
|
||||
void*),
|
||||
void *user,
|
||||
void *nat,
|
||||
const char *path,
|
||||
const char *ifc,
|
||||
const char *func,
|
||||
int first_arg_type,
|
||||
va_list args) {
|
||||
DBusMessage *msg = NULL;
|
||||
const char *name;
|
||||
dbus_async_call_t *pending;
|
||||
dbus_bool_t reply = FALSE;
|
||||
|
||||
/* Compose the command */
|
||||
msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
|
||||
|
||||
if (msg == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Make the call. */
|
||||
pending = (dbus_async_call_t *)malloc(sizeof(dbus_async_call_t));
|
||||
if (pending) {
|
||||
DBusPendingCall *call;
|
||||
|
||||
pending->user_cb = user_cb;
|
||||
pending->user = user;
|
||||
pending->nat = nat;
|
||||
//pending->method = msg;
|
||||
|
||||
reply = dbus_connection_send_with_reply(conn, msg,
|
||||
&call,
|
||||
timeout_ms);
|
||||
if (reply == TRUE) {
|
||||
dbus_pending_call_set_notify(call,
|
||||
dbus_func_args_async_callback,
|
||||
pending,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (msg) dbus_message_unref(msg);
|
||||
return reply;
|
||||
}
|
||||
|
||||
dbus_bool_t dbus_func_args_async(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
void (*reply)(DBusMessage *, void *, void*),
|
||||
void *user,
|
||||
void *nat,
|
||||
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, nat,
|
||||
path, ifc, func,
|
||||
first_arg_type, lst);
|
||||
va_end(lst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// If err is NULL, then any errors will be LOG'd, and free'd and the reply
|
||||
// will be NULL.
|
||||
// If err is not NULL, 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 NULL 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) {
|
||||
|
||||
DBusMessage *msg = NULL, *reply = NULL;
|
||||
const char *name;
|
||||
bool return_error = (err != NULL);
|
||||
|
||||
if (!return_error) {
|
||||
err = (DBusError*)malloc(sizeof(DBusError));
|
||||
dbus_error_init(err);
|
||||
}
|
||||
|
||||
/* Compose the command */
|
||||
msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
|
||||
|
||||
if (msg == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Make the call. */
|
||||
reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout_ms, err);
|
||||
if (!return_error && dbus_error_is_set(err)) {
|
||||
//LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
|
||||
}
|
||||
|
||||
done:
|
||||
if (!return_error) {
|
||||
free(err);
|
||||
}
|
||||
if (msg) dbus_message_unref(msg);
|
||||
return reply;
|
||||
}
|
||||
|
||||
DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
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, NULL,
|
||||
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, NULL,
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,9 @@
|
||||
#ifndef mozilla_ipc_dbus_dbusutils_h__
|
||||
#define mozilla_ipc_dbus_dbusutils_h__
|
||||
|
||||
#include <dbus/dbus.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);
|
||||
@ -29,7 +32,71 @@ struct DBusError;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
void log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg = NULL);
|
||||
|
||||
class DBusMessageRefPtr
|
||||
{
|
||||
public:
|
||||
DBusMessageRefPtr(DBusMessage* aMsg) : mMsg(aMsg)
|
||||
{
|
||||
if (mMsg) dbus_message_ref(mMsg);
|
||||
}
|
||||
~DBusMessageRefPtr()
|
||||
{
|
||||
if (mMsg) dbus_message_unref(mMsg);
|
||||
}
|
||||
operator DBusMessage*() { return mMsg; }
|
||||
DBusMessage* get() { return mMsg; }
|
||||
private:
|
||||
DBusMessage* mMsg;
|
||||
};
|
||||
|
||||
void log_and_free_dbus_error(DBusError* err,
|
||||
const char* function,
|
||||
DBusMessage* msg = NULL);
|
||||
dbus_bool_t dbus_func_args_async(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
void (*reply)(DBusMessage *, void *, void *),
|
||||
void *user,
|
||||
void *nat,
|
||||
const char *path,
|
||||
const char *ifc,
|
||||
const char *func,
|
||||
int first_arg_type,
|
||||
...);
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,15 +15,19 @@ RawDBusConnection::RawDBusConnection() {
|
||||
RawDBusConnection::~RawDBusConnection() {
|
||||
}
|
||||
|
||||
bool RawDBusConnection::Create() {
|
||||
nsresult RawDBusConnection::EstablishDBusConnection() {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
mConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
dbus_error_free(&err);
|
||||
return false;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
dbus_connection_set_exit_on_disconnect(mConnection, FALSE);
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void RawDBusConnection::ScopedDBusConnectionPtrTraits::release(DBusConnection* ptr)
|
||||
{
|
||||
if(ptr) dbus_connection_unref(ptr);
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include "nscore.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "dbus/dbus.h"
|
||||
|
||||
struct DBusConnection;
|
||||
|
||||
@ -24,14 +24,13 @@ class RawDBusConnection
|
||||
{
|
||||
struct ScopedDBusConnectionPtrTraits : ScopedFreePtrTraits<DBusConnection>
|
||||
{
|
||||
static void release(DBusConnection* ptr) { if(ptr) dbus_connection_unref(ptr); }
|
||||
static void release(DBusConnection* ptr);
|
||||
};
|
||||
|
||||
public:
|
||||
RawDBusConnection();
|
||||
~RawDBusConnection();
|
||||
bool Create();
|
||||
protected:
|
||||
nsresult EstablishDBusConnection();
|
||||
Scoped<ScopedDBusConnectionPtrTraits> mConnection;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user