Bug 1259148 - Notify content when a Push permissions pop-up is dismissed by the user
MozReview-Commit-ID: 7HG7oOd8RWe
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2594,16 +2594,17 @@ ContentPermissionPrompt.prototype = {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
this._showPrompt(aRequest, message, "geo", actions, "geolocation",
"geo-notification-icon", options);
},
_promptWebNotifications : function(aRequest) {
+ // aRequest.QueryInterface(Ci.nsIContentPermissionRequestDismissible);
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
var actions;
var browser = this._getBrowserForRequest(aRequest);
// Only show "allow for session" in PB mode, we don't
// support "allow for session" in non-PB mode.
if (PrivateBrowsingUtils.isBrowserPrivate(browser)) {
@@ -2630,16 +2631,17 @@ ContentPermissionPrompt.prototype = {
callback: function() {},
},
];
}
var options = {
learnMoreURL:
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push",
+ eventCallback: type => type == "dismissed" && aRequest.dismiss(),
};
this._showPrompt(aRequest, message, "desktop-notification", actions,
"web-notifications",
"web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
--- a/dom/interfaces/base/nsIContentPermissionPrompt.idl
+++ b/dom/interfaces/base/nsIContentPermissionPrompt.idl
@@ -97,16 +97,29 @@ interface nsIContentPermissionRequest :
* allow or cancel the request
*/
void cancel();
void allow([optional] in jsval choices); // {"type1": "choice1", "type2": "choiceA"}
};
/**
+ * Interface allows access to a content to request
+ * permission to perform a privileged operation such as
+ * push notification that can be dismissed.
+ */
+[scriptable, uuid(bc65c84f-caa6-4b8e-8a30-c83432300036)]
+interface nsIContentPermissionRequestDismissible : nsIContentPermissionRequest {
+ /**
+ * dismiss the request
+ */
+ void dismiss();
+};
+
+/**
* Interface provides a way for the application to handle
* the UI prompts associated with geo position.
*/
[scriptable, function, uuid(F72DE90D-E954-4E69-9A61-917303029301)]
interface nsIContentPermissionPrompt : nsISupports {
/**
* Called when a request has been made to access
* privileged content apis
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -224,25 +224,26 @@ public:
rv = notificationStorage->Get(mOrigin, mTag, mCallback);
//XXXnsm Is it guaranteed mCallback will be called in case of failure?
Unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
};
-class NotificationPermissionRequest : public nsIContentPermissionRequest,
+class NotificationPermissionRequest : public nsIContentPermissionRequestDismissible,
public nsIRunnable
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
+ NS_DECL_NSICONTENTPERMISSIONREQUESTDISMISSIBLE
NS_DECL_NSIRUNNABLE
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(NotificationPermissionRequest,
- nsIContentPermissionRequest)
+ nsIContentPermissionRequestDismissible)
NotificationPermissionRequest(nsIPrincipal* aPrincipal,
nsPIDOMWindowInner* aWindow, Promise* aPromise,
NotificationPermissionCallback* aCallback)
: mPrincipal(aPrincipal), mWindow(aWindow),
mPermission(NotificationPermission::Default),
mPromise(aPromise),
mCallback(aCallback)
@@ -541,19 +542,19 @@ protected:
NotificationAction mAction;
};
uint32_t Notification::sCount = 0;
NS_IMPL_CYCLE_COLLECTION(NotificationPermissionRequest, mWindow, mPromise)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NotificationPermissionRequest)
- NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
+ NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequestDismissible)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequest)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequestDismissible)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(NotificationPermissionRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(NotificationPermissionRequest)
NS_IMETHODIMP
NotificationPermissionRequest::Run()
{
@@ -577,20 +578,16 @@ NotificationPermissionRequest::Run()
if (Preferences::GetBool("notification.prompt.testing", false)) {
if (Preferences::GetBool("notification.prompt.testing.allow", true)) {
mPermission = NotificationPermission::Granted;
} else {
mPermission = NotificationPermission::Denied;
}
}
- if (mPermission != NotificationPermission::Default) {
- return DispatchResolvePromise();
- }
-
return nsContentPermissionUtils::AskPermission(this, mWindow);
}
NS_IMETHODIMP
NotificationPermissionRequest::GetPrincipal(nsIPrincipal** aRequestingPrincipal)
{
NS_ADDREF(*aRequestingPrincipal = mPrincipal);
return NS_OK;
@@ -623,16 +620,23 @@ NotificationPermissionRequest::Allow(JS:
{
MOZ_ASSERT(aChoices.isUndefined());
mPermission = NotificationPermission::Granted;
return DispatchResolvePromise();
}
NS_IMETHODIMP
+NotificationPermissionRequest::Dismiss()
+{
+ mPermission = NotificationPermission::Default;
+ return DispatchResolvePromise();
+}
+
+NS_IMETHODIMP
NotificationPermissionRequest::GetRequester(nsIContentPermissionRequester** aRequester)
{
NS_ENSURE_ARG_POINTER(aRequester);
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
requester.forget(aRequester);
return NS_OK;
}
@@ -651,17 +655,21 @@ NotificationPermissionRequest::ResolvePr
nsresult rv = NS_OK;
if (mCallback) {
ErrorResult error;
mCallback->Call(mPermission, error);
rv = error.StealNSResult();
}
Telemetry::Accumulate(
Telemetry::WEB_NOTIFICATION_REQUEST_PERMISSION_CALLBACK, !!mCallback);
- mPromise->MaybeResolve(mPermission);
+
+ if (mPermission != NotificationPermission::Default) {
+ mPromise->MaybeResolve(mPermission);
+ }
+
return rv;
}
NS_IMETHODIMP
NotificationPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
@@ -2781,9 +2789,8 @@ Notification::Observe(nsISupports* aSubj
}
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla
-
--- a/dom/push/Push.js
+++ b/dom/push/Push.js
@@ -146,31 +146,36 @@ Push.prototype = {
type: "desktop-notification",
access: null,
options: [],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]),
};
let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
typeArray.appendElement(type, false);
- // create a nsIContentPermissionRequest
+ // create a nsIContentPermissionRequestDismissible
let request = {
types: typeArray,
principal: this._principal,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequestDismissible]),
allow: function() {
let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_GRANTED");
histogram.add();
allowCallback();
},
cancel: function() {
let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_DENIED");
histogram.add();
cancelCallback();
},
+ dismiss: function() {
+ let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_DISMISSED");
+ histogram.add();
+ cancelCallback();
+ },
window: this._window,
};
let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_REQUESTED");
histogram.add(1);
// Using askPermission from nsIDOMWindowUtils that takes care of the
// remoting if needed.
let windowUtils = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -10032,16 +10032,22 @@
"description": "Count of number of times the PermissionManager explicitly prompted user for Push Notifications permission"
},
"PUSH_API_PERMISSION_DENIED": {
"alert_emails": ["push@mozilla.com"],
"expires_in_version": "55",
"kind": "count",
"description": "User explicitly denied Push Notifications permission"
},
+ "PUSH_API_PERMISSION_DISMISSED": {
+ "alert_emails": ["push@mozilla.com"],
+ "expires_in_version": "55",
+ "kind": "count",
+ "description": "User dismissed request for Push Notifications permission"
+ },
"PUSH_API_PERMISSION_GRANTED": {
"alert_emails": ["push@mozilla.com"],
"expires_in_version": "55",
"kind": "count",
"description": "User explicitly granted Push Notifications permission"
},
"PUSH_API_SUBSCRIBE_ATTEMPT": {
"alert_emails": ["push@mozilla.com"],
--- a/toolkit/components/telemetry/histogram-whitelists.json
+++ b/toolkit/components/telemetry/histogram-whitelists.json
@@ -2163,16 +2163,17 @@
"PREDICTOR_WAIT_TIME",
"PROCESS_CRASH_SUBMIT_ATTEMPT",
"PROCESS_CRASH_SUBMIT_SUCCESS",
"PUSH_API_NOTIFICATION_RECEIVED",
"PUSH_API_NOTIFICATION_RECEIVED_BUT_DID_NOT_NOTIFY",
"PUSH_API_NOTIFY",
"PUSH_API_NOTIFY_REGISTRATION_LOST",
"PUSH_API_PERMISSION_DENIED",
+ "PUSH_API_PERMISSION_DISMISSED",
"PUSH_API_PERMISSION_GRANTED",
"PUSH_API_PERMISSION_REQUESTED",
"PUSH_API_QUOTA_EXPIRATION_TIME",
"PUSH_API_QUOTA_RESET_TO",
"PUSH_API_SUBSCRIBE_ATTEMPT",
"PUSH_API_SUBSCRIBE_FAILED",
"PUSH_API_SUBSCRIBE_HTTP2_TIME",
"PUSH_API_SUBSCRIBE_SUCCEEDED",