зеркало из https://github.com/mozilla/gecko-dev.git
Bug 978660 - no need to prompt if gUM is already granted. r=fabrice.
This commit is contained in:
Родитель
289ee87838
Коммит
8cf6c4014d
|
@ -42,6 +42,39 @@ XPCOMUtils.defineLazyServiceGetter(this,
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
/**
|
||||
* Determine if a permission should be prompt to user or not.
|
||||
*
|
||||
* @param aPerm requested permission
|
||||
* @param aAction the action according to principal
|
||||
* @return true if prompt is required
|
||||
*/
|
||||
function shouldPrompt(aPerm, aAction) {
|
||||
return ((aAction == Ci.nsIPermissionManager.PROMPT_ACTION) ||
|
||||
(aAction == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
||||
PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the default choices for the requested permissions
|
||||
*
|
||||
* @param aTypesInfo requested permissions
|
||||
* @return the default choices for permissions with options, return
|
||||
* undefined if no option in all requested permissions.
|
||||
*/
|
||||
function buildDefaultChoices(aTypesInfo) {
|
||||
let choices;
|
||||
for (let type of aTypesInfo) {
|
||||
if (type.options.length > 0) {
|
||||
if (!choices) {
|
||||
choices = {};
|
||||
}
|
||||
choices[type.access] = type.options[0];
|
||||
}
|
||||
}
|
||||
return choices;
|
||||
}
|
||||
|
||||
/**
|
||||
* aTypesInfo is an array of {permission, access, action, deny} which keeps
|
||||
* the information of each permission. This arrary is initialized in
|
||||
|
@ -62,9 +95,7 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
|
|||
{
|
||||
let type =
|
||||
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
|
||||
if (type == Ci.nsIPermissionManager.PROMPT_ACTION ||
|
||||
(type == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
||||
PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0)) {
|
||||
if (shouldPrompt(aPerm, type)) {
|
||||
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
|
||||
if (!aSession) {
|
||||
permissionManager.addFromPrincipal(aPrincipal,
|
||||
|
@ -104,22 +135,23 @@ ContentPermissionPrompt.prototype = {
|
|||
type.action =
|
||||
Services.perms.testExactPermissionFromPrincipal(request.principal,
|
||||
type.access);
|
||||
if (type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
||||
PROMPT_FOR_UNKNOWN.indexOf(type.access) >= 0) {
|
||||
if (shouldPrompt(type.access, type.action)) {
|
||||
type.action = Ci.nsIPermissionManager.PROMPT_ACTION;
|
||||
}
|
||||
});
|
||||
|
||||
// If all permissions are allowed already, call allow() without prompting.
|
||||
// If all permissions are allowed already and no more than one option,
|
||||
// call allow() without prompting.
|
||||
let checkAllowPermission = function(type) {
|
||||
if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION &&
|
||||
type.options.length <= 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (typesInfo.every(checkAllowPermission)) {
|
||||
debug("all permission requests are allowed");
|
||||
request.allow();
|
||||
request.allow(buildDefaultChoices(typesInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -185,7 +217,8 @@ ContentPermissionPrompt.prototype = {
|
|||
}
|
||||
return !type.deny;
|
||||
}
|
||||
if (typesInfo.filter(notDenyAppPrincipal).length === 0) {
|
||||
// Cancel the entire request if one of the requested permissions is denied
|
||||
if (!typesInfo.every(notDenyAppPrincipal)) {
|
||||
request.cancel();
|
||||
return true;
|
||||
}
|
||||
|
@ -206,11 +239,6 @@ ContentPermissionPrompt.prototype = {
|
|||
|
||||
_id: 0,
|
||||
prompt: function(request) {
|
||||
if (secMan.isSystemPrincipal(request.principal)) {
|
||||
request.allow();
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the typesInfo and set the default value.
|
||||
let typesInfo = [];
|
||||
let perms = request.types.QueryInterface(Ci.nsIArray);
|
||||
|
@ -234,6 +262,12 @@ ContentPermissionPrompt.prototype = {
|
|||
typesInfo.push(tmp);
|
||||
}
|
||||
|
||||
if (secMan.isSystemPrincipal(request.principal)) {
|
||||
request.allow(buildDefaultChoices(typesInfo));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (typesInfo.length == 0) {
|
||||
request.cancel();
|
||||
return;
|
||||
|
@ -254,11 +288,9 @@ ContentPermissionPrompt.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// prompt PROMPT_ACTION request only.
|
||||
typesInfo.forEach(function(aType, aIndex) {
|
||||
if (aType.action != Ci.nsIPermissionManager.PROMPT_ACTION || aType.deny) {
|
||||
typesInfo.splice(aIndex);
|
||||
}
|
||||
// prompt PROMPT_ACTION request or request with options.
|
||||
typesInfo = typesInfo.filter(function(type) {
|
||||
return !type.deny && (type.action == Ci.nsIPermissionManager.PROMPT_ACTION || type.options.length > 0) ;
|
||||
});
|
||||
|
||||
let frame = request.element;
|
||||
|
@ -366,6 +398,9 @@ ContentPermissionPrompt.prototype = {
|
|||
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
|
||||
? true
|
||||
: request.remember;
|
||||
let isGranted = typesInfo.every(function(type) {
|
||||
return type.action == Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
});
|
||||
let permissions = {};
|
||||
for (let i in typesInfo) {
|
||||
debug("prompt " + typesInfo[i].permission);
|
||||
|
@ -378,7 +413,8 @@ ContentPermissionPrompt.prototype = {
|
|||
id: requestId,
|
||||
origin: principal.origin,
|
||||
isApp: isApp,
|
||||
remember: remember
|
||||
remember: remember,
|
||||
isGranted: isGranted,
|
||||
};
|
||||
|
||||
if (isApp) {
|
||||
|
|
|
@ -11,4 +11,6 @@ run-if = toolkit == "gonk"
|
|||
run-if = toolkit == "gonk"
|
||||
[test_permission_deny.html]
|
||||
run-if = toolkit == "gonk"
|
||||
[test_permission_gum_remember.html]
|
||||
run-if = toolkit == "gonk"
|
||||
[test_systemapp.html]
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=978660
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>gUM Remember Permission Test</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978660">Test remembering gUM Permission</a>
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
'use strict';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
|
||||
|
||||
var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js');
|
||||
var gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||
gScript.addMessageListener('permission-request', function(detail) {
|
||||
ok(false, 'unexpected mozChromeEvent for permission prompt');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'permission-deny',
|
||||
remember: false,
|
||||
};
|
||||
gScript.sendAsyncMessage('permission-response', response);
|
||||
});
|
||||
|
||||
var gTests = [
|
||||
{
|
||||
'audio': true,
|
||||
'video': {facingMode: 'environment', required: ['facingMode']},
|
||||
},
|
||||
{
|
||||
'video': {facingMode: 'environment', required: ['facingMode']},
|
||||
},
|
||||
{
|
||||
'audio': true,
|
||||
},
|
||||
];
|
||||
|
||||
function testGranted() {
|
||||
info('test remember permission granted');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let steps = [].concat(gTests);
|
||||
function nextStep() {
|
||||
if (steps.length > 0) {
|
||||
let requestedType = steps.shift();
|
||||
info('getUserMedia for ' + JSON.stringify(requestedType));
|
||||
navigator.mozGetUserMedia(requestedType, function success() {
|
||||
ok(true, 'expected gUM success');
|
||||
nextStep();
|
||||
}, function failure(err) {
|
||||
ok(false, 'unexpected gUM fail: ' + err);
|
||||
nextStep();
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'video-capture', allow: true, context: document},
|
||||
{type: 'audio-capture', allow: true, context: document},
|
||||
], nextStep);
|
||||
});
|
||||
}
|
||||
|
||||
function testDenied() {
|
||||
info('test remember permission denied');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let steps = [].concat(gTests);
|
||||
function nextStep() {
|
||||
if (steps.length > 0) {
|
||||
let requestedType = steps.shift();
|
||||
info('getUserMedia for ' + JSON.stringify(requestedType));
|
||||
navigator.mozGetUserMedia(requestedType, function success() {
|
||||
ok(false, 'unexpected gUM success');
|
||||
nextStep();
|
||||
}, function failure(err) {
|
||||
ok(true, 'expected gUM fail: ' + err);
|
||||
nextStep();
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'video-capture', allow: false, context: document},
|
||||
{type: 'audio-capture', allow: false, context: document},
|
||||
], nextStep);
|
||||
});
|
||||
}
|
||||
|
||||
function testPartialDeniedAudio() {
|
||||
info('test remember permission partial denied: audio');
|
||||
return new Promise(function(resolve, reject) {
|
||||
info('getUserMedia for video and audio');
|
||||
function nextStep() {
|
||||
navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
|
||||
audio: true}, function success() {
|
||||
ok(false, 'unexpected gUM success');
|
||||
resolve();
|
||||
}, function failure(err) {
|
||||
ok(true, 'expected gUM fail: ' + err);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'video-capture', allow: true, context: document},
|
||||
{type: 'audio-capture', allow: false, context: document},
|
||||
], nextStep);
|
||||
});
|
||||
}
|
||||
|
||||
function testPartialDeniedVideo() {
|
||||
info('test remember permission partial denied: video');
|
||||
return new Promise(function(resolve, reject) {
|
||||
info('getUserMedia for video and audio');
|
||||
function nextStep() {
|
||||
navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
|
||||
audio: true}, function success() {
|
||||
ok(false, 'unexpected gUM success');
|
||||
resolve();
|
||||
}, function failure(err) {
|
||||
ok(true, 'expected gUM fail: ' + err);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'video-capture', allow: false, context: document},
|
||||
{type: 'audio-capture', allow: true, context: document},
|
||||
], nextStep);
|
||||
});
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
testGranted()
|
||||
.then(testDenied)
|
||||
.then(testPartialDeniedAudio)
|
||||
.then(testPartialDeniedVideo)
|
||||
.then(function() {
|
||||
info('test finished, teardown');
|
||||
gScript.sendAsyncMessage('teardown', '');
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['media.navigator.permission.disabled', false],
|
||||
]
|
||||
}, runTests);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче