Bug 1141415 - add expire setting of permission to SpecialPowers. r=jmaher
authorchunminchang <cchang@mozilla.com>
Fri, 12 Jun 2015 18:01:00 +0200
changeset 248861 cc4bddc9546269d947ab1d30f17dbc1fec626788
parent 248860 d95c168ab22b350c6001d891fb732a3521b532a6
child 248862 85383f7a9d53782cbb06b013cad784421112e362
push id28909
push userryanvm@gmail.com
push dateMon, 15 Jun 2015 19:55:33 +0000
treeherdermozilla-central@cd0d976e5f5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1141415
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1141415 - add expire setting of permission to SpecialPowers. r=jmaher
testing/mochitest/tests/Harness_sanity/mochitest.ini
testing/mochitest/tests/Harness_sanity/specialPowers_framescript.js
testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushPermissions.html
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowersAPI.js
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -7,16 +7,18 @@ skip-if = true #depends on fix for bug 1
 [test_sanityException2.html]
 [test_sanityParams.html]
 [test_sanityWindowSnapshot.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
 support-files = file_SpecialPowersFrame1.html
 [test_SpecialPowersPushPermissions.html]
+support-files =
+    specialPowers_framescript.js
 [test_SpecialPowersPushAppPermissions.html]
 support-files =
     file_app.sjs
     file_app.template.webapp
     app.html
 [test_SpecialPowersPushPrefEnv.html]
 [test_SimpletestGetTestFileURL.html]
 [test_SpecialPowersLoadChromeScript.html]
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/Harness_sanity/specialPowers_framescript.js
@@ -0,0 +1,13 @@
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var permChangedObs = {
+  observe: function(subject, topic, data) {
+    if (topic == 'perm-changed') {
+      var permission = subject.QueryInterface(Components.interfaces.nsIPermission);
+      var msg = { op: data, type: permission.type };
+      sendAsyncMessage('perm-changed', msg);
+    }
+  }
+};
+
+Services.obs.addObserver(permChangedObs, 'perm-changed', false);
--- a/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushPermissions.html
+++ b/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushPermissions.html
@@ -12,16 +12,27 @@
 const ALLOW_ACTION = SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION;
 const DENY_ACTION = SpecialPowers.Ci.nsIPermissionManager.DENY_ACTION;
 const UNKNOWN_ACTION = SpecialPowers.Ci.nsIPermissionManager.UNKNOWN_ACTION;
 const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
 const ACCESS_SESSION = SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION;
 const ACCESS_ALLOW_FIRST_PARTY_ONLY = SpecialPowers.Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY;
 const ACCESS_LIMIT_THIRD_PARTY = SpecialPowers.Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY;
 
+const EXPIRE_TIME = SpecialPowers.Ci.nsIPermissionManager.EXPIRE_TIME;
+var start;
+const DELAY = 500;
+// PR_Now() that called in nsPermissionManager to get the system time and
+// Date.now() are out of sync on win32 platform(XP/win7). The PR_Now() is
+// 15~20ms less than Date.now(). Unfortunately, this time skew can't be
+// avoided, so it needs to add a time buffer to compensate.
+const TIME_SKEW = 100;
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('specialPowers_framescript.js'));
+SimpleTest.requestFlakyTimeout("untriaged");
+
 function starttest(){
   SpecialPowers.addPermission("pPROMPT", PROMPT_ACTION, document);
   SpecialPowers.addPermission("pALLOW", ALLOW_ACTION, document);
   SpecialPowers.addPermission("pDENY", DENY_ACTION, document);
   SpecialPowers.addPermission("pREMOVE", ALLOW_ACTION, document);
   SpecialPowers.addPermission("pSESSION", ACCESS_SESSION, document);
   SpecialPowers.addPermission("pFIRSTPARTY", ACCESS_ALLOW_FIRST_PARTY_ONLY, document);
   SpecialPowers.addPermission("pTHIRDPARTY", ACCESS_LIMIT_THIRD_PARTY, document);
@@ -131,16 +142,77 @@ function test6() {
     setTimeout(test6, 0);
   } else if (!SpecialPowers.testPermission('pFIRSTPARTY', UNKNOWN_ACTION, document)) {
     dump('/**** pFIRSTPARTY still set ****/\n');
     setTimeout(test6, 0);
   } else if (!SpecialPowers.testPermission('pTHIRDPARTY', UNKNOWN_ACTION, document)) {
     dump('/**** pTHIRDPARTY still set ****/\n');
     setTimeout(test6, 0);
   } else {
-    SimpleTest.finish();
+    test7();
   }
 }
