1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/alerts/nsAlertsService.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,169 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/dom/ContentChild.h" 1.10 +#include "mozilla/dom/PermissionMessageUtils.h" 1.11 +#include "nsXULAppAPI.h" 1.12 + 1.13 +#include "nsAlertsService.h" 1.14 + 1.15 +#ifdef MOZ_WIDGET_ANDROID 1.16 +#include "AndroidBridge.h" 1.17 +using namespace mozilla::widget::android; 1.18 +#else 1.19 + 1.20 +#include "nsXPCOM.h" 1.21 +#include "nsIServiceManager.h" 1.22 +#include "nsIDOMWindow.h" 1.23 +#include "nsPromiseFlatString.h" 1.24 +#include "nsToolkitCompsCID.h" 1.25 + 1.26 +#endif // !MOZ_WIDGET_ANDROID 1.27 + 1.28 +using namespace mozilla; 1.29 + 1.30 +using mozilla::dom::ContentChild; 1.31 + 1.32 +NS_IMPL_ISUPPORTS(nsAlertsService, nsIAlertsService, nsIAlertsProgressListener) 1.33 + 1.34 +nsAlertsService::nsAlertsService() 1.35 +{ 1.36 +} 1.37 + 1.38 +nsAlertsService::~nsAlertsService() 1.39 +{} 1.40 + 1.41 +bool nsAlertsService::ShouldShowAlert() 1.42 +{ 1.43 + bool result = true; 1.44 + 1.45 +#ifdef XP_WIN 1.46 + HMODULE shellDLL = ::LoadLibraryW(L"shell32.dll"); 1.47 + if (!shellDLL) 1.48 + return result; 1.49 + 1.50 + SHQueryUserNotificationStatePtr pSHQueryUserNotificationState = 1.51 + (SHQueryUserNotificationStatePtr) ::GetProcAddress(shellDLL, "SHQueryUserNotificationState"); 1.52 + 1.53 + if (pSHQueryUserNotificationState) { 1.54 + MOZ_QUERY_USER_NOTIFICATION_STATE qstate; 1.55 + if (SUCCEEDED(pSHQueryUserNotificationState(&qstate))) { 1.56 + if (qstate != QUNS_ACCEPTS_NOTIFICATIONS) { 1.57 + result = false; 1.58 + } 1.59 + } 1.60 + } 1.61 + 1.62 + ::FreeLibrary(shellDLL); 1.63 +#endif 1.64 + 1.65 + return result; 1.66 +} 1.67 + 1.68 +NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle, 1.69 + const nsAString & aAlertText, bool aAlertTextClickable, 1.70 + const nsAString & aAlertCookie, 1.71 + nsIObserver * aAlertListener, 1.72 + const nsAString & aAlertName, 1.73 + const nsAString & aBidi, 1.74 + const nsAString & aLang, 1.75 + nsIPrincipal * aPrincipal) 1.76 +{ 1.77 + if (XRE_GetProcessType() == GeckoProcessType_Content) { 1.78 + ContentChild* cpc = ContentChild::GetSingleton(); 1.79 + 1.80 + if (aAlertListener) 1.81 + cpc->AddRemoteAlertObserver(PromiseFlatString(aAlertCookie), aAlertListener); 1.82 + 1.83 + cpc->SendShowAlertNotification(PromiseFlatString(aImageUrl), 1.84 + PromiseFlatString(aAlertTitle), 1.85 + PromiseFlatString(aAlertText), 1.86 + aAlertTextClickable, 1.87 + PromiseFlatString(aAlertCookie), 1.88 + PromiseFlatString(aAlertName), 1.89 + PromiseFlatString(aBidi), 1.90 + PromiseFlatString(aLang), 1.91 + IPC::Principal(aPrincipal)); 1.92 + return NS_OK; 1.93 + } 1.94 + 1.95 +#ifdef MOZ_WIDGET_ANDROID 1.96 + mozilla::AndroidBridge::Bridge()->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, 1.97 + aAlertListener, aAlertName); 1.98 + return NS_OK; 1.99 +#else 1.100 + // Check if there is an optional service that handles system-level notifications 1.101 + nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID)); 1.102 + nsresult rv; 1.103 + if (sysAlerts) { 1.104 + return sysAlerts->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable, 1.105 + aAlertCookie, aAlertListener, aAlertName, 1.106 + aBidi, aLang, IPC::Principal(aPrincipal)); 1.107 + } 1.108 + 1.109 + if (!ShouldShowAlert()) { 1.110 + // Do not display the alert. Instead call alertfinished and get out. 1.111 + if (aAlertListener) 1.112 + aAlertListener->Observe(nullptr, "alertfinished", PromiseFlatString(aAlertCookie).get()); 1.113 + return NS_OK; 1.114 + } 1.115 + 1.116 + // Use XUL notifications as a fallback if above methods have failed. 1.117 + rv = mXULAlerts.ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable, 1.118 + aAlertCookie, aAlertListener, aAlertName, 1.119 + aBidi, aLang); 1.120 + return rv; 1.121 +#endif // !MOZ_WIDGET_ANDROID 1.122 +} 1.123 + 1.124 +NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName, 1.125 + nsIPrincipal* aPrincipal) 1.126 +{ 1.127 + if (XRE_GetProcessType() == GeckoProcessType_Content) { 1.128 + ContentChild* cpc = ContentChild::GetSingleton(); 1.129 + cpc->SendCloseAlert(nsAutoString(aAlertName), IPC::Principal(aPrincipal)); 1.130 + return NS_OK; 1.131 + } 1.132 + 1.133 +#ifdef MOZ_WIDGET_ANDROID 1.134 + mozilla::widget::android::GeckoAppShell::CloseNotification(aAlertName); 1.135 + return NS_OK; 1.136 +#else 1.137 + 1.138 + // Try the system notification service. 1.139 + nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID)); 1.140 + if (sysAlerts) { 1.141 + return sysAlerts->CloseAlert(aAlertName, nullptr); 1.142 + } 1.143 + 1.144 + return mXULAlerts.CloseAlert(aAlertName); 1.145 +#endif // !MOZ_WIDGET_ANDROID 1.146 +} 1.147 + 1.148 + 1.149 +NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName, 1.150 + int64_t aProgress, 1.151 + int64_t aProgressMax, 1.152 + const nsAString & aAlertText) 1.153 +{ 1.154 +#ifdef MOZ_WIDGET_ANDROID 1.155 + mozilla::widget::android::GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName, 1.156 + aProgress, aProgressMax, 1.157 + aAlertText); 1.158 + return NS_OK; 1.159 +#else 1.160 + return NS_ERROR_NOT_IMPLEMENTED; 1.161 +#endif // !MOZ_WIDGET_ANDROID 1.162 +} 1.163 + 1.164 +NS_IMETHODIMP nsAlertsService::OnCancel(const nsAString & aAlertName) 1.165 +{ 1.166 +#ifdef MOZ_WIDGET_ANDROID 1.167 + mozilla::widget::android::GeckoAppShell::CloseNotification(aAlertName); 1.168 + return NS_OK; 1.169 +#else 1.170 + return NS_ERROR_NOT_IMPLEMENTED; 1.171 +#endif // !MOZ_WIDGET_ANDROID 1.172 +}