Bug 1238160 - Set tab context's isolation from frame attr. r=smaug
authorJ. Ryan Stinnett <jryans@gmail.com>
Wed, 17 Feb 2016 21:31:29 -0600
changeset 322809 86b3d7cbff15bf6edb96cc771036a86d5e06d436
parent 322808 267ab6361fa18937288c482612d996c7bf074d3f
child 322810 981fee6f681f8e24aa8ea37c39ab74f91c7c5ede
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1238160
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1238160 - Set tab context's isolation from frame attr. r=smaug Renames existing nsFrameLoader::OwnerIsBrowser* methods to add "Moz" prefix for clarity. Adds nsFrameLoader::OwnerIsIsolatedMozBrowserFrame which checks the noisolation attribute of mozbrowser frames, if present. This is used to set isolation in nsFrameLoader::GetNewTabContext only when true. MozReview-Commit-ID: Dz02xBoKh1P
accessible/jsat/AccessFu.jsm
b2g/chrome/content/runapp.js
b2g/components/ErrorPage.jsm
dom/base/nsFrameLoader.cpp
dom/base/nsFrameLoader.h
dom/base/nsGkAtomList.h
dom/base/nsIFrameLoader.idl
dom/html/nsBrowserElement.cpp
dom/html/nsGenericHTMLFrameElement.cpp
dom/inputmethod/Keyboard.jsm
dom/interfaces/html/nsIMozBrowserFrame.idl
dom/ipc/ProcessPriorityManager.cpp
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -339,17 +339,17 @@ this.AccessFu = { // jshint ignore:line
       case 'Accessibility:MoveByGranularity':
         this.Input.moveByGranularity(JSON.parse(aData));
         break;
       case 'remote-browser-shown':
       case 'inprocess-browser-shown':
       {
         // Ignore notifications that aren't from a BrowserOrApp
         let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
-        if (!frameLoader.ownerIsBrowserOrAppFrame) {
+        if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
           return;
         }
         this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
 
--- a/b2g/chrome/content/runapp.js
+++ b/b2g/chrome/content/runapp.js
@@ -52,17 +52,17 @@ function AppRunner(aName) {
   this._apps = [];
 }
 AppRunner.prototype = {
   observe: function(aSubject, aTopic, aData) {
     let frameLoader = aSubject;
     // get a ref to the app <iframe>
     frameLoader.QueryInterface(Ci.nsIFrameLoader);
     // Ignore notifications that aren't from a BrowserOrApp
-    if (!frameLoader.ownerIsBrowserOrAppFrame) {
+    if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
       return;
     }
 
     let frame = frameLoader.ownerElement;
     if (!frame.appManifestURL) { // Ignore all frames but app frames
       return;
     }
 
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -172,16 +172,16 @@ var ErrorPage = {
   init: function errorPageInit() {
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'remote-browser-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
     // Ignore notifications that aren't from a BrowserOrApp
-    if (!frameLoader.ownerIsBrowserOrAppFrame) {
+    if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
       return;
     }
     this._listenError(frameLoader);
   }
 };
 
 ErrorPage.init();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -417,17 +417,17 @@ nsFrameLoader::ReallyStartLoadingInterna
     }
   }
   loadInfo->SetReferrerPolicy(referrerPolicy);
 
   // Default flags:
   int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
   // Flags for browser frame:
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
             nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
   }
 
   // Kick off the load...
   bool tmpState = mNeedsAsyncDestroy;
   mNeedsAsyncDestroy = true;
   nsCOMPtr<nsIURI> uriToLoad = mURIToLoad;
@@ -1572,27 +1572,27 @@ nsFrameLoader::SetOwnerContent(Element* 
   if (RenderFrameParent* rfp = GetCurrentRenderFrame()) {
     rfp->OwnerContentChanged(aContent);
   }
 
   ResetPermissionManagerStatus();
 }
 
 bool
-nsFrameLoader::OwnerIsBrowserOrAppFrame()
+nsFrameLoader::OwnerIsMozBrowserOrAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
 }
 
 // The xpcom getter version
 NS_IMETHODIMP
-nsFrameLoader::GetOwnerIsBrowserOrAppFrame(bool* aResult)
+nsFrameLoader::GetOwnerIsMozBrowserOrAppFrame(bool* aResult)
 {
-  *aResult = OwnerIsBrowserOrAppFrame();
+  *aResult = OwnerIsMozBrowserOrAppFrame();
   return NS_OK;
 }
 
 bool
 nsFrameLoader::OwnerIsWidget()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsWidget() : false;
