Bug 1192458, Part 1 - Consolidate push and desktop notification permissions. r=nsm,wchen,MattN

This commit is contained in:
Kit Cambridge 2015-10-05 16:39:34 -07:00
parent db56810f49
commit 25c133e1db
40 changed files with 97 additions and 176 deletions

View File

@ -713,7 +713,6 @@
<image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="push-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="login-fill-notification-icon" class="notification-anchor-icon" role="button"/>

View File

@ -2552,38 +2552,6 @@ ContentPermissionPrompt.prototype = {
mainAction, secondaryActions, aOptions);
},
_promptPush : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("push.enablePush2");
var actions = [
{
stringId: "push.alwaysAllow",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {}
},
{
stringId: "push.allowForSession",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
callback: function() {}
},
{
stringId: "push.alwaysBlock",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {}
}]
var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),
};
this._showPrompt(aRequest, message, "push", actions, "push",
"push-notification-icon", options);
},
_promptGeo : function(aRequest) {
var secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
@ -2638,12 +2606,6 @@ ContentPermissionPrompt.prototype = {
var message = gBrowserBundle.GetStringFromName("webNotifications.showFromSite2");
var actions = [
{
stringId: "webNotifications.showForSession",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
callback: function() {},
},
{
stringId: "webNotifications.alwaysShow",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
@ -2658,9 +2620,13 @@ ContentPermissionPrompt.prototype = {
},
];
var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),
};
this._showPrompt(aRequest, message, "desktop-notification", actions,
"web-notifications",
"web-notifications-notification-icon", null);
"web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
@ -2731,7 +2697,6 @@ ContentPermissionPrompt.prototype = {
const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification",
"pointerLock" : "pointerLock",
"push" : "push"
};
// Make sure that we support the request.
@ -2782,9 +2747,6 @@ ContentPermissionPrompt.prototype = {
case "pointerLock":
this._promptPointerLock(request, autoAllow);
break;
case "push":
this._promptPush(request);
break;
}
},

View File

@ -46,7 +46,7 @@ var gVisitStmt = gPlacesDatabase.createAsyncStatement(
* Permission types that should be tested with testExactPermission, as opposed
* to testPermission. This is based on what consumers use to test these permissions.
*/
var TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone"];
var TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone", "desktop-notification"];
/**
* Site object represents a single site, uniquely identified by a principal.
@ -321,16 +321,9 @@ var PermissionDefaults = {
Services.prefs.setBoolPref("dom.disable_open_during_load", value);
},
get push() {
if (!Services.prefs.getBoolPref("dom.push.enabled")) {
return this.DENY;
}
get ["desktop-notification"]() {
return this.UNKNOWN;
},
set push(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("dom.push.enabled", value);
},
get camera() {
return this.UNKNOWN;
},
@ -384,17 +377,18 @@ var AboutPermissions = {
* Potential future additions: "sts/use", "sts/subd"
*/
_supportedPermissions: ["password", "cookie", "geo", "indexedDB", "popup",
"camera", "microphone", "push"],
"camera", "microphone", "desktop-notification"],
/**
* Permissions that don't have a global "Allow" option.
*/
_noGlobalAllow: ["geo", "indexedDB", "camera", "microphone", "push"],
_noGlobalAllow: ["geo", "indexedDB", "camera", "microphone",
"desktop-notification"],
/**
* Permissions that don't have a global "Deny" option.
*/
_noGlobalDeny: ["camera", "microphone"],
_noGlobalDeny: ["camera", "microphone", "desktop-notification"],
_stringBundle: Services.strings.
createBundle("chrome://browser/locale/preferences/aboutPermissions.properties"),

View File

@ -239,21 +239,21 @@
</vbox>
</hbox>
<!-- Push Notifications -->
<hbox id="push-pref-item"
<!-- Notifications -->
<hbox id="desktop-notification-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="push"/>
<image class="pref-icon" type="desktop-notification"/>
<vbox>
<label class="pref-title" value="&push.label;"/>
<label class="pref-title" value="&desktop-notification.label;"/>
<hbox align="center">
<menulist id="push-menulist"
<menulist id="desktop-notification-menulist"
class="pref-menulist"
type="push"
type="desktop-notification"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="push-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="push-1" value="1" label="&permission.allow;"/>
<menuitem id="push-2" value="2" label="&permission.block;"/>
<menuitem id="desktop-notification-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="desktop-notification-1" value="1" label="&permission.allow;"/>
<menuitem id="desktop-notification-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>

