Files
palemoon27/ipc/dbus/DBusHelpers.cpp
roytam1 72eedd88b9 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1266578 - OOM crash if malloc fails in ProcessIncomingMessages(). r=billm (5eca51be20)
- Bug 1261340: Don't refer to |ScopedFreePtrTraits| in |RawDBusConnection|, r=shuang (61996db57c)
- Bug 1246931: Move |DBusWatcher| into its own files, r=shuang (a7fc4a68c3)
- Bug 1246931: Add support for |RefPtr<DBusConnection>| and convert callers, r=shuang (6c07d3e8d3)
- Bug 1246931: Add support for |RefPtr<DBusMessage>|, r=shuang (c0ed14cc2b)
- Bug 1246931: Add support for |RefPtr<DBusPendingCall>|, r=shuang (a007a15699)
- Bug 1246931: Use |DBusConnection| in |DBusWatcher|, r=shuang (11b5eaf535)
- Bug 1246931: Add DBus I/O helpers, r=shuang (be249fa65b)
- Bug 1264398 - Avoid extra assign() on windows in IPC code (r=jld) (0f31b798a3)
- fix Mac again (02991fd77d)
- Bug 1261231: Fix shutdown leak in imgLoader::GetInstance. r=gabor (96e5143c41)
- Bug 1256999 - Use nsIDocument for ImageCacheKey. r=bz r=seth (cd4765ce34)
- Bug 1257101. imgFrame::IsImageComplete says whether we've had pixels decoded to the whole image rect, but it's used to check if the frame is finished decoding. These are different things when the image has more than one progress pass. r=seth (06d619410f)
- Bug 1222596. If RasterImage::LookupFrame does (some) sync decoding and encouters an error we don't want to return the surface with an error. r=seth (c4dbc8e0d5)
- Bug 763784 - Make VectorImage::GetAnimated check for CSS animations. r=dholbert (4d0e5b88eb)
- Bug 1210745 - Update CheckProgressConsistency() to match current ImageLib behavior. r=tn (2317b24fcc)
- Bug 1249576. Add crashtest. (485f03120b)
- Bug 1251091. Add crashtest. (7e1682a1e6)
- Bug 1253362. SVGDocumentWrapper::IsAnimated can be called after SVGDocumentWrapper::DestroyViewer so null check mViewer. r=dholbert (2b4a1c4619)
- Bug 1210745. Change image progress asserts to allow transparency to be posted after the size is posted. r=seth (699f3c5496)
- Bug 1209780. Use the DrawResult return value of imgIContainer::Draw in the cocoa code. r=seth (abaea789e3)
- No Bug - Remove some unnecessary SVGImageContext.h includes and add comments. r=sparky (8232661a23)
- cleanup style (de33e4bfa8)
- Bug 860857, support custom datatransfer types using a special type, r=smaug,jmathies,mstange (cf7e19deb6)
- Bug 1248459 - Don't query out-of-bounds selection; r=masayuki (86c127f143)
- Bug 1261671 - ContentEventHandler::ConvertToRootRelativeOffset() should return the root-relative result in the frame's own appUnits, not the root's appUnits in the case when they're different. r=masayuki (2cd72b5ebc)
- Bug 1266702 - Clean up formatting in dom/events/DataTransfer.* and mark some methods const, r=jwatt (bd439cdad5)
2024-07-26 21:44:22 +08:00

247 lines
6.6 KiB
C++

/* -*- 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;
}
}
}