☠☠ backed out by 4469d30b6943 ☠ ☠ | |
author | Kyle Machulis <kyle@nonpolynomial.com> |
Fri, 13 Apr 2012 22:40:09 -0700 | |
changeset 94973 | db5d4c1aece7290741f14f3f438f196be51ae710 |
parent 94972 | d50bc535870c6765ef10e73120e8eed831f15303 |
child 94974 | 4469d30b694330c086b057ce3e28ab5ae598a4b8 |
push id | 886 |
push user | lsblakk@mozilla.com |
push date | Mon, 04 Jun 2012 19:57:52 +0000 |
treeherder | mozilla-beta@bbd8d5efd6d1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cjones |
bugs | 732639 |
milestone | 14.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/bluetooth/Makefile.in +++ b/dom/bluetooth/Makefile.in @@ -23,10 +23,22 @@ CPPSRCS = \ $(NULL) XPIDLSRCS = \ nsIDOMNavigatorBluetooth.idl \ nsIDOMBluetoothAdapter.idl \ nsIDOMBluetoothDevice.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 +
--- a/dom/system/gonk/SystemWorkerManager.cpp +++ b/dom/system/gonk/SystemWorkerManager.cpp @@ -44,16 +44,19 @@ #include "nsIRadioInterfaceLayer.h" #include "nsIWifi.h" #include "nsIWorkerHolder.h" #include "nsIXPConnect.h" #include "jstypedarray.h" #include "mozilla/dom/workers/Workers.h" #include "mozilla/ipc/Ril.h" +#ifdef MOZ_B2G_BT +#include "mozilla/ipc/DBusThread.h" +#endif #include "nsContentUtils.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" #include "nsRadioInterfaceLayer.h" #include "WifiWorker.h" USING_WORKERS_NAMESPACE @@ -226,16 +229,21 @@ SystemWorkerManager::Init() } rv = InitRIL(cx); NS_ENSURE_SUCCESS(rv, rv); rv = InitWifi(cx); NS_ENSURE_SUCCESS(rv, rv); +#ifdef MOZ_B2G_BT + rv = InitBluetooth(cx); + NS_ENSURE_SUCCESS(rv, rv); +#endif + nsCOMPtr<nsIObserverService> obs = do_GetService(NS_OBSERVERSERVICE_CONTRACTID); if (!obs) { NS_WARNING("Failed to get observer service!"); return NS_ERROR_FAILURE; } rv = obs->AddObserver(this, WORKERS_SHUTDOWN_TOPIC, false); @@ -247,17 +255,19 @@ SystemWorkerManager::Init() void SystemWorkerManager::Shutdown() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); mShutdown = true; StopRil(); - +#ifdef MOZ_B2G_BT + StopDBus(); +#endif mRILWorker = nsnull; nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker)); if (wifi) { wifi->Shutdown(); wifi = nsnull; } mWifiWorker = nsnull; @@ -360,16 +370,29 @@ SystemWorkerManager::InitWifi(JSContext { nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID); NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE); mWifiWorker = worker; return NS_OK; } +nsresult +SystemWorkerManager::InitBluetooth(JSContext *cx) +{ + // nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID); + // NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE); + + // mWifiWorker = worker; +#ifdef MOZ_B2G_BT + StartDBus(); +#endif + return NS_OK; +} + NS_IMPL_ISUPPORTS2(SystemWorkerManager, nsIObserver, nsIInterfaceRequestor) NS_IMETHODIMP SystemWorkerManager::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { if (!strcmp(aTopic, WORKERS_SHUTDOWN_TOPIC)) { Shutdown();
--- a/dom/system/gonk/SystemWorkerManager.h +++ b/dom/system/gonk/SystemWorkerManager.h @@ -73,17 +73,18 @@ public: GetInterfaceRequestor(); private: SystemWorkerManager(); ~SystemWorkerManager(); nsresult InitRIL(JSContext *cx); nsresult InitWifi(JSContext *cx); - + nsresult InitBluetooth(JSContext *cx); + nsCOMPtr<nsIWorkerHolder> mRILWorker; nsCOMPtr<nsIWorkerHolder> mWifiWorker; bool mShutdown; }; } }
--- a/ipc/Makefile.in +++ b/ipc/Makefile.in @@ -42,11 +42,15 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk DIRS += chromium glue ipdl testshell ifdef MOZ_B2G_RIL #{ DIRS += ril endif #} +ifdef MOZ_B2G_BT #{ +DIRS += dbus +endif #} + TOOL_DIRS = app include $(topsrcdir)/config/rules.mk
new file mode 100644 --- /dev/null +++ b/ipc/dbus/DBusThread.cpp @@ -0,0 +1,531 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=2 et sw=2 tw=40: */ +/* + * Copyright 2009, 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. + * + * NOTE: Due to being based on the dbus compatibility layer for + * android's bluetooth implementation, this file is licensed under the + * apache license instead of MPL. + * + */ + +#include "DBusThread.h" +#include "RawDBusConnection.h" +#include "DBusUtils.h" + +#include <dbus/dbus.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/select.h> +#include <sys/types.h> + +#include <string.h> +#include <stdint.h> +#include <stdio.h> +#include <string> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <poll.h> + +#include <list> + +#include "base/eintr_wrapper.h" +#include "base/message_loop.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Monitor.h" +#include "mozilla/Util.h" +#include "mozilla/FileUtils.h" +#include "nsAutoPtr.h" +#include "nsIThread.h" +#include "nsXULAppAPI.h" + +#undef LOG +#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 + +#define DEFAULT_INITIAL_POLLFD_COUNT 8 + +// Functions for converting between unix events in the poll struct, +// and their dbus definitions + +// TODO Add Wakeup to this list once we've moved to ics + +enum { + DBUS_EVENT_LOOP_EXIT = 1, + DBUS_EVENT_LOOP_ADD = 2, + DBUS_EVENT_LOOP_REMOVE = 3, +} DBusEventTypes; + +// Signals that the DBus thread should listen for. Needs to include +// all signals any DBus observer object may need. + +static const char* DBUS_SIGNALS[] = +{ + "type='signal',interface='org.freedesktop.DBus'", + "type='signal',interface='org.bluez.Adapter'", + "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'" +}; + +static unsigned int UnixEventsToDBusFlags(short events) +{ + return (events & DBUS_WATCH_READABLE ? POLLIN : 0) | + (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) | + (events & DBUS_WATCH_ERROR ? POLLERR : 0) | + (events & DBUS_WATCH_HANGUP ? POLLHUP : 0); +} + +static short DBusFlagsToUnixEvents(unsigned int flags) +{ + return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) | + (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) | + (flags & POLLERR ? DBUS_WATCH_ERROR : 0) | + (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0); +} + +namespace mozilla { +namespace ipc { + +struct PollFdComparator { + bool Equals(const pollfd& a, const pollfd& b) const { + return ((a.fd == b.fd) && + (a.events == b.events)); + } + bool LessThan(const pollfd& a, const pollfd&b) const { + return false; + } +}; + +// DBus Thread Class prototype + +struct DBusThread : public RawDBusConnection +{ + DBusThread(); + ~DBusThread(); + + bool StartEventLoop(); + void StopEventLoop(); + bool IsEventLoopRunning(); + static void* EventLoop(void* aPtr); + + // Thread members + pthread_t mThread; + Mutex mMutex; + bool mIsRunning; + + // Information about the sockets we're polling. Socket counts + // increase/decrease depending on how many add/remove watch signals + // we're received via the control sockets. + nsTArray<pollfd> mPollData; + nsTArray<DBusWatch*> mWatchData; + + // Sockets for receiving dbus control information (watch + // add/removes, loop shutdown, etc...) + ScopedClose mControlFdR; + ScopedClose mControlFdW; + +protected: + bool SetUpEventLoop(); + bool TearDownData(); + bool TearDownEventLoop(); +}; + +static nsAutoPtr<DBusThread> sDBusThread; + +// DBus utility functions +// Free statics, as they're used as function pointers in dbus setup + +static dbus_bool_t +AddWatch(DBusWatch *aWatch, void *aData) +{ + DBusThread *dbt = (DBusThread *)aData; + + if (dbus_watch_get_enabled(aWatch)) { + // note that we can't just send the watch and inspect it later + // because we may get a removeWatch call before this data is reacted + // to by our eventloop and remove this watch.. reading the add first + // and then inspecting the recently deceased watch would be bad. + char control = DBUS_EVENT_LOOP_ADD; + write(dbt->mControlFdW.mFd, &control, sizeof(char)); + + // TODO change this to dbus_watch_get_unix_fd once we move to ics + int fd = dbus_watch_get_fd(aWatch); + write(dbt->mControlFdW.mFd, &fd, sizeof(int)); + + unsigned int flags = dbus_watch_get_flags(aWatch); + write(dbt->mControlFdW.mFd, &flags, sizeof(unsigned int)); + + write(dbt->mControlFdW.mFd, &aWatch, sizeof(DBusWatch*)); + } + return true; +} + +static void +RemoveWatch(DBusWatch *aWatch, void *aData) +{ + DBusThread *dbt = (DBusThread *)aData; + + char control = DBUS_EVENT_LOOP_REMOVE; + write(dbt->mControlFdW.mFd, &control, sizeof(char)); + + // TODO change this to dbus_watch_get_unix_fd once we move to ics + int fd = dbus_watch_get_fd(aWatch); + write(dbt->mControlFdW.mFd, &fd, sizeof(int)); + + unsigned int flags = dbus_watch_get_flags(aWatch); + write(dbt->mControlFdW.mFd, &flags, sizeof(unsigned int)); +} + +static void +ToggleWatch(DBusWatch *aWatch, void *aData) +{ + if (dbus_watch_get_enabled(aWatch)) { + AddWatch(aWatch, aData); + } else { + RemoveWatch(aWatch, aData); + } +} + +static void +HandleWatchAdd(DBusThread* aDbt) +{ + DBusWatch *watch; + int newFD; + unsigned int flags; + read(aDbt->mControlFdR.mFd, &newFD, sizeof(int)); + read(aDbt->mControlFdR.mFd, &flags, sizeof(unsigned int)); + read(aDbt->mControlFdR.mFd, &watch, sizeof(DBusWatch *)); + short events = DBusFlagsToUnixEvents(flags); + + pollfd p; + p.fd = newFD; + p.revents = 0; + p.events = events; + if(aDbt->mPollData.Contains(p, PollFdComparator())) return; + aDbt->mPollData.AppendElement(p); + aDbt->mWatchData.AppendElement(watch); +} + +static void HandleWatchRemove(DBusThread* aDbt) { + int removeFD; + unsigned int flags; + + read(aDbt->mControlFdR.mFd, &removeFD, sizeof(int)); + read(aDbt->mControlFdR.mFd, &flags, sizeof(unsigned int)); + short events = DBusFlagsToUnixEvents(flags); + pollfd p; + p.fd = removeFD; + p.events = events; + int index = aDbt->mPollData.IndexOf(p, 0, PollFdComparator()); + aDbt->mPollData.RemoveElementAt(index); + + // DBusWatch pointers are maintained by DBus, so we won't leak by + // removing. + 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") + , mIsRunning(false) + , mControlFdR(-1) + , mControlFdW(-1) +{ +} + +DBusThread::~DBusThread() +{ + +} + +bool +DBusThread::SetUpEventLoop() +{ + // If we already have a connection, exit + if(mConnection) { + return false; + } + // If we can't establish a connection to dbus, nothing else will work + if(!Create()) { + return false; + } + + dbus_threads_init_default(); + DBusError err; + dbus_error_init(&err); + + // Add a filter for all incoming messages_base + if (!dbus_connection_add_filter(mConnection, EventFilter, this, NULL)){ + return false; + } + + // Set which messages will be processed by this dbus connection. + // Since we are maintaining a single thread for all the DBus bluez + // signals we want, register all of them in this thread at startup. + // The event handler will sort the destinations out as needed. + for(uint32_t i = 0; i < ArrayLength(DBUS_SIGNALS); ++i) { + dbus_bus_add_match(mConnection, + DBUS_SIGNALS[i], + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return false; + } + } + return true; +} + +bool +DBusThread::TearDownData() +{ + if (mControlFdW.mFd) { + close(mControlFdW.mFd); + mControlFdW.mFd = 0; + } + if (mControlFdR.mFd) { + close(mControlFdR.mFd); + mControlFdR.mFd = 0; + } + mPollData.Clear(); + + // DBusWatch pointers are maintained by DBus, so we won't leak by + // clearing. + mWatchData.Clear(); + return true; +} + +bool +DBusThread::TearDownEventLoop() +{ + MOZ_ASSERT(mConnection); + + DBusError err; + dbus_error_init(&err); + + for(uint32_t i = 0; i < ArrayLength(DBUS_SIGNALS); ++i) { + dbus_bus_remove_match(mConnection, + DBUS_SIGNALS[i], + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + } + + dbus_connection_remove_filter(mConnection, EventFilter, this); + return true; +} + +void* +DBusThread::EventLoop(void *aPtr) +{ + DBusThread* dbt = static_cast<DBusThread*>(aPtr); + MOZ_ASSERT(dbt); + + dbus_connection_set_watch_functions(dbt->mConnection, AddWatch, + RemoveWatch, ToggleWatch, aPtr, NULL); + + dbt->mIsRunning = true; + + while (1) { + poll(dbt->mPollData.Elements(), dbt->mPollData.Length(), -1); + + for (uint32_t i = 0; i < dbt->mPollData.Length(); i++) { + if (!dbt->mPollData[i].revents) { + continue; + } + + if (dbt->mPollData[i].fd == dbt->mControlFdR.mFd) { + char data; + while (recv(dbt->mControlFdR.mFd, &data, sizeof(char), MSG_DONTWAIT) + != -1) { + switch (data) { + case DBUS_EVENT_LOOP_EXIT: + { + dbus_connection_set_watch_functions(dbt->mConnection, + NULL, NULL, NULL, NULL, NULL); + dbt->TearDownEventLoop(); + return NULL; + } + case DBUS_EVENT_LOOP_ADD: + { + HandleWatchAdd(dbt); + break; + } + case DBUS_EVENT_LOOP_REMOVE: + { + HandleWatchRemove(dbt); + break; + } + } + } + } else { + short events = dbt->mPollData[i].revents; + unsigned int flags = UnixEventsToDBusFlags(events); + dbus_watch_handle(dbt->mWatchData[i], flags); + dbt->mPollData[i].revents = 0; + // Break at this point since we don't know if the operation + // was destructive + break; + } + } + while (dbus_connection_dispatch(dbt->mConnection) == + DBUS_DISPATCH_DATA_REMAINS) + {} + } +} + +bool +DBusThread::StartEventLoop() +{ + MutexAutoLock lock(mMutex); + mIsRunning = false; + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(mControlFdR.mFd))) { + TearDownData(); + return false; + } + pollfd p; + p.fd = mControlFdR.mFd; + p.events = POLLIN; + mPollData.AppendElement(p); + // Due to the fact that mPollData and mWatchData have to match, we + // push a null to the front of mWatchData since it has the control + // fd in the first slot of mPollData. + mWatchData.AppendElement((DBusWatch*)NULL); + if (SetUpEventLoop() != true) { + TearDownData(); + return false; + } + pthread_create(&(mThread), NULL, DBusThread::EventLoop, this); + return true; +} + +void +DBusThread::StopEventLoop() +{ + MutexAutoLock lock(mMutex); + if (mIsRunning) { + char data = DBUS_EVENT_LOOP_EXIT; + write(mControlFdW.mFd, &data, sizeof(char)); + void *ret; + pthread_join(mThread, &ret); + TearDownData(); + } + mIsRunning = false; +} + +bool +DBusThread::IsEventLoopRunning() +{ + MutexAutoLock lock(mMutex); + return mIsRunning; +} + +// Startup/Shutdown utility functions + +static void +ConnectDBus(Monitor* aMonitor, bool* aSuccess) +{ + MOZ_ASSERT(!sDBusThread); + + sDBusThread = new DBusThread(); + *aSuccess = true; + if(!sDBusThread->StartEventLoop()) + { + *aSuccess = false; + } + { + MonitorAutoLock lock(*aMonitor); + lock.Notify(); + } +} + +static void +DisconnectDBus(Monitor* aMonitor, bool* aSuccess) +{ + MOZ_ASSERT(sDBusThread); + + *aSuccess = true; + sDBusThread->StopEventLoop(); + sDBusThread = NULL; + { + MonitorAutoLock lock(*aMonitor); + lock.Notify(); + } +} + +bool +StartDBus() +{ + Monitor monitor("StartDBus.monitor"); + bool success; + { + MonitorAutoLock lock(monitor); + + XRE_GetIOMessageLoop()->PostTask( + FROM_HERE, + NewRunnableFunction(ConnectDBus, &monitor, &success)); + lock.Wait(); + } + return success; +} + +bool +StopDBus() +{ + Monitor monitor("StopDBus.monitor"); + bool success; + { + MonitorAutoLock lock(monitor); + + XRE_GetIOMessageLoop()->PostTask( + FROM_HERE, + NewRunnableFunction(DisconnectDBus, &monitor, &success)); + lock.Wait(); + } + return success; +} + +} +}
new file mode 100644 --- /dev/null +++ b/ipc/dbus/DBusThread.h @@ -0,0 +1,25 @@ +/* -*- 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_ipc_dbus_gonk_dbusthread_h__ +#define mozilla_ipc_dbus_gonk_dbusthread_h__ + +namespace mozilla { +namespace ipc { + + +// Starts the DBus thread, which handles returning signals to objects +// that call asynchronous functions. This should be called from the +// main thread at startup. +bool StartDBus(); + +// Stop the DBus thread, assuming it's currently running. Should be +// called from main thread. +bool StopDBus(); +} +} +#endif +
new file mode 100644 --- /dev/null +++ b/ipc/dbus/DBusUtils.cpp @@ -0,0 +1,47 @@ +/* -*- 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 <stdio.h> +#include "dbus/dbus.h" + +#undef LOG +#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 + +namespace mozilla { +namespace ipc { + +void +log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg) +{ + if(msg) { + LOG("%s: D-Bus error in %s: %s (%s)", function, + dbus_message_get_member((msg)), (err)->name, (err)->message); + } else { + LOG("%s: D-Bus error: %s (%s)", __FUNCTION__, + (err)->name, (err)->message); + } + dbus_error_free((err)); +} + +} +}
new file mode 100644 --- /dev/null +++ b/ipc/dbus/DBusUtils.h @@ -0,0 +1,37 @@ +/* -*- 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. +*/ + +#ifndef mozilla_ipc_dbus_dbusutils_h__ +#define mozilla_ipc_dbus_dbusutils_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; + +namespace mozilla { +namespace ipc { +void log_and_free_dbus_error(DBusError* err, const char* function, DBusMessage* msg = NULL); +} +} + +#endif +
new file mode 100644 --- /dev/null +++ b/ipc/dbus/Makefile.in @@ -0,0 +1,44 @@ +# 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/. + +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = ipc +LIBRARY_NAME = mozdbus_s +FORCE_STATIC_LIB = 1 +LIBXUL_LIBRARY = 1 +EXPORT_LIBRARY = 1 + +ifdef MOZ_ENABLE_DBUS + LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) +endif + +EXPORTS_NAMESPACES = mozilla/ipc + +EXPORTS_mozilla/ipc = \ + RawDBusConnection.h \ + DBusThread.h \ + DBusUtils.h \ + $(NULL) + +CPPSRCS += \ + RawDBusConnection.cpp \ + DBusThread.cpp \ + DBusUtils.cpp \ + $(NULL) + +include $(topsrcdir)/config/config.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk + +include $(topsrcdir)/config/rules.mk + +ifdef MOZ_ENABLE_DBUS + CFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) + CXXFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) +endif
new file mode 100644 --- /dev/null +++ b/ipc/dbus/RawDBusConnection.cpp @@ -0,0 +1,30 @@ +/* -*- 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/. */ + +#include "RawDBusConnection.h" +#include <dbus/dbus.h> + +using namespace mozilla::ipc; + +RawDBusConnection::RawDBusConnection() { +} + +RawDBusConnection::~RawDBusConnection() { +} + +bool RawDBusConnection::Create() { + DBusError err; + dbus_error_init(&err); + dbus_threads_init_default(); + mConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + dbus_error_free(&err); + return false; + } + dbus_connection_set_exit_on_disconnect(mConnection, FALSE); + return true; +} +
new file mode 100644 --- /dev/null +++ b/ipc/dbus/RawDBusConnection.h @@ -0,0 +1,41 @@ +/* -*- 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_ipc_dbus_gonk_rawdbusconnection_h__ +#define mozilla_ipc_dbus_gonk_rawdbusconnection_h__ + +#include <string.h> +#include <stdint.h> +#include <stdio.h> +#include <string> +#include <stdlib.h> +#include "mozilla/Scoped.h" +#include "dbus/dbus.h" + +struct DBusConnection; + +namespace mozilla { +namespace ipc { + +class RawDBusConnection +{ + struct ScopedDBusConnectionPtrTraits : ScopedFreePtrTraits<DBusConnection> + { + static void release(DBusConnection* ptr) { dbus_connection_unref(ptr); } + }; + +public: + RawDBusConnection(); + ~RawDBusConnection(); + bool Create(); +protected: + Scoped<ScopedDBusConnectionPtrTraits> mConnection; +}; + +} +} + +#endif
--- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -110,16 +110,20 @@ STATIC_LIBS += \ hal_s \ dombindings_s \ $(NULL) ifdef MOZ_B2G_RIL #{ STATIC_LIBS += mozril_s endif #} +ifdef MOZ_B2G_BT #{ +STATIC_LIBS += mozdbus_s +endif #} + ifdef MOZ_IPDL_TESTS STATIC_LIBS += ipdlunittest_s endif ifeq (Linux,$(OS_ARCH)) ifneq (Android,$(OS_TARGET)) OS_LIBS += -lrt endif @@ -393,16 +397,17 @@ OS_LIBS += \ -lmedia \ -lhardware_legacy \ -lhardware \ -lutils \ -lcutils \ -lcamera_client \ -lbinder \ -lsensorservice \ + -ldbus \ $(NULL) endif EXTRA_DEPS += \ $(topsrcdir)/intl/unicharutil/util/objs.mk \ $(topsrcdir)/rdf/util/src/objs.mk \ $(NULL)