1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/components/ContentPermissionPrompt.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,120 @@ 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 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Ci = Components.interfaces; 1.9 +const Cr = Components.results; 1.10 +const Cu = Components.utils; 1.11 +const Cc = Components.classes; 1.12 + 1.13 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.14 +Cu.import("resource://gre/modules/Services.jsm"); 1.15 + 1.16 +const kEntities = { "geolocation": "geolocation", 1.17 + "desktop-notification": "desktopNotification", 1.18 + "contacts": "contacts" }; 1.19 + 1.20 +function ContentPermissionPrompt() {} 1.21 + 1.22 +ContentPermissionPrompt.prototype = { 1.23 + classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"), 1.24 + 1.25 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]), 1.26 + 1.27 + handleExistingPermission: function handleExistingPermission(request, type, isApp) { 1.28 + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, type); 1.29 + if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { 1.30 + request.allow(); 1.31 + return true; 1.32 + } 1.33 + if (result == Ci.nsIPermissionManager.DENY_ACTION) { 1.34 + request.cancel(); 1.35 + return true; 1.36 + } 1.37 + 1.38 + if (isApp && (result == Ci.nsIPermissionManager.UNKNOWN_ACTION && !!kEntities[type])) { 1.39 + request.cancel(); 1.40 + return true; 1.41 + } 1.42 + 1.43 + return false; 1.44 + }, 1.45 + 1.46 + getChromeWindow: function getChromeWindow(aWindow) { 1.47 + let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) 1.48 + .getInterface(Ci.nsIWebNavigation) 1.49 + .QueryInterface(Ci.nsIDocShellTreeItem) 1.50 + .rootTreeItem 1.51 + .QueryInterface(Ci.nsIInterfaceRequestor) 1.52 + .getInterface(Ci.nsIDOMWindow) 1.53 + .QueryInterface(Ci.nsIDOMChromeWindow); 1.54 + return chromeWin; 1.55 + }, 1.56 + 1.57 + getChromeForRequest: function getChromeForRequest(request) { 1.58 + if (request.window) { 1.59 + let requestingWindow = request.window.top; 1.60 + return this.getChromeWindow(requestingWindow).wrappedJSObject; 1.61 + } 1.62 + return request.element.ownerDocument.defaultView; 1.63 + }, 1.64 + 1.65 + prompt: function(request) { 1.66 + let isApp = request.principal.appId !== Ci.nsIScriptSecurityManager.NO_APP_ID && request.principal.appId !== Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID; 1.67 + 1.68 + // Only allow exactly one permission rquest here. 1.69 + let types = request.types.QueryInterface(Ci.nsIArray); 1.70 + if (types.length != 1) { 1.71 + request.cancel(); 1.72 + return; 1.73 + } 1.74 + let perm = types.queryElementAt(0, Ci.nsIContentPermissionType); 1.75 + 1.76 + // Returns true if the request was handled 1.77 + if (this.handleExistingPermission(request, perm.type, isApp)) 1.78 + return; 1.79 + 1.80 + let chromeWin = this.getChromeForRequest(request); 1.81 + let tab = chromeWin.BrowserApp.getTabForWindow(request.window.top); 1.82 + if (!tab) 1.83 + return; 1.84 + 1.85 + let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); 1.86 + let entityName = kEntities[perm.type]; 1.87 + 1.88 + let buttons = [{ 1.89 + label: browserBundle.GetStringFromName(entityName + ".allow"), 1.90 + callback: function(aChecked) { 1.91 + // If the user checked "Don't ask again", make a permanent exception 1.92 + if (aChecked) { 1.93 + Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.ALLOW_ACTION); 1.94 + } else if (isApp || entityName == "desktopNotification") { 1.95 + // Otherwise allow the permission for the current session (if the request comes from an app or if it's a desktop-notification request) 1.96 + Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.ALLOW_ACTION, Ci.nsIPermissionManager.EXPIRE_SESSION); 1.97 + } 1.98 + 1.99 + request.allow(); 1.100 + } 1.101 + }, 1.102 + { 1.103 + label: browserBundle.GetStringFromName(entityName + ".dontAllow"), 1.104 + callback: function(aChecked) { 1.105 + // If the user checked "Don't ask again", make a permanent exception 1.106 + if (aChecked) 1.107 + Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.DENY_ACTION); 1.108 + 1.109 + request.cancel(); 1.110 + } 1.111 + }]; 1.112 + 1.113 + let requestor = chromeWin.BrowserApp.manifest ? "'" + chromeWin.BrowserApp.manifest.name + "'" : request.principal.URI.host; 1.114 + let message = browserBundle.formatStringFromName(entityName + ".ask", [requestor], 1); 1.115 + let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") }; 1.116 + 1.117 + chromeWin.NativeWindow.doorhanger.show(message, entityName + request.principal.URI.host, buttons, tab.id, options); 1.118 + } 1.119 +}; 1.120 + 1.121 + 1.122 +//module initialization 1.123 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);