Bug 858919 - Add support for libnotify calls which was removed for new notification API. r=karlt

This commit is contained in:
Martin Stransky 2014-11-14 04:04:00 +01:00
parent 178bd2ca14
commit 9bddd229c3
7 changed files with 227 additions and 26 deletions

View File

@ -100,10 +100,12 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
nsresult rv;
if (sysAlerts) {
return sysAlerts->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener, aAlertName,
aBidi, aLang, aData,
IPC::Principal(aPrincipal));
rv = sysAlerts->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener, aAlertName,
aBidi, aLang, aData,
IPC::Principal(aPrincipal));
if (NS_SUCCEEDED(rv))
return NS_OK;
}
if (!ShouldShowAlert()) {

View File

@ -5,7 +5,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
SOURCES += [
'nsAlertsIconListener.cpp',
'nsGnomeModule.cpp',
'nsSystemAlertsService.cpp',
]
if CONFIG['MOZ_ENABLE_GCONF']:

View File

@ -51,6 +51,21 @@ static void notify_closed_marshal(GClosure* closure,
NS_RELEASE(alert);
}
static GdkPixbuf*
GetPixbufFromImgRequest(imgIRequest* aRequest)
{
nsCOMPtr<imgIContainer> image;
nsresult rv = aRequest->GetImage(getter_AddRefs(image));
if (NS_FAILED(rv)) {
return nullptr;
}
nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
return imgToPixbuf->ConvertImageToPixbuf(image);
}
NS_IMPL_ISUPPORTS(nsAlertsIconListener, imgINotificationObserver,
nsIObserver, nsISupportsWeakReference)
@ -106,47 +121,45 @@ nsAlertsIconListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRe
nsresult
nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest)
{
NS_ASSERTION(mIconRequest == aRequest, "aRequest does not match!");
uint32_t imgStatus = imgIRequest::STATUS_ERROR;
nsresult rv = aRequest->GetImageStatus(&imgStatus);
NS_ENSURE_SUCCESS(rv, rv);
if ((imgStatus & imgIRequest::STATUS_ERROR) && !mLoadedFrame) {
// We have an error getting the image. Display the notification with no icon.
ShowAlert(nullptr);
}
if (mIconRequest) {
// Cancel any pending request
mIconRequest->Cancel(NS_BINDING_ABORTED);
mIconRequest = nullptr;
}
return NS_OK;
}
nsresult
nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest)
{
if (aRequest != mIconRequest)
return NS_ERROR_FAILURE;
NS_ASSERTION(mIconRequest == aRequest, "aRequest does not match!");
if (mLoadedFrame)
return NS_OK; // only use one frame
nsCOMPtr<imgIContainer> image;
nsresult rv = aRequest->GetImage(getter_AddRefs(image));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
GdkPixbuf* imagePixbuf = imgToPixbuf->ConvertImageToPixbuf(image);
if (!imagePixbuf)
return NS_ERROR_FAILURE;
ShowAlert(imagePixbuf);
g_object_unref(imagePixbuf);
GdkPixbuf* imagePixbuf = GetPixbufFromImgRequest(aRequest);
if (!imagePixbuf) {
ShowAlert(nullptr);
} else {
ShowAlert(imagePixbuf);
g_object_unref(imagePixbuf);
}
mLoadedFrame = true;
// Cancel any pending request (multipart image loading/decoding for instance)
mIconRequest->Cancel(NS_BINDING_ABORTED);
mIconRequest = nullptr;
return NS_OK;
}
@ -180,6 +193,9 @@ nsAlertsIconListener::ShowAlert(GdkPixbuf* aPixbuf)
mClosureHandler = g_signal_connect_closure(mNotification, "closed", closure, FALSE);
gboolean result = notify_notification_show(mNotification, nullptr);
if (result && mAlertListener)
mAlertListener->Observe(nullptr, "alertshow", mAlertCookie.get());
return result ? NS_OK : NS_ERROR_FAILURE;
}
@ -201,9 +217,15 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
if (!il)
return ShowAlert(nullptr);
return il->LoadImageXPCOM(imageUri, nullptr, nullptr, nullptr, nullptr,
this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
nullptr, getter_AddRefs(mIconRequest));
nsresult rv = il->LoadImageXPCOM(imageUri, nullptr, nullptr, nullptr, nullptr,
this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
0 /* use default */, getter_AddRefs(mIconRequest));
if (NS_FAILED(rv))
return rv;
mIconRequest->StartDecoding();
return NS_OK;
}
void

View File

@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 nsAlertsIconListener_h__
#define nsAlertsIconListener_h__
#include "nsCOMPtr.h"
#include "imgINotificationObserver.h"
#include "nsStringAPI.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
class imgIRequest;
struct NotifyNotification;
class nsAlertsIconListener : public imgINotificationObserver,
public nsIObserver,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGINOTIFICATIONOBSERVER
NS_DECL_NSIOBSERVER
nsAlertsIconListener();
nsresult InitAlertAsync(const nsAString & aImageUrl,
const nsAString & aAlertTitle,
const nsAString & aAlertText,
bool aAlertTextClickable,
const nsAString & aAlertCookie,
nsIObserver * aAlertListener);
void SendCallback();
void SendClosed();
protected:
virtual ~nsAlertsIconListener();
nsresult OnStopRequest(imgIRequest* aRequest);
nsresult OnStopFrame(imgIRequest* aRequest);
/**
* The only difference between libnotify.so.4 and libnotify.so.1 for these symbols
* is that notify_notification_new takes three arguments in libnotify.so.4 and
* four in libnotify.so.1.
* Passing the fourth argument as NULL is binary compatible.
*/
typedef void (*NotifyActionCallback)(NotifyNotification*, char*, gpointer);
typedef bool (*notify_is_initted_t)(void);
typedef bool (*notify_init_t)(const char*);
typedef GList* (*notify_get_server_caps_t)(void);
typedef NotifyNotification* (*notify_notification_new_t)(const char*, const char*, const char*, const char*);
typedef bool (*notify_notification_show_t)(void*, char*);
typedef void (*notify_notification_set_icon_from_pixbuf_t)(void*, GdkPixbuf*);
typedef void (*notify_notification_add_action_t)(void*, const char*, const char*, NotifyActionCallback, gpointer, GFreeFunc);
nsCOMPtr<imgIRequest> mIconRequest;
nsCString mAlertTitle;
nsCString mAlertText;
nsCOMPtr<nsIObserver> mAlertListener;
nsString mAlertCookie;
bool mLoadedFrame;
bool mAlertHasAction;
static void* libNotifyHandle;
static bool libNotifyNotAvail;
static notify_is_initted_t notify_is_initted;
static notify_init_t notify_init;
static notify_get_server_caps_t notify_get_server_caps;
static notify_notification_new_t notify_notification_new;
static notify_notification_show_t notify_notification_show;
static notify_notification_set_icon_from_pixbuf_t notify_notification_set_icon_from_pixbuf;
static notify_notification_add_action_t notify_notification_add_action;
NotifyNotification* mNotification;
gulong mClosureHandler;
nsresult StartRequest(const nsAString & aImageUrl);
nsresult ShowAlert(GdkPixbuf* aPixbuf);
};
#endif

View File

@ -22,6 +22,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGnomeVFSService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIOService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGSettingsService, Init)
#endif
#include "nsSystemAlertsService.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemAlertsService, Init)
#ifdef MOZ_ENABLE_GCONF
NS_DEFINE_NAMED_CID(NS_GCONFSERVICE_CID);
@ -33,6 +35,7 @@ NS_DEFINE_NAMED_CID(NS_GNOMEVFSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_GIOSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_GSETTINGSSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
static const mozilla::Module::CIDEntry kGnomeCIDs[] = {
#ifdef MOZ_ENABLE_GCONF
@ -45,6 +48,7 @@ static const mozilla::Module::CIDEntry kGnomeCIDs[] = {
{ &kNS_GIOSERVICE_CID, false, nullptr, nsGIOServiceConstructor },
{ &kNS_GSETTINGSSERVICE_CID, false, nullptr, nsGSettingsServiceConstructor },
#endif
{ &kNS_SYSTEMALERTSSERVICE_CID, false, nullptr, nsSystemAlertsServiceConstructor },
{ nullptr }
};
@ -59,6 +63,7 @@ static const mozilla::Module::ContractIDEntry kGnomeContracts[] = {
{ NS_GIOSERVICE_CONTRACTID, &kNS_GIOSERVICE_CID },
{ NS_GSETTINGSSERVICE_CONTRACTID, &kNS_GSETTINGSSERVICE_CID },
#endif
{ NS_SYSTEMALERTSERVICE_CONTRACTID, &kNS_SYSTEMALERTSSERVICE_CID },
{ nullptr }
};

View File

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
/* 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 "nsXULAppAPI.h"
#include "nsSystemAlertsService.h"
#include "nsAlertsIconListener.h"
#include "nsAutoPtr.h"
NS_IMPL_ADDREF(nsSystemAlertsService)
NS_IMPL_RELEASE(nsSystemAlertsService)
NS_INTERFACE_MAP_BEGIN(nsSystemAlertsService)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAlertsService)
NS_INTERFACE_MAP_ENTRY(nsIAlertsService)
NS_INTERFACE_MAP_END_THREADSAFE
nsSystemAlertsService::nsSystemAlertsService()
{
}
nsSystemAlertsService::~nsSystemAlertsService()
{}
nsresult
nsSystemAlertsService::Init()
{
return NS_OK;
}
NS_IMETHODIMP nsSystemAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle,
const nsAString & aAlertText, bool aAlertTextClickable,
const nsAString & aAlertCookie,
nsIObserver * aAlertListener,
const nsAString & aAlertName,
const nsAString & aBidi,
const nsAString & aLang,
const nsAString & aData,
nsIPrincipal * aPrincipal)
{
nsRefPtr<nsAlertsIconListener> alertListener = new nsAlertsIconListener();
if (!alertListener)
return NS_ERROR_OUT_OF_MEMORY;
return alertListener->InitAlertAsync(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener);
}
NS_IMETHODIMP nsSystemAlertsService::CloseAlert(const nsAString& aAlertName,
nsIPrincipal* aPrincipal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -0,0 +1,27 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 nsSystemAlertsService_h__
#define nsSystemAlertsService_h__
#include "nsIAlertsService.h"
#include "nsCOMPtr.h"
class nsSystemAlertsService : public nsIAlertsService
{
public:
NS_DECL_NSIALERTSSERVICE
NS_DECL_ISUPPORTS
nsSystemAlertsService();
nsresult Init();
protected:
virtual ~nsSystemAlertsService();
};
#endif /* nsSystemAlertsService_h__ */