BrowserHost.cpp (8320B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 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/. */ 6 7 #include "mozilla/dom/BrowserHost.h" 8 9 #include "mozilla/ProcessPriorityManager.h" 10 #include "mozilla/dom/BrowsingContextGroup.h" 11 #include "mozilla/dom/CancelContentJSOptionsBinding.h" 12 #include "mozilla/dom/ContentParent.h" 13 #include "mozilla/dom/WindowGlobalParent.h" 14 #include "nsIObserverService.h" 15 16 namespace mozilla::dom { 17 18 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserHost) 19 NS_INTERFACE_MAP_ENTRY(nsIRemoteTab) 20 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) 21 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, RemoteBrowser) 22 NS_INTERFACE_MAP_END 23 24 NS_IMPL_CYCLE_COLLECTION_WEAK(BrowserHost, mRoot) 25 26 NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserHost) 27 NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserHost) 28 29 BrowserHost::BrowserHost(BrowserParent* aParent) 30 : mId(aParent->GetTabId()), 31 mRoot(aParent), 32 mEffectsInfo{EffectsInfo::FullyHidden()} { 33 mRoot->SetBrowserHost(this); 34 } 35 36 BrowserHost* BrowserHost::GetFrom(nsIRemoteTab* aRemoteTab) { 37 return static_cast<BrowserHost*>(aRemoteTab); 38 } 39 40 TabId BrowserHost::GetTabId() const { return mId; } 41 42 mozilla::layers::LayersId BrowserHost::GetLayersId() const { 43 return mRoot->GetLayersId(); 44 } 45 46 BrowsingContext* BrowserHost::GetBrowsingContext() const { 47 return mRoot->GetBrowsingContext(); 48 } 49 50 nsILoadContext* BrowserHost::GetLoadContext() const { 51 RefPtr<nsILoadContext> loadContext = mRoot->GetLoadContext(); 52 return loadContext; 53 } 54 55 bool BrowserHost::CanRecv() const { return mRoot && mRoot->CanRecv(); } 56 57 a11y::DocAccessibleParent* BrowserHost::GetTopLevelDocAccessible() const { 58 return mRoot ? mRoot->GetTopLevelDocAccessible() : nullptr; 59 } 60 61 void BrowserHost::LoadURL(nsDocShellLoadState* aLoadState) { 62 MOZ_ASSERT(aLoadState); 63 mRoot->LoadURL(aLoadState); 64 } 65 66 void BrowserHost::ResumeLoad(uint64_t aPendingSwitchId) { 67 mRoot->ResumeLoad(aPendingSwitchId); 68 } 69 70 void BrowserHost::DestroyStart() { mRoot->Destroy(); } 71 72 void BrowserHost::DestroyComplete() { 73 if (!mRoot) { 74 return; 75 } 76 mRoot->SetOwnerElement(nullptr); 77 mRoot->Destroy(); 78 mRoot->SetBrowserHost(nullptr); 79 mRoot = nullptr; 80 81 nsCOMPtr<nsIObserverService> os = services::GetObserverService(); 82 if (os) { 83 os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, this), 84 "ipc:browser-destroyed", nullptr); 85 } 86 } 87 88 bool BrowserHost::Show(const OwnerShowInfo& aShowInfo) { 89 return mRoot->Show(aShowInfo); 90 } 91 92 void BrowserHost::UpdateDimensions(const LayoutDeviceIntRect& aRect, 93 const LayoutDeviceIntSize& aSize) { 94 mRoot->UpdateDimensions(aRect, aSize); 95 } 96 97 void BrowserHost::UpdateEffects(EffectsInfo aEffects) { 98 if (!mRoot || mEffectsInfo == aEffects) { 99 return; 100 } 101 mEffectsInfo = aEffects; 102 (void)mRoot->SendUpdateEffects(mEffectsInfo); 103 } 104 105 /* attribute boolean renderLayers; */ 106 NS_IMETHODIMP 107 BrowserHost::GetRenderLayers(bool* aRenderLayers) { 108 if (!mRoot) { 109 *aRenderLayers = false; 110 return NS_OK; 111 } 112 *aRenderLayers = mRoot->GetRenderLayers(); 113 return NS_OK; 114 } 115 116 NS_IMETHODIMP 117 BrowserHost::SetRenderLayers(bool aRenderLayers) { 118 if (!mRoot) { 119 return NS_OK; 120 } 121 122 mRoot->SetRenderLayers(aRenderLayers); 123 return NS_OK; 124 } 125 126 /* readonly attribute boolean hasLayers; */ 127 NS_IMETHODIMP 128 BrowserHost::GetHasLayers(bool* aHasLayers) { 129 *aHasLayers = mRoot && mRoot->GetHasLayers(); 130 return NS_OK; 131 } 132 133 /* attribute boolean priorityHint; */ 134 NS_IMETHODIMP 135 BrowserHost::SetPriorityHint(bool aPriorityHint) { 136 if (!mRoot) { 137 return NS_OK; 138 } 139 mRoot->SetPriorityHint(aPriorityHint); 140 return NS_OK; 141 } 142 143 NS_IMETHODIMP 144 BrowserHost::GetPriorityHint(bool* aPriorityHint) { 145 *aPriorityHint = mRoot && mRoot->GetPriorityHint(); 146 return NS_OK; 147 } 148 149 /* void resolutionChanged (); */ 150 NS_IMETHODIMP 151 BrowserHost::NotifyResolutionChanged() { 152 if (!mRoot) { 153 return NS_OK; 154 } 155 VisitAll([](BrowserParent* aBrowserParent) { 156 aBrowserParent->NotifyResolutionChanged(); 157 }); 158 return NS_OK; 159 } 160 161 /* void deprioritize (); */ 162 NS_IMETHODIMP 163 BrowserHost::Deprioritize() { 164 if (!mRoot) { 165 return NS_OK; 166 } 167 auto* bc = GetBrowsingContext()->Canonical(); 168 ProcessPriorityManager::BrowserPriorityChanged(bc, 169 /* aPriority = */ false); 170 return NS_OK; 171 } 172 173 /* void preserveLayers (in boolean aPreserveLayers); */ 174 NS_IMETHODIMP 175 BrowserHost::PreserveLayers(bool aPreserveLayers) { 176 if (!mRoot) { 177 return NS_OK; 178 } 179 VisitAll([&](BrowserParent* aBrowserParent) { 180 aBrowserParent->PreserveLayers(aPreserveLayers); 181 }); 182 return NS_OK; 183 } 184 185 /* readonly attribute uint64_t tabId; */ 186 NS_IMETHODIMP 187 BrowserHost::GetTabId(uint64_t* aTabId) { 188 *aTabId = mId; 189 return NS_OK; 190 } 191 192 /* readonly attribute uint64_t contentProcessId; */ 193 NS_IMETHODIMP 194 BrowserHost::GetContentProcessId(uint64_t* aContentProcessId) { 195 if (!mRoot) { 196 *aContentProcessId = 0; 197 return NS_OK; 198 } 199 *aContentProcessId = GetContentParent()->ChildID(); 200 return NS_OK; 201 } 202 203 /* readonly attribute int32_t osPid; */ 204 NS_IMETHODIMP 205 BrowserHost::GetOsPid(int32_t* aOsPid) { 206 if (!mRoot) { 207 *aOsPid = 0; 208 return NS_OK; 209 } 210 *aOsPid = GetContentParent()->Pid(); 211 return NS_OK; 212 } 213 214 /* readonly attribute BrowsingContext browsingContext; */ 215 NS_IMETHODIMP 216 BrowserHost::GetBrowsingContext(BrowsingContext** aBc) { 217 if (!mRoot) { 218 *aBc = nullptr; 219 return NS_OK; 220 } 221 RefPtr<BrowsingContext> bc = mRoot->GetBrowsingContext(); 222 bc.forget(aBc); 223 return NS_OK; 224 } 225 226 /* readonly attribute boolean hasPresented; */ 227 NS_IMETHODIMP 228 BrowserHost::GetHasPresented(bool* aHasPresented) { 229 if (!mRoot) { 230 *aHasPresented = false; 231 return NS_OK; 232 } 233 *aHasPresented = mRoot->GetHasPresented(); 234 return NS_OK; 235 } 236 237 /* void transmitPermissionsForPrincipal (in nsIPrincipal aPrincipal); */ 238 NS_IMETHODIMP 239 BrowserHost::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal) { 240 if (!mRoot) { 241 return NS_OK; 242 } 243 return GetContentParent()->TransmitPermissionsForPrincipal(aPrincipal); 244 } 245 246 /* void createAboutBlankDocumentViewer(in nsIPrincipal aPrincipal, in 247 * nsIPrincipal aPartitionedPrincipal); */ 248 NS_IMETHODIMP 249 BrowserHost::CreateAboutBlankDocumentViewer( 250 nsIPrincipal* aPrincipal, nsIPrincipal* aPartitionedPrincipal) { 251 if (!mRoot) { 252 return NS_OK; 253 } 254 255 // Before creating the viewer in-content, ensure that the process is allowed 256 // to load this principal. 257 if (NS_WARN_IF(!mRoot->Manager()->ValidatePrincipal(aPrincipal))) { 258 ContentParent::LogAndAssertFailedPrincipalValidationInfo( 259 aPrincipal, "BrowserHost::CreateAboutBlankDocumentViewer"); 260 return NS_ERROR_DOM_SECURITY_ERR; 261 } 262 263 // Ensure the content process has permisisons for the new document we're about 264 // to create in it. 265 nsresult rv = GetContentParent()->TransmitPermissionsForPrincipal(aPrincipal); 266 if (NS_FAILED(rv)) { 267 return rv; 268 } 269 270 // Ensure that UsesOriginAgentCluster has been initialized for this 271 // BrowsingContextGroup/principal pair before creating the document in 272 // content. 273 mRoot->GetBrowsingContext()->Group()->EnsureUsesOriginAgentClusterInitialized( 274 aPrincipal); 275 276 (void)mRoot->SendCreateAboutBlankDocumentViewer(aPrincipal, 277 aPartitionedPrincipal); 278 return NS_OK; 279 } 280 281 NS_IMETHODIMP 282 BrowserHost::MaybeCancelContentJSExecutionFromScript( 283 nsIRemoteTab::NavigationType aNavigationType, 284 JS::Handle<JS::Value> aCancelContentJSOptions, JSContext* aCx) { 285 // If we're in the process of creating a new window (via window.open), then 286 // the load that called this function isn't a "normal" load and should be 287 // ignored for the purposes of cancelling content JS. 288 if (!mRoot || mRoot->CreatingWindow()) { 289 return NS_OK; 290 } 291 dom::CancelContentJSOptions cancelContentJSOptions; 292 if (!cancelContentJSOptions.Init(aCx, aCancelContentJSOptions)) { 293 return NS_ERROR_INVALID_ARG; 294 } 295 GetContentParent()->CancelContentJSExecutionIfRunning(mRoot, aNavigationType, 296 cancelContentJSOptions); 297 return NS_OK; 298 } 299 300 } // namespace mozilla::dom