Bug 775377 - Modify nsIContentPermissionRequest to use nsIPrincipal instead of nsIURI. r=dougt+cjones
authorWilliam Chen <wchen@mozilla.com>
Mon, 30 Jul 2012 10:58:26 -0400
changeset 101842 37694e6f8df0117982ad6b79c63d59691b8b8db5
parent 101841 e6fff75af75fe27c97120d6b27fb1f24269578b8
child 101843 a7594623ad0dd1ba98b8d4e961ff5e8f439d2edb
push idunknown
push userunknown
push dateunknown
reviewersdougt
bugs775377
milestone17.0a1
Bug 775377 - Modify nsIContentPermissionRequest to use nsIPrincipal instead of nsIURI. r=dougt+cjones
b2g/components/ContentPermissionPrompt.js
browser/components/nsBrowserGlue.js
dom/base/nsContentPermissionHelper.cpp
dom/base/nsContentPermissionHelper.h
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/nsDeviceStorage.h
dom/interfaces/base/nsIContentPermissionPrompt.idl
dom/ipc/Makefile.in
dom/ipc/PBrowser.ipdl
dom/ipc/PermissionMessageUtils.cpp
dom/ipc/PermissionMessageUtils.h
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/src/notification/nsDesktopNotification.cpp
dom/src/notification/nsDesktopNotification.h
mobile/android/components/ContentPermissionPrompt.js
mobile/xul/chrome/content/IndexedDB.js
mobile/xul/chrome/content/WebappsUI.js
mobile/xul/components/ContentPermissionPrompt.js
webapprt/ContentPermission.js
--- a/b2g/components/ContentPermissionPrompt.js
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -10,17 +10,17 @@ const Cc = Components.classes;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
 
   handleExistingPermission: function handleExistingPermission(request) {
-    let result = Services.perms.testExactPermission(request.uri, request.type);
+    let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return true;
     }
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return true;
     }
@@ -51,17 +51,17 @@ ContentPermissionPrompt.prototype = {
 
       request.cancel();
     });
 
     let details = {
       "type": "permission-prompt",
       "permission": request.type,
       "id": requestId,
-      "url": request.uri.spec
+      "url": request.principal.URI.spec
     };
     let event = content.document.createEvent("CustomEvent");
     event.initCustomEvent("mozChromeEvent", true, true, details);
     content.dispatchEvent(event);
   },
 
   classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1555,23 +1555,24 @@ ContentPermissionPrompt.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
 
   prompt: function CPP_prompt(request) {
 
     if (request.type != "geolocation") {
         return;
     }
 
-    var requestingURI = request.uri;
+    var requestingPrincipal = request.principal;
+    var requestingURI = requestingPrincipal.URI;
 
     // Ignore requests from non-nsIStandardURLs
     if (!(requestingURI instanceof Ci.nsIStandardURL))
       return;
 
-    var result = Services.perms.testExactPermission(requestingURI, "geo");
+    var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, "geo");
 
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return;
     }
 
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
@@ -1614,25 +1615,25 @@ ContentPermissionPrompt.prototype = {
                                                    [requestingURI.host], 1);
 
       // Don't offer to "always/never share" in PB mode
       if (("gPrivateBrowsingUI" in chromeWin) && !chromeWin.gPrivateBrowsingUI.privateWindow) {
         secondaryActions.push({
           label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
           accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
           callback: function () {
-            Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
+            Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
             request.allow();
           }
         });
         secondaryActions.push({
           label: browserBundle.GetStringFromName("geolocation.neverShareLocation"),
           accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
           callback: function () {
-            Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
+            Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.DENY_ACTION);
             request.cancel();
           }
         });
       }
     }
 
     var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
 
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -2,34 +2,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsContentPermissionHelper.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsCOMPtr.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMElement.h"
-
+#include "nsIPrincipal.h"
 #include "mozilla/unused.h"
 
 using mozilla::unused;          // <snicker>