@@ -1610,19 +1610,29 @@ nsFrameLoader::GetOwnerIsWidget(bool* aR
 bool
 nsFrameLoader::OwnerIsAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsApp() : false;
 }
 
 bool
-nsFrameLoader::OwnerIsBrowserFrame()
+nsFrameLoader::OwnerIsMozBrowserFrame()
 {
-  return OwnerIsBrowserOrAppFrame() && !OwnerIsAppFrame();
+  return OwnerIsMozBrowserOrAppFrame() && !OwnerIsAppFrame();
+}
+
+bool
+nsFrameLoader::OwnerIsIsolatedMozBrowserFrame()
+{
+  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
+  if (!browserFrame) {
+    return false;
+  }
+  return OwnerIsMozBrowserFrame() && browserFrame->GetIsolated();
 }
 
 void
 nsFrameLoader::GetOwnerAppManifestURL(nsAString& aOut)
 {
   aOut.Truncate();
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   if (browserFrame) {
@@ -1687,25 +1697,25 @@ nsFrameLoader::ShouldUseRemoteProcess()
   if (XRE_IsContentProcess() &&
       !(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
         Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
     return false;
   }
 
   // If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
   // fall back to the default.
-  if (OwnerIsBrowserOrAppFrame() &&
+  if (OwnerIsMozBrowserOrAppFrame() &&
       !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
 
     return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
   }
 
   // Otherwise, we're remote if we have "remote=true" and we're either a
   // browser frame or a XUL element.
-  return (OwnerIsBrowserOrAppFrame() ||
+  return (OwnerIsMozBrowserOrAppFrame() ||
           mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
          mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                     nsGkAtoms::Remote,
                                     nsGkAtoms::_true,
                                     eCaseMatters);
 }
 
 bool
@@ -1878,42 +1888,42 @@ nsFrameLoader::MaybeCreateDocShell()
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     webNav->SetSessionHistory(sessionHistory);
   }
 
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
-    MOZ_ASSERT(!OwnerIsBrowserFrame());
+    MOZ_ASSERT(!OwnerIsMozBrowserFrame());
 
     nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
     MOZ_ASSERT(ownApp);
     uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (ownApp) {
       NS_ENSURE_SUCCESS(ownApp->GetLocalId(&ownAppId), NS_ERROR_FAILURE);
     }
 
     mDocShell->SetIsApp(ownAppId);
   }
 
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     // You can't be both a browser and an app frame.
     MOZ_ASSERT(!OwnerIsAppFrame());
 
     nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
     uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (containingApp) {
       NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
                         NS_ERROR_FAILURE);
     }
     mDocShell->SetIsBrowserInsideApp(containingAppId);
   }
 
