123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "mozilla/dom/TabContext.h"
- #include "mozilla/dom/PTabContext.h"
- #include "mozilla/dom/TabParent.h"
- #include "mozilla/dom/TabChild.h"
- #include "nsIAppsService.h"
- #include "nsIScriptSecurityManager.h"
- #include "nsServiceManagerUtils.h"
- #define NO_APP_ID (nsIScriptSecurityManager::NO_APP_ID)
- using namespace mozilla::dom::ipc;
- using namespace mozilla::layout;
- namespace mozilla {
- namespace dom {
- TabContext::TabContext()
- : mIsPrerendered(false)
- , mInitialized(false)
- , mIsMozBrowserElement(false)
- , mContainingAppId(NO_APP_ID)
- , mShowAccelerators(UIStateChangeType_NoChange)
- , mShowFocusRings(UIStateChangeType_NoChange)
- {
- }
- bool
- TabContext::IsMozBrowserElement() const
- {
- return mIsMozBrowserElement;
- }
- bool
- TabContext::IsIsolatedMozBrowserElement() const
- {
- return mOriginAttributes.mInIsolatedMozBrowser;
- }
- bool
- TabContext::IsMozBrowserOrApp() const
- {
- return HasOwnApp() || IsMozBrowserElement();
- }
- uint32_t
- TabContext::OwnAppId() const
- {
- return mOriginAttributes.mAppId;
- }
- already_AddRefed<mozIApplication>
- TabContext::GetOwnApp() const
- {
- nsCOMPtr<mozIApplication> ownApp = mOwnApp;
- return ownApp.forget();
- }
- bool
- TabContext::HasOwnApp() const
- {
- nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
- return !!ownApp;
- }
- uint32_t
- TabContext::BrowserOwnerAppId() const
- {
- if (IsMozBrowserElement()) {
- return mContainingAppId;
- }
- return NO_APP_ID;
- }
- already_AddRefed<mozIApplication>
- TabContext::GetBrowserOwnerApp() const
- {
- nsCOMPtr<mozIApplication> ownerApp;
- if (IsMozBrowserElement()) {
- ownerApp = mContainingApp;
- }
- return ownerApp.forget();
- }
- bool
- TabContext::HasBrowserOwnerApp() const
- {
- nsCOMPtr<mozIApplication> ownerApp = GetBrowserOwnerApp();
- return !!ownerApp;
- }
- uint32_t
- TabContext::AppOwnerAppId() const
- {
- if (HasOwnApp()) {
- return mContainingAppId;
- }
- return NO_APP_ID;
- }
- already_AddRefed<mozIApplication>
- TabContext::GetAppOwnerApp() const
- {
- nsCOMPtr<mozIApplication> ownerApp;
- if (HasOwnApp()) {
- ownerApp = mContainingApp;
- }
- return ownerApp.forget();
- }
- bool
- TabContext::HasAppOwnerApp() const
- {
- nsCOMPtr<mozIApplication> ownerApp = GetAppOwnerApp();
- return !!ownerApp;
- }
- uint32_t
- TabContext::OwnOrContainingAppId() const
- {
- if (HasOwnApp()) {
- return mOriginAttributes.mAppId;
- }
- return mContainingAppId;
- }
- already_AddRefed<mozIApplication>
- TabContext::GetOwnOrContainingApp() const
- {
- nsCOMPtr<mozIApplication> ownOrContainingApp;
- if (HasOwnApp()) {
- ownOrContainingApp = mOwnApp;
- } else {
- ownOrContainingApp = mContainingApp;
- }
- return ownOrContainingApp.forget();
- }
- bool
- TabContext::HasOwnOrContainingApp() const
- {
- nsCOMPtr<mozIApplication> ownOrContainingApp = GetOwnOrContainingApp();
- return !!ownOrContainingApp;
- }
- bool
- TabContext::SetTabContext(const TabContext& aContext)
- {
- NS_ENSURE_FALSE(mInitialized, false);
- *this = aContext;
- mInitialized = true;
- return true;
- }
- void
- TabContext::SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing)
- {
- mOriginAttributes.SyncAttributesWithPrivateBrowsing(aIsPrivateBrowsing);
- }
- 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) {
- return false;
- }
- mIsMozBrowserElement = aContext.mIsMozBrowserElement;
- return true;
- }
- const DocShellOriginAttributes&
- TabContext::OriginAttributesRef() const
- {
- return mOriginAttributes;
- }
- UIStateChangeType
- TabContext::ShowAccelerators() const
- {
- return mShowAccelerators;
- }
- UIStateChangeType
- TabContext::ShowFocusRings() const
- {
- return mShowFocusRings;
- }
- bool
- TabContext::SetTabContext(bool aIsMozBrowserElement,
- bool aIsPrerendered,
- mozIApplication* aOwnApp,
- mozIApplication* aAppFrameOwnerApp,
- UIStateChangeType aShowAccelerators,
- UIStateChangeType aShowFocusRings,
- const DocShellOriginAttributes& aOriginAttributes)
- {
- 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);
- NS_ENSURE_SUCCESS(rv, false);
- NS_ENSURE_TRUE(ownAppId != NO_APP_ID, false);
- }
- uint32_t containingAppId = NO_APP_ID;
- if (aAppFrameOwnerApp) {
- nsresult rv = aAppFrameOwnerApp->GetLocalId(&containingAppId);
- NS_ENSURE_SUCCESS(rv, false);
- NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
- }
- // Veryify that app id matches mAppId passed in originAttributes
- MOZ_RELEASE_ASSERT((aOwnApp && aOriginAttributes.mAppId == ownAppId) ||
- (aAppFrameOwnerApp && aOriginAttributes.mAppId == containingAppId) ||
- aOriginAttributes.mAppId == NO_APP_ID);
- mInitialized = true;
- mIsMozBrowserElement = aIsMozBrowserElement;
- mIsPrerendered = aIsPrerendered;
- mOriginAttributes = aOriginAttributes;
- mContainingAppId = containingAppId;
- mOwnApp = aOwnApp;
- mContainingApp = aAppFrameOwnerApp;
- mShowAccelerators = aShowAccelerators;
- mShowFocusRings = aShowFocusRings;
- return true;
- }
- IPCTabContext
- TabContext::AsIPCTabContext() const
- {
- return IPCTabContext(FrameIPCTabContext(mOriginAttributes,
- mContainingAppId,
- mIsMozBrowserElement,
- mIsPrerendered,
- mShowAccelerators,
- mShowFocusRings));
- }
- static already_AddRefed<mozIApplication>
- GetAppForId(uint32_t aAppId)
- {
- nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
- NS_ENSURE_TRUE(appsService, nullptr);
- nsCOMPtr<mozIApplication> app;
- appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
- return app.forget();
- }
- MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
- : mInvalidReason(nullptr)
- {
- bool isMozBrowserElement = false;
- bool isPrerendered = false;
- uint32_t containingAppId = NO_APP_ID;
- DocShellOriginAttributes originAttributes;
- 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();
- 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.
- 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);
- if (!rv) {
- mInvalidReason = "Couldn't initialize TabContext.";
- }
- }
- bool
- MaybeInvalidTabContext::IsValid()
- {
- return mInvalidReason == nullptr;
- }
- const char*
- MaybeInvalidTabContext::GetInvalidReason()
- {
- return mInvalidReason;
- }
- const TabContext&
- MaybeInvalidTabContext::GetTabContext()
- {
- if (!IsValid()) {
- MOZ_CRASH("Can't GetTabContext() if !IsValid().");
- }
- return mTabContext;
- }
- } // namespace dom
- } // namespace mozilla
|