Bug 1259148 - Notify content when the notification permission pop-up is dismissed by the user. r=past,wchen
MozReview-Commit-ID: 8CcgQcJDeie
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2613,16 +2613,26 @@ ContentPermissionPrompt.prototype = {
callback: function() {},
},
];
}
var options = {
learnMoreURL:
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push",
+ eventCallback(type) {
+ if (type == "dismissed") {
+ // Bug 1259148: Hide the doorhanger icon. Unlike other permission
+ // doorhangers, the user can't restore the doorhanger using the icon
+ // in the location bar. Instead, the site will be notified that the
+ // doorhanger was dismissed.
+ this.remove();
+ aRequest.cancel();
+ }
+ },
};
this._showPrompt(aRequest, message, "desktop-notification", actions,
"web-notifications",
"web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -609,17 +609,21 @@ NotificationPermissionRequest::GetElemen
NS_ENSURE_ARG_POINTER(aElement);
*aElement = nullptr;
return NS_OK;
}
NS_IMETHODIMP
NotificationPermissionRequest::Cancel()
{
- mPermission = NotificationPermission::Denied;
+ // `Cancel` is called if the user denied permission or dismissed the
+ // permission request. To distinguish between the two, we set the
+ // permission to "default" and query the permission manager in
+ // `ResolvePromise`.
+ mPermission = NotificationPermission::Default;
return DispatchResolvePromise();
}
NS_IMETHODIMP
NotificationPermissionRequest::Allow(JS::HandleValue aChoices)
{
MOZ_ASSERT(aChoices.isUndefined());
@@ -644,16 +648,21 @@ NotificationPermissionRequest::DispatchR
&NotificationPermissionRequest::ResolvePromise);
return NS_DispatchToMainThread(resolveRunnable);
}
nsresult
NotificationPermissionRequest::ResolvePromise()
{
nsresult rv = NS_OK;
+ if (mPermission == NotificationPermission::Default) {
+ // This will still be "default" if the user dismissed the doorhanger,
+ // or "denied" otherwise.
+ mPermission = Notification::TestPermission(mPrincipal);
+ }
if (mCallback) {
ErrorResult error;
mCallback->Call(mPermission, error);
rv = error.StealNSResult();
}
Telemetry::Accumulate(
Telemetry::WEB_NOTIFICATION_REQUEST_PERMISSION_CALLBACK, !!mCallback);
mPromise->MaybeResolve(mPermission);
@@ -1942,20 +1951,31 @@ Notification::GetPermissionInternal(nsIP
if (Preferences::GetBool("notification.prompt.testing", false)) {
if (Preferences::GetBool("notification.prompt.testing.allow", true)) {
return NotificationPermission::Granted;
} else {
return NotificationPermission::Denied;
}
}
+ return TestPermission(aPrincipal);
+}
+
+/* static */ NotificationPermission
+Notification::TestPermission(nsIPrincipal* aPrincipal)
+{
+ AssertIsOnMainThread();
+
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
nsCOMPtr<nsIPermissionManager> permissionManager =
services::GetPermissionManager();
+ if (!permissionManager) {
+ return NotificationPermission::Default;
+ }
permissionManager->TestExactPermissionFromPrincipal(aPrincipal,
"desktop-notification",
&permission);
// Convert the result to one of the enum types.
switch (permission) {
case nsIPermissionManager::ALLOW_ACTION:
--- a/dom/notification/Notification.h
+++ b/dom/notification/Notification.h
@@ -312,16 +312,18 @@ public:
void ReleaseObject();
static NotificationPermission GetPermission(nsIGlobalObject* aGlobal,
ErrorResult& aRv);
static NotificationPermission GetPermissionInternal(nsIPrincipal* aPrincipal,
ErrorResult& rv);
+ static NotificationPermission TestPermission(nsIPrincipal* aPrincipal);
+
bool DispatchClickEvent();
bool DispatchNotificationClickEvent();
static nsresult RemovePermission(nsIPrincipal* aPrincipal);
static nsresult OpenSettings(nsIPrincipal* aPrincipal);
protected:
Notification(nsIGlobalObject* aGlobal, const nsAString& aID,
const nsAString& aTitle, const nsAString& aBody,