+using namespace mozilla::dom;
 
 nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
 {
   MOZ_COUNT_CTOR(nsContentPermissionRequestProxy);
 }
 
 nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy()
 {
   MOZ_COUNT_DTOR(nsContentPermissionRequestProxy);
 }
 
 nsresult
 nsContentPermissionRequestProxy::Init(const nsACString & type,
-				                      mozilla::dom::ContentPermissionRequestParent* parent)
+                                      ContentPermissionRequestParent* parent)
 {
   NS_ASSERTION(parent, "null parent");
   mParent = parent;
   mType   = type;
 
   nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
   if (!prompt) {
     return NS_ERROR_FAILURE;
@@ -58,82 +59,89 @@ NS_IMETHODIMP
 nsContentPermissionRequestProxy::GetWindow(nsIDOMWindow * *aRequestingWindow)
 {
   NS_ENSURE_ARG_POINTER(aRequestingWindow);
   *aRequestingWindow = nullptr; // ipc doesn't have a window
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsContentPermissionRequestProxy::GetUri(nsIURI * *aRequestingURI)
+nsContentPermissionRequestProxy::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
 {
-  NS_ENSURE_ARG_POINTER(aRequestingURI);
-  if (mParent == nullptr)
+  NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
+  if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
+  }
 
-  NS_ADDREF(*aRequestingURI = mParent->mURI);
+  NS_ADDREF(*aRequestingPrincipal = mParent->mPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
 {
   NS_ENSURE_ARG_POINTER(aRequestingElement);
-  if (mParent == nullptr)
+  if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
+  }
+
   NS_ADDREF(*aRequestingElement = mParent->mElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::Cancel()
 {
-  if (mParent == nullptr)
+  if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
-  unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, false);
+  }
+
+  unused << ContentPermissionRequestParent::Send__delete__(mParent, false);
   mParent = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::Allow()
 {
-  if (mParent == nullptr)
+  if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
-  unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, true);
+  }
+  unused << ContentPermissionRequestParent::Send__delete__(mParent, true);
   mParent = nullptr;
   return NS_OK;
 }
 
 namespace mozilla {
 namespace dom {
 
 ContentPermissionRequestParent::ContentPermissionRequestParent(const nsACString& aType,
                                                                nsIDOMElement *aElement,
-                                                               const IPC::URI& aUri)
+                                                               const IPC::Principal& aPrincipal)
 {
   MOZ_COUNT_CTOR(ContentPermissionRequestParent);
-  
-  mURI       = aUri;
+
+  mPrincipal = aPrincipal;
   mElement   = aElement;
   mType      = aType;
 }
 
 ContentPermissionRequestParent::~ContentPermissionRequestParent()
 {
   MOZ_COUNT_DTOR(ContentPermissionRequestParent);
 }
 
 bool
 ContentPermissionRequestParent::Recvprompt()
 {
   mProxy = new nsContentPermissionRequestProxy();
   NS_ASSERTION(mProxy, "Alloc of request proxy failed");
-  if (NS_FAILED(mProxy->Init(mType, this)))
+  if (NS_FAILED(mProxy->Init(mType, this))) {
     mProxy->Cancel();
+  }
   return true;
 }
 
 void
 ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
 {
   mProxy->OnParentDestroyed();
 }
--- a/dom/base/nsContentPermissionHelper.h
+++ b/dom/base/nsContentPermissionHelper.h
@@ -6,51 +6,52 @@
 #define nsContentPermissionHelper_h
 
 #include "base/basictypes.h"
 
 #include "nsIContentPermissionPrompt.h"
 #include "nsString.h"
 #include "nsIDOMElement.h"
 
+#include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/PContentPermissionRequestParent.h"
 
 class nsContentPermissionRequestProxy;
 
 namespace mozilla {
 namespace dom {
 
 class ContentPermissionRequestParent : public PContentPermissionRequestParent
 {
  public:
-  ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::URI& principal);
+  ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::Principal& principal);
   virtual ~ContentPermissionRequestParent();
-  
-  nsCOMPtr<nsIURI>           mURI;
+
+  nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<nsIDOMElement>    mElement;
   nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
   nsCString mType;
 
- private:  
+ private:
   virtual bool Recvprompt();
   virtual void ActorDestroy(ActorDestroyReason why);
 };
-  
+
 } // namespace dom
 } // namespace mozilla
 
 class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
 {
  public:
   nsContentPermissionRequestProxy();
   virtual ~nsContentPermissionRequestProxy();
-  
+
   nsresult Init(const nsACString& type, mozilla::dom::ContentPermissionRequestParent* parent);
   void OnParentDestroyed();
-  
+
   NS_DECL_ISUPPORTS
   NS_DECL_NSICONTENTPERMISSIONREQUEST
 
  private:
   // Non-owning pointer to the ContentPermissionRequestParent object which owns this proxy.
   mozilla::dom::ContentPermissionRequestParent* mParent;
   nsCString mType;
 };
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef DeviceStorage_h
 #define DeviceStorage_h
 
 #include "nsIDOMDeviceStorage.h"
 #include "nsIFile.h"
+#include "nsIPrincipal.h"
 #include "nsIObserver.h"
 #include "nsDOMEventTargetHelper.h"
 
 class nsDOMDeviceStorage MOZ_FINAL
   : public nsIDOMDeviceStorage
   , public nsIFileUpdateListener
   , public nsDOMEventTargetHelper
   , public nsIObserver
@@ -50,17 +51,17 @@ private:
                              JSContext* aCx,
                              PRUint8 aArgc, 
                              bool aEditable, 
                              nsIDOMDeviceStorageCursor** aRetval);
 
   PRInt32 mStorageType;
   nsCOMPtr<nsIFile> mFile;
 
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 
   friend class WatchFileEvent;
   friend class DeviceStorageRequest;
 
   bool  mIsWatchingFile;
 
   // nsIDOMDeviceStorage.type
   enum {
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -29,16 +29,17 @@
 #include "nsXULAppAPI.h"
 #include "TabChild.h"
 #include "DeviceStorageRequestChild.h"
 #include "nsIDOMDeviceStorageChangeEvent.h"
 #include "nsCRT.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "GeneratedEvents.h"
+#include "mozilla/dom/PermissionMessageUtils.h"
 
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsIVolumeService.h"
 #endif
 
@@ -631,42 +632,42 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDeviceStorageCursor)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceStorageCursor)
 NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
 NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
 
 nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
-                                                   nsIURI* aURI,
+                                                   nsIPrincipal* aPrincipal,
                                                    DeviceStorageFile* aFile,
                                                    PRUint64 aSince)
   : DOMRequest(aWindow)
   , mOkToCallContinue(false)
   , mSince(aSince)
   , mFile(aFile)
