diff -r 000000000000 -r 6474c204b198 dom/permission/PermissionPromptHelper.jsm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/permission/PermissionPromptHelper.jsm Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,146 @@ +/* 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/. */ + +/* PermissionPromptHelper checks the permissionDB for a given permission + * name and performs prompting if needed. + * Usage: send PermissionPromptHelper:AskPermission via the FrameMessageManager with: + * |origin|, |appID|, |browserFlag| -> used for getting the principal and + * |type| and |access| to call testExactPermissionFromPrincipal. + * Note that |access| isn't currently used. + * Other arugments are: + * requestID: ID that gets returned with the result message. + * + * Once the permission is checked, it returns with the message + * "PermissionPromptHelper:AskPermission:OK" + * The result contains the |result| e.g.Ci.nsIPermissionManager.ALLOW_ACTION + * and a requestID that + */ + +"use strict"; + +let DEBUG = 0; +let debug; +if (DEBUG) + debug = function (s) { dump("-*- Permission Prompt Helper component: " + s + "\n"); } +else + debug = function (s) {} + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; + +this.EXPORTED_SYMBOLS = ["PermissionPromptHelper"]; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "ppmm", + "@mozilla.org/parentprocessmessagemanager;1", + "nsIMessageListenerManager"); + +XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService", + "@mozilla.org/permission-prompt-service;1", + "nsIPermissionPromptService"); + +let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService); + +this.PermissionPromptHelper = { + init: function init() { + debug("Init"); + ppmm.addMessageListener("PermissionPromptHelper:AskPermission", this); + Services.obs.addObserver(this, "profile-before-change", false); + }, + + askPermission: function askPermission(aMessage, aCallbacks) { + let msg = aMessage.json; + + let access = msg.type; + if (msg.access) { + access = access + "-" + msg.access; + } + + let uri = Services.io.newURI(msg.origin, null, null); + let principal = + Services.scriptSecurityManager.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag); + + let permValue = + Services.perms.testExactPermissionFromPrincipal(principal, access); + + if (permValue == Ci.nsIPermissionManager.DENY_ACTION || + permValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) { + aCallbacks.cancel(); + return; + } + + if (permValue == Ci.nsIPermissionManager.PROMPT_ACTION) { + + // create the options from permission request. + let options = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + if (msg.options) { + for (let option of options) { + options.appendElement(option); + } + } + + // create an array with a nsIContentPermissionType element + let type = { + type: msg.type, + access: msg.access ? msg.access : "unused", + options: options, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]) + }; + let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + typeArray.appendElement(type, false); + + // create a nsIContentPermissionRequest + let request = { + types: typeArray, + principal: principal, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]), + allow: aCallbacks.allow, + cancel: aCallbacks.cancel, + window: Services.wm.getOuterWindowWithId(msg.windowID) + }; + + permissionPromptService.getPermission(request); + return; + } + + if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) { + aCallbacks.allow(); + return; + } + }, + + observe: function observe(aSubject, aTopic, aData) { + ppmm.removeMessageListener("PermissionPromptHelper:AskPermission", this); + Services.obs.removeObserver(this, "profile-before-change"); + ppmm = null; + }, + + receiveMessage: function receiveMessage(aMessage) { + debug("PermissionPromptHelper::receiveMessage " + aMessage.name); + let mm = aMessage.target; + let msg = aMessage.data; + + let result; + if (aMessage.name == "PermissionPromptHelper:AskPermission") { + this.askPermission(aMessage, { + cancel: function() { + mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", + { result: Ci.nsIPermissionManager.DENY_ACTION, + requestID: msg.requestID }); + }, + allow: function(aChoice) { + mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", + { result: Ci.nsIPermissionManager.ALLOW_ACTION, + choice: aChoice, + requestID: msg.requestID }); + } + }); + } + } +} + +PermissionPromptHelper.init();