View File

@ -28,7 +28,7 @@ const TEST_PERMS = {
"password": PERM_ALLOW,
"cookie": PERM_ALLOW,
"geo": PERM_UNKNOWN,
"push": PERM_DENY,
"desktop-notification": PERM_UNKNOWN,
"indexedDB": PERM_UNKNOWN,
"popup": PERM_DENY,
"camera": PERM_UNKNOWN,

View File

@ -375,23 +375,12 @@ geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
webNotifications.showForSession=Show for this session
webNotifications.showForSession.accesskey=s
webNotifications.alwaysShow=Always Show Notifications
webNotifications.alwaysShow.accesskey=A
webNotifications.neverShow=Always Block Notifications
webNotifications.neverShow.accesskey=N
webNotifications.showFromSite2=Would you like to show notifications from this site?
# Push Notifications
push.allowForSession=Allow for Session
push.allowForSession.accesskey=S
push.alwaysAllow=Always Allow Push Notifications
push.alwaysAllow.accesskey=A
push.alwaysBlock=Always Block Push Notifications
push.alwaysBlock.accesskey=B
push.enablePush2=Would you like to allow Push Notifications for this site?
# Pointer lock UI
pointerLock.allow2=Hide pointer

View File

@ -41,7 +41,7 @@
<!ENTITY popup.label "Open Pop-up Windows">
<!ENTITY push.label "Receive Push Notifications">
<!ENTITY desktop-notification.label "Show Notifications">
<!ENTITY camera.label "Use the Camera">
<!ENTITY microphone.label "Use the Microphone">

View File

@ -17,4 +17,3 @@ permission.popup.label = Open Pop-up Windows
permission.geo.label = Access Your Location
permission.indexedDB.label = Maintain Offline Storage
permission.pointerLock.label = Hide the Mouse Pointer
permission.push.label = Receive Push Notifications

View File

@ -161,7 +161,9 @@ var gPermissionObject = {
}
},
"desktop-notification": {},
"desktop-notification": {
exactHostMatch: true
},
"camera": {},
"microphone": {},
@ -188,9 +190,5 @@ var gPermissionObject = {
"pointerLock": {
exactHostMatch: true
},
"push": {
exactHostMatch: true
}
};

View File