-  , mURI(aURI)
+  , mPrincipal(aPrincipal)
 {
 }
 
 nsDOMDeviceStorageCursor::~nsDOMDeviceStorageCursor()
 {
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorageCursor::GetType(nsACString & aType)
 {
   aType = "device-storage";
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMDeviceStorageCursor::GetUri(nsIURI * *aRequestingURI)
+nsDOMDeviceStorageCursor::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
 {
-  NS_IF_ADDREF(*aRequestingURI = mURI);
+  NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorageCursor::GetWindow(nsIDOMWindow * *aRequestingWindow)
 {
   NS_IF_ADDREF(*aRequestingWindow = GetOwner());
   return NS_OK;
@@ -932,38 +933,38 @@ public:
         DEVICE_STORAGE_REQUEST_READ,
         DEVICE_STORAGE_REQUEST_WRITE,
         DEVICE_STORAGE_REQUEST_DELETE,
         DEVICE_STORAGE_REQUEST_WATCH
     };
 
     DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
                          nsPIDOMWindow *aWindow,
-                         nsIURI *aURI,
+                         nsIPrincipal *aPrincipal,
                          DeviceStorageFile *aFile,
                          DOMRequest* aRequest,
                          nsDOMDeviceStorage *aDeviceStorage,
                          nsIDOMEventListener *aListener)
       : mRequestType(aRequestType)
       , mWindow(aWindow)
-      , mURI(aURI)
+      , mPrincipal(aPrincipal)
       , mFile(aFile)
       , mRequest(aRequest)
       , mDeviceStorage(aDeviceStorage)
-      , mListener(aListener) {}  
+      , mListener(aListener) {}
 
     DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
                          nsPIDOMWindow *aWindow,
-                         nsIURI *aURI,
+                         nsIPrincipal *aPrincipal,
                          DeviceStorageFile *aFile,
                          DOMRequest* aRequest,
                          nsIDOMBlob *aBlob = nullptr)
       : mRequestType(aRequestType)
       , mWindow(aWindow)
-      , mURI(aURI)
+      , mPrincipal(aPrincipal)
       , mFile(aFile)
       , mRequest(aRequest)
       , mBlob(aBlob) {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest, nsIContentPermissionRequest)
 
   NS_IMETHOD Run() {
@@ -982,17 +983,17 @@ public:
         return NS_OK;
       }
 
       // Retain a reference so the object isn't deleted without IPDL's knowledge.
       // Corresponding release occurs in DeallocPContentPermissionRequest.
       AddRef();
 
       nsCString type = NS_LITERAL_CSTRING("device-storage");
-      child->SendPContentPermissionRequestConstructor(this, type, IPC::URI(mURI));
+      child->SendPContentPermissionRequestConstructor(this, type, IPC::Principal(mPrincipal));
 
       Sendprompt();
       return NS_OK;
     }
 
     nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
     if (prompt) {
       prompt->Prompt(this);
@@ -1001,19 +1002,19 @@ public:
   }
 
   NS_IMETHOD GetType(nsACString & aType)
   {
     aType = "device-storage";
     return NS_OK;
   }
 
-  NS_IMETHOD GetUri(nsIURI * *aRequestingURI)
+  NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
   {
-    NS_IF_ADDREF(*aRequestingURI = mURI);
+    NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
     return NS_OK;
   }
 
   NS_IMETHOD GetWindow(nsIDOMWindow * *aRequestingWindow)
   {
     NS_IF_ADDREF(*aRequestingWindow = mWindow);
     return NS_OK;
   }
@@ -1148,17 +1149,17 @@ public:
   void IPDLRelease()
   {
     Release();
   }
 
 private:
   PRInt32 mRequestType;
   nsCOMPtr<nsPIDOMWindow> mWindow;
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
   nsRefPtr<DeviceStorageFile> mFile;
 
   nsRefPtr<DOMRequest> mRequest;
   nsCOMPtr<nsIDOMBlob> mBlob;
   nsRefPtr<nsDOMDeviceStorage> mDeviceStorage;
   nsCOMPtr<nsIDOMEventListener> mListener;
 };
 
@@ -1221,24 +1222,24 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* 
 
   SetRootFileForType(aType);
   if (!mFile) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   BindToOwner(aWindow);
 
-  // Grab the uri of the document
+  // Grab the principal of the document
   nsCOMPtr<nsIDOMDocument> domdoc;
   aWindow->GetDocument(getter_AddRefs(domdoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
-  doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
+  mPrincipal = doc->NodePrincipal();
   return NS_OK;
 }
 
 nsDOMDeviceStorage::~nsDOMDeviceStorage()
 {
 }
 
 void
@@ -1306,17 +1307,17 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob 
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, aPath);
 
   if (!dsf->IsSafePath()) {
     r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
   }
   else {
     r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE,
-                                 win, mURI, dsf, request, aBlob);
+                                 win, mPrincipal, dsf, request, aBlob);
   }
   NS_DispatchToMainThread(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorage::Get(const JS::Value & aPath,
                         JSContext* aCx,
@@ -1362,17 +1363,17 @@ nsDOMDeviceStorage::GetInternal(const JS
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
   dsf->SetEditable(aEditable);
 
   if (!dsf->IsSafePath()) {
     r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
   } else {
     r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ,
-                                 win, mURI, dsf, request);
+                                 win, mPrincipal, dsf, request);
   }
   NS_DispatchToMainThread(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMRequest * *_retval)
 {
@@ -1397,17 +1398,17 @@ nsDOMDeviceStorage::Delete(const JS::Val
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
 
   if (!dsf->IsSafePath()) {
     r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
   }
   else {
     r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE,
-                                 win, mURI, dsf, request);
+                                 win, mPrincipal, dsf, request);
   }
   NS_DispatchToMainThread(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorage::Enumerate(const JS::Value & aName,
                              const JS::Value & aOptions,
@@ -1480,17 +1481,18 @@ nsDOMDeviceStorage::EnumerateInternal(co
       return NS_ERROR_FAILURE;
     }
     since = ExtractDateFromOptions(aCx, aOptions);
   }
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
   dsf->SetEditable(aEditable);
 
-  nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, since);
+  nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mPrincipal,
+                                                                           dsf, since);
   nsRefPtr<DeviceStorageCursorRequest> r = new DeviceStorageCursorRequest(cursor);
 
   NS_ADDREF(*aRetval = cursor);
 
   if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
     r->Allow();
     return NS_OK;
   }
