# HG changeset patch # User Paul Theriault # Date 1355920950 -39600 # Node ID 9eeabc3a328d81ef0410dd01474103c83ccca4e3 # Parent 1b6ab3a080d81bb9519e09304abd0713489eebba Bug 815105: Suite 2 testing for webapi permissions testing diff --git a/dom/apps/tests/Makefile.in b/dom/apps/tests/Makefile.in --- a/dom/apps/tests/Makefile.in +++ b/dom/apps/tests/Makefile.in @@ -9,13 +9,24 @@ VPATH = @srcdir@ relativesrcdir = @relativesrcdir@ include $(DEPTH)/config/autoconf.mk DIRS = \ $(NULL) +_TEST_FILES = \ + permission_tests.js \ + permissions_table.js \ + shim_async.html \ + shim_blank.html \ + test_permissions.html \ + $(NULL) + MOCHITEST_CHROME_FILES = \ test_apps_service.xul \ $(NULL) +libs:: $(_TEST_FILES) + $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) + include $(topsrcdir)/config/rules.mk diff --git a/dom/apps/tests/permission_tests.js b/dom/apps/tests/permission_tests.js new file mode 100644 --- /dev/null +++ b/dom/apps/tests/permission_tests.js @@ -0,0 +1,733 @@ +/* +Permissions tests for verifying that a page actually has a permission by calls to the relevant API + +List of permissions originally came from AllPossiblePermissions variable in +https://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsInstaller.jsm + +Not all permissions are able to be tested, consuming code must check for existence +of a test (i.e. permissionsTests.hasOwnProperty(name) ) before attempting to call. + +Known permission name which are do not have tests yet are commented below. + +usage: permissionTests[permissionname].verify(successCallback, failCallback) +*/ + +// Use SpecialPowers for testing or Components.interfaces, until it is removed, then use fake object +if( typeof SpecialPowers == 'undefined') { + SpecialPowers = {} + if(Components && Components.interfaces) { + SpecialPowers.Ci = Components.interfaces + } else { + SpecialPowers.Ci = new Proxy(Object, handler) + } +} + + +//If we can't access Components.interfaces, we change the checks just to be instanceof Object. +var handler = { + get : function(target, name) { + return name in Object; + } +}; + +var permissionTests = { + 'alarms' : { + verify : function(success, fail) { + try { + if(window.navigator.mozAlarms instanceof SpecialPowers.Ci.nsIDOMMozAlarmsManager) { + success("navigator.mozAlarms is nsIDOMMozAlarmsManager"); + } else { + fail('navigator.mozAlarms is ' + navigator.mozAlarms); + } + } catch (e) { + fail(e.name); + } + } + }, + /* + 'attentionscreen': {}, // gaia permission to put content in attention screen window, not testable automatically? + 'background-sensors': {}, // allows page to listen to proximity events, probably not testable unless events can be faked. + 'backgroundservice': {}, gaiapermission to allow background service. Could install an app as a service maybe and see check to see if service is running... not sure how to do with mochitest. + * */ + 'bluetooth' : { + verify : function(success, fail) { + try { + if(window.navigator.mozBluetooth instanceof SpecialPowers.Ci.nsIDOMBluetoothManager) { + success("navigator.mozBluetooth is " + navigator.mozBluetooth); + } else { + fail("navigator.mozBluetooth is " + navigator.mozBluetooth); + } + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'browser' : { + verify : function(success, fail) { + + try { + var iframe = document.createElement('iframe'); + iframe.mozbrowser = true; + var element = document.body.appendChild(iframe); + iframe.src = 'data:text/html,' + 'testbrowserpermissionframe'; + var hasPermission = ( typeof iframe.getScreenshot) == 'function'; + document.body.removeChild(element); + if(hasPermission) { + success('iframe.getScreenshot is:' + (typeof iframe.getScreenshot)); + } else { + fail('iframe.getScreenshot is:' + (typeof iframe.getScreenshot)); + } + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'camera' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozCameras instanceof SpecialPowers.Ci.nsIDOMCameraManager) { + success("navigator.mozCameras is " + navigator.mozCameras); + } else { + fail("navigator.mozCameras is " + navigator.mozCameras); + } + } catch (e) { + fail("Error:" + e.name); + } + } + }, + /* + 'contacts' : { + permission doesnt do anything with access role. + }, + */ + 'contacts-create' : { + verify : function(success, fail) { + try { + + var properties1 = { + name : "Testname1", + familyName : ["TestFamilyName", "Wagner"], + givenName : ["Test1", "Test2"], + nickname : "nicktest", + tel : [{ + type : ["work"], + value : "123456", + carrier : "testCarrier" + }, { + type : ["home", "fax"], + value : "+9-876-5432" + }], + email : [{ + type : ["work"], + value : "x@y.com" + }] + }; + + var createResult1 = new mozContact(); + createResult1.init(properties1); + req = navigator.mozContacts.save(createResult1) + req.onsuccess = function(e) { + var remReq = navigator.mozContacts.remove(createResult1); + remReq.onsuccess = function() { + dump('cleaned up created contact') + }; + remReq.onsuccess = function() { + dump('cleaned up created contact') + }; + success("created contact"); + } + req.onerror = fail; + } catch (e) { + log('Contacts API Error:' + e.name); + fail(); + } + } + }, + 'contacts-read' : { + verify : function(success, fail) { + try { + req = navigator.mozContacts.find({}); + req.onsuccess = function(e) { + success('called navigator.mozContacts.find({})') + }; + req.onerror = function(e) { + fail('error calling navigator.mozContacts.find({}):' + e.target.error.name) + }; + ; + } catch (e) { + console.log('Contacts API Error:' + e); + fail("Error:" + e.name); + } + } + }, + /* // test broken, fails on creating contact. + 'contacts-write' : { + + verify : function(success, fail) { + try { + + var properties1 = { + name : "Testname2"+Math.random(), + familyName : ["TestFamilyName", "Wagner"], + givenName : ["Test1", "Test2"], + nickname : "nicktest", + tel : [{ + type : ["work"], + value : "123456", + carrier : "testCarrier" + }, { + type : ["home", "fax"], + value : "+9-876-5432" + }], + email : [{ + type : ["work"], + value : "x@y.com" + }] + }; + + var createResult1 = new mozContact(); + createResult1.init(properties1); + createReq = navigator.mozContacts.save(createResult1) + createReq.onsuccess = function(e) { + dump('created ' + createResult1.id) + createResult1.givenName = ["xxxx", "yyyy"]; + var saveReq = navigator.mozContacts.save(createResult1); + saveReq.onsuccess = function(e) { + //remove temp contact + dump('saved ' + success) + var remReq = navigator.mozContacts.remove(createResult1); + remReq.onsuccess = function() { + dump('cleaned up created contact') + }; + remReq.onerror = function() { + dump('failed to delete modified') + }; + success("modified contact"); + } + saveReq.onerror = function(e) { + dump('cant create ') + //remove temp contact + var remReq = navigator.mozContacts.remove(createResult1); + remReq.onsuccess = function() { + dump('cleaned up created contact') + }; + remReq.onerror = function(e) { + dump('Failed to delete modified'+e.name) + }; + fail("Failed to modify contact..."+e.name); + } + dump('after save;') + } + createReq.onerror = function() { + fail('Cant create contact to modify.') + } + } catch (e) { + fail('Error in contacts API test:' + error.name); + } + } + }, + + // this permission is a hack, and doesnt need a test. It wont be used by thirdparty apps. + deprecated-hwvideo + */ + /* can't detect succes in an automated fashion. + 'desktop-notification' : { + verify : function(success, fail) { + try { + var notify = window.navigator.mozNotification; + var notification = notify.createNotification("text", "desc"); + notification.show(); + fail('No way to test automatically, check the notification tray.') + } catch(e) { + fail('Error:' + error.name); + } + } + }, + */ + 'device-storage:apps' : { + verify : function(success, fail) { + + try { + req = navigator.getDeviceStorage('apps').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + } + }, + /* + device-storage:apps-create + */ + + 'device-storage:apps-read' : { + verify : function(success, fail) { + + try { + req = navigator.getDeviceStorage('apps').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e); + } + } + }, + /* + device-storage:apps-write + */ + 'device-storage:music' : { + verify : function(success, fail) { + + try { + req = navigator.getDeviceStorage('music').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e); + } + } + }, + /* + device-storage:music-create + */ + 'device-storage:music-read' : { + verify : function(success, fail) { + + try { + req = navigator.getDeviceStorage('music').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e); + } + } + }, + + /* + device-storage:music-write + */ + 'device-storage:pictures' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('pictures').enumerate(); + req.onsuccess = function(e){success("success calling getDeviceStorage('pictures').enumerate()")}; + req.onerror = function(e){fail(e.target.error.name)}; + } catch (e) { + fail("Error:" + e); + } + + } + }, + /* + device-storage:pictures-create + */ + 'device-storage:pictures-read' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('pictures').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + /* + device-storage:pictures-write + */ + 'device-storage:sdcard' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('sdcard').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + /* + device-storage:sdcard-create + */ + 'device-storage:sdcard-read' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('sdcard').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + } + }, + /* + device-storage:sdcard-write + */ + 'device-storage:videos-read' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('videos').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + /* + device-storage:videos-create + */ + 'device-storage:videos-read' : { + verify : function(success, fail) { + try { + req = navigator.getDeviceStorage('videos').enumerate(); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + + /* + device-storage:videos-write + */ + //not working yet + /* + 'embed-apps': { verify: function(success,fail) { + try { + var iframe = document.createElement('iframe'); + iframe.mozbrowser = true; + iframe.mozapp = 'http://clock.gaiamobile.org'; + var element = document.body.appendChild(iframe); + + var isMozBrowser = ( typeof iframe.getScreenshot) == 'function'; + if(!isMozBrowser) { + fail("App doesnt have mozbrowser permission, so can't embed apps"); + document.body.removeChild(element); + return; + } + // this is a hack: there must be a better way for child -> parent communication from an mozbrowser iframe + iframe.addEventListener('mozbrowsertitlechange', function(e) { + document.body.removeChild(element); + success("getSelf returns an app"); + }); + iframe.addEventListener('mozbrowsererror', function(e) { + document.body.removeChild(element); + fail(e.name); + }); + + var script = 'var request = window.navigator.mozApps.getSelf(); request.onsuccess=function(e){if(request.result){document.title=true} else {document.title=false}};request.onerror=function(e){new Error(123)};' + iframe.src = 'data:text/html,testbrowserpermissionframe'; + } catch (e) { + fail("Error:" + e.name); + } + } + */ + + 'fmradio' : { + verify : function(success, fail) { + try { + if(window.navigator.mozFMRadio instanceof SpecialPowers.Ci.nsIDOMFMRadio) { + success("navigator.mozFMRadio is nsIDOMFMRadio"); + } else { + fail("navigator.mozFMRadio is "+window.navigator.mozFMRadio); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + + 'geolocation' : { + verify : function(success, fail) { + try { + //note this test might not call either success() or fail() + window.gotGeo = false; + navigator.geolocation.getCurrentPosition(function(e) { + success("got " + e); + }, function(e) { + fail("Error:" + e); + }); + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + /* + idle + indexedDB-chrome-settings + indexedDB-chrome-settings-read + indexedDB-chrome-settings-write + indexedDB-unlimited + keyboard + */ + 'mobileconnection' : { + verify : function(success, fail) { + try { + if(window.navigator.mozMobileConnection instanceof SpecialPowers.Ci.nsIDOMMozMobileConnection) { + success(); + } else { + fail(); + } + } catch (e) { + fail("Error:" + e.name); + } + } + }, + /* + 'network-events' : { + verify : function(success, fail) { + var element; + try { + + //we just test one since this is enough to prove the permission is present + addEventListener('moznetworkupload', function(e){ + document.body.removeChild(Error.target) + success('caught moznetworkupload event'+e.name) + }); + const TEST_URL = "http://www.mozilla.org"; + var iframe = document.createElement('iframe'); + iframe.src = TEST_URL + element = document.body.appendChild(iframe); + + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + */ + 'networkstats-manage' : { + verify : function(success, fail) { + + try { + var sr=window.navigator.mozNetworkStats.sampleRate; + success("window.navigator.mozNetworkStats.sampleRate:"+sr); + + } catch (e) { + fail("Caught error:" + e); + } + + } + }, + /* + offline-app + */ + 'permissions' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozPermissionSettings !=null) { + success("mozPermissionSettings is not null "); + } else { + fail("navigator.mozPermissionSettings is:" + navigator.mozPermissionSettings); + } + } catch (e) { + fail("Error:" + e); + } + + } + }, + /* + pin-app + */ + 'power' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozPower instanceof SpecialPowers.Ci.nsIDOMMozPowerManager) { + success("mozPower is a nsIDOMMozPowerManager"); + } else { + fail("mozPower is " + window.navigator.mozPower); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + /* + push //afaict this is never used + resource-lock //afaict this is never used + */ + 'settings' : { + verify : function(success, fail) { + try { + var lock = navigator.mozSettings.createLock(); + req = lock.get('screen.automatic-brightness'); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'settings-read' : { + verify : function(success, fail) { + try { + var lock = navigator.mozSettings.createLock(); + req = lock.get('screen.automatic-brightness'); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'settings-write' : { + verify : function(success, fail) { + try { + var lock = navigator.mozSettings.createLock(); + req = lock.set({ + 'screen.automatic-brightness' : 1.0 + }); + req.onsuccess = success; + req.onerror = fail; + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'sms' : { + verify : function(success, fail) { + try { + if(window.navigator.mozSms instanceof SpecialPowers.Ci.nsIDOMMozSmsManager) { + success(); + } else { + fail(); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + //todo make the URL not hardcoded in the test. + 'systemXHR' : { + verify : function(success, fail) { + // This URL needs to be a file which is not same origin with page running the tests. + const TEST_URL = "http://example.org/tests/content/base/test/test_XHR_system.html"; + + var xhr = new XMLHttpRequest({ + mozSystem : true + }); + + xhr.open("GET", TEST_URL); + xhr.onload = function onload() { + if(xhr.status == 200) + success('made cross-domain XHR request'); + else + fail('XHR request returned something other than 200') + }; + xhr.onerror = function onerror() { + fail('couldnt make cross-domain XHR request'); + } + xhr.send(); + + } + }, + 'tcp-socket' : { + verify : function(success, fail) { + + try { + var sock = navigator.mozTCPSocket.open('www.mozilla.org', 80); + sock.onopen = function(e) { + success('connected to port 80') + } + sock.onclose = function(e) { + fail('port was closed, but open was attempted') + } + sock.onerror = function(e) { + fail('error occured opening socket' + e.name) + } + } catch (e) { + fail("Error occured:" + e.name); + } + + } + }, + 'telephony' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozTelephony instanceof SpecialPowers.Ci.nsIDOMTelephony) { + success(window.navigator.mozTelephony); + } else { + fail(window.navigator.mozTelephony); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + 'time' : { + verify : function(success, fail) { + try { + if(window.navigator.mozTime instanceof SpecialPowers.Ci.nsIDOMMozTimeManager) { + success("navigator.mozTime is nsIDOMMozTimeManager"); + } else { + fail("navigator.mozTime is:"+window.navigator.mozTime); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + }, + 'voicemail' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozVoicemail instanceof SpecialPowers.Ci.nsIDOMMozVoicemail) { + success(); + } else { + fail(); + } + } catch (e) { + fail("Error:" + e.name); + } + } + }, + 'webapps-manage' : { + verify : function(success, fail) { + + try { + req = navigator.mozApps.mgmt.getAll(); + req.onsuccess = function() { + success('called mozApps.mgmt.getAll') + }; + req.onerror = function() { + fail('error calling mozApps.mgmt.getAll') + }; + } catch (e) { + console.log('WebApps manage API Error:' + e); + fail(); + } + + } + }, + 'wifi-manage' : { + verify : function(success, fail) { + + try { + if(window.navigator.mozWifiManager instanceof SpecialPowers.Ci.nsIDOMMozWifiManager) { + success(); + } else { + fail(); + } + } catch (e) { + fail("Error:" + e.name); + } + + } + } +}; diff --git a/dom/apps/tests/permissions_table.js b/dom/apps/tests/permissions_table.js new file mode 100644 --- /dev/null +++ b/dom/apps/tests/permissions_table.js @@ -0,0 +1,242 @@ +const UNKNOWN_ACTION = 0; +// Ci.nsIPermissionManager.UNKNOWN_ACTION; +const ALLOW_ACTION = 1; +//Ci.nsIPermissionManager.ALLOW_ACTION; +const DENY_ACTION = 2; +// Ci.nsIPermissionManager.DENY_ACTION; +const PROMPT_ACTION = 3; +//Ci.nsIPermissionManager.PROMPT_ACTION; +// Permission access flags +const READONLY = "readonly"; +const CREATEONLY = "createonly"; +const READCREATE = "readcreate"; +const READWRITE = "readwrite"; + + +//table which shows which permissions are allowed at each level +var PermissionsTable = { + "geolocation": { + app: PROMPT_ACTION, + privileged: PROMPT_ACTION, + certified: ALLOW_ACTION + }, + "camera": { + app: DENY_ACTION, + privileged: DENY_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 + }, + "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: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 + }, + telephony: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + browser: { + app: DENY_ACTION, + privileged: ALLOW_ACTION, + certified: ALLOW_ACTION + }, + bluetooth: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + mobileconnection: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + power: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + settings: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION, + access: ["read", "write"], + additional: ["indexedDB-chrome-settings"] + }, + permissions: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + fmradio: { + app: ALLOW_ACTION, + privileged: ALLOW_ACTION, + certified: ALLOW_ACTION + }, + attention: { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "webapps-manage": { + app: DENY_ACTION, + privileged: DENY_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 + }, + "voicemail": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "deprecated-hwvideo": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "idle": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "time": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "embed-apps": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "storage": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION, + substitute: ["indexedDB-unlimited", "offline-app", "pin-app"] + }, + "background-sensors": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + cellbroadcast: { + 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-telephony": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "audio-channel-ringer": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "audio-channel-publicnotification": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, + "open-remote-window": { + app: DENY_ACTION, + privileged: DENY_ACTION, + certified: ALLOW_ACTION + }, +}; diff --git a/dom/apps/tests/shim_async.html b/dom/apps/tests/shim_async.html new file mode 100644 --- /dev/null +++ b/dom/apps/tests/shim_async.html @@ -0,0 +1,50 @@ + + + + + + Test for Bug + + + +Mozilla Bug +

+ +
+
+
+ + diff --git a/dom/apps/tests/shim_blank.html b/dom/apps/tests/shim_blank.html new file mode 100644 --- /dev/null +++ b/dom/apps/tests/shim_blank.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dom/apps/tests/test_permissions.html b/dom/apps/tests/test_permissions.html new file mode 100644 --- /dev/null +++ b/dom/apps/tests/test_permissions.html @@ -0,0 +1,153 @@ + + + + + + Test for Bug 815105 + + + + + + + Mozilla Bug 815105 +

+ +
+
+
+ +
+