Bug 1224785, Part 1 - Implement alert favicons backend. r=wchen

MozReview-Commit-ID: Day8Hj8lT1f
This commit is contained in:
Kit Cambridge 2016-01-07 13:15:55 -07:00
parent 8140864840
commit 0800e490a2
3 changed files with 156 additions and 4 deletions

View File

@ -117,6 +117,16 @@ AlertNotification::GetPrincipal(nsIPrincipal** aPrincipal)
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetURI(nsIURI** aURI)
{
if (!nsAlertsUtils::IsActionablePrincipal(mPrincipal)) {
*aURI = nullptr;
return NS_OK;
}
return mPrincipal->GetURI(aURI);
}
NS_IMETHODIMP
AlertNotification::GetInPrivateBrowsing(bool* aInPrivateBrowsing)
{

View File

@ -22,10 +22,118 @@
#endif // !MOZ_WIDGET_ANDROID
#ifdef MOZ_PLACES
#include "mozIAsyncFavicons.h"
#include "nsIFaviconService.h"
#endif // MOZ_PLACES
using namespace mozilla;
using mozilla::dom::ContentChild;
namespace {
#ifdef MOZ_PLACES
class IconCallback final : public nsIFaviconDataCallback
{
public:
NS_DECL_ISUPPORTS
IconCallback(nsIAlertsService* aBackend,
nsIAlertNotification* aAlert,
nsIObserver* aAlertListener)
: mBackend(aBackend)
, mAlert(aAlert)
, mAlertListener(aAlertListener)
{}
NS_IMETHOD
OnComplete(nsIURI *aIconURI, uint32_t aIconSize, const uint8_t *aIconData,
const nsACString &aMimeType) override
{
nsresult rv = NS_ERROR_FAILURE;
if (aIconSize > 0) {
nsCOMPtr<nsIAlertsIconData> alertsIconData(do_QueryInterface(mBackend));
if (alertsIconData) {
rv = alertsIconData->ShowAlertWithIconData(mAlert, mAlertListener,
aIconSize, aIconData);
}
} else if (aIconURI) {
nsCOMPtr<nsIAlertsIconURI> alertsIconURI(do_QueryInterface(mBackend));
if (alertsIconURI) {
rv = alertsIconURI->ShowAlertWithIconURI(mAlert, mAlertListener,
aIconURI);
}
}
if (NS_FAILED(rv)) {
rv = mBackend->ShowAlert(mAlert, mAlertListener);
}
return rv;
}
private:
virtual ~IconCallback() {}
nsCOMPtr<nsIAlertsService> mBackend;
nsCOMPtr<nsIAlertNotification> mAlert;
nsCOMPtr<nsIObserver> mAlertListener;
};
NS_IMPL_ISUPPORTS(IconCallback, nsIFaviconDataCallback)
#endif // MOZ_PLACES
nsresult
ShowWithIconBackend(nsIAlertsService* aBackend, nsIAlertNotification* aAlert,
nsIObserver* aAlertListener)
{
#ifdef MOZ_PLACES
nsCOMPtr<nsIURI> uri;
nsresult rv = aAlert->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv) || !uri) {
return NS_ERROR_FAILURE;
}
// Ensure the backend supports favicons.
nsCOMPtr<nsIAlertsIconData> alertsIconData(do_QueryInterface(aBackend));
nsCOMPtr<nsIAlertsIconURI> alertsIconURI;
if (!alertsIconData) {
alertsIconURI = do_QueryInterface(aBackend);
}
if (!alertsIconData && !alertsIconURI) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsCOMPtr<mozIAsyncFavicons> favicons(do_GetService(
"@mozilla.org/browser/favicon-service;1"));
NS_ENSURE_TRUE(favicons, NS_ERROR_FAILURE);
nsCOMPtr<nsIFaviconDataCallback> callback =
new IconCallback(aBackend, aAlert, aAlertListener);
if (alertsIconData) {
return favicons->GetFaviconDataForPage(uri, callback);
}
return favicons->GetFaviconURLForPage(uri, callback);
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif // !MOZ_PLACES
}
nsresult
ShowWithBackend(nsIAlertsService* aBackend, nsIAlertNotification* aAlert,
nsIObserver* aAlertListener)
{
nsresult rv = ShowWithIconBackend(aBackend, aAlert, aAlertListener);
if (NS_SUCCEEDED(rv)) {
return rv;
}
// If the backend doesn't support favicons, show the alert without one.
return aBackend->ShowAlert(aAlert, aAlertListener);
}
} // anonymous namespace
NS_IMPL_ISUPPORTS(nsAlertsService, nsIAlertsService, nsIAlertsDoNotDisturb, nsIAlertsProgressListener)
nsAlertsService::nsAlertsService() :
@ -66,7 +174,7 @@ bool nsAlertsService::ShouldShowAlert()
return result;
}
NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle,
NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle,
const nsAString & aAlertText, bool aAlertTextClickable,
const nsAString & aAlertCookie,
nsIObserver * aAlertListener,
@ -135,7 +243,7 @@ NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
#else
// Check if there is an optional service that handles system-level notifications
if (mBackend) {
rv = mBackend->ShowAlert(aAlert, aAlertListener);
rv = ShowWithBackend(mBackend, aAlert, aAlertListener);
if (NS_SUCCEEDED(rv)) {
return rv;
}
@ -154,7 +262,7 @@ NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
// Use XUL notifications as a fallback if above methods have failed.
nsCOMPtr<nsIAlertsService> xulBackend(nsXULAlerts::GetInstance());
NS_ENSURE_TRUE(xulBackend, NS_ERROR_FAILURE);
return xulBackend->ShowAlert(aAlert, aAlertListener);
return ShowWithBackend(xulBackend, aAlert, aAlertListener);
#endif // !MOZ_WIDGET_ANDROID
}

