Bug 1227861 - Add OriginAttributes getter/setter into nsIDocShell. r=smaug, sicking
authorYoshi Huang <allstars.chh@mozilla.com>
Tue, 16 Feb 2016 15:04:14 +0800
changeset 322998 6588774cd85961227b6a651365512d63bf69e8b2
parent 322997 4ddd4d39a83555c786c0a49695d16295b85be1c1
child 322999 76beb311155c91ae7afd19cb8e173ec9bcf8f580
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, sicking
bugs1227861
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 1227861 - Add OriginAttributes getter/setter into nsIDocShell. r=smaug, sicking
browser/components/sessionstore/SessionHistory.jsm
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
dom/base/nsFrameLoader.cpp
dom/ipc/TabChild.cpp
mobile/android/chrome/content/browser.js
webapprt/Startup.jsm
webapprt/content/webapp.js
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -259,17 +259,19 @@ var SessionHistoryInternal = {
    * @param tabData
    *        The tabdata including all history entries.
    */
   restore: function (docShell, tabData) {
     let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
     let history = webNavigation.sessionHistory;
 
     if ("userContextId" in tabData) {
-      docShell.setUserContextId(tabData.userContextId);
+      let attrs = docShell.getOriginAttributes();
+      attrs.userContextId = tabData.userContextId;
+      docShell.setOriginAttributes(attrs);
     }
 
     if (history.count > 0) {
       history.PurgeHistory(history.count);
     }
     history.QueryInterface(Ci.nsISHistoryInternal);
 
     let idMap = { used: {} };
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -800,20 +800,18 @@ nsDocShell::nsDocShell()
 #ifdef DEBUG
   , mInEnsureScriptEnv(false)
 #endif
   , mAffectPrivateSessionLifetime(true)
   , mInvisible(false)
   , mHasLoadedNonBlankURI(false)
   , mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
   , mBlankTiming(false)
-  , mFrameType(eFrameTypeRegular)
+  , mFrameType(FRAME_TYPE_REGULAR)
   , mIsInIsolatedMozBrowser(false)
-  , mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
-  , mUserContextId(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)
   , mParentCharsetSource(0)
   , mJSRunToCompletionDepth(0)
 {
   mHistoryID = ++gDocshellIDCounter;
   if (gDocShellCount++ == 0) {
     NS_ASSERTION(sURIFixup == nullptr,
                  "Huh, sURIFixup not null in first nsDocShell ctor!");
 
@@ -4004,17 +4002,16 @@ nsDocShell::AddChild(nsIDocShellTreeItem
     childDocShell->SetUseGlobalHistory(true);
   }
 
   if (aChild->ItemType() != mItemType) {
     return NS_OK;
   }
 
   aChild->SetTreeOwner(mTreeOwner);
-  childDocShell->SetUserContextId(mUserContextId);
   childDocShell->SetIsInIsolatedMozBrowserElement(mIsInIsolatedMozBrowser);
 
   nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
   if (!childAsDocShell) {
     return NS_OK;
   }
 
   // charset, style-disabling, and zoom will be inherited in SetupNewViewer()
@@ -9546,17 +9543,17 @@ nsDocShell::JustStartedNetworkLoad()
   return mDocumentRequest && mDocumentRequest != GetCurrentDocChannel();
 }
 
 nsresult
 nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
                                         nsIPrincipal** aResult)
 {
   PrincipalOriginAttributes attrs;
-  attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aReferrer);
+  attrs.InheritFromDocShellToDoc(mOriginAttributes, aReferrer);
   nsCOMPtr<nsIPrincipal> prin =
     BasePrincipal::CreateCodebasePrincipal(aReferrer, attrs);
   prin.forget(aResult);
 
   return *aResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
@@ -13845,202 +13842,154 @@ unsigned long nsDocShell::gNumberOfDocSh
 
 NS_IMETHODIMP
 nsDocShell::GetCanExecuteScripts(bool* aResult)
 {
   *aResult = mCanExecuteScripts;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocShell::SetIsApp(uint32_t aOwnAppId)
-{
-  mOwnOrContainingAppId = aOwnAppId;
-  if (aOwnAppId != nsIScriptSecurityManager::NO_APP_ID &&
-      aOwnAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-    mFrameType = eFrameTypeApp;
-  } else {
-    mFrameType = eFrameTypeRegular;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::SetIsBrowserInsideApp(uint32_t aContainingAppId)
-{
-  mOwnOrContainingAppId = aContainingAppId;
-  mFrameType = eFrameTypeBrowser;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::SetIsSignedPackage(const nsAString& aSignedPkg)
-{
-  mSignedPkg = aSignedPkg;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::SetUserContextId(uint32_t aUserContextId)
-{
-  mUserContextId = aUserContextId;
-
-  nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
-  while (iter.HasMore()) {
-    nsCOMPtr<nsIDocShell> docshell = do_QueryObject(iter.GetNext());
-    if (!docshell || docshell->ItemType() != ItemType()) {
-      continue;
-    }
-
-    docshell->SetUserContextId(aUserContextId);
-  }
-
+/* [infallible] */ NS_IMETHODIMP
+nsDocShell::SetFrameType(uint32_t aFrameType)
+{
+  mFrameType = aFrameType;
+  return NS_OK;
+}
+
+/* [infallible] */ NS_IMETHODIMP
+nsDocShell::GetFrameType(uint32_t* aFrameType)
+{
+  *aFrameType = mFrameType;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetIsApp(bool* aIsApp)
 {
-  *aIsApp = (mFrameType == eFrameTypeApp);
+  *aIsApp = (mFrameType == FRAME_TYPE_APP);
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetIsMozBrowserOrApp(bool* aIsMozBrowserOrApp)
 {
-  switch (mFrameType) {
-    case eFrameTypeRegular:
-      *aIsMozBrowserOrApp = false;
-      break;
-    case eFrameTypeBrowser:
-    case eFrameTypeApp:
-      *aIsMozBrowserOrApp = true;
-      break;
-  }
-
-  return NS_OK;
-}
-
-nsDocShell::FrameType
+  *aIsMozBrowserOrApp = (mFrameType != FRAME_TYPE_REGULAR);
+  return NS_OK;
+}
+
+uint32_t
 nsDocShell::GetInheritedFrameType()
 {
-  if (mFrameType != eFrameTypeRegular) {
+  if (mFrameType != FRAME_TYPE_REGULAR) {
     return mFrameType;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
   GetSameTypeParent(getter_AddRefs(parentAsItem));
 
   nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
   if (!parent) {
-    return eFrameTypeRegular;
+    return FRAME_TYPE_REGULAR;
   }
 
   return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
 {
-  bool result = mFrameType == eFrameTypeBrowser && mIsInIsolatedMozBrowser;
+  bool result = mFrameType == FRAME_TYPE_BROWSER && mIsInIsolatedMozBrowser;
   *aIsIsolatedMozBrowserElement = result;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
 {
   MOZ_ASSERT(!mIsInIsolatedMozBrowser ||
-             (GetInheritedFrameType() == eFrameTypeBrowser),
+             (GetInheritedFrameType() == FRAME_TYPE_BROWSER),
              "Isolated mozbrowser should only be true inside browser frames");
-  bool result = (GetInheritedFrameType() == eFrameTypeBrowser) &&
+  bool result = (GetInheritedFrameType() == FRAME_TYPE_BROWSER) &&
                 mIsInIsolatedMozBrowser;
   *aIsInIsolatedMozBrowserElement = result;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::SetIsInIsolatedMozBrowserElement(bool aIsInIsolatedMozBrowserElement)
 {
   mIsInIsolatedMozBrowser = aIsInIsolatedMozBrowserElement;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetIsInMozBrowserOrApp(bool* aIsInMozBrowserOrApp)
 {
-  switch (GetInheritedFrameType()) {
-    case eFrameTypeRegular:
-      *aIsInMozBrowserOrApp = false;
-      break;
-    case eFrameTypeBrowser:
-    case eFrameTypeApp:
-      *aIsInMozBrowserOrApp = true;
-      break;
-  }
-
+  *aIsInMozBrowserOrApp = (GetInheritedFrameType() != FRAME_TYPE_REGULAR);
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsDocShell::GetAppId(uint32_t* aAppId)
 {
-  if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-    *aAppId = mOwnOrContainingAppId;
+  if (mOriginAttributes.mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+    *aAppId = mOriginAttributes.mAppId;
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocShell> parent;
   GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));
 
   if (!parent) {
     *aAppId = nsIScriptSecurityManager::NO_APP_ID;
     return NS_OK;
   }
 
   return parent->GetAppId(aAppId);
 }
 
-DocShellOriginAttributes
-nsDocShell::GetOriginAttributes()
-{
-  DocShellOriginAttributes attrs;
-  RefPtr<nsDocShell> parent = GetParentDocshell();
-  if (parent) {
-    nsCOMPtr<nsIPrincipal> parentPrin = parent->GetDocument()->NodePrincipal();
-    PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
-    attrs.InheritFromDocToChildDocShell(poa);
-  } else {
-    // This is the topmost docshell, so we get the mSignedPkg attribute if it is
-    // set before.
-    attrs.mSignedPkg = mSignedPkg;
-  }
-
-  if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-    attrs.mAppId = mOwnOrContainingAppId;
-  }
-
-  attrs.mUserContextId = mUserContextId;
-  attrs.mInIsolatedMozBrowser = mIsInIsolatedMozBrowser;
-
-  return attrs;
-}
-
+// Implements nsILoadContext.originAttributes
 NS_IMETHODIMP
 nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
 {
   JSContext* cx = nsContentUtils::GetCurrentJSContext();
   MOZ_ASSERT(cx);
 
-  bool ok = ToJSValue(cx, GetOriginAttributes(), aVal);
+  return GetOriginAttributes(cx, aVal);
+}
+
+// Implements nsIDocShell.GetOriginAttributes()
+NS_IMETHODIMP
+nsDocShell::GetOriginAttributes(JSContext* aCx,
+                                JS::MutableHandle<JS::Value> aVal)
+{
+  bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
+void
+nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
+{
+  mOriginAttributes = aAttrs;
+}
+
+NS_IMETHODIMP
+nsDocShell::SetOriginAttributes(JS::Handle<JS::Value> aOriginAttributes,
+                                JSContext* aCx)
+{
+  DocShellOriginAttributes attrs;
+  if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  SetOriginAttributes(attrs);
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsDocShell::GetAppManifestURL(nsAString& aAppManifestURL)
 {
   uint32_t appId = nsIDocShell::GetAppId();
   if (appId != nsIScriptSecurityManager::NO_APP_ID &&
       appId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
     nsCOMPtr<nsIAppsService> appsService =
       do_GetService(APPS_SERVICE_CONTRACTID);
@@ -14221,17 +14170,17 @@ nsDocShell::ShouldPrepareForIntercept(ns
       if (isThirdPartyURI) {
         return NS_OK;
       }
     }
   }
 
   if (aIsNonSubresourceRequest) {
     PrincipalOriginAttributes attrs;
-    attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aURI);
+    attrs.InheritFromDocShellToDoc(mOriginAttributes, aURI);
     *aShouldIntercept = swm->IsAvailable(attrs, aURI);
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = GetDocument();
   if (!doc) {
     return NS_ERROR_NOT_AVAILABLE;
   }
@@ -14275,17 +14224,17 @@ nsDocShell::ChannelIntercepted(nsIInterc
 
   bool isReload = mLoadType & LOAD_CMD_RELOAD;
 
   nsCOMPtr<nsIURI> uri;
   rv = channel->GetURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PrincipalOriginAttributes attrs;
-  attrs.InheritFromDocShellToDoc(GetOriginAttributes(), uri);
+  attrs.InheritFromDocShellToDoc(mOriginAttributes, uri);
 
   ErrorResult error;
   swm->DispatchFetchEvent(attrs, doc, mInterceptedDocumentId, aChannel,
                           isReload, isSubresourceLoad, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -265,17 +265,23 @@ public:
   void NotifyAsyncPanZoomStopped();
 
   void SetInFrameSwap(bool aInSwap)
   {
     mInFrameSwap = aInSwap;
   }
   bool InFrameSwap();
 
-  mozilla::DocShellOriginAttributes GetOriginAttributes();
+  const mozilla::DocShellOriginAttributes&
+  GetOriginAttributes()
+  {
+    return mOriginAttributes;
+  }
+
+  void SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
 
   void GetInterceptedDocumentId(nsAString& aId)
   {
     aId = mInterceptedDocumentId;
   }
 
 private:
   // An observed docshell wrapper is created when recording markers is enabled.
@@ -759,39 +765,32 @@ public:
   };
 
 protected:
   bool JustStartedNetworkLoad();
 
   nsresult CreatePrincipalFromReferrer(nsIURI* aReferrer,
                                        nsIPrincipal** aResult);
 
-  enum FrameType
-  {
-    eFrameTypeRegular,
-    eFrameTypeBrowser,
-    eFrameTypeApp
-  };
-
-  static const nsCString FrameTypeToString(FrameType aFrameType)
+  static const nsCString FrameTypeToString(uint32_t aFrameType)
   {
     switch (aFrameType) {
-      case FrameType::eFrameTypeApp:
+      case FRAME_TYPE_APP:
         return NS_LITERAL_CSTRING("app");
-      case FrameType::eFrameTypeBrowser:
+      case FRAME_TYPE_BROWSER:
         return NS_LITERAL_CSTRING("browser");
-      case FrameType::eFrameTypeRegular:
+      case FRAME_TYPE_REGULAR:
         return NS_LITERAL_CSTRING("regular");
       default:
         NS_ERROR("Unknown frame type");
         return EmptyCString();
     }
   }
 
-  FrameType GetInheritedFrameType();
+  uint32_t GetInheritedFrameType();
 
   bool HasUnloadedParent();
 
   // Dimensions of the docshell
   nsIntRect mBounds;
   nsString mName;
   nsString mTitle;
   nsString mCustomUserAgent;
@@ -994,54 +993,38 @@ protected:
   RefPtr<nsDOMNavigationTiming> mTiming;
 
   // This flag means that mTiming has been initialized but nulled out.
   // We will check the innerWin's timing before creating a new one
   // in MaybeInitTiming()
   bool mBlankTiming;
 
   // Are we a regular frame, a browser frame, or an app frame?
-  FrameType mFrameType;
+  uint32_t mFrameType;
 
   // Whether we are in an isolated mozbrowser frame.
   bool mIsInIsolatedMozBrowser;
 
-  // We only expect mOwnOrContainingAppId to be something other than
-  // UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes
-  // inside an app, we'll retrieve the containing app-id by walking up the
-  // docshell hierarchy.
-  //
-  // (This needs to be the docshell's own /or containing/ app id because the
-  // containing app frame might be in another process, in which case we won't
-  // find it by walking up the docshell hierarchy.)
-  uint32_t mOwnOrContainingAppId;
-
-  // userContextId signifying which container we are in
-  uint32_t mUserContextId;
-
   nsString mPaymentRequestId;
 
   nsString GetInheritedPaymentRequestId();
 
-  // The packageId for a signed packaged iff this docShell is created
-  // for a signed package.
-  nsString mSignedPkg;
-
   nsString mInterceptedDocumentId;
 
 private:
   nsCString mForcedCharset;
   nsCString mParentCharset;
   int32_t mParentCharsetSource;
   nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
   nsTObserverArray<nsWeakPtr> mPrivacyObservers;
   nsTObserverArray<nsWeakPtr> mReflowObservers;
   nsTObserverArray<nsWeakPtr> mScrollObservers;
   nsCString mOriginalUriString;
   nsWeakPtr mOpener;
+  mozilla::DocShellOriginAttributes mOriginAttributes;
 
   // A depth count of how many times NotifyRunToCompletionStart
   // has been called without a matching NotifyRunToCompletionStop.
   uint32_t mJSRunToCompletionDepth;
 
   // Separate function to do the actual name (i.e. not _top, _self etc.)
   // searching for FindItemWithName.
   nsresult DoFindItemWithName(const char16_t* aName,
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -764,16 +764,25 @@ interface nsIDocShell : nsIDocShellTreeI
   [noscript] void notifyScrollObservers();
 
   /**
    * Returns true iff the docshell corresponds to an <iframe mozapp>.
    */
   [infallible] readonly attribute boolean isApp;
 
   /**
+   * The type of iframe that this docshell lives.
+   */
+  const unsigned long FRAME_TYPE_REGULAR = 0;
+  const unsigned long FRAME_TYPE_BROWSER = 1;
+  const unsigned long FRAME_TYPE_APP     = 2;
+
+  [infallible] attribute unsigned long frameType;
+
+  /**
    * Returns true if this docshell corresponds to an <iframe mozbrowser> or
    * <iframe mozapp>.  <xul:browser> returns false here.
    */
   [infallible] readonly attribute boolean isMozBrowserOrApp;
 
   /**
    * Returns true if this docshell corresponds to an isolated <iframe
    * mozbrowser>.
@@ -808,58 +817,24 @@ interface nsIDocShell : nsIDocShellTreeI
    * or <iframe mozapp>.  <xul:browser> returns false here.
    *
    * To compute this value, we walk up the docshell hierarchy.  If we encounter
    * a docshell with isMozBrowserOrApp before we hit the end of the hierarchy,
    * we return true.  Otherwise, we return false.
    */
   [infallible] readonly attribute boolean isInMozBrowserOrApp;
 
-   /**
-    * Indicate that this docshell corresponds to an app with the given app id.
-    *
-    * You may pass NO_APP_ID or UNKNOWN_APP_ID for containingAppId.  If you
-    * pass NO_APP_ID, then this docshell will return NO_APP_ID for appId.  If
-    * you pass UNKNOWN_APP_ID, then this docshell will search its hiearchy for
-    * an app frame and use that frame's appId.
-    *
-    * You can call this method more than once, but there's no guarantee that
-    * other components will update their view of the world if you change a
-    * docshell's app id, so tread lightly.
-    *
-    * If you call this method after calling setIsBrowserInsideApp, this
-    * docshell will forget the fact that it was a browser.
-    */
-   void setIsApp(in unsigned long ownAppId);
-
-   /**
-    * Indicate that this docshell corresponds to a browser inside an app with
-    * the given ID.  As with setIsApp, you may pass NO_APP_ID or
-    * UNKNOWN_APP_ID.
-    *
-    * As with setIsApp, you may call this more than once, but it's kind of a
-    * hack, so be careful.
-    */
-   void setIsBrowserInsideApp(in unsigned long containingAppId);
-
-   /**
-    * Indicate that this docshell corresponds to a signed package with
-    * the given packageId.
-    */
-   void setIsSignedPackage(in AString packageId);
-
   /**
    * Returns the id of the app associated with this docshell.  If this docshell
    * is an <iframe mozbrowser> inside an <iframe mozapp>, we return the app's
    * appId.
    *
    * We compute this value by walking up the docshell hierarchy until we find a
-   * docshell on which setIsApp(x) or setIsBrowserInsideApp(x) was called
-   * (ignoring those docshells where x == UNKNOWN_APP_ID).  We return the app
-   * id x.
+   * docshell on which origin attributes was set. (ignoring those docshells
+   * where x == UNKNOWN_APP_ID).  We return the app id x.
    *
    * If we don't find a docshell with an associated app id in our hierarchy, we
    * return NO_APP_ID.  We never return UNKNOWN_APP_ID.
    *
    * Notice that a docshell may have an associated app even if it returns true
    * for isBrowserElement!
    */
   [infallible] readonly attribute unsigned long appId;
@@ -1100,16 +1075,20 @@ interface nsIDocShell : nsIDocShellTreeI
    * True for top level chrome docshells. Throws if set to false with
    * top level chrome docshell.
    */
   attribute boolean windowDraggingAllowed;
 
   /**
    * Sets/gets the current scroll restoration mode.
    * @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
-  */
+   */
   attribute boolean currentScrollRestorationIsManual;
 
-  /*
-   * Sets the user context ID for this docshell.
+  /**
+   * Setter and getter for the origin attributes living on this docshell.
    */
-  void setUserContextId(in unsigned long aUserContextId);
+  [implicit_jscontext]
+  jsval getOriginAttributes();
+
+  [implicit_jscontext]
+  void setOriginAttributes(in jsval aAttrs);
 };
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1843,36 +1843,16 @@ nsFrameLoader::MaybeCreateDocShell()
       mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
     }
   }
 
   if (!frameName.IsEmpty()) {
     mDocShell->SetName(frameName);
   }
 
-  //Grab the userContextId from owner if XUL
-  nsAutoString userContextIdStr;
-  if (namespaceID == kNameSpaceID_XUL) {
-    if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usercontextid)) {
-      mOwnerContent->GetAttr(kNameSpaceID_None,
-                             nsGkAtoms::usercontextid,
-                             userContextIdStr);
-    }
-  }
-
-  if (!userContextIdStr.IsEmpty()) {
-    nsresult rv;
-    uint32_t userContextId =
-      static_cast<uint32_t>(userContextIdStr.ToInteger(&rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = mDocShell->SetUserContextId(userContextId);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   // Inform our docShell that it has a new child.
   // Note: This logic duplicates a lot of logic in
   // nsSubDocumentFrame::AttributeChanged.  We should fix that.
 
   int32_t parentType = docShell->ItemType();
 
   // XXXbz why is this in content code, exactly?  We should handle
   // this some other way.....  Not sure how yet.
@@ -1933,44 +1913,68 @@ nsFrameLoader::MaybeCreateDocShell()
     nsCOMPtr<nsISHistory> sessionHistory =
       do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     webNav->SetSessionHistory(sessionHistory);
   }
 
+  DocShellOriginAttributes attrs;
+
+  if (!mOwnerContent->IsXULElement(nsGkAtoms::browser)) {
+    nsCOMPtr<nsIPrincipal> parentPrin = doc->NodePrincipal();
+    PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
+    attrs.InheritFromDocToChildDocShell(poa);
+  }
+
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
     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);
+    attrs.mAppId = ownAppId;
+    mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_APP);
   }
 
   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);
+
+    attrs.mAppId = containingAppId;
+    attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
+    mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
     mDocShell->SetIsInIsolatedMozBrowserElement(OwnerIsIsolatedMozBrowserFrame());
   }
 
+  // Grab the userContextId from owner if XUL
+  nsAutoString userContextIdStr;
+  if ((namespaceID == kNameSpaceID_XUL) &&
+      mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usercontextid, userContextIdStr) &&
+      !userContextIdStr.IsEmpty()) {
+    nsresult rv;
+    attrs.mUserContextId = userContextIdStr.ToInteger(&rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
+
   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(
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -854,33 +854,32 @@ TabChild::Init()
   mAPZEventState = new APZEventState(mPuppetWidget, Move(callback));
 
   return NS_OK;
 }
 
 void
 TabChild::NotifyTabContextUpdated()
 {
-    nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
-    MOZ_ASSERT(docShell);
-
-    if (docShell) {
-        // nsDocShell will do the right thing if we pass NO_APP_ID or
-        // UNKNOWN_APP_ID for aOwnOrContainingAppId.
-        if (IsMozBrowserElement()) {
-          docShell->SetIsBrowserInsideApp(BrowserOwnerAppId());
-          docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
-        } else {
-          docShell->SetIsApp(OwnAppId());
-        }
-
-        OriginAttributes attrs = OriginAttributesRef();
-        docShell->SetIsSignedPackage(attrs.mSignedPkg);
-        docShell->SetUserContextId(attrs.mUserContextId);
-    }
+  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
+  MOZ_ASSERT(docShell);
+
+  if (!docShell) {
+    return;
+  }
+
+  if (IsMozBrowserElement()) {
+    docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
+  }
+  docShell->SetFrameType(IsMozBrowserElement() ?
+                           nsIDocShell::FRAME_TYPE_BROWSER :
+                           HasOwnApp() ?
+                             nsIDocShell::FRAME_TYPE_APP :
+                             nsIDocShell::FRAME_TYPE_REGULAR);
+  nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef());
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3374,17 +3374,18 @@ Tab.prototype = {
     BrowserApp.deck.insertBefore(this.browser, aParams.sibling || null);
     BrowserApp.deck.selectedPanel = selectedPanel;
 
     if (BrowserApp.manifestUrl) {
       let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
       let manifest = appsService.getAppByManifestURL(BrowserApp.manifestUrl);
       if (manifest) {
         let app = manifest.QueryInterface(Ci.mozIApplication);
-        this.browser.docShell.setIsApp(app.localId);
+        this.browser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
+        this.browser.docShell.setOriginAttributes({appId: app.localId});
       }
     }
 
     // Must be called after appendChild so the docShell has been created.
     this.setActive(false);
 
     let isPrivate = ("isPrivate" in aParams) && aParams.isPrivate;
     if (isPrivate) {
--- a/webapprt/Startup.jsm
+++ b/webapprt/Startup.jsm
@@ -190,17 +190,18 @@ this.startup = function(window) {
     Cu.import("resource://gre/modules/AlarmService.jsm");
     Cu.import("resource://webapprt/modules/WebRTCHandler.jsm");
     Cu.import("resource://webapprt/modules/DownloadView.jsm");
 
     // Get the <browser> element in the webapp.xul window.
     let appBrowser = window.document.getElementById("content");
 
     // Set the principal to the correct appID and launch the application.
-    appBrowser.docShell.setIsApp(WebappRT.appID);
+    appBrowser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
+    appBrowser.docShell.setOriginAttributes({appId: WebappRT.appID});
     appBrowser.setAttribute("src", WebappRT.launchURI);
 
     if (appData.manifest.fullscreen) {
       appBrowser.addEventListener("load", function onLoad() {
         appBrowser.removeEventListener("load", onLoad, true);
         appBrowser.contentDocument.
           documentElement.requestFullscreen();
       }, true);
--- a/webapprt/content/webapp.js
+++ b/webapprt/content/webapp.js
@@ -105,17 +105,18 @@ function onDOMContentLoaded() {
   // The initial window's app ID is set by Startup.jsm before the app
   // is loaded, so this code only handles subsequent windows that are opened
   // by the app via window.open calls.  We do this on DOMContentLoaded
   // in order to ensure it gets set before the window's content is loaded.
   if (gAppBrowser.docShell.appId === Ci.nsIScriptSecurityManager.NO_APP_ID) {
     // Set the principal to the correct app ID.  Since this is a subsequent
     // window, we know that WebappRT.configPromise has been resolved, so we
     // don't have to yield to it before accessing WebappRT.appID.
-    gAppBrowser.docShell.setIsApp(WebappRT.appID);
+    gAppBrowser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
+    gAppBrowser.docShell.setOriginAttributes({appId: WebappRT.appID});
   }
 }
 window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false);
 
 function onLoad() {
   window.removeEventListener("load", onLoad, false);
 
   gAppBrowser.addProgressListener(progressListener,