/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/BrowserHost.h" #include "mozilla/Unused.h" #include "mozilla/dom/CancelContentJSOptionsBinding.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/ProcessPriorityManager.h" #include "nsIObserverService.h" namespace mozilla::dom { NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserHost) NS_INTERFACE_MAP_ENTRY(nsIRemoteTab) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, RemoteBrowser) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTION_WEAK(BrowserHost, mRoot) NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserHost) NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserHost) BrowserHost::BrowserHost(BrowserParent* aParent) : mId(aParent->GetTabId()), mRoot(aParent), mEffectsInfo{EffectsInfo::FullyHidden()} { mRoot->SetBrowserHost(this); } BrowserHost* BrowserHost::GetFrom(nsIRemoteTab* aRemoteTab) { return static_cast(aRemoteTab); } TabId BrowserHost::GetTabId() const { return mId; } mozilla::layers::LayersId BrowserHost::GetLayersId() const { return mRoot->GetLayersId(); } BrowsingContext* BrowserHost::GetBrowsingContext() const { return mRoot->GetBrowsingContext(); } nsILoadContext* BrowserHost::GetLoadContext() const { RefPtr loadContext = mRoot->GetLoadContext(); return loadContext; } bool BrowserHost::CanRecv() const { return mRoot && mRoot->CanRecv(); } a11y::DocAccessibleParent* BrowserHost::GetTopLevelDocAccessible() const { return mRoot ? mRoot->GetTopLevelDocAccessible() : nullptr; } void BrowserHost::LoadURL(nsDocShellLoadState* aLoadState) { MOZ_ASSERT(aLoadState); mRoot->LoadURL(aLoadState); } void BrowserHost::ResumeLoad(uint64_t aPendingSwitchId) { mRoot->ResumeLoad(aPendingSwitchId); } void BrowserHost::DestroyStart() { mRoot->Destroy(); } void BrowserHost::DestroyComplete() { if (!mRoot) { return; } mRoot->SetOwnerElement(nullptr); mRoot->Destroy(); mRoot->SetBrowserHost(nullptr); mRoot = nullptr; nsCOMPtr os = services::GetObserverService(); if (os) { os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, this), "ipc:browser-destroyed", nullptr); } } bool BrowserHost::Show(const OwnerShowInfo& aShowInfo) { return mRoot->Show(aShowInfo); } void BrowserHost::UpdateDimensions(const nsIntRect& aRect, const ScreenIntSize& aSize) { mRoot->UpdateDimensions(aRect, aSize); } void BrowserHost::UpdateEffects(EffectsInfo aEffects) { if (!mRoot || mEffectsInfo == aEffects) { return; } mEffectsInfo = aEffects; Unused << mRoot->SendUpdateEffects(mEffectsInfo); } /* attribute boolean renderLayers; */ NS_IMETHODIMP BrowserHost::GetRenderLayers(bool* aRenderLayers) { if (!mRoot) { *aRenderLayers = false; return NS_OK; } *aRenderLayers = mRoot->GetRenderLayers(); return NS_OK; } NS_IMETHODIMP BrowserHost::SetRenderLayers(bool aRenderLayers) { if (!mRoot) { return NS_OK; } mRoot->SetRenderLayers(aRenderLayers); return NS_OK; } /* readonly attribute boolean hasLayers; */ NS_IMETHODIMP BrowserHost::GetHasLayers(bool* aHasLayers) { *aHasLayers = mRoot && mRoot->GetHasLayers(); return NS_OK; } /* attribute boolean priorityHint; */ NS_IMETHODIMP BrowserHost::SetPriorityHint(bool aPriorityHint) { if (!mRoot) { return NS_OK; } mRoot->SetPriorityHint(aPriorityHint); return NS_OK; } NS_IMETHODIMP BrowserHost::GetPriorityHint(bool* aPriorityHint) { *aPriorityHint = mRoot && mRoot->GetPriorityHint(); return NS_OK; } /* void resolutionChanged (); */ NS_IMETHODIMP BrowserHost::NotifyResolutionChanged() { if (!mRoot) { return NS_OK; } VisitAll([](BrowserParent* aBrowserParent) { aBrowserParent->NotifyResolutionChanged(); }); return NS_OK; } /* void deprioritize (); */ NS_IMETHODIMP BrowserHost::Deprioritize() { if (!mRoot) { return NS_OK; } auto* bc = GetBrowsingContext()->Canonical(); ProcessPriorityManager::BrowserPriorityChanged(bc, /* aPriority = */ false); return NS_OK; } /* void preserveLayers (in boolean aPreserveLayers); */ NS_IMETHODIMP BrowserHost::PreserveLayers(bool aPreserveLayers) { if (!mRoot) { return NS_OK; } VisitAll([&](BrowserParent* aBrowserParent) { aBrowserParent->PreserveLayers(aPreserveLayers); }); return NS_OK; } /* readonly attribute uint64_t tabId; */ NS_IMETHODIMP BrowserHost::GetTabId(uint64_t* aTabId) { *aTabId = mId; return NS_OK; } /* readonly attribute uint64_t contentProcessId; */ NS_IMETHODIMP BrowserHost::GetContentProcessId(uint64_t* aContentProcessId) { if (!mRoot) { *aContentProcessId = 0; return NS_OK; } *aContentProcessId = GetContentParent()->ChildID(); return NS_OK; } /* readonly attribute int32_t osPid; */ NS_IMETHODIMP BrowserHost::GetOsPid(int32_t* aOsPid) { if (!mRoot) { *aOsPid = 0; return NS_OK; } *aOsPid = GetContentParent()->Pid(); return NS_OK; } /* readonly attribute BrowsingContext browsingContext; */ NS_IMETHODIMP BrowserHost::GetBrowsingContext(BrowsingContext** aBc) { if (!mRoot) { *aBc = nullptr; return NS_OK; } RefPtr bc = mRoot->GetBrowsingContext(); bc.forget(aBc); return NS_OK; } /* readonly attribute boolean hasPresented; */ NS_IMETHODIMP BrowserHost::GetHasPresented(bool* aHasPresented) { if (!mRoot) { *aHasPresented = false; return NS_OK; } *aHasPresented = mRoot->GetHasPresented(); return NS_OK; } /* void transmitPermissionsForPrincipal (in nsIPrincipal aPrincipal); */ NS_IMETHODIMP BrowserHost::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal) { if (!mRoot) { return NS_OK; } return GetContentParent()->TransmitPermissionsForPrincipal(aPrincipal); } /* void createAboutBlankContentViewer(in nsIPrincipal aPrincipal, in * nsIPrincipal aPartitionedPrincipal); */ NS_IMETHODIMP BrowserHost::CreateAboutBlankContentViewer( nsIPrincipal* aPrincipal, nsIPrincipal* aPartitionedPrincipal) { if (!mRoot) { return NS_OK; } // Ensure the content process has permisisons for the new document we're about // to create in it. nsresult rv = GetContentParent()->TransmitPermissionsForPrincipal(aPrincipal); if (NS_FAILED(rv)) { return rv; } Unused << mRoot->SendCreateAboutBlankContentViewer(aPrincipal, aPartitionedPrincipal); return NS_OK; } NS_IMETHODIMP BrowserHost::MaybeCancelContentJSExecutionFromScript( nsIRemoteTab::NavigationType aNavigationType, JS::Handle aCancelContentJSOptions, JSContext* aCx) { // If we're in the process of creating a new window (via window.open), then // the load that called this function isn't a "normal" load and should be // ignored for the purposes of cancelling content JS. if (!mRoot || mRoot->CreatingWindow()) { return NS_OK; } dom::CancelContentJSOptions cancelContentJSOptions; if (!cancelContentJSOptions.Init(aCx, aCancelContentJSOptions)) { return NS_ERROR_INVALID_ARG; } if (StaticPrefs::dom_ipc_cancel_content_js_when_navigating()) { GetContentParent()->CancelContentJSExecutionIfRunning( mRoot, aNavigationType, cancelContentJSOptions); } return NS_OK; } } // namespace mozilla::dom