Bug 1234128 - Part 1: Add mozpresentation attribute in browser element. r=smaug
☠☠ backed out by e42d3d42dafa ☠ ☠
authorShih-Chiang Chien <schien@mozilla.com>
Tue, 17 May 2016 11:10:59 +0800
changeset 298139 7cf300dda85ae7435db346b46c109a4ba6c5edae
parent 298138 7521936774c1eacd5872c34be824c8f1db39778d
child 298140 8a0848fb59acc1e9fcf4a5ad7e0b0dfc0c385f73
push id30273
push userkwierso@gmail.com
push dateFri, 20 May 2016 21:08:12 +0000
treeherdermozilla-central@c403ac05b8f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1234128
milestone49.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 1234128 - Part 1: Add mozpresentation attribute in browser element. r=smaug
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsFrameLoader.cpp
dom/base/nsGkAtomList.h
dom/ipc/PTabContext.ipdlh
dom/ipc/TabContext.cpp
dom/ipc/TabContext.h
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -110,16 +110,17 @@
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMEvent.h"
+#include "nsIDOMElement.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsIDragService.h"
@@ -198,16 +199,17 @@
 #include "xpcprivate.h" // nsXPConnect
 #include "HTMLSplitOnSpacesTokenizer.h"
 #include "nsContentTypeParser.h"
 #include "nsICookiePermission.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsICookieService.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/BloomFilter.h"
+#include "TabChild.h"
 
 #include "nsIBidiKeyboard.h"
 
 #if defined(XP_WIN)
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
@@ -8834,8 +8836,36 @@ nsContentUtils::SetScrollbarsVisibility(
     }
 
     scroller->SetDefaultScrollbarPreferences(
                 nsIScrollable::ScrollOrientation_Y, prefValue);
     scroller->SetDefaultScrollbarPreferences(
                 nsIScrollable::ScrollOrientation_X, prefValue);
   }
 }
+
+/* static */ void
+nsContentUtils::GetPresentationURL(nsIDocShell* aDocShell, nsAString& aPresentationUrl)
+{
+  MOZ_ASSERT(aDocShell);
+
+  if (XRE_IsContentProcess()) {
+    nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
+    aDocShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
+    nsCOMPtr<nsIDocShellTreeItem> root;
+    aDocShell->GetRootTreeItem(getter_AddRefs(root));
+    if (sameTypeRoot.get() == root.get()) {
+      // presentation URL is stored in TabChild for the top most
+      // <iframe mozbrowser> in content process.
+      TabChild* tabChild = TabChild::GetFrom(aDocShell);
+      if (tabChild) {
+        aPresentationUrl = tabChild->PresentationURL();
+      }
+      return;
+    }
+  }
+
+  nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(aDocShell));
+  nsCOMPtr<nsIDOMElement> topFrameElement;
+  loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement));
+
+  topFrameElement->GetAttribute(NS_LITERAL_STRING("mozpresentation"), aPresentationUrl);
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2548,16 +2548,22 @@ public:
    * the provided about: URI.
    * @param aGlobal the JSObject whose URI to check, if it is a global.
    * @param aUri the URI to match, e.g. "about:feeds"
    */
   static bool IsSpecificAboutPage(JSObject* aGlobal, const char* aUri);
 
   static void SetScrollbarsVisibility(nsIDocShell* aDocShell, bool aVisible);
 
+  /*
+   * Return the associated presentation URL of the presented content.
+   * Will return empty string if the docshell is not in a presented content.
+   */
+  static void GetPresentationURL(nsIDocShell* aDocShell, nsAString& aPresentationUrl);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -3335,22 +3335,28 @@ nsFrameLoader::GetNewTabContext(MutableT
   }
   if (!userContextIdStr.IsEmpty()) {
     nsresult err;
     uint32_t userContextId = userContextIdStr.ToInteger(&err);
     NS_ENSURE_SUCCESS(err, err);
     attrs.mUserContextId = userContextId;
   }
 