+
+function test7() {
+  afterPermissionChanged('pEXPIRE', 'deleted', test8);
+  afterPermissionChanged('pEXPIRE', 'added', permissionPollingCheck);
+  start = Number(Date.now());
+  SpecialPowers.addPermission('pEXPIRE', true, document, EXPIRE_TIME, start + DELAY);
+}
+
+function test8() {
+  afterPermissionChanged('pEXPIRE', 'deleted', SimpleTest.finish);
+  afterPermissionChanged('pEXPIRE', 'added', permissionPollingCheck);
+  start = Number(Date.now());
+  SpecialPowers.pushPermissions([
+    { 'type': 'pEXPIRE',
+      'allow': true,
+      'expireType': EXPIRE_TIME,
+      'expireTime': start + DELAY,
+      'context': document
+    }], function() {
+      info("Wait permission changed signal!");
+    }
+  );
+}
+
+function afterPermissionChanged(type, op, callback) {
+  // handle the message from specialPowers_framescript.js
+  gScript.addMessageListener('perm-changed', function onChange(msg) {
+    if (msg.type == type && msg.op == op) {
+      gScript.removeMessageListener('perm-changed', onChange);
+      callback();
+    }
+  });
+}
+
+function permissionPollingCheck() {
+  var now = Number(Date.now());
+  if (now < start + DELAY) {
+    ok(SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document),
+       'unexpired permission is still there!');
+    setTimeout(permissionPollingCheck, DELAY);
+    return;
+  }
+
+  if (SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document) &&
+      (now < start + DELAY + TIME_SKEW) &&
+      isWin32()) {
+    setTimeout(permissionPollingCheck, DELAY);
+    return;
+  }
+
+  // The permission is already expired!
+  ok(!SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document),
+     'expired permission should be removed!');
+}
+
+function isWin32() {
+  var version = SpecialPowers.Services.sysinfo.getProperty('version');
+  version = parseFloat(version);
+  // version 5.1 is win XP, 6.1 is win7
+  return (navigator.platform.indexOf('Win') == 0) && (version <= 6.1);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -313,17 +313,17 @@ SpecialPowersObserverAPI.prototype = {
       case "SPPermissionManager": {
         let msg = aMessage.json;
 
         let secMan = Services.scriptSecurityManager;
         let principal = secMan.getAppCodebasePrincipal(this._getURI(msg.url), msg.appId, msg.isInBrowserElement);
 
         switch (msg.op) {
           case "add":
-            Services.perms.addFromPrincipal(principal, msg.type, msg.permission);
+            Services.perms.addFromPrincipal(principal, msg.type, msg.permission, msg.expireType, msg.expireTime);
             break;
           case "remove":
             Services.perms.removeFromPrincipal(principal, msg.type);
             break;
           case "has":
             let hasPerm = Services.perms.testPermissionFromPrincipal(principal, msg.type);
             if (hasPerm == Ci.nsIPermissionManager.ALLOW_ACTION) 
               return true;
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -801,24 +801,36 @@ SpecialPowersAPI.prototype = {
 
         if (permission.remove == true)
           perm = Ci.nsIPermissionManager.UNKNOWN_ACTION;
 
         if (originalValue == perm) {
           continue;
         }
 
-        var todo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
+        var todo = {'op': 'add',
+                    'type': permission.type,
+                    'permission': perm,
+                    'value': perm,
+                    'url': url,
+                    'appId': appId,
+                    'isInBrowserElement': isInBrowserElement,
+                    'expireType': (typeof permission.expireType === "number") ?
+                      permission.expireType : 0, // default: EXPIRE_NEVER
+                    'expireTime': (typeof permission.expireTime === "number") ?
+                      permission.expireTime : 0};
+
+        var cleanupTodo = Object.assign({}, todo);
+
         if (permission.remove == true)
           todo.op = 'remove';
 
         pendingPermissions.push(todo);
 
         /* Push original permissions value or clear into cleanup array */
-        var cleanupTodo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
         if (originalValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
           cleanupTodo.op = 'remove';
         } else {
           cleanupTodo.value = originalValue;
           cleanupTodo.permission = originalValue;
         }
         cleanupPermissions.push(cleanupTodo);
     }
@@ -1861,17 +1873,17 @@ SpecialPowersAPI.prototype = {
       url = arg.url;
       appId = arg.appId;
       isInBrowserElement = arg.isInBrowserElement;
     }
 
     return [ url, appId, isInBrowserElement, isSystem ];
   },
 
-  addPermission: function(type, allow, arg) {
+  addPermission: function(type, allow, arg, expireType, expireTime) {
     let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return; // nothing to do
     }
 
     let permission;
     if (typeof allow !== 'boolean') {
       permission = allow;
@@ -1881,17 +1893,19 @@ SpecialPowersAPI.prototype = {
     }
 
     var msg = {
       'op': 'add',
       'type': type,
       'permission': permission,
       'url': url,
       'appId': appId,
-      'isInBrowserElement': isInBrowserElement
+      'isInBrowserElement': isInBrowserElement,
+      'expireType': (typeof expireType === "number") ? expireType : 0,
+      'expireTime': (typeof expireTime === "number") ? expireTime : 0
     };
 
     this._sendSyncMessage('SPPermissionManager', msg);
   },
 
   removePermission: function(type, arg) {
     let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {