dom/ipc/TabContext.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set sw=2 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "mozilla/dom/TabContext.h"
     8 #include "mozilla/dom/PTabContext.h"
     9 #include "mozilla/dom/TabParent.h"
    10 #include "mozilla/dom/TabChild.h"
    11 #include "nsIAppsService.h"
    12 #include "nsIScriptSecurityManager.h"
    13 #include "nsServiceManagerUtils.h"
    15 #define NO_APP_ID (nsIScriptSecurityManager::NO_APP_ID)
    17 using namespace mozilla::dom::ipc;
    18 using namespace mozilla::layout;
    20 namespace mozilla {
    21 namespace dom {
    23 TabContext::TabContext()
    24   : mInitialized(false)
    25   , mOwnAppId(NO_APP_ID)
    26   , mContainingAppId(NO_APP_ID)
    27   , mScrollingBehavior(DEFAULT_SCROLLING)
    28   , mIsBrowser(false)
    29 {
    30 }
    32 bool
    33 TabContext::IsBrowserElement() const
    34 {
    35   return mIsBrowser;
    36 }
    38 bool
    39 TabContext::IsBrowserOrApp() const
    40 {
    41   return HasOwnApp() || IsBrowserElement();
    42 }
    44 uint32_t
    45 TabContext::OwnAppId() const
    46 {
    47   return mOwnAppId;
    48 }
    50 already_AddRefed<mozIApplication>
    51 TabContext::GetOwnApp() const
    52 {
    53   nsCOMPtr<mozIApplication> ownApp = mOwnApp;
    54   return ownApp.forget();
    55 }
    57 bool
    58 TabContext::HasOwnApp() const
    59 {
    60   nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
    61   return !!ownApp;
    62 }
    64 uint32_t
    65 TabContext::BrowserOwnerAppId() const
    66 {
    67   if (IsBrowserElement()) {
    68     return mContainingAppId;
    69   }
    70   return NO_APP_ID;
    71 }
    73 already_AddRefed<mozIApplication>
    74 TabContext::GetBrowserOwnerApp() const
    75 {
    76   nsCOMPtr<mozIApplication> ownerApp;
    77   if (IsBrowserElement()) {
    78     ownerApp = mContainingApp;
    79   }
    80   return ownerApp.forget();
    81 }
    83 bool
    84 TabContext::HasBrowserOwnerApp() const
    85 {
    86   nsCOMPtr<mozIApplication> ownerApp = GetBrowserOwnerApp();
    87   return !!ownerApp;
    88 }
    90 uint32_t
    91 TabContext::AppOwnerAppId() const
    92 {
    93   if (HasOwnApp()) {
    94     return mContainingAppId;
    95   }
    96   return NO_APP_ID;
    97 }
    99 already_AddRefed<mozIApplication>
   100 TabContext::GetAppOwnerApp() const
   101 {
   102   nsCOMPtr<mozIApplication> ownerApp;
   103   if (HasOwnApp()) {
   104     ownerApp = mContainingApp;
   105   }
   106   return ownerApp.forget();
   107 }
   109 bool
   110 TabContext::HasAppOwnerApp() const
   111 {
   112   nsCOMPtr<mozIApplication> ownerApp = GetAppOwnerApp();
   113   return !!ownerApp;
   114 }
   116 uint32_t
   117 TabContext::OwnOrContainingAppId() const
   118 {
   119   if (HasOwnApp()) {
   120     return mOwnAppId;
   121   }
   123   return mContainingAppId;
   124 }
   126 already_AddRefed<mozIApplication>
   127 TabContext::GetOwnOrContainingApp() const
   128 {
   129   nsCOMPtr<mozIApplication> ownOrContainingApp;
   130   if (HasOwnApp()) {
   131     ownOrContainingApp = mOwnApp;
   132   } else {
   133     ownOrContainingApp = mContainingApp;
   134   }
   136   return ownOrContainingApp.forget();
   137 }
   139 bool
   140 TabContext::HasOwnOrContainingApp() const
   141 {
   142   nsCOMPtr<mozIApplication> ownOrContainingApp = GetOwnOrContainingApp();
   143   return !!ownOrContainingApp;
   144 }
   146 bool
   147 TabContext::SetTabContext(const TabContext& aContext)
   148 {
   149   NS_ENSURE_FALSE(mInitialized, false);
   151   *this = aContext;
   152   mInitialized = true;
   154   return true;
   155 }
   157 bool
   158 TabContext::SetTabContextForAppFrame(mozIApplication* aOwnApp,
   159                                      mozIApplication* aAppFrameOwnerApp,
   160                                      ScrollingBehavior aRequestedBehavior)
   161 {
   162   NS_ENSURE_FALSE(mInitialized, false);
   164   // Get ids for both apps and only write to our member variables after we've
   165   // verified that this worked.
   166   uint32_t ownAppId = NO_APP_ID;
   167   if (aOwnApp) {
   168     nsresult rv = aOwnApp->GetLocalId(&ownAppId);
   169     NS_ENSURE_SUCCESS(rv, false);
   170     NS_ENSURE_TRUE(ownAppId != NO_APP_ID, false);
   171   }
   173   uint32_t containingAppId = NO_APP_ID;
   174   if (aAppFrameOwnerApp) {
   175     nsresult rv = aAppFrameOwnerApp->GetLocalId(&containingAppId);
   176     NS_ENSURE_SUCCESS(rv, false);
   177     NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
   178   }
   180   mInitialized = true;
   181   mIsBrowser = false;
   182   mOwnAppId = ownAppId;
   183   mContainingAppId = containingAppId;
   184   mScrollingBehavior = aRequestedBehavior;
   185   mOwnApp = aOwnApp;
   186   mContainingApp = aAppFrameOwnerApp;
   187   return true;
   188 }
   190 bool
   191 TabContext::SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp,
   192                                          ScrollingBehavior aRequestedBehavior)
   193 {
   194   NS_ENSURE_FALSE(mInitialized, false);
   196   uint32_t containingAppId = NO_APP_ID;
   197   if (aBrowserFrameOwnerApp) {
   198     nsresult rv = aBrowserFrameOwnerApp->GetLocalId(&containingAppId);
   199     NS_ENSURE_SUCCESS(rv, false);
   200     NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
   201   }
   203   mInitialized = true;
   204   mIsBrowser = true;
   205   mOwnAppId = NO_APP_ID;
   206   mContainingAppId = containingAppId;
   207   mScrollingBehavior = aRequestedBehavior;
   208   mContainingApp = aBrowserFrameOwnerApp;
   209   return true;
   210 }
   212 bool
   213 TabContext::SetTabContextForNormalFrame(ScrollingBehavior aRequestedBehavior)
   214 {
   215   NS_ENSURE_FALSE(mInitialized, false);
   217   mInitialized = true;
   218   mScrollingBehavior = aRequestedBehavior;
   219   return true;
   220 }
   222 IPCTabContext
   223 TabContext::AsIPCTabContext() const
   224 {
   225   if (mIsBrowser) {
   226     return IPCTabContext(BrowserFrameIPCTabContext(mContainingAppId),
   227                          mScrollingBehavior);
   228   }
   230   return IPCTabContext(AppFrameIPCTabContext(mOwnAppId, mContainingAppId),
   231                        mScrollingBehavior);
   232 }
   234 static already_AddRefed<mozIApplication>
   235 GetAppForId(uint32_t aAppId)
   236 {
   237   nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
   238   NS_ENSURE_TRUE(appsService, nullptr);
   240   nsCOMPtr<mozIApplication> app;
   241   appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
   243   return app.forget();
   244 }
   246 MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
   247   : mInvalidReason(nullptr)
   248 {
   249   bool isBrowser = false;
   250   uint32_t ownAppId = NO_APP_ID;
   251   uint32_t containingAppId = NO_APP_ID;
   253   const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext();
   254   switch(appBrowser.type()) {
   255     case IPCTabAppBrowserContext::TPopupIPCTabContext: {
   256       const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();
   258       TabContext *context;
   259       if (ipcContext.openerParent()) {
   260         context = static_cast<TabParent*>(ipcContext.openerParent());
   261         if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
   262           // If the TabParent corresponds to a browser element, then it can only
   263           // open other browser elements, for security reasons.  We should have
   264           // checked this before calling the TabContext constructor, so this is
   265           // a fatal error.
   266           mInvalidReason = "Child is-browser process tried to "
   267                            "open a non-browser tab.";
   268           return;
   269         }
   270       } else if (ipcContext.openerChild()) {
   271         context = static_cast<TabChild*>(ipcContext.openerChild());
   272       } else {
   273         // This should be unreachable because PopupIPCTabContext::opener is not a
   274         // nullable field.
   275         mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
   276         return;
   277       }
   279       // Browser elements can't nest other browser elements.  So if
   280       // our opener is browser element, we must be a new DOM window
   281       // opened by it.  In that case we inherit our containing app ID
   282       // (if any).
   283       //
   284       // Otherwise, we're a new app window and we inherit from our
   285       // opener app.
   286       if (ipcContext.isBrowserElement()) {
   287         isBrowser = true;
   288         ownAppId = NO_APP_ID;
   289         containingAppId = context->OwnOrContainingAppId();
   290       } else {
   291         isBrowser = false;
   292         ownAppId = context->mOwnAppId;
   293         containingAppId = context->mContainingAppId;
   294       }
   295       break;
   296     }
   297     case IPCTabAppBrowserContext::TAppFrameIPCTabContext: {
   298       const AppFrameIPCTabContext &ipcContext =
   299         appBrowser.get_AppFrameIPCTabContext();
   301       isBrowser = false;
   302       ownAppId = ipcContext.ownAppId();
   303       containingAppId = ipcContext.appFrameOwnerAppId();
   304       break;
   305     }
   306     case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: {
   307       const BrowserFrameIPCTabContext &ipcContext =
   308         appBrowser.get_BrowserFrameIPCTabContext();
   310       isBrowser = true;
   311       ownAppId = NO_APP_ID;
   312       containingAppId = ipcContext.browserFrameOwnerAppId();
   313       break;
   314     }
   315     case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: {
   316       isBrowser = false;
   317       ownAppId = NO_APP_ID;
   318       containingAppId = NO_APP_ID;
   319       break;
   320     }
   321     default: {
   322       MOZ_CRASH();
   323     }
   324   }
   326   nsCOMPtr<mozIApplication> ownApp = GetAppForId(ownAppId);
   327   if ((ownApp == nullptr) != (ownAppId == NO_APP_ID)) {
   328     mInvalidReason = "Got an ownAppId that didn't correspond to an app.";
   329     return;
   330   }
   332   nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId);
   333   if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) {
   334     mInvalidReason = "Got a containingAppId that didn't correspond to an app.";
   335     return;
   336   }
   338   bool rv;
   339   if (isBrowser) {
   340     rv = mTabContext.SetTabContextForBrowserFrame(containingApp,
   341                                                   aParams.scrollingBehavior());
   342   } else {
   343     rv = mTabContext.SetTabContextForAppFrame(ownApp,
   344                                               containingApp,
   345                                               aParams.scrollingBehavior());
   346   }
   348   if (!rv) {
   349     mInvalidReason = "Couldn't initialize TabContext.";
   350   }
   351 }
   353 bool
   354 MaybeInvalidTabContext::IsValid()
   355 {
   356   return mInvalidReason == nullptr;
   357 }
   359 const char*
   360 MaybeInvalidTabContext::GetInvalidReason()
   361 {
   362   return mInvalidReason;
   363 }
   365 const TabContext&
   366 MaybeInvalidTabContext::GetTabContext()
   367 {
   368   if (!IsValid()) {
   369     MOZ_CRASH("Can't GetTabContext() if !IsValid().");
   370   }
   372   return mTabContext;
   373 }
   375 } // namespace dom
   376 } // namespace mozilla

mercurial