View File

@ -7,12 +7,13 @@
#include "nsIObserver.idl"
interface nsIPrincipal;
interface nsIURI;
%{C++
#define ALERT_NOTIFICATION_CONTRACTID "@mozilla.org/alert-notification;1"
%}
[scriptable, uuid(9e87fc34-8dbb-4b14-a724-b27be6822ec8)]
[scriptable, uuid(1650a064-79d5-4eb6-8c9e-57dd6522b6ac)]
interface nsIAlertNotification : nsISupports
{
/** Initializes an alert notification. */
@ -85,6 +86,12 @@ interface nsIAlertNotification : nsISupports
*/
readonly attribute nsIPrincipal principal;
/**
* The URI of the page that created the alert. |null| if the alert is not
* actionable.
*/
readonly attribute nsIURI URI;
/**
* Controls the image loading behavior. If true, the image URL will be loaded
* in private browsing mode.
@ -224,3 +231,30 @@ interface nsIAlertsProgressListener : nsISupports
void onCancel(in AString name);
};
[scriptable, uuid(fc6d7f0a-0cf6-4268-8c71-ab640842b9b1)]
interface nsIAlertsIconData : nsISupports
{
/**
* Shows an alert with an icon. Web notifications use the favicon of the
* page that created the alert. If the favicon is not in the Places database,
* |iconSize| will be zero.
*/
void showAlertWithIconData(in nsIAlertNotification alert,
[optional] in nsIObserver alertListener,
[optional] in uint32_t iconSize,
[const, array, size_is(iconSize)] in uint8_t
iconData);
};
[scriptable, uuid(f3c82915-bf60-41ea-91ce-6c46b22e381a)]
interface nsIAlertsIconURI : nsISupports
{
/**
* Shows an alert with an icon URI. Web notifications use |moz-anno:|
* URIs to reference favicons from Places. If the page doesn't have a
* favicon, |iconURI| will be |null|.
*/
void showAlertWithIconURI(in nsIAlertNotification alert,
[optional] in nsIObserver alertListener,
[optional] in nsIURI iconURI);
};