1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/permission/PermissionPromptHelper.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* PermissionPromptHelper checks the permissionDB for a given permission 1.9 + * name and performs prompting if needed. 1.10 + * Usage: send PermissionPromptHelper:AskPermission via the FrameMessageManager with: 1.11 + * |origin|, |appID|, |browserFlag| -> used for getting the principal and 1.12 + * |type| and |access| to call testExactPermissionFromPrincipal. 1.13 + * Note that |access| isn't currently used. 1.14 + * Other arugments are: 1.15 + * requestID: ID that gets returned with the result message. 1.16 + * 1.17 + * Once the permission is checked, it returns with the message 1.18 + * "PermissionPromptHelper:AskPermission:OK" 1.19 + * The result contains the |result| e.g.Ci.nsIPermissionManager.ALLOW_ACTION 1.20 + * and a requestID that 1.21 + */ 1.22 + 1.23 +"use strict"; 1.24 + 1.25 +let DEBUG = 0; 1.26 +let debug; 1.27 +if (DEBUG) 1.28 + debug = function (s) { dump("-*- Permission Prompt Helper component: " + s + "\n"); } 1.29 +else 1.30 + debug = function (s) {} 1.31 + 1.32 +const Cu = Components.utils; 1.33 +const Cc = Components.classes; 1.34 +const Ci = Components.interfaces; 1.35 + 1.36 +this.EXPORTED_SYMBOLS = ["PermissionPromptHelper"]; 1.37 + 1.38 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.39 +Cu.import("resource://gre/modules/Services.jsm"); 1.40 + 1.41 +XPCOMUtils.defineLazyServiceGetter(this, "ppmm", 1.42 + "@mozilla.org/parentprocessmessagemanager;1", 1.43 + "nsIMessageListenerManager"); 1.44 + 1.45 +XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService", 1.46 + "@mozilla.org/permission-prompt-service;1", 1.47 + "nsIPermissionPromptService"); 1.48 + 1.49 +let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService); 1.50 + 1.51 +this.PermissionPromptHelper = { 1.52 + init: function init() { 1.53 + debug("Init"); 1.54 + ppmm.addMessageListener("PermissionPromptHelper:AskPermission", this); 1.55 + Services.obs.addObserver(this, "profile-before-change", false); 1.56 + }, 1.57 + 1.58 + askPermission: function askPermission(aMessage, aCallbacks) { 1.59 + let msg = aMessage.json; 1.60 + 1.61 + let access = msg.type; 1.62 + if (msg.access) { 1.63 + access = access + "-" + msg.access; 1.64 + } 1.65 + 1.66 + let uri = Services.io.newURI(msg.origin, null, null); 1.67 + let principal = 1.68 + Services.scriptSecurityManager.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag); 1.69 + 1.70 + let permValue = 1.71 + Services.perms.testExactPermissionFromPrincipal(principal, access); 1.72 + 1.73 + if (permValue == Ci.nsIPermissionManager.DENY_ACTION || 1.74 + permValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) { 1.75 + aCallbacks.cancel(); 1.76 + return; 1.77 + } 1.78 + 1.79 + if (permValue == Ci.nsIPermissionManager.PROMPT_ACTION) { 1.80 + 1.81 + // create the options from permission request. 1.82 + let options = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); 1.83 + if (msg.options) { 1.84 + for (let option of options) { 1.85 + options.appendElement(option); 1.86 + } 1.87 + } 1.88 + 1.89 + // create an array with a nsIContentPermissionType element 1.90 + let type = { 1.91 + type: msg.type, 1.92 + access: msg.access ? msg.access : "unused", 1.93 + options: options, 1.94 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]) 1.95 + }; 1.96 + let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); 1.97 + typeArray.appendElement(type, false); 1.98 + 1.99 + // create a nsIContentPermissionRequest 1.100 + let request = { 1.101 + types: typeArray, 1.102 + principal: principal, 1.103 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]), 1.104 + allow: aCallbacks.allow, 1.105 + cancel: aCallbacks.cancel, 1.106 + window: Services.wm.getOuterWindowWithId(msg.windowID) 1.107 + }; 1.108 + 1.109 + permissionPromptService.getPermission(request); 1.110 + return; 1.111 + } 1.112 + 1.113 + if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) { 1.114 + aCallbacks.allow(); 1.115 + return; 1.116 + } 1.117 + }, 1.118 + 1.119 + observe: function observe(aSubject, aTopic, aData) { 1.120 + ppmm.removeMessageListener("PermissionPromptHelper:AskPermission", this); 1.121 + Services.obs.removeObserver(this, "profile-before-change"); 1.122 + ppmm = null; 1.123 + }, 1.124 + 1.125 + receiveMessage: function receiveMessage(aMessage) { 1.126 + debug("PermissionPromptHelper::receiveMessage " + aMessage.name); 1.127 + let mm = aMessage.target; 1.128 + let msg = aMessage.data; 1.129 + 1.130 + let result; 1.131 + if (aMessage.name == "PermissionPromptHelper:AskPermission") { 1.132 + this.askPermission(aMessage, { 1.133 + cancel: function() { 1.134 + mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", 1.135 + { result: Ci.nsIPermissionManager.DENY_ACTION, 1.136 + requestID: msg.requestID }); 1.137 + }, 1.138 + allow: function(aChoice) { 1.139 + mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", 1.140 + { result: Ci.nsIPermissionManager.ALLOW_ACTION, 1.141 + choice: aChoice, 1.142 + requestID: msg.requestID }); 1.143 + } 1.144 + }); 1.145 + } 1.146 + } 1.147 +} 1.148 + 1.149 +PermissionPromptHelper.init();