Backout e54c3b878993
authorYoshi Huang <allstars.chh@mozilla.com>
Tue, 27 Oct 2015 15:49:11 +0800
changeset 304930 afa51178a780763be38c80564ed234fb05a42075
parent 304929 525116f5e83caefcd54f5c6e715b9be4a37b121d
child 304931 4c230018cccc3ddd942fecf1fcf7b79414a52ba8
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone44.0a1
backs oute54c3b87899304ef17ed9a18c39c7b4a8b2ea8a7
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
Backout e54c3b878993
dom/apps/tests/test_third_party_homescreen.html
dom/base/test/test_messagemanager_assertpermission.html
dom/base/test/test_messagemanager_targetchain.html
dom/browser-element/mochitest/browserElement_AllowEmbedAppsInNestedOOIframe.js
dom/browser-element/mochitest/browserElement_CopyPaste.js
dom/browser-element/mochitest/browserElement_DisallowEmbedAppsInOOP.js
dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html
dom/browser-element/mochitest/priority/test_NestedFrames.html
dom/cache/test/mochitest/driver.js
dom/cache/test/mochitest/test_cache_orphaned_body.html
dom/cache/test/mochitest/test_cache_orphaned_cache.html
dom/cache/test/mochitest/test_cache_restart.html
dom/cache/test/mochitest/test_cache_shrink.html
dom/indexedDB/test/file.js
dom/indexedDB/test/helpers.js
dom/indexedDB/test/webapp_clearBrowserData.js
dom/inputmethod/mochitest/test_bug1043828.html
dom/inputmethod/mochitest/test_bug944397.html
dom/inputmethod/mochitest/test_focus_blur_manage_events.html
dom/inputmethod/mochitest/test_input_registry_events.html
dom/inputmethod/mochitest/test_simple_manage_events.html
dom/ipc/tests/test_permission_for_nested_oop_app.html
dom/ipc/tests/test_permission_for_two_oop_apps.html
dom/ipc/tests/test_permission_helper.js
dom/ipc/tests/test_permission_when_oop_app_crashes.html
dom/tv/test/mochitest/head.js
testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushAppPermissions.html
testing/mochitest/tests/Harness_sanity/test_bug816847.html
testing/specialpowers/components/SpecialPowersObserver.js
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowersAPI.js
--- a/dom/apps/tests/test_third_party_homescreen.html
+++ b/dom/apps/tests/test_third_party_homescreen.html
@@ -159,17 +159,17 @@ function runTest() {
   request.onerror = cbError;
   request.onsuccess = continueTest;
   yield undefined;
 
   var app = request.result;
   ok(app, "App is non-null");
   is(app.manifestURL, gManifestURL, "App manifest url is correct.");
 
-  var context = {"manifestURL": app.manifestURL};
+  var context = {"manifestURL": app.manifestURL, "isInBrowserElement": false};
 
   SpecialPowers.pushPermissions([{"type": "homescreen-webapps-manage",
                                   "allow": 1,
                                   "context": context}], continueTest);
   yield undefined;
 
   // Launch the app.
   info("Running " + app.manifestURL);
--- a/dom/base/test/test_messagemanager_assertpermission.html
+++ b/dom/base/test/test_messagemanager_assertpermission.html
@@ -27,18 +27,18 @@ let gAppsService = SpecialPowers.Cc["@mo
                      .getService(SpecialPowers.Ci.nsIAppsService);
 
 function setUp() {
   SpecialPowers.addPermission("browser", true, window.document);
   SpecialPowers.addPermission("embed-apps", true, window.document);
 
   let appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
   SpecialPowers.addPermission("foobar", true, { url: APP_URL,
-                                                originAttributes: { appId: appId }
-                                              });
+                                                appId: appId,
+                                                isInBrowserElement: false });
   SpecialPowers.pushPrefEnv({"set":[['dom.mozBrowserFramesEnabled', true],
                                     ['dom.ipc.browser_frames.oop_by_default', true]]}, runNextTest);
 }
 
 /**
  * Load the example.org app in an <iframe mozbrowser mozapp>
  */
 function loadApp(callback) {
--- a/dom/base/test/test_messagemanager_targetchain.html
+++ b/dom/base/test/test_messagemanager_targetchain.html
@@ -99,23 +99,21 @@
       }, true);
       document.body.appendChild(iframe);
     }
 
     addEventListener("load", function() {
       var principal = SpecialPowers.wrap(document).nodePrincipal;
       SpecialPowers.pushPermissions([
         { "type": "browser", "allow": 1, "context": { "url": principal.URI.spec,
-                                                      "originAttributes": {
-                                                        "appId": principal.appId
-                                                      }}},
+                                                      "appId": principal.appId,
+                                                      "isInBrowserElement": false }},
         { "type": "browser", "allow": 1, "context": { "url": principal.URI.spec,
-                                                      "originAttributes": {
-                                                        "appId": principal.appId,
-                                                        "inBrowser": true }}}
+                                                      "appId": principal.appId,
+                                                      "isInBrowserElement": true }}
       ], () => {
         SpecialPowers.pushPrefEnv({
           "set": [
             ["dom.mozBrowserFramesEnabled", true],
             ["dom.ipc.browser_frames.oop_by_default", false],
           ]
         }, runTests);
       });
--- a/dom/browser-element/mochitest/browserElement_AllowEmbedAppsInNestedOOIframe.js
+++ b/dom/browser-element/mochitest/browserElement_AllowEmbedAppsInNestedOOIframe.js
@@ -18,17 +18,18 @@ function runTest() {
   iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
     is(e.detail.message == 'app', true, e.detail.message);
     SimpleTest.finish();
   });
 
   document.body.appendChild(iframe);
 
   var context = { 'url': 'http://example.org',
-                  'originAttributes': {'inBrowser': true} };
+                  'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+                  'isInBrowserElement': true };
   SpecialPowers.pushPermissions([
     {'type': 'browser', 'allow': 1, 'context': context},
     {'type': 'embed-apps', 'allow': 1, 'context': context}
   ], function() {
     iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AllowEmbedAppsInNestedOOIframe.html';
   });
 }
 
--- a/dom/browser-element/mochitest/browserElement_CopyPaste.js
+++ b/dom/browser-element/mochitest/browserElement_CopyPaste.js
@@ -339,18 +339,17 @@ function testCut2(e) {
   });
 
   mm.loadFrameScript(getScriptForGetContent(), false);
 }
 
 // Give our origin permission to open browsers, and remove it when the test is complete.
 var principal = SpecialPowers.wrap(document).nodePrincipal;
 var context = { 'url': SpecialPowers.wrap(principal.URI).spec,
-                'originAttributes': {
-                   'appId': principal.appId,
-                   'inBrowser': true }};
+                'appId': principal.appId,
+                'isInBrowserElement': true };
 
 addEventListener('testready', function() {
   SpecialPowers.pushPermissions([
     {'type': 'browser', 'allow': 1, 'context': context}
   ], runTest);
 });
 
--- a/dom/browser-element/mochitest/browserElement_DisallowEmbedAppsInOOP.js
+++ b/dom/browser-element/mochitest/browserElement_DisallowEmbedAppsInOOP.js
@@ -23,18 +23,19 @@ function runTest() {
 
   iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
     is(e.detail.message == 'app', canEmbedApp, e.detail.message);
     SimpleTest.finish();
   });
 
   document.body.appendChild(iframe);
 
-  var context = {'url': 'http://example.org',
-                 'originAttributes': {'inBrowser': true}};
+  var context = { 'url': 'http://example.org',
+                  'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+                  'isInBrowserElement': true };
   SpecialPowers.pushPermissions([
     {'type': 'browser', 'allow': 1, 'context': context},
     {'type': 'embed-apps', 'allow': 1, 'context': context}
   ], function() {
     iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_DisallowEmbedAppsInOOP.html';
   });
 }
 
--- a/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
+++ b/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
@@ -31,17 +31,18 @@ function runTest() {
   let imeUrl = location.protocol + '//' + location.host +
                path.substring(0, path.lastIndexOf('/')) +
                '/file_inputmethod.html';
   SpecialPowers.pushPermissions([{
     type: 'input',
     allow: true,
     context: {
       url: imeUrl,
-      originAttributes: {'inBrowser': true}
+      appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+      isInBrowserElement: true
     }
   }], SimpleTest.waitForFocus.bind(SimpleTest, createFrames));
 }
 
 var gFrames = [];
 var gInputFrame;
 
 function createFrames() {
--- a/dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
+++ b/dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
@@ -13,21 +13,19 @@
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 
 var iframe;
 
 function runTest() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
-  SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
-                                                originAttributes: {
-                                                  appId: principal.appId,
-                                                  inBrowser: true
-                                                }});
+  SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
+                                                 appId: principal.appId,
+                                                 isInBrowserElement: true });
 
   iframe = document.createElement('iframe');
   iframe.setAttribute('mozbrowser', 'true');
 
   // Our test involves three <iframe mozbrowser>'s, parent, child1, and child2.
   // child1 and child2 are contained inside parent.  child1 is visibile, and
   // child2 is not.
   //
@@ -72,21 +70,20 @@ function finish() {
   // We need to remove this listener because when this test finishes and the
   // iframe containing this document is navigated, we'll fire a
   // visibilitychange(false) event on all child iframes.  That's OK and
   // expected, but if we don't remove our listener, then we'll end up causing
   // the /next/ test to fail!
   iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
 
   var principal = SpecialPowers.wrap(document).nodePrincipal;
-  SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
-                                             originAttributes: {
-                                               appId: principal.appId,
-                                               inBrowser: true
-                                             }});
+  SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
+                                              appId: principal.appId,
+                                              isInBrowserElement: true });
+
   SimpleTest.finish();
 }
 
 var expectedMsg = null;
 var expectedMsgCallback = null;
 function expectMessage(msg, next) {
   expectedMsg = msg;
   expectedMsgCallback = next;
--- a/dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
+++ b/dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
@@ -7,21 +7,19 @@
 "use strict";
 
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 
 function runTest() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
-  SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
-                                                originAttributes: {
-                                                  appId: principal.appId,
-                                                  inBrowser: true
-                                                }});
+  SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
+                                                 appId: principal.appId,
+                                                 isInBrowserElement: true });
 
   var iframe = document.createElement('iframe');
   iframe.setAttribute('mozbrowser', 'true');
 
   // We need remote = false here until bug 761935 is fixed; see
   // SetVisibleFrames.js for an explanation.
   iframe.remote = false;
 
@@ -54,17 +52,15 @@ function runTest() {
   });
 
   document.body.appendChild(iframe);
 }
 
 function finish() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
   SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
-                                              originAttributes: {
-                                                appId: principal.appId,
-                                                inBrowser: true
-                                              }});
+                                              appId: principal.appId,
+                                              isInBrowserElement: true });
 
   SimpleTest.finish();
 }
 
 addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html
+++ b/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html
@@ -17,29 +17,25 @@ message gets priority BACKGROUND_PERCEIV
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 browserElementTestHelpers.enableProcessPriorityManager();
 SpecialPowers.addPermission("embed-apps", true, document);
 
 // Give our origin permission to open browsers, and remove it when the test is complete.
 var principal = SpecialPowers.wrap(document).nodePrincipal;
-SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
-                                              originAttributes: {
-                                                appId: principal.appId,
-                                                inBrowser: true
-                                              }});
+SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
+                                               appId: principal.appId,
+                                               isInBrowserElement: true });
 
 addEventListener('unload', function() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
-  SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
-                                             originAttributes: {
-                                               appId: principal.appId,
-                                               inBrowser: true
-                                             }});
+  SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
+                                              appId: principal.appId,
+                                              isInBrowserElement: true });
 });
 
 function runTest() {
   var iframe = document.createElement('iframe');
   iframe.setAttribute('mozbrowser', true);
   iframe.setAttribute('expecting-system-message', true);
   iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
 
--- a/dom/browser-element/mochitest/priority/test_NestedFrames.html
+++ b/dom/browser-element/mochitest/priority/test_NestedFrames.html
@@ -16,29 +16,25 @@ Test changing the visibility of an <ifra
 
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 browserElementTestHelpers.enableProcessPriorityManager();
 
 // Give our origin permission to open browsers, and remove it when the test is complete.
 var principal = SpecialPowers.wrap(document).nodePrincipal;
-SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
-                                              originAttributes: {
-                                                appId: principal.appId,
-                                                inBrowser: true
-                                              }});
+SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
+                                               appId: principal.appId,
+                                               isInBrowserElement: true });
 
 addEventListener('unload', function() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
-  SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
-                                             originAttributes: {
-                                               appId: principal.appId,
-                                               inBrowser: true
-                                             }});
+  SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
+                                              appId: principal.appId,
+                                              isInBrowserElement: true });
 });
 
 function runTest() {
   // Set up the following hierarchy of frames:
   //
   //   <iframe mozbrowser remote=false src='file_NestedFramesOuter.html'>
   //     <iframe mozbrowser remote=true src='file_empty.html'>
   //
--- a/dom/cache/test/mochitest/driver.js
+++ b/dom/cache/test/mochitest/driver.js
@@ -30,17 +30,26 @@ function runTests(testFile, order) {
         resolve();
       });
     });
   }
 
   // adapted from dom/indexedDB/test/helpers.js
   function clearStorage() {
     return new Promise(function(resolve, reject) {
-      SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
+      var principal = SpecialPowers.wrap(document).nodePrincipal;
+      var appId, inBrowser;
+      var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+      if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+          principal.appId != nsIPrincipal.NO_APP_ID) {
+        appId = principal.appId;
+        inBrowser = principal.isInBrowserElement;
+      }
+      SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
+                                       inBrowser);
     });
   }
 
   function loadScript(script) {
     return new Promise(function(resolve, reject) {
       var s = document.createElement("script");
       s.src = script;
       s.onerror = reject;
--- a/dom/cache/test/mochitest/test_cache_orphaned_body.html
+++ b/dom/cache/test/mochitest/test_cache_orphaned_body.html
@@ -19,29 +19,56 @@ function setupTestIframe() {
       resolve();
     };
     document.body.appendChild(iframe);
   });
 }
 
 function clearStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
+                                        inBrowser);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function gc() {
   return new Promise(function(resolve, reject) {
     SpecialPowers.exactGC(window, resolve);
   });
 }
--- a/dom/cache/test/mochitest/test_cache_orphaned_cache.html
+++ b/dom/cache/test/mochitest/test_cache_orphaned_cache.html
@@ -19,29 +19,56 @@ function setupTestIframe() {
       resolve();
     };
     document.body.appendChild(iframe);
   });
 }
 
 function clearStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
+                                        inBrowser);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function gc() {
   return new Promise(function(resolve, reject) {
     SpecialPowers.exactGC(window, resolve);
   });
 }
--- a/dom/cache/test/mochitest/test_cache_restart.html
+++ b/dom/cache/test/mochitest/test_cache_restart.html
@@ -18,17 +18,26 @@ function setupTestIframe() {
       resolve();
     };
     document.body.appendChild(iframe);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({
   "set": [["dom.caches.enabled", true],
           ["dom.caches.testing.enabled", true],
           ["dom.quotaManager.testing", true]],
--- a/dom/cache/test/mochitest/test_cache_shrink.html
+++ b/dom/cache/test/mochitest/test_cache_shrink.html
@@ -19,29 +19,56 @@ function setupTestIframe() {
       resolve();
     };
     document.body.appendChild(iframe);
   });
 }
 
 function clearStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function storageUsage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
+                                        inBrowser);
   });
 }
 
 function resetStorage() {
   return new Promise(function(resolve, reject) {
-    SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
+    var principal = SpecialPowers.wrap(document).nodePrincipal;
+    var appId, inBrowser;
+    var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
+    if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
+        principal.appId != nsIPrincipal.NO_APP_ID) {
+      appId = principal.appId;
+      inBrowser = principal.isInBrowserElement;
+    }
+    SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
+                                     inBrowser);
   });
 }
 
 function gc() {
   return new Promise(function(resolve, reject) {
     SpecialPowers.exactGC(window, resolve);
   });
 }
--- a/dom/indexedDB/test/file.js
+++ b/dom/indexedDB/test/file.js
@@ -184,17 +184,27 @@ function verifyMutableFile(mutableFile1,
 
 function grabFileUsageAndContinueHandler(usage, fileUsage)
 {
   testGenerator.send(fileUsage);
 }
 
 function getUsage(usageHandler)
 {
-  SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), usageHandler);
+  let principal = SpecialPowers.wrap(document).nodePrincipal;
+  let appId, inBrowser;
+  if (principal.appId != Components.interfaces.nsIPrincipal.UNKNOWN_APP_ID &&
+      principal.appId != Components.interfaces.nsIPrincipal.NO_APP_ID) {
+    appId = principal.appId;
+    inBrowser = principal.isInBrowserElement;
+  }
+  SpecialPowers.getStorageUsageForURI(window.document.documentURI,
+                                      usageHandler,
+                                      appId,
+                                      inBrowser);
 }
 
 function getFileId(file)
 {
   return utils.getFileId(file);
 }
 
 function getFilePath(file)
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -29,17 +29,24 @@ function executeSoon(aFun)
   thread.dispatch({
     run: function() {
       aFun();
     }
   }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
 }
 
 function clearAllDatabases(callback) {
-  SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), callback);
+  let principal = SpecialPowers.wrap(document).nodePrincipal;
+  let appId, inBrowser;
+  if (principal.appId != Components.interfaces.nsIPrincipal.UNKNOWN_APP_ID &&
+      principal.appId != Components.interfaces.nsIPrincipal.NO_APP_ID) {
+    appId = principal.appId;
+    inBrowser = principal.isInBrowserElement;
+  }
+  SpecialPowers.clearStorageForURI(document.documentURI, callback, appId, inBrowser);
 }
 
 var testHarnessGenerator = testHarnessSteps();
 testHarnessGenerator.next();
 
 function testHarnessSteps() {
   function nextTestHarnessStep(val) {
     testHarnessGenerator.send(val);
--- a/dom/indexedDB/test/webapp_clearBrowserData.js
+++ b/dom/indexedDB/test/webapp_clearBrowserData.js
@@ -112,19 +112,21 @@ function start()
 {
   if (!SpecialPowers.isMainProcess()) {
     todo(false, "Test disabled in child processes, for now");
     SimpleTest.finish();
     return;
   }
 
   SpecialPowers.addPermission("browser", true, document);
-  SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL });
+  SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL,
+                                                 isInBrowserElement: false });
   SpecialPowers.addPermission("embed-apps", true, document);
-  SpecialPowers.addPermission("indexedDB", true, { manifestURL: manifestURL });
+  SpecialPowers.addPermission("indexedDB", true, { manifestURL: manifestURL,
+                                                   isInBrowserElement: false });
 
   SpecialPowers.setAllAppsLaunchable(true);
 
   window.addEventListener("unload", function cleanup(event) {
     if (event.target == document) {
       window.removeEventListener("unload", cleanup, false);
 
       SpecialPowers.removePermission("browser", location.href);
--- a/dom/inputmethod/mochitest/test_bug1043828.html
+++ b/dom/inputmethod/mochitest/test_bug1043828.html
@@ -86,19 +86,18 @@ function runTest() {
     // simulate two different keyboard apps
     let imeUrl = basePath + '/file_blank.html';
 
     SpecialPowers.pushPermissions([{
       type: 'input',
       allow: true,
       context: {
         url: imeUrl,
-        originAttributes: {
-          inBrowser: true
-        }
+        appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+        isInBrowserElement: true
       }
     }], function() {
       keyboardA.src = imeUrl;
       keyboardB.src = imeUrl;
 
       var handler = {
         handleEvent: function(){
           keyboardB.removeEventListener('mozbrowserloadend', this);
--- a/dom/inputmethod/mochitest/test_bug944397.html
+++ b/dom/inputmethod/mochitest/test_bug944397.html
@@ -73,19 +73,18 @@ function runTest() {
     // STEP 2b: Grant input privileges to the keyboard iframe
     let imeUrl = basePath + '/file_inputmethod.html#data';
 
     SpecialPowers.pushPermissions([{
       type: 'input',
       allow: true,
       context: {
         url: imeUrl,
-        originAttributes: {
-          inBrowser: true
-        }
+        appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+        isInBrowserElement: true
       }
     }], function() {
       // STEP 2c: Tell Gecko to use this iframe as its keyboard app
       let req = keyboard.setInputMethodActive(true);
 
       req.onsuccess = function() {
         ok(true, 'setInputMethodActive succeeded.');
       };
--- a/dom/inputmethod/mochitest/test_focus_blur_manage_events.html
+++ b/dom/inputmethod/mochitest/test_focus_blur_manage_events.html
@@ -136,19 +136,18 @@ function setupInputAppFrame() {
     inputAppFrame.src = imeUrl;
     document.body.appendChild(inputAppFrame);
 
     SpecialPowers.pushPermissions([{
       type: 'input',
       allow: true,
       context: {
         url: imeUrl,
-        originAttributes: {
-          inBrowser: true
-        }
+        appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+        isInBrowserElement: true
       }
     }], function() {
       let mm = SpecialPowers.getBrowserFrameMessageManager(inputAppFrame);
       inputAppFrame.addEventListener('mozbrowserloadend', function() {
         mm.addMessageListener('text:appEvent', function(msg) {
           ok(false, 'Input app should not receive ' + msg.data.type + ' event.');
         });
         mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
--- a/dom/inputmethod/mochitest/test_input_registry_events.html
+++ b/dom/inputmethod/mochitest/test_input_registry_events.html
@@ -65,19 +65,18 @@ function setupInputAppFrame() {
     inputAppFrame.src = imeUrl;
     document.body.appendChild(inputAppFrame);
 
     SpecialPowers.pushPermissions([{
       type: 'input',
       allow: true,
       context: {
         url: imeUrl,
-        originAttributes: {
-          inBrowser: true
-        }
+        appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+        isInBrowserElement: true
       }
     }], function() {
       let mm = appFrameMM =
         SpecialPowers.getBrowserFrameMessageManager(inputAppFrame);
 
       inputAppFrame.addEventListener('mozbrowserloadend', function() {
         mm.addMessageListener('test:appEvent', function(msg) {
           ok(false, 'Input app should not receive ' + msg.data.type + ' event.');
--- a/dom/inputmethod/mochitest/test_simple_manage_events.html
+++ b/dom/inputmethod/mochitest/test_simple_manage_events.html
@@ -98,19 +98,18 @@ function setupInputAppFrame() {
     inputAppFrame.src = imeUrl;
     document.body.appendChild(inputAppFrame);
 
     SpecialPowers.pushPermissions([{
       type: 'input',
       allow: true,
       context: {
         url: imeUrl,
-        originAttributes: {
-          inBrowser: true
-        }
+        appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
+        isInBrowserElement: true
       }
     }], function() {
       let mm = appFrameMM =
         SpecialPowers.getBrowserFrameMessageManager(inputAppFrame);
 
       inputAppFrame.addEventListener('mozbrowserloadend', function() {
         mm.addMessageListener('test:appEvent', function(msg) {
           ok(false, 'Input app should not receive ' + msg.data.type + ' event.');
--- a/dom/ipc/tests/test_permission_for_nested_oop_app.html
+++ b/dom/ipc/tests/test_permission_for_nested_oop_app.html
@@ -28,17 +28,18 @@ var tests = [
 
   // Install the app
   installApp,
 
   // Allow permission for embedApp to open mozbrowser and mozapp
   function() {
     var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
     var context = { url: embedApp.origin,
-                    originAttributes: { appId: appId } };
+                    appId: appId,
+                    isInBrowserElement: false };
     setupOpenAppPermission(context, runTests);
   },
 
   // +-------------------------------------------+
   // | Test 3: Open a test-target-app on 3rd     |
   // |         level child-process then close it |
   // +-------------------------------------------+
   //
--- a/dom/ipc/tests/test_permission_for_two_oop_apps.html
+++ b/dom/ipc/tests/test_permission_for_two_oop_apps.html
@@ -28,17 +28,18 @@ var tests = [
 
   // Install the app
   installApp,
 
   // Allow permission for embedApp to open mozbrowser and mozapp
   function() {
     var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
     var context = { url: embedApp.origin,
-                    originAttributes: { appId: appId } };
+                    appId: appId,
+                    isInBrowserElement: false };
     setupOpenAppPermission(context, runTests);
   },
 
   // +---------------------------------------------------------+
   // | Test 4: Open two test-target-app on 2nd and 3rd level   |
   // |         child-processes then close the one on 3rd level |
   // +---------------------------------------------------------+
   //
--- a/dom/ipc/tests/test_permission_helper.js
+++ b/dom/ipc/tests/test_permission_helper.js
@@ -48,17 +48,18 @@ function runTests() {
 
 function test1() {
   allocateAppFrame(APP_IFRAME_ID, DOM_PARENT, APP_URL, APP_MANIFEST);
 
   var appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
 
   if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
                                     { url: APP_URL,
-                                      originAttributes: { appId: appId }})) {
+                                      appId: appId,
+                                      isInBrowserElement: false })) {
     errorHandler('[test 1] App should have permission: ' + PERMISSION_TYPE);
   }
 
   removeAppFrame(APP_IFRAME_ID);
 
   // We expect there is no permission for the test-target-app
   // after removing the in-process iframe embedding this app
   runNextIfAppHasPermission(1, false, APP_URL, APP_MANIFEST);
@@ -76,17 +77,18 @@ function test2() {
   afterContentShutdown(1, afterShutdown);
 
   allocateAppFrame(APP_IFRAME_ID, DOM_PARENT, APP_URL, APP_MANIFEST, true);
 
   var appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
 
   if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
                                     { url: APP_URL,
-                                      originAttributes: { appId: appId }})) {
+                                      appId: appId,
+                                      isInBrowserElement: false })) {
     errorHandler('[test 2] App should have permission: ' + PERMISSION_TYPE);
   }
 
   removeAppFrame(APP_IFRAME_ID);
 }
 
 function test3() {
   var afterGrandchildShutdown = function () {
@@ -104,17 +106,18 @@ function test3() {
                    embedApp.manifest.launch_path,
                    embedApp.manifestURL,
                    true);
 
   var appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
 
   if (!SpecialPowers.hasPermission(PERMISSION_TYPE,
                                    { url: APP_URL,
-                                     originAttributes: { appId: appId }})) {
+                                     appId: appId,
+                                     isInBrowserElement: false })) {
     errorHandler('[test 3] App should have permission: ' + PERMISSION_TYPE);
   }
 }
 
 function test4() {
   var afterGrandchildShutdown = function () {
     // We expect there is still a permission for the test-target-app
     // after killing test-target-app on 3rd-level process
@@ -140,17 +143,18 @@ function test4() {
                    APP_URL,
                    APP_MANIFEST,
                    true);
 
   var appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
 
   if (!SpecialPowers.hasPermission(PERMISSION_TYPE,
                                    { url: APP_URL,
-                                     originAttributes: { appId: appId }})) {
+                                     appId: appId,
+                                     isInBrowserElement: false })) {
     errorHandler('[test 4] App should have permission: ' + PERMISSION_TYPE);
   }
 }
 
 function test5() {
   var afterShutdown = function () {
     // We expect there is no permission for the test-target-app
     // after crashing its parent-process
@@ -165,17 +169,18 @@ function test5() {
                    embedApp.manifest.launch_path + '#' + encodeURIComponent('crash'),
                    embedApp.manifestURL,
                    true);
 
   var appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
 
   if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
                                     { url: APP_URL,
-                                      originAttributes: { appId: appId }})) {
+                                      appId: appId,
+                                      isInBrowserElement: false })) {
     errorHandler('[test 5] App should have permission: ' + PERMISSION_TYPE);
   }
 
   // Crash the child-process on 2nd level after
   // the grandchild process on 3rd is allocated
   var handler = {'crash': function() {
       gScript.sendAsyncMessage("crashreporter-status", {});
 
@@ -280,29 +285,31 @@ function addPermissionToApp(appURL, mani
 
   // Add app's permission asynchronously
   SpecialPowers.pushPermissions([
       { "type":PERMISSION_TYPE,
         "allow": 1,
         "expireType":permManager.EXPIRE_SESSION,
         "expireTime":now + SESSION_PERSIST_MINUTES*60*1000,
         "context": { url: appURL,
-                     originAttributes: { appId: appId } }
+                     appId: appId,
+                     isInBrowserElement:false }
       }
     ], function() {
       runTests();
     });
 }
 
 function runNextIfAppHasPermission(round, expect, appURL, manifestURL) {
   var appId = gAppsService.getAppLocalIdByManifestURL(manifestURL);
 
   var hasPerm = SpecialPowers.hasPermission(PERMISSION_TYPE,
                                             { url: appURL,
-                                              originAttributes: { appId: appId }});
+                                              appId: appId,
+                                              isInBrowserElement: false });
   var result = (expect==hasPerm);
   if (result) {
     runTests();
   } else {
     errorHandler( '[test ' + round + '] App should ' + ((expect)? '':'NOT ') +
                   'have permission: ' + PERMISSION_TYPE);
   }
 }
--- a/dom/ipc/tests/test_permission_when_oop_app_crashes.html
+++ b/dom/ipc/tests/test_permission_when_oop_app_crashes.html
@@ -28,17 +28,18 @@ var tests = [
 
   // Install the app
   installApp,
 
   // Allow permission for embedApp to open mozbrowser and mozapp
   function() {
     var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
     var context = { url: embedApp.origin,
-                    originAttributes: { appId: appId } };
+                    appId: appId,
+                    isInBrowserElement: false };
     setupOpenAppPermission(context, runTests);
   },
 
   // +-----------------------------------------------+
   // | Test 5: Open a test-target-app on 3rd level   |
   // |         process then crash its parent-process |
   // +-----------------------------------------------+
   //
--- a/dom/tv/test/mochitest/head.js
+++ b/dom/tv/test/mochitest/head.js
@@ -17,19 +17,18 @@ function installApp(aTestToken, aTemplat
                           + aTestToken + '&template=' + aTemplate;
   var request = navigator.mozApps.install(hostedManifestURL);
   request.onerror = cbError;
   request.onsuccess = function() {
     gApp = request.result;
 
     var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL);
     SpecialPowers.addPermission("tv", true, { url: gApp.origin,
-                                              originAttributes: {
-                                                appId: appId
-                                              }});
+                                              appId: appId,
+                                              isInBrowserElement: false });
 
     runTest();
   }
 }
 
 function uninstallApp() {
   var request = navigator.mozApps.mgmt.uninstall(gApp);
   request.onerror = cbError;
--- a/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushAppPermissions.html
+++ b/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushAppPermissions.html
@@ -64,44 +64,46 @@ function installApp(aTestToken, aTemplat
     gApp = request.result; // Assign to global variable
     pushPermissionsToApp();
   }
 }
 
 function pushPermissionsToApp() {
   var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL);
   var context = { url: gApp.origin,
-                  originAttributes: {appId: appId}};
+                  appId: appId,
+                  isInBrowserElement: false };
   SpecialPowers.pushPermissions([
       { "type": "pAppPermission", "allow": true, "context": context }
     ], testPermissionsForApp);
 }
 
 function testPermissionsForApp() {
   var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL);
   var context = { url: gApp.origin,
-                  originAttributes: {appId: appId}};
+                  appId: appId,
+                  isInBrowserElement: false };
   ok(SpecialPowers.hasPermission('pAppPermission', context), 'pAppPermission should have permission');
   uninstallApp();
 }
 
 function uninstallApp() {
   var request = navigator.mozApps.mgmt.uninstall(gApp);
   request.onerror = cbError;
   request.onsuccess = function() {
     testPermissionsForSelfAndApp();
   }
 }
 
 function testPermissionsForSelfAndApp() {
   var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL);
-  is(appId, 0, "appId should become NO_APP_ID");
-  // since gApp is uninstalled, calling SpecialPowers.hasPermission with the
-  // app's properties (manifestURL, origin, principal, ... etc) will throw.
-  // So we don't need to test hasPermission for the app.
+  var context = { url: gApp.origin,
+                  appId: appId,
+                  isInBrowserElement: false };
+  ok(!SpecialPowers.hasPermission('pAppPermission', context), 'pAppPermission should not have permission');
 
   ok(SpecialPowers.hasPermission('pAppPermission', document), 'pAppPermission should have permission');
 
   SimpleTest.finish();
 }
 </script>
 </pre>
 </body>
--- a/testing/mochitest/tests/Harness_sanity/test_bug816847.html
+++ b/testing/mochitest/tests/Harness_sanity/test_bug816847.html
@@ -52,33 +52,35 @@ function starttest(){
   var origin = app.origin 
   var nodePrincipal = SpecialPowers.wrap(document).nodePrincipal;
   var appPrincipal = createPrincipal(manifest, true);
   var noappPrincipal = createPrincipal(origin, false);
 
   SpecialPowers.addPermission(perms[0], true, origin);
   SpecialPowers.addPermission(perms[1], true, {manifestURL: manifest});
   SpecialPowers.addPermission(perms[2], true, document);
-  SpecialPowers.addPermission(perms[3], true, {url: origin});
+  SpecialPowers.addPermission(perms[3], true, {url: origin,
+                                               appId: Ci.nsIScriptSecurityManager.NO_APP_ID});
 
   is(Services.perms.testPermissionFromPrincipal(noappPrincipal, perms[0]),
      allow, "Set permission by string");
   is(Services.perms.testPermissionFromPrincipal(appPrincipal, perms[1]),
      allow, "Set permission by manifestURL");
   is(Services.perms.testPermissionFromPrincipal(nodePrincipal, perms[2]),
      allow, "Set permission by principal");
   is(Services.perms.testPermissionFromPrincipal(noappPrincipal, perms[3]),
      allow, "Set permission by other");
   is(Services.perms.testPermissionFromPrincipal(noappPrincipal, perms[1]),
      unknown, "Check that app permission doesn't leak to normal page");
 
   SpecialPowers.removePermission(perms[0], origin);
   SpecialPowers.removePermission(perms[1], {manifestURL: manifest});
   SpecialPowers.removePermission(perms[2], document);
-  SpecialPowers.removePermission(perms[3], {url: origin});
+  SpecialPowers.removePermission(perms[3], {url: origin,
+                                            appId: Ci.nsIScriptSecurityManager.NO_APP_ID});
 
   is(Services.perms.testPermissionFromPrincipal(noappPrincipal, perms[0]),
      unknown, "Removed permission by string");
   is(Services.perms.testPermissionFromPrincipal(appPrincipal, perms[1]),
      unknown, "Removed permission by manifestURL");
   is(Services.perms.testPermissionFromPrincipal(nodePrincipal, perms[2]),
      unknown, "Removed permission by principal");
   is(Services.perms.testPermissionFromPrincipal(noappPrincipal, perms[3]),
--- a/testing/specialpowers/components/SpecialPowersObserver.js
+++ b/testing/specialpowers/components/SpecialPowersObserver.js
@@ -229,20 +229,17 @@ SpecialPowersObserver.prototype = new Sp
           var permission = aSubject.QueryInterface(Ci.nsIPermission);
 
           // specialPowersAPI will consume this value, and it is used as a
           // fake permission, but only type and principal.appId will be used.
           //
           // We need to ensure that it looks the same as a real permission,
           // so we fake these properties.
           msg.permission = {
-            principal: {
-              appId: permission.principal.appId,
-              originAttributes: {appId: permission.principal.appId}
-            },
+            principal: { appId: permission.principal.appId },
             type: permission.type
           };
         default:
           this._self._sendAsyncMessage("specialpowers-" + aTopic, msg);
       }
     }
   };
 
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -316,31 +316,42 @@ SpecialPowersObserverAPI.prototype = {
           default:
             throw new SpecialPowersError("Invalid operation for SPProcessCrashService");
         }
         return undefined;	// See comment at the beginning of this function.
       }
 
       case "SPPermissionManager": {
         let msg = aMessage.json;
-        let principal = msg.principal;
+
+        let secMan = Services.scriptSecurityManager;
+        // TODO: Bug 1196665 - Add originAttributes into SpecialPowers
+        let attrs = {appId: msg.appId, inBrowser: msg.isInBrowserElement};
+        let principal = secMan.createCodebasePrincipal(this._getURI(msg.url), attrs);
 
         switch (msg.op) {
           case "add":
             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);
-            return hasPerm == Ci.nsIPermissionManager.ALLOW_ACTION;
+            if (hasPerm == Ci.nsIPermissionManager.ALLOW_ACTION) 
+              return true;
+            return false;
+            break;
           case "test":
             let testPerm = Services.perms.testPermissionFromPrincipal(principal, msg.type, msg.value);
-            return testPerm == msg.value;
+            if (testPerm == msg.value)  {
+              return true;
+            }
+            return false;
+            break;
           default:
             throw new SpecialPowersError(
               "Invalid operation for SPPermissionManager");
         }
         return undefined;	// See comment at the beginning of this function.
       }
 
       case "SPSetTestPluginEnabledState": {
@@ -494,23 +505,28 @@ SpecialPowersObserverAPI.prototype = {
       case 'SPQuotaManager': {
         let qm = Cc['@mozilla.org/dom/quota/manager;1']
                    .getService(Ci.nsIQuotaManager);
         let mm = aMessage.target
                          .QueryInterface(Ci.nsIFrameLoaderOwner)
                          .frameLoader
                          .messageManager;
         let msg = aMessage.data;
-        let principal = msg.principal;
         let op = msg.op;
 
         if (op != 'clear' && op != 'getUsage' && op != 'reset') {
           throw new SpecialPowersError('Invalid operation for SPQuotaManager');
         }
 
+        let secMan = Services.scriptSecurityManager;
+        let principal = secMan.createCodebasePrincipal(this._getURI(msg.uri), {
+          appId: msg.appId,
+          inBrowser: msg.inBrowser,
+        });
+
         if (op == 'clear') {
           qm.clearStoragesForPrincipal(principal);
         } else if (op == 'reset') {
           qm.reset();
         }
 
         // We always use the getUsageForPrincipal callback even if we're clearing
         // since we know that clear and getUsageForPrincipal are synchronized by the
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -781,17 +781,17 @@ SpecialPowersAPI.prototype = {
         } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_SESSION, context)) {
           originalValue = Ci.nsICookiePermission.ACCESS_SESSION;
         } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY, context)) {
           originalValue = Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY;
         } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY, context)) {
           originalValue = Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY;
         }
 
-        let [principal, isSystem] = this._getInfoFromPermissionArg(context);
+        let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(context);
         if (isSystem) {
           continue;
         }
 
         let perm;
         if (typeof permission.allow !== 'boolean') {
           perm = permission.allow;
         } else {
@@ -805,17 +805,19 @@ SpecialPowersAPI.prototype = {
         if (originalValue == perm) {
           continue;
         }
 
         var todo = {'op': 'add',
                     'type': permission.type,
                     'permission': perm,
                     'value': perm,
-                    'principal': principal,
+                    '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)
@@ -960,17 +962,17 @@ SpecialPowersAPI.prototype = {
         }
       } else {
         var found = false;
         for (var i = 0; !found && i < this._self._permissionsUndoStack.length; i++) {
           var undos = this._self._permissionsUndoStack[i];
           for (var j = 0; j < undos.length; j++) {
             var undo = undos[j];
             if (undo.op == this._obsDataMap[aData] &&
-                undo.principal.originAttributes.appId == permission.principal.originAttributes.appId &&
+                undo.appId == permission.principal.appId &&
                 undo.type == permission.type) {
               // Remove this undo item if it has been done by others(not
               // specialpowers itself.)
               undos.splice(j,1);
               found = true;
               break;
             }
           }
@@ -1814,118 +1816,137 @@ SpecialPowersAPI.prototype = {
    */
   getBrowserFrameMessageManager: function(aFrameElement) {
     return this.wrap(aFrameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
                                   .frameLoader
                                   .messageManager);
   },
 
   _getInfoFromPermissionArg: function(arg) {
-    let principal;
+    let url = "";
+    let appId = Ci.nsIScriptSecurityManager.NO_APP_ID;
+    let isInBrowserElement = false;
     let isSystem = false;
-    let secMan = Services.scriptSecurityManager;
 
     if (typeof(arg) == "string") {
       // It's an URL.
-      let uri = Services.io.newURI(arg, null, null);
-      principal = secMan.createCodebasePrincipal(uri, {});
+      url = Cc["@mozilla.org/network/io-service;1"]
+              .getService(Ci.nsIIOService)
+              .newURI(arg, null, null)
+              .spec;
     } else if (arg.manifestURL) {
       // It's a thing representing an app.
       let appsSvc = Cc["@mozilla.org/AppsService;1"]
                       .getService(Ci.nsIAppsService)
       let app = appsSvc.getAppByManifestURL(arg.manifestURL);
+
       if (!app) {
         throw "No app for this manifest!";
       }
 
-      principal = app.principal;
+      appId = appsSvc.getAppLocalIdByManifestURL(arg.manifestURL);
+      url = app.origin;
+      isInBrowserElement = arg.isInBrowserElement || false;
     } else if (arg.nodePrincipal) {
       // It's a document.
       isSystem = (arg.nodePrincipal instanceof Ci.nsIPrincipal) &&
-                 Cc["@mozilla.org/scriptsecuritymanager;1"]
-                   .getService(Ci.nsIScriptSecurityManager)
-                   .isSystemPrincipal(arg.nodePrincipal);
-      // some tests the arg is a wrapped DOM element, so we unwrap it first.
-      principal = unwrapIfWrapped(arg).nodePrincipal;
+                 Cc["@mozilla.org/scriptsecuritymanager;1"].
+                 getService(Ci.nsIScriptSecurityManager).
+                 isSystemPrincipal(arg.nodePrincipal);
+      if (!isSystem) {
+        // System principals don't have a URL associated with them, and they
+        // don't really need any permissions to be registered with the
+        // permission manager anyway.
+        url = arg.nodePrincipal.URI.spec;
+        appId = arg.nodePrincipal.appId;
+        isInBrowserElement = arg.nodePrincipal.isInBrowserElement;
+      }
     } else {
-      let uri = Services.io.newURI(arg.url, null, null);
-      let attrs = arg.originAttributes || {};
-      principal = secMan.createCodebasePrincipal(uri, attrs);
+      url = arg.url;
+      appId = arg.appId;
+      isInBrowserElement = arg.isInBrowserElement;
     }
 
-    return [ principal, isSystem ];
+    return [ url, appId, isInBrowserElement, isSystem ];
   },
 
   addPermission: function(type, allow, arg, expireType, expireTime) {
-    let [principal, isSystem] = this._getInfoFromPermissionArg(arg);
+    let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return; // nothing to do
     }
 
     let permission;
     if (typeof allow !== 'boolean') {
       permission = allow;
     } else {
       permission = allow ? Ci.nsIPermissionManager.ALLOW_ACTION
                          : Ci.nsIPermissionManager.DENY_ACTION;
     }
 
     var msg = {
       'op': 'add',
       'type': type,
       'permission': permission,
-      'principal': principal,
+      'url': url,
+      'appId': appId,
+      'isInBrowserElement': isInBrowserElement,
       'expireType': (typeof expireType === "number") ? expireType : 0,
       'expireTime': (typeof expireTime === "number") ? expireTime : 0
     };
 
     this._sendSyncMessage('SPPermissionManager', msg);
   },
 
   removePermission: function(type, arg) {
-    let [principal, isSystem] = this._getInfoFromPermissionArg(arg);
+    let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return; // nothing to do
     }
 
     var msg = {
       'op': 'remove',
       'type': type,
-      'principal': principal
+      'url': url,
+      'appId': appId,
+      'isInBrowserElement': isInBrowserElement
     };
 
     this._sendSyncMessage('SPPermissionManager', msg);
   },
 
   hasPermission: function (type, arg) {
-    let [principal, isSystem] = this._getInfoFromPermissionArg(arg);
+    let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return true; // system principals have all permissions
     }
 
     var msg = {
       'op': 'has',
       'type': type,
-      'principal': principal
+      'url': url,
+      'appId': appId,
+      'isInBrowserElement': isInBrowserElement
     };
 
     return this._sendSyncMessage('SPPermissionManager', msg)[0];
   },
-
   testPermission: function (type, value, arg) {
-    let [principal, isSystem] = this._getInfoFromPermissionArg(arg);
+    let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return true; // system principals have all permissions
     }
 
     var msg = {
       'op': 'test',
       'type': type,
-      'value': value,
-      'principal': principal
+      'value': value, 
+      'url': url,
+      'appId': appId,
+      'isInBrowserElement': isInBrowserElement
     };
     return this._sendSyncMessage('SPPermissionManager', msg)[0];
   },
 
   isContentWindowPrivate: function(win) {
     return PrivateBrowsingUtils.isContentWindowPrivate(win);
   },
 
@@ -1940,30 +1961,38 @@ SpecialPowersAPI.prototype = {
     var msg = {
       'op': 'notify',
       'observerTopic': topic,
       'observerData': data
     };
     this._sendSyncMessage('SPObserverService', msg);
   },
 
-  clearStorageForDoc: function(wrappedDocument, callback) {
-    this._quotaManagerRequest('clear', wrappedDocument, callback);
+  clearStorageForURI: function(uri, callback, appId, inBrowser) {
+    this._quotaManagerRequest('clear', uri, appId, inBrowser, callback);
+  },
+
+  getStorageUsageForURI: function(uri, callback, appId, inBrowser) {
+    this._quotaManagerRequest('getUsage', uri, appId, inBrowser, callback);
   },
 
-  getStorageUsageForDoc: function(wrappedDocument, callback) {
-    this._quotaManagerRequest('getUsage', wrappedDocument, callback);
+  // Technically this restarts the QuotaManager for all URIs, but we need
+  // a specific one to perform the synchronized callback when the reset is
+  // complete.
+  resetStorageForURI: function(uri, callback, appId, inBrowser) {
+    this._quotaManagerRequest('reset', uri, appId, inBrowser, callback);
   },
 
-  resetStorageForDoc: function(wrappedDocument, callback) {
-    this._quotaManagerRequest('reset', wrappedDocument, callback);
-  },
+  _quotaManagerRequest: function(op, uri, appId, inBrowser, callback) {
+    const messageTopic = "SPQuotaManager";
 
-  _quotaManagerRequest: function(op, wrappedDocument, callback) {
-    const messageTopic = "SPQuotaManager";
+    if (uri instanceof Ci.nsIURI) {
+      uri = uri.spec;
+    }
+
     const id = Cc["@mozilla.org/uuid-generator;1"]
                  .getService(Ci.nsIUUIDGenerator)
                  .generateUUID()
                  .toString();
 
     let callbackInfo = { id: id, callback: callback };
 
     if (this._quotaManagerCallbackInfos) {
@@ -1990,18 +2019,17 @@ SpecialPowersAPI.prototype = {
           }
         }
       }.bind(this);
 
       this._addMessageListener(messageTopic, callbackInfo.listener);
       this._quotaManagerCallbackInfos = [ callbackInfo ];
     }
 
-    let principal = unwrapIfWrapped(wrappedDocument).nodePrincipal;
-    let msg = { op: op, principal: principal, id: id };
+    let msg = { op: op, uri: uri, appId: appId, inBrowser: inBrowser, id: id };
     this._sendAsyncMessage(messageTopic, msg);
   },
 
   createDOMFile: function(path, options) {
     return new File(path, options);
   },
 
   startPeriodicServiceWorkerUpdates: function() {