@@ -1502,17 +1504,17 @@ nsDOMDeviceStorage::EnumerateInternal(co
     if (!child)
       return NS_OK;
 
     // Retain a reference so the object isn't deleted without IPDL's knowledge.
     // Corresponding release occurs in DeallocPContentPermissionRequest.
     r->AddRef();
 
     nsCString type = NS_LITERAL_CSTRING("device-storage");
-    child->SendPContentPermissionRequestConstructor(r, type, IPC::URI(mURI));
+    child->SendPContentPermissionRequestConstructor(r, type, IPC::Principal(mPrincipal));
 
     r->Sendprompt();
 
     return NS_OK;
   }
 
   nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
   if (prompt) {
@@ -1608,17 +1610,17 @@ nsDOMDeviceStorage::AddEventListener(con
   nsCOMPtr<nsPIDOMWindow> win = GetOwner();
   if (!win) {
     return NS_ERROR_UNEXPECTED;
   }
 
   nsRefPtr<DOMRequest> request = new DOMRequest(win);
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile);
   nsCOMPtr<nsIRunnable> r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WATCH,
-                                                     win, mURI, dsf, request, this, aListener);
+                                                     win, mPrincipal, dsf, request, this, aListener);
   NS_DispatchToMainThread(r);
   return nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted, aArgc);
 }
 
 NS_IMETHODIMP
 nsDOMDeviceStorage::AddSystemEventListener(const nsAString & aType,
                                            nsIDOMEventListener *aListener,
                                            bool aUseCapture,
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -13,16 +13,17 @@ class nsPIDOMWindow;
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsIDOMDeviceStorageCursor.h"
 #include "nsIDOMWindow.h"
 #include "nsIURI.h"
 #include "nsInterfaceHashtable.h"
+#include "nsIPrincipal.h"
 #include "nsString.h"
 #include "nsWeakPtr.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIObserver.h"
 #include "mozilla/Mutex.h"
 #include "DeviceStorage.h"
 
@@ -81,33 +82,33 @@ class nsDOMDeviceStorageCursor MOZ_FINAL
   , public PCOMContentPermissionRequestChild
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSICONTENTPERMISSIONREQUEST
   NS_DECL_NSIDOMDEVICESTORAGECURSOR
 
   nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
-                           nsIURI* aURI,
+                           nsIPrincipal* aPrincipal,
                            DeviceStorageFile* aFile,
                            PRUint64 aSince);
 
 
   nsTArray<nsRefPtr<DeviceStorageFile> > mFiles;
   bool mOkToCallContinue;
   PRUint64 mSince;
 
   virtual bool Recv__delete__(const bool& allow);
   virtual void IPDLRelease();
 
 private:
   ~nsDOMDeviceStorageCursor();
 
   nsRefPtr<DeviceStorageFile> mFile;
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 //helpers
 jsval StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString);
 jsval nsIFileToJsval(nsPIDOMWindow* aWindow, DeviceStorageFile* aFile, bool aEditable);
 jsval BlobToJsval(nsPIDOMWindow* aWindow, nsIDOMBlob* aBlob);
 
 
--- a/dom/interfaces/base/nsIContentPermissionPrompt.idl
+++ b/dom/interfaces/base/nsIContentPermissionPrompt.idl
@@ -1,36 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIURI;
+interface nsIPrincipal;
 interface nsIDOMWindow;
 interface nsIDOMElement;
 
 /**
  * Interface allows access to a content to request
  * permission to perform a privileged operation such as
  * geolocation.
  */
-[scriptable, uuid(E79C7063-DBAB-45E3-8A98-D0142E1ABC9A)]
+[scriptable, uuid(E1F3796C-ADFA-414B-B2A7-AC62F29395EE)]
 interface nsIContentPermissionRequest : nsISupports {
 
   /**
    *  The type of the permission request, such as
    *  "geolocation".
    */
   readonly attribute ACString type;
 
   /**
-   *  The uri of the permission request.
+   *  The principal of the permission request.
    */
-  readonly attribute nsIURI uri;
+  readonly attribute nsIPrincipal principal;
 
   /**
    *  The window or element that the permission request was
    *  originated in.  Typically the element will be non-null
    *  in when using out of process content.  window or
    *  element can be null but not both.
    */
   readonly attribute nsIDOMWindow window;
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -28,16 +28,17 @@ EXPORTS_NAMESPACES = \
   $(NULL)
 
 EXPORTS_mozilla/dom = \
   ContentChild.h \
   ContentParent.h \
   ContentProcess.h \
   CrashReporterChild.h \
   CrashReporterParent.h \
+  PermissionMessageUtils.h \
   StructuredCloneUtils.h \
   TabParent.h \
   TabChild.h \
   TabMessageUtils.h \
   $(NULL)
 
 EXPORTS_mozilla/dom/ipc = \
   Blob.h \
@@ -47,16 +48,17 @@ EXPORTS_mozilla/dom/ipc = \
 
 CPPSRCS = \
   Blob.cpp \
   ContentProcess.cpp \
   ContentParent.cpp \
   ContentChild.cpp \
   CrashReporterParent.cpp \
   CrashReporterChild.cpp \
+  PermissionMessageUtils.cpp \
   ProcessPriorityManager.cpp \
   StructuredCloneUtils.cpp \
   TabParent.cpp \
   TabChild.cpp \
   TabMessageUtils.cpp \
   $(NULL)
 
 ifdef MOZ_SYDNEYAUDIO
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -12,22 +12,24 @@ include protocol PDocumentRenderer;
 include protocol PContentPermissionRequest;
 include protocol PRenderFrame;
 include protocol POfflineCacheUpdate;
 include protocol PIndexedDB;
 
 include "gfxMatrix.h";
 include "IPC/nsGUIEventIPC.h";
 include "mozilla/dom/TabMessageUtils.h";
+include "mozilla/dom/PermissionMessageUtils.h";
 include "mozilla/layout/RenderFrameUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
 
 include DOMTypes;
 
 using IPC::URI;
+using IPC::Principal;
 using gfxMatrix;
 using gfxSize;
 using mozilla::layers::LayersBackend;
 using mozilla::layout::ScrollingBehavior;
 using mozilla::WindowsHandle;
 using nscolor;
 using nsCompositionEvent;
 using nsIMEUpdatePreference;
@@ -169,17 +171,30 @@ parent:
     /**
      * Return native data of root widget
      */
     sync GetWidgetNativeData() returns (WindowsHandle value);
 
     SetCursor(PRUint32 value);
     SetBackgroundColor(nscolor color);
 
-    PContentPermissionRequest(nsCString aType, URI uri);
+    /**
+     * Initiates an asynchronous request for permission for the
+     * provided principal.
+     *
+     * @param aType
+     *   The type of permission to request.
+     * @param aPrincipal
+     *   The principal of the request.
+     *
+     * NOTE: The principal is untrusted in the parent process. Only
+     *       principals that can live in the content process should
+     *       provided.
+     */
+    PContentPermissionRequest(nsCString aType, Principal principal);
 
     PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
                    PRInt32[] aIntParams, nsString[] aStringParams);
 
     /**
      * Create a layout frame (encapsulating a remote layer tree) for
      * the page that is currently loaded in the <browser>.
      */
@@ -337,9 +352,9 @@ state LIVE:
 state DYING:
     discard send blah;
 // etc.
     recv __delete__;
  */
 };
 
 }
-}
\ No newline at end of file
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PermissionMessageUtils.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/PermissionMessageUtils.h"
+#include "nsISerializable.h"
+#include "nsSerializationHelper.h"
+
+namespace IPC {
+
+void
+ParamTraits<Principal>::Write(Message* aMsg, const paramType& aParam) {
+  bool isNull = !aParam.mPrincipal;
+  WriteParam(aMsg, isNull);
+  if (isNull) {
+    return;
+  }
+
+  bool isSerialized = false;
+  nsCString principalString;
+  nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aParam.mPrincipal);
+  if (serializable) {
+    nsresult rv = NS_SerializeToString(serializable, principalString);
+    if (NS_SUCCEEDED(rv)) {
+      isSerialized = true;
+    }
+  }
+
+  if (!isSerialized) {
+    NS_RUNTIMEABORT("Unable to serialize principal.");
+    return;
+  }
+
+  WriteParam(aMsg, principalString);
+}
+
+bool
+ParamTraits<Principal>::Read(const Message* aMsg, void** aIter, paramType* aResult)
+{
+  bool isNull;
+  if (!ReadParam(aMsg, aIter, &isNull)) {
+    return false;
+  }
+
+  if (isNull) {
+    aResult->mPrincipal = nullptr;
+    return true;
+  }
+
+  nsCString principalString;
+  if (!ReadParam(aMsg, aIter, &principalString)) {
+    return false;
+  }
+
+  nsCOMPtr<nsISupports> iSupports;
+  nsresult rv = NS_DeserializeObject(principalString, getter_AddRefs(iSupports));
+  NS_ENSURE_SUCCESS(rv, false);
+
+  nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(iSupports);
+  NS_ENSURE_TRUE(principal, false);
+
+  principal.swap(aResult->mPrincipal);
+  return true;
+}
+
+} // namespace IPC
+
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PermissionMessageUtils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_permission_message_utils_h__
+#define mozilla_dom_permission_message_utils_h__
+
+#include "IPC/IPCMessageUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIPrincipal.h"
+
+namespace IPC {
+
+class Principal {
+  friend struct ParamTraits<Principal>;
+
+public:
+  Principal() : mPrincipal(nsnull) {}
+  Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {}
+  operator nsIPrincipal*() const { return mPrincipal.get(); }
+
+private:
+  // Unimplemented
+  Principal& operator=(Principal&);
+  nsCOMPtr<nsIPrincipal> mPrincipal;
+};
+
+template <>
+struct ParamTraits<Principal>
+{
+  typedef Principal paramType;
+  static void Write(Message* aMsg, const paramType& aParam);
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
+};
+
+} // namespace IPC
+
+#endif // mozilla_dom_permission_message_utils_h__
+
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -914,17 +914,17 @@ TabChild::AllocPContentDialog(const PRUi
 bool
 TabChild::DeallocPContentDialog(PContentDialogChild* aDialog)
 {
   delete aDialog;
   return true;
 }
 
 PContentPermissionRequestChild*
-TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI&)
+TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal&)
 {
   NS_RUNTIMEABORT("unused");
   return nullptr;
 }
 
 bool
 TabChild::DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor)
 {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -225,26 +225,26 @@ public:
                                InfallibleTArray<nsString>& aStringParams);
     static void ArraysToParams(const InfallibleTArray<int>& aIntParams,
                                const InfallibleTArray<nsString>& aStringParams,
                                nsIDialogParamBlock* aParams);
 
 #ifdef DEBUG
     virtual PContentPermissionRequestChild* SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
                                                                                      const nsCString& aType,
-                                                                                     const URI& aUri)
+                                                                                     const IPC::Principal& aPrincipal)
     {
       PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
-      PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aUri);
+      PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aPrincipal);
       child->mIPCOpen = true;
       return request;
     }
 #endif /* DEBUG */
 
-    virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
+    virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
 
     virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI,
             const URI& documentURI,
             const nsCString& clientID,
             const bool& stickDocument);
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);
 
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -287,21 +287,21 @@ TabParent::AllocPDocumentRenderer(const 
 bool
 TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor)
 {
     delete actor;
     return true;
 }
 
 PContentPermissionRequestParent*
-TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::URI& uri)
+TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::Principal& principal)
 {
-  return new ContentPermissionRequestParent(type, mFrameElement, uri);
+  return new ContentPermissionRequestParent(type, mFrameElement, principal);
 }
-  
+
 bool
 TabParent::DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor)
 {
   delete actor;
   return true;
 }
 
 void
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -142,17 +142,18 @@ public:
 
     virtual PDocumentRendererParent*
     AllocPDocumentRenderer(const nsRect& documentRect, const gfxMatrix& transform,
                            const nsString& bgcolor,
                            const PRUint32& renderFlags, const bool& flushLayout,
                            const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
 
-    virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
+    virtual PContentPermissionRequestParent*
+    AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
 
     virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
             const URI& aManifestURI,
             const URI& aDocumentURI,
             const nsCString& aClientID,
             const bool& stickDocument);
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateParent* actor);
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -275,22 +275,22 @@ nsGeolocationRequest::Notify(nsITimer* a
   mLocator->RemoveRequest(this);
   NotifyError(nsIDOMGeoPositionError::TIMEOUT);
 
   mTimeoutTimer = nullptr;
   return NS_OK;
 }
  
 NS_IMETHODIMP