-  if (OwnerIsBrowserOrAppFrame()) {
+  if (OwnerIsMozBrowserOrAppFrame()) {
     // For inproc frames, set the docshell properties.
     nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
     nsAutoString name;
     if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
       item->SetName(name);
     }
     mDocShell->SetFullscreenAllowed(
       mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
@@ -2244,17 +2254,17 @@ nsFrameLoader::TryRemoteBrowser()
 
   if (openingTab &&
       openingTab->Manager() &&
       openingTab->Manager()->IsContentParent()) {
     openerContentParent = openingTab->Manager()->AsContentParent();
   }
 
   // <iframe mozbrowser> gets to skip these checks.
-  if (!OwnerIsBrowserOrAppFrame()) {
+  if (!OwnerIsMozBrowserOrAppFrame()) {
     if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
       return false;
     }
 
     if (!mOwnerContent->IsXULElement()) {
       return false;
     }
 
@@ -2561,17 +2571,17 @@ nsFrameLoader::EnsureMessageManager()
 {
   NS_ENSURE_STATE(mOwnerContent);
 
   if (mMessageManager) {
     return NS_OK;
   }
 
   if (!mIsTopLevelContent &&
-      !OwnerIsBrowserOrAppFrame() &&
+      !OwnerIsMozBrowserOrAppFrame() &&
       !IsRemoteFrame() &&
       !(mOwnerContent->IsXULElement() &&
         mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                    nsGkAtoms::forcemessagemanager,
                                    nsGkAtoms::_true, eCaseMatters))) {
     return NS_OK;
   }
 
@@ -2667,17 +2677,17 @@ nsFrameLoader::SwapRemoteBrowser(nsITabP
   RefPtr<TabParent> newParent = TabParent::GetFrom(aTabParent);
   if (!newParent || !mRemoteBrowser) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
   if (!IsRemoteFrame()) {
     NS_WARNING("Switching from in-process to out-of-process is not supported.");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
-  if (!OwnerIsBrowserOrAppFrame()) {
+  if (!OwnerIsMozBrowserOrAppFrame()) {
     NS_WARNING("Switching process for non-mozbrowser/app frame is not supported.");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   if (newParent == mRemoteBrowser) {
     return NS_OK;
   }
 
   MaybeUpdatePrimaryTabParent(eTabParentRemoved);
@@ -2818,27 +2828,27 @@ nsFrameLoader::ResetPermissionManagerSta
 
   // Finding the new app Id:
   // . first we check if the owner is an app frame
   // . second, we check if the owner is a browser frame
   // in both cases we populate the appId variable.
   uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
-    MOZ_ASSERT(!OwnerIsBrowserFrame());
+    MOZ_ASSERT(!OwnerIsMozBrowserFrame());
 
     nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
     MOZ_ASSERT(ownApp);
     uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (ownApp && NS_SUCCEEDED(ownApp->GetLocalId(&ownAppId))) {
       appId = ownAppId;
     }
   }
 
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     // You can't be both a browser and an app frame.
     MOZ_ASSERT(!OwnerIsAppFrame());
 
     nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
     uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (containingApp && NS_SUCCEEDED(containingApp->GetLocalId(&containingAppId))) {
       appId = containingAppId;
     }
@@ -2966,17 +2976,17 @@ nsFrameLoader::GetLoadContext(nsILoadCon
   }
   loadContext.forget(aLoadContext);
   return NS_OK;
 }
 
 void
 nsFrameLoader::InitializeBrowserAPI()
 {
-  if (OwnerIsBrowserOrAppFrame()) {
+  if (OwnerIsMozBrowserOrAppFrame()) {
     if (!IsRemoteFrame()) {
       nsresult rv = EnsureMessageManager();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return;
       }
       if (mMessageManager) {
         mMessageManager->LoadFrameScript(
           NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
@@ -3061,17 +3071,17 @@ nsFrameLoader::MaybeUpdatePrimaryTabPare
 nsresult
 nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
                                 nsIURI* aURI,
                                 const nsACString& aPackageId)
 {
   nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
   nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
   DocShellOriginAttributes attrs;
-  attrs.mInIsolatedMozBrowser = OwnerIsBrowserFrame();
+  attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
 
   nsCString signedPkgOrigin;
   if (!aPackageId.IsEmpty()) {
     // Only when aPackageId is not empty would signed package origin
     // be meaningful.
     nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
   }
 
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -138,17 +138,17 @@ public:
    * Return the primary frame for our owning content, or null if it
    * can't be found.
    */
   nsIFrame* GetPrimaryFrameOfOwningContent() const
   {
     return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
   }
 
-  /** 
+  /**
    * Return the document that owns this, or null if we don't have
    * an owner.
    */
   nsIDocument* GetOwnerDoc() const
   { return mOwnerContent ? mOwnerContent->OwnerDoc() : nullptr; }
 
   PBrowserParent* GetRemoteBrowser() const;
 
@@ -189,17 +189,17 @@ public:
 
   /**
    * Stashes a detached view on the frame loader. We do this when we're
    * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
    * being reframed we'll restore the detached view when it's recreated,
    * otherwise we'll discard the old presentation and set the detached
    * subdoc view to null. aContainerDoc is the document containing the
    * the subdoc frame. This enables us to detect when the containing
-   * document has changed during reframe, so we can discard the presentation 
+   * document has changed during reframe, so we can discard the presentation
    * in that case.
    */
   void SetDetachedSubdocView(nsView* aDetachedView,
                              nsIDocument* aContainerDoc);
 
   /**
    * Retrieves the detached view and the document containing the view,
    * as set by SetDetachedSubdocView().
@@ -237,35 +237,46 @@ private:
    * Return true if the frame is a remote frame. Return false otherwise
    */
   bool IsRemoteFrame();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozbrowser> or
    * <iframe mozapp>?  (I.e., does the frame return true for
    * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
+   * <xul:browser> is not a mozbrowser or app, so this is false for that case.
    */
-  bool OwnerIsBrowserOrAppFrame();
+  bool OwnerIsMozBrowserOrAppFrame();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozwidget>?  (I.e., does the
    * frame return true for nsIMozBrowserFrame::GetReallyIsWidget()?)
    */
   bool OwnerIsWidget();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozapp>?  (I.e., does the
    * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
    */
   bool OwnerIsAppFrame();
 
   /**
    * Is this a frame loader for a bona fide <iframe mozbrowser>?
+   * <xul:browser> is not a mozbrowser, so this is false for that case.
    */
-  bool OwnerIsBrowserFrame();
+  bool OwnerIsMozBrowserFrame();
+
+  /**
+   * Is this a frame loader for an isolated <iframe mozbrowser>?
+   *
+   * By default, mozbrowser frames are isolated.  Isolation can be disabled by
+   * setting the frame's noisolation attribute.  Disabling isolation is
+   * only allowed if the containing document is chrome.
+   */
+  bool OwnerIsIsolatedMozBrowserFrame();
 
   /**
    * Get our owning element's app manifest URL, or return the empty string if
    * our owning element doesn't have an app manifest URL.
    */
   void GetOwnerAppManifestURL(nsAString& aOut);
 
   /**
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -652,16 +652,17 @@ GK_ATOM(noautohide, "noautohide")
 GK_ATOM(norolluponanchor, "norolluponanchor")
 GK_ATOM(nobr, "nobr")
 GK_ATOM(node, "node")
 GK_ATOM(nodefaultsrc, "nodefaultsrc")
 GK_ATOM(nodeSet, "node-set")
 GK_ATOM(noembed, "noembed")
 GK_ATOM(noframes, "noframes")
 GK_ATOM(nohref, "nohref")
+GK_ATOM(noisolation, "noisolation")
 GK_ATOM(nonce, "nonce")
 GK_ATOM(none, "none")
 GK_ATOM(noresize, "noresize")
 GK_ATOM(normal, "normal")
 GK_ATOM(normalizeSpace, "normalize-space")
 GK_ATOM(noscript, "noscript")
 GK_ATOM(noshade, "noshade")
 GK_ATOM(novalidate, "novalidate")
--- a/dom/base/nsIFrameLoader.idl
+++ b/dom/base/nsIFrameLoader.idl
@@ -145,17 +145,17 @@ interface nsIFrameLoader : nsISupports
    * the child content process when these events are targeted to
    * the remote browser element.
    *
    * Used primarly for input events (mouse, keyboard)
    */
   const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
 
   /**
-   * With this event mode, it's the application's responsability to 
+   * With this event mode, it's the application's responsability to
    * convert and forward events to the content process
    */
   const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
 
   attribute unsigned long eventMode;
 
   /**
    * If false, then the subdocument is not clipped to its CSS viewport, and the
@@ -191,24 +191,25 @@ interface nsIFrameLoader : nsISupports
    *
    * The notion of "visibility" here is separate from the notion of a
    * window/docshell's visibility.  This field is mostly here so that we can
    * have a notion of visibility in the parent process when frames are OOP.
    */
   [infallible] attribute boolean visible;
 
   /**
-   * Find out whether the owner content really is a browser or app frame
-   * Especially, a widget frame is regarded as an app frame.
+   * Find out whether the owner content really is a mozbrowser or app frame
+   * Especially, a widget frame is regarded as an app frame.  <xul:browser> is
+   * not considered to be a mozbrowser frame.
    */
-  readonly attribute boolean ownerIsBrowserOrAppFrame;
+  readonly attribute boolean ownerIsMozBrowserOrAppFrame;
 
   /**
    * Find out whether the owner content really is a widget. If this attribute
-   * returns true, |ownerIsBrowserOrAppFrame| must return true.
+   * returns true, |ownerIsMozBrowserOrAppFrame| must return true.
    */
   readonly attribute boolean ownerIsWidget;
 
 };
 
 %{C++
 class nsFrameLoader;
 %}
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -49,25 +49,25 @@ nsBrowserElement::IsNotWidgetOrThrow(Err
   }
   aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
   return false;
 }
 
 void
 nsBrowserElement::InitBrowserElementAPI()
 {
-  bool isBrowserOrApp;
+  bool isMozBrowserOrApp;
   nsCOMPtr<nsIFrameLoader> frameLoader = GetFrameLoader();
   NS_ENSURE_TRUE_VOID(frameLoader);
-  nsresult rv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
+  nsresult rv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
   NS_ENSURE_SUCCESS_VOID(rv);
   rv = frameLoader->GetOwnerIsWidget(&mOwnerIsWidget);
   NS_ENSURE_SUCCESS_VOID(rv);
 
-  if (!isBrowserOrApp) {
+  if (!isMozBrowserOrApp) {
     return;
   }
 
   if (!mBrowserElementAPI) {
     mBrowserElementAPI = do_CreateInstance("@mozilla.org/dom/browser-element-api;1");
     if (NS_WARN_IF(!mBrowserElementAPI)) {
       return;
     }
@@ -505,23 +505,23 @@ nsBrowserElement::GetAllowedAudioChannel
 
   // If empty, it means that this is the first call of this method.
   if (mBrowserElementAudioChannels.IsEmpty()) {
     nsCOMPtr<nsIFrameLoader> frameLoader = GetFrameLoader();
     if (NS_WARN_IF(!frameLoader)) {
       return;
     }
 
-    bool isBrowserOrApp;
-    aRv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
+    bool isMozBrowserOrApp;
+    aRv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
-    if (!isBrowserOrApp) {
+    if (!isMozBrowserOrApp) {
       return;
     }
 
     nsCOMPtr<nsIDOMElement> frameElement;
     aRv = frameLoader->GetOwnerElement(getter_AddRefs(frameElement));
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -546,16 +546,30 @@ nsGenericHTMLFrameElement::GetReallyIsWi
   GetManifestURLByType(nsGkAtoms::mozwidget, widgetManifestURL);
   bool isWidget = !widgetManifestURL.IsEmpty();
 
   *aOut = isWidget && !isApp;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
+nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
+{
+  *aOut = true;
+
+  if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
+    return NS_OK;
+  }
+
+  // Isolation is only disabled if the attribute is present
+  *aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
+  return NS_OK;
+}
+
+/* [infallible] */ NS_IMETHODIMP
 nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut)
 {
   *aOut = false;
 
   if (!nsIMozBrowserFrame::GetReallyIsApp()) {
     return NS_OK;
   }
 
@@ -700,9 +714,8 @@ nsGenericHTMLFrameElement::InitializeBro
 }
 
 void
 nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
                                             ErrorResult& aError)
 {
   aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
 }
-
--- a/dom/inputmethod/Keyboard.jsm
+++ b/dom/inputmethod/Keyboard.jsm
@@ -146,17 +146,17 @@ this.Keyboard = {
           type: 'inputmethod-contextchange',
           inputType: 'blur'
         });
 
         this.formMM = null;
       }
     } else {
       // Ignore notifications that aren't from a BrowserOrApp
-      if (!frameLoader.ownerIsBrowserOrAppFrame) {
+      if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
         return;
       }
       this.initFormsFrameScript(mm);
     }
   },
 
   initFormsFrameScript: function(mm) {
     mm.addMessageListener('Forms:Focus', this);
--- a/dom/interfaces/html/nsIMozBrowserFrame.idl
+++ b/dom/interfaces/html/nsIMozBrowserFrame.idl
@@ -39,16 +39,30 @@ interface nsIMozBrowserFrame : nsIDOMMoz
    * In order to really be a frame, this frame must really be a browser
    * frame (this requirement will go away eventually), the frame's mozwidget
    * attribute must point to the manifest of a valid app, and the src should
    * be in the |widgetPages| specified by the manifest.
    */
   [infallible] readonly attribute boolean reallyIsWidget;
 
   /**
+   * Gets whether this frame is an isolated frame.
+   *
+   * By default, browser frames are isolated, meaning they have a principal
+   * where OriginAttributes.mIsInIsolatedMozBrowser == true.  This isolates
+   * storage and other origin related items from non-browser apps, xul:browsers,
+   * etc.
+   *
+   * Isolation can be disabled by setting the frame's isolated attribute to
+   * false.  Disabling isolation is only allowed if the containing document has
+   * browser permission (or equivalent access).
+   */
+  [infallible] readonly attribute boolean isolated;
+
+  /**
    * This corresponds to the expecting-system-message attribute, which tells us
    * whether we should expect that this frame will receive a system message once
    * it starts up.
    *
    * It's the embedder's job to set this attribute on a frame.  Its presence
    * might cause us to increase the priority of the frame's process.
    */
   [infallible] readonly attribute boolean isExpectingSystemMessage;
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -864,19 +864,19 @@ ParticularProcessPriorityManager::OnRemo
   NS_ENSURE_TRUE_VOID(tp);
 
   MOZ_ASSERT(XRE_IsParentProcess());
   if (tp->Manager() != mContentParent) {
     return;
   }
 
   // Ignore notifications that aren't from a BrowserOrApp
-  bool isBrowserOrApp;
-  fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
-  if (isBrowserOrApp) {
+  bool isMozBrowserOrApp;
+  fl->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
+  if (isMozBrowserOrApp) {
     ResetPriority();
   }
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->RemoveObserver(this, "remote-browser-shown");
   }
 }