@ -8,7 +8,6 @@ Components.utils.import("resource:///modules/SitePermissions.jsm");
add_task(function* testPermissionsListing() {
Assert.deepEqual(SitePermissions.listPermissions().sort(),
["camera","cookie","desktop-notification","geo","image",
"indexedDB","install","microphone","pointerLock","popup",
"push"],
"indexedDB","install","microphone","pointerLock","popup"],
"Correct list of all permissions");
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -23,8 +23,6 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-64.png
skin/classic/browser/Info.png
skin/classic/browser/menuPanel.png
skin/classic/browser/menuPanel@2x.png

View File

@ -94,8 +94,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -25,10 +25,6 @@ browser.jar:
skin/classic/browser/Geolocation-16@2x.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Geolocation-64@2x.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-16@2x.png
skin/classic/browser/Push-64.png
skin/classic/browser/Push-64@2x.png
skin/classic/browser/Info.png
skin/classic/browser/keyhole-circle.png
skin/classic/browser/keyhole-circle@2x.png

View File

@ -104,8 +104,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);
@ -133,6 +133,9 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
}
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/notification-64@2x.png);
}
}
.pref-title {

View File

@ -14,10 +14,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.popup-notification-icon[popupid="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
}
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-install-blocked"],
.popup-notification-icon[popupid="addon-install-origin-blocked"] {
@ -142,10 +138,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#push-notification-icon {
list-style-image: url(chrome://browser/skin/Push-16.png);
}
#addons-notification-icon {
list-style-image: url(chrome://browser/skin/addons/addon-install-anchor.svg#default);
}
@ -369,10 +361,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
}
#push-notification-icon {
list-style-image: url(chrome://browser/skin/Push-16@2x.png);
}
.indexedDB-notification-icon,
#indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-32.png);
@ -438,10 +426,6 @@
list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
}
.popup-notification-icon[popupid="push"] {
list-style-image: url(chrome://browser/skin/Push-64@2x.png);
}
.popup-notification-icon[popupid="web-notifications"] {
list-style-image: url(chrome://browser/skin/notification-64@2x.png);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -25,8 +25,6 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Push-16.png
skin/classic/browser/Push-64.png
skin/classic/browser/Info.png
skin/classic/browser/Info-XP.png
skin/classic/browser/keyhole-forward-mask.svg

View File

@ -98,8 +98,8 @@
.pref-icon[type="geo"] {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
.pref-icon[type="push"] {
list-style-image: url(chrome://browser/skin/Push-64.png);
.pref-icon[type="desktop-notification"] {
list-style-image: url(chrome://browser/skin/notification-64.png);
}
.pref-icon[type="indexedDB"] {
list-style-image: url(chrome://global/skin/icons/question-64.png);

View File

@ -1639,9 +1639,9 @@ Notification::GetPermissionInternal(nsIPrincipal* aPrincipal,
nsCOMPtr<nsIPermissionManager> permissionManager =
services::GetPermissionManager();
permissionManager->TestPermissionFromPrincipal(aPrincipal,
"desktop-notification",
&permission);
permissionManager->TestExactPermissionFromPrincipal(aPrincipal,
"desktop-notification",
&permission);
// Convert the result to one of the enum types.
switch (permission) {

View File

@ -12,7 +12,8 @@ namespace dom {
const char* kPermissionTypes[] = {
"geo",
"desktop-notification",
"push",
// Alias `push` to `desktop-notification`.
"desktop-notification",
"midi"
};

View File

@ -23,7 +23,7 @@ SimpleTest.waitForExplicitFinish();
const PERMISSIONS = [
{ name: 'geolocation', perm: 'geo' },
{ name: 'notifications', perm: 'desktop-notification' },
{ name: 'push', perm: 'push' },
{ name: 'push', perm: 'desktop-notification' },
];
const UNSUPPORTED_PERMISSIONS = [

View File

@ -67,13 +67,13 @@ Push.prototype = {
askPermission: function (aAllowCallback, aCancelCallback) {
debug("askPermission");
let principal = this._window.document.nodePrincipal;
let type = "push";
let permValue =
Services.perms.testExactPermissionFromPrincipal(principal, type);
let permValue = Services.perms.testExactPermissionFromPrincipal(
this._principal,
"desktop-notification"
);
if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
aAllowCallback();
aAllowCallback();
return;
}
@ -83,8 +83,8 @@ Push.prototype = {
}
// Create an array with a single nsIContentPermissionType element.
type = {
type: "push",
let type = {
type: "desktop-notification",
access: null,
options: [],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType])
@ -95,7 +95,7 @@ Push.prototype = {
// create a nsIContentPermissionRequest
let request = {
types: typeArray,
principal: principal,
principal: this._principal,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
allow: function() {
let histogram = Services.telemetry.getHistogramById("PUSH_API_PERMISSION_GRANTED");
@ -182,11 +182,8 @@ Push.prototype = {
let permission = Ci.nsIPermissionManager.DENY_ACTION;
try {
let permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
permission =
permissionManager.testExactPermissionFromPrincipal(this._principal,
"push");
permission = Services.perms.testExactPermissionFromPrincipal(
this._principal, "desktop-notification");
} catch(e) {
reject();
return;

View File

@ -592,7 +592,7 @@ public:
uint32_t permission = nsIPermissionManager::DENY_ACTION;
nsresult rv = permManager->TestExactPermissionFromPrincipal(
principal,
"push",
"desktop-notification",
&permission);
if (NS_WARN_IF(NS_FAILED(rv)) || permission != nsIPermissionManager::ALLOW_ACTION) {
@ -732,28 +732,20 @@ public:
mozilla::services::GetPermissionManager();
nsresult rv = NS_ERROR_FAILURE;
PushPermissionState state = PushPermissionState::Denied;
PushPermissionState state = PushPermissionState::Prompt;
if (permManager) {
uint32_t permission = nsIPermissionManager::DENY_ACTION;
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
rv = permManager->TestExactPermissionFromPrincipal(
mProxy->GetWorkerPrivate()->GetPrincipal(),
"push",
"desktop-notification",
&permission);
if (NS_SUCCEEDED(rv)) {
switch (permission) {
case nsIPermissionManager::ALLOW_ACTION:
state = PushPermissionState::Granted;
break;
case nsIPermissionManager::DENY_ACTION:
state = PushPermissionState::Denied;
break;
case nsIPermissionManager::PROMPT_ACTION:
state = PushPermissionState::Prompt;
break;
default:
MOZ_CRASH("Unexpected case!");
if (permission == nsIPermissionManager::ALLOW_ACTION) {
state = PushPermissionState::Granted;
} else if (permission == nsIPermissionManager::DENY_ACTION) {
state = PushPermissionState::Denied;
}
}
}

View File

@ -160,21 +160,13 @@ PushRecord.prototype = {
return false;
},
/**
* Returns the push permission state for the principal associated with
* this registration.
*/
pushPermission() {
return Services.perms.testExactPermissionFromPrincipal(
this.principal, "push");
},
/**
* Indicates whether the registration can deliver push messages to its
* associated service worker.
*/
hasPermission() {
let permission = this.pushPermission();
let permission = Services.perms.testExactPermissionFromPrincipal(
this.principal, "desktop-notification");
return permission == Ci.nsIPermissionManager.ALLOW_ACTION;
},

View File

@ -179,7 +179,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -65,7 +65,7 @@ http://creativecommons.org/licenses/publicdomain/
}).then(SimpleTest.finish);
}
SpecialPowers.addPermission('push', false, document);
SpecialPowers.addPermission("desktop-notification", false, document);
SpecialPowers.pushPrefEnv({"set": [
["dom.push.enabled", true],
["dom.serviceWorkers.exemptFromPerDomainMax", true],

View File

@ -125,7 +125,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -119,7 +119,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -107,7 +107,7 @@ var defaultServerURL = SpecialPowers.getCharPref("dom.push.serverURL");
["dom.serviceWorkers.testing.enabled", true],
["dom.push.serverURL", "wss://something.org"]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -71,13 +71,33 @@ http://creativecommons.org/licenses/publicdomain/
}
function checkPermissionState(swr) {
return swr.pushManager.permissionState().then(function(state) {
ok(state === "denied", "permissionState() should resolve to denied.");
return swr;
}).catch(function(e) {
ok(false, "permissionState() should resolve to denied.");
return swr;
});
var permissionManager = SpecialPowers.Ci.nsIPermissionManager;
var tests = [{
action: permissionManager.ALLOW_ACTION,
state: "granted",
}, {
action: permissionManager.DENY_ACTION,
state: "denied",
}, {
action: permissionManager.PROMPT_ACTION,
state: "prompt",
}, {
action: permissionManager.UNKNOWN_ACTION,
state: "prompt",
}];
return tests.reduce((promise, test) => {
return promise.then(function() {
if (test.action == permissionManager.UNKNOWN_ACTION) {
SpecialPowers.removePermission("desktop-notification", document);
} else {
SpecialPowers.addPermission("desktop-notification",
test.action, document);
}
return swr.pushManager.permissionState().then(state => {
is(state, test.state, JSON.stringify(test));
});
});
}, Promise.resolve());
}
function runTest() {
@ -91,7 +111,7 @@ http://creativecommons.org/licenses/publicdomain/
}).then(SimpleTest.finish);
}
SpecialPowers.addPermission('push', false, document);
SpecialPowers.addPermission("desktop-notification", false, document);
SpecialPowers.pushPrefEnv({"set": [
["dom.push.enabled", true],
["dom.serviceWorkers.exemptFromPerDomainMax", true],

View File

@ -131,7 +131,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -293,7 +293,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>

View File

@ -85,7 +85,7 @@ http://creativecommons.org/licenses/publicdomain/
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
SpecialPowers.addPermission('push', true, document);
SpecialPowers.addPermission("desktop-notification", true, document);
SimpleTest.waitForExplicitFinish();
</script>
</body>