-nsGeolocationRequest::GetUri(nsIURI * *aRequestingURI)
+nsGeolocationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
 {
-  NS_ENSURE_ARG_POINTER(aRequestingURI);
+  NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
 
-  nsCOMPtr<nsIURI> uri = mLocator->GetURI();
-  uri.forget(aRequestingURI);
+  nsCOMPtr<nsIPrincipal> principal = mLocator->GetPrincipal();
+  principal.forget(aRequestingPrincipal);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::GetType(nsACString & aType)
 {
   aType = "geolocation";
@@ -900,33 +900,29 @@ nsGeolocation::Init(nsIDOMWindow* aConte
       return NS_ERROR_FAILURE;
     }
 
     mOwner = do_GetWeakReference(window->GetCurrentInnerWindow());
     if (!mOwner) {
       return NS_ERROR_FAILURE;
     }
 
-    // Grab the uri of the document
+    // Grab the principal of the document
     nsCOMPtr<nsIDOMDocument> domdoc;
     aContentDom->GetDocument(getter_AddRefs(domdoc));
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
     if (!doc) {
       return NS_ERROR_FAILURE;
     }
 
-    doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
-    
-    if (!mURI) {
-      return NS_ERROR_FAILURE;
-    }
+    mPrincipal = doc->NodePrincipal();
   }
 
   // If no aContentDom was passed into us, we are being used
-  // by chrome/c++ and have no mOwner, no mURI, and no need
+  // by chrome/c++ and have no mOwner, no mPrincipal, and no need
   // to prompt.
   mService = nsGeolocationService::GetInstance();
   if (mService) {
     mService->AddLocator(this);
   }
   return NS_OK;
 }
 
@@ -942,17 +938,17 @@ nsGeolocation::Shutdown()
     mWatchingCallbacks[i]->Shutdown();
   mWatchingCallbacks.Clear();
 
   if (mService) {
     mService->RemoveLocator(this);
   }
 
   mService = nullptr;
-  mURI = nullptr;
+  mPrincipal = nullptr;
 }
 
 bool
 nsGeolocation::HasActiveCallbacks()
 {
   for (PRUint32 i = 0; i < mWatchingCallbacks.Length(); i++) {
     if (mWatchingCallbacks[i]->IsActive()) {
       return true;
@@ -1169,18 +1165,18 @@ nsGeolocation::RegisterRequestWithPrompt
       return false;
     }
 
     // Retain a reference so the object isn't deleted without IPDL's knowledge.
     // Corresponding release occurs in DeallocPContentPermissionRequest.
     request->AddRef();
 
     nsCString type = NS_LITERAL_CSTRING("geolocation");
-    child->SendPContentPermissionRequestConstructor(request, type, IPC::URI(mURI));
-    
+    child->SendPContentPermissionRequestConstructor(request, type, IPC::Principal(mPrincipal));
+
     request->Sendprompt();
     return true;
   }
 
   nsCOMPtr<nsIRunnable> ev  = new RequestPromptEvent(request);
   NS_DispatchToMainThread(ev);
   return true;
 }
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -176,18 +176,18 @@ public:
   bool HasActiveCallbacks();
 
   // Remove request from all callbacks arrays
   void RemoveRequest(nsGeolocationRequest* request);
 
   // Shutting down.
   void Shutdown();
 
-  // Getter for the URI that this nsGeolocation was loaded from
-  nsIURI* GetURI() { return mURI; }
+  // Getter for the principal that this nsGeolocation was loaded from
+  nsIPrincipal* GetPrincipal() { return mPrincipal; }
 
   // Getter for the window that this nsGeolocation is owned by
   nsIWeakReference* GetOwner() { return mOwner; }
 
   // Check to see if the widnow still exists
   bool WindowOwnerStillExists();
 
 private:
@@ -203,15 +203,15 @@ private:
 
   nsTArray<nsRefPtr<nsGeolocationRequest> > mPendingCallbacks;
   nsTArray<nsRefPtr<nsGeolocationRequest> > mWatchingCallbacks;
 
   // window that this was created for.  Weak reference.
   nsWeakPtr mOwner;
 
   // where the content was loaded from
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 
   // owning back pointer.
   nsRefPtr<nsGeolocationService> mService;
 };
 
 #endif /* nsGeoLocation_h */
--- a/dom/src/notification/nsDesktopNotification.cpp
+++ b/dom/src/notification/nsDesktopNotification.cpp
@@ -62,21 +62,21 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEve
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
 
 nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
                                                    const nsAString & description,
                                                    const nsAString & iconURL,
                                                    nsPIDOMWindow *aWindow,
-                                                   nsIURI* uri)
+                                                   nsIPrincipal* principal)
   : mTitle(title)
   , mDescription(description)
   , mIconURL(iconURL)
-  , mURI(uri)
+  , mPrincipal(principal)
   , mAllow(false)
   , mShowHasBeenCalled(false)
 {
   BindToOwner(aWindow);
   if (Preferences::GetBool("notification.disabled", false)) {
     return;
   }
 
@@ -97,24 +97,24 @@ nsDOMDesktopNotification::nsDOMDesktopNo
     // bail.  The user will not see a notification, and that
     // is fine.
     if (!GetOwner())
       return;
 
     // because owner implements nsITabChild, we can assume that it is
     // the one and only TabChild for this docshell.
     TabChild* child = GetTabChildFrom(GetOwner()->GetDocShell());
-    
+
     // Retain a reference so the object isn't deleted without IPDL's knowledge.
     // Corresponding release occurs in DeallocPContentPermissionRequest.
     nsRefPtr<nsDesktopNotificationRequest> copy = request;
 
     nsCString type = NS_LITERAL_CSTRING("desktop-notification");
-    child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::URI(mURI));
-    
+    child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::Principal(mPrincipal));
+
     request->Sendprompt();
     return;
   }
 
   // otherwise, dispatch it
   NS_DispatchToMainThread(request);
 
 }
@@ -227,37 +227,37 @@ nsDesktopNotificationCenter::CreateNotif
                                                 const nsAString & iconURL,
                                                 nsIDOMDesktopNotification **aResult)
 {
   NS_ENSURE_STATE(mOwner);
   nsRefPtr<nsIDOMDesktopNotification> notification = new nsDOMDesktopNotification(title, 
                                                                                   description,
                                                                                   iconURL,
                                                                                   mOwner,
-                                                                                  mURI);
+                                                                                  mPrincipal);
   notification.forget(aResult);
   return NS_OK;
 }
 
 
 /* ------------------------------------------------------------------------ */
 /* nsDesktopNotificationRequest                                             */
 /* ------------------------------------------------------------------------ */
 
 NS_IMPL_ISUPPORTS2(nsDesktopNotificationRequest,
                    nsIContentPermissionRequest,
                    nsIRunnable)
 
 NS_IMETHODIMP
-nsDesktopNotificationRequest::GetUri(nsIURI * *aRequestingURI)
+nsDesktopNotificationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
 {
   if (!mDesktopNotification)
     return NS_ERROR_NOT_INITIALIZED;
 
-  NS_IF_ADDREF(*aRequestingURI = mDesktopNotification->mURI);
+  NS_IF_ADDREF(*aRequestingPrincipal = mDesktopNotification->mPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDesktopNotificationRequest::GetWindow(nsIDOMWindow * *aRequestingWindow)
 {
   if (!mDesktopNotification)
     return NS_ERROR_NOT_INITIALIZED;
--- a/dom/src/notification/nsDesktopNotification.h
+++ b/dom/src/notification/nsDesktopNotification.h
@@ -43,30 +43,30 @@ public:
   nsDesktopNotificationCenter(nsPIDOMWindow *aWindow)
   {
     mOwner = aWindow;
 
     // Grab the uri of the document
     nsCOMPtr<nsIDOMDocument> domdoc;
     mOwner->GetDocument(getter_AddRefs(domdoc));
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
-    doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
+    mPrincipal = doc->NodePrincipal();
   }
 
   virtual ~nsDesktopNotificationCenter()
   {
   }
 
   void Shutdown() {
     mOwner = nullptr;
   }
 
 private:
   nsCOMPtr<nsPIDOMWindow> mOwner;
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 
 class nsDOMDesktopNotification : public nsDOMEventTargetHelper,
                                  public nsIDOMDesktopNotification
 {
   friend class nsDesktopNotificationRequest;
 
@@ -74,17 +74,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDesktopNotification,nsDOMEventTargetHelper)
   NS_DECL_NSIDOMDESKTOPNOTIFICATION
 
   nsDOMDesktopNotification(const nsAString & title,
                            const nsAString & description,
                            const nsAString & iconURL,
                            nsPIDOMWindow *aWindow,
-                           nsIURI* uri);
+                           nsIPrincipal* principal);
 
   virtual ~nsDOMDesktopNotification();
 
   /*
    * PostDesktopNotification
    * Uses alert service to display a notification
    */
   void PostDesktopNotification();
@@ -103,17 +103,17 @@ protected:
   nsString mTitle;
   nsString mDescription;
   nsString mIconURL;
 
   nsRefPtr<nsDOMEventListenerWrapper> mOnClickCallback;
   nsRefPtr<nsDOMEventListenerWrapper> mOnCloseCallback;
 
   nsRefPtr<AlertServiceObserver> mObserver;
-  nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
   bool mAllow;
   bool mShowHasBeenCalled;
 };
 
 /*
  * Simple Request
  */
 class nsDesktopNotificationRequest : public nsIContentPermissionRequest,
--- a/mobile/android/components/ContentPermissionPrompt.js
+++ b/mobile/android/components/ContentPermissionPrompt.js
@@ -16,17 +16,17 @@ const kEntities = { "geolocation": "geol
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
   classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
 
   handleExistingPermission: function handleExistingPermission(request) {
-    let result = Services.perms.testExactPermission(request.uri, request.type);
+    let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return true;
     }
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return true;
     }
@@ -65,37 +65,37 @@ ContentPermissionPrompt.prototype = {
     let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
     let entityName = kEntities[request.type];
 
     let buttons = [{
       label: browserBundle.GetStringFromName(entityName + ".allow"),
       callback: function(aChecked) {
         // If the user checked "Don't ask again", make a permanent exception
         if (aChecked)
-          Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
+          Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
 
         request.allow();
       }
     },
     {
       label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
       callback: function(aChecked) {
         // If the user checked "Don't ask again", make a permanent exception
         if (aChecked)
-          Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.DENY_ACTION);
+          Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.DENY_ACTION);
 
         request.cancel();
       }
     }];
 
     let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
-                                                     [request.uri.host], 1);
+                                                     [request.principal.URI.host], 1);
     let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") };
 
     chromeWin.NativeWindow.doorhanger.show(message,
-                                           entityName + request.uri.host,
+                                           entityName + request.principal.URI.host,
                                            buttons, tab.id, options);
   }
 };
 
 
 //module initialization
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
--- a/mobile/xul/chrome/content/IndexedDB.js
+++ b/mobile/xul/chrome/content/IndexedDB.js
@@ -56,17 +56,17 @@ let IndexedDB = {
       if (timeoutId === null) return true;
       clearTimeout(timeoutId);
       timeoutId = null;
       return false;
     }
 
     prompt.prompt({
       type: type,
-      uri: Services.io.newURI(payload.location, null, null),
+      principal: browser.contentPrincipal,
       window: null,
       element: aMessage.target,
 
       cancel: function() {
         if (checkTimeout()) return;
         payload.permission = Ci.nsIPermissionManager.DENY_ACTION;
         browser.messageManager.sendAsyncMessage("IndexedDB:Response", payload);
       },
--- a/mobile/xul/chrome/content/WebappsUI.js
+++ b/mobile/xul/chrome/content/WebappsUI.js
@@ -59,41 +59,42 @@ var WebappsUI = {
 
     let root = baseURI.resolve("/").toString();
     app.appURI = root.substring(0, root.length - 1);
 
     return app;
   },
 
   askPermission: function(aMessage, aType, aCallbacks) {
-    let uri = Services.io.newURI(aMessage.json.from, null, null);
-    let perm = Services.perms.testExactPermission(uri, aType);
+    let browser = aMessage.target;
+    let principal = browser.contentPrincipal;
+    let perm = Services.perms.testExactPermissionFromPrincipal(principal, aType);
     switch(perm) {
       case Ci.nsIPermissionManager.ALLOW_ACTION:
         aCallbacks.allow();
         return;
       case Ci.nsIPermissionManager.DENY_ACTION:
         aCallbacks.cancel();
         return;
     }
 
     let prompt = Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt);
 
     prompt.prompt({
       type: aType,
-      uri: uri,
+      principal: principal,
       window: null,
       element: getBrowser(),
 
       cancel: function() {
         aCallbacks.cancel();
       },
 
       allow: function() {
-        Services.perms.add(uri, aType, Ci.nsIPermissionManager.ALLOW_ACTION);
+        Services.perms.addFromPrincipal(principal, aType, Ci.nsIPermissionManager.ALLOW_ACTION);
         aCallbacks.allow();
       }
     });
   },
 
   receiveMessage: function(aMessage) {
     this._browser = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
     switch(aMessage.name) {
--- a/mobile/xul/components/ContentPermissionPrompt.js
+++ b/mobile/xul/components/ContentPermissionPrompt.js
@@ -6,36 +6,36 @@ const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const kCountBeforeWeRemember = 5;
 
-function setPagePermission(type, uri, allow) {
+function setPagePermission(type, principal, allow) {
   let pm = Services.perms;
   let contentPrefs = Services.contentPrefs;
   let contentPrefName = type + ".request.remember";
 
-  if (!contentPrefs.hasPref(uri, contentPrefName))
-      contentPrefs.setPref(uri, contentPrefName, 0);
+  if (!contentPrefs.hasPref(principal.URI, contentPrefName))
+      contentPrefs.setPref(principal.URI, contentPrefName, 0);
 
-  let count = contentPrefs.getPref(uri, contentPrefName);
+  let count = contentPrefs.getPref(principal.URI, contentPrefName);
 
   if (allow == false)
     count--;
   else
     count++;
-    
-  contentPrefs.setPref(uri, contentPrefName, count);
+
+  contentPrefs.setPref(principal.URI, contentPrefName, count);
   if (count == kCountBeforeWeRemember)
-    pm.add(uri, type, Ci.nsIPermissionManager.ALLOW_ACTION);
+    pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.ALLOW_ACTION);
   else if (count == -kCountBeforeWeRemember)
-    pm.add(uri, type, Ci.nsIPermissionManager.DENY_ACTION);
+    pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.DENY_ACTION);
 }
 
 const kEntities = { "geolocation": "geolocation", "desktop-notification": "desktopNotification",
                     "indexedDB": "offlineApps", "indexedDBQuota": "indexedDBQuota",
                     "openWebappsManage": "openWebappsManage" };
 
 function ContentPermissionPrompt() {}
 
@@ -65,17 +65,17 @@ ContentPermissionPrompt.prototype = {
       return chromeWin.getNotificationBox(browser);
     }
 
     let chromeWin = request.element.ownerDocument.defaultView;
     return chromeWin.Browser.getNotificationBox(request.element);
   },
 
   handleExistingPermission: function handleExistingPermission(request) {
-    let result = Services.perms.testExactPermission(request.uri, request.type);
+    let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return true;
     }
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return true;
     }
@@ -96,31 +96,31 @@ ContentPermissionPrompt.prototype = {
       return;
 
     let entityName = kEntities[request.type];
 
     let buttons = [{
       label: browserBundle.GetStringFromName(entityName + ".allow"),
       accessKey: null,
       callback: function(notification) {
-        setPagePermission(request.type, request.uri, true);
+        setPagePermission(request.type, request.principal, true);
         request.allow();
       }
     },
     {
       label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
       accessKey: null,
       callback: function(notification) {
-        setPagePermission(request.type, request.uri, false);
+        setPagePermission(request.type, request.principal, false);
         request.cancel();
       }
     }];
 
     let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
-                                                     [request.uri.host], 1);
+                                                     [request.principal.URI.host], 1);
     let newBar = notificationBox.appendNotification(message,
                                                     request.type,
                                                     "", // Notifications in Fennec do not display images.
                                                     notificationBox.PRIORITY_WARNING_MEDIUM,
                                                     buttons);
   }
 };
 
--- a/webapprt/ContentPermission.js
+++ b/webapprt/ContentPermission.js
@@ -18,17 +18,17 @@ ContentPermission.prototype = {
 
   prompt: function(request) {
     // Only handle geolocation requests for now
     if (request.type != "geolocation") {
       return;
     }
 
     // Reuse any remembered permission preferences
-    let result = Services.perms.testExactPermission(request.uri, "geo");
+    let result = Services.perms.testExactPermissionFromPrincipal(request.principal, "geo");
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return;
     }
     else if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return;
     }
@@ -68,17 +68,17 @@ ContentPermission.prototype = {
       remember);
 
     // Persist the choice if the user wants to remember
     if (remember.value) {
       let action = Ci.nsIPermissionManager.ALLOW_ACTION;
       if (choice != 0) {
         action = Ci.nsIPermissionManager.DENY_ACTION;
       }
-      Services.perms.add(request.uri, "geo", action);
+      Services.perms.addFromPrincipal(request.principal, "geo", action);
     }
 
     // Trigger the selected choice
     if (choice == 0) {
       request.allow();
     }
     else {
       request.cancel();