+  nsAutoString presentationURLStr;
+  mOwnerContent->GetAttr(kNameSpaceID_None,
+                         nsGkAtoms::mozpresentation,
+                         presentationURLStr);
+
   bool tabContextUpdated =
     aTabContext->SetTabContext(OwnerIsMozBrowserFrame(),
                                ownApp,
                                containingApp,
                                attrs,
-                               signedPkgOrigin);
+                               signedPkgOrigin,
+                               presentationURLStr);
   NS_ENSURE_STATE(tabContextUpdated);
 
   return NS_OK;
 }
 
 nsresult
 nsFrameLoader::PopulateUserContextIdFromAttribute(DocShellOriginAttributes& aAttr)
 {
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -1009,16 +1009,17 @@ GK_ATOM(position, "position")
 GK_ATOM(poster, "poster")
 GK_ATOM(pre, "pre")
 GK_ATOM(preceding, "preceding")
 GK_ATOM(precedingSibling, "preceding-sibling")
 GK_ATOM(predicate, "predicate")
 GK_ATOM(prefix, "prefix")
 GK_ATOM(preload, "preload")
 GK_ATOM(prerendered, "prerendered")
+GK_ATOM(mozpresentation, "mozpresentation")
 GK_ATOM(preserve, "preserve")
 GK_ATOM(preserveSpace, "preserve-space")
 GK_ATOM(preventdefault, "preventdefault")
 GK_ATOM(primary, "primary")
 GK_ATOM(print, "print")
 GK_ATOM(priority, "priority")
 GK_ATOM(processingInstruction, "processing-instruction")
 GK_ATOM(profile, "profile")
--- a/dom/ipc/PTabContext.ipdlh
+++ b/dom/ipc/PTabContext.ipdlh
@@ -42,16 +42,21 @@ struct FrameIPCTabContext
   // The origin without originAttribute suffix for a signed package.
   // This value would be empty if the TabContext doesn't own a signed
   // package.
   nsCString signedPkgOriginNoSuffix;
 
   // Whether this is a mozbrowser frame.  <iframe mozbrowser mozapp> and
   // <xul:browser> are not considered to be mozbrowser frames.
   bool isMozBrowserElement;
+
+  // The requested presentation URL.
+  // This value would be empty if the TabContext isn't created for
+  // presented content.
+  nsString presentationURL;
 };
 
 // XXXcatalinb: This is only used by ServiceWorkerClients::OpenWindow.
 // Because service workers don't have an associated TabChild
 // we can't satisfy the security constraints on b2g. As such, the parent
 // process will accept this tab context only on desktop.
 struct UnsafeIPCTabContext
 { };
--- a/dom/ipc/TabContext.cpp
+++ b/dom/ipc/TabContext.cpp
@@ -185,22 +185,29 @@ TabContext::OriginAttributesRef() const
 }
 
 const nsACString&
 TabContext::SignedPkgOriginNoSuffix() const
 {
   return mSignedPkgOriginNoSuffix;
 }
 
+const nsAString&
+TabContext::PresentationURL() const
+{
+  return mPresentationURL;
+}
+
 bool
 TabContext::SetTabContext(bool aIsMozBrowserElement,
                           mozIApplication* aOwnApp,
                           mozIApplication* aAppFrameOwnerApp,
                           const DocShellOriginAttributes& aOriginAttributes,
-                          const nsACString& aSignedPkgOriginNoSuffix)
+                          const nsACString& aSignedPkgOriginNoSuffix,
+                          const nsAString& aPresentationURL)
 {
   NS_ENSURE_FALSE(mInitialized, false);
 
   // Get ids for both apps and only write to our member variables after we've
   // verified that this worked.
   uint32_t ownAppId = NO_APP_ID;
   if (aOwnApp) {
     nsresult rv = aOwnApp->GetLocalId(&ownAppId);
@@ -222,28 +229,30 @@ TabContext::SetTabContext(bool aIsMozBro
 
   mInitialized = true;
   mIsMozBrowserElement = aIsMozBrowserElement;
   mOriginAttributes = aOriginAttributes;
   mContainingAppId = containingAppId;
   mOwnApp = aOwnApp;
   mContainingApp = aAppFrameOwnerApp;
   mSignedPkgOriginNoSuffix = aSignedPkgOriginNoSuffix;
+  mPresentationURL = aPresentationURL;
   return true;
 }
 
 IPCTabContext
 TabContext::AsIPCTabContext() const
 {
   nsAutoCString originSuffix;
   mOriginAttributes.CreateSuffix(originSuffix);
   return IPCTabContext(FrameIPCTabContext(originSuffix,
                                           mContainingAppId,
                                           mSignedPkgOriginNoSuffix,
-                                          mIsMozBrowserElement));
+                                          mIsMozBrowserElement,
+                                          mPresentationURL));
 }
 
 static already_AddRefed<mozIApplication>
 GetAppForId(uint32_t aAppId)
 {
   nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(appsService, nullptr);
 
@@ -256,16 +265,17 @@ GetAppForId(uint32_t aAppId)
 MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
   : mInvalidReason(nullptr)
 {
   bool isMozBrowserElement = false;
   uint32_t containingAppId = NO_APP_ID;
   DocShellOriginAttributes originAttributes;
   nsAutoCString originSuffix;
   nsAutoCString signedPkgOriginNoSuffix;
+  nsAutoString presentationURL;
 
   switch(aParams.type()) {
     case IPCTabContext::TPopupIPCTabContext: {
       const PopupIPCTabContext &ipcContext = aParams.get_PopupIPCTabContext();
 
       TabContext *context;
       if (ipcContext.opener().type() == PBrowserOrId::TPBrowserParent) {
         context = TabParent::GetFrom(ipcContext.opener().get_PBrowserParent());
@@ -316,16 +326,17 @@ MaybeInvalidTabContext::MaybeInvalidTabC
     }
     case IPCTabContext::TFrameIPCTabContext: {
       const FrameIPCTabContext &ipcContext =
         aParams.get_FrameIPCTabContext();
 
       isMozBrowserElement = ipcContext.isMozBrowserElement();
       containingAppId = ipcContext.frameOwnerAppId();
       signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
+      presentationURL = ipcContext.presentationURL();
       originSuffix = ipcContext.originSuffix();
       originAttributes.PopulateFromSuffix(originSuffix);
       break;
     }
     case IPCTabContext::TUnsafeIPCTabContext: {
       // XXXcatalinb: This used *only* by ServiceWorkerClients::OpenWindow.
       // It is meant as a temporary solution until service workers can
       // provide a TabChild equivalent. Don't allow this on b2g since
@@ -364,17 +375,18 @@ MaybeInvalidTabContext::MaybeInvalidTabC
     return;
   }
 
   bool rv;
   rv = mTabContext.SetTabContext(isMozBrowserElement,
                                  ownApp,
                                  containingApp,
                                  originAttributes,
-                                 signedPkgOriginNoSuffix);
+                                 signedPkgOriginNoSuffix,
+                                 presentationURL);
   if (!rv) {
     mInvalidReason = "Couldn't initialize TabContext.";
   }
 }
 
 bool
 MaybeInvalidTabContext::IsValid()
 {
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -125,16 +125,22 @@ public:
   const DocShellOriginAttributes& OriginAttributesRef() const;
 
   /**
    * Returns the origin associated with the tab (w/o suffix) if this tab owns
    * a signed packaged content.
    */
   const nsACString& SignedPkgOriginNoSuffix() const;
 
+  /**
+   * Returns the presentation URL associated with the tab if this tab is
+   * created for presented content
+   */
+  const nsAString& PresentationURL() const;
+
 protected:
   friend class MaybeInvalidTabContext;
 
   /**
    * These protected mutator methods let you modify a TabContext once.  Further
    * attempts to modify a given TabContext will fail (the method will return
    * false).
    *
@@ -153,17 +159,18 @@ protected:
    *    apps can be null.
    *  - a browser frame inside the given owner app (which may be null).
    *  - a non-browser, non-app frame. Both own app and owner app should be null.
    */
   bool SetTabContext(bool aIsMozBrowserElement,
                      mozIApplication* aOwnApp,
                      mozIApplication* aAppFrameOwnerApp,
                      const DocShellOriginAttributes& aOriginAttributes,
-                     const nsACString& aSignedPkgOriginNoSuffix);
+                     const nsACString& aSignedPkgOriginNoSuffix,
+                     const nsAString& aPresentationURL);
 
   /**
    * Modify this TabContext to match the given TabContext.  This is a special
    * case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have
    * caused the owner content to change.
    *
    * This special case only allows the field `mIsMozBrowserElement` to be
    * changed.  If any other fields have changed, the update is ignored and
@@ -210,16 +217,21 @@ private:
 
   /**
    * The signed package origin without suffix. Since the signed packaged
    * web content is always loaded in a separate process, it makes sense
    * that we store this immutable value in TabContext. If the TabContext
    * doesn't own a signed package, this value would be empty.
    */
   nsCString mSignedPkgOriginNoSuffix;
+
+  /**
+   * The requested presentation URL.
+   */
+  nsString mPresentationURL;
 };
 
 /**
  * MutableTabContext is the same as MaybeInvalidTabContext, except the mutation
  * methods are public instead of protected.  You can still only call these
  * mutation methods once on a given object.
  */
 class MutableTabContext : public TabContext
@@ -230,23 +242,25 @@ public:
     return TabContext::SetTabContext(aContext);
   }
 
   bool
   SetTabContext(bool aIsMozBrowserElement,
                 mozIApplication* aOwnApp,
                 mozIApplication* aAppFrameOwnerApp,
                 const DocShellOriginAttributes& aOriginAttributes,
-                const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
+                const nsACString& aSignedPkgOriginNoSuffix = EmptyCString(),
+                const nsAString& aPresentationURL = EmptyString())
   {
     return TabContext::SetTabContext(aIsMozBrowserElement,
                                      aOwnApp,
                                      aAppFrameOwnerApp,
                                      aOriginAttributes,
-                                     aSignedPkgOriginNoSuffix);
+                                     aSignedPkgOriginNoSuffix,
+                                     aPresentationURL);
   }
 };
 
 /**
  * MaybeInvalidTabContext is a simple class that lets you transform an
  * IPCTabContext into a TabContext.
  *
  * The issue is that an IPCTabContext is not necessarily valid; for example, it