Bug 1318218 - Remove PermissionsTable; r=baku,jryans

This also removes the WebIDE UI for viewing the permissions table.
This commit is contained in:
Ehsan Akhgari 2016-11-16 22:23:35 -05:00
parent e599757126
commit f0f85366d9
44 changed files with 1 additions and 2122 deletions

View File

@ -3296,17 +3296,6 @@ module.exports={
"_retval": "longstring"
}
}
},
{
"name": "getRawPermissionsTable",
"request": {
"type": "getRawPermissionsTable"
},
"response": {
"value": {
"_retval": "json"
}
}
}
],
"events": {}

View File

@ -24,7 +24,6 @@ const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsTable.jsm");
var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
@ -67,56 +66,6 @@ function buildDefaultChoices(aTypesInfo) {
return choices;
}
/**
* aTypesInfo is an array of {permission, access, action, deny} which keeps
* the information of each permission. This arrary is initialized in
* ContentPermissionPrompt.prompt and used among functions.
*
* aTypesInfo[].permission : permission name
* aTypesInfo[].access : permission name + request.access
* aTypesInfo[].action : the default action of this permission
* aTypesInfo[].deny : true if security manager denied this app's origin
* principal.
* Note:
* aTypesInfo[].permission will be sent to prompt only when
* aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
*/
function rememberPermission(aTypesInfo, aPrincipal, aSession)
{
function convertPermToAllow(aPerm, aPrincipal)
{
let type =
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
if (shouldPrompt(aPerm, type)) {
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
if (!aSession) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION);
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
}
}
}
for (let i in aTypesInfo) {
// Expand the permission to see if we have multiple access properties
// to convert
let perm = aTypesInfo[i].permission;
let access = PermissionsTable[perm].access;
if (access) {
for (let idx in access) {
convertPermToAllow(perm + "-" + access[idx], aPrincipal);
}
} else {
convertPermToAllow(perm, aPrincipal);
}
}
}
function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = {
@ -296,7 +245,6 @@ ContentPermissionPrompt.prototype = {
this.sendToBrowserWindow("permission-prompt", request, typesInfo,
function(type, remember, choices) {
if (type == "permission-allow") {
rememberPermission(typesInfo, request.principal, !remember);
if (callback) {
callback();
}

View File

@ -32,8 +32,6 @@
<!ENTITY runtimeMenu_accesskey "R">
<!ENTITY runtimeMenu_disconnect_label "Disconnect">
<!ENTITY runtimeMenu_disconnect_accesskey "D">
<!ENTITY runtimeMenu_showPermissionTable_label "Permissions Table">
<!ENTITY runtimeMenu_showPermissionTable_accesskey "P">
<!ENTITY runtimeMenu_takeScreenshot_label "Screenshot">
<!ENTITY runtimeMenu_takeScreenshot_accesskey "S">
<!ENTITY runtimeMenu_showDetails_label "Runtime Info">
@ -141,10 +139,6 @@
<!ENTITY prefs_options_autosavefiles "Autosave files">
<!ENTITY prefs_options_autosavefiles_tooltip "Automatically save edited files before running project">
<!-- Permissions Table -->
<!ENTITY permissionstable_title "Permissions Table">
<!ENTITY permissionstable_name_header "Name">
<!-- Runtime Details -->
<!ENTITY runtimedetails_title "Runtime Info">
<!ENTITY runtimedetails_adbIsRoot "ADB is root: ">

View File

@ -12,8 +12,6 @@ webide.jar:
content/details.js (details.js)
content/addons.js (addons.js)
content/addons.xhtml (addons.xhtml)
content/permissionstable.js (permissionstable.js)
content/permissionstable.xhtml (permissionstable.xhtml)
content/runtimedetails.js (runtimedetails.js)
content/runtimedetails.xhtml (runtimedetails.xhtml)
content/prefs.js (prefs.js)

View File

@ -1,78 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var Cu = Components.utils;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const Services = require("Services");
const {AppManager} = require("devtools/client/webide/modules/app-manager");
const {Connection} = require("devtools/shared/client/connection-manager");
window.addEventListener("load", function onLoad() {
window.removeEventListener("load", onLoad);
document.querySelector("#close").onclick = CloseUI;
AppManager.on("app-manager-update", OnAppManagerUpdate);
BuildUI();
}, true);
window.addEventListener("unload", function onUnload() {
window.removeEventListener("unload", onUnload);
AppManager.off("app-manager-update", OnAppManagerUpdate);
});
function CloseUI() {
window.parent.UI.openProject();
}
function OnAppManagerUpdate(event, what) {
if (what == "connection" || what == "runtime-global-actors") {
BuildUI();
}
}
function generateFields(json) {
let table = document.querySelector("table");
let permissionsTable = json.rawPermissionsTable;
for (let name in permissionsTable) {
let tr = document.createElement("tr");
tr.className = "line";
let td = document.createElement("td");
td.textContent = name;
tr.appendChild(td);
for (let type of ["app", "privileged", "certified"]) {
let td = document.createElement("td");
if (permissionsTable[name][type] == json.ALLOW_ACTION) {
td.textContent = "✓";
td.className = "permallow";
}
if (permissionsTable[name][type] == json.PROMPT_ACTION) {
td.textContent = "!";
td.className = "permprompt";
}
if (permissionsTable[name][type] == json.DENY_ACTION) {
td.textContent = "✕";
td.className = "permdeny";
}
tr.appendChild(td);
}
table.appendChild(tr);
}
}
var getRawPermissionsTablePromise; // Used by tests
function BuildUI() {
let table = document.querySelector("table");
let lines = table.querySelectorAll(".line");
for (let line of lines) {
line.remove();
}
if (AppManager.connection &&
AppManager.connection.status == Connection.Status.CONNECTED &&
AppManager.deviceFront) {
getRawPermissionsTablePromise = AppManager.deviceFront.getRawPermissionsTable()
.then(json => generateFields(json));
} else {
CloseUI();
}
}

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" >
%webideDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf8"/>
<link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/>
<link rel="stylesheet" href="chrome://webide/skin/permissionstable.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="chrome://webide/content/permissionstable.js"></script>
</head>
<body>
<div id="controls">
<a id="close">&deck_close;</a>
</div>
<h1>&permissionstable_title;</h1>
<table class="permissionstable">
<tr>
<th>&permissionstable_name_header;</th>
<th>type:web</th>
<th>type:privileged</th>
<th>type:certified</th>
</tr>
</table>
</body>
</html>

View File

@ -11,7 +11,6 @@ var runtimeList = new RuntimeList(window, window.parent);
window.addEventListener("load", function onLoad() {
window.removeEventListener("load", onLoad, true);
document.getElementById("runtime-screenshot").onclick = TakeScreenshot;
document.getElementById("runtime-permissions").onclick = ShowPermissionsTable;
document.getElementById("runtime-details").onclick = ShowRuntimeDetails;
document.getElementById("runtime-disconnect").onclick = DisconnectRuntime;
document.getElementById("runtime-preferences").onclick = ShowDevicePreferences;
@ -37,10 +36,6 @@ function ShowRuntimeDetails() {
runtimeList.showRuntimeDetails();
}
function ShowPermissionsTable() {
runtimeList.showPermissionsTable();
}
function ShowDevicePreferences() {
runtimeList.showDevicePreferences();
}

View File

@ -33,7 +33,6 @@
<div id="runtime-panel-other"></div>
<div id="runtime-actions">
<button class="panel-item" id="runtime-details">&runtimeMenu_showDetails_label;</button>
<button class="panel-item" id="runtime-permissions">&runtimeMenu_showPermissionTable_label;</button>
<button class="panel-item" id="runtime-preferences">&runtimeMenu_showDevicePrefs_label;</button>
<button class="panel-item" id="runtime-settings">&runtimeMenu_showSettings_label;</button>
<button class="panel-item" id="runtime-screenshot">&runtimeMenu_takeScreenshot_label;</button>

View File

@ -440,7 +440,6 @@ var UI = {
// Runtime commands
let monitorCmd = document.querySelector("#cmd_showMonitor");
let screenshotCmd = document.querySelector("#cmd_takeScreenshot");
let permissionsCmd = document.querySelector("#cmd_showPermissionsTable");
let detailsCmd = document.querySelector("#cmd_showRuntimeDetails");
let disconnectCmd = document.querySelector("#cmd_disconnectRuntime");
let devicePrefsCmd = document.querySelector("#cmd_showDevicePrefs");
@ -450,7 +449,6 @@ var UI = {
if (AppManager.deviceFront) {
monitorCmd.removeAttribute("disabled");
detailsCmd.removeAttribute("disabled");
permissionsCmd.removeAttribute("disabled");
screenshotCmd.removeAttribute("disabled");
}
if (AppManager.preferenceFront) {
@ -463,7 +461,6 @@ var UI = {
} else {
monitorCmd.setAttribute("disabled", "true");
detailsCmd.setAttribute("disabled", "true");
permissionsCmd.setAttribute("disabled", "true");
screenshotCmd.setAttribute("disabled", "true");
disconnectCmd.setAttribute("disabled", "true");
devicePrefsCmd.setAttribute("disabled", "true");
@ -1047,10 +1044,6 @@ var Cmds = {
}), "taking screenshot");
},
showPermissionsTable: function () {
UI.selectDeckPanel("permissionstable");
},
showRuntimeDetails: function () {
UI.selectDeckPanel("runtimedetails");
},

View File

@ -45,7 +45,6 @@
<command id="cmd_showRuntimePanel" oncommand="Cmds.showRuntimePanel()"/>
<command id="cmd_disconnectRuntime" oncommand="Cmds.disconnectRuntime()" label="&runtimeMenu_disconnect_label;"/>
<command id="cmd_showMonitor" oncommand="Cmds.showMonitor()" label="&runtimeMenu_showMonitor_label;"/>
<command id="cmd_showPermissionsTable" oncommand="Cmds.showPermissionsTable()" label="&runtimeMenu_showPermissionTable_label;"/>
<command id="cmd_showRuntimeDetails" oncommand="Cmds.showRuntimeDetails()" label="&runtimeMenu_showDetails_label;"/>
<command id="cmd_takeScreenshot" oncommand="Cmds.takeScreenshot()" label="&runtimeMenu_takeScreenshot_label;"/>
<command id="cmd_toggleEditor" oncommand="Cmds.toggleEditors()" label="&viewMenu_toggleEditor_label;"/>
@ -84,7 +83,6 @@
<menupopup id="menu-runtime-popup">
<menuitem command="cmd_showMonitor" accesskey="&runtimeMenu_showMonitor_accesskey;"/>
<menuitem command="cmd_takeScreenshot" accesskey="&runtimeMenu_takeScreenshot_accesskey;"/>
<menuitem command="cmd_showPermissionsTable" accesskey="&runtimeMenu_showPermissionTable_accesskey;"/>
<menuitem command="cmd_showRuntimeDetails" accesskey="&runtimeMenu_showDetails_accesskey;"/>
<menuitem command="cmd_showDevicePrefs" accesskey="&runtimeMenu_showDevicePrefs_accesskey;"/>
<menuitem command="cmd_showSettings" accesskey="&runtimeMenu_showSettings_accesskey;"/>
@ -156,7 +154,6 @@
<iframe id="deck-panel-projecteditor" flex="1"/>
<iframe id="deck-panel-addons" flex="1" src="addons.xhtml"/>
<iframe id="deck-panel-prefs" flex="1" src="prefs.xhtml"/>
<iframe id="deck-panel-permissionstable" flex="1" lazysrc="permissionstable.xhtml"/>
<iframe id="deck-panel-runtimedetails" flex="1" lazysrc="runtimedetails.xhtml"/>
<iframe id="deck-panel-monitor" flex="1" lazysrc="monitor.xhtml"/>
<iframe id="deck-panel-devicepreferences" flex="1" lazysrc="devicepreferences.xhtml"/>

View File

@ -66,10 +66,6 @@ RuntimeList.prototype = {
this._Cmds.showRuntimeDetails();
},
showPermissionsTable: function () {
this._Cmds.showPermissionsTable();
},
showDevicePreferences: function () {
this._Cmds.showDevicePrefs();
},
@ -95,7 +91,6 @@ RuntimeList.prototype = {
// Runtime commands
let screenshotCmd = doc.querySelector("#runtime-screenshot");
let permissionsCmd = doc.querySelector("#runtime-permissions");
let detailsCmd = doc.querySelector("#runtime-details");
let disconnectCmd = doc.querySelector("#runtime-disconnect");
let devicePrefsCmd = doc.querySelector("#runtime-preferences");
@ -104,7 +99,6 @@ RuntimeList.prototype = {
if (AppManager.connected) {
if (AppManager.deviceFront) {
detailsCmd.removeAttribute("disabled");
permissionsCmd.removeAttribute("disabled");
screenshotCmd.removeAttribute("disabled");
}
if (AppManager.preferenceFront) {
@ -116,7 +110,6 @@ RuntimeList.prototype = {
disconnectCmd.removeAttribute("disabled");
} else {
detailsCmd.setAttribute("disabled", "true");
permissionsCmd.setAttribute("disabled", "true");
screenshotCmd.setAttribute("disabled", "true");
disconnectCmd.setAttribute("disabled", "true");
devicePrefsCmd.setAttribute("disabled", "true");

View File

@ -54,7 +54,6 @@ skip-if = (os == "win" && os_version == "10.0") # Bug 1197053
[test_addons.html]
skip-if = true # Bug 1201392 - Update add-ons after migration
[test_device_runtime.html]
[test_device_permissions.html]
[test_autoconnect_runtime.html]
[test_autoselect_project.html]
[test_telemetry.html]

View File

@ -1,81 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title></title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
<script type="application/javascript;version=1.8" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<script type="application/javascript;version=1.8">
window.onload = function() {
SimpleTest.waitForExplicitFinish();
Task.spawn(function* () {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
let win = yield openWebIDE();
let permIframe = win.document.querySelector("#deck-panel-permissionstable");
let docRuntime = getRuntimeDocument(win);
let winRuntime = getRuntimeWindow(win);
yield connectToLocalRuntime(win);
let perm = docRuntime.querySelector("#runtime-permissions");
ok(!perm.hasAttribute("disabled"), "perm cmd enabled");
let deck = win.document.querySelector("#deck");
winRuntime.runtimeList.showPermissionsTable();
is(deck.selectedPanel, permIframe, "permission iframe selected");
yield nextTick();
yield lazyIframeIsLoaded(permIframe);
yield permIframe.contentWindow.getRawPermissionsTablePromise;
doc = permIframe.contentWindow.document;
trs = doc.querySelectorAll(".line");
found = false;
for (let tr of trs) {
let [name,v1,v2,v3] = tr.querySelectorAll("td");
if (name.textContent == "geolocation") {
found = true;
is(v1.className, "permprompt", "geolocation perm is valid");
is(v2.className, "permprompt", "geolocation perm is valid");
is(v3.className, "permprompt", "geolocation perm is valid");
break;
}
}
ok(found, "Found geolocation line");
doc.querySelector("#close").click();
ok(!deck.selectedPanel, "No panel selected");
DebuggerServer.destroy();
yield closeWebIDE(win);
SimpleTest.finish();
}).then(null, e => {
ok(false, "Exception: " + e);
SimpleTest.finish();
});
}
</script>
</body>
</html>

View File

@ -12,7 +12,6 @@ webide.jar:
skin/deck.css (deck.css)
skin/addons.css (addons.css)
skin/runtimedetails.css (runtimedetails.css)
skin/permissionstable.css (permissionstable.css)
skin/monitor.css (monitor.css)
skin/config-view.css (config-view.css)
skin/wifi-auth.css (wifi-auth.css)

View File

@ -130,7 +130,6 @@ button.panel-item:not(:disabled):hover {
.project-panel-item-openpackaged { background-image: -moz-image-rect(url("icons.png"), 260, 438, 286, 412); }
.runtime-panel-item-simulator { background-image: -moz-image-rect(url("icons.png"), 0, 438, 26, 412); }
.runtime-panel-item-other { background-image: -moz-image-rect(url("icons.png"), 26, 438, 52, 412); }
#runtime-permissions { background-image: -moz-image-rect(url("icons.png"), 105, 438, 131, 412); }
#runtime-screenshot { background-image: -moz-image-rect(url("icons.png"), 131, 438, 156, 412); }
#runtime-preferences,

View File

@ -1,23 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html, body {
background: white;
}
.permissionstable td {
text-align: center;
}
.permallow {
color: rgb(152,207,57);
}
.permprompt {
color: rgb(0,158,237);
}
.permdeny {
color: rgb(204,73,8);
}

View File

@ -13,7 +13,6 @@ const {DebuggerServer} = require("devtools/server/main");
const {getSystemInfo, getSetting} = require("devtools/shared/system");
const {deviceSpec} = require("devtools/shared/specs/device");
const FileReader = require("FileReader");
const {PermissionsTable} = require("resource://gre/modules/PermissionsTable.jsm");
var DeviceActor = exports.DeviceActor = protocol.ActorClassWithSpec(deviceSpec, {
_desc: null,
@ -56,15 +55,5 @@ var DeviceActor = exports.DeviceActor = protocol.ActorClassWithSpec(deviceSpec,
context.drawWindow(window, 0, 0, width, height, "rgb(255,255,255)", flags);
let dataURL = canvas.toDataURL("image/png");
return new LongStringActor(this.conn, dataURL);
},
getRawPermissionsTable: function () {
return {
rawPermissionsTable: PermissionsTable,
UNKNOWN_ACTION: Ci.nsIPermissionManager.UNKNOWN_ACTION,
ALLOW_ACTION: Ci.nsIPermissionManager.ALLOW_ACTION,
DENY_ACTION: Ci.nsIPermissionManager.DENY_ACTION,
PROMPT_ACTION: Ci.nsIPermissionManager.PROMPT_ACTION
};
}
});

View File

@ -18,7 +18,6 @@ window.onload = function() {
var Cc = Components.classes;
var Ci = Components.interfaces;
Cu.import("resource://gre/modules/PermissionsTable.jsm");
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var {DebuggerClient} = require("devtools/shared/client/main");
var {DebuggerServer} = require("devtools/server/main");
@ -38,7 +37,7 @@ window.onload = function() {
client.listTabs(function onListTabs(aResponse) {
var d = getDeviceFront(client, aResponse);
var desc, permissions;
var desc;
var appInfo = Services.appinfo;
var utils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
@ -72,11 +71,6 @@ window.onload = function() {
var profileDir = currProfD.path;
ok(profileDir.indexOf(desc.profile.length > 0 && desc.profile) != -1, "valid profile name");
var a = JSON.stringify(PermissionsTable);
var b = JSON.stringify(permissions.rawPermissionsTable);
is(a, b, "Permissions Tables is valid");
client.close().then(() => {
DebuggerServer.destroy();
SimpleTest.finish()
@ -85,8 +79,6 @@ window.onload = function() {
d.getDescription().then((v) => desc = v)
.then(() => d.getRawPermissionsTable())
.then((json) => permissions = json)
.then(checkValues);
});

View File

@ -12,7 +12,6 @@ const deviceSpec = generateActorSpec({
getDescription: {request: {}, response: { value: RetVal("json")}},
getWallpaper: {request: {}, response: { value: RetVal("longstring")}},
screenshotToDataURL: {request: {}, response: { value: RetVal("longstring")}},
getRawPermissionsTable: {request: {}, response: { value: RetVal("json")}},
},
});

View File

@ -1,583 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Ci = Components.interfaces;
const Cu = Components.utils;
this.EXPORTED_SYMBOLS = [
"PermissionsTable",
"PermissionsReverseTable",
"expandPermissions",
"appendAccessToPermName",
"isExplicitInPermissionsTable",
"AllPossiblePermissions"
];
// Permission access flags
const READONLY = "readonly";
const CREATEONLY = "createonly";
const READCREATE = "readcreate";
const READWRITE = "readwrite";
const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
// Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
// Permissions that are implicit:
// battery-status, network-information, vibration,
// device-capabilities
this.PermissionsTable = { geolocation: {
app: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: PROMPT_ACTION
},
"geolocation-noprompt": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
substitute: ["geolocation"]
},
camera: {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
alarms: {
app: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"tcp-socket": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"udp-socket": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"network-events": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
contacts: {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:apps": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read"]
},
"device-storage:crashes": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read"]
},
"device-storage:pictures": {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:videos": {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:music": {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:sdcard": {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
sms: {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"speech-recognition": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
browser: {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"browser:universalxss": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
mobilenetwork: {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
power: {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
push: {
app: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
settings: {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"],
additional: ["indexedDB-chrome-settings", "settings-api"]
},
// This exists purely for tests, no app
// should ever use it. It can only be
// handed out by SpecialPowers.
"settings-clear": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: DENY_ACTION,
additional: ["indexedDB-chrome-settings", "settings-api"]
},
permissions: {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
attention: {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"global-clickthrough-overlay": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"moz-attention": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["attention"]
},
"webapps-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"homescreen-webapps-manage": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"backgroundservice": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"desktop-notification": {
app: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"networkstats-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"wifi-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"systemXHR": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"idle": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"time": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"background-sensors": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-normal": {
app: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-content": {
app: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-notification": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-alarm": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-system": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-telephony": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-audio-channel-telephony": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["audio-channel-telephony"]
},
"audio-channel-ringer": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-audio-channel-ringer": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["audio-channel-ringer"]
},
"audio-channel-publicnotification": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"open-remote-window": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"input": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"input-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"audio-capture": {
app: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
"audio-capture:3gpp": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-capture:3gpp2": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"speaker-control": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"downloads": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"video-capture": {
app: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
"feature-detection": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
// This permission doesn't actually grant access to
// anything. It exists only to check the correctness
// of web prompt composed permissions in tests.
"test-permission": {
app: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"firefox-accounts": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-firefox-accounts": {
app: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
substitute: ["firefox-accounts"]
},
"themeable": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"settings:wallpaper.image": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"],
additional: ["settings-api"]
},
"tv": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"before-after-keyboard-event": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"presentation-device-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"secureelement-manage": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"inputport": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"system-update": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"open-hidden-window": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-extremely-unstable-and-will-change-webcomponents": {
app: DENY_ACTION,
trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"system-app-only-audio-channels-in-app": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"previously-certified-app": {
app: DENY_ACTION,
trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
}
};
/**
* Append access modes to the permission name as suffixes.
* e.g. permission name 'contacts' with ['read', 'write'] =
* ['contacts-read', contacts-write']
* @param string aPermName
* @param array aAccess
* @returns array containing access-appended permission names.
**/
this.appendAccessToPermName = function appendAccessToPermName(aPermName, aAccess) {
if (aAccess.length == 0) {
return [aPermName];
}
return aAccess.map(function(aMode) {
return aPermName + "-" + aMode;
});
};
/**
* Expand an access string into multiple permission names,
* e.g: permission name 'contacts' with 'readwrite' =
* ['contacts-read', 'contacts-create', 'contacts-write']
* @param string aPermName
* @param string aAccess (optional)
* @returns array containing expanded permission names.
**/
this.expandPermissions = function expandPermissions(aPermName, aAccess) {
if (!PermissionsTable[aPermName]) {
let errorMsg =
"PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName;
Cu.reportError(errorMsg);
dump(errorMsg);
return [];
}
const tableEntry = PermissionsTable[aPermName];
if (tableEntry.substitute && tableEntry.additional) {
let errorMsg =
"PermissionsTable.jsm: expandPermissions: Can't handle both 'substitute' " +
"and 'additional' entries for permission: " + aPermName;
Cu.reportError(errorMsg);
dump(errorMsg);
return [];
}
if (!aAccess && tableEntry.access ||
aAccess && !tableEntry.access) {
let errorMsg =
"PermissionsTable.jsm: expandPermissions: Invalid access for permission " +
aPermName + ": " + aAccess + "\n";
Cu.reportError(errorMsg);
dump(errorMsg);
return [];
}
let expandedPermNames = [];
if (tableEntry.access && aAccess) {
let requestedSuffixes = [];
switch (aAccess) {
case READONLY:
requestedSuffixes.push("read");
break;
case CREATEONLY:
requestedSuffixes.push("create");
break;
case READCREATE:
requestedSuffixes.push("read", "create");
break;
case READWRITE:
requestedSuffixes.push("read", "create", "write");
break;
default:
return [];
}
let permArr = appendAccessToPermName(aPermName, requestedSuffixes);
// Add the same suffix to each of the additions.
if (tableEntry.additional) {
for (let additional of tableEntry.additional) {
permArr = permArr.concat(appendAccessToPermName(additional, requestedSuffixes));
}
}
// Only add the suffixed version if the suffix exists in the table.
for (let idx in permArr) {
let suffix = requestedSuffixes[idx % requestedSuffixes.length];
if (tableEntry.access.indexOf(suffix) != -1) {
expandedPermNames.push(permArr[idx]);
}
}
} else if (tableEntry.substitute) {
expandedPermNames = expandedPermNames.concat(tableEntry.substitute);
} else {
expandedPermNames.push(aPermName);
// Include each of the additions exactly as they appear in the table.
if (tableEntry.additional) {
expandedPermNames = expandedPermNames.concat(tableEntry.additional);
}
}
return expandedPermNames;
};
this.PermissionsReverseTable = {};
this.AllPossiblePermissions = [];
(function () {
// PermissionsTable as it is works well for direct searches, but not
// so well for reverse ones (that is, if I get something like
// device-storage:music-read or indexedDB-chrome-settings-read how
// do I know which permission it really is? Hence this table is
// born. The idea is that
// reverseTable[device-storage:music-read] should return
// device-storage:music
//
// We also need a list of all the possible permissions for things like the
// settingsmanager, so construct that while we're at it.
for (let permName in PermissionsTable) {
let permAliases = [];
if (PermissionsTable[permName].access) {
permAliases = expandPermissions(permName, "readwrite");
} else if (!PermissionsTable[permName].substitute) {
permAliases = expandPermissions(permName);
}
for (let i = 0; i < permAliases.length; i++) {
PermissionsReverseTable[permAliases[i]] = permName;
AllPossiblePermissions.push(permAliases[i]);
}
}
AllPossiblePermissions =
AllPossiblePermissions.concat(["indexedDB", "offline-app", "pin-app"]);
})();
this.isExplicitInPermissionsTable = function(aPermName, aIntStatus) {
// Check to see if the 'webapp' is app/privileged/certified.
let appStatus;
switch (aIntStatus) {
case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
appStatus = "certified";
break;
case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
appStatus = "privileged";
break;
default: // If it isn't certified or privileged, it's app
appStatus = "app";
break;
}
let realPerm = PermissionsReverseTable[aPermName];
if (realPerm) {
return (PermissionsTable[realPerm][appStatus] ==
Ci.nsIPermissionManager.PROMPT_ACTION);
} else {
return false;
}
}

View File

@ -1,9 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'PermissionsTable.jsm',
]

View File

@ -1,163 +0,0 @@
#!/usr/bin/env python
import jwt
receipt1 = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314356"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt2 = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314357"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_typ = {
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_product = {
"typ": "purchase-receipt",
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_user = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_iss = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_nbf = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_without_iat = {
"typ": "purchase-receipt",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
receipt_with_wrong_typ = {
"typ": "fake",
"product": {
"url": "https://www.mozilla.org",
"storedata": "5169314358"
},
"user": {
"type": "directed-identifier",
"value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
},
"iss": "http://mochi.test:8888",
"nbf": 131360185,
"iat": 131360188,
"detail": "http://mochi.test:8888/receipt/5169314356",
"verify": "http://mochi.test:8888/verify/5169314356",
"reissue": "http://mochi.test:8888/reissue/5169314356"
}
print("let valid_receipt1 = \"" + jwt.encode(receipt1, "") + "\";\n")
print("let valid_receipt2 = \"" + jwt.encode(receipt2, "") + "\";\n")
print("let receipt_without_typ = \"" + jwt.encode(receipt_without_typ, "") + "\";\n")
print("let receipt_without_product = \"" + jwt.encode(receipt_without_product, "") + "\";\n")
print("let receipt_without_user = \"" + jwt.encode(receipt_without_user, "") + "\";\n")
print("let receipt_without_iss = \"" + jwt.encode(receipt_without_iss, "") + "\";\n")
print("let receipt_without_nbf = \"" + jwt.encode(receipt_without_nbf, "") + "\";\n")
print("let receipt_without_iat = \"" + jwt.encode(receipt_without_iat, "") + "\";\n")
print("let receipt_with_wrong_typ = \"" + jwt.encode(receipt_with_wrong_typ, "") + "\";\n")

View File

@ -1,118 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function runAll(steps) {
SimpleTest.waitForExplicitFinish();
// Clone the array so we don't modify the original.
steps = steps.concat();
function next() {
if (steps.length) {
steps.shift()(next);
}
else {
SimpleTest.finish();
}
}
next();
}
function confirmNextPopup() {
var Ci = SpecialPowers.Ci;
var popupNotifications = SpecialPowers.wrap(window).top.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIWebNavigation).
QueryInterface(Ci.nsIDocShell).
chromeEventHandler.ownerDocument.defaultView.
PopupNotifications;
var popupPanel = popupNotifications.panel;
function onPopupShown() {
popupPanel.removeEventListener("popupshown", onPopupShown, false);
SpecialPowers.wrap(this).childNodes[0].button.doCommand();
popupNotifications._dismiss();
}
popupPanel.addEventListener("popupshown", onPopupShown, false);
}
function promiseNoPopup() {
var Ci = SpecialPowers.Ci;
var popupNotifications = SpecialPowers.wrap(window).top.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIWebNavigation).
QueryInterface(Ci.nsIDocShell).
chromeEventHandler.ownerDocument.defaultView.
PopupNotifications;
return new Promise((resolve) => {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(true, "The webapps-install notification didn't appear");
moveOn();
}
if (popupNotifications.getNotification("webapps-install")) {
ok(false, "Found the webapps-install notification");
moveOn();
}
tries++;
}, 100);
var moveOn = () => {
clearInterval(interval);
resolve();
};
});
}
// We need to mock the Alerts service, otherwise the alert that is shown
// at the end of an installation makes the test leak the app's icon.
const CID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
const ALERTS_SERVICE_CID = Components.ID(Cc[ALERTS_SERVICE_CONTRACT_ID].number);
var AlertsService = {
classID: Components.ID(CID),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
Ci.nsIAlertsService]),
createInstance: function(aOuter, aIID) {
if (aOuter) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(aIID);
},
init: function() {
Components.manager.nsIComponentRegistrar.registerFactory(this.classID,
"", ALERTS_SERVICE_CONTRACT_ID, this);
},
restore: function() {
Components.manager.nsIComponentRegistrar.registerFactory(ALERTS_SERVICE_CID,
"", ALERTS_SERVICE_CONTRACT_ID, null);
},
showAlert: function() {
},
showAlertNotification: function() {
},
};
AlertsService.init();
SimpleTest.registerCleanupFunction(() => {
AlertsService.restore();
});

View File

@ -36,7 +36,6 @@ DIRS += ['interfaces/' + i for i in interfaces]
DIRS += [
'animation',
'apps',
'base',
'archivereader',
'bindings',

View File

@ -16,13 +16,8 @@ UNIFIED_SOURCES += [
'PermissionUtils.cpp',
]
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
if CONFIG['MOZ_TIME_MANAGER']:
MOCHITEST_MANIFESTS += ['tests/mochitest-time.ini']
FINAL_LIBRARY = 'xul'
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -1,224 +0,0 @@
/** Test for Bug 815105 **/
/*
* gData is an array of object that tests using this framework must pass in
* The current tests only pass in a single element array. Each test in
* gData is executed by the framework for a given file
*
* Fields in gData object
* perms (required) Array of Strings
* list of permissions that this test will need. See
* http://dxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm
* These permissions are added after a sanity check and removed at
* test conclusion
*
* obj (required for default verifier) String
* The name of the window.navigator object used for accessing the
* WebAPI during the tests
*
* webidl (required for default verifier) String
* idl (required for default verifier) String
* Only one of webidl / idl is required
* The IDL describing the navigator object. The returned object
* during tests /must/ be an instanceof this
*
* skip (optional) Array of Strings
* A list of navigator.userAgent's to skip the second part of tests
* on. The tests still verify that you can't get obj on those
* platforms without permissions, however it is expected that adding
* the permission still won't allow access to those objects
*
* settings (optional) Array of preference tuples
* A list of settings that need to be set before this API is
* enabled. Note the settings are set before the sanity check is
* performed. If an API gates access only by preferences, then it
* will fail the initial test
*
* verifier (optional) Function
* A function used to test whether a WebAPI is accessible or not.
* The function takes a success and failure callback which both
* accept a msg argument. msg is surfaced up to the top level tests
* A default verifier is provided which only attempts to access
* the navigator object.
*
* needParentPerm (optional) Boolean
* Whether or not the parent frame requires these permissions as
* well. Otherwise the test process may be killed.
*/
SimpleTest.waitForExplicitFinish();
var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions;
const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable;
const TEST_DOMAIN = "http://example.org";
const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html"
var gContent = document.getElementById('content');
//var gData; defined in external files
var gCurrentTest = 0;
var gRemainingTests;
var pendingTests = {};
function PermTest(aData) {
var self = this;
var skip = aData.skip || false;
this.step = 0;
this.data = aData;
this.isSkip = skip &&
skip.some(function (el) {
return navigator.
userAgent.toLowerCase().
indexOf(el.toLowerCase()) != -1;
});
this.setupParent = false;
this.perms = expandPermissions(aData.perm);
this.id = gCurrentTest++;
this.iframe = null;
// keep a reference to this for eventhandler
pendingTests[this.id] = this;
this.createFrame = function() {
if (self.iframe) {
gContent.removeChild(self.iframe);
}
var iframe = document.createElement('iframe');
iframe.setAttribute('id', 'testframe' + self.step + self.perms)
iframe.setAttribute('remote', true);
iframe.src = TEST_DOMAIN + SHIM_PATH;
iframe.addEventListener('load', function _iframeLoad() {
iframe.removeEventListener('load', _iframeLoad);
// check permissions are correct
var allow = (self.step == 0 ? false : true);
self.perms.forEach(function (el) {
try {
var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe)
.contentDocument);
is(res, allow, (allow ? "Has " : "Doesn't have ") + el);
} catch(e) {
ok(false, "failed " + e);
}
});
var msg = {
id: self.id,
step: self.step++,
testdata: self.data,
}
// start the tests
iframe.contentWindow.postMessage(msg, "*");
});
self.iframe = iframe;
gContent.appendChild(iframe);
}
this.next = function () {
switch(self.step) {
case 0:
self.createFrame();
break;
case 1:
// add permissions
addPermissions(self.perms, SpecialPowers.
wrap(self.iframe).
contentDocument,
self.createFrame.bind(self));
break;
case 2:
if (self.iframe) {
gContent.removeChild(self.iframe);
}
checkFinish();
break;
default:
ok(false, "Should not be reached");
break
}
}
this.start = function() {
// some permissions need parent to have permission as well
if (!self.setupParent && self.data.needParentPerm &&
!SpecialPowers.isMainProcess()) {
self.setupParent = true;
addPermissions(self.perms, window.document, self.start.bind(self));
} else if (self.data.settings && self.data.settings.length) {
SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)},
self.next.bind(self));
} else {
self.next();
}
}
}
function addPermissions(aPerms, aDoc, aCallback) {
var permList = [];
aPerms.forEach(function (el) {
var obj = {'type': el,
'allow': 1,
'context': aDoc};
permList.push(obj);
});
SpecialPowers.pushPermissions(permList, aCallback);
}
function expandPermissions(aPerms) {
var perms = [];
aPerms.forEach(function(el) {
var access = permTable[el].access ? "readwrite" : null;
var expanded = expand(el, access);
for (let i = 0; i < expanded.length; i++) {
perms.push(SpecialPowers.unwrap(expanded[i]));
}
});
return perms;
}
function msgHandler(evt) {
var data = evt.data;
var test = pendingTests[data.id];
/*
* step 2 of tests should fail on
* platforms which are skipped
*/
if (test.isSkip && test.step == 2) {
todo(data.result, data.msg);
} else {
ok(data.result, data.msg);
}
if (test) {
test.next();
} else {
ok(false, "Received unknown id " + data.id);
checkFinish();
}
}
function checkFinish() {
if (--gRemainingTests) {
gTestRunner.next();
} else {
window.removeEventListener('message', msgHandler);
SimpleTest.finish();
}
}
function runTest() {
gRemainingTests = Object.keys(gData).length;
for (var test in gData) {
var test = new PermTest(gData[test]);
test.start();
yield undefined;
}
}
var gTestRunner = runTest();
window.addEventListener('load', function() { gTestRunner.next(); }, false);
window.addEventListener('message', msgHandler, false);

View File

@ -1,99 +0,0 @@
<html>
<head>
<script type="application/javascript;version=1.8">
function TestData(aOpts) {
for (var opt in aOpts) {
if (aOpts.hasOwnProperty(opt)) {
this[opt] = aOpts[opt];
}
}
}
TestData.prototype = {
getObj: function() {
if (!this.obj) {
return null;
}
// only one of the 2 should be set
if ((this.idl && this.webidl) ||
(!this.idl && !this.webidl)) {
return null;
}
// split on . to allow nested props
var props = this.obj.split(".");
var obj = window.navigator;
for (var i = 0; i < props.length && obj !== undefined; i++) {
obj = obj[props[i]];
}
if ((this.webidl && obj instanceof window[this.webidl]) ||
(this.idl && obj instanceof SpecialPowers.Ci[this.idl])) {
return obj;
} else {
return null;
}
},
// default verifier
verifier: function(success, failure) {
try {
if (this.getObj()) {
success(this.perm);
} else {
failure("Did not receive proper object");
}
} catch (e) {
failure("Received exception!: " + e);
}
},
}
function receiveMessage(e) {
var src = e.source;
var step = e.data.step;
var id = e.data.id;
var data = new TestData(e.data.testdata);
var success, failure;
function reply(res, msg) {
window.removeEventListener("message", receiveMessage, false);
src.postMessage({result: res, msg: msg,
id: id}, "*");
}
function _success(msg) {
reply(true, msg);
}
function _failure(msg) {
reply(false, msg);
}
// flip success and failure around for precheck
if (step == 0) {
success = _failure;
failure = _success;
} else {
success = _success;
failure = _failure;
}
if (data.verifier instanceof Function) {
data.verifier(success, failure);
} else {
// import toSource() function to global
eval(data.verifier);
verifier.bind(data, success, failure)();
}
}
window.addEventListener("message", receiveMessage, false);
</script>
</head>
<body>
<div id="content" style="display: none"></div>
</body>
</html>

View File

@ -1 +0,0 @@
[test_time.html]

View File

@ -1,27 +1,5 @@
[DEFAULT]
support-files =
file_framework.js
file_shim.html
file_empty.html
[test_browser.html]
skip-if = true
[test_idle.html]
# skip-if = (toolkit == 'gonk' && debug) #debug-only failure
skip-if = true
[test_permissions_api.html]
[test_power.html]
skip-if = true
[test_presentation-device-manage.html]
skip-if = true
[test_systemXHR.html]
[test_tcp-socket.html]
skip-if = true
[test_udp-socket.html]
skip-if = true
[test_keyboard.html]
# skip-if = toolkit == 'android'
skip-if = true
[test_input-manage.html]
# skip-if = toolkit == 'android'
skip-if = true

View File

@ -1,49 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.src = "http://example.org/";
iframe.addEventListener('load', function() {
iframe.removeEventListener('load', arguments.callee);
if (iframe.getScreenshot && typeof iframe.getScreenshot == "function") {
success("Got mozbrowser");
} else {
failure("Didn't get mozbrowser") ;
}
});
document.getElementById('content').appendChild(iframe);
}
var gData = [
{
perm: ["browser"],
needParentPerm: true,
settings: [["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true]],
verifier: verifier.toSource(),
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
try {
var obs = {
time: 1,
onidle: function() {
window.navigator.removeIdleObserver(obs);
},
}
// addIdleObserver throws if prinicpal doesn't have the permission
window.navigator.addIdleObserver(obs);
success("idle");
} catch (e) {
failure("Got an exception " + e);
}
}
var gData = [
{
perm: ["idle"],
verifier: verifier.toSource(),
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,69 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=920977
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 920977 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=920977">Mozilla Bug 920977 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
try {
if (!this.getObj()) {
failure("Did not receive proper object");
return;
}
} catch (e) {
failure("Received exception!: " + e);
return;
}
try {
this.getObj().removeFocus();
} catch (e) {
failure("Received exception!: " + e);
return;
}
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", true);
iframe.src = "http://example.org/";
iframe.addEventListener("load", function() {
iframe.removeEventListener("load", arguments.callee);
if (iframe.setInputMethodActive &&
typeof iframe.setInputMethodActive == "function") {
success("Got setInputMethodActive");
} else {
failure("Didn't get setInputMethodActive") ;
}
});
document.getElementById('content').appendChild(iframe);
}
var gData = [
{
perm: ["input-manage", "browser"],
needParentPerm: true,
obj: "mozInputMethod",
webidl: "MozInputMethod",
settings: [["dom.mozInputMethod.enabled", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true]],
verifier: verifier.toSource()
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,51 +0,0 @@
-<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=920977
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 920977 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=920977">Mozilla Bug 920977 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
try {
if (!this.getObj()) {
failure("Did not receive proper object");
return;
}
} catch (e) {
failure("Received exception!: " + e);
return;
}
try {
this.getObj().removeFocus();
failure("Should receive exception when accessing system only method.!");
} catch (e) {
success(this.perm);
}
}
var gData = [
{
perm: ["input"],
obj: "mozInputMethod",
webidl: "MozInputMethod",
settings: [["dom.mozInputMethod.enabled", true]],
verifier: verifier.toSource()
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,31 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
var gData = [
{
perm: ["networkstats-manage"],
obj: "mozNetworkStats",
webidl: "MozNetworkStatsManager",
settings: [["dom.mozNetworkStats.enabled", true]],
},
]
</script>
</pre>
</body>
</html>

View File

@ -1,30 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
var gData = [
{
perm: ["power"],
obj: "mozPower",
webidl: "MozPowerManager",
},
]
</script>
</pre>
</body>
</html>

View File

@ -1,38 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1080474
-->
<head>
<meta charset="utf-8">
<title>Test for presentation-device-manage permission</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1080474">test presentation-device-manage</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
if (window.navigator.mozPresentationDeviceInfo) {
success("Got mozPresentationDeviceInfo object!");
} else {
failure("Failed to get mozPresentationDeviceInfo object!");
}
}
var gData = [
{
perm: ["presentation-device-manage"],
settings: [["dom.presentation.enabled", true]],
obj: "mozPresentationDeviceInfo",
webidl: "PresentationDeviceInfoManager"
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,38 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
var xhr = new XMLHttpRequest({mozSystem: true});
if (xhr.mozSystem === true) {
success("systemXHR");
} else {
failure("Couldn't create systemXHR");
}
}
var gData = [
{
perm: ["systemXHR"],
verifier: verifier.toSource(),
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,52 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
/* mozTCPSocket only returns null on window init
* if the permission isn't set
*/
function verifier(success, failure) {
try {
var conn = navigator.mozTCPSocket.open("http://mochi.test/", 80);
if (conn) {
if (conn instanceof window.TCPSocket) {
success("Opened connection");
} else {
failure("connection didn't match interface");
}
} else {
failure("failed to open connection");
}
} catch (e) {
failure("Got an exception " + e);
}
}
var gData = [
{
perm: ["tcp-socket"],
needParentPerm: true,
settings: [["dom.mozTCPSocket.enabled", true]],
verifier: verifier.toSource(),
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,30 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
var gData = [
{
perm: ["time"],
obj: "mozTime",
webidl: "MozTimeManager",
},
]
</script>
</pre>
</body>
</html>

View File

@ -1,47 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=745283
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 745283 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=745283">Mozilla Bug 745283 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
function verifier(success, failure) {
try {
var socket = new UDPSocket();
if (socket) {
success("Opened socket");
} else {
failure("failed to open socket");
}
} catch (e) {
failure("Got an exception " + e);
}
}
var gData = [
{
perm: ["udp-socket"],
needParentPerm: true,
obj: "UDPSocket",
webidl: "UDPSocket",
settings: [["dom.udpsocket.enabled", true]],
verifier: verifier.toSource(),
}
]
</script>
</pre>
</body>
</html>

View File

@ -1,73 +0,0 @@
var Cu = Components.utils;
const READWRITE = "readwrite";
const UNKNOWN = "foobar";
var gData = [
// test normal expansion
{
permission: "contacts",
access: READWRITE,
expected: ["contacts-read", "contacts-create",
"contacts-write"]
},
// test additional expansion and access not having read+create+write
{
permission: "settings",
access: READWRITE,
expected: ["settings-read", "settings-write",
"settings-api-read", "settings-api-write",
"indexedDB-chrome-settings-read",
"indexedDB-chrome-settings-write"]
},
// test unknown access
{
permission: "contacts",
access: UNKNOWN,
expected: []
},
// test unknown permission
{
permission: UNKNOWN,
access: READWRITE,
expected: []
}
];
// check if 2 arrays contain the same elements
function do_check_set_eq(a1, a2) {
do_check_eq(a1.length, a2.length)
Array.sort(a1);
Array.sort(a2);
for (let i = 0; i < a1.length; ++i) {
do_check_eq(a1[i], a2[i])
}
}
function test_substitute_does_not_break_substituted(scope) {
const Ci = Components.interfaces;
// geolocation-noprompt substitutes for geolocation ...
do_check_eq(scope.PermissionsTable["geolocation-noprompt"].substitute[0],
"geolocation");
// ... and sets silent allow ...
do_check_eq(scope.PermissionsTable["geolocation-noprompt"].certified,
Ci.nsIPermissionManager.ALLOW_ACTION)
// ... which works ...
do_check_false(scope.isExplicitInPermissionsTable("geolocation-noprompt", Ci.nsIPrincipal.APP_STATUS_CERTIFIED));
// ... but does not interfere with geolocation's PROMPT value
do_check_true(scope.isExplicitInPermissionsTable("geolocation", Ci.nsIPrincipal.APP_STATUS_CERTIFIED));
}
function run_test() {
var scope = {};
Cu.import("resource://gre/modules/PermissionsTable.jsm", scope);
for (var i = 0; i < gData.length; i++) {
var perms = scope.expandPermissions(gData[i].permission,
gData[i].access);
do_check_set_eq(perms, gData[i].expected);
}
test_substitute_does_not_break_substituted(scope);
}

View File

@ -1,5 +0,0 @@
[DEFAULT]
head =
tail =
[test_bug808734.js]

View File

@ -16,7 +16,6 @@ this.EXPORTED_SYMBOLS = ["SettingsRequestManager"];
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsTable.jsm");
var DEBUG = false;
var VERBOSE = false;

View File

@ -167,7 +167,6 @@
"passwords.js": ["PasswordEngine", "LoginRec", "PasswordValidator"],
"passwords.jsm": ["Password", "DumpPasswords"],
"PdfJsNetwork.jsm": ["NetworkManager"],
"PermissionsTable.jsm": ["PermissionsTable", "PermissionsReverseTable", "expandPermissions", "appendAccessToPermName", "isExplicitInPermissionsTable", "AllPossiblePermissions"],
"PhoneNumberMetaData.jsm": ["PHONE_NUMBER_META_DATA"],
"PlacesUtils.jsm": ["PlacesUtils", "PlacesAggregatedTransaction", "PlacesCreateFolderTransaction", "PlacesCreateBookmarkTransaction", "PlacesCreateSeparatorTransaction", "PlacesCreateLivemarkTransaction", "PlacesMoveItemTransaction", "PlacesRemoveItemTransaction", "PlacesEditItemTitleTransaction", "PlacesEditBookmarkURITransaction", "PlacesSetItemAnnotationTransaction", "PlacesSetPageAnnotationTransaction", "PlacesEditBookmarkKeywordTransaction", "PlacesEditBookmarkPostDataTransaction", "PlacesEditItemDateAddedTransaction", "PlacesEditItemLastModifiedTransaction", "PlacesSortFolderByNameTransaction", "PlacesTagURITransaction", "PlacesUntagURITransaction"],
"PluginProvider.jsm": [],