Esempio n. 1
0
bool
AssertAppProcess(TabContext& aContext,
                 AssertAppProcessType aType,
                 const char* aCapability)
{

  nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
  return CheckAppTypeHelper(app, aType, aCapability, aContext.IsBrowserElement());
}
uint32_t
ContentProcessManager::GetAppIdByProcessAndTabId(const ContentParentId& aChildCpId,
                                                 const TabId& aChildTabId)
{
  uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
  if (aChildCpId && aChildTabId) {
    TabContext tabContext;
    if (GetTabContextByProcessAndTabId(aChildCpId, aChildTabId, &tabContext)) {
      appId = tabContext.OwnOrContainingAppId();
    }
  }
  return appId;
}
Esempio n. 3
0
nsresult
NeckoParent::OfflineNotification(nsISupports *aSubject)
{
  nsCOMPtr<nsIAppOfflineInfo> info(do_QueryInterface(aSubject));
  if (!info) {
    return NS_OK;
  }

  uint32_t targetAppId = NECKO_UNKNOWN_APP_ID;
  info->GetAppId(&targetAppId);

  nsTArray<TabContext> contextArray =
      static_cast<ContentParent*>(Manager())->GetManagedTabContext();
  for (uint32_t i = 0; i < contextArray.Length(); ++i) {
    TabContext tabContext = contextArray[i];
    uint32_t appId = tabContext.OwnOrContainingAppId();

    if (appId == targetAppId) {
      if (gIOService) {
        bool offline = false;
        nsresult rv = gIOService->IsAppOffline(appId, &offline);
        if (NS_FAILED(rv)) {
          printf_stderr("Unexpected - NeckoParent: "
                        "appId not found by isAppOffline(): %u\n", appId);
          break;
        }
        if (!SendAppOfflineStatus(appId, offline)) {
          printf_stderr("NeckoParent: "
                        "SendAppOfflineStatus failed for appId: %u\n", appId);
        }
        // Once we found the targetAppId, we don't need to continue
        break;
      }
    }

  }

  // XPCShells don't have any TabParents
  // Just send the ipdl message to the child process.
  if (!UsingNeckoIPCSecurity()) {
    bool offline = false;
    gIOService->IsAppOffline(targetAppId, &offline);
    if (!SendAppOfflineStatus(targetAppId, offline)) {
      printf_stderr("NeckoParent: "
                    "SendAppOfflineStatus failed for targetAppId: %u\n", targetAppId);
    }
  }

  return NS_OK;
}
Esempio n. 4
0
bool
AssertAppStatus(TabContext& aContext,
                unsigned short aStatus)
{

  nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
  return CheckAppStatusHelper(app, aStatus);
}
// static
bool
IndexedDatabaseManager::TabContextMayAccessOrigin(const TabContext& aContext,
                                                  const nsACString& aOrigin)
{
  NS_ASSERTION(!aOrigin.IsEmpty(), "Empty origin!");

  // If aContext is for a browser element, it's allowed only to access other
  // browser elements.  But if aContext is not for a browser element, it may
  // access both browser and non-browser elements.
  nsAutoCString pattern;
  QuotaManager::GetOriginPatternStringMaybeIgnoreBrowser(
                                                aContext.OwnOrContainingAppId(),
                                                aContext.IsBrowserElement(),
                                                pattern);

  return PatternMatchesOrigin(pattern, aOrigin);
}
Esempio n. 6
0
bool
AssertAppProcess(TabContext& aContext,
                 AssertAppProcessType aType,
                 const char* aCapability)
{
  const mozilla::DocShellOriginAttributes& attr = aContext.OriginAttributesRef();
  nsCString suffix;
  attr.CreateSuffix(suffix);

  if (!aContext.SignedPkgOriginNoSuffix().IsEmpty()) {
    LOG("TabContext owning signed package origin: %s, originAttr; %s\n",
        nsCString(aContext.SignedPkgOriginNoSuffix()).get(),
        suffix.get());
  }

  // Do a origin-based permission check if the TabContext owns a signed package.
  if (!aContext.SignedPkgOriginNoSuffix().IsEmpty() &&
      (ASSERT_APP_HAS_PERMISSION == aType || ASSERT_APP_PROCESS_PERMISSION == aType)) {
    nsCString origin = aContext.SignedPkgOriginNoSuffix() + suffix;
    return CheckOriginPermission(origin, aCapability);
  }

  nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
  return CheckAppTypeHelper(app, aType, aCapability, aContext.IsBrowserElement());
}
Esempio n. 7
0
bool
TabContext::UpdateTabContextAfterSwap(const TabContext& aContext)
{
  // This is only used after already initialized.
  MOZ_ASSERT(mInitialized);

  // The only permissable change is to `mIsMozBrowserElement`.  All other fields
  // must match for the change to be accepted.
  if (aContext.OwnAppId() != OwnAppId() ||
      aContext.mContainingAppId != mContainingAppId ||
      aContext.mOriginAttributes != mOriginAttributes ||
      aContext.mSignedPkgOriginNoSuffix != mSignedPkgOriginNoSuffix) {
    return false;
  }

  mIsMozBrowserElement = aContext.mIsMozBrowserElement;
  return true;
}
TabContext::TabContext(const IPCTabContext& aParams)
  : mInitialized(true)
{
  const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext();
  switch(appBrowser.type()) {
    case IPCTabAppBrowserContext::TPopupIPCTabContext: {
      const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();

      TabContext *context;
      if (ipcContext.openerParent()) {
        context = static_cast<TabParent*>(ipcContext.openerParent());
        if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
          // If the TabParent corresponds to a browser element, then it can only
          // open other browser elements, for security reasons.  We should have
          // checked this before calling the TabContext constructor, so this is
          // a fatal error.
          MOZ_CRASH();
        }
      }
      else if (ipcContext.openerChild()) {
        context = static_cast<TabChild*>(ipcContext.openerChild());
      }
      else {
        // This should be unreachable because PopupIPCTabContext::opener is not a
        // nullable field.
        MOZ_CRASH();
      }

      // If ipcContext is a browser element, then the opener's app-id becomes
      // our containing app-id.  Otherwise, our own and containing app-ids are
      // directly inherited from our opener.
      if (ipcContext.isBrowserElement()) {
        mIsBrowser = true;
        mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
        mContainingAppId = context->OwnAppId();
      }
      else {
        mIsBrowser = false;
        mOwnAppId = context->mOwnAppId;
        mContainingAppId = context->mContainingAppId;
      }
      break;
    }
    case IPCTabAppBrowserContext::TAppFrameIPCTabContext: {
      const AppFrameIPCTabContext &ipcContext =
        appBrowser.get_AppFrameIPCTabContext();

      mIsBrowser = false;
      mOwnAppId = ipcContext.ownAppId();
      mContainingAppId = ipcContext.appFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: {
      const BrowserFrameIPCTabContext &ipcContext =
        appBrowser.get_BrowserFrameIPCTabContext();

      mIsBrowser = true;
      mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
      mContainingAppId = ipcContext.browserFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: {
      mIsBrowser = false;
      mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
      mContainingAppId = nsIScriptSecurityManager::NO_APP_ID;
      break;
    }
    default: {
      MOZ_CRASH();
    }
  }

  mScrollingBehavior = aParams.scrollingBehavior();
}
Esempio n. 9
0
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
  : mInvalidReason(nullptr)
{
  bool isMozBrowserElement = false;
  bool isPrerendered = false;
  uint32_t containingAppId = NO_APP_ID;
  DocShellOriginAttributes originAttributes;
  nsAutoCString signedPkgOriginNoSuffix;
  nsAutoString presentationURL;
  UIStateChangeType showAccelerators = UIStateChangeType_NoChange;
  UIStateChangeType showFocusRings = UIStateChangeType_NoChange;

  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());
        if (!context) {
          mInvalidReason = "Child is-browser process tried to "
                           "open a null tab.";
          return;
        }
        if (context->IsMozBrowserElement() &&
            !ipcContext.isMozBrowserElement()) {
          // If the TabParent corresponds to a browser element, then it can only
          // open other browser elements, for security reasons.  We should have
          // checked this before calling the TabContext constructor, so this is
          // a fatal error.
          mInvalidReason = "Child is-browser process tried to "
                           "open a non-browser tab.";
          return;
        }
      } else if (ipcContext.opener().type() == PBrowserOrId::TPBrowserChild) {
        context = static_cast<TabChild*>(ipcContext.opener().get_PBrowserChild());
      } else if (ipcContext.opener().type() == PBrowserOrId::TTabId) {
        // We should never get here because this PopupIPCTabContext is only
        // used for allocating a new tab id, not for allocating a PBrowser.
        mInvalidReason = "Child process tried to open an tab without the opener information.";
        return;
      } else {
        // This should be unreachable because PopupIPCTabContext::opener is not a
        // nullable field.
        mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
        return;
      }

      // Browser elements can't nest other browser elements.  So if
      // our opener is browser element, we must be a new DOM window
      // opened by it.  In that case we inherit our containing app ID
      // (if any).
      //
      // Otherwise, we're a new app window and we inherit from our
      // opener app.
      isMozBrowserElement = ipcContext.isMozBrowserElement();
      originAttributes = context->mOriginAttributes;
      if (isMozBrowserElement) {
        containingAppId = context->OwnOrContainingAppId();
      } else {
        containingAppId = context->mContainingAppId;
      }
      break;
    }
    case IPCTabContext::TFrameIPCTabContext: {
      const FrameIPCTabContext &ipcContext =
        aParams.get_FrameIPCTabContext();

      isMozBrowserElement = ipcContext.isMozBrowserElement();
      isPrerendered = ipcContext.isPrerendered();
      containingAppId = ipcContext.frameOwnerAppId();
      signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
      presentationURL = ipcContext.presentationURL();
      showAccelerators = ipcContext.showAccelerators();
      showFocusRings = ipcContext.showFocusRings();
      originAttributes = ipcContext.originAttributes();
      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
      // it might be used to escalate privileges.
#ifdef MOZ_B2G
      mInvalidReason = "ServiceWorkerClients::OpenWindow is not supported.";
      return;
#endif
      if (!Preferences::GetBool("dom.serviceWorkers.enabled", false)) {
        mInvalidReason = "ServiceWorkers should be enabled.";
        return;
      }

      containingAppId = NO_APP_ID;
      break;
    }
    default: {
      MOZ_CRASH();
    }
  }

  nsCOMPtr<mozIApplication> ownApp;
  if (!isMozBrowserElement) {
    // mAppId corresponds to OwnOrContainingAppId; if isMozBrowserElement is
    // false then it's ownApp otherwise it's containingApp
    ownApp = GetAppForId(originAttributes.mAppId);
    if ((ownApp == nullptr) != (originAttributes.mAppId == NO_APP_ID)) {
      mInvalidReason = "Got an ownAppId that didn't correspond to an app.";
      return;
    }
  }

  nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId);
  if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) {
    mInvalidReason = "Got a containingAppId that didn't correspond to an app.";
    return;
  }

  bool rv;
  rv = mTabContext.SetTabContext(isMozBrowserElement,
                                 isPrerendered,
                                 ownApp,
                                 containingApp,
                                 showAccelerators,
                                 showFocusRings,
                                 originAttributes,
                                 signedPkgOriginNoSuffix,
                                 presentationURL);
  if (!rv) {
    mInvalidReason = "Couldn't initialize TabContext.";
  }
}
Esempio n. 10
0
PRemoteOpenFileParent*
NeckoParent::AllocPRemoteOpenFileParent(const SerializedLoadContext& aSerialized,
                                        const URIParams& aURI,
                                        const OptionalURIParams& aAppURI)
{
  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
  if (!fileURL) {
    return nullptr;
  }

  // security checks
  if (UsingNeckoIPCSecurity()) {
    nsCOMPtr<nsIAppsService> appsService =
      do_GetService(APPS_SERVICE_CONTRACTID);
    if (!appsService) {
      return nullptr;
    }
    bool haveValidBrowser = false;
    bool hasManage = false;
    nsCOMPtr<mozIApplication> mozApp;
    nsTArray<TabContext> contextArray =
      static_cast<ContentParent*>(Manager())->GetManagedTabContext();
    for (uint32_t i = 0; i < contextArray.Length(); i++) {
      TabContext tabContext = contextArray[i];
      uint32_t appId = tabContext.OwnOrContainingAppId();
      // Note: this enforces that SerializedLoadContext.appID is one of the apps
      // in the child process, but there's currently no way to verify the
      // request is not from a different app in that process.
      if (appId == aSerialized.mAppId) {
        nsresult rv = appsService->GetAppByLocalId(appId, getter_AddRefs(mozApp));
        if (NS_FAILED(rv) || !mozApp) {
          break;
        }
        rv = mozApp->HasPermission("webapps-manage", &hasManage);
        if (NS_FAILED(rv)) {
          break;
        }
        haveValidBrowser = true;
        break;
      }
    }

    if (!haveValidBrowser) {
      return nullptr;
    }

    nsAutoCString requestedPath;
    fileURL->GetPath(requestedPath);
    NS_UnescapeURL(requestedPath);

    // Check if we load the whitelisted app uri for the neterror page.
    bool netErrorWhiteList = false;

    nsCOMPtr<nsIURI> appUri = DeserializeURI(aAppURI);
    if (appUri) {
      nsAdoptingString netErrorURI;
      netErrorURI = Preferences::GetString("b2g.neterror.url");
      if (netErrorURI) {
        nsAutoCString spec;
        appUri->GetSpec(spec);
        netErrorWhiteList = spec.Equals(NS_ConvertUTF16toUTF8(netErrorURI).get());
      }
    }

    // Check if we load a resource from the shared theme url space.
    // If we try to load the theme but have no permission, refuse to load.
    bool themeWhitelist = false;
    if (Preferences::GetBool("dom.mozApps.themable") && appUri) {
      nsAutoCString origin;
      nsPrincipal::GetOriginForURI(appUri, getter_Copies(origin));
      nsAutoCString themeOrigin;
      themeOrigin = Preferences::GetCString("b2g.theme.origin");
      themeWhitelist = origin.Equals(themeOrigin);
      if (themeWhitelist) {
        bool hasThemePerm = false;
        mozApp->HasPermission("themeable", &hasThemePerm);
        if (!hasThemePerm) {
          return nullptr;
        }
      }
    }

    if (hasManage || netErrorWhiteList || themeWhitelist) {
      // webapps-manage permission means allow reading any application.zip file
      // in either the regular webapps directory, or the core apps directory (if
      // we're using one).
      NS_NAMED_LITERAL_CSTRING(appzip, "/application.zip");
      nsAutoCString pathEnd;
      requestedPath.Right(pathEnd, appzip.Length());
      if (!pathEnd.Equals(appzip)) {
        return nullptr;
      }
      nsAutoCString pathStart;
      requestedPath.Left(pathStart, mWebAppsBasePath.Length());
      if (!pathStart.Equals(mWebAppsBasePath)) {
        if (mCoreAppsBasePath.IsEmpty()) {
          return nullptr;
        }
        requestedPath.Left(pathStart, mCoreAppsBasePath.Length());
        if (!pathStart.Equals(mCoreAppsBasePath)) {
          return nullptr;
        }
      }
      // Finally: make sure there are no "../" in URI.
      // Note: not checking for symlinks (would cause I/O for each path
      // component).  So it's up to us to avoid creating symlinks that could
      // provide attack vectors.
      if (PL_strnstr(requestedPath.BeginReading(), "/../",
                     requestedPath.Length())) {
        printf_stderr("NeckoParent::AllocPRemoteOpenFile: "
                      "FATAL error: requested file URI '%s' contains '/../' "
                      "KILLING CHILD PROCESS\n", requestedPath.get());
        return nullptr;
      }
    } else {
      // regular packaged apps can only access their own application.zip file
      nsAutoString basePath;
      nsresult rv = mozApp->GetBasePath(basePath);
      if (NS_FAILED(rv)) {
        return nullptr;
      }
      nsAutoString uuid;
      rv = mozApp->GetId(uuid);
      if (NS_FAILED(rv)) {
        return nullptr;
      }
      nsPrintfCString mustMatch("%s/%s/application.zip",
                                NS_LossyConvertUTF16toASCII(basePath).get(),
                                NS_LossyConvertUTF16toASCII(uuid).get());
      if (!requestedPath.Equals(mustMatch)) {
        printf_stderr("NeckoParent::AllocPRemoteOpenFile: "
                      "FATAL error: app without webapps-manage permission is "
                      "requesting file '%s' but is only allowed to open its "
                      "own application.zip at %s: KILLING CHILD PROCESS\n",
                      requestedPath.get(), mustMatch.get());
        return nullptr;
      }
    }
  }

  RemoteOpenFileParent* parent = new RemoteOpenFileParent(fileURL);
  return parent;
}
Esempio n. 11
0
TabContext::TabContext(const IPCTabContext& aParams)
  : mInitialized(true)
{
  const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext();
  switch(appBrowser.type()) {
    case IPCTabAppBrowserContext::TPopupIPCTabContext: {
      const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();

      TabContext *context;
      if (ipcContext.openerParent()) {
        context = static_cast<TabParent*>(ipcContext.openerParent());
        if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
          // If the TabParent corresponds to a browser element, then it can only
          // open other browser elements, for security reasons.  We should have
          // checked this before calling the TabContext constructor, so this is
          // a fatal error.
          MOZ_CRASH();
        }
      }
      else if (ipcContext.openerChild()) {
        context = static_cast<TabChild*>(ipcContext.openerChild());
      }
      else {
        // This should be unreachable because PopupIPCTabContext::opener is not a
        // nullable field.
        MOZ_CRASH();
      }

      // Browser elements can't nest other browser elements.  So if
      // our opener is browser element, we must be a new DOM window
      // opened by it.  In that case we inherit our containing app ID
      // (if any).
      //
      // Otherwise, we're a new app window and we inherit from our
      // opener app.
      if (ipcContext.isBrowserElement()) {
        mIsBrowser = true;
        mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
        mContainingAppId = context->OwnOrContainingAppId();
      }
      else {
        mIsBrowser = false;
        mOwnAppId = context->mOwnAppId;
        mContainingAppId = context->mContainingAppId;
      }
      break;
    }
    case IPCTabAppBrowserContext::TAppFrameIPCTabContext: {
      const AppFrameIPCTabContext &ipcContext =
        appBrowser.get_AppFrameIPCTabContext();

      mIsBrowser = false;
      mOwnAppId = ipcContext.ownAppId();
      mContainingAppId = ipcContext.appFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: {
      const BrowserFrameIPCTabContext &ipcContext =
        appBrowser.get_BrowserFrameIPCTabContext();

      mIsBrowser = true;
      mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
      mContainingAppId = ipcContext.browserFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: {
      mIsBrowser = false;
      mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
      mContainingAppId = nsIScriptSecurityManager::NO_APP_ID;
      break;
    }
    default: {
      MOZ_CRASH();
    }
  }

  mScrollingBehavior = aParams.scrollingBehavior();
}
Esempio n. 12
0
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
  : mInvalidReason(nullptr)
{
  bool isBrowser = false;
  uint32_t ownAppId = NO_APP_ID;
  uint32_t containingAppId = NO_APP_ID;

  const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext();
  switch(appBrowser.type()) {
    case IPCTabAppBrowserContext::TPopupIPCTabContext: {
      const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();

      TabContext *context;
      if (ipcContext.openerParent()) {
        context = static_cast<TabParent*>(ipcContext.openerParent());
        if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
          // If the TabParent corresponds to a browser element, then it can only
          // open other browser elements, for security reasons.  We should have
          // checked this before calling the TabContext constructor, so this is
          // a fatal error.
          mInvalidReason = "Child is-browser process tried to "
                           "open a non-browser tab.";
          return;
        }
      } else if (ipcContext.openerChild()) {
        context = static_cast<TabChild*>(ipcContext.openerChild());
      } else {
        // This should be unreachable because PopupIPCTabContext::opener is not a
        // nullable field.
        mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
        return;
      }

      // Browser elements can't nest other browser elements.  So if
      // our opener is browser element, we must be a new DOM window
      // opened by it.  In that case we inherit our containing app ID
      // (if any).
      //
      // Otherwise, we're a new app window and we inherit from our
      // opener app.
      if (ipcContext.isBrowserElement()) {
        isBrowser = true;
        ownAppId = NO_APP_ID;
        containingAppId = context->OwnOrContainingAppId();
      } else {
        isBrowser = false;
        ownAppId = context->mOwnAppId;
        containingAppId = context->mContainingAppId;
      }
      break;
    }
    case IPCTabAppBrowserContext::TAppFrameIPCTabContext: {
      const AppFrameIPCTabContext &ipcContext =
        appBrowser.get_AppFrameIPCTabContext();

      isBrowser = false;
      ownAppId = ipcContext.ownAppId();
      containingAppId = ipcContext.appFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: {
      const BrowserFrameIPCTabContext &ipcContext =
        appBrowser.get_BrowserFrameIPCTabContext();

      isBrowser = true;
      ownAppId = NO_APP_ID;
      containingAppId = ipcContext.browserFrameOwnerAppId();
      break;
    }
    case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: {
      isBrowser = false;
      ownAppId = NO_APP_ID;
      containingAppId = NO_APP_ID;
      break;
    }
    default: {
      MOZ_CRASH();
    }
  }

  nsCOMPtr<mozIApplication> ownApp = GetAppForId(ownAppId);
  if ((ownApp == nullptr) != (ownAppId == NO_APP_ID)) {
    mInvalidReason = "Got an ownAppId that didn't correspond to an app.";
    return;
  }

  nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId);
  if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) {
    mInvalidReason = "Got a containingAppId that didn't correspond to an app.";
    return;
  }

  bool rv;
  if (isBrowser) {
    rv = mTabContext.SetTabContextForBrowserFrame(containingApp,
                                                  aParams.scrollingBehavior());
  } else {
    rv = mTabContext.SetTabContextForAppFrame(ownApp,
                                              containingApp,
                                              aParams.scrollingBehavior());
  }

  if (!rv) {
    mInvalidReason = "Couldn't initialize TabContext.";
  }
}