Bug Summary

File:root/firefox-clang/dom/base/nsGlobalWindowInner.cpp
Warning:line 5413, column 7
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nsGlobalWindowInner.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/base -I /root/firefox-clang/dom/battery -I /root/firefox-clang/dom/events -I /root/firefox-clang/dom/media -I /root/firefox-clang/dom/network -I /root/firefox-clang/caps -I /root/firefox-clang/docshell/base -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/file -I /root/firefox-clang/dom/geolocation -I /root/firefox-clang/dom/html -I /root/firefox-clang/dom/ipc -I /root/firefox-clang/dom/storage -I /root/firefox-clang/dom/svg -I /root/firefox-clang/dom/xml -I /root/firefox-clang/dom/xslt/xpath -I /root/firefox-clang/dom/xul -I /root/firefox-clang/extensions/spellcheck/src -I /root/firefox-clang/gfx/2d -I /root/firefox-clang/image -I /root/firefox-clang/js/xpconnect/loader -I /root/firefox-clang/js/xpconnect/src -I /root/firefox-clang/js/xpconnect/wrappers -I /root/firefox-clang/layout/base -I /root/firefox-clang/layout/forms -I /root/firefox-clang/layout/generic -I /root/firefox-clang/layout/style -I /root/firefox-clang/layout/xul -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/protocol/http -I /root/firefox-clang/netwerk/url-classifier -I /root/firefox-clang/parser/htmlparser -I /root/firefox-clang/security/manager/ssl -I /root/firefox-clang/third_party/xsimd/include -I /root/firefox-clang/widget -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/xpcom/ds -I /root/firefox-clang/netwerk/sctp/datachannel -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/dom/base/nsGlobalWindowInner.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsGlobalWindowInner.h"
6
7#include <inttypes.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <cstdint>
13#include <new>
14#include <utility>
15
16#include "AudioChannelService.h"
17#include "AutoplayPolicy.h"
18#include "Crypto.h"
19#include "MainThreadUtils.h"
20#include "Navigator.h"
21#include "PaintWorkletImpl.h"
22#include "SessionStorageCache.h"
23#include "Units.h"
24#include "VRManagerChild.h"
25#include "WindowDestroyedEvent.h"
26#include "WindowNamedPropertiesHandler.h"
27#include "js/ComparisonOperators.h"
28#include "js/CompilationAndEvaluation.h"
29#include "js/CompileOptions.h"
30#include "js/Id.h"
31#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_GetProperty
32#include "js/PropertyDescriptor.h"
33#include "js/RealmOptions.h"
34#include "js/RootingAPI.h"
35#include "js/TypeDecls.h"
36#include "js/Value.h"
37#include "js/Warnings.h"
38#include "js/friend/PerformanceHint.h"
39#include "js/loader/LoadedScript.h"
40#include "js/shadow/String.h"
41#include "jsapi.h"
42#include "jsfriendapi.h"
43#include "mozIDOMWindow.h"
44#include "moz_external_vr.h"
45#include "mozilla/AlreadyAddRefed.h"
46#include "mozilla/AppShutdown.h"
47#include "mozilla/ArrayIterator.h"
48#include "mozilla/Attributes.h"
49#include "mozilla/BaseProfilerMarkersPrerequisites.h"
50#include "mozilla/BasicEvents.h"
51#include "mozilla/CallState.h"
52#include "mozilla/Components.h"
53#include "mozilla/CycleCollectedJSContext.h"
54#include "mozilla/DOMEventTargetHelper.h"
55#include "mozilla/ErrorResult.h"
56#include "mozilla/EventDispatcher.h"
57#include "mozilla/EventListenerManager.h"
58#include "mozilla/EventQueue.h"
59#include "mozilla/ExtensionPolicyService.h"
60#include "mozilla/FloatingPoint.h"
61#include "mozilla/FlushType.h"
62#include "mozilla/Likely.h"
63#include "mozilla/Logging.h"
64#include "mozilla/LookAndFeel.h"
65#include "mozilla/Maybe.h"
66#include "mozilla/OwningNonNull.h"
67#include "mozilla/PermissionDelegateHandler.h"
68#include "mozilla/Preferences.h"
69#include "mozilla/PresShell.h"
70#include "mozilla/ProcessHangMonitor.h"
71#include "mozilla/RefPtr.h"
72#include "mozilla/Result.h"
73#include "mozilla/ScrollContainerFrame.h"
74#include "mozilla/ScrollTypes.h"
75#include "mozilla/SizeOfState.h"
76#include "mozilla/SpinEventLoopUntil.h"
77#include "mozilla/Sprintf.h"
78#include "mozilla/StaticPrefs_browser.h"
79#include "mozilla/StaticPrefs_docshell.h"
80#include "mozilla/StaticPrefs_dom.h"
81#include "mozilla/StaticPrefs_extensions.h"
82#include "mozilla/StorageAccess.h"
83#include "mozilla/StoragePrincipalHelper.h"
84#include "mozilla/TelemetryHistogramEnums.h"
85#include "mozilla/ThrottledEventQueue.h"
86#include "mozilla/TimeStamp.h"
87#include "mozilla/UniquePtr.h"
88#include "mozilla/Utf16.h"
89#include "mozilla/dom/AudioContext.h"
90#include "mozilla/dom/AutoEntryScript.h"
91#include "mozilla/dom/BarProps.h"
92#include "mozilla/dom/BindingDeclarations.h"
93#include "mozilla/dom/BindingUtils.h"
94#include "mozilla/dom/BrowserChild.h"
95#include "mozilla/dom/BrowsingContext.h"
96#include "mozilla/dom/CSPEvalChecker.h"
97#include "mozilla/dom/CallbackDebuggerNotification.h"
98#include "mozilla/dom/ChromeMessageBroadcaster.h"
99#include "mozilla/dom/ClientInfo.h"
100#include "mozilla/dom/ClientManager.h"
101#include "mozilla/dom/ClientSource.h"
102#include "mozilla/dom/ClientState.h"
103#include "mozilla/dom/ClientsBinding.h"
104#include "mozilla/dom/CloseWatcher.h"
105#include "mozilla/dom/CloseWatcherManager.h"
106#include "mozilla/dom/Console.h"
107#include "mozilla/dom/ContentChild.h"
108#include "mozilla/dom/ContentFrameMessageManager.h"
109#include "mozilla/dom/ContentMediaController.h"
110#include "mozilla/dom/CookieStore.h"
111#include "mozilla/dom/Credential.h"
112#include "mozilla/dom/CustomElementRegistry.h"
113#include "mozilla/dom/DebuggerNotification.h"
114#include "mozilla/dom/DebuggerNotificationBinding.h"
115#include "mozilla/dom/DebuggerNotificationManager.h"
116#include "mozilla/dom/DocGroup.h"
117#include "mozilla/dom/Document.h"
118#include "mozilla/dom/DocumentInlines.h"
119#include "mozilla/dom/DocumentPictureInPicture.h"
120#include "mozilla/dom/Element.h"
121#include "mozilla/dom/Event.h"
122#include "mozilla/dom/EventTarget.h"
123#include "mozilla/dom/External.h"
124#include "mozilla/dom/Fetch.h"
125#include "mozilla/dom/Gamepad.h"
126#include "mozilla/dom/GamepadHandle.h"
127#include "mozilla/dom/GamepadManager.h"
128#include "mozilla/dom/HashChangeEvent.h"
129#include "mozilla/dom/HashChangeEventBinding.h"
130#include "mozilla/dom/IDBFactory.h"
131#include "mozilla/dom/IdleRequest.h"
132#include "mozilla/dom/ImageBitmap.h"
133#include "mozilla/dom/ImageBitmapSource.h"
134#include "mozilla/dom/IntlUtils.h"
135#include "mozilla/dom/JSExecutionUtils.h" // mozilla::dom::Compile, mozilla::dom::EvaluationExceptionToNSResult
136#include "mozilla/dom/LSObject.h"
137#include "mozilla/dom/LocalStorage.h"
138#include "mozilla/dom/LocalStorageCommon.h"
139#include "mozilla/dom/Location.h"
140#include "mozilla/dom/MediaDevices.h"
141#include "mozilla/dom/MediaKeys.h"
142#include "mozilla/dom/ModuleLoader.h"
143#include "mozilla/dom/Navigation.h"
144#include "mozilla/dom/NavigatorBinding.h"
145#include "mozilla/dom/Nullable.h"
146#include "mozilla/dom/PartitionedLocalStorage.h"
147#include "mozilla/dom/Performance.h"
148#include "mozilla/dom/PerformanceMainThread.h"
149#include "mozilla/dom/PolicyContainer.h"
150#include "mozilla/dom/PopStateEvent.h"
151#include "mozilla/dom/PopStateEventBinding.h"
152#include "mozilla/dom/PopupBlocker.h"
153#include "mozilla/dom/PrimitiveConversions.h"
154#include "mozilla/dom/Promise.h"
155#include "mozilla/dom/PushManager.h"
156#include "mozilla/dom/RootedDictionary.h"
157#include "mozilla/dom/ScriptLoader.h"
158#include "mozilla/dom/ScriptSettings.h"
159#include "mozilla/dom/ServiceWorker.h"
160#include "mozilla/dom/ServiceWorkerDescriptor.h"
161#include "mozilla/dom/ServiceWorkerRegistration.h"
162#include "mozilla/dom/SessionStorageManager.h"
163#include "mozilla/dom/SharedWorker.h"
164#include "mozilla/dom/Storage.h"
165#include "mozilla/dom/StorageEvent.h"
166#include "mozilla/dom/StorageEventBinding.h"
167#include "mozilla/dom/StorageNotifierService.h"
168#include "mozilla/dom/StorageUtils.h"
169#include "mozilla/dom/TabMessageTypes.h"
170#include "mozilla/dom/Timeout.h"
171#include "mozilla/dom/TimeoutHandler.h"
172#include "mozilla/dom/TimeoutManager.h"
173#include "mozilla/dom/ToJSValue.h"
174#include "mozilla/dom/TrustedTypePolicyFactory.h"
175#include "mozilla/dom/TrustedTypeUtils.h"
176#include "mozilla/dom/TrustedTypesConstants.h"
177#include "mozilla/dom/VRDisplay.h"
178#include "mozilla/dom/VRDisplayEvent.h"
179#include "mozilla/dom/VRDisplayEventBinding.h"
180#include "mozilla/dom/VREventObserver.h"
181#include "mozilla/dom/VisualViewport.h"
182#include "mozilla/dom/WebCompatBinding.h"
183#include "mozilla/dom/WebIDLGlobalNameHash.h"
184#include "mozilla/dom/WebIdentityHandler.h"
185#include "mozilla/dom/WebTaskSchedulerMainThread.h"
186#include "mozilla/dom/WindowBinding.h"
187#include "mozilla/dom/WindowContext.h"
188#include "mozilla/dom/WindowGlobalChild.h"
189#include "mozilla/dom/WindowOrWorkerGlobalScopeBinding.h"
190#include "mozilla/dom/WindowProxyHolder.h"
191#include "mozilla/dom/WorkerCommon.h"
192#include "mozilla/dom/Worklet.h"
193#include "mozilla/dom/XRPermissionRequest.h"
194#include "mozilla/dom/cache/CacheStorage.h"
195#include "mozilla/dom/cache/Types.h"
196#include "mozilla/extensions/WebExtensionPolicy.h"
197#include "mozilla/fallible.h"
198#include "mozilla/gfx/BasePoint.h"
199#include "mozilla/gfx/BaseRect.h"
200#include "mozilla/gfx/BaseSize.h"
201#include "mozilla/gfx/Rect.h"
202#include "mozilla/gfx/Types.h"
203#include "mozilla/glean/DomMetrics.h"
204#include "mozilla/glean/bindings/Glean.h"
205#include "mozilla/glean/bindings/GleanPings.h"
206#include "mozilla/intl/LocaleService.h"
207#include "mozilla/ipc/BackgroundUtils.h"
208#include "mozilla/ipc/PBackgroundSharedTypes.h"
209#include "mozilla/net/CookieJarSettings.h"
210#include "nsAtom.h"
211#include "nsBaseHashtable.h"
212#include "nsCCUncollectableMarker.h"
213#include "nsCOMPtr.h"
214#include "nsCRT.h"
215#include "nsCRTGlue.h"
216#include "nsCanvasFrame.h"
217#include "nsCheapSets.h"
218#include "nsContentUtils.h"
219#include "nsCoord.h"
220#include "nsCycleCollectionNoteChild.h"
221#include "nsCycleCollectionTraversalCallback.h"
222#include "nsDOMNavigationTiming.h"
223#include "nsDebug.h"
224#include "nsDeviceContext.h"
225#include "nsDocShell.h"
226#include "nsFocusManager.h"
227#include "nsFrameMessageManager.h"
228#include "nsGkAtoms.h"
229#include "nsGlobalWindowOuter.h"
230#include "nsHashKeys.h"
231#include "nsHistory.h"
232#include "nsIAddonPolicyService.h"
233#include "nsIArray.h"
234#include "nsIBrowserChild.h"
235#include "nsICancelableRunnable.h"
236#include "nsIChannel.h"
237#include "nsIClipboard.h"
238#include "nsIContentSecurityPolicy.h"
239#include "nsIControllers.h"
240#include "nsICookieJarSettings.h"
241#include "nsICookieService.h"
242#include "nsID.h"
243#include "nsIDOMStorageManager.h"
244#include "nsIDOMXULControlElement.h"
245#include "nsIDeviceSensors.h"
246#include "nsIDocShell.h"
247#include "nsIDocShellTreeItem.h"
248#include "nsIDocShellTreeOwner.h"
249#include "nsIDocumentLoader.h"
250#include "nsIDragService.h"
251#include "nsIFocusManager.h"
252#include "nsIFrame.h"
253#include "nsIGlobalObject.h"
254#include "nsIIOService.h"
255#include "nsIIdleRunnable.h"
256#include "nsIInterfaceRequestorUtils.h"
257#include "nsILoadContext.h"
258#include "nsILoadGroup.h"
259#include "nsILoadInfo.h"
260#include "nsINamed.h"
261#include "nsINode.h"
262#include "nsIObserver.h"
263#include "nsIObserverService.h"
264#include "nsIPermission.h"
265#include "nsIPermissionManager.h"
266#include "nsIPrefBranch.h"
267#include "nsIPrincipal.h"
268#include "nsIPrintSettings.h"
269#include "nsIPrompt.h"
270#include "nsIRunnable.h"
271#include "nsIScreen.h"
272#include "nsIScreenManager.h"
273#include "nsIScriptContext.h"
274#include "nsIScriptGlobalObject.h"
275#include "nsIScriptObjectPrincipal.h"
276#include "nsISerialEventTarget.h"
277#include "nsISimpleEnumerator.h"
278#include "nsISizeOfEventTarget.h"
279#include "nsISlowScriptDebug.h"
280#include "nsISupportsPrimitives.h"
281#include "nsISupportsUtils.h"
282#include "nsIThread.h"
283#include "nsITimedChannel.h"
284#include "nsIURI.h"
285#include "nsIWeakReference.h"
286#include "nsIWebBrowserChrome.h"
287#include "nsIWebNavigation.h"
288#include "nsIWebProgressListener.h"
289#include "nsIWidget.h"
290#include "nsIWidgetListener.h"
291#include "nsIXULRuntime.h"
292#include "nsJSPrincipals.h"
293#include "nsJSUtils.h"
294#include "nsLayoutStatics.h"
295#include "nsLiteralString.h"
296#include "nsNetUtil.h"
297#include "nsPIDOMWindow.h"
298#include "nsPIDOMWindowInlines.h"
299#include "nsPIWindowRoot.h"
300#include "nsPoint.h"
301#include "nsPresContext.h"
302#include "nsQueryObject.h"
303#include "nsSandboxFlags.h"
304#include "nsScreen.h"
305#include "nsServiceManagerUtils.h"
306#include "nsString.h"
307#include "nsStringFlags.h"
308#include "nsStringFwd.h"
309#include "nsTArray.h"
310#include "nsTLiteralString.h"
311#include "nsTObserverArray.h"
312#include "nsTStringRepr.h"
313#include "nsThreadUtils.h"
314#include "nsWeakReference.h"
315#include "nsWindowMemoryReporter.h"
316#include "nsWindowSizes.h"
317#include "nsWrapperCache.h"
318#include "nsWrapperCacheInlines.h"
319#include "nsXULAppAPI.h"
320#include "nsrootidl.h"
321#include "prclist.h"
322#include "prtypes.h"
323#include "xpcprivate.h"
324#include "xpcpublic.h"
325
326#ifdef MOZ_WEBSPEECH1
327# include "mozilla/dom/SpeechSynthesis.h"
328#endif
329
330#ifdef ANDROID
331# include <android/log.h>
332#endif
333
334#ifdef XP_WIN
335# include <process.h>
336
337# include "mozilla/Debug.h"
338# define getpid _getpid
339#else
340# include <unistd.h> // for getpid()
341#endif
342
343using namespace mozilla;
344using namespace mozilla::dom;
345using namespace mozilla::dom::ipc;
346using mozilla::TimeDuration;
347using mozilla::TimeStamp;
348using mozilla::dom::GamepadHandle;
349using mozilla::dom::cache::CacheStorage;
350
351#define FORWARD_TO_OUTER(method, args, err_rval) \
352 PR_BEGIN_MACROdo { \
353 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
354 if (!HasActiveDocument()) { \
355 NS_WARNING(outer ? "Inner window does not have active document." \NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 356)
356 : "No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 356)
; \
357 return err_rval; \
358 } \
359 return outer->method args; \
360 PR_END_MACRO} while (0)
361
362static nsGlobalWindowOuter* GetOuterWindowForForwarding(
363 nsGlobalWindowInner* aInner, ErrorResult& aError) {
364 nsGlobalWindowOuter* outer = aInner->GetOuterWindowInternal();
365 if (MOZ_LIKELY(aInner->HasActiveDocument())(__builtin_expect(!!(aInner->HasActiveDocument()), 1))) {
366 return outer;
367 }
368 if (!outer) {
369 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 369)
;
370 aError.Throw(NS_ERROR_NOT_INITIALIZED);
371 } else {
372 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
373 }
374 return nullptr;
375}
376
377#define FORWARD_TO_OUTER_OR_THROW(method, args, rv, err_rval) \
378 PR_BEGIN_MACROdo { \
379 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowForForwarding(this, rv); \
380 if (MOZ_LIKELY(outer)(__builtin_expect(!!(outer), 1))) { \
381 return outer->method args; \
382 } \
383 return err_rval; \
384 PR_END_MACRO} while (0)
385
386#define FORWARD_TO_OUTER_VOID(method, args) \
387 PR_BEGIN_MACROdo { \
388 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
389 if (!HasActiveDocument()) { \
390 NS_WARNING(outer ? "Inner window does not have active document." \NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 391)
391 : "No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, outer ? "Inner window does not have active document."
: "No outer window available!", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 391)
; \
392 return; \
393 } \
394 outer->method args; \
395 return; \
396 PR_END_MACRO} while (0)
397
398#define ENSURE_ACTIVE_DOCUMENT(errorresult, err_rval)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return err_rval; }
} while (0)
\
399 PR_BEGIN_MACROdo { \
400 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) { \
401 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); \
402 return err_rval; \
403 } \
404 PR_END_MACRO} while (0)
405
406#define DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added" "dom-touch-listener-added"
407#define MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure" "memory-pressure"
408#define PERMISSION_CHANGED_TOPIC"perm-changed" "perm-changed"
409
410static LazyLogModule gDOMLeakPRLogInner("DOMLeakInner");
411extern mozilla::LazyLogModule gTimeoutLog;
412
413#ifdef DEBUG1
414static LazyLogModule gDocShellAndDOMWindowLeakLogging(
415 "DocShellAndDOMWindowLeak");
416#endif
417
418static FILE* gDumpFile = nullptr;
419
420mozilla::StaticAutoPtr<nsGlobalWindowInner::InnerWindowByIdTable>
421 nsGlobalWindowInner::sInnerWindowsById;
422
423bool nsGlobalWindowInner::sDragServiceDisabled = false;
424bool nsGlobalWindowInner::sMouseDown = false;
425
426/**
427 * An indirect observer object that means we don't have to implement nsIObserver
428 * on nsGlobalWindow, where any script could see it.
429 */
430class nsGlobalWindowObserver final : public nsIObserver,
431 public nsIInterfaceRequestor,
432 public StorageNotificationObserver {
433 public:
434 explicit nsGlobalWindowObserver(nsGlobalWindowInner* aWindow)
435 : mWindow(aWindow) {}
436 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
437 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODvirtual nsresult
438 Observe(nsISupports* aSubject, const char* aTopic,
439 const char16_t* aData) override {
440 if (!mWindow) return NS_OK;
441 const RefPtr<nsGlobalWindowInner> win = mWindow;
442 return win->Observe(aSubject, aTopic, aData);
443 }
444 void Forget() { mWindow = nullptr; }
445 NS_IMETHODvirtual nsresult GetInterface(const nsIID& aIID, void** aResult) override {
446 if (mWindow && aIID.Equals(NS_GET_IID(nsIDOMWindow)(nsIDOMWindow::kIID)) && mWindow) {
447 return mWindow->QueryInterface(aIID, aResult);
448 }
449 return NS_NOINTERFACE;
450 }
451
452 void ObserveStorageNotification(StorageEvent* aEvent,
453 const char16_t* aStorageType,
454 bool aPrivateBrowsing) override {
455 if (mWindow) {
456 mWindow->ObserveStorageNotification(aEvent, aStorageType,
457 aPrivateBrowsing);
458 }
459 }
460
461 nsIPrincipal* GetEffectiveCookiePrincipal() const override {
462 return mWindow ? mWindow->GetEffectiveCookiePrincipal() : nullptr;
463 }
464
465 nsIPrincipal* GetEffectiveStoragePrincipal() const override {
466 return mWindow ? mWindow->GetEffectiveStoragePrincipal() : nullptr;
467 }
468
469 bool IsPrivateBrowsing() const override {
470 return mWindow ? mWindow->IsPrivateBrowsing() : false;
471 }
472
473 nsIEventTarget* GetEventTarget() const override {
474 return mWindow ? mWindow->SerialEventTarget() : nullptr;
475 }
476
477 private:
478 ~nsGlobalWindowObserver() = default;
479
480 // This reference is non-owning and safe because it's cleared by
481 // nsGlobalWindowInner::FreeInnerObjects().
482 nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
483};
484
485NS_IMPL_ISUPPORTS(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)MozExternalRefCountType nsGlobalWindowObserver::AddRef(void) {
static_assert(!std::is_destructible_v<nsGlobalWindowObserver
>, "Reference-counted class " "nsGlobalWindowObserver" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 485
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsGlobalWindowObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsGlobalWindowObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsGlobalWindowObserver\" != nullptr"
" (" "Must specify a name" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 485); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsGlobalWindowObserver" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("nsGlobalWindowObserver"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
nsGlobalWindowObserver::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 485
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsGlobalWindowObserver" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("nsGlobalWindowObserver" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"nsGlobalWindowObserver\" != nullptr"
" (" "Must specify a name" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 485); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsGlobalWindowObserver" " not thread-safe"); const char* const
nametmp = "nsGlobalWindowObserver"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
nsGlobalWindowObserver::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 485); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsGlobalWindowObserver, nsIObserver>,
int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((nsGlobalWindowObserver*)0x1000)) - reinterpret_cast<
char*>((nsGlobalWindowObserver*)0x1000))}, {&mozilla::
detail::kImplementedIID<nsGlobalWindowObserver, nsIInterfaceRequestor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIInterfaceRequestor
*>((nsGlobalWindowObserver*)0x1000)) - reinterpret_cast<
char*>((nsGlobalWindowObserver*)0x1000))}, {&mozilla::
detail::kImplementedIID<nsGlobalWindowObserver, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIObserver*>((nsGlobalWindowObserver
*)0x1000))) - reinterpret_cast<char*>((nsGlobalWindowObserver
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
486
487class IdleRequestExecutor;
488
489class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler {
490 public:
491 explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor)
492 : mExecutor(aExecutor) {}
493
494 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
495 NS_DECL_CYCLE_COLLECTION_CLASS(IdleRequestExecutorTimeoutHandler)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestExecutorTimeoutHandler"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestExecutorTimeoutHandler
>(p)->DeleteCycleCollectable(); } static IdleRequestExecutorTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<IdleRequestExecutorTimeoutHandler
*>(static_cast<IdleRequestExecutorTimeoutHandler*>(s
)); } static nsISupports* Upcast(IdleRequestExecutorTimeoutHandler
* p) { return static_cast<nsISupports*>(static_cast<
IdleRequestExecutorTimeoutHandler*>(p)); } virtual void Unlink
(void* p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &IdleRequestExecutorTimeoutHandler
::_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() clang diagnostic pop { nsXPCOMCycleCollectionParticipant*
p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 495); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
496
497 bool Call(const char* /* unused */) override;
498
499 private:
500 ~IdleRequestExecutorTimeoutHandler() override = default;
501 RefPtr<IdleRequestExecutor> mExecutor;
502};
503
504NS_IMPL_CYCLE_COLLECTION(IdleRequestExecutorTimeoutHandler, mExecutor)IdleRequestExecutorTimeoutHandler::cycleCollection IdleRequestExecutorTimeoutHandler
::_cycleCollectorGlobal; void IdleRequestExecutorTimeoutHandler
::cycleCollection::Unlink(void* p) { IdleRequestExecutorTimeoutHandler
* tmp = DowncastCCParticipant<IdleRequestExecutorTimeoutHandler
>(p); ImplCycleCollectionUnlink(tmp->mExecutor); (void)
tmp; } nsresult IdleRequestExecutorTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutorTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestExecutorTimeoutHandler>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "IdleRequestExecutorTimeoutHandler");
ImplCycleCollectionTraverse(cb, tmp->mExecutor, "mExecutor"
, 0); (void)tmp; return NS_OK; }
505
506NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestExecutorTimeoutHandler)MozExternalRefCountType IdleRequestExecutorTimeoutHandler::AddRef
(void) { static_assert(!std::is_destructible_v<IdleRequestExecutorTimeoutHandler
>, "Reference-counted class " "IdleRequestExecutorTimeoutHandler"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 506); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 506
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutorTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutorTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
507NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestExecutorTimeoutHandler)MozExternalRefCountType IdleRequestExecutorTimeoutHandler::Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 507); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 507
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutorTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestExecutorTimeoutHandler"
)); return count; } void IdleRequestExecutorTimeoutHandler::DeleteCycleCollectable
(void) { delete (this); }
508
509NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutorTimeoutHandler)nsresult IdleRequestExecutorTimeoutHandler::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 509); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestExecutorTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestExecutorTimeoutHandler
::cycleCollection::Upcast(this); return NS_OK; } foundInterface
= nullptr; } else
510 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
511NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 511); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 511); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
512
513class IdleRequestExecutor final : public nsIRunnable,
514 public nsICancelableRunnable,
515 public nsINamed,
516 public nsIIdleRunnable {
517 public:
518 explicit IdleRequestExecutor(nsGlobalWindowInner* aWindow)
519 : mDispatched(false), mDeadline(TimeStamp::Now()), mWindow(aWindow) {
520 MOZ_DIAGNOSTIC_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 520); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow"
")"); do { MOZ_CrashSequence(__null, 520); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
521
522 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
523 mDelayedExecutorDispatcher =
524 MakeRefPtr<IdleRequestExecutorTimeoutHandler>(this);
525 }
526
527 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
528 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IdleRequestExecutor, nsIRunnable)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestExecutor"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestExecutor
>(p)->DeleteCycleCollectable(); } static IdleRequestExecutor
* Downcast(nsISupports* s) { return static_cast<IdleRequestExecutor
*>(static_cast<nsIRunnable*>(s)); } static nsISupports
* Upcast(IdleRequestExecutor* p) { return static_cast<nsISupports
*>(static_cast<nsIRunnable*>(p)); } virtual void Unlink
(void* p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &IdleRequestExecutor::_cycleCollectorGlobal
; } }; clang diagnostic push clang diagnostic ignored "-Wunnecessary-virtual-specifier"
virtual void CheckForRightParticipant() clang diagnostic pop
{ nsXPCOMCycleCollectionParticipant* p; CallQueryInterface(
this, &p); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(p == &_cycleCollectorGlobal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(p == &_cycleCollectorGlobal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"p == &_cycleCollectorGlobal" " (" "IdleRequestExecutor" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
528); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutor" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 528); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
529
530 NS_DECL_NSIRUNNABLEvirtual nsresult Run(void) override;
531 NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override;
532 nsresult Cancel() override;
533 void SetDeadline(TimeStamp aDeadline) override;
534
535 bool IsCancelled() const { return !mWindow || mWindow->IsDying(); }
536 // Checks if aRequest shouldn't execute in the current idle period
537 // since it has been queued from a chained call to
538 // requestIdleCallback from within a running idle callback.
539 bool IneligibleForCurrentIdlePeriod(IdleRequest* aRequest) const {
540 return aRequest->Handle() >= mIdlePeriodLimit.mLastRequestIdInIdlePeriod &&
541 TimeStamp::Now() <= mIdlePeriodLimit.mEndOfIdlePeriod;
542 }
543
544 void MaybeUpdateIdlePeriodLimit();
545
546 // Maybe dispatch the IdleRequestExecutor. MabyeDispatch will
547 // schedule a delayed dispatch if the associated window is in the
548 // background or if given a time to wait until dispatching.
549 void MaybeDispatch(TimeStamp aDelayUntil = TimeStamp());
550 void ScheduleDispatch();
551
552 private:
553 struct IdlePeriodLimit {
554 TimeStamp mEndOfIdlePeriod;
555 uint32_t mLastRequestIdInIdlePeriod;
556 };
557
558 void DelayedDispatch(uint32_t aDelay);
559
560 ~IdleRequestExecutor() override = default;
561
562 bool mDispatched;
563 TimeStamp mDeadline;
564 IdlePeriodLimit mIdlePeriodLimit;
565 RefPtr<nsGlobalWindowInner> mWindow;
566 // The timeout handler responsible for dispatching this executor in
567 // the case of immediate dispatch to the idle queue isn't
568 // desirable. This is used if we've dispatched all idle callbacks
569 // that are allowed to run in the current idle period, or if the
570 // associated window is currently in the background.
571 RefPtr<TimeoutHandler> mDelayedExecutorDispatcher;
572 // If not Nothing() then this value is the handle to the currently
573 // scheduled delayed executor dispatcher. This is needed to be able
574 // to cancel the timeout handler in case of the executor being
575 // cancelled.
576 Maybe<int32_t> mDelayedExecutorHandle;
577};
578
579NS_IMPL_CYCLE_COLLECTION(IdleRequestExecutor, mWindow,IdleRequestExecutor::cycleCollection IdleRequestExecutor::_cycleCollectorGlobal
; void IdleRequestExecutor::cycleCollection::Unlink(void* p) {
IdleRequestExecutor* tmp = DowncastCCParticipant<IdleRequestExecutor
>(p); ImplCycleCollectionUnlink(tmp->mWindow); ImplCycleCollectionUnlink
(tmp->mDelayedExecutorDispatcher); (void)tmp; } nsresult IdleRequestExecutor
::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutor* tmp = DowncastCCParticipant<
IdleRequestExecutor>(p); cb.DescribeRefCountedNode(tmp->
mRefCnt.get(), "IdleRequestExecutor"); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); ImplCycleCollectionTraverse
(cb, tmp->mDelayedExecutorDispatcher, "mDelayedExecutorDispatcher"
, 0); (void)tmp; return NS_OK; }
580 mDelayedExecutorDispatcher)IdleRequestExecutor::cycleCollection IdleRequestExecutor::_cycleCollectorGlobal
; void IdleRequestExecutor::cycleCollection::Unlink(void* p) {
IdleRequestExecutor* tmp = DowncastCCParticipant<IdleRequestExecutor
>(p); ImplCycleCollectionUnlink(tmp->mWindow); ImplCycleCollectionUnlink
(tmp->mDelayedExecutorDispatcher); (void)tmp; } nsresult IdleRequestExecutor
::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestExecutor* tmp = DowncastCCParticipant<
IdleRequestExecutor>(p); cb.DescribeRefCountedNode(tmp->
mRefCnt.get(), "IdleRequestExecutor"); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); ImplCycleCollectionTraverse
(cb, tmp->mDelayedExecutorDispatcher, "mDelayedExecutorDispatcher"
, 0); (void)tmp; return NS_OK; }
581
582NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestExecutor)MozExternalRefCountType IdleRequestExecutor::AddRef(void) { static_assert
(!std::is_destructible_v<IdleRequestExecutor>, "Reference-counted class "
"IdleRequestExecutor" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 582); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 582
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutor"
" not thread-safe"); nsISupports* base = IdleRequestExecutor
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutor")
, (uint32_t)(sizeof(*this))); return count; }
583NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestExecutor)MozExternalRefCountType IdleRequestExecutor::Release(void) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 583); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 583
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestExecutor"
" not thread-safe"); nsISupports* base = IdleRequestExecutor
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestExecutor")); return
count; } void IdleRequestExecutor::DeleteCycleCollectable(void
) { delete (this); }
584
585NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutor)nsresult IdleRequestExecutor::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 585); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestExecutor::cycleCollection::GetParticipant(); return
NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestExecutor::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
586 NS_INTERFACE_MAP_ENTRY(nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRunnable>)) foundInterface = static_cast
<nsIRunnable*>(this); else
587 NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICancelableRunnable>)) foundInterface
= static_cast<nsICancelableRunnable*>(this); else
588 NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsINamed>)) foundInterface = static_cast
<nsINamed*>(this); else
589 NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdleRunnable>)) foundInterface
= static_cast<nsIIdleRunnable*>(this); else
590 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIRunnable*>(this)); else
591NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 591); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
592
593NS_IMETHODIMPnsresult
594IdleRequestExecutor::GetName(nsACString& aName) {
595 aName.AssignLiteral("IdleRequestExecutor");
596 return NS_OK;
597}
598
599// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT.
600// See bug 1535398.
601MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult IdleRequestExecutor::Run() {
602 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 602
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 602); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
603
604 mDispatched = false;
605 if (mWindow) {
606 RefPtr<nsGlobalWindowInner> window(mWindow);
607 window->ExecuteIdleRequest(mDeadline);
608 }
609
610 return NS_OK;
611}
612
613nsresult IdleRequestExecutor::Cancel() {
614 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 614
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 614); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
615
616 if (mDelayedExecutorHandle && mWindow) {
617 mWindow->GetTimeoutManager()->ClearTimeout(
618 mDelayedExecutorHandle.value(), Timeout::Reason::eIdleCallbackTimeout);
619 }
620
621 mWindow = nullptr;
622 return NS_OK;
623}
624
625void IdleRequestExecutor::SetDeadline(TimeStamp aDeadline) {
626 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 626
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 626); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
627
628 if (!mWindow) {
629 return;
630 }
631
632 mDeadline = aDeadline;
633}
634
635void IdleRequestExecutor::MaybeUpdateIdlePeriodLimit() {
636 if (TimeStamp::Now() > mIdlePeriodLimit.mEndOfIdlePeriod) {
637 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
638 }
639}
640
641void IdleRequestExecutor::MaybeDispatch(TimeStamp aDelayUntil) {
642 // If we've already dispatched the executor we don't want to do it
643 // again. Also, if we've called IdleRequestExecutor::Cancel mWindow
644 // will be null, which indicates that we shouldn't dispatch this
645 // executor either.
646 if (mDispatched || IsCancelled()) {
647 return;
648 }
649
650 mDispatched = true;
651
652 nsPIDOMWindowOuter* outer = mWindow->GetOuterWindow();
653 if (outer && outer->IsBackground()) {
654 // Set a timeout handler with a timeout of 0 ms to throttle idle
655 // callback requests coming from a backround window using
656 // background timeout throttling.
657 DelayedDispatch(0);
658 return;
659 }
660
661 TimeStamp now = TimeStamp::Now();
662 if (!aDelayUntil || aDelayUntil < now) {
663 ScheduleDispatch();
664 return;
665 }
666
667 TimeDuration delay = aDelayUntil - now;
668 DelayedDispatch(static_cast<uint32_t>(delay.ToMilliseconds()));
669}
670
671void IdleRequestExecutor::ScheduleDispatch() {
672 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 672); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 672); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
673 mDelayedExecutorHandle = Nothing();
674 RefPtr<IdleRequestExecutor> request = this;
675 NS_DispatchToCurrentThreadQueue(request.forget(), EventQueuePriority::Idle);
676}
677
678void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) {
679 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 679); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 679); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
680 MOZ_ASSERT(mDelayedExecutorHandle.isNothing())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDelayedExecutorHandle.isNothing())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDelayedExecutorHandle.isNothing
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mDelayedExecutorHandle.isNothing()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDelayedExecutorHandle.isNothing()"
")"); do { MOZ_CrashSequence(__null, 680); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
681 int32_t handle;
682 mWindow->GetTimeoutManager()->SetTimeout(
683 mDelayedExecutorDispatcher, aDelay, false,
684 Timeout::Reason::eIdleCallbackTimeout, &handle);
685 mDelayedExecutorHandle = Some(handle);
686}
687
688bool IdleRequestExecutorTimeoutHandler::Call(const char* /* unused */) {
689 if (!mExecutor->IsCancelled()) {
690 mExecutor->ScheduleDispatch();
691 }
692 return true;
693}
694
695void nsGlobalWindowInner::ScheduleIdleRequestDispatch() {
696 AssertIsOnMainThread();
697
698 if (!mIdleRequestExecutor) {
699 mIdleRequestExecutor = MakeRefPtr<IdleRequestExecutor>(this);
700 }
701
702 mIdleRequestExecutor->MaybeDispatch();
703}
704
705void nsGlobalWindowInner::SuspendIdleRequests() {
706 if (mIdleRequestExecutor) {
707 mIdleRequestExecutor->Cancel();
708 mIdleRequestExecutor = nullptr;
709 }
710}
711
712void nsGlobalWindowInner::ResumeIdleRequests() {
713 MOZ_ASSERT(!mIdleRequestExecutor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIdleRequestExecutor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIdleRequestExecutor))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mIdleRequestExecutor"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 713
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIdleRequestExecutor"
")"); do { MOZ_CrashSequence(__null, 713); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
714
715 ScheduleIdleRequestDispatch();
716}
717
718void nsGlobalWindowInner::RemoveIdleCallback(
719 mozilla::dom::IdleRequest* aRequest) {
720 AssertIsOnMainThread();
721
722 if (aRequest->HasTimeout()) {
723 mTimeoutManager->ClearTimeout(aRequest->GetTimeoutHandle(),
724 Timeout::Reason::eIdleCallbackTimeout);
725 }
726
727 aRequest->RemoveFromList();
728}
729
730void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
731 DOMHighResTimeStamp aDeadline,
732 bool aDidTimeout) {
733 AssertIsOnMainThread();
734 // XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should
735 // guarantee that caller is holding a strong ref on the stack.
736 RefPtr<IdleRequest> request(aRequest);
737 RemoveIdleCallback(request);
738 request->IdleRun(this, aDeadline, aDidTimeout);
739}
740
741void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
742 AssertIsOnMainThread();
743 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
744
745 if (!request) {
746 // There are no more idle requests, so stop scheduling idle
747 // request callbacks.
748 return;
749 }
750
751 // If the request that we're trying to execute has been queued
752 // during the current idle period, then dispatch it again at the end
753 // of the idle period.
754 if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
755 mIdleRequestExecutor->MaybeDispatch(aDeadline);
756 return;
757 }
758
759 DOMHighResTimeStamp deadline = 0.0;
760
761 if (Performance* perf = GetPerformance()) {
762 deadline = perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline);
763 }
764
765 mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
766 RunIdleRequest(request, deadline, false);
767
768 // Running the idle callback could've suspended the window, in which
769 // case mIdleRequestExecutor will be null.
770 if (mIdleRequestExecutor) {
771 mIdleRequestExecutor->MaybeDispatch();
772 }
773}
774
775class IdleRequestTimeoutHandler final : public TimeoutHandler {
776 public:
777 IdleRequestTimeoutHandler(JSContext* aCx, IdleRequest* aIdleRequest,
778 nsPIDOMWindowInner* aWindow)
779 : TimeoutHandler(aCx), mIdleRequest(aIdleRequest), mWindow(aWindow) {}
780
781 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINALpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) final; virtual MozExternalRefCountType
AddRef(void) final; virtual MozExternalRefCountType Release(
void) final; using HasThreadSafeRefCnt = std::false_type; protected
: nsCycleCollectingAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public: void DeleteCycleCollectable(void); public:
782 NS_DECL_CYCLE_COLLECTION_CLASS(IdleRequestTimeoutHandler)class cycleCollection : public nsXPCOMCycleCollectionParticipant
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : nsXPCOMCycleCollectionParticipant(aFlags) {} private: public
: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "IdleRequestTimeoutHandler"; }; virtual void DeleteCycleCollectable
(void* p) override { DowncastCCParticipant<IdleRequestTimeoutHandler
>(p)->DeleteCycleCollectable(); } static IdleRequestTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<IdleRequestTimeoutHandler
*>(static_cast<IdleRequestTimeoutHandler*>(s)); } static
nsISupports* Upcast(IdleRequestTimeoutHandler* p) { return static_cast
<nsISupports*>(static_cast<IdleRequestTimeoutHandler
*>(p)); } virtual void Unlink(void* p) override; static constexpr
nsXPCOMCycleCollectionParticipant* GetParticipant() { return
&IdleRequestTimeoutHandler::_cycleCollectorGlobal; } }; clang
diagnostic push clang diagnostic ignored "-Wunnecessary-virtual-specifier"
virtual void CheckForRightParticipant() clang diagnostic pop
{ nsXPCOMCycleCollectionParticipant* p; CallQueryInterface(
this, &p); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(p == &_cycleCollectorGlobal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(p == &_cycleCollectorGlobal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"p == &_cycleCollectorGlobal" " (" "IdleRequestTimeoutHandler"
" should QI to its own CC participant" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 782); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 782); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void BaseCycleCollectable
() final{} clang diagnostic pop
783
784 MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override {
785 RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow));
786 RefPtr<IdleRequest> request(mIdleRequest);
787 window->RunIdleRequest(request, 0.0, true);
788 return true;
789 }
790
791 private:
792 ~IdleRequestTimeoutHandler() override = default;
793
794 RefPtr<IdleRequest> mIdleRequest;
795 nsCOMPtr<nsPIDOMWindowInner> mWindow;
796};
797
798NS_IMPL_CYCLE_COLLECTION(IdleRequestTimeoutHandler, mIdleRequest, mWindow)IdleRequestTimeoutHandler::cycleCollection IdleRequestTimeoutHandler
::_cycleCollectorGlobal; void IdleRequestTimeoutHandler::cycleCollection
::Unlink(void* p) { IdleRequestTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestTimeoutHandler>(p); ImplCycleCollectionUnlink
(tmp->mIdleRequest); ImplCycleCollectionUnlink(tmp->mWindow
); (void)tmp; } nsresult IdleRequestTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { IdleRequestTimeoutHandler* tmp = DowncastCCParticipant
<IdleRequestTimeoutHandler>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "IdleRequestTimeoutHandler"); ImplCycleCollectionTraverse
(cb, tmp->mIdleRequest, "mIdleRequest", 0); ImplCycleCollectionTraverse
(cb, tmp->mWindow, "mWindow", 0); (void)tmp; return NS_OK;
}
799
800NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestTimeoutHandler)MozExternalRefCountType IdleRequestTimeoutHandler::AddRef(void
) { static_assert(!std::is_destructible_v<IdleRequestTimeoutHandler
>, "Reference-counted class " "IdleRequestTimeoutHandler" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 800
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
801NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestTimeoutHandler)MozExternalRefCountType IdleRequestTimeoutHandler::Release(void
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 801); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 801
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("IdleRequestTimeoutHandler"
" not thread-safe"); nsISupports* base = IdleRequestTimeoutHandler
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("IdleRequestTimeoutHandler"
)); return count; } void IdleRequestTimeoutHandler::DeleteCycleCollectable
(void) { delete (this); }
802
803NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestTimeoutHandler)nsresult IdleRequestTimeoutHandler::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 803); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= IdleRequestTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = IdleRequestTimeoutHandler::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
804 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
805NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 805); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 805); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
806
807uint32_t nsGlobalWindowInner::RequestIdleCallback(
808 JSContext* aCx, IdleRequestCallback& aCallback,
809 const IdleRequestOptions& aOptions, ErrorResult& aError) {
810 AssertIsOnMainThread();
811
812 if (IsDying()) {
813 return 0;
814 }
815
816 uint32_t handle = mIdleRequestCallbackCounter++;
817
818 RefPtr request = MakeRefPtr<IdleRequest>(&aCallback, handle);
819
820 if (aOptions.mTimeout.WasPassed()) {
821 int32_t timeoutHandle;
822 RefPtr handler = MakeRefPtr<IdleRequestTimeoutHandler>(aCx, request, this);
823
824 nsresult rv = mTimeoutManager->SetTimeout(
825 handler, aOptions.mTimeout.Value(), false,
826 Timeout::Reason::eIdleCallbackTimeout, &timeoutHandle);
827
828 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 828)
) {
829 return 0;
830 }
831
832 request->SetTimeoutHandle(timeoutHandle);
833 }
834
835 request->SetContainer(mIdleRequestCallbacksByHandle);
836 mIdleRequestCallbacks.insertBack(request);
837
838 if (!IsSuspended()) {
839 ScheduleIdleRequestDispatch();
840 }
841
842 return handle;
843}
844
845void nsGlobalWindowInner::CancelIdleCallback(uint32_t aHandle) {
846 if (IdleRequest* request = mIdleRequestCallbacksByHandle->Get(aHandle)) {
847 RemoveIdleCallback(request);
848 }
849}
850
851void nsGlobalWindowInner::DisableIdleCallbackRequests() {
852 if (mIdleRequestExecutor) {
853 mIdleRequestExecutor->Cancel();
854 mIdleRequestExecutor = nullptr;
855 }
856
857 while (!mIdleRequestCallbacks.isEmpty()) {
858 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
859 RemoveIdleCallback(request);
860 }
861}
862
863bool nsGlobalWindowInner::IsBackgroundInternal() const {
864 return !mOuterWindow || mOuterWindow->IsBackground();
865}
866
867class PromiseDocumentFlushedResolver final {
868 public:
869 PromiseDocumentFlushedResolver(Promise* aPromise,
870 PromiseDocumentFlushedCallback& aCallback)
871 : mPromise(aPromise), mCallback(&aCallback) {}
872
873 virtual ~PromiseDocumentFlushedResolver() = default;
874
875 void Call() {
876 nsMutationGuard guard;
877 ErrorResult error;
878 JS::Rooted<JS::Value> returnVal(RootingCx());
879 mCallback->Call(&returnVal, error);
880
881 if (error.Failed()) {
882 mPromise->MaybeReject(std::move(error));
883 } else if (guard.Mutated(0)) {
884 // Something within the callback mutated the DOM.
885 mPromise->MaybeRejectWithNoModificationAllowedError(
886 "DOM mutated from promiseDocumentFlushed callbacks");
887 } else {
888 mPromise->MaybeResolve(returnVal);
889 }
890 }
891
892 RefPtr<Promise> mPromise;
893 RefPtr<PromiseDocumentFlushedCallback> mCallback;
894};
895
896//*****************************************************************************
897//*** nsGlobalWindowInner: Object Management
898//*****************************************************************************
899
900nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
901 WindowGlobalChild* aActor)
902 : nsPIDOMWindowInner(aOuterWindow, aActor),
903 mHasOrientationChangeListeners(false),
904 mWasOffline(false),
905 mHasHadSlowScript(false),
906 mIsChrome(false),
907 mCleanMessageManager(false),
908 mNeedsFocus(true),
909 mFocusByKeyOccurred(false),
910 mDidFireDocElemInserted(false),
911 mHasGamepad(false),
912 mHasXRSession(false),
913 mHasVRDisplayActivateEvents(false),
914 mXRRuntimeDetectionInFlight(false),
915 mXRPermissionRequestInFlight(false),
916 mXRPermissionGranted(false),
917 mWasCurrentInnerWindow(false),
918 mHasSeenGamepadInput(false),
919 mHintedWasLoading(false),
920 mHasOpenedExternalProtocolFrame(false),
921 mScrollMarksOnHScrollbar(false),
922 mStorageAllowedReasonCache(0),
923 mSuspendDepth(0),
924 mFreezeDepth(0),
925#ifdef DEBUG1
926 mSerial(0),
927#endif
928 mFocusMethod(0),
929 mIdleRequestCallbackCounter(1),
930 mIdleRequestCallbacksByHandle(new mozilla::dom::IdleRequestMap()),
931 mIdleRequestExecutor(nullptr),
932 mObservingRefresh(false),
933 mIteratingDocumentFlushedResolvers(false),
934 mCanSkipCCGeneration(0) {
935 mIsInnerWindow = true;
936
937 AssertIsOnMainThread();
938 SetIsOnMainThread();
939 nsLayoutStatics::AddRef();
940
941 // Initialize the PRCList (this).
942 PR_INIT_CLIST(this)do {(this)->next = (this); (this)->prev = (this); } while
(0)
;
943
944 // add this inner window to the outer window list of inners.
945 PR_INSERT_AFTER(this, aOuterWindow)do {(this)->next = (aOuterWindow)->next; (this)->prev
= (aOuterWindow); (aOuterWindow)->next->prev = (this);
(aOuterWindow)->next = (this); } while (0)
;
946
947 mTimeoutManager = MakeUnique<dom::TimeoutManager>(
948 *this, StaticPrefs::dom_timeout_max_idle_defer_ms(),
949 static_cast<nsISerialEventTarget*>(nsPIDOMWindowInner::From(this)
950 ->GetBrowsingContextGroup()
951 ->GetTimerEventQueue()));
952
953 mObserver = MakeRefPtr<nsGlobalWindowObserver>(this);
954 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
955 // Watch for online/offline status changes so we can fire events. Use
956 // a strong reference.
957 os->AddObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed", false);
958 os->AddObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure", false);
959 os->AddObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed", false);
960 os->AddObserver(mObserver, "browser-perm-changed", false);
961 os->AddObserver(mObserver, "screen-information-changed", false);
962 os->AddObserver(mObserver, "audio-playback", false);
963 }
964
965 Preferences::AddStrongObserver(mObserver, "intl.accept_languages");
966
967 // Watch for storage notifications so we can fire storage events.
968 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
969 if (sns) {
970 sns->Register(mObserver);
971 }
972
973 if (XRE_IsContentProcess()) {
974 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
975 if (docShell) {
976 mBrowserChild = docShell->GetBrowserChild();
977 }
978 }
979
980 if (gDumpFile == nullptr) {
981 nsAutoCString fname;
982 Preferences::GetCString("browser.dom.window.dump.file", fname);
983 if (!fname.IsEmpty()) {
984 // If this fails to open, Dump() knows to just go to stdout on null.
985 gDumpFile = fopen(fname.get(), "wb+");
986 } else {
987 gDumpFile = stdoutstdout;
988 }
989 }
990
991#ifdef DEBUG1
992 mSerial = nsContentUtils::InnerOrOuterWindowCreated();
993
994 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
995 MOZ_LOG(gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
996 ("++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
997 nsContentUtils::GetCurrentInnerOrOuterWindowCount(),do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
998 static_cast<void*>(ToCanonicalSupports(this)), getpid(), mSerial,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
999 static_cast<void*>(ToCanonicalSupports(aOuterWindow))))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p]\n"
, nsContentUtils::GetCurrentInnerOrOuterWindowCount(), static_cast
<void*>(ToCanonicalSupports(this)), getpid(), mSerial, static_cast
<void*>(ToCanonicalSupports(aOuterWindow))); } } while (
0)
;
1000
1001 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
1002 if (obs) {
1003 nsString data;
1004 data.AppendPrintf(
1005 "serial=%d address=0x%" PRIxPTR"l" "x" " type=inner outer=0x%" PRIxPTR"l" "x",
1006 mSerial, reinterpret_cast<uintptr_t>(ToCanonicalSupports(this)),
1007 reinterpret_cast<uintptr_t>(ToCanonicalSupports(aOuterWindow)));
1008 obs->NotifyObservers(nullptr, "debug-domwindow-created", data.get());
1009 }
1010 }
1011#endif
1012
1013 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p created outer=%p", this, aOuterWindow
); } } while (0)
1014 ("DOMWINDOW %p created outer=%p", this, aOuterWindow))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p created outer=%p", this, aOuterWindow
); } } while (0)
;
1015
1016 // Add ourselves to the inner windows list.
1017 MOZ_ASSERT(sInnerWindowsById, "Inner Windows hash table must be created!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sInnerWindowsById)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sInnerWindowsById))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("sInnerWindowsById"
" (" "Inner Windows hash table must be created!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1017); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sInnerWindowsById"
") (" "Inner Windows hash table must be created!" ")"); do {
MOZ_CrashSequence(__null, 1017); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1018 MOZ_ASSERT(!sInnerWindowsById->Contains(mWindowID),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!sInnerWindowsById->Contains(mWindowID))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!sInnerWindowsById->Contains(mWindowID)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!sInnerWindowsById->Contains(mWindowID)"
" (" "This window shouldn't be in the hash table yet!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1019); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1019); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1019 "This window shouldn't be in the hash table yet!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!sInnerWindowsById->Contains(mWindowID))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!sInnerWindowsById->Contains(mWindowID)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!sInnerWindowsById->Contains(mWindowID)"
" (" "This window shouldn't be in the hash table yet!" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1019); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1019); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1020 // We seem to see crashes in release builds because of null
1021 // |sInnerWindowsById|.
1022 if (sInnerWindowsById) {
1023 sInnerWindowsById->InsertOrUpdate(mWindowID, this);
1024 }
1025}
1026
1027#ifdef DEBUG1
1028
1029/* static */
1030void nsGlobalWindowInner::AssertIsOnMainThread() {
1031 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1031
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1031); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1032}
1033
1034#endif // DEBUG
1035
1036/* static */
1037void nsGlobalWindowInner::Init() {
1038 AssertIsOnMainThread();
1039
1040 NS_ASSERTION(gDOMLeakPRLogInner,do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1041
); MOZ_PretendNoReturn(); } } while (0)
1041 "gDOMLeakPRLogInner should have been initialized!")do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1041
); MOZ_PretendNoReturn(); } } while (0)
;
1042
1043 sInnerWindowsById = new InnerWindowByIdTable();
1044}
1045
1046nsGlobalWindowInner::~nsGlobalWindowInner() {
1047 AssertIsOnMainThread();
1048 MOZ_ASSERT(!mHintedWasLoading)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mHintedWasLoading)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mHintedWasLoading))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mHintedWasLoading"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1048
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHintedWasLoading"
")"); do { MOZ_CrashSequence(__null, 1048); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1049
1050 if (IsChromeWindow()) {
1051 MOZ_ASSERT(mCleanMessageManager,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCleanMessageManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCleanMessageManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCleanMessageManager"
" (" "chrome windows may always disconnect the msg manager" ")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1052
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1052); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1052 "chrome windows may always disconnect the msg manager")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCleanMessageManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCleanMessageManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCleanMessageManager"
" (" "chrome windows may always disconnect the msg manager" ")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1052
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1052); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1053
1054 DisconnectAndClearGroupMessageManagers();
1055
1056 if (mChromeFields.mMessageManager) {
1057 static_cast<nsFrameMessageManager*>(mChromeFields.mMessageManager.get())
1058 ->Disconnect();
1059 }
1060
1061 mCleanMessageManager = false;
1062 }
1063
1064 // In most cases this should already have been called, but call it again
1065 // here to catch any corner cases.
1066 FreeInnerObjects();
1067
1068 if (sInnerWindowsById) {
1069 sInnerWindowsById->Remove(mWindowID);
1070 }
1071
1072 nsContentUtils::InnerOrOuterWindowDestroyed();
1073
1074#ifdef DEBUG1
1075 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
1076 nsAutoCString url;
1077 if (mLastOpenedURI) {
1078 url = mLastOpenedURI->GetSpecOrDefault();
1079
1080 // Data URLs can be very long, so truncate to avoid flooding the log.
1081 const uint32_t maxURLLength = 1000;
1082 if (url.Length() > maxURLLength) {
1083 url.Truncate(maxURLLength);
1084 }
1085 }
1086
1087 nsGlobalWindowOuter* outer = nsGlobalWindowOuter::Cast(mOuterWindow);
1088 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1089 gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1090 ("--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1091 "%s]\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1092 nsContentUtils::GetCurrentInnerOrOuterWindowCount(),do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1093 static_cast<void*>(ToCanonicalSupports(this)), getpid(), mSerial,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
1094 static_cast<void*>(ToCanonicalSupports(outer)), url.get()))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = "
"%s]\n", nsContentUtils::GetCurrentInnerOrOuterWindowCount()
, static_cast<void*>(ToCanonicalSupports(this)), getpid
(), mSerial, static_cast<void*>(ToCanonicalSupports(outer
)), url.get()); } } while (0)
;
1095
1096 uint32_t serial = mSerial;
1097 NS_DispatchToMainThread(
1098 NS_NewRunnableFunction(
1099 "TestDOMWindowDestroyed",
1100 [serial, url = std::move(url)] {
1101 nsCOMPtr<nsIObserverService> obs =
1102 mozilla::services::GetObserverService();
1103 if (obs) {
1104 nsString data;
1105 data.AppendPrintf("serial=%d type=inner url=%s", serial,
1106 url.get());
1107 obs->NotifyObservers(nullptr, "debug-domwindow-destroyed",
1108 data.get());
1109 }
1110 }),
1111 NS_DISPATCH_FALLIBLEnsIEventTarget::DISPATCH_FALLIBLE);
1112 }
1113#endif
1114 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p destroyed", this); } } while
(0)
1115 ("DOMWINDOW %p destroyed", this))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p destroyed", this); } } while
(0)
;
1116
1117 // An inner window is destroyed, pull it out of the outer window's
1118 // list if inner windows.
1119
1120 PR_REMOVE_LINK(this)do {(this)->prev->next = (this)->next; (this)->next
->prev = (this)->prev; } while (0)
;
1121
1122 // If our outer window's inner window is this window, null out the
1123 // outer window's reference to this window that's being deleted.
1124 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1125 if (outer) {
1126 outer->MaybeClearInnerWindow(this);
1127 }
1128
1129 // We don't have to leave the tab group if we are an inner window.
1130
1131 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
1132 if (ac) ac->RemoveWindowAsListener(this);
1133
1134 nsLayoutStatics::Release();
1135}
1136
1137// static
1138void nsGlobalWindowInner::ShutDown() {
1139 AssertIsOnMainThread();
1140
1141 if (gDumpFile && gDumpFile != stdoutstdout) {
1142 fclose(gDumpFile);
1143 }
1144 gDumpFile = nullptr;
1145
1146 sInnerWindowsById = nullptr;
1147}
1148
1149void nsGlobalWindowInner::FreeInnerObjects() {
1150 if (IsDying()) {
1151 return;
1152 }
1153 StartDying();
1154
1155 if (JSObject* global = GetWrapperPreserveColor()) {
1156 js::SetRealmIsDyingHint(global);
1157 }
1158
1159 ClearHasPointerRawUpdateEventListeners();
1160
1161 if (mDoc && mDoc->GetWindowContext()) {
1162 // The document is about to lose its window, so this is a good time to send
1163 // our page use counters.
1164 //
1165 // (We also do this in Document::SetScriptGlobalObject(nullptr), which
1166 // catches most cases of documents losing their window, but not all.)
1167 mDoc->SendPageUseCounters();
1168 }
1169
1170 // Make sure that this is called before we null out the document and
1171 // other members that the window destroyed observers could
1172 // re-create.
1173 if (auto* reporter = nsWindowMemoryReporter::Get()) {
1174 reporter->ObserveDOMWindowDetached(this);
1175 }
1176
1177 // Kill all of the workers for this window.
1178 CancelWorkersForWindow(*this);
1179
1180 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
1181 mSharedWorkers.ForwardRange()) {
1182 pinnedWorker->Close();
1183 }
1184
1185 if (mTimeoutManager) {
1186 mTimeoutManager->ClearAllTimeouts();
1187 }
1188
1189 DisableIdleCallbackRequests();
1190
1191 mChromeEventHandler = nullptr;
1192
1193 if (mListenerManager) {
1194 mListenerManager->RemoveAllListeners();
1195 mListenerManager->Disconnect();
1196 mListenerManager = nullptr;
1197 }
1198
1199 mHistory = nullptr;
1200
1201 mNavigation = nullptr;
1202
1203 if (mNavigator) {
1204 mNavigator->OnNavigation();
1205 mNavigator->Invalidate();
1206 mNavigator = nullptr;
1207 }
1208
1209 mScreen = nullptr;
1210
1211 if (mDoc) {
1212 // Remember the document's principal, URI, and policyContainer.
1213 mDocumentPrincipal = mDoc->NodePrincipal();
1214 mDocumentCookiePrincipal = mDoc->EffectiveCookiePrincipal();
1215 mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
1216 mDocumentPartitionedPrincipal = mDoc->PartitionedPrincipal();
1217 mDocumentURI = mDoc->GetDocumentURI();
1218 mDocBaseURI = mDoc->GetDocBaseURI();
1219 mDocumentPolicyContainer = mDoc->GetPolicyContainer();
1220
1221 while (mDoc->EventHandlingSuppressed()) {
1222 mDoc->UnsuppressEventHandlingAndFireEvents(false);
1223 }
1224 }
1225
1226 // Remove our reference to the document and the document principal.
1227 mFocusedElement = nullptr;
1228
1229 // Unregister any remaining media source blob: URLs created by this window.
1230 if (RefPtr<DocGroup> docGroup = GetDocGroup()) {
1231 nsTArray<nsCString> mediaSourceURLs = std::move(mMediaSourceURLs);
1232 for (auto& url : mediaSourceURLs) {
1233 docGroup->UnregisterMediaSourceURL(url, /* aNotifyWindow */ false);
1234 }
1235 }
1236
1237 nsIGlobalObject::UnlinkObjectsInGlobal();
1238
1239 NotifyWindowIDDestroyed("inner-window-destroyed");
1240
1241 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
1242 mAudioContexts[i]->OnWindowDestroy();
1243 }
1244 mAudioContexts.Clear();
1245
1246 for (MediaKeys* mediaKeys : mMediaKeysInstances) {
1247 mediaKeys->OnInnerWindowDestroy();
1248 }
1249 mMediaKeysInstances.Clear();
1250
1251 DisableGamepadUpdates();
1252 mHasGamepad = false;
1253 mGamepads.Clear();
1254 DisableVRUpdates();
1255 mHasXRSession = false;
1256 mHasVRDisplayActivateEvents = false;
1257 mXRRuntimeDetectionInFlight = false;
1258 mXRPermissionRequestInFlight = false;
1259 mXRPermissionGranted = false;
1260 mVRDisplays.Clear();
1261
1262 // This breaks a cycle between the window and the ClientSource object.
1263 mClientSource.reset();
1264
1265 if (mWindowGlobalChild) {
1266 // Remove any remaining listeners.
1267 int64_t nListeners = mWindowGlobalChild->BeforeUnloadListeners();
1268 for (int64_t i = 0; i < nListeners; ++i) {
1269 mWindowGlobalChild->BeforeUnloadRemoved();
1270 }
1271 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() == 0)
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() == 0)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mWindowGlobalChild->BeforeUnloadListeners() == 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1271
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() == 0"
")"); do { MOZ_CrashSequence(__null, 1271); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1272 }
1273
1274 // If we have any promiseDocumentFlushed callbacks, fire them now so
1275 // that the Promises can resolve.
1276 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
1277
1278 DisconnectGlobalTeardownObservers();
1279
1280#ifdef MOZ_WIDGET_ANDROID
1281 DisableOrientationChangeListener();
1282#endif
1283
1284 if (mObserver) {
1285 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
1286 os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed");
1287 os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure");
1288 os->RemoveObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed");
1289 os->RemoveObserver(mObserver, "browser-perm-changed");
1290 os->RemoveObserver(mObserver, "screen-information-changed");
1291 os->RemoveObserver(mObserver, "audio-playback");
1292 }
1293
1294 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
1295 if (sns) {
1296 sns->Unregister(mObserver);
1297 }
1298
1299 Preferences::RemoveObserver(mObserver, "intl.accept_languages");
1300
1301 // Drop its reference to this dying window, in case for some bogus reason
1302 // the object stays around.
1303 mObserver->Forget();
1304 }
1305
1306 mMenubar = nullptr;
1307 mToolbar = nullptr;
1308 mLocationbar = nullptr;
1309 mPersonalbar = nullptr;
1310 mStatusbar = nullptr;
1311 mScrollbars = nullptr;
1312
1313 mConsole = nullptr;
1314 mCookieStore = nullptr;
1315 mDocumentPiP = nullptr;
1316 mPushManager = nullptr;
1317 mCloseWatcherManager = nullptr;
1318
1319 mPaintWorklet = nullptr;
1320
1321 mExternal = nullptr;
1322
1323 if (mLocalStorage) {
1324 mLocalStorage->Disconnect();
1325 mLocalStorage = nullptr;
1326 }
1327 mSessionStorage = nullptr;
1328 if (mPerformance) {
1329 // Since window is dying, nothing is going to be painted with meaningful
1330 // sizes, so the temp data for LCP and container timing is no longer needed.
1331 // Clearing the container timing records also drops their raw element keys.
1332 auto* perf = static_cast<PerformanceMainThread*>(mPerformance.get());
1333 perf->ClearGeneratedTempDataForLCP();
1334 perf->ClearContainerTimingData();
1335 }
1336 mPerformance = nullptr;
1337
1338 mContentMediaController = nullptr;
1339
1340 if (mWebTaskScheduler) {
1341 mWebTaskScheduler->Disconnect();
1342 mWebTaskScheduler = nullptr;
1343 }
1344
1345 mTrustedTypePolicyFactory = nullptr;
1346
1347 mSharedWorkers.Clear();
1348
1349#ifdef MOZ_WEBSPEECH1
1350 mSpeechSynthesis = nullptr;
1351#endif
1352
1353 mGlean = nullptr;
1354 mGleanPings = nullptr;
1355
1356 mParentTarget = nullptr;
1357
1358 if (mCleanMessageManager) {
1359 MOZ_ASSERT(mIsChrome, "only chrome should have msg manager cleaned")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIsChrome)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIsChrome))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mIsChrome" " (" "only chrome should have msg manager cleaned"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1359); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIsChrome" ") ("
"only chrome should have msg manager cleaned" ")"); do { MOZ_CrashSequence
(__null, 1359); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1360 if (mChromeFields.mMessageManager) {
1361 mChromeFields.mMessageManager->Disconnect();
1362 }
1363 }
1364
1365 if (mWindowGlobalChild && !mWindowGlobalChild->IsClosed()) {
1366 mWindowGlobalChild->Destroy();
1367 }
1368
1369 mIntlUtils = nullptr;
1370
1371 HintIsLoading(false);
1372}
1373
1374//*****************************************************************************
1375// nsGlobalWindowInner::nsISupports
1376//*****************************************************************************
1377
1378// QueryInterface implementation for nsGlobalWindowInner
1379NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowInner)nsresult nsGlobalWindowInner::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1379); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= nsGlobalWindowInner::cycleCollection::GetParticipant(); return
NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = nsGlobalWindowInner::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
1380 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRYif (aIID.Equals((nsWrapperCache::kIID))) { *aInstancePtr = static_cast
<nsWrapperCache*>(this); return NS_OK; } else
1381 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<EventTarget*>(this)); else
1382 NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDOMWindow>)) foundInterface = static_cast
<nsIDOMWindow*>(this); else
1383 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIGlobalObject>)) foundInterface
= static_cast<nsIGlobalObject*>(this); else
1384 NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptGlobalObject>)) foundInterface
= static_cast<nsIScriptGlobalObject*>(this); else
1385 NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptObjectPrincipal>)) foundInterface
= static_cast<nsIScriptObjectPrincipal*>(this); else
1386 NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozilla::dom::EventTarget>)) foundInterface
= static_cast<mozilla::dom::EventTarget*>(this); else
1387 NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowInner)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsPIDOMWindowInner>)) foundInterface
= static_cast<nsPIDOMWindowInner*>(this); else
1388 NS_INTERFACE_MAP_ENTRY(mozIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozIDOMWindow>)) foundInterface =
static_cast<mozIDOMWindow*>(this); else
1389 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
1390 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInterfaceRequestor>)) foundInterface
= static_cast<nsIInterfaceRequestor*>(this); else
1391NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1391); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 1391); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1392
1393NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindowInner)MozExternalRefCountType nsGlobalWindowInner::AddRef(void) { static_assert
(!std::is_destructible_v<nsGlobalWindowInner>, "Reference-counted class "
"nsGlobalWindowInner" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1393
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsGlobalWindowInner"
" not thread-safe"); nsISupports* base = nsGlobalWindowInner
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("nsGlobalWindowInner")
, (uint32_t)(sizeof(*this))); return count; }
1394NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindowInner)MozExternalRefCountType nsGlobalWindowInner::Release(void) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1394
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsGlobalWindowInner"
" not thread-safe"); nsISupports* base = nsGlobalWindowInner
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("nsGlobalWindowInner")); return
count; } void nsGlobalWindowInner::DeleteCycleCollectable(void
) { delete (this); }
1395
1396NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipReal( void*
p, [[maybe_unused]] bool aRemovingAllowed) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1397 if (tmp->IsBlackForCC(false)) {
1398 if (nsCCUncollectableMarker::InGeneration(tmp->mCanSkipCCGeneration)) {
1399 return true;
1400 }
1401 tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration;
1402 if (EventListenerManager* elm = tmp->GetExistingListenerManager()) {
1403 elm->MarkForCC();
1404 }
1405 if (tmp->mTimeoutManager) {
1406 tmp->mTimeoutManager->UnmarkGrayTimers();
1407 }
1408 return true;
1409 }
1410NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END(void)tmp; return false; }
1411
1412NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipInCCReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1413 return tmp->IsBlackForCC(true);
1414NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END(void)tmp; return false; }
1415
1416NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipThisReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1417 return tmp->IsBlackForCC(false);
1418NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END(void)tmp; return false; }
1419
1420NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowInner)nsGlobalWindowInner::cycleCollection nsGlobalWindowInner::_cycleCollectorGlobal
;
1421
1422NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)nsresult nsGlobalWindowInner::cycleCollection::TraverseNative
( void* p, nsCycleCollectionTraversalCallback& cb) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1423 if (MOZ_UNLIKELY(cb.WantDebugInfo())(__builtin_expect(!!(cb.WantDebugInfo()), 0))) {
1424 char name[512];
1425 nsAutoCString uri;
1426 if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
1427 uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
1428 }
1429 SprintfLiteral(name, "nsGlobalWindowInner # %" PRIu64"l" "u" " inner %s",
1430 tmp->mWindowID, uri.get());
1431 cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
1432 } else {
1433 NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindowInner, tmp->mRefCnt.get())cb.DescribeRefCountedNode(tmp->mRefCnt.get(), "nsGlobalWindowInner"
);
1434 }
1435
1436 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigation)ImplCycleCollectionTraverse(cb, tmp->mNavigation, "mNavigation"
, 0);
1437
1438 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)ImplCycleCollectionTraverse(cb, tmp->mNavigator, "mNavigator"
, 0);
1439
1440 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)ImplCycleCollectionTraverse(cb, tmp->mPerformance, "mPerformance"
, 0);
1441
1442 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebTaskScheduler)ImplCycleCollectionTraverse(cb, tmp->mWebTaskScheduler, "mWebTaskScheduler"
, 0);
1443
1444 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTrustedTypePolicyFactory)ImplCycleCollectionTraverse(cb, tmp->mTrustedTypePolicyFactory
, "mTrustedTypePolicyFactory", 0);
1445
1446#ifdef MOZ_WEBSPEECH1
1447 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)ImplCycleCollectionTraverse(cb, tmp->mSpeechSynthesis, "mSpeechSynthesis"
, 0);
1448#endif
1449
1450 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlean)ImplCycleCollectionTraverse(cb, tmp->mGlean, "mGlean", 0);
1451 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGleanPings)ImplCycleCollectionTraverse(cb, tmp->mGleanPings, "mGleanPings"
, 0);
1452
1453 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOuterWindow)ImplCycleCollectionTraverse(cb, tmp->mOuterWindow, "mOuterWindow"
, 0);
1454
1455 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopInnerWindow)ImplCycleCollectionTraverse(cb, tmp->mTopInnerWindow, "mTopInnerWindow"
, 0);
1456
1457 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)ImplCycleCollectionTraverse(cb, tmp->mListenerManager, "mListenerManager"
, 0);
1458
1459 if (tmp->mTimeoutManager) {
1460 tmp->mTimeoutManager->ForEachUnorderedTimeout([&cb](Timeout* timeout) {
1461 cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(Timeout)Timeout::cycleCollection::GetParticipant());
1462 });
1463 }
1464
1465 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)ImplCycleCollectionTraverse(cb, tmp->mLocation, "mLocation"
, 0);
1466 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHistory)ImplCycleCollectionTraverse(cb, tmp->mHistory, "mHistory",
0);
1467 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCustomElements)ImplCycleCollectionTraverse(cb, tmp->mCustomElements, "mCustomElements"
, 0);
1468 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSharedWorkers)ImplCycleCollectionTraverse(cb, tmp->mSharedWorkers, "mSharedWorkers"
, 0);
1469 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)ImplCycleCollectionTraverse(cb, tmp->mLocalStorage, "mLocalStorage"
, 0);
1470 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)ImplCycleCollectionTraverse(cb, tmp->mSessionStorage, "mSessionStorage"
, 0);
1471 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)ImplCycleCollectionTraverse(cb, tmp->mIndexedDB, "mIndexedDB"
, 0);
1472 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPrincipal, "mDocumentPrincipal"
, 0);
1473 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentCookiePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentCookiePrincipal
, "mDocumentCookiePrincipal", 0);
1474 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentStoragePrincipal
, "mDocumentStoragePrincipal", 0);
1475 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPartitionedPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPartitionedPrincipal
, "mDocumentPartitionedPrincipal", 0);
1476 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPolicyContainer)ImplCycleCollectionTraverse(cb, tmp->mDocumentPolicyContainer
, "mDocumentPolicyContainer", 0);
1477 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserChild)ImplCycleCollectionTraverse(cb, tmp->mBrowserChild, "mBrowserChild"
, 0);
1478 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)ImplCycleCollectionTraverse(cb, tmp->mDoc, "mDoc", 0);
1479 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebIdentityHandler)ImplCycleCollectionTraverse(cb, tmp->mWebIdentityHandler, "mWebIdentityHandler"
, 0);
1480
1481 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleRequestExecutor)ImplCycleCollectionTraverse(cb, tmp->mIdleRequestExecutor,
"mIdleRequestExecutor", 0);
1482 for (IdleRequest* request : tmp->mIdleRequestCallbacks) {
1483 cb.NoteNativeChild(request, NS_CYCLE_COLLECTION_PARTICIPANT(IdleRequest)IdleRequest::cycleCollection::GetParticipant());
1484 }
1485
1486 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClientSource)ImplCycleCollectionTraverse(cb, tmp->mClientSource, "mClientSource"
, 0);
1487
1488 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)ImplCycleCollectionTraverse(cb, tmp->mGamepads, "mGamepads"
, 0);
1489
1490 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)ImplCycleCollectionTraverse(cb, tmp->mCacheStorage, "mCacheStorage"
, 0);
1491 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)ImplCycleCollectionTraverse(cb, tmp->mVRDisplays, "mVRDisplays"
, 0);
1492
1493 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)ImplCycleCollectionTraverse(cb, tmp->mDebuggerNotificationManager
, "mDebuggerNotificationManager", 0);
1494
1495 // Traverse stuff from nsPIDOMWindow
1496 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler, "mChromeEventHandler"
, 0);
1497 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)ImplCycleCollectionTraverse(cb, tmp->mParentTarget, "mParentTarget"
, 0);
1498 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedElement)ImplCycleCollectionTraverse(cb, tmp->mFocusedElement, "mFocusedElement"
, 0);
1499 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0);
1500 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobalChild)ImplCycleCollectionTraverse(cb, tmp->mWindowGlobalChild, "mWindowGlobalChild"
, 0);
1501 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCloseWatcherManager)ImplCycleCollectionTraverse(cb, tmp->mCloseWatcherManager,
"mCloseWatcherManager", 0);
1502
1503 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenubar)ImplCycleCollectionTraverse(cb, tmp->mMenubar, "mMenubar",
0);
1504 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToolbar)ImplCycleCollectionTraverse(cb, tmp->mToolbar, "mToolbar",
0);
1505 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)ImplCycleCollectionTraverse(cb, tmp->mLocationbar, "mLocationbar"
, 0);
1506 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)ImplCycleCollectionTraverse(cb, tmp->mPersonalbar, "mPersonalbar"
, 0);
1507 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)ImplCycleCollectionTraverse(cb, tmp->mStatusbar, "mStatusbar"
, 0);
1508 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)ImplCycleCollectionTraverse(cb, tmp->mScrollbars, "mScrollbars"
, 0);
1509 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)ImplCycleCollectionTraverse(cb, tmp->mCrypto, "mCrypto", 0
);
1510 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)ImplCycleCollectionTraverse(cb, tmp->mConsole, "mConsole",
0);
1511 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCookieStore)ImplCycleCollectionTraverse(cb, tmp->mCookieStore, "mCookieStore"
, 0);
1512 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPiP)ImplCycleCollectionTraverse(cb, tmp->mDocumentPiP, "mDocumentPiP"
, 0);
1513 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPushManager)ImplCycleCollectionTraverse(cb, tmp->mPushManager, "mPushManager"
, 0);
1514 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)ImplCycleCollectionTraverse(cb, tmp->mPaintWorklet, "mPaintWorklet"
, 0);
1515 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)ImplCycleCollectionTraverse(cb, tmp->mExternal, "mExternal"
, 0);
1516 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)ImplCycleCollectionTraverse(cb, tmp->mIntlUtils, "mIntlUtils"
, 0);
1517 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualViewport)ImplCycleCollectionTraverse(cb, tmp->mVisualViewport, "mVisualViewport"
, 0);
1518 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPasteDataTransfer)ImplCycleCollectionTraverse(cb, tmp->mCurrentPasteDataTransfer
, "mCurrentPasteDataTransfer", 0);
1519
1520 tmp->TraverseObjectsInGlobal(cb);
1521
1522 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mMessageManager
, "mChromeFields.mMessageManager", 0);
1523 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mGroupMessageManagers
, "mChromeFields.mGroupMessageManagers", 0);
1524
1525 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1526 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mPromise, "mDocumentFlushedResolvers[i]->mPromise"
, 0);
;
1527 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mCallback, "mDocumentFlushedResolvers[i]->mCallback"
, 0);
;
1528 }
1529
1530NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
1531
1532NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Unlink(void* p) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1533 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences();
1534 if (sInnerWindowsById) {
1535 sInnerWindowsById->Remove(tmp->mWindowID);
1536 }
1537
1538 JSObject* wrapper = tmp->GetWrapperPreserveColor();
1539 if (wrapper) {
1540 // Mark our realm as dead, so the JS engine won't hand out our
1541 // global after this point.
1542 JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
1543 }
1544
1545 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1546
1547 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)ImplCycleCollectionUnlink(tmp->mNavigator);
1548
1549 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)ImplCycleCollectionUnlink(tmp->mPerformance);
1550
1551 if (tmp->mWebTaskScheduler) {
1552 tmp->mWebTaskScheduler->Disconnect();
1553 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebTaskScheduler)ImplCycleCollectionUnlink(tmp->mWebTaskScheduler);
1554 }
1555
1556 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTrustedTypePolicyFactory)ImplCycleCollectionUnlink(tmp->mTrustedTypePolicyFactory);
1557
1558#ifdef MOZ_WEBSPEECH1
1559 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)ImplCycleCollectionUnlink(tmp->mSpeechSynthesis);
1560#endif
1561
1562 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlean)ImplCycleCollectionUnlink(tmp->mGlean);
1563 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGleanPings)ImplCycleCollectionUnlink(tmp->mGleanPings);
1564
1565 if (tmp->mOuterWindow) {
1566 nsGlobalWindowOuter::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp);
1567 NS_IMPL_CYCLE_COLLECTION_UNLINK(mOuterWindow)ImplCycleCollectionUnlink(tmp->mOuterWindow);
1568 }
1569
1570 if (tmp->mListenerManager) {
1571 tmp->mListenerManager->Disconnect();
1572 NS_IMPL_CYCLE_COLLECTION_UNLINK(mListenerManager)ImplCycleCollectionUnlink(tmp->mListenerManager);
1573 }
1574
1575 // Here the Timeouts list would've been unlinked, but we rely on
1576 // that Timeout objects have been traced and will remove themselves
1577 // while unlinking.
1578
1579 tmp->UpdateTopInnerWindow();
1580 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTopInnerWindow)ImplCycleCollectionUnlink(tmp->mTopInnerWindow);
1581
1582 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)ImplCycleCollectionUnlink(tmp->mLocation);
1583 NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)ImplCycleCollectionUnlink(tmp->mHistory);
1584 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1585 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)ImplCycleCollectionUnlink(tmp->mCustomElements);
1586 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSharedWorkers)ImplCycleCollectionUnlink(tmp->mSharedWorkers);
1587 if (tmp->mLocalStorage) {
1588 tmp->mLocalStorage->Disconnect();
1589 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)ImplCycleCollectionUnlink(tmp->mLocalStorage);
1590 }
1591 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)ImplCycleCollectionUnlink(tmp->mSessionStorage);
1592 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)ImplCycleCollectionUnlink(tmp->mIndexedDB);
1593 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPrincipal);
1594 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentCookiePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentCookiePrincipal);
1595 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentStoragePrincipal);
1596 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPartitionedPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPartitionedPrincipal
);
1597 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPolicyContainer)ImplCycleCollectionUnlink(tmp->mDocumentPolicyContainer);
1598 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserChild)ImplCycleCollectionUnlink(tmp->mBrowserChild);
1599 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)ImplCycleCollectionUnlink(tmp->mDoc);
1600 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebIdentityHandler)ImplCycleCollectionUnlink(tmp->mWebIdentityHandler);
1601
1602 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)ImplCycleCollectionUnlink(tmp->mGamepads);
1603
1604 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)ImplCycleCollectionUnlink(tmp->mCacheStorage);
1605 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)ImplCycleCollectionUnlink(tmp->mVRDisplays);
1606
1607 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)ImplCycleCollectionUnlink(tmp->mDebuggerNotificationManager
);
1608
1609 // Unlink stuff from nsPIDOMWindow
1610 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)ImplCycleCollectionUnlink(tmp->mChromeEventHandler);
1611 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)ImplCycleCollectionUnlink(tmp->mParentTarget);
1612 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedElement)ImplCycleCollectionUnlink(tmp->mFocusedElement);
1613 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)ImplCycleCollectionUnlink(tmp->mBrowsingContext);
1614
1615 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1617); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1617); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1616 !tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1617); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1617); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1617 "How are we unlinking a window before its actor has been destroyed?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild
->IsClosed())>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!tmp->mWindowGlobalChild ||
tmp->mWindowGlobalChild->IsClosed()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
" (" "How are we unlinking a window before its actor has been destroyed?"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1617); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!tmp->mWindowGlobalChild || tmp->mWindowGlobalChild->IsClosed()"
") (" "How are we unlinking a window before its actor has been destroyed?"
")"); do { MOZ_CrashSequence(__null, 1617); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1618 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobalChild)ImplCycleCollectionUnlink(tmp->mWindowGlobalChild);
1619 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCloseWatcherManager)ImplCycleCollectionUnlink(tmp->mCloseWatcherManager);
1620
1621 NS_IMPL_CYCLE_COLLECTION_UNLINK(mMenubar)ImplCycleCollectionUnlink(tmp->mMenubar);
1622 NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)ImplCycleCollectionUnlink(tmp->mToolbar);
1623 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)ImplCycleCollectionUnlink(tmp->mLocationbar);
1624 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)ImplCycleCollectionUnlink(tmp->mPersonalbar);
1625 NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)ImplCycleCollectionUnlink(tmp->mStatusbar);
1626 NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)ImplCycleCollectionUnlink(tmp->mScrollbars);
1627 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)ImplCycleCollectionUnlink(tmp->mCrypto);
1628 NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)ImplCycleCollectionUnlink(tmp->mConsole);
1629 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCookieStore)ImplCycleCollectionUnlink(tmp->mCookieStore);
1630 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)ImplCycleCollectionUnlink(tmp->mPaintWorklet);
1631 NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)ImplCycleCollectionUnlink(tmp->mExternal);
1632 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)ImplCycleCollectionUnlink(tmp->mIntlUtils);
1633 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualViewport)ImplCycleCollectionUnlink(tmp->mVisualViewport);
1634 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCurrentPasteDataTransfer)ImplCycleCollectionUnlink(tmp->mCurrentPasteDataTransfer);
1635
1636 tmp->UnlinkObjectsInGlobal();
1637
1638 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)ImplCycleCollectionUnlink(tmp->mIdleRequestExecutor);
1639
1640 // Here the IdleRequest list would've been unlinked, but we rely on
1641 // that IdleRequest objects have been traced and will remove
1642 // themselves while unlinking.
1643
1644 NS_IMPL_CYCLE_COLLECTION_UNLINK(mClientSource)ImplCycleCollectionUnlink(tmp->mClientSource);
1645
1646 if (tmp->IsChromeWindow()) {
1647 if (tmp->mChromeFields.mMessageManager) {
1648 static_cast<nsFrameMessageManager*>(
1649 tmp->mChromeFields.mMessageManager.get())
1650 ->Disconnect();
1651 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)ImplCycleCollectionUnlink(tmp->mChromeFields.mMessageManager
);
1652 }
1653 tmp->DisconnectAndClearGroupMessageManagers();
1654 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mGroupMessageManagers)ImplCycleCollectionUnlink(tmp->mChromeFields.mGroupMessageManagers
);
1655 }
1656
1657 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1658 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mPromise);
;
1659 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mCallback);
;
1660 }
1661 tmp->mDocumentFlushedResolvers.Clear();
1662
1663 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPERtmp->ReleaseWrapper(p);
1664NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
1665
1666#ifdef DEBUG1
1667void nsGlobalWindowInner::RiskyUnlink() {
1668 NS_CYCLE_COLLECTION_INNERNAME_cycleCollectorGlobal.Unlink(this);
1669}
1670#endif
1671
1672NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Trace( void* p, [[
maybe_unused]] const TraceCallbacks& aCallbacks, [[maybe_unused
]] void* aClosure) { nsGlobalWindowInner* tmp = DowncastCCParticipant
<nsGlobalWindowInner>(p);
1673 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPERtmp->TraceWrapper(aCallbacks, aClosure);
1674NS_IMPL_CYCLE_COLLECTION_TRACE_END(void)tmp; }
1675
1676bool nsGlobalWindowInner::IsBlackForCC(bool aTracingNeeded) {
1677 if (!nsCCUncollectableMarker::sGeneration) {
1678 return false;
1679 }
1680
1681 return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) ||
1682 HasKnownLiveWrapper()) &&
1683 (!aTracingNeeded || HasNothingToTrace(ToSupports(this)));
1684}
1685
1686//*****************************************************************************
1687// nsGlobalWindowInner::nsIScriptGlobalObject
1688//*****************************************************************************
1689
1690bool nsGlobalWindowInner::ShouldResistFingerprinting(RFPTarget aTarget) const {
1691 if (mDoc) {
1692 return mDoc->ShouldResistFingerprinting(aTarget);
1693 }
1694 return nsContentUtils::ShouldResistFingerprinting(
1695 "If we do not have a document then we do not have any context"
1696 "to make an informed RFP choice, so we fall back to the global pref",
1697 aTarget);
1698}
1699
1700OriginTrials nsGlobalWindowInner::Trials() const {
1701 return OriginTrials::FromWindow(this);
1702}
1703
1704FontFaceSet* nsGlobalWindowInner::GetFonts() {
1705 if (mDoc) {
1706 return mDoc->Fonts();
1707 }
1708 return nullptr;
1709}
1710
1711mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult>
1712nsGlobalWindowInner::GetStorageKey() {
1713 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1713
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1713); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1714
1715 nsIPrincipal* principal = GetEffectiveStoragePrincipal();
1716 if (!principal) {
1717 return mozilla::Err(NS_ERROR_FAILURE);
1718 }
1719
1720 mozilla::ipc::PrincipalInfo principalInfo;
1721 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
1722 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1723 return mozilla::Err(rv);
1724 }
1725
1726 // Block expanded and null principals, let content and system through.
1727 if (principalInfo.type() !=
1728 mozilla::ipc::PrincipalInfo::TContentPrincipalInfo &&
1729 principalInfo.type() !=
1730 mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
1731 return Err(NS_ERROR_DOM_SECURITY_ERR);
1732 }
1733
1734 return std::move(principalInfo);
1735}
1736
1737mozilla::dom::StorageManager* nsGlobalWindowInner::GetStorageManager() {
1738 return Navigator()->Storage();
1739}
1740
1741// https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging
1742// * a Window object whose associated Document is fully active
1743bool nsGlobalWindowInner::IsEligibleForMessaging() { return IsFullyActive(); }
1744
1745void nsGlobalWindowInner::ReportToConsole(
1746 uint32_t aErrorFlags, const nsCString& aCategory, PropertiesFile aFile,
1747 const nsCString& aMessageName, const nsTArray<nsString>& aParams,
1748 const mozilla::SourceLocation& aLocation) {
1749 nsContentUtils::ReportToConsole(aErrorFlags, aCategory, mDoc, aFile,
1750 aMessageName.get(), aParams, aLocation);
1751}
1752
1753nsresult nsGlobalWindowInner::EnsureScriptEnvironment() {
1754 // NOTE: We can't use FORWARD_TO_OUTER here because we don't want to fail if
1755 // we're called on an inactive inner window.
1756 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1757 if (!outer) {
1758 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1758)
;
1759 return NS_ERROR_FAILURE;
1760 }
1761 return outer->EnsureScriptEnvironment();
1762}
1763
1764nsIScriptContext* nsGlobalWindowInner::GetScriptContext() {
1765 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1766 if (!outer) {
1767 return nullptr;
1768 }
1769 return outer->GetScriptContext();
1770}
1771
1772void nsGlobalWindowInner::TraceGlobalJSObject(JSTracer* aTrc) {
1773 TraceWrapper(aTrc, "active window global");
1774}
1775
1776void nsGlobalWindowInner::UpdateAutoplayPermission() {
1777 if (!GetWindowContext()) {
1778 return;
1779 }
1780 uint32_t perm =
1781 media::AutoplayPolicy::GetSiteAutoplayPermission(GetPrincipal());
1782 if (GetWindowContext()->GetAutoplayPermission() == perm) {
1783 return;
1784 }
1785
1786 // Setting autoplay permission on a discarded context has no effect.
1787 (void)GetWindowContext()->SetAutoplayPermission(perm);
1788}
1789
1790void nsGlobalWindowInner::UpdateShortcutsPermission() {
1791 if (!GetWindowContext() ||
1792 !GetWindowContext()->GetBrowsingContext()->IsTop()) {
1793 // We only cache the shortcuts permission on top-level WindowContexts
1794 // since we always check the top-level principal for the permission.
1795 return;
1796 }
1797
1798 uint32_t perm = GetShortcutsPermission(GetPrincipal());
1799
1800 if (GetWindowContext()->GetShortcutsPermission() == perm) {
1801 return;
1802 }
1803
1804 // If the WindowContext is discarded this has no effect.
1805 (void)GetWindowContext()->SetShortcutsPermission(perm);
1806}
1807
1808/* static */
1809uint32_t nsGlobalWindowInner::GetShortcutsPermission(nsIPrincipal* aPrincipal) {
1810 uint32_t perm = nsIPermissionManager::DENY_ACTION;
1811 nsCOMPtr<nsIPermissionManager> permMgr =
1812 mozilla::components::PermissionManager::Service();
1813 if (aPrincipal && permMgr) {
1814 permMgr->TestExactPermissionFromPrincipal(aPrincipal, "shortcuts"_ns,
1815 &perm);
1816 }
1817 return perm;
1818}
1819
1820void nsGlobalWindowInner::UpdatePopupPermission() {
1821 if (!GetWindowContext()) {
1822 return;
1823 }
1824
1825 uint32_t perm = PopupBlocker::GetPopupPermission(GetPrincipal());
1826 if (GetWindowContext()->GetPopupPermission() == perm) {
1827 return;
1828 }
1829
1830 // If the WindowContext is discarded this has no effect.
1831 (void)GetWindowContext()->SetPopupPermission(perm);
1832}
1833
1834void nsGlobalWindowInner::UpdatePermissions() {
1835 if (!GetWindowContext()) {
1836 return;
1837 }
1838
1839 nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
1840 RefPtr<WindowContext> windowContext = GetWindowContext();
1841
1842 WindowContext::Transaction txn;
1843 txn.SetAutoplayPermission(
1844 media::AutoplayPolicy::GetSiteAutoplayPermission(principal));
1845 txn.SetPopupPermission(PopupBlocker::GetPopupPermission(principal));
1846
1847 if (windowContext->IsTop()) {
1848 txn.SetShortcutsPermission(GetShortcutsPermission(principal));
1849 }
1850
1851 // Setting permissions on a discarded WindowContext has no effect
1852 (void)txn.Commit(windowContext);
1853}
1854
1855void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
1856 MOZ_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1856); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 1856); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1857
1858 if (MOZ_LOG_TEST(gDOMLeakPRLogInner, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gDOMLeakPRLogInner
, LogLevel::Debug)), 0))
) {
1859 nsIURI* uri = mDoc->GetDocumentURI();
1860 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
1861 ("DOMWINDOW %p SetNewDocument %s", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
1862 uri ? uri->GetSpecOrDefault().get() : ""))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOMWINDOW %p SetNewDocument %s", this, uri
? uri->GetSpecOrDefault().get() : ""); } } while (0)
;
1863 }
1864
1865 mFocusedElement = nullptr;
1866 mLocalStorage = nullptr;
1867 mSessionStorage = nullptr;
1868 mPerformance = nullptr;
1869 if (mWebTaskScheduler) {
1870 mWebTaskScheduler->Disconnect();
1871 mWebTaskScheduler = nullptr;
1872 SetWebTaskSchedulingState(nullptr);
1873 }
1874
1875 // This must be called after nullifying the internal objects because here we
1876 // could recreate them, calling the getter methods, and store them into the JS
1877 // slots. If we nullify them after, the slot values and the objects will be
1878 // out of sync.
1879 ClearDocumentDependentSlots(aCx);
1880
1881 if (!mWindowGlobalChild) {
1882 mWindowGlobalChild = WindowGlobalChild::Create(this);
1883 } else {
1884 // If the window global existed before the window, it must've come from the
1885 // AboutBlankInitializer
1886 MOZ_ASSERT(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI()),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" " ("
"AboutBlankInitializer should only be used with about:blank"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1887); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1887 "AboutBlankInitializer should only be used with about:blank")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI(
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())" " ("
"AboutBlankInitializer should only be used with about:blank"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
1887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1887); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1888 }
1889 MOZ_ASSERT(!GetWindowContext()->HasBeenUserGestureActivated(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1891); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1890 "WindowContext should always not have user gesture activation at "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1891); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1891 "this point.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetWindowContext()->HasBeenUserGestureActivated(
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!GetWindowContext()->HasBeenUserGestureActivated(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!GetWindowContext()->HasBeenUserGestureActivated()" " ("
"WindowContext should always not have user gesture activation at "
"this point." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1891); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
1892
1893 UpdatePermissions();
1894
1895 RefPtr<PermissionDelegateHandler> permDelegateHandler =
1896 mDoc->GetPermissionDelegateHandler();
1897
1898 if (permDelegateHandler) {
1899 permDelegateHandler->PopulateAllDelegatedPermissions();
1900 }
1901
1902#if defined(MOZ_WIDGET_ANDROID)
1903 // When we insert the new document to the window in the top-level browsing
1904 // context, we should reset the status of the request which is used for the
1905 // previous document.
1906 if (mWindowGlobalChild && GetBrowsingContext() &&
1907 !GetBrowsingContext()->GetParent()) {
1908 // Return value of setting synced field should be checked. See bug 1656492.
1909 (void)GetBrowsingContext()->ResetGVAutoplayRequestStatus();
1910 }
1911#endif
1912
1913#ifdef DEBUG1
1914 mLastOpenedURI = mDoc->GetDocumentURI();
1915#endif
1916}
1917
1918nsresult nsGlobalWindowInner::EnsureClientSource() {
1919 MOZ_DIAGNOSTIC_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1919); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mDoc"
")"); do { MOZ_CrashSequence(__null, 1919); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1920
1921 bool newClientSource = false;
1922
1923 // Get the load info for the document if we performed a load. Be careful not
1924 // to look at local URLs, though. Local URLs are those that have a scheme of:
1925 // * about:
1926 // * data:
1927 // * blob:
1928 // We also do an additional check here so that we only treat about:blank
1929 // and about:srcdoc as local URLs. Other internal firefox about: URLs should
1930 // not be treated this way.
1931 nsCOMPtr<nsILoadInfo> loadInfo;
1932 nsCOMPtr<nsIChannel> channel = mDoc->GetChannel();
1933 if (channel) {
1934 nsCOMPtr<nsIURI> uri;
1935 (void)channel->GetURI(getter_AddRefs(uri));
1936
1937 bool ignoreLoadInfo = false;
1938
1939 if (uri->SchemeIs("about")) {
1940 ignoreLoadInfo =
1941 NS_IsAboutBlankAllowQueryAndFragment(uri) || NS_IsAboutSrcdoc(uri);
1942 } else {
1943 // Its not an about: URL, so now check for our other URL types.
1944 ignoreLoadInfo = uri->SchemeIs("data") || uri->SchemeIs("blob");
1945 }
1946
1947 if (!ignoreLoadInfo) {
1948 loadInfo = channel->LoadInfo();
1949 }
1950 }
1951
1952 // Take the initial client source from the docshell immediately. Even if we
1953 // don't end up using it here we should consume it.
1954 UniquePtr<ClientSource> initialClientSource;
1955 nsIDocShell* docshell = GetDocShell();
1956 if (docshell) {
1957 initialClientSource = docshell->TakeInitialClientSource();
1958 }
1959
1960 // Try to get the reserved client from the LoadInfo. A Client is
1961 // reserved at the start of the channel load if there is not an
1962 // initial uncommitted about:blank whose window will be reused. It is also
1963 // created if the channel load encounters a cross-origin redirect.
1964 if (loadInfo) {
1965 UniquePtr<ClientSource> reservedClient =
1966 loadInfo->TakeReservedClientSource();
1967 if (reservedClient) {
1968 mClientSource.reset();
1969 mClientSource = std::move(reservedClient);
1970 newClientSource = true;
1971 }
1972 }
1973
1974 // We don't have a LoadInfo reserved client, but maybe we should
1975 // be inheriting an initial one from the docshell. This means
1976 // that the docshell started the channel load before creating the
1977 // initial about:blank document. This is an optimization, though,
1978 // and it created an initial Client as a placeholder for the document.
1979 // In this case we want to inherit this placeholder Client here.
1980 if (!mClientSource) {
1981 mClientSource = std::move(initialClientSource);
1982 if (mClientSource) {
1983 newClientSource = true;
1984 }
1985 }
1986
1987 nsCOMPtr<nsIPrincipal> foreignPartitionedPrincipal;
1988
1989 nsresult rv = StoragePrincipalHelper::GetPrincipal(
1990 this, StoragePrincipalHelper::eForeignPartitionedPrincipal,
1991 getter_AddRefs(foreignPartitionedPrincipal));
1992 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1992); return rv; } } while (false)
;
1993
1994 // Verify the final ClientSource principal matches the final document
1995 // principal. The ClientChannelHelper handles things like network
1996 // redirects, but there are other ways the document principal can change.
1997 // For example, if something sets the nsIChannel.owner property, then
1998 // the final channel principal can be anything. Unfortunately there is
1999 // no good way to detect this until after the channel completes loading.
2000 //
2001 // For now we handle this just by reseting the ClientSource. This will
2002 // result in a new ClientSource with the correct principal being created.
2003 // To APIs like ServiceWorker and Clients API it will look like there was
2004 // an initial content page created that was then immediately replaced.
2005 // This is pretty close to what we are actually doing.
2006 if (mClientSource) {
2007 auto principalOrErr = mClientSource->Info().GetPrincipal();
2008 nsCOMPtr<nsIPrincipal> clientPrincipal =
2009 principalOrErr.isOk() ? principalOrErr.unwrap() : nullptr;
2010 if (!clientPrincipal ||
2011 !clientPrincipal->Equals(foreignPartitionedPrincipal)) {
2012 mClientSource.reset();
2013 }
2014 }
2015
2016 // If we don't have a reserved client or an initial client, then create
2017 // one now. This can happen in certain cases where we avoid preallocating
2018 // the client in the docshell. This mainly occurs in situations where
2019 // the principal is not clearly inherited from the parent; e.g. sandboxed
2020 // iframes, window.open(), etc.
2021 //
2022 // We also do this late ClientSource creation if the final document ended
2023 // up with a different principal.
2024 //
2025 // TODO: We may not be marking initial about:blank documents created
2026 // this way as controlled by a service worker properly. The
2027 // controller should be coming from the same place as the inheritted
2028 // principal. We do this in docshell, but as mentioned we aren't
2029 // smart enough to handle all cases yet. For example, a
2030 // window.open() with new URL should inherit the controller from
2031 // the opener, but we probably don't handle that yet.
2032 if (!mClientSource) {
2033 mClientSource = ClientManager::CreateSource(
2034 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2035 MOZ_DIAGNOSTIC_ASSERT(mClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mClientSource))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mClientSource",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2035
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2035); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2036 newClientSource = true;
2037
2038 // Note, we don't apply the loadinfo controller below if we create
2039 // the ClientSource here.
2040 }
2041
2042 // The load may have started controlling the Client as well. If
2043 // so, mark it as controlled immediately here. The actor may
2044 // or may not have been notified by the parent side about being
2045 // controlled yet.
2046 //
2047 // Note: We should be careful not to control a client that was created late.
2048 // These clients were not seen by the ServiceWorkerManager when it
2049 // marked the LoadInfo controlled and it won't know about them. Its
2050 // also possible we are creating the client late due to the final
2051 // principal changing and these clients should definitely not be
2052 // controlled by a service worker with a different principal.
2053 else if (loadInfo) {
2054 const Maybe<ServiceWorkerDescriptor> controller = loadInfo->GetController();
2055 if (controller.isSome()) {
2056 mClientSource->SetController(controller.ref());
2057 }
2058
2059 // We also have to handle the case where te initial about:blank is
2060 // controlled due to inheritting the service worker from its parent,
2061 // but the actual nsIChannel load is not covered by any service worker.
2062 // In this case we want the final page to be uncontrolled. There is
2063 // an open spec issue about how exactly this should be handled, but for
2064 // now we just force creation of a new ClientSource to clear the
2065 // controller.
2066 //
2067 // https://github.com/w3c/ServiceWorker/issues/1232
2068 //
2069 else if (mClientSource->GetController().isSome()) {
2070 mClientSource.reset();
2071 mClientSource = ClientManager::CreateSource(
2072 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2073 MOZ_DIAGNOSTIC_ASSERT(mClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mClientSource))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mClientSource",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2073
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2073); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2074 newClientSource = true;
2075 }
2076 }
2077
2078 if (mClientSource) {
2079 // Generally the policyContainer is stored within the Client and cached on
2080 // the document. At the time of policyContainer parsing however, the Client
2081 // has not been created yet, hence we store the policyContainer on the
2082 // document and propagate/sync the policyContainer with Client here when we
2083 // create the Client.
2084 mClientSource->SetPolicyContainer(mDoc->GetPolicyContainer());
2085
2086 DocGroup* docGroup = GetDocGroup();
2087 MOZ_DIAGNOSTIC_ASSERT(docGroup)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docGroup)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(docGroup))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("docGroup", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2087); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "docGroup"
")"); do { MOZ_CrashSequence(__null, 2087); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2088 mClientSource->SetAgentClusterId(docGroup->AgentClusterId());
2089
2090 if (mWindowGlobalChild) {
2091 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
2092 }
2093 }
2094
2095 // Its possible that we got a client just after being frozen in
2096 // the bfcache. In that case freeze the client immediately.
2097 if (newClientSource && IsFrozen()) {
2098 mClientSource->Freeze();
2099 }
2100
2101 return NS_OK;
2102}
2103
2104nsresult nsGlobalWindowInner::ExecutionReady() {
2105 nsresult rv = EnsureClientSource();
2106 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2106); return rv; } } while (false)
;
2107
2108 rv = mClientSource->WindowExecutionReady(this);
2109 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2109); return rv; } } while (false)
;
2110
2111 return NS_OK;
2112}
2113
2114void nsGlobalWindowInner::UpdateParentTarget() {
2115 // NOTE: This method is identical to
2116 // nsGlobalWindowOuter::UpdateParentTarget(). IF YOU UPDATE THIS METHOD,
2117 // UPDATE THE OTHER ONE TOO!
2118
2119 // Try to get our frame element's tab child global (its in-process message
2120 // manager). If that fails, fall back to the chrome event handler's tab
2121 // child global, and if it doesn't have one, just use the chrome event
2122 // handler itself.
2123
2124 nsPIDOMWindowOuter* outer = GetOuterWindow();
2125 if (!outer) {
2126 return;
2127 }
2128 nsCOMPtr<Element> frameElement = outer->GetFrameElementInternal();
2129 nsCOMPtr<EventTarget> eventTarget =
2130 nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2131
2132 if (!eventTarget) {
2133 nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal();
2134 if (topWin) {
2135 frameElement = topWin->GetFrameElementInternal();
2136 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2137 }
2138 }
2139
2140 if (!eventTarget) {
2141 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(mChromeEventHandler);
2142 }
2143
2144 if (!eventTarget) {
2145 eventTarget = mChromeEventHandler;
2146 }
2147
2148 mParentTarget = std::move(eventTarget);
2149}
2150
2151EventTarget* nsGlobalWindowInner::GetTargetForDOMEvent() {
2152 return GetOuterWindowInternal();
2153}
2154
2155void nsGlobalWindowInner::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
2156 aVisitor.mCanHandle = true;
2157 aVisitor.mForceContentDispatch = true; // FIXME! Bug 329119
2158 switch (aVisitor.mEvent->mMessage) {
2159 case eResize:
2160 if (aVisitor.mEvent->IsTrusted()) {
2161 // Checking whether the event target is an inner window or not, so we
2162 // can keep the old behavior also in case a child window is handling
2163 // resize.
2164 if (aVisitor.mEvent->mOriginalTarget &&
2165 aVisitor.mEvent->mOriginalTarget->IsInnerWindow()) {
2166 mIsHandlingResizeEvent = true;
2167 }
2168 }
2169 break;
2170 case eMouseDown:
2171 if (aVisitor.mEvent->IsTrusted()) {
2172 sMouseDown = true;
2173 }
2174 break;
2175 case eMouseUp:
2176 case eDragEnd:
2177 if (aVisitor.mEvent->IsTrusted()) {
2178 MouseButtonReleased();
2179 }
2180 break;
2181 default:
2182 break;
2183 }
2184
2185 aVisitor.SetParentTarget(GetParentTarget(), true);
2186}
2187
2188/* static */
2189void nsGlobalWindowInner::MouseButtonReleased() {
2190 if (!sMouseDown) {
2191 return;
2192 }
2193 sMouseDown = false;
2194 if (sDragServiceDisabled) {
2195 nsCOMPtr<nsIDragService> ds =
2196 do_GetService("@mozilla.org/widget/dragservice;1");
2197 if (ds) {
2198 sDragServiceDisabled = false;
2199 ds->Unsuppress();
2200 }
2201 }
2202}
2203
2204// Editor library types for about:blank compat workaround
2205enum class EmptyFrameLibrary {
2206 None,
2207 CKEditor,
2208 GWT,
2209 ZE,
2210};
2211
2212// ckeditor 4 uses UA sniffing to wait for an async load event for its editor
2213// iframe. This patch makes it work by delaying the sync-about:blank's load
2214// event on such frames. See bug 2002481 and:
2215// https://github.com/ckeditor/ckeditor4/blob/c7e59ec199298b6b23f4aa7a7668f18572385bac/plugins/wysiwygarea/plugin.js#L43
2216//
2217// GWT RichTextArea also uses UA sniffing and expects an async `load` event
2218// for its editor iframe. See bug 2020927,
2219// https://github.com/gwtproject/gwt/issues/10292 , and
2220// https://github.com/gwtproject/gwt/blob/4b6a646faf0e9ce579658d78b6acf9fe5c840379/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplMozilla.java#L44
2221// .
2222//
2223// Polarion appears to use the GWT Editor too, but with a different class name.
2224//
2225// Old version of ZE appears to have a similar problem. Newer versions don't,
2226// because they have `srcdoc`. See bug 2020668.
2227MOZ_CAN_RUN_SCRIPT static bool IsDeferredLoadEmptyFrame(Element& aEmbedder) {
2228 const nsAttrValue* classes = aEmbedder.GetClasses();
2229 if (!classes) {
2230 return false;
2231 }
2232 EmptyFrameLibrary lib = EmptyFrameLibrary::None;
2233 if (StaticPrefs::dom_about_blank_ckeditor_hack_enabled() &&
2234 classes->Contains(nsGkAtoms::cke_wysiwyg_frame, eCaseMatters)) {
2235 lib = EmptyFrameLibrary::CKEditor;
2236 } else if (StaticPrefs::dom_about_blank_gwt_hack_enabled() &&
2237 classes->Contains(nsGkAtoms::gwt_RichTextArea, eCaseMatters)) {
2238 lib = EmptyFrameLibrary::GWT;
2239 } else if (StaticPrefs::dom_about_blank_polarion_gwt_hack_enabled() &&
2240 classes->Contains(nsGkAtoms::polarion_rte_RichTextArea,
2241 eCaseMatters)) {
2242 lib = EmptyFrameLibrary::GWT;
2243 } else if (StaticPrefs::dom_about_blank_ze_hack_enabled() &&
2244 classes->Contains(nsGkAtoms::ze_area, eCaseMatters)) {
2245 lib = EmptyFrameLibrary::ZE;
2246 }
2247 if (lib == EmptyFrameLibrary::None) {
2248 return false;
2249 }
2250 if (!aEmbedder.IsHTMLElement(nsGkAtoms::iframe)) {
2251 return false;
2252 }
2253 // We only come here if the initial document is reaching its load event.
2254 // That doesn't happen with `srcdoc`, which is an immediate navigation
2255 // to a non-about:blank document. Newer versions of ZE don't need this
2256 // and don't come here, because they have `srcdoc`.
2257 // Note: We can assert on `srcdoc` only after excluding non-iframe
2258 // element type above!
2259 MOZ_ASSERT(!aEmbedder.HasAttr(nsGkAtoms::srcdoc))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aEmbedder.HasAttr(nsGkAtoms::srcdoc))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!aEmbedder.HasAttr(nsGkAtoms::srcdoc)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!aEmbedder.HasAttr(nsGkAtoms::srcdoc)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2259
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aEmbedder.HasAttr(nsGkAtoms::srcdoc)"
")"); do { MOZ_CrashSequence(__null, 2259); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2260 const auto* src = aEmbedder.GetParsedAttr(nsGkAtoms::src);
2261 // Require empty src for CKEditor 4 and no src for GWT and ZE.
2262 switch (lib) {
2263 case EmptyFrameLibrary::CKEditor:
2264 if (!src || !src->IsEmptyString()) {
2265 return false;
2266 }
2267 break;
2268 default:
2269 if (src) {
2270 return false;
2271 }
2272 break;
2273 }
2274 const char* blocklistPref = "";
2275 switch (lib) {
2276 case EmptyFrameLibrary::CKEditor:
2277 blocklistPref = "dom.about-blank-ckeditor-hack.disabled-domains";
2278 break;
2279 case EmptyFrameLibrary::GWT:
2280 blocklistPref = "dom.about-blank-gwt-hack.disabled-domains";
2281 break;
2282 case EmptyFrameLibrary::ZE:
2283 blocklistPref = "dom.about-blank-ze-hack.disabled-domains";
2284 break;
2285 case EmptyFrameLibrary::None:
2286 MOZ_ASSERT_UNREACHABLE()do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
2286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2286); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2287 return false;
2288 }
2289
2290 // Deal with the blocklist here before properties on the global
2291 // (which is potentially observable via JS getters).
2292 if (aEmbedder.NodePrincipal()->IsURIInPrefList(blocklistPref)) {
2293 return false;
2294 }
2295 // Finally, we also look for an identifying property on the embedder's global
2296 // to be extra sure.
2297 RefPtr global = aEmbedder.GetRelevantGlobal();
2298 if (!global || !global->GetGlobalJSObject()) {
2299 return false;
2300 }
2301 AutoJSAPI jsapi;
2302 if (!jsapi.Init(global)) {
2303 return false;
2304 }
2305 if (lib == EmptyFrameLibrary::GWT) {
2306 JS::Rooted<JSObject*> globalObj(jsapi.cx(), global->GetGlobalJSObject());
2307 JS::Rooted<JS::Value> val(jsapi.cx());
2308 if (!JS_GetProperty(jsapi.cx(), globalObj, "__gwt_stylesLoaded", &val)) {
2309 JS_ClearPendingException(jsapi.cx());
2310 return false;
2311 }
2312 if (!val.isObject()) {
2313 return false;
2314 }
2315 aEmbedder.OwnerDoc()->WarnOnceAbout(
2316 DeprecatedOperations::eGWTRichTextAreaCompatHack);
2317 return true;
2318 }
2319 CkEditorProperty property;
2320 JS::Rooted<JS::Value> v(jsapi.cx(),
2321 JS::ObjectValue(*global->GetGlobalJSObject()));
2322 if (!property.Init(jsapi.cx(), v)) {
2323 JS_ClearPendingException(jsapi.cx());
2324 return false;
2325 }
2326 switch (lib) {
2327 case EmptyFrameLibrary::GWT:
2328 case EmptyFrameLibrary::None:
2329 MOZ_ASSERT_UNREACHABLE()do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
2329); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2329); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2330 return false;
2331 case EmptyFrameLibrary::ZE:
2332 if (!property.mZE_Init.WasPassed()) {
2333 return false;
2334 }
2335 // No use counter at least for now.
2336 aEmbedder.OwnerDoc()->WarnOnceAbout(
2337 DeprecatedOperations::eOldZECompatHack);
2338 return true;
2339 case EmptyFrameLibrary::CKEditor:
2340 const auto* version = [&]() -> const CkEditorVersion* {
2341 if (property.mCKEDITOR.WasPassed()) {
2342 return &property.mCKEDITOR.Value();
2343 }
2344 if (property.mJEDITOR.WasPassed()) {
2345 return &property.mJEDITOR.Value();
2346 }
2347 return nullptr;
2348 }();
2349 if (!version) {
2350 return false;
2351 }
2352 // The CKEditor source code has "%VERSION%", which may be left in place
2353 // in deployment if a proper build step is missing.
2354 if (!(StringBeginsWith(version->mVersion, u"4."_ns) ||
2355 version->mVersion.EqualsLiteral(u"%VERSION%"))) {
2356 return false;
2357 }
2358 aEmbedder.OwnerDoc()->WarnOnceAbout(
2359 DeprecatedOperations::eCKEditor4CompatHack);
2360 return true;
2361 }
2362 MOZ_ASSERT_UNREACHABLE("Every switch case should have returned.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Every switch case should have returned." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2362); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Every switch case should have returned."
")"); do { MOZ_CrashSequence(__null, 2362); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2363 return false;
2364}
2365
2366MOZ_CAN_RUN_SCRIPT static bool NeedsAsyncLoadEventForInitialDocument(
2367 nsGlobalWindowInner& aInner, Element& aEmbedder) {
2368 if (auto* doc = aInner.GetExtantDoc(); !doc || !doc->IsInitialDocument()) {
2369 return false;
2370 }
2371 return IsDeferredLoadEmptyFrame(aEmbedder);
2372}
2373
2374void nsGlobalWindowInner::FireFrameLoadEvent() {
2375 // If we're not in a content frame, or are at a BrowsingContext tree boundary,
2376 // such as the content-chrome boundary, don't fire the "load" event.
2377 if (GetBrowsingContext()->IsTopContent() ||
2378 GetBrowsingContext()->IsChrome()) {
2379 return;
2380 }
2381
2382 // If embedder is same-process, fire the event on our embedder element.
2383 //
2384 // XXX: Bug 1440212 is looking into potentially changing this behaviour to act
2385 // more like the remote case when in-process.
2386 if (RefPtr<Element> element = GetBrowsingContext()->GetEmbedderElement()) {
2387 if (NeedsAsyncLoadEventForInitialDocument(*this, *element)) {
2388 (new AsyncEventDispatcher(element, eLoad, CanBubble::eNo))
2389 ->PostDOMEvent();
2390 return;
2391 }
2392
2393 nsEventStatus status = nsEventStatus_eIgnore;
2394 WidgetEvent event(/* aIsTrusted = */ true, eLoad);
2395 event.mFlags.mBubbles = false;
2396 event.mFlags.mCancelable = false;
2397
2398 // Most of the time we could get a pres context to pass in here, but not
2399 // always (i.e. if this window is not shown there won't be a pres context
2400 // available). Since we're not firing a GUI event we don't need a pres
2401 // context anyway so we just pass null as the pres context all the time.
2402 EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status);
2403 return;
2404 }
2405
2406 // We don't have an in-process embedder. Try to get our `BrowserChild` actor
2407 // to send a message to that embedder. We want to double-check that our outer
2408 // window is actually the one at the root of this browserChild though, just in
2409 // case.
2410 RefPtr<BrowserChild> browserChild =
2411 BrowserChild::GetFrom(static_cast<nsPIDOMWindowInner*>(this));
2412 if (browserChild &&
2413 !GetBrowsingContext()->GetParentWindowContext()->IsInProcess()) {
2414 // Double-check that our outer window is actually at the root of this
2415 // `BrowserChild`, in case we're in an odd maybe-unhosted situation like a
2416 // print preview dialog.
2417 nsCOMPtr<nsPIDOMWindowOuter> rootOuter =
2418 do_GetInterface(browserChild->WebNavigation());
2419 if (!rootOuter || rootOuter != GetOuterWindow()) {
2420 return;
2421 }
2422
2423 (void)browserChild->SendMaybeFireEmbedderLoadEvents(
2424 EmbedderElementEventType::LoadEvent);
2425 }
2426}
2427
2428nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) {
2429 // Return early if there is nothing to do.
2430 switch (aVisitor.mEvent->mMessage) {
2431 case eResize:
2432 case eUnload:
2433 case eLoad:
2434 break;
2435 default:
2436 return NS_OK;
2437 }
2438
2439 /* mChromeEventHandler and mContext go dangling in the middle of this
2440 function under some circumstances (events that destroy the window)
2441 without this addref. */
2442 RefPtr<EventTarget> kungFuDeathGrip1(mChromeEventHandler);
2443 (void)kungFuDeathGrip1; // These aren't referred to through the function
2444 nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
2445 (void)kungFuDeathGrip2; // These aren't referred to through the function
2446
2447 if (aVisitor.mEvent->mMessage == eResize) {
2448 mIsHandlingResizeEvent = false;
2449 } else if (aVisitor.mEvent->mMessage == eUnload &&
2450 aVisitor.mEvent->IsTrusted()) {
2451 // If any VR display presentation is active at unload, the next page
2452 // will receive a vrdisplayactive event to indicate that it should
2453 // immediately begin vr presentation. This should occur when navigating
2454 // forwards, navigating backwards, and on page reload.
2455 for (const auto& display : mVRDisplays) {
2456 if (display->IsPresenting()) {
2457 display->StartVRNavigation();
2458 // Save this VR display ID to trigger vrdisplayactivate event
2459 // after the next load event.
2460 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2461 if (outer) {
2462 outer->SetAutoActivateVRDisplayID(display->DisplayId());
2463 }
2464
2465 // XXX The WebVR 1.1 spec does not define which of multiple VR
2466 // presenting VR displays will be chosen during navigation.
2467 // As the underlying platform VR API's currently only allow a single
2468 // VR display, it is safe to choose the first VR display for now.
2469 break;
2470 }
2471 }
2472 mIsDocumentLoaded = false;
2473 // Tell the parent process that the document is not loaded.
2474 if (mWindowGlobalChild) {
2475 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2476 mWindowGlobalChild->OnDocumentUnloaded();
2477 }
2478 } else if (aVisitor.mEvent->mMessage == eLoad &&
2479 aVisitor.mEvent->IsTrusted()) {
2480 // This is page load event since load events don't propagate to |window|.
2481 // @see Document::GetEventTargetParent.
2482 mIsDocumentLoaded = true;
2483 // Tell the parent process that the document is loaded.
2484 if (mWindowGlobalChild) {
2485 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2486 mWindowGlobalChild->OnDocumentLoaded();
2487 }
2488
2489 mTimeoutManager->OnDocumentLoaded();
2490
2491 MOZ_ASSERT(aVisitor.mEvent->IsTrusted())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aVisitor.mEvent->IsTrusted())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aVisitor.mEvent->IsTrusted
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aVisitor.mEvent->IsTrusted()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVisitor.mEvent->IsTrusted()"
")"); do { MOZ_CrashSequence(__null, 2491); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2492 FireFrameLoadEvent();
2493
2494 if (mVREventObserver) {
2495 mVREventObserver->NotifyAfterLoad();
2496 }
2497
2498 uint32_t autoActivateVRDisplayID = 0;
2499 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2500 if (outer) {
2501 autoActivateVRDisplayID = outer->GetAutoActivateVRDisplayID();
2502 }
2503 if (autoActivateVRDisplayID) {
2504 DispatchVRDisplayActivate(autoActivateVRDisplayID,
2505 VRDisplayEventReason::Navigation);
2506 }
2507 }
2508
2509 return NS_OK;
2510}
2511
2512nsresult nsGlobalWindowInner::DefineArgumentsProperty(nsIArray* aArguments) {
2513 nsIScriptContext* ctx = GetOuterWindowInternal()->mContext;
2514 NS_ENSURE_TRUE(aArguments && ctx, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(aArguments && ctx)), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aArguments && ctx"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2514); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2515
2516 JS::Rooted<JSObject*> obj(RootingCx(), GetWrapperPreserveColor());
2517 return ctx->SetProperty(obj, "arguments", aArguments);
2518}
2519
2520//*****************************************************************************
2521// nsGlobalWindowInner::nsIScriptObjectPrincipal
2522//*****************************************************************************
2523
2524nsIPrincipal* nsGlobalWindowInner::GetPrincipal() {
2525 if (mDoc) {
2526 // If we have a document, get the principal from the document
2527 return mDoc->NodePrincipal();
2528 }
2529
2530 if (mDocumentPrincipal) {
2531 return mDocumentPrincipal;
2532 }
2533
2534 // If we don't have a principal and we don't have a document we
2535 // ask the parent window for the principal. This can happen when
2536 // loading a frameset that has a <frame src="javascript:xxx">, in
2537 // that case the global window is used in JS before we've loaded
2538 // a document into the window.
2539
2540 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2541 do_QueryInterface(GetInProcessParentInternal());
2542
2543 if (objPrincipal) {
2544 return objPrincipal->GetPrincipal();
2545 }
2546
2547 return nullptr;
2548}
2549
2550nsIPrincipal* nsGlobalWindowInner::GetEffectiveCookiePrincipal() {
2551 if (mDoc) {
2552 // If we have a document, get the principal from the document
2553 return mDoc->EffectiveCookiePrincipal();
2554 }
2555
2556 if (mDocumentCookiePrincipal) {
2557 return mDocumentCookiePrincipal;
2558 }
2559
2560 // If we don't have a cookie principal and we don't have a document we ask
2561 // the parent window for the cookie principal.
2562
2563 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2564 do_QueryInterface(GetInProcessParentInternal());
2565
2566 if (objPrincipal) {
2567 return objPrincipal->GetEffectiveCookiePrincipal();
2568 }
2569
2570 return nullptr;
2571}
2572
2573nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() {
2574 if (mDoc) {
2575 // If we have a document, get the principal from the document
2576 return mDoc->EffectiveStoragePrincipal();
2577 }
2578
2579 if (mDocumentStoragePrincipal) {
2580 return mDocumentStoragePrincipal;
2581 }
2582
2583 // If we don't have a cookie principal and we don't have a document we ask
2584 // the parent window for the cookie principal.
2585
2586 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2587 do_QueryInterface(GetInProcessParentInternal());
2588
2589 if (objPrincipal) {
2590 return objPrincipal->GetEffectiveStoragePrincipal();
2591 }
2592
2593 return nullptr;
2594}
2595
2596nsIPrincipal* nsGlobalWindowInner::PartitionedPrincipal() {
2597 if (mDoc) {
2598 // If we have a document, get the principal from the document
2599 return mDoc->PartitionedPrincipal();
2600 }
2601
2602 if (mDocumentPartitionedPrincipal) {
2603 return mDocumentPartitionedPrincipal;
2604 }
2605
2606 // If we don't have a partitioned principal and we don't have a document we
2607 // ask the parent window for the partitioned principal.
2608
2609 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2610 do_QueryInterface(GetInProcessParentInternal());
2611
2612 if (objPrincipal) {
2613 return objPrincipal->PartitionedPrincipal();
2614 }
2615
2616 return nullptr;
2617}
2618
2619//*****************************************************************************
2620// nsGlobalWindowInner::nsIDOMWindow
2621//*****************************************************************************
2622
2623bool nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext) {
2624 mAudioContexts.AppendElement(aAudioContext);
2625
2626 // Return true if the context should be muted and false if not.
2627 nsIDocShell* docShell = GetDocShell();
2628 return docShell && !docShell->GetAllowMedia() && !aAudioContext->IsOffline();
2629}
2630
2631void nsPIDOMWindowInner::RemoveAudioContext(AudioContext* aAudioContext) {
2632 mAudioContexts.RemoveElement(aAudioContext);
2633}
2634
2635void nsPIDOMWindowInner::MuteAudioContexts() {
2636 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2637 if (!mAudioContexts[i]->IsOffline()) {
2638 mAudioContexts[i]->Mute();
2639 }
2640 }
2641}
2642
2643void nsPIDOMWindowInner::UnmuteAudioContexts() {
2644 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2645 if (!mAudioContexts[i]->IsOffline()) {
2646 mAudioContexts[i]->Unmute();
2647 }
2648 }
2649}
2650
2651WindowProxyHolder nsGlobalWindowInner::Window() {
2652 return WindowProxyHolder(GetBrowsingContext());
2653}
2654
2655Navigation* nsPIDOMWindowInner::Navigation() {
2656 if (!mNavigation && Navigation::IsAPIEnabled()) {
2657 mNavigation = MakeRefPtr<mozilla::dom::Navigation>(this);
2658 }
2659
2660 return mNavigation;
2661}
2662
2663Navigator* nsPIDOMWindowInner::Navigator() {
2664 if (!mNavigator) {
2665 mNavigator = MakeRefPtr<mozilla::dom::Navigator>(this);
2666 }
2667
2668 return mNavigator;
2669}
2670
2671MediaDevices* nsPIDOMWindowInner::GetExtantMediaDevices() const {
2672 return mNavigator ? mNavigator->GetExtantMediaDevices() : nullptr;
2673}
2674
2675VisualViewport* nsGlobalWindowInner::VisualViewport() {
2676 if (!mVisualViewport) {
2677 mVisualViewport = MakeRefPtr<mozilla::dom::VisualViewport>(this);
2678 }
2679 return mVisualViewport;
2680}
2681
2682nsScreen* nsGlobalWindowInner::Screen() {
2683 if (!mScreen) {
2684 mScreen = nsScreen::Create(this);
2685 }
2686 return mScreen;
2687}
2688
2689nsHistory* nsGlobalWindowInner::GetHistory(ErrorResult& aError) {
2690 if (!mHistory) {
2691 mHistory = MakeRefPtr<nsHistory>(this);
2692 }
2693 return mHistory;
2694}
2695
2696CustomElementRegistry* nsGlobalWindowInner::CustomElements() {
2697 if (!mCustomElements) {
2698 mCustomElements = MakeRefPtr<CustomElementRegistry>(this);
2699 }
2700
2701 return mCustomElements;
2702}
2703
2704CustomElementRegistry* nsGlobalWindowInner::GetExistingCustomElements() {
2705 return mCustomElements;
2706}
2707
2708Performance* nsPIDOMWindowInner::GetPerformance() {
2709 CreatePerformanceObjectIfNeeded();
2710 return mPerformance;
2711}
2712
2713void nsPIDOMWindowInner::QueuePerformanceNavigationTiming() {
2714 CreatePerformanceObjectIfNeeded();
2715 if (mPerformance) {
2716 mPerformance->QueueNavigationTimingEntry();
2717 }
2718}
2719
2720void nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded() {
2721 if (mPerformance || !mDoc) {
2722 return;
2723 }
2724 RefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming();
2725 nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel()));
2726 if (timing) {
2727 mPerformance = Performance::CreateForMainThread(this, mDoc->NodePrincipal(),
2728 timing, timedChannel);
2729 }
2730}
2731
2732bool nsPIDOMWindowInner::IsSecureContext() const {
2733 return nsGlobalWindowInner::Cast(this)->IsSecureContext();
2734}
2735
2736void nsPIDOMWindowInner::Suspend(bool aIncludeSubWindows) {
2737 nsGlobalWindowInner::Cast(this)->Suspend(aIncludeSubWindows);
2738}
2739
2740void nsPIDOMWindowInner::Resume(bool aIncludeSubWindows) {
2741 nsGlobalWindowInner::Cast(this)->Resume(aIncludeSubWindows);
2742}
2743
2744void nsPIDOMWindowInner::SyncStateFromParentWindow() {
2745 nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow();
2746}
2747
2748Maybe<ClientInfo> nsPIDOMWindowInner::GetClientInfo() const {
2749 return nsGlobalWindowInner::Cast(this)->GetClientInfo();
2750}
2751
2752Maybe<ClientState> nsPIDOMWindowInner::GetClientState() const {
2753 return nsGlobalWindowInner::Cast(this)->GetClientState();
2754}
2755
2756Maybe<ServiceWorkerDescriptor> nsPIDOMWindowInner::GetController() const {
2757 return nsGlobalWindowInner::Cast(this)->GetController();
2758}
2759
2760ClientSource* nsPIDOMWindowInner::GetClientSource() const {
2761 return nsGlobalWindowInner::Cast(this)->GetClientSource();
2762}
2763
2764void nsPIDOMWindowInner::SetPolicyContainer(
2765 nsIPolicyContainer* aPolicyContainer) {
2766 return nsGlobalWindowInner::Cast(this)->SetPolicyContainer(aPolicyContainer);
2767}
2768
2769void nsPIDOMWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
2770 return nsGlobalWindowInner::Cast(this)->SetPreloadCsp(aPreloadCsp);
2771}
2772
2773nsIPolicyContainer* nsPIDOMWindowInner::GetPolicyContainer() {
2774 return nsGlobalWindowInner::Cast(this)->GetPolicyContainer();
2775}
2776
2777void nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(
2778 const nsACString& aScope) {
2779 nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope(
2780 aScope);
2781}
2782
2783void nsPIDOMWindowInner::NoteDOMContentLoaded() {
2784 nsGlobalWindowInner::Cast(this)->NoteDOMContentLoaded();
2785}
2786
2787bool nsGlobalWindowInner::ShouldReportForServiceWorkerScope(
2788 const nsAString& aScope) {
2789 bool result = false;
2790
2791 nsPIDOMWindowOuter* topOuter = GetInProcessScriptableTop();
2792 NS_ENSURE_TRUE(topOuter, false)do { if ((__builtin_expect(!!(!(topOuter)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "topOuter" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2792
); return false; } } while (false)
;
2793
2794 nsGlobalWindowInner* topInner =
2795 nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
2796 NS_ENSURE_TRUE(topInner, false)do { if ((__builtin_expect(!!(!(topInner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "topInner" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2796
); return false; } } while (false)
;
2797
2798 topInner->ShouldReportForServiceWorkerScopeInternal(
2799 NS_ConvertUTF16toUTF8(aScope), &result);
2800 return result;
2801}
2802
2803void nsGlobalWindowInner::GetInstallTrigger(
2804 JSContext* aCx, JS::MutableHandle<JSObject*> aResult) {
2805 // Return nullptr, to avoid breaking "typeof InstallTrigger !== 'undefined"
2806 // "UA detection" use case.
2807 //
2808 // A pref ("extensions.InstallTrigger.enabled"), associated to this
2809 // property using the [Pref] extended attribute in Window.webidl, hides the
2810 // entire InstallTrigger property.
2811 //
2812 // See Bug 1754441 for more details about this deprecation.
2813 aResult.set(nullptr);
2814}
2815
2816nsIDOMWindowUtils* nsGlobalWindowInner::GetWindowUtils(ErrorResult& aRv) {
2817 FORWARD_TO_OUTER_OR_THROW(WindowUtils, (), aRv, nullptr);
2818}
2819
2820bool nsGlobalWindowInner::SynthesizeMouseEvent(
2821 const nsAString& aType, float aOffsetX, float aOffsetY,
2822 const SynthesizeMouseEventData& aMouseEventData,
2823 const SynthesizeMouseEventOptions& aOptions,
2824 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2825 ErrorResult& aError) {
2826 nsIDocShell* docShell = GetDocShell();
2827 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2828 if (!presShell) {
2829 aError.Throw(NS_ERROR_FAILURE);
2830 return false;
2831 }
2832
2833 nsPoint offset;
2834 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2835 if (!widget) {
2836 aError.Throw(NS_ERROR_FAILURE);
2837 return false;
2838 }
2839
2840 LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint(
2841 CSSPoint(aOffsetX, aOffsetY), offset, presShell->GetPresContext());
2842 auto result = nsContentUtils::SynthesizeMouseEvent(
2843 presShell, widget, aType, refPoint, aMouseEventData, aOptions, aCallback);
2844 if (result.isErr()) {
2845 aError.Throw(result.unwrapErr());
2846 return false;
2847 }
2848
2849 return result.unwrap();
2850}
2851
2852bool nsGlobalWindowInner::SynthesizeTouchEvent(
2853 const nsAString& aType, const nsTArray<SynthesizeTouchEventData>& aTouches,
2854 const int32_t aModifiers, const SynthesizeTouchEventOptions& aOptions,
2855 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2856 mozilla::ErrorResult& aError) {
2857 nsIDocShell* docShell = GetDocShell();
2858 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2859 if (!presShell) {
2860 aError.Throw(NS_ERROR_FAILURE);
2861 return false;
2862 }
2863
2864 nsPoint offset;
2865 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2866 if (!widget) {
2867 aError.Throw(NS_ERROR_FAILURE);
2868 return false;
2869 }
2870
2871 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
2872 if (!presContext) {
2873 aError.Throw(NS_ERROR_FAILURE);
2874 return false;
2875 }
2876
2877 auto result = nsContentUtils::SynthesizeTouchEvent(
2878 presContext, widget, offset, aType, aTouches, aModifiers, aOptions,
2879 aCallback);
2880 if (result.isErr()) {
2881 aError.Throw(result.unwrapErr());
2882 return false;
2883 }
2884
2885 return result.unwrap();
2886}
2887
2888CallState nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal(
2889 const nsACString& aScope, bool* aResultOut) {
2890 MOZ_DIAGNOSTIC_ASSERT(aResultOut)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResultOut)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResultOut))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aResultOut", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 2890); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aResultOut"
")"); do { MOZ_CrashSequence(__null, 2890); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2891
2892 // First check to see if this window is controlled. If so, then we have
2893 // found a match and are done.
2894 const Maybe<ServiceWorkerDescriptor> swd = GetController();
2895 if (swd.isSome() && swd.ref().Scope() == aScope) {
2896 *aResultOut = true;
2897 return CallState::Stop;
2898 }
2899
2900 // Next, check to see if this window has called
2901 // navigator.serviceWorker.register() for this scope. If so, then treat this
2902 // as a match so console reports appear in the devtools console.
2903 if (mClientSource &&
2904 mClientSource->CalledRegisterForServiceWorkerScope(aScope)) {
2905 *aResultOut = true;
2906 return CallState::Stop;
2907 }
2908
2909 // Finally check the current docshell nsILoadGroup to see if there are any
2910 // outstanding navigation requests. If so, match the scope against the
2911 // channel's URL. We want to show console reports during the FetchEvent
2912 // intercepting the navigation itself.
2913 nsCOMPtr<nsIDocumentLoader> loader(do_QueryInterface(GetDocShell()));
2914 if (loader) {
2915 nsCOMPtr<nsILoadGroup> loadgroup;
2916 (void)loader->GetLoadGroup(getter_AddRefs(loadgroup));
2917 if (loadgroup) {
2918 nsCOMPtr<nsISimpleEnumerator> iter;
2919 (void)loadgroup->GetRequests(getter_AddRefs(iter));
2920 if (iter) {
2921 nsCOMPtr<nsISupports> tmp;
2922 bool hasMore = true;
2923 // Check each network request in the load group.
2924 while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(iter->HasMoreElements
(&hasMore))), 1)))
&& hasMore) {
2925 iter->GetNext(getter_AddRefs(tmp));
2926 nsCOMPtr<nsIChannel> loadingChannel(do_QueryInterface(tmp));
2927 // Ignore subresource requests. Logging for a subresource
2928 // FetchEvent should be handled above since the client is
2929 // already controlled.
2930 if (!loadingChannel ||
2931 !nsContentUtils::IsNonSubresourceRequest(loadingChannel)) {
2932 continue;
2933 }
2934 nsCOMPtr<nsIURI> loadingURL;
2935 (void)loadingChannel->GetURI(getter_AddRefs(loadingURL));
2936 if (!loadingURL) {
2937 continue;
2938 }
2939 nsAutoCString loadingSpec;
2940 (void)loadingURL->GetSpec(loadingSpec);
2941 // Perform a simple substring comparison to match the scope
2942 // against the channel URL.
2943 if (StringBeginsWith(loadingSpec, aScope)) {
2944 *aResultOut = true;
2945 return CallState::Stop;
2946 }
2947 }
2948 }
2949 }
2950 }
2951
2952 // The current window doesn't care about this service worker, but maybe
2953 // one of our child frames does.
2954 return CallOnInProcessChildren(
2955 &nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal, aScope,
2956 aResultOut);
2957}
2958
2959void nsGlobalWindowInner::NoteCalledRegisterForServiceWorkerScope(
2960 const nsACString& aScope) {
2961 if (!mClientSource) {
2962 return;
2963 }
2964
2965 mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope);
2966}
2967
2968void nsGlobalWindowInner::NoteDOMContentLoaded() {
2969 if (!mClientSource) {
2970 return;
2971 }
2972
2973 mClientSource->NoteDOMContentLoaded();
2974}
2975
2976void nsGlobalWindowInner::UpdateTopInnerWindow() {
2977 if (IsTopInnerWindow() || !mTopInnerWindow) {
2978 return;
2979 }
2980
2981 nsGlobalWindowInner::Cast(mTopInnerWindow)
2982 ->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets);
2983}
2984
2985bool nsGlobalWindowInner::IsInSyncOperation() {
2986 return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
2987}
2988
2989bool nsGlobalWindowInner::IsSharedMemoryAllowedInternal(
2990 nsIPrincipal* aPrincipal) const {
2991 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 2991
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 2991); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2992
2993 if (StaticPrefs::
2994 dom_postMessage_sharedArrayBuffer_bypassCOOP_COEP_insecure_enabled()) {
2995 return true;
2996 }
2997
2998 if (ExtensionPolicyService::GetSingleton().IsExtensionProcess()) {
2999 if (auto* basePrincipal = BasePrincipal::Cast(aPrincipal)) {
3000 if (auto* policy = basePrincipal->AddonPolicy()) {
3001 return policy->IsPrivileged();
3002 }
3003 }
3004 }
3005
3006 return CrossOriginIsolated();
3007}
3008
3009bool nsGlobalWindowInner::CrossOriginIsolated() const {
3010 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3010
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3010); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3011
3012 RefPtr<BrowsingContext> bc = GetBrowsingContext();
3013 MOZ_DIAGNOSTIC_ASSERT(bc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(bc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("bc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3013); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "bc"
")"); do { MOZ_CrashSequence(__null, 3013); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3014 return bc->CrossOriginIsolated();
3015}
3016
3017bool nsGlobalWindowInner::OriginAgentCluster() const {
3018 if (DocGroup* docGroup = GetDocGroup()) {
3019 return docGroup->IsOriginKeyed();
3020 }
3021 return false;
3022}
3023
3024WindowContext* TopWindowContext(nsPIDOMWindowInner& aWindow) {
3025 WindowContext* wc = aWindow.GetWindowContext();
3026 if (!wc) {
3027 return nullptr;
3028 }
3029
3030 return wc->TopWindowContext();
3031}
3032
3033void nsPIDOMWindowInner::AddPeerConnection() {
3034 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3034
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3034); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3035 ++mActivePeerConnections;
3036 if (mActivePeerConnections == 1 && mWindowGlobalChild) {
3037 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3038 /*aIsAdded*/ true);
3039
3040 // We need to present having active peer connections immediately. If we need
3041 // to wait for the parent process to come back with this information we
3042 // might start throttling.
3043 if (WindowContext* top = TopWindowContext(*this)) {
3044 top->TransientSetHasActivePeerConnections();
3045 }
3046 }
3047}
3048
3049void nsPIDOMWindowInner::RemovePeerConnection() {
3050 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3050
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3050); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3051 MOZ_ASSERT(mActivePeerConnections > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActivePeerConnections > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mActivePeerConnections > 0
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mActivePeerConnections > 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3051); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActivePeerConnections > 0"
")"); do { MOZ_CrashSequence(__null, 3051); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3052 --mActivePeerConnections;
3053 if (mActivePeerConnections == 0 && mWindowGlobalChild) {
3054 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3055 /*aIsAdded*/ false);
3056 }
3057}
3058
3059bool nsGlobalWindowInner::HasActivePeerConnections() {
3060 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3060
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3060); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3061
3062 WindowContext* topWindowContext = TopWindowContext(*this);
3063 return topWindowContext && topWindowContext->GetHasActivePeerConnections();
3064}
3065
3066void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) {
3067 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3067
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3067); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3068 mMediaKeysInstances.AppendElement(aMediaKeys);
3069 if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) {
3070 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3071 }
3072}
3073
3074void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) {
3075 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3075
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3075); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3076 mMediaKeysInstances.RemoveElement(aMediaKeys);
3077 if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) {
3078 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3079 }
3080}
3081
3082bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() {
3083 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3083
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3083); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3084 return !mMediaKeysInstances.IsEmpty();
3085}
3086
3087bool nsGlobalWindowInner::IsPlayingAudio() {
3088 for (uint32_t i = 0; i < mAudioContexts.Length(); i++) {
3089 if (mAudioContexts[i]->IsRunning()) {
3090 return true;
3091 }
3092 }
3093 RefPtr<AudioChannelService> acs = AudioChannelService::Get();
3094 if (!acs) {
3095 return false;
3096 }
3097 auto outer = GetOuterWindow();
3098 if (!outer) {
3099 // We've been unlinked and are about to die. Not a good time to pretend to
3100 // be playing audio.
3101 return false;
3102 }
3103 return acs->IsWindowActive(outer);
3104}
3105
3106bool nsPIDOMWindowInner::IsDocumentLoaded() const { return mIsDocumentLoaded; }
3107
3108mozilla::dom::TimeoutManager* nsGlobalWindowInner::GetTimeoutManager() {
3109 return mTimeoutManager.get();
3110}
3111
3112bool nsGlobalWindowInner::IsRunningTimeout() {
3113 return GetTimeoutManager()->IsRunningTimeout();
3114}
3115
3116void nsPIDOMWindowInner::TryToCacheTopInnerWindow() {
3117 if (mHasTriedToCacheTopInnerWindow) {
3118 return;
3119 }
3120
3121 nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(this);
3122
3123 MOZ_ASSERT(!window->IsDying())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!window->IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!window->IsDying()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!window->IsDying()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3123
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!window->IsDying()"
")"); do { MOZ_CrashSequence(__null, 3123); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3124
3125 mHasTriedToCacheTopInnerWindow = true;
3126
3127 MOZ_ASSERT(window)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(window)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(window))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("window", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { MOZ_CrashSequence(__null, 3127); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3128
3129 if (nsCOMPtr<nsPIDOMWindowOuter> topOutter =
3130 window->GetInProcessScriptableTop()) {
3131 mTopInnerWindow = topOutter->GetCurrentInnerWindow();
3132 }
3133}
3134
3135void nsGlobalWindowInner::UpdateActiveIndexedDBDatabaseCount(int32_t aDelta) {
3136 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3136
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3136); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3137
3138 if (aDelta == 0) {
3139 return;
3140 }
3141
3142 // We count databases but not transactions because only active databases
3143 // could block throttling.
3144 uint32_t& counter = mTopInnerWindow
3145 ? mTopInnerWindow->mNumOfIndexedDBDatabases
3146 : mNumOfIndexedDBDatabases;
3147
3148 counter += aDelta;
3149}
3150
3151bool nsGlobalWindowInner::HasActiveIndexedDBDatabases() const {
3152 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3152
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3152); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3153
3154 return mTopInnerWindow ? mTopInnerWindow->mNumOfIndexedDBDatabases > 0
3155 : mNumOfIndexedDBDatabases > 0;
3156}
3157
3158void nsGlobalWindowInner::UpdateWebSocketCount(int32_t aDelta) {
3159 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3159
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3159); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3160
3161 if (aDelta == 0) {
3162 return;
3163 }
3164
3165 if (mTopInnerWindow && !IsTopInnerWindow()) {
3166 nsGlobalWindowInner::Cast(mTopInnerWindow)->UpdateWebSocketCount(aDelta);
3167 }
3168
3169 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) <
mNumOfOpenWebSockets))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets
) < mNumOfOpenWebSockets)))), 0))) { do { } while (false);
MOZ_ReportAssertionFailure("aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3170
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3170); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3170 aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) <
mNumOfOpenWebSockets))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDelta > 0 || ((aDelta + mNumOfOpenWebSockets
) < mNumOfOpenWebSockets)))), 0))) { do { } while (false);
MOZ_ReportAssertionFailure("aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3170
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3170); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3171
3172 mNumOfOpenWebSockets += aDelta;
3173}
3174
3175bool nsGlobalWindowInner::HasOpenWebSockets() const {
3176 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3176
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3176); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3177
3178 return mNumOfOpenWebSockets ||
3179 (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
3180}
3181
3182void nsGlobalWindowInner::AudioPlaybackChanged(bool aIsPlayingAudio) {
3183 AUTO_PROFILER_MARKER_UNTYPED("AudioPlaybackChanged", DOM, {})AutoProfilerUntypedMarker raiiObject3183( "AudioPlaybackChanged"
, ::mozilla::baseprofiler::category::DOM, {})
;
3184 UpdateWorkersPlaybackState(*this, aIsPlayingAudio);
3185}
3186
3187bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
3188 if (mBrowsingContext && mBrowsingContext->IsInBFCache()) {
3189 return false;
3190 }
3191
3192 if (!mBrowsingContext || mBrowsingContext->IsDiscarded()) {
3193 // If our BrowsingContext has been discarded, we consider ourselves
3194 // still-current if we were current at the time it was discarded.
3195 return mOuterWindow && WasCurrentInnerWindow();
3196 }
3197
3198 nsPIDOMWindowOuter* outer = mBrowsingContext->GetDOMWindow();
3199 return outer && outer->GetCurrentInnerWindow() == this;
3200}
3201
3202bool nsGlobalWindowInner::HasScheduledNormalOrHighPriorityWebTasks() const {
3203 return gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0;
3204}
3205
3206bool nsPIDOMWindowInner::IsFullyActive() const {
3207 WindowContext* wc = GetWindowContext();
3208 if (!wc || wc->IsDiscarded() || !wc->IsCurrent()) {
3209 return false;
3210 }
3211 return GetBrowsingContext()->AncestorsAreCurrent();
3212}
3213
3214void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
3215 RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
3216 if (service) {
3217 service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
3218 }
3219}
3220
3221void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
3222 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
3223 gTimeoutLog, mozilla::LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
3224 ("SetActiveLoadingState innerwindow %p: %d", (void*)this, aIsLoading))do { const ::mozilla::LogModule* moz_real_module = gTimeoutLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "SetActiveLoadingState innerwindow %p: %d"
, (void*)this, aIsLoading); } } while (0)
;
3225 if (GetBrowsingContext()) {
3226 // Setting loading on a discarded context has no effect.
3227 (void)GetBrowsingContext()->SetLoading(aIsLoading);
3228 }
3229
3230 if (StaticPrefs::dom_timeout_defer_during_load() && !IsChromeWindow()) {
3231 nsIPrincipal* principal = GetPrincipal();
3232 if (!principal || !principal->IsURIInPrefList(
3233 "dom.timeout.defer_during_load.force-disable")) {
3234 mTimeoutManager->SetLoading(aIsLoading);
3235 }
3236 }
3237
3238 HintIsLoading(aIsLoading);
3239}
3240
3241void nsGlobalWindowInner::HintIsLoading(bool aIsLoading) {
3242 // Hint to tell the JS GC to use modified triggers during pageload.
3243 if (mHintedWasLoading != aIsLoading) {
3244 using namespace js::gc;
3245 SetPerformanceHint(danger::GetJSContext(), aIsLoading
3246 ? PerformanceHint::InPageLoad
3247 : PerformanceHint::Normal);
3248 mHintedWasLoading = aIsLoading;
3249 }
3250}
3251
3252// nsISpeechSynthesisGetter
3253
3254#ifdef MOZ_WEBSPEECH1
3255SpeechSynthesis* nsGlobalWindowInner::GetSpeechSynthesis(ErrorResult& aError) {
3256 if (!mSpeechSynthesis) {
3257 mSpeechSynthesis = MakeRefPtr<SpeechSynthesis>(this);
3258 }
3259
3260 return mSpeechSynthesis;
3261}
3262
3263bool nsGlobalWindowInner::HasActiveSpeechSynthesis() {
3264 if (mSpeechSynthesis) {
3265 return !mSpeechSynthesis->HasEmptyQueue();
3266 }
3267
3268 return false;
3269}
3270
3271#endif
3272
3273mozilla::glean::Glean* nsGlobalWindowInner::Glean() {
3274 if (!mGlean) {
3275 mGlean = MakeRefPtr<mozilla::glean::Glean>(this);
3276 }
3277
3278 return mGlean;
3279}
3280
3281mozilla::glean::GleanPings* nsGlobalWindowInner::GleanPings() {
3282 if (!mGleanPings) {
3283 mGleanPings = MakeRefPtr<mozilla::glean::GleanPings>();
3284 }
3285
3286 return mGleanPings;
3287}
3288
3289Nullable<WindowProxyHolder> nsGlobalWindowInner::GetParent(
3290 ErrorResult& aError) {
3291 FORWARD_TO_OUTER_OR_THROW(GetParentOuter, (), aError, nullptr);
3292}
3293
3294/**
3295 * GetInProcessScriptableParent used to be called when a script read
3296 * window.parent. Under Fission, that is now handled by
3297 * BrowsingContext::GetParent, and the result is a WindowProxyHolder rather than
3298 * an actual global window. This method still exists for legacy callers which
3299 * relied on the old logic, and require in-process windows. However, it only
3300 * works correctly when no out-of-process frames exist between this window and
3301 * the top-level window, so it should not be used in new code.
3302 *
3303 * In contrast to GetRealParent, GetInProcessScriptableParent respects <iframe
3304 * mozbrowser> boundaries, so if |this| is contained by an <iframe
3305 * mozbrowser>, we will return |this| as its own parent.
3306 */
3307nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableParent() {
3308 FORWARD_TO_OUTER(GetInProcessScriptableParent, (), nullptr);
3309}
3310
3311/**
3312 * GetInProcessScriptableTop used to be called when a script read window.top.
3313 * Under Fission, that is now handled by BrowsingContext::Top, and the result is
3314 * a WindowProxyHolder rather than an actual global window. This method still
3315 * exists for legacy callers which relied on the old logic, and require
3316 * in-process windows. However, it only works correctly when no out-of-process
3317 * frames exist between this window and the top-level window, so it should not
3318 * be used in new code.
3319 *
3320 * In contrast to GetRealTop, GetInProcessScriptableTop respects <iframe
3321 * mozbrowser> boundaries. If we encounter a window owned by an <iframe
3322 * mozbrowser> while walking up the window hierarchy, we'll stop and return that
3323 * window.
3324 */
3325nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableTop() {
3326 FORWARD_TO_OUTER(GetInProcessScriptableTop, (), nullptr);
3327}
3328
3329void nsGlobalWindowInner::GetContent(JSContext* aCx,
3330 JS::MutableHandle<JSObject*> aRetval,
3331 CallerType aCallerType,
3332 ErrorResult& aError) {
3333 FORWARD_TO_OUTER_OR_THROW(GetContentOuter,
3334 (aCx, aRetval, aCallerType, aError), aError, );
3335}
3336
3337BarProp* nsGlobalWindowInner::GetMenubar(ErrorResult& aError) {
3338 if (!mMenubar) {
3339 mMenubar = MakeRefPtr<MenubarProp>(this);
3340 }
3341
3342 return mMenubar;
3343}
3344
3345BarProp* nsGlobalWindowInner::GetToolbar(ErrorResult& aError) {
3346 if (!mToolbar) {
3347 mToolbar = MakeRefPtr<ToolbarProp>(this);
3348 }
3349
3350 return mToolbar;
3351}
3352
3353BarProp* nsGlobalWindowInner::GetLocationbar(ErrorResult& aError) {
3354 if (!mLocationbar) {
3355 mLocationbar = MakeRefPtr<LocationbarProp>(this);
3356 }
3357 return mLocationbar;
3358}
3359
3360BarProp* nsGlobalWindowInner::GetPersonalbar(ErrorResult& aError) {
3361 if (!mPersonalbar) {
3362 mPersonalbar = MakeRefPtr<PersonalbarProp>(this);
3363 }
3364 return mPersonalbar;
3365}
3366
3367BarProp* nsGlobalWindowInner::GetStatusbar(ErrorResult& aError) {
3368 if (!mStatusbar) {
3369 mStatusbar = MakeRefPtr<StatusbarProp>(this);
3370 }
3371 return mStatusbar;
3372}
3373
3374BarProp* nsGlobalWindowInner::GetScrollbars(ErrorResult& aError) {
3375 if (!mScrollbars) {
3376 mScrollbars = MakeRefPtr<ScrollbarsProp>(this);
3377 }
3378
3379 return mScrollbars;
3380}
3381
3382bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
3383 // If we're called from JS (which is the only way we should be getting called
3384 // here) and we reach this point, that means our JS global is the current
3385 // target of the WindowProxy, which means that we are the "current inner"
3386 // of our outer. So if FORWARD_TO_OUTER fails to forward, that means the
3387 // outer is already torn down, which corresponds to the closed state.
3388 FORWARD_TO_OUTER(GetClosedOuter, (), true);
3389}
3390
3391Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
3392 uint32_t aIndex) {
3393 FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
3394}
3395
3396namespace {
3397
3398struct InterfaceShimEntry {
3399 const char* geckoName;
3400 const char* domName;
3401};
3402
3403} // anonymous namespace
3404
3405// We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
3406// interface that has interface constants that sites might be getting off
3407// of Ci.
3408const InterfaceShimEntry kInterfaceShimMap[] = {
3409 {"nsIXMLHttpRequest", "XMLHttpRequest"},
3410 {"nsIDOMDOMException", "DOMException"},
3411 {"nsIDOMNode", "Node"},
3412 {"nsIDOMCSSRule", "CSSRule"},
3413 {"nsIDOMEvent", "Event"},
3414 {"nsIDOMNSEvent", "Event"},
3415 {"nsIDOMKeyEvent", "KeyEvent"},
3416 {"nsIDOMMouseEvent", "MouseEvent"},
3417 {"nsIDOMMouseScrollEvent", "MouseScrollEvent"},
3418 {"nsIDOMMutationEvent", "MutationEvent"},
3419 {"nsIDOMUIEvent", "UIEvent"},
3420 {"nsIDOMHTMLMediaElement", "HTMLMediaElement"},
3421 {"nsIDOMRange", "Range"},
3422 // Think about whether Ci.nsINodeFilter can just go away for websites!
3423 {"nsIDOMNodeFilter", "NodeFilter"},
3424 {"nsIDOMXPathResult", "XPathResult"}};
3425
3426bool nsGlobalWindowInner::ResolveComponentsShim(
3427 JSContext* aCx, JS::Handle<JSObject*> aGlobal,
3428 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3429 // Warn once.
3430 nsCOMPtr<Document> doc = GetExtantDoc();
3431 if (doc) {
3432 doc->WarnOnceAndReportAbout(
3433 DeprecatedOperations::eComponents, /* asError = */
3434 true);
3435 // Keep track of how often this happens.
3436 doc->SetUseCounter(eUseCounter_custom_ComponentsShimResolved);
3437 }
3438
3439 // Create a fake Components object.
3440 AssertSameCompartment(aCx, aGlobal);
3441 JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx));
3442 if (NS_WARN_IF(!components)NS_warn_if_impl(!components, "!components", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3442)
) {
3443 return false;
3444 }
3445
3446 // Create a fake interfaces object.
3447 JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx));
3448 if (NS_WARN_IF(!interfaces)NS_warn_if_impl(!interfaces, "!interfaces", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3448)
) {
3449 return false;
3450 }
3451 bool ok =
3452 JS_DefineProperty(aCx, components, "interfaces", interfaces,
3453 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3454 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3454)
) {
3455 return false;
3456 }
3457
3458 // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
3459 // interfaces with constants.
3460 for (auto entry : kInterfaceShimMap) {
3461 // Grab the names from the table.
3462 const char* geckoName = entry.geckoName;
3463 const char* domName = entry.domName;
3464
3465 // Look up the appopriate interface object on the global.
3466 JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue());
3467 ok = JS_GetProperty(aCx, aGlobal, domName, &v);
3468 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3468)
) {
3469 return false;
3470 }
3471 if (!v.isObject()) {
3472 NS_WARNING("Unable to find interface object on global")NS_DebugBreak(NS_DEBUG_WARNING, "Unable to find interface object on global"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3472)
;
3473 continue;
3474 }
3475
3476 // Define the shim on the interfaces object.
3477 ok = JS_DefineProperty(
3478 aCx, interfaces, geckoName, v,
3479 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3480 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3480)
) {
3481 return false;
3482 }
3483 }
3484
3485 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3486 JS::ObjectValue(*components),
3487 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3488 JS::PropertyAttribute::Writable})));
3489 return true;
3490}
3491
3492#ifdef RELEASE_OR_BETA
3493# define USE_CONTROLLERS_SHIM
3494#endif
3495
3496#ifdef USE_CONTROLLERS_SHIM
3497static const JSClass ControllersShimClass = {"Controllers", 0};
3498static const JSClass XULControllersShimClass = {"XULControllers", 0};
3499#endif
3500
3501bool nsGlobalWindowInner::DoResolve(
3502 JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
3503 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3504 // Note: Keep this in sync with MayResolve.
3505
3506 // Note: The infallibleInit call in GlobalResolve depends on this check.
3507 if (!aId.isString()) {
3508 return true;
3509 }
3510
3511 bool found;
3512 if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) {
3513 return false;
3514 }
3515
3516 if (found) {
3517 return true;
3518 }
3519
3520 // We support a cut-down Components.interfaces in case websites are
3521 // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones
3522 // that have constants.
3523 if (StaticPrefs::dom_use_components_shim() &&
3524 aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3525 return ResolveComponentsShim(aCx, aObj, aDesc);
3526 }
3527
3528 // We also support a "window.controllers" thing; apparently some
3529 // sites use it for browser-sniffing. See bug 1010577.
3530#ifdef USE_CONTROLLERS_SHIM
3531 // Note: We use |aObj| rather than |this| to get the principal here, because
3532 // this is called during Window setup when the Document isn't necessarily
3533 // hooked up yet.
3534 if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3535 aId == XPCJSRuntime::Get()->GetStringID(
3536 XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
3537 !xpc::IsXrayWrapper(aObj) &&
3538 !nsContentUtils::ObjectPrincipal(aObj)->IsSystemPrincipal()) {
3539 if (GetExtantDoc()) {
3540 GetExtantDoc()->WarnOnceAndReportAbout(
3541 DeprecatedOperations::eWindow_Cc_ontrollers);
3542 }
3543 const JSClass* clazz;
3544 if (aId ==
3545 XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
3546 clazz = &XULControllersShimClass;
3547 } else {
3548 clazz = &ControllersShimClass;
3549 }
3550 MOZ_ASSERT(JS_IsGlobalObject(aObj))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(JS_IsGlobalObject(aObj))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(JS_IsGlobalObject(aObj)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("JS_IsGlobalObject(aObj)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 3550
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(aObj)"
")"); do { MOZ_CrashSequence(__null, 3550); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3551 JS::Rooted<JSObject*> shim(aCx, JS_NewObject(aCx, clazz));
3552 if (NS_WARN_IF(!shim)NS_warn_if_impl(!shim, "!shim", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3552)
) {
3553 return false;
3554 }
3555
3556 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3557 JS::ObjectValue(*shim),
3558 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3559 JS::PropertyAttribute::Writable})));
3560 return true;
3561 }
3562#endif
3563
3564 return true;
3565}
3566
3567/* static */
3568bool nsGlobalWindowInner::MayResolve(jsid aId) {
3569 // Note: This function does not fail and may not have any side-effects.
3570 // Note: Keep this in sync with DoResolve.
3571 if (!aId.isString()) {
3572 return false;
3573 }
3574
3575 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3576 return true;
3577 }
3578
3579 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3580 aId == XPCJSRuntime::Get()->GetStringID(
3581 XPCJSContext::IDX_CONTROLLERS_CLASS)) {
3582 // We only resolve .controllers/.Controllers in release builds and on
3583 // non-chrome windows, but let's not worry about any of that stuff.
3584 return true;
3585 }
3586
3587 return WebIDLGlobalNameHash::MayResolve(aId);
3588}
3589
3590void nsGlobalWindowInner::GetOwnPropertyNames(
3591 JSContext* aCx, JS::MutableHandleVector<jsid> aNames, bool aEnumerableOnly,
3592 ErrorResult& aRv) {
3593 if (aEnumerableOnly) {
3594 // The names we would return from here get defined on the window via one of
3595 // two codepaths. The ones coming from the WebIDLGlobalNameHash will end up
3596 // in the DefineConstructor function in BindingUtils, which always defines
3597 // things as non-enumerable. The ones coming from the script namespace
3598 // manager get defined by our resolve hook using FillPropertyDescriptor with
3599 // 0 for the property attributes, so non-enumerable as well.
3600 //
3601 // So in the aEnumerableOnly case we have nothing to do.
3602 return;
3603 }
3604
3605 // "Components" is marked as enumerable but only resolved on demand :-/.
3606 // aNames.AppendElement(u"Components"_ns);
3607
3608 JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
3609
3610 // There are actually two ways we can get called here: For normal
3611 // enumeration or for Xray enumeration. In the latter case, we want to
3612 // return all possible WebIDL names, because we don't really support
3613 // deleting these names off our Xray; trying to resolve them will just make
3614 // them come back. In the former case, we want to avoid returning deleted
3615 // names. But the JS engine already knows about the non-deleted
3616 // already-resolved names, so we can just return the so-far-unresolved ones.
3617 //
3618 // We can tell which case we're in by whether aCx is in our wrapper's
3619 // compartment. If not, we're in the Xray case.
3620 WebIDLGlobalNameHash::NameType nameType =
3621 js::IsObjectInContextCompartment(wrapper, aCx)
3622 ? WebIDLGlobalNameHash::UnresolvedNamesOnly
3623 : WebIDLGlobalNameHash::AllNames;
3624 if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) {
3625 aRv.NoteJSContextException(aCx);
3626 }
3627}
3628
3629/* static */
3630bool nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext*, JSObject* aObj) {
3631 // For now, have to deal with XPConnect objects here.
3632 nsGlobalWindowInner* win = xpc::WindowOrNull(aObj);
3633 return win && win->IsChromeWindow() &&
3634 nsContentUtils::ObjectPrincipal(aObj) ==
3635 nsContentUtils::GetSystemPrincipal();
3636}
3637
3638/* static */
3639bool nsGlobalWindowInner::DeviceSensorsEnabled(JSContext*, JSObject*) {
3640 return Preferences::GetBool("device.sensors.enabled");
3641}
3642
3643Crypto* nsGlobalWindowInner::GetCrypto(ErrorResult& aError) {
3644 if (!mCrypto) {
3645 mCrypto = MakeRefPtr<Crypto>(this);
3646 }
3647 return mCrypto;
3648}
3649
3650nsIControllers* nsGlobalWindowInner::GetControllers(ErrorResult& aError) {
3651 FORWARD_TO_OUTER_OR_THROW(GetControllersOuter, (aError), aError, nullptr);
3652}
3653
3654nsresult nsGlobalWindowInner::GetControllers(nsIControllers** aResult) {
3655 ErrorResult rv;
3656 nsCOMPtr<nsIControllers> controllers = GetControllers(rv);
3657 controllers.forget(aResult);
3658
3659 return rv.StealNSResult();
3660}
3661
3662Nullable<WindowProxyHolder> nsGlobalWindowInner::GetOpenerWindow(
3663 ErrorResult& aError) {
3664 FORWARD_TO_OUTER_OR_THROW(GetOpenerWindowOuter, (), aError, nullptr);
3665}
3666
3667void nsGlobalWindowInner::GetOpener(JSContext* aCx,
3668 JS::MutableHandle<JS::Value> aRetval,
3669 ErrorResult& aError) {
3670 Nullable<WindowProxyHolder> opener = GetOpenerWindow(aError);
3671 if (aError.Failed() || opener.IsNull()) {
3672 aRetval.setNull();
3673 return;
3674 }
3675
3676 if (!ToJSValue(aCx, opener.Value(), aRetval)) {
3677 aError.NoteJSContextException(aCx);
3678 }
3679}
3680
3681void nsGlobalWindowInner::SetOpener(JSContext* aCx,
3682 JS::Handle<JS::Value> aOpener,
3683 ErrorResult& aError) {
3684 if (aOpener.isNull()) {
3685 RefPtr<BrowsingContext> bc(GetBrowsingContext());
3686 if (!bc->IsDiscarded()) {
3687 bc->SetOpener(nullptr);
3688 }
3689 return;
3690 }
3691
3692 // If something other than null is passed, just define aOpener on our inner
3693 // window's JS object, wrapped into the current compartment so that for Xrays
3694 // we define on the Xray expando object, but don't set it on the outer window,
3695 // so that it'll get reset on navigation. This is just like replaceable
3696 // properties, but we're not quite readonly.
3697 RedefineProperty(aCx, "opener", aOpener, aError);
3698}
3699
3700void nsGlobalWindowInner::GetEvent(OwningEventOrUndefined& aRetval) {
3701 if (mEvent) {
3702 aRetval.SetAsEvent() = mEvent;
3703 } else {
3704 aRetval.SetUndefined();
3705 }
3706}
3707
3708void nsGlobalWindowInner::GetStatus(nsAString& aStatus, ErrorResult& aError) {
3709 FORWARD_TO_OUTER_OR_THROW(GetStatusOuter, (aStatus), aError, );
3710}
3711
3712void nsGlobalWindowInner::SetStatus(const nsAString& aStatus,
3713 ErrorResult& aError) {
3714 FORWARD_TO_OUTER_OR_THROW(SetStatusOuter, (aStatus), aError, );
3715}
3716
3717void nsGlobalWindowInner::GetName(nsAString& aName, ErrorResult& aError) {
3718 FORWARD_TO_OUTER_OR_THROW(GetNameOuter, (aName), aError, );
3719}
3720
3721void nsGlobalWindowInner::SetName(const nsAString& aName,
3722 mozilla::ErrorResult& aError) {
3723 FORWARD_TO_OUTER_OR_THROW(SetNameOuter, (aName, aError), aError, );
3724}
3725
3726double nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3727 ErrorResult& aError) {
3728 FORWARD_TO_OUTER_OR_THROW(GetInnerWidthOuter, (aCallerType, aError), aError,
3729 0);
3730}
3731
3732nsresult nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3733 double* aWidth) {
3734 ErrorResult rv;
3735 *aWidth = GetInnerWidth(aCallerType, rv);
3736 return rv.StealNSResult();
3737}
3738
3739double nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3740 ErrorResult& aError) {
3741 FORWARD_TO_OUTER_OR_THROW(GetInnerHeightOuter, (aCallerType, aError), aError,
3742 0);
3743}
3744
3745nsresult nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3746 double* aHeight) {
3747 ErrorResult rv;
3748 *aHeight = GetInnerHeight(aCallerType, rv);
3749 return rv.StealNSResult();
3750}
3751
3752int32_t nsGlobalWindowInner::GetOuterWidth(CallerType aCallerType,
3753 ErrorResult& aError) {
3754 FORWARD_TO_OUTER_OR_THROW(GetOuterWidthOuter, (aCallerType, aError), aError,
3755 0);
3756}
3757
3758int32_t nsGlobalWindowInner::GetOuterHeight(CallerType aCallerType,
3759 ErrorResult& aError) {
3760 FORWARD_TO_OUTER_OR_THROW(GetOuterHeightOuter, (aCallerType, aError), aError,
3761 0);
3762}
3763
3764double nsGlobalWindowInner::ScreenEdgeSlopX() const {
3765 FORWARD_TO_OUTER(ScreenEdgeSlopX, (), 0);
3766}
3767
3768double nsGlobalWindowInner::ScreenEdgeSlopY() const {
3769 FORWARD_TO_OUTER(ScreenEdgeSlopY, (), 0);
3770}
3771
3772int32_t nsGlobalWindowInner::GetScreenX(CallerType aCallerType,
3773 ErrorResult& aError) {
3774 FORWARD_TO_OUTER_OR_THROW(GetScreenXOuter, (aCallerType, aError), aError, 0);
3775}
3776
3777int32_t nsGlobalWindowInner::GetScreenY(CallerType aCallerType,
3778 ErrorResult& aError) {
3779 FORWARD_TO_OUTER_OR_THROW(GetScreenYOuter, (aCallerType, aError), aError, 0);
3780}
3781
3782float nsGlobalWindowInner::GetMozInnerScreenX(CallerType aCallerType,
3783 ErrorResult& aError) {
3784 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenXOuter, (aCallerType), aError, 0);
3785}
3786
3787float nsGlobalWindowInner::GetMozInnerScreenY(CallerType aCallerType,
3788 ErrorResult& aError) {
3789 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenYOuter, (aCallerType), aError, 0);
3790}
3791
3792static nsPresContext* GetPresContextForRatio(Document* aDoc) {
3793 if (nsPresContext* presContext = aDoc->GetPresContext()) {
3794 return presContext;
3795 }
3796 // We're in an undisplayed subdocument... There's not really an awesome way
3797 // to tell what the right DPI is from here, so we try to walk up our parent
3798 // document chain to the extent that the docs can observe each other.
3799 Document* doc = aDoc;
3800 while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
3801 doc = doc->GetInProcessParentDocument();
3802 if (nsPresContext* presContext = doc->GetPresContext()) {
3803 return presContext;
3804 }
3805 }
3806 return nullptr;
3807}
3808
3809double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType,
3810 ErrorResult& aError) {
3811 ENSURE_ACTIVE_DOCUMENT(aError, 0.0)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return 0.0; } } while
(0)
;
3812
3813 RefPtr<nsPresContext> presContext = GetPresContextForRatio(mDoc);
3814 if (NS_WARN_IF(!presContext)NS_warn_if_impl(!presContext, "!presContext", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3814)
) {
3815 // Still nothing, oh well.
3816 return 1.0;
3817 }
3818
3819 if (nsIGlobalObject::ShouldResistFingerprinting(
3820 aCallerType, RFPTarget::WindowDevicePixelRatio)) {
3821 return nsRFPService::GetDevicePixelRatioAtZoom(presContext->GetFullZoom());
3822 }
3823
3824 if (aCallerType == CallerType::NonSystem) {
3825 float overrideDPPX = presContext->GetOverrideDPPX();
3826 if (overrideDPPX > 0.0f) {
3827 return overrideDPPX;
3828 }
3829 }
3830
3831 return double(AppUnitsPerCSSPixel()) /
3832 double(presContext->AppUnitsPerDevPixel());
3833}
3834
3835double nsGlobalWindowInner::GetDesktopToDeviceScale(ErrorResult& aError) {
3836 ENSURE_ACTIVE_DOCUMENT(aError, 0.0)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return 0.0; } } while
(0)
;
3837 nsPresContext* presContext = GetPresContextForRatio(mDoc);
3838 if (!presContext) {
3839 return 1.0;
3840 }
3841 return presContext->DeviceContext()->GetDesktopToDeviceScale().scale;
3842}
3843
3844uint32_t nsGlobalWindowInner::RequestAnimationFrame(
3845 FrameRequestCallback& aCallback, ErrorResult& aError) {
3846 if (!mDoc) {
3847 return 0;
3848 }
3849
3850 if (GetWrapperPreserveColor()) {
3851 js::NotifyAnimationActivity(GetWrapperPreserveColor());
3852 }
3853
3854 DebuggerNotificationDispatch(this,
3855 DebuggerNotificationType::RequestAnimationFrame);
3856
3857 uint32_t handle;
3858 aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
3859 return handle;
3860}
3861
3862void nsGlobalWindowInner::CancelAnimationFrame(uint32_t aHandle,
3863 ErrorResult& aError) {
3864 if (!mDoc) {
3865 return;
3866 }
3867
3868 DebuggerNotificationDispatch(this,
3869 DebuggerNotificationType::CancelAnimationFrame);
3870
3871 mDoc->CancelFrameRequestCallback(aHandle);
3872}
3873
3874already_AddRefed<MediaQueryList> nsGlobalWindowInner::MatchMedia(
3875 const nsACString& aMediaQueryList, CallerType aCallerType,
3876 ErrorResult& aError) {
3877 ENSURE_ACTIVE_DOCUMENT(aError, nullptr)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return nullptr; }
} while (0)
;
3878 return mDoc->MatchMedia(aMediaQueryList, aCallerType);
3879}
3880
3881int32_t nsGlobalWindowInner::GetScrollMinX(ErrorResult& aError) {
3882 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, 0);
3883}
3884
3885int32_t nsGlobalWindowInner::GetScrollMinY(ErrorResult& aError) {
3886 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideTop), aError, 0);
3887}
3888
3889int32_t nsGlobalWindowInner::GetScrollMaxX(ErrorResult& aError) {
3890 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideRight), aError, 0);
3891}
3892
3893int32_t nsGlobalWindowInner::GetScrollMaxY(ErrorResult& aError) {
3894 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0);
3895}
3896
3897double nsGlobalWindowInner::GetScrollX(ErrorResult& aError) {
3898 FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0);
3899}
3900
3901double nsGlobalWindowInner::GetScrollY(ErrorResult& aError) {
3902 FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0);
3903}
3904
3905uint32_t nsGlobalWindowInner::Length() { FORWARD_TO_OUTER(Length, (), 0); }
3906
3907Nullable<WindowProxyHolder> nsGlobalWindowInner::GetTop(
3908 mozilla::ErrorResult& aError) {
3909 FORWARD_TO_OUTER_OR_THROW(GetTopOuter, (), aError, nullptr);
3910}
3911
3912already_AddRefed<BrowsingContext> nsGlobalWindowInner::GetChildWindow(
3913 const nsAString& aName) {
3914 if (GetOuterWindowInternal()) {
3915 return GetOuterWindowInternal()->GetChildWindow(aName);
3916 }
3917 return nullptr;
3918}
3919
3920void nsGlobalWindowInner::RefreshRealmPrincipal() {
3921 JS::SetRealmPrincipals(js::GetNonCCWObjectRealm(GetWrapperPreserveColor()),
3922 nsJSPrincipals::get(mDoc->NodePrincipal()));
3923}
3924
3925void nsGlobalWindowInner::RefreshReduceTimerPrecisionCallerType() {
3926 JS::SetRealmReduceTimerPrecisionCallerType(
3927 js::GetNonCCWObjectRealm(GetWrapperPreserveColor()),
3928 RTPCallerTypeToToken(GetRTPCallerType()));
3929}
3930
3931already_AddRefed<nsIWidget> nsGlobalWindowInner::GetMainWidget() const {
3932 FORWARD_TO_OUTER(GetMainWidget, (), nullptr);
3933}
3934
3935nsIWidget* nsGlobalWindowInner::GetNearestWidget() const {
3936 if (GetOuterWindowInternal()) {
3937 return GetOuterWindowInternal()->GetNearestWidget();
3938 }
3939 return nullptr;
3940}
3941
3942void nsGlobalWindowInner::SetFullScreen(bool aFullscreen,
3943 CallerType aCallerType,
3944 ErrorResult& aError) {
3945 if (aCallerType == CallerType::NonSystem) {
3946 if (Document* doc = GetExtantDoc()) {
3947 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3948 }
3949 }
3950 FORWARD_TO_OUTER_OR_THROW(SetFullscreenOuter, (aFullscreen, aError), aError,
3951 /* void */);
3952}
3953
3954bool nsGlobalWindowInner::GetFullScreen(CallerType aCallerType,
3955 ErrorResult& aError) {
3956 if (aCallerType == CallerType::NonSystem) {
3957 if (Document* doc = GetExtantDoc()) {
3958 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3959 }
3960 }
3961 FORWARD_TO_OUTER_OR_THROW(GetFullscreenOuter, (), aError, false);
3962}
3963
3964bool nsGlobalWindowInner::GetFullScreen() {
3965 bool fullscreen = GetFullScreen(CallerType::System, IgnoreErrors());
3966 return fullscreen;
3967}
3968
3969void nsGlobalWindowInner::Dump(const nsAString& aStr) {
3970 if (!nsJSUtils::DumpEnabled()) {
3971 return;
3972 }
3973
3974 char* cstr = ToNewUTF8String(aStr);
3975
3976#if defined(XP_MACOSX)
3977 // have to convert \r to \n so that printing to the console works
3978 char *c = cstr, *cEnd = cstr + strlen(cstr);
3979 while (c < cEnd) {
3980 if (*c == '\r') *c = '\n';
3981 c++;
3982 }
3983#endif
3984
3985 if (cstr) {
3986 MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = nsContentUtils
::DOMDumpLog(); if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, LogLevel::Debug)), 0))) { mozilla::detail::
log_print(moz_real_module, LogLevel::Debug, "[Window.Dump] %s"
, cstr); } } while (0)
3987 ("[Window.Dump] %s", cstr))do { const ::mozilla::LogModule* moz_real_module = nsContentUtils
::DOMDumpLog(); if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, LogLevel::Debug)), 0))) { mozilla::detail::
log_print(moz_real_module, LogLevel::Debug, "[Window.Dump] %s"
, cstr); } } while (0)
;
3988#ifdef XP_WIN
3989 PrintToDebugger(cstr);
3990#endif
3991#ifdef ANDROID
3992 __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
3993#endif
3994 FILE* fp = gDumpFile ? gDumpFile : stdoutstdout;
3995 fputs(cstr, fp);
3996 fflush(fp);
3997 free(cstr);
3998 }
3999}
4000
4001void nsGlobalWindowInner::Alert(nsIPrincipal& aSubjectPrincipal,
4002 ErrorResult& aError) {
4003 Alert(u""_ns, aSubjectPrincipal, aError);
4004}
4005
4006void nsGlobalWindowInner::Alert(const nsAString& aMessage,
4007 nsIPrincipal& aSubjectPrincipal,
4008 ErrorResult& aError) {
4009 FORWARD_TO_OUTER_OR_THROW(AlertOuter, (aMessage, aSubjectPrincipal, aError),
4010 aError, );
4011}
4012
4013bool nsGlobalWindowInner::Confirm(const nsAString& aMessage,
4014 nsIPrincipal& aSubjectPrincipal,
4015 ErrorResult& aError) {
4016 FORWARD_TO_OUTER_OR_THROW(ConfirmOuter, (aMessage, aSubjectPrincipal, aError),
4017 aError, false);
4018}
4019
4020already_AddRefed<Promise> nsGlobalWindowInner::Fetch(
4021 const RequestOrUTF8String& aInput, const RequestInit& aInit,
4022 CallerType aCallerType, ErrorResult& aRv) {
4023 return FetchRequest(this, aInput, aInit, aCallerType, aRv);
4024}
4025
4026void nsGlobalWindowInner::Prompt(const nsAString& aMessage,
4027 const nsAString& aInitial, nsAString& aReturn,
4028 nsIPrincipal& aSubjectPrincipal,
4029 ErrorResult& aError) {
4030 FORWARD_TO_OUTER_OR_THROW(
4031 PromptOuter, (aMessage, aInitial, aReturn, aSubjectPrincipal, aError),
4032 aError, );
4033}
4034
4035void nsGlobalWindowInner::Focus(CallerType aCallerType, ErrorResult& aError) {
4036 FORWARD_TO_OUTER_OR_THROW(FocusOuter,
4037 (aCallerType, /* aFromOtherProcess */ false,
4038 nsFocusManager::GenerateFocusActionId()),
4039 aError, );
4040}
4041
4042nsresult nsGlobalWindowInner::Focus(CallerType aCallerType) {
4043 ErrorResult rv;
4044 Focus(aCallerType, rv);
4045
4046 return rv.StealNSResult();
4047}
4048
4049void nsGlobalWindowInner::Blur(CallerType aCallerType, ErrorResult& aError) {
4050 FORWARD_TO_OUTER_OR_THROW(BlurOuter, (aCallerType), aError, );
4051}
4052
4053void nsGlobalWindowInner::Stop(ErrorResult& aError) {
4054 FORWARD_TO_OUTER_OR_THROW(StopOuter, (aError), aError, );
4055}
4056
4057void nsGlobalWindowInner::Print(ErrorResult& aError) {
4058 FORWARD_TO_OUTER_OR_THROW(PrintOuter, (aError), aError, );
4059}
4060
4061Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview(
4062 nsIPrintSettings* aSettings, nsIWebProgressListener* aListener,
4063 nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) {
4064 FORWARD_TO_OUTER_OR_THROW(
4065 Print,
4066 (aSettings,
4067 /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto,
4068 nsGlobalWindowOuter::IsPreview::Yes,
4069 nsGlobalWindowOuter::IsForWindowDotPrint::No,
4070 /* aPrintPreviewCallback = */ nullptr, nullptr, aError),
4071 aError, nullptr);
4072}
4073
4074void nsGlobalWindowInner::MoveTo(int32_t aXPos, int32_t aYPos,
4075 CallerType aCallerType, ErrorResult& aError) {
4076 FORWARD_TO_OUTER_OR_THROW(MoveToOuter, (aXPos, aYPos, aCallerType, aError),
4077 aError, );
4078}
4079
4080void nsGlobalWindowInner::MoveBy(int32_t aXDif, int32_t aYDif,
4081 CallerType aCallerType, ErrorResult& aError) {
4082 FORWARD_TO_OUTER_OR_THROW(MoveByOuter, (aXDif, aYDif, aCallerType, aError),
4083 aError, );
4084}
4085
4086void nsGlobalWindowInner::ResizeTo(int32_t aWidth, int32_t aHeight,
4087 CallerType aCallerType,
4088 ErrorResult& aError) {
4089 FORWARD_TO_OUTER_OR_THROW(ResizeToOuter,
4090 (aWidth, aHeight, aCallerType, aError), aError, );
4091}
4092
4093void nsGlobalWindowInner::ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
4094 CallerType aCallerType,
4095 ErrorResult& aError) {
4096 FORWARD_TO_OUTER_OR_THROW(
4097 ResizeByOuter, (aWidthDif, aHeightDif, aCallerType, aError), aError, );
4098}
4099
4100void nsGlobalWindowInner::MoveResize(int32_t aX, int32_t aY, int32_t aWidth,
4101 int32_t aHeight, ErrorResult& aError) {
4102 const auto callerType = CallerType::System; // We're ChromeOnly
4103 FORWARD_TO_OUTER_OR_THROW(
4104 MoveResizeOuter, (aX, aY, aWidth, aHeight, callerType, aError), aError, );
4105}
4106
4107void nsGlobalWindowInner::SizeToContent(
4108 const SizeToContentConstraints& aConstraints, ErrorResult& aError) {
4109 FORWARD_TO_OUTER_OR_THROW(SizeToContentOuter, (aConstraints, aError),
4110 aError, );
4111}
4112
4113already_AddRefed<nsPIWindowRoot> nsGlobalWindowInner::GetTopWindowRoot() {
4114 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
4115 if (!outer) {
4116 return nullptr;
4117 }
4118 return outer->GetTopWindowRoot();
4119}
4120
4121void nsGlobalWindowInner::ScrollTo(double aXScroll, double aYScroll) {
4122 ScrollToOptions options;
4123 options.mLeft.Construct(aXScroll);
4124 options.mTop.Construct(aYScroll);
4125 ScrollTo(options);
4126}
4127
4128void nsGlobalWindowInner::ScrollTo(const ScrollToOptions& aOptions) {
4129 Maybe<double> left;
4130 Maybe<double> top;
4131 if (aOptions.mLeft.WasPassed()) {
4132 left.emplace(ToZeroIfNonfinite(aOptions.mLeft.Value()));
4133 }
4134 if (aOptions.mTop.WasPassed()) {
4135 top.emplace(ToZeroIfNonfinite(aOptions.mTop.Value()));
4136 }
4137
4138 // When scrolling to a non-zero offset, we need to determine whether that
4139 // position is within our scrollable range, so we need updated layout
4140 // information.
4141 if ((top && *top != 0) || (left && *left != 0)) {
4142 FlushPendingNotifications(FlushType::Layout);
4143 }
4144
4145 ScrollContainerFrame* sf = GetScrollContainerFrame();
4146 if (!sf) {
4147 return;
4148 }
4149 CSSPoint scrollPos = sf->GetScrollPositionCSSPixels();
4150 if (left) {
4151 scrollPos.x = *left;
4152 }
4153 if (top) {
4154 scrollPos.y = *top;
4155 }
4156 // Here we calculate what the max pixel value is that we can
4157 // scroll to, we do this by dividing maxint with the pixel to
4158 // twips conversion factor, and subtracting 4, the 4 comes from
4159 // experimenting with this value, anything less makes the view
4160 // code not scroll correctly, I have no idea why. -- jst
4161 //
4162 // FIXME(emilio): This seems like if needed it should be done by the
4163 // scrolling code itself...
4164 const double maxpx = CSSPixel::FromAppUnits(0x7fffffff) - 4;
4165 if (scrollPos.x > maxpx) {
4166 scrollPos.x = maxpx;
4167 }
4168 if (scrollPos.y > maxpx) {
4169 scrollPos.y = maxpx;
4170 }
4171 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4172 sf->ScrollToCSSPixels(scrollPos, scrollMode);
4173}
4174
4175void nsGlobalWindowInner::ScrollBy(double aXScrollDif, double aYScrollDif) {
4176 ScrollToOptions options;
4177 options.mLeft.Construct(aXScrollDif);
4178 options.mTop.Construct(aYScrollDif);
4179 // It seems like it would make more sense for ScrollBy to use
4180 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4181 // Perhaps Web content does too.
4182 ScrollBy(options);
4183}
4184
4185void nsGlobalWindowInner::ScrollBy(const ScrollToOptions& aOptions) {
4186 CSSPoint scrollDelta;
4187 if (aOptions.mLeft.WasPassed()) {
4188 scrollDelta.x = ToZeroIfNonfinite(aOptions.mLeft.Value());
4189 }
4190 if (aOptions.mTop.WasPassed()) {
4191 scrollDelta.y = ToZeroIfNonfinite(aOptions.mTop.Value());
4192 }
4193
4194 if (!scrollDelta.x && !scrollDelta.y) {
4195 return;
4196 }
4197
4198 FlushPendingNotifications(FlushType::Layout);
4199 ScrollContainerFrame* sf = GetScrollContainerFrame();
4200 if (!sf) {
4201 return;
4202 }
4203
4204 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4205 sf->ScrollByCSSPixels(scrollDelta, scrollMode);
4206}
4207
4208void nsGlobalWindowInner::ScrollByLines(int32_t numLines,
4209 const ScrollOptions& aOptions) {
4210 if (!numLines) {
4211 return;
4212 }
4213 FlushPendingNotifications(FlushType::Layout);
4214 ScrollContainerFrame* sf = GetScrollContainerFrame();
4215 if (!sf) {
4216 return;
4217 }
4218 // It seems like it would make more sense for ScrollByLines to use
4219 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4220 // Perhaps Web content does too.
4221 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4222 sf->ScrollBy(nsIntPoint(0, numLines), ScrollUnit::LINES, scrollMode);
4223}
4224
4225void nsGlobalWindowInner::ScrollByPages(int32_t numPages,
4226 const ScrollOptions& aOptions) {
4227 if (!numPages) {
4228 return;
4229 }
4230 FlushPendingNotifications(FlushType::Layout);
4231 ScrollContainerFrame* sf = GetScrollContainerFrame();
4232 if (!sf) {
4233 return;
4234 }
4235 // It seems like it would make more sense for ScrollByPages to use
4236 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4237 // Perhaps Web content does too.
4238 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4239
4240 sf->ScrollBy(nsIntPoint(0, numPages), ScrollUnit::PAGES, scrollMode);
4241}
4242
4243void nsGlobalWindowInner::MozScrollSnap() {
4244 FlushPendingNotifications(FlushType::Layout);
4245 if (ScrollContainerFrame* sf = GetScrollContainerFrame()) {
4246 sf->ScrollSnap();
4247 }
4248}
4249
4250void nsGlobalWindowInner::ClearTimeout(int32_t aHandle) {
4251 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout);
4252
4253 if (aHandle > 0) {
4254 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4255 }
4256}
4257
4258void nsGlobalWindowInner::ClearInterval(int32_t aHandle) {
4259 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval);
4260
4261 if (aHandle > 0) {
4262 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4263 }
4264}
4265
4266void nsGlobalWindowInner::SetResizable(bool aResizable) const {
4267 // nop
4268}
4269
4270void nsGlobalWindowInner::CaptureEvents() {
4271 // Intentionally a no-op, as this API is deprecated.
4272}
4273
4274void nsGlobalWindowInner::ReleaseEvents() {
4275 // Intentionally a no-op, as this API is deprecated.
4276}
4277
4278Nullable<WindowProxyHolder> nsGlobalWindowInner::Open(const nsAString& aUrl,
4279 const nsAString& aName,
4280 const nsAString& aOptions,
4281 ErrorResult& aError) {
4282 FORWARD_TO_OUTER_OR_THROW(OpenOuter, (aUrl, aName, aOptions, aError), aError,
4283 nullptr);
4284}
4285
4286Nullable<WindowProxyHolder> nsGlobalWindowInner::OpenDialog(
4287 JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
4288 const nsAString& aOptions, const Sequence<JS::Value>& aExtraArgument,
4289 ErrorResult& aError) {
4290 FORWARD_TO_OUTER_OR_THROW(
4291 OpenDialogOuter, (aCx, aUrl, aName, aOptions, aExtraArgument, aError),
4292 aError, nullptr);
4293}
4294
4295WindowProxyHolder nsGlobalWindowInner::GetFrames(ErrorResult& aError) {
4296 FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, Window());
4297}
4298
4299void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4300 JS::Handle<JS::Value> aMessage,
4301 const nsAString& aTargetOrigin,
4302 JS::Handle<JS::Value> aTransfer,
4303 nsIPrincipal& aSubjectPrincipal,
4304 ErrorResult& aError) {
4305 FORWARD_TO_OUTER_OR_THROW(
4306 PostMessageMozOuter,
4307 (aCx, aMessage, aTargetOrigin, aTransfer, aSubjectPrincipal, aError),
4308 aError, );
4309}
4310
4311void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4312 JS::Handle<JS::Value> aMessage,
4313 const nsAString& aTargetOrigin,
4314 const Sequence<JSObject*>& aTransfer,
4315 nsIPrincipal& aSubjectPrincipal,
4316 ErrorResult& aRv) {
4317 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4318
4319 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer,
4320 &transferArray);
4321 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4321)
) {
4322 return;
4323 }
4324
4325 PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aSubjectPrincipal,
4326 aRv);
4327}
4328
4329void nsGlobalWindowInner::PostMessageMoz(
4330 JSContext* aCx, JS::Handle<JS::Value> aMessage,
4331 const WindowPostMessageOptions& aOptions, nsIPrincipal& aSubjectPrincipal,
4332 ErrorResult& aRv) {
4333 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4334
4335 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(
4336 aCx, aOptions.mTransfer, &transferArray);
4337 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4337)
) {
4338 return;
4339 }
4340
4341 PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, transferArray,
4342 aSubjectPrincipal, aRv);
4343}
4344
4345void nsGlobalWindowInner::Close(CallerType aCallerType, ErrorResult& aError) {
4346 FORWARD_TO_OUTER_OR_THROW(CloseOuter, (aCallerType == CallerType::System),
4347 aError, );
4348}
4349
4350nsresult nsGlobalWindowInner::Close() {
4351 FORWARD_TO_OUTER(Close, (), NS_ERROR_UNEXPECTED);
4352}
4353
4354bool nsGlobalWindowInner::IsInModalState() {
4355 FORWARD_TO_OUTER(IsInModalState, (), false);
4356}
4357
4358void nsGlobalWindowInner::NotifyWindowIDDestroyed(const char* aTopic) {
4359 RefPtr runnable = MakeRefPtr<WindowDestroyedEvent>(this, mWindowID, aTopic);
4360 Dispatch(runnable.forget());
4361}
4362
4363Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
4364 ErrorResult& aError) {
4365 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (aSubjectPrincipal), aError,
4366 nullptr);
4367}
4368
4369Element* nsGlobalWindowInner::GetRealFrameElement(ErrorResult& aError) {
4370 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (), aError, nullptr);
4371}
4372
4373void nsGlobalWindowInner::UpdateCommands(const nsAString& anAction) {
4374 if (GetOuterWindowInternal()) {
4375 GetOuterWindowInternal()->UpdateCommands(anAction);
4376 }
4377}
4378
4379Selection* nsGlobalWindowInner::GetSelection(ErrorResult& aError) {
4380 FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr);
4381}
4382
4383WebTaskScheduler* nsGlobalWindowInner::Scheduler() {
4384 if (!mWebTaskScheduler) {
4385 mWebTaskScheduler = WebTaskScheduler::CreateForMainThread(this);
4386 }
4387 MOZ_ASSERT(mWebTaskScheduler)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWebTaskScheduler)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWebTaskScheduler))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mWebTaskScheduler"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4387
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWebTaskScheduler"
")"); do { MOZ_CrashSequence(__null, 4387); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4388 return mWebTaskScheduler;
4389}
4390
4391bool nsGlobalWindowInner::Find(const nsAString& aString, bool aCaseSensitive,
4392 bool aBackwards, bool aWrapAround,
4393 bool aWholeWord, bool aSearchInFrames,
4394 bool aShowDialog, ErrorResult& aError) {
4395 FORWARD_TO_OUTER_OR_THROW(FindOuter,
4396 (aString, aCaseSensitive, aBackwards, aWrapAround,
4397 aWholeWord, aSearchInFrames, aShowDialog, aError),
4398 aError, false);
4399}
4400
4401void nsGlobalWindowInner::GetOrigin(nsAString& aOrigin) {
4402 nsContentUtils::GetWebExposedOriginSerialization(GetPrincipal(), aOrigin);
4403}
4404
4405// See also AutoJSAPI::ReportException
4406void nsGlobalWindowInner::ReportError(JSContext* aCx,
4407 JS::Handle<JS::Value> aError,
4408 CallerType aCallerType,
4409 ErrorResult& aRv) {
4410 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) {
4411 return aRv.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
4412 }
4413
4414 JS::ErrorReportBuilder jsReport(aCx);
4415 JS::ExceptionStack exnStack(aCx, aError, nullptr);
4416 if (!jsReport.init(aCx, exnStack, JS::ErrorReportBuilder::NoSideEffects)) {
4417 return aRv.NoteJSContextException(aCx);
4418 }
4419
4420 RefPtr xpcReport = MakeRefPtr<xpc::ErrorReport>();
4421 bool isChrome = aCallerType == CallerType::System;
4422 xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
4423 isChrome, WindowID());
4424
4425 JS::RootingContext* rcx = JS::RootingContext::get(aCx);
4426 DispatchScriptErrorEvent(this, rcx, xpcReport, exnStack.exception(),
4427 exnStack.stack());
4428}
4429
4430void nsGlobalWindowInner::Atob(const nsAString& aAsciiBase64String,
4431 nsAString& aBinaryData, ErrorResult& aError) {
4432 aError = nsContentUtils::Atob(aAsciiBase64String, aBinaryData);
4433}
4434
4435void nsGlobalWindowInner::Btoa(const nsAString& aBinaryData,
4436 nsAString& aAsciiBase64String,
4437 ErrorResult& aError) {
4438 aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
4439}
4440
4441//*****************************************************************************
4442// EventTarget
4443//*****************************************************************************
4444
4445bool nsGlobalWindowInner::DispatchEvent(Event& aEvent, CallerType aCallerType,
4446 ErrorResult& aRv) {
4447 if (!IsCurrentInnerWindow()) {
4448 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4450)
4449 "DispatchEvent called on non-current inner window, dropping. "NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4450)
4450 "Please check the window in the caller instead.")NS_DebugBreak(NS_DEBUG_WARNING, "DispatchEvent called on non-current inner window, dropping. "
"Please check the window in the caller instead.", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4450)
;
4451 aRv.Throw(NS_ERROR_FAILURE);
4452 return false;
4453 }
4454
4455 if (!mDoc) {
4456 aRv.Throw(NS_ERROR_FAILURE);
4457 return false;
4458 }
4459
4460 // Obtain a presentation shell
4461 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
4462
4463 nsEventStatus status = nsEventStatus_eIgnore;
4464 nsresult rv = EventDispatcher::DispatchDOMEvent(this, nullptr, &aEvent,
4465 presContext, &status);
4466 bool retval = !aEvent.DefaultPrevented(aCallerType);
4467 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4468 aRv.Throw(rv);
4469 }
4470 return retval;
4471}
4472
4473mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
4474nsGlobalWindowInner::GetDebuggerNotificationType() const {
4475 return mozilla::Some(
4476 mozilla::dom::EventCallbackDebuggerNotificationType::Global);
4477}
4478
4479bool nsGlobalWindowInner::ComputeDefaultWantsUntrusted(ErrorResult& aRv) {
4480 return !nsContentUtils::IsChromeDoc(mDoc);
4481}
4482
4483EventListenerManager* nsGlobalWindowInner::GetOrCreateListenerManager() {
4484 if (!mListenerManager) {
4485 mListenerManager =
4486 MakeRefPtr<EventListenerManager>(static_cast<EventTarget*>(this));
4487 }
4488
4489 return mListenerManager;
4490}
4491
4492EventListenerManager* nsGlobalWindowInner::GetExistingListenerManager() const {
4493 return mListenerManager;
4494}
4495
4496mozilla::dom::DebuggerNotificationManager*
4497nsGlobalWindowInner::GetOrCreateDebuggerNotificationManager() {
4498 if (!mDebuggerNotificationManager) {
4499 mDebuggerNotificationManager =
4500 MakeRefPtr<DebuggerNotificationManager>(this);
4501 }
4502
4503 return mDebuggerNotificationManager;
4504}
4505
4506mozilla::dom::DebuggerNotificationManager*
4507nsGlobalWindowInner::GetExistingDebuggerNotificationManager() {
4508 return mDebuggerNotificationManager;
4509}
4510
4511//*****************************************************************************
4512// nsGlobalWindowInner::nsPIDOMWindow
4513//*****************************************************************************
4514
4515Location* nsGlobalWindowInner::Location() {
4516 if (!mLocation) {
4517 mLocation = MakeRefPtr<dom::Location>(this);
4518 }
4519
4520 return mLocation;
4521}
4522
4523void nsGlobalWindowInner::MaybeUpdateTouchState() {
4524 if (mMayHaveTouchEventListener) {
4525 nsCOMPtr<nsIObserverService> observerService =
4526 services::GetObserverService();
4527
4528 if (observerService) {
4529 observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
4530 DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added", nullptr);
4531 }
4532 }
4533}
4534
4535void nsGlobalWindowInner::EnableGamepadUpdates() {
4536 if (mHasGamepad) {
4537 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4538 if (gamepadManager) {
4539 gamepadManager->AddListener(this);
4540 }
4541 }
4542}
4543
4544void nsGlobalWindowInner::DisableGamepadUpdates() {
4545 if (mHasGamepad) {
4546 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4547 if (gamepadManager) {
4548 gamepadManager->RemoveListener(this);
4549 }
4550 }
4551}
4552
4553void nsGlobalWindowInner::EnableVRUpdates() {
4554 // We need to create a VREventObserver before we can either detect XR runtimes
4555 // or start an XR session
4556 if (!mVREventObserver && (mHasXRSession || mXRRuntimeDetectionInFlight)) {
4557 // Assert that we are not creating the observer while IsDying() as
4558 // that would result in a leak. VREventObserver holds a RefPtr to
4559 // this nsGlobalWindowInner and would prevent it from being deallocated.
4560 MOZ_ASSERT(!IsDying(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4562); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4562); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4561 "Creating a VREventObserver for an nsGlobalWindow that is "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4562); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4562); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4562 "dying would cause it to leak.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4562); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4562); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4563 mVREventObserver = MakeRefPtr<VREventObserver>(this);
4564 }
4565 // If the content has an XR session, then we need to tell
4566 // VREventObserver that there is VR activity.
4567 if (mHasXRSession) {
4568 nsPIDOMWindowOuter* outer = GetOuterWindow();
4569 if (outer && !outer->IsBackground()) {
4570 StartVRActivity();
4571 }
4572 }
4573}
4574
4575void nsGlobalWindowInner::DisableVRUpdates() {
4576 if (mVREventObserver) {
4577 mVREventObserver->DisconnectFromOwner();
4578 mVREventObserver = nullptr;
4579 }
4580}
4581
4582void nsGlobalWindowInner::StartVRActivity() {
4583 /**
4584 * If the content has an XR session, tell
4585 * the VREventObserver that the window is accessing
4586 * VR devices.
4587 *
4588 * It's possible to have a VREventObserver without
4589 * and XR session, if we are using it to get updates
4590 * about XR runtime enumeration. In this case,
4591 * we would not tell the VREventObserver that
4592 * we are accessing VR devices.
4593 */
4594 if (mVREventObserver && mHasXRSession) {
4595 mVREventObserver->StartActivity();
4596 }
4597}
4598
4599void nsGlobalWindowInner::StopVRActivity() {
4600 /**
4601 * If the content has an XR session, tell
4602 * the VReventObserver that the window is no longer
4603 * accessing VR devices. This does not stop the
4604 * XR session itself, which may be resumed with
4605 * EnableVRUpdates.
4606 * It's possible to have a VREventObserver without
4607 * and XR session, if we are using it to get updates
4608 * about XR runtime enumeration. In this case,
4609 * we would not tell the VREventObserver that
4610 * we ending an activity that accesses VR devices.
4611 */
4612 if (mVREventObserver && mHasXRSession) {
4613 mVREventObserver->StopActivity();
4614 }
4615}
4616
4617void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
4618 uint32_t aFocusMethod,
4619 bool aNeedsFocus) {
4620 if (aElement && aElement->GetComposedDoc() != mDoc) {
4621 NS_WARNING("Trying to set focus to a node from a wrong document")NS_DebugBreak(NS_DEBUG_WARNING, "Trying to set focus to a node from a wrong document"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4621)
;
4622 return;
4623 }
4624
4625 if (IsDying()) {
4626 NS_ASSERTION(!aElement, "Trying to focus cleaned up window!")do { if (!(!aElement)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Trying to focus cleaned up window!"
, "!aElement", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4626); MOZ_PretendNoReturn(); } } while (0)
;
4627 aElement = nullptr;
4628 aNeedsFocus = false;
4629 }
4630 if (mFocusedElement != aElement) {
4631 mFocusedElement = aElement;
4632 // TODO: Maybe this should be set on refocus too?
4633 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4634 }
4635
4636 if (mFocusedElement) {
4637 // if a node was focused by a keypress, turn on focus rings for the
4638 // window.
4639 if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
4640 mUnknownFocusMethodShouldShowOutline = true;
4641 mFocusByKeyOccurred = true;
4642 } else if (nsFocusManager::GetFocusMoveActionCause(mFocusMethod) !=
4643 widget::InputContextAction::CAUSE_UNKNOWN) {
4644 mUnknownFocusMethodShouldShowOutline = false;
4645 } else if (aFocusMethod & nsIFocusManager::FLAG_NOSHOWRING) {
4646 // If we get focused via script, and script has explicitly opted out of
4647 // outlines via FLAG_NOSHOWRING, we don't want to make a refocus start
4648 // showing outlines.
4649 mUnknownFocusMethodShouldShowOutline = false;
4650 }
4651 }
4652
4653 if (aNeedsFocus) {
4654 mNeedsFocus = aNeedsFocus;
4655 }
4656}
4657
4658uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
4659
4660bool nsGlobalWindowInner::ShouldShowFocusRing() {
4661 if (mFocusByKeyOccurred &&
4662 StaticPrefs::browser_display_always_show_rings_after_key_focus()) {
4663 return true;
4664 }
4665 return StaticPrefs::browser_display_show_focus_rings();
4666}
4667
4668bool nsGlobalWindowInner::TakeFocus(bool aFocus, uint32_t aFocusMethod) {
4669 if (IsDying()) {
4670 return false;
4671 }
4672
4673 if (aFocus) {
4674 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4675 }
4676
4677 // if mNeedsFocus is true, then the document has not yet received a
4678 // document-level focus event. If there is a root content node, then return
4679 // true to tell the calling focus manager that a focus event is expected. If
4680 // there is no root content node, the document hasn't loaded enough yet, or
4681 // there isn't one and there is no point in firing a focus event.
4682 if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement()) {
4683 mNeedsFocus = false;
4684 return true;
4685 }
4686
4687 mNeedsFocus = false;
4688 return false;
4689}
4690
4691void nsGlobalWindowInner::SetReadyForFocus() {
4692 bool oldNeedsFocus = mNeedsFocus;
4693 mNeedsFocus = false;
4694
4695 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4696 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4697 fm->WindowShown(outerWindow, oldNeedsFocus);
4698 }
4699}
4700
4701void nsGlobalWindowInner::PageHidden(bool aIsEnteringBFCacheInParent) {
4702 // the window is being hidden, so tell the focus manager that the frame is
4703 // no longer valid. Use the persisted field to determine if the document
4704 // is being destroyed.
4705
4706 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4707 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4708 fm->WindowHidden(outerWindow, nsFocusManager::GenerateFocusActionId(),
4709 aIsEnteringBFCacheInParent);
4710 }
4711
4712 mNeedsFocus = true;
4713}
4714
4715class HashchangeCallback : public Runnable {
4716 public:
4717 HashchangeCallback(const nsAString& aOldURL, const nsAString& aNewURL,
4718 nsGlobalWindowInner* aWindow)
4719 : mozilla::Runnable("HashchangeCallback"), mWindow(aWindow) {
4720 MOZ_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4720); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 4720); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4721 mOldURL.Assign(aOldURL);
4722 mNewURL.Assign(aNewURL);
4723 }
4724
4725 NS_IMETHODvirtual nsresult Run() override {
4726 MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be called on the main thread." ")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4726); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread." ")"); do { MOZ_CrashSequence
(__null, 4726); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4727 return mWindow->FireHashchange(mOldURL, mNewURL);
4728 }
4729
4730 private:
4731 nsString mOldURL;
4732 nsString mNewURL;
4733 RefPtr<nsGlobalWindowInner> mWindow;
4734};
4735
4736nsresult nsGlobalWindowInner::DispatchAsyncHashchange(nsIURI* aOldURI,
4737 nsIURI* aNewURI) {
4738 // Make sure that aOldURI and aNewURI are identical up to the '#', and that
4739 // their hashes are different.
4740 bool equal = false;
4741 NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->EqualsExceptRef(aNewURI, &equal)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal
))), 1))) && equal)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal))), 1))) && equal"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4742); return NS_ERROR_UNEXPECTED; } } while (false)
4742 equal)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal
))), 1))) && equal)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->EqualsExceptRef(aNewURI, &equal))), 1))) && equal"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4742); return NS_ERROR_UNEXPECTED; } } while (false)
;
4743 nsAutoCString oldHash, newHash;
4744 bool oldHasHash, newHasHash;
4745 NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->GetRef(oldHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4749); return NS_ERROR_UNEXPECTED; } } while (false)
4746 NS_SUCCEEDED(aNewURI->GetRef(newHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4749); return NS_ERROR_UNEXPECTED; } } while (false)
4747 NS_SUCCEEDED(aOldURI->GetHasRef(&oldHasHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4749); return NS_ERROR_UNEXPECTED; } } while (false)
4748 NS_SUCCEEDED(aNewURI->GetHasRef(&newHasHash)) &&do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4749); return NS_ERROR_UNEXPECTED; } } while (false)
4749 (oldHasHash != newHasHash || !oldHash.Equals(newHash)))do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) &&
((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef
(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((
bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef
(&newHasHash))), 1))) && (oldHasHash != newHasHash
|| !oldHash.Equals(newHash)))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetRef(oldHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetRef(newHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aOldURI->GetHasRef(&oldHasHash))), 1))) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(aNewURI->GetHasRef(&newHasHash))), 1))) && (oldHasHash != newHasHash || !oldHash.Equals(newHash))"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4749); return NS_ERROR_UNEXPECTED; } } while (false)
;
4750
4751 nsAutoCString oldSpec, newSpec;
4752 nsresult rv = aOldURI->GetSpec(oldSpec);
4753 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4753); return rv; } } while (false)
;
4754 rv = aNewURI->GetSpec(newSpec);
4755 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4755); return rv; } } while (false)
;
4756
4757 NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec);
4758 NS_ConvertUTF8toUTF16 newWideSpec(newSpec);
4759
4760 RefPtr callback =
4761 MakeRefPtr<HashchangeCallback>(oldWideSpec, newWideSpec, this);
4762 return Dispatch(callback.forget());
4763}
4764
4765nsresult nsGlobalWindowInner::FireHashchange(const nsAString& aOldURL,
4766 const nsAString& aNewURL) {
4767 // Don't do anything if the window is frozen.
4768 if (IsFrozen()) {
4769 return NS_OK;
4770 }
4771
4772 // Get a presentation shell for use in creating the hashchange event.
4773 NS_ENSURE_STATE(IsCurrentInnerWindow())do { if ((__builtin_expect(!!(!(IsCurrentInnerWindow())), 0))
) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "IsCurrentInnerWindow()"
") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4773); return NS_ERROR_UNEXPECTED; } } while (false)
;
4774
4775 HashChangeEventInit init;
4776 init.mNewURL = aNewURL;
4777 init.mOldURL = aOldURL;
4778
4779 RefPtr<HashChangeEvent> event =
4780 HashChangeEvent::Constructor(this, u"hashchange"_ns, init);
4781
4782 event->SetTrusted(true);
4783
4784 ErrorResult rv;
4785 DispatchEvent(*event, rv);
4786 return rv.StealNSResult();
4787}
4788
4789nsresult nsGlobalWindowInner::DispatchSyncPopState() {
4790 NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),do { if (!(nsContentUtils::IsSafeToRunScript())) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Must be safe to run script here.", "nsContentUtils::IsSafeToRunScript()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4791
); MOZ_PretendNoReturn(); } } while (0)
4791 "Must be safe to run script here.")do { if (!(nsContentUtils::IsSafeToRunScript())) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Must be safe to run script here.", "nsContentUtils::IsSafeToRunScript()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4791
); MOZ_PretendNoReturn(); } } while (0)
;
4792
4793 // Bail if the window is frozen.
4794 if (IsFrozen()) {
4795 return NS_OK;
4796 }
4797
4798 AutoJSAPI jsapi;
4799 bool result = jsapi.Init(this);
4800 NS_ENSURE_TRUE(result, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(result)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "result" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4800
); return NS_ERROR_FAILURE; } } while (false)
;
4801
4802 JSContext* cx = jsapi.cx();
4803
4804 // Get the document's pending state object -- it contains the data we're
4805 // going to send along with the popstate event. The object is serialized
4806 // using structured clone.
4807 JS::Rooted<JS::Value> stateJSValue(cx);
4808 nsresult rv = mDoc->GetStateObject(&stateJSValue);
4809 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4809); return rv; } } while (false)
;
4810
4811 if (!JS_WrapValue(cx, &stateJSValue)) {
4812 return NS_ERROR_OUT_OF_MEMORY;
4813 }
4814
4815 RootedDictionary<PopStateEventInit> init(cx);
4816 init.mState = stateJSValue;
4817
4818 RefPtr<PopStateEvent> event =
4819 PopStateEvent::Constructor(this, u"popstate"_ns, init);
4820 event->SetTrusted(true);
4821 event->SetTarget(this);
4822
4823 ErrorResult err;
4824 DispatchEvent(*event, err);
4825 return err.StealNSResult();
4826}
4827
4828already_AddRefed<nsDOMCSSDeclaration> nsGlobalWindowInner::GetComputedStyle(
4829 Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) {
4830 return GetComputedStyleHelper(aElt, aPseudoElt, false, aError);
4831}
4832
4833already_AddRefed<nsDOMCSSDeclaration>
4834nsGlobalWindowInner::GetDefaultComputedStyle(Element& aElt,
4835 const nsAString& aPseudoElt,
4836 ErrorResult& aError) {
4837 return GetComputedStyleHelper(aElt, aPseudoElt, true, aError);
4838}
4839
4840already_AddRefed<nsDOMCSSDeclaration>
4841nsGlobalWindowInner::GetComputedStyleHelper(Element& aElt,
4842 const nsAString& aPseudoElt,
4843 bool aDefaultStylesOnly,
4844 ErrorResult& aError) {
4845 FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter,
4846 (aElt, aPseudoElt, aDefaultStylesOnly, aError),
4847 aError, nullptr);
4848}
4849
4850Storage* nsGlobalWindowInner::GetSessionStorage(ErrorResult& aError) {
4851 nsIPrincipal* principal = GetPrincipal();
4852 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
4853 BrowsingContext* browsingContext = GetBrowsingContext();
4854
4855 if (!principal || !storagePrincipal || !browsingContext ||
4856 !Storage::StoragePrefIsEnabled()) {
4857 return nullptr;
4858 }
4859
4860 if (mSessionStorage) {
4861 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4862 ("nsGlobalWindowInner %p has %p sessionStorage", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4863 mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p has %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
;
4864 bool canAccess =
4865 principal->Subsumes(mSessionStorage->Principal()) &&
4866 storagePrincipal->Subsumes(mSessionStorage->StoragePrincipal());
4867 if (!canAccess) {
4868 mSessionStorage = nullptr;
4869 }
4870 }
4871
4872 if (!mSessionStorage) {
4873 nsString documentURI;
4874 if (mDoc) {
4875 aError = mDoc->GetDocumentURI(documentURI);
4876 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4876)
) {
4877 return nullptr;
4878 }
4879 }
4880
4881 if (!mDoc) {
4882 aError.Throw(NS_ERROR_FAILURE);
4883 return nullptr;
4884 }
4885
4886 // If the document's sandboxed origin flag is set, then accessing
4887 // sessionStorage is prohibited.
4888 if (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
4889 aError.ThrowSecurityError(
4890 "Forbidden in a sandboxed document without the 'allow-same-origin' "
4891 "flag.");
4892 return nullptr;
4893 }
4894
4895 uint32_t rejectedReason = 0;
4896 StorageAccess access = StorageAllowedForWindow(this, &rejectedReason);
4897
4898 // SessionStorage is an ephemeral per-tab per-origin storage that only lives
4899 // as long as the tab is open, although it may survive browser restarts
4900 // thanks to the session store. So we interpret storage access differently
4901 // than we would for persistent per-origin storage like LocalStorage and so
4902 // it may be okay to provide SessionStorage even when we receive a value of
4903 // eDeny.
4904 //
4905 // ContentBlocking::ShouldAllowAccessFor will return false for 3 main
4906 // reasons.
4907 //
4908 // 1. Cookies are entirely blocked due to a per-origin permission
4909 // (nsICookiePermission::ACCESS_DENY for the top-level principal or this
4910 // window's principal) or the very broad BEHAVIOR_REJECT. This will return
4911 // eDeny with a reason of STATE_COOKIES_BLOCKED_BY_PERMISSION or
4912 // STATE_COOKIES_BLOCKED_ALL.
4913 //
4914 // 2. Third-party cookies are limited via BEHAVIOR_REJECT_FOREIGN and
4915 // BEHAVIOR_LIMIT_FOREIGN and this is a third-party window. This will return
4916 // eDeny with a reason of STATE_COOKIES_BLOCKED_FOREIGN.
4917 //
4918 // 3. Tracking protection (BEHAVIOR_REJECT_TRACKER and
4919 // BEHAVIOR_PARTITION_FOREIGN) is in effect and
4920 // IsThirdPartyTrackingResourceWindow() returned true and there wasn't a
4921 // permission that allows it. This will return ePartitionTrackersOrDeny with
4922 // a reason of STATE_COOKIES_BLOCKED_TRACKER or
4923 // STATE_COOKIES_BLOCKED_SOCIALTRACKER.
4924 // TODO(Bug 2039931): case 3 is out of date.
4925 //
4926 // In the 1st case, the user has explicitly indicated that they don't want
4927 // to allow any storage to the origin or all origins and so we throw an
4928 // error and deny access to SessionStorage. In the 2nd case, a legacy
4929 // decision reasoned that there's no harm in providing SessionStorage
4930 // because the information is not durable and cannot escape the current tab.
4931 // The rationale is similar for the 3rd case.
4932 if (access == StorageAccess::eDeny &&
4933 rejectedReason !=
4934 nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
4935 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
4936 return nullptr;
4937 }
4938
4939 const RefPtr<SessionStorageManager> storageManager =
4940 browsingContext->GetSessionStorageManager();
4941 if (!storageManager) {
4942 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4943 return nullptr;
4944 }
4945
4946 RefPtr<Storage> storage;
4947 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
4948 documentURI, IsPrivateBrowsing(),
4949 getter_AddRefs(storage));
4950 if (aError.Failed()) {
4951 return nullptr;
4952 }
4953
4954 mSessionStorage = storage;
4955 MOZ_ASSERT(mSessionStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSessionStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSessionStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mSessionStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 4955
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSessionStorage" ")"
); do { MOZ_CrashSequence(__null, 4955); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4956
4957 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
4958 ("nsGlobalWindowInner %p tried to get a new sessionStorage %p",do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
4959 this, mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p tried to get a new sessionStorage %p"
, this, mSessionStorage.get()); } } while (0)
;
4960
4961 if (!mSessionStorage) {
4962 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4963 return nullptr;
4964 }
4965 }
4966
4967 MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4968 ("nsGlobalWindowInner %p returns %p sessionStorage", this,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
4969 mSessionStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p returns %p sessionStorage"
, this, mSessionStorage.get()); } } while (0)
;
4970
4971 return mSessionStorage;
4972}
4973
4974Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
4975 if (!Storage::StoragePrefIsEnabled()) {
4976 return nullptr;
4977 }
4978
4979 // If the document's sandboxed origin flag is set, then accessing localStorage
4980 // is prohibited.
4981 if (mDoc && mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
4982 aError.ThrowSecurityError(
4983 "Forbidden in a sandboxed document without the 'allow-same-origin' "
4984 "flag.");
4985 return nullptr;
4986 }
4987
4988 // LocalStorage needs to be exposed in every context except for sandboxes and
4989 // NullPrincipals (data: URLs, for instance). But we need to keep data
4990 // separate in some scenarios: private-browsing and partitioned trackers.
4991 // In private-browsing, LocalStorage keeps data in memory, and it shares
4992 // StorageEvents just with other origins in the same private-browsing
4993 // environment.
4994 // For Partitioned Trackers, we expose a partitioned LocalStorage, which
4995 // doesn't share data with other contexts, and it's just in memory.
4996 // Partitioned localStorage is available only for trackers listed in the
4997 // privacy.restrict3rdpartystorage.partitionedHosts pref. See
4998 // nsContentUtils::IsURIInPrefList to know the syntax for the pref value.
4999 // This is a temporary web-compatibility hack.
5000
5001 StorageAccess access = StorageAllowedForWindow(this);
5002
5003 // We allow partitioned localStorage only to some hosts.
5004 bool isolated = false;
5005 if (ShouldPartitionStorage(access)) {
5006 if (!mDoc) {
5007 access = StorageAccess::eDeny;
5008 } else if (!StoragePartitioningEnabled(access, mDoc->CookieJarSettings())) {
5009 static const char* kPrefName =
5010 "privacy.restrict3rdpartystorage.partitionedHosts";
5011
5012 bool isInList = false;
5013 mDoc->NodePrincipal()->IsURIInPrefList(kPrefName, &isInList);
5014 if (!isInList) {
5015 access = StorageAccess::eDeny;
5016 } else {
5017 isolated = true;
5018 }
5019 }
5020 }
5021
5022 if (access == StorageAccess::eDeny) {
5023 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5024 return nullptr;
5025 }
5026
5027 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
5028 if (mDoc) {
5029 cookieJarSettings = mDoc->CookieJarSettings();
5030 } else {
5031 cookieJarSettings = net::CookieJarSettings::GetBlockingAll(
5032 ShouldResistFingerprinting(RFPTarget::IsAlwaysEnabledForPrecompute));
5033 }
5034
5035 // Note that this behavior is observable: if we grant storage permission to a
5036 // tracker, we pass from the partitioned LocalStorage (or a partitioned cookie
5037 // jar) to the 'normal' one. The previous data is lost and the 2
5038 // window.localStorage objects, before and after the permission granted, will
5039 // be different.
5040 if (mLocalStorage) {
5041 if ((mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
5042 : Storage::eLocalStorage)) &&
5043 (mLocalStorage->StoragePrincipal() == GetEffectiveStoragePrincipal())) {
5044 return mLocalStorage;
5045 }
5046
5047 // storage needs change
5048 mLocalStorage = nullptr;
5049 }
5050
5051 MOZ_ASSERT(!mLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mLocalStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5051
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5051); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5052
5053 if (!isolated) {
5054 RefPtr<Storage> storage;
5055
5056 if (NextGenLocalStorageEnabled()) {
5057 aError = LSObject::CreateForWindow(this, getter_AddRefs(storage));
5058 } else {
5059 nsresult rv;
5060 nsCOMPtr<nsIDOMStorageManager> storageManager =
5061 do_GetService("@mozilla.org/dom/localStorage-manager;1", &rv);
5062 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5063 aError.Throw(rv);
5064 return nullptr;
5065 }
5066
5067 nsString documentURI;
5068 if (mDoc) {
5069 aError = mDoc->GetDocumentURI(documentURI);
5070 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5070)
) {
5071 return nullptr;
5072 }
5073 }
5074
5075 nsIPrincipal* principal = GetPrincipal();
5076 if (!principal) {
5077 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5078 return nullptr;
5079 }
5080
5081 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5082 if (!storagePrincipal) {
5083 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5084 return nullptr;
5085 }
5086
5087 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
5088 documentURI, IsPrivateBrowsing(),
5089 getter_AddRefs(storage));
5090 }
5091
5092 if (aError.Failed()) {
5093 return nullptr;
5094 }
5095
5096 mLocalStorage = storage;
5097 } else {
5098 nsresult rv;
5099 nsCOMPtr<nsIDOMSessionStorageManager> storageManager =
5100 do_GetService("@mozilla.org/dom/sessionStorage-manager;1", &rv);
5101 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5102 aError.Throw(rv);
5103 return nullptr;
5104 }
5105
5106 nsIPrincipal* principal = GetPrincipal();
5107 if (!principal) {
5108 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5109 return nullptr;
5110 }
5111
5112 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5113 if (!storagePrincipal) {
5114 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5115 return nullptr;
5116 }
5117
5118 RefPtr<SessionStorageCache> cache;
5119 if (isolated) {
5120 cache = MakeRefPtr<SessionStorageCache>();
5121 } else {
5122 // This will clone the session storage if it exists.
5123 rv = storageManager->GetSessionStorageCache(principal, storagePrincipal,
5124 &cache);
5125 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5126 aError.Throw(rv);
5127 return nullptr;
5128 }
5129 }
5130
5131 mLocalStorage = MakeRefPtr<PartitionedLocalStorage>(
5132 this, principal, storagePrincipal, cache);
5133 }
5134
5135 MOZ_ASSERT(mLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mLocalStorage",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5135
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5135); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5136 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5138
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5138); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5137 mLocalStorage->Type() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5138
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5138); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5138 (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
: Storage::eLocalStorage))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage->Type() == (
isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5138
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5138); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5139 return mLocalStorage;
5140}
5141
5142IDBFactory* nsGlobalWindowInner::GetIndexedDB(JSContext* aCx,
5143 ErrorResult& aError) {
5144 if (!mIndexedDB) {
5145 // This may keep mIndexedDB null without setting an error.
5146 auto res = IDBFactory::CreateForWindow(this);
5147 if (res.isErr()) {
5148 aError = res.unwrapErr();
5149 } else {
5150 mIndexedDB = res.unwrap();
5151 }
5152 }
5153
5154 return mIndexedDB;
5155}
5156
5157//*****************************************************************************
5158// nsGlobalWindowInner::nsIInterfaceRequestor
5159//*****************************************************************************
5160
5161NS_IMETHODIMPnsresult
5162nsGlobalWindowInner::GetInterface(const nsIID& aIID, void** aSink) {
5163 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
5164 NS_ENSURE_TRUE(outer, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(outer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "outer" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5164
); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
5165
5166 nsresult rv = outer->GetInterfaceInternal(aIID, aSink);
5167 if (rv == NS_ERROR_NO_INTERFACE) {
5168 return QueryInterface(aIID, aSink);
5169 }
5170 return rv;
5171}
5172
5173void nsGlobalWindowInner::GetInterface(JSContext* aCx,
5174 JS::Handle<JS::Value> aIID,
5175 JS::MutableHandle<JS::Value> aRetval,
5176 ErrorResult& aError) {
5177 dom::GetInterface(aCx, this, aIID, aRetval, aError);
5178}
5179
5180already_AddRefed<CacheStorage> nsGlobalWindowInner::GetCaches(
5181 ErrorResult& aRv) {
5182 if (!mCacheStorage) {
5183 bool forceTrustedOrigin =
5184 GetBrowsingContext() &&
5185 GetBrowsingContext()->Top()->GetServiceWorkersTestingEnabled();
5186 mCacheStorage = CacheStorage::CreateOnMainThread(
5187 cache::DEFAULT_NAMESPACE, this, GetEffectiveStoragePrincipal(),
5188 forceTrustedOrigin, aRv);
5189 }
5190
5191 RefPtr<CacheStorage> ref = mCacheStorage;
5192 return ref.forget();
5193}
5194
5195void nsGlobalWindowInner::FireOfflineStatusEventIfChanged() {
5196 if (!IsCurrentInnerWindow()) return;
5197
5198 bool isOffline =
5199 NS_IsOffline() ||
5200 (GetBrowsingContext() && GetBrowsingContext()->Top()->GetForceOffline());
5201
5202 // Don't fire an event if the status hasn't changed
5203 if (mWasOffline == isOffline) {
5204 return;
5205 }
5206
5207 if (ShouldResistFingerprinting(RFPTarget::NetworkConnection)) {
5208 // We always report online=true when resistFingerprinting is enabled.
5209 return;
5210 }
5211
5212 mWasOffline = !mWasOffline;
5213
5214 nsAutoString name;
5215 if (mWasOffline) {
5216 name.AssignLiteral("offline");
5217 } else {
5218 name.AssignLiteral("online");
5219 }
5220 nsContentUtils::DispatchTrustedEvent(this, this, name, CanBubble::eNo,
5221 Cancelable::eNo);
5222}
5223
5224nsGlobalWindowInner::SlowScriptResponse
5225nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx,
5226 const nsString& aAddonId,
5227 const double aDuration) {
5228 nsresult rv;
5229
5230 if (Preferences::GetBool("dom.always_stop_slow_scripts")) {
1
Assuming the condition is false
2
Taking false branch
5231 return KillSlowScript;
5232 }
5233
5234 // If it isn't safe to run script, then it isn't safe to bring up the prompt
5235 // (since that spins the event loop). In that (rare) case, we just kill the
5236 // script and report a warning.
5237 if (!nsContentUtils::IsSafeToRunScript()) {
3
Assuming the condition is false
4
Taking false branch
5238 JS::WarnASCII(aCx, "A long running script was terminated");
5239 return KillSlowScript;
5240 }
5241
5242 // If our document is not active, just kill the script: we've been unloaded
5243 if (!HasActiveDocument()) {
5
Assuming the condition is false
6
Taking false branch
5244 return KillSlowScript;
5245 }
5246
5247 // Check if we should offer the option to debug
5248 JS::AutoFilename filename;
5249 uint32_t lineno;
7
'lineno' declared without an initial value
5250 // Computing the line number can be very expensive (see bug 1330231 for
5251 // example), and we don't use the line number anywhere except than in the
5252 // parent process, so we avoid computing it elsewhere. This gives us most of
5253 // the wins we are interested in, since the source of the slowness here is
5254 // minified scripts which is more common in Web content that is loaded in the
5255 // content process.
5256 uint32_t* linenop = XRE_IsParentProcess() ? &lineno : nullptr;
8
Assuming the condition is false
9
'?' condition is false
5257 bool hasFrame = JS::DescribeScriptedCaller(&filename, aCx, linenop);
5258
5259 // Record the slow script event if we haven't done so already for this inner
5260 // window (which represents a particular page to the user).
5261 if (!mHasHadSlowScript) {
10
Assuming field 'mHasHadSlowScript' is true
11
Taking false branch
5262 glean::dom::slow_script_page_count.Add(1);
5263 }
5264 mHasHadSlowScript = true;
5265
5266 // Override the cursor to something that we're sure the user can see.
5267 SetCursor("auto"_ns, IgnoreErrors());
5268
5269 if (XRE_IsContentProcess() && ProcessHangMonitor::Get()) {
12
Assuming the condition is false
5270 ProcessHangMonitor::SlowScriptAction action;
5271 RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
5272 nsIDocShell* docShell = GetDocShell();
5273 nsCOMPtr<nsIBrowserChild> child =
5274 docShell ? docShell->GetBrowserChild() : nullptr;
5275 action =
5276 monitor->NotifySlowScript(child, filename.get(), aAddonId, aDuration);
5277 if (action == ProcessHangMonitor::Terminate) {
5278 return KillSlowScript;
5279 }
5280
5281 if (action == ProcessHangMonitor::StartDebugger) {
5282 // Spin a nested event loop so that the debugger in the parent can fetch
5283 // any information it needs. Once the debugger has started, return to the
5284 // script.
5285 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal();
5286 outer->EnterModalState();
5287 SpinEventLoopUntil("nsGlobalWindowInner::ShowSlowScriptDialog"_ns, [&]() {
5288 return monitor->IsDebuggerStartupComplete() ||
5289 AppShutdown::IsShutdownImpending();
5290 });
5291 outer->LeaveModalState();
5292 return (AppShutdown::IsShutdownImpending()) ? KillSlowScript
5293 : ContinueSlowScript;
5294 }
5295
5296 return ContinueSlowScriptAndKeepNotifying;
5297 }
5298
5299 // Reached only on non-e10s - once per slow script dialog.
5300 // On e10s - we probe once at ProcessHangsMonitor.sys.mjs
5301 glean::dom::slow_script_notice_count.Add(1);
5302
5303 // Get the nsIPrompt interface from the docshell
5304 nsCOMPtr<nsIDocShell> ds = GetDocShell();
5305 NS_ENSURE_TRUE(ds, KillSlowScript)do { if ((__builtin_expect(!!(!(ds)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ds" ") failed", nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5305); return KillSlowScript; } } while (false)
;
13
Taking false branch
14
Loop condition is false. Exiting loop
5306 nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ds);
5307 NS_ENSURE_TRUE(prompt, KillSlowScript)do { if ((__builtin_expect(!!(!(prompt)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prompt" ") failed", nullptr
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5307
); return KillSlowScript; } } while (false)
;
15
Taking false branch
16
Loop condition is false. Exiting loop
5308
5309 // Prioritize the SlowScriptDebug interface over JSD1.
5310 nsCOMPtr<nsISlowScriptDebugCallback> debugCallback;
5311
5312 if (hasFrame) {
17
Assuming 'hasFrame' is false
18
Taking false branch
5313 const char* debugCID = "@mozilla.org/dom/slow-script-debug;1";
5314 nsCOMPtr<nsISlowScriptDebug> debugService = do_GetService(debugCID, &rv);
5315 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5316 debugService->GetActivationHandler(getter_AddRefs(debugCallback));
5317 }
5318 }
5319
5320 bool failed = false;
5321 auto getString = [&](const char* name, PropertiesFile propFile =
5322 PropertiesFile::DOM_PROPERTIES) {
5323 nsAutoString result;
5324 nsresult rv = nsContentUtils::GetLocalizedString(propFile, name, result);
5325
5326 // GetStringFromName can return NS_OK and still give nullptr string
5327 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || result.IsEmpty();
5328 return result;
5329 };
5330
5331 bool isAddonScript = !aAddonId.IsEmpty();
19
Assuming the condition is false
5332 bool showDebugButton = debugCallback && !isAddonScript;
5333
5334 // Get localizable strings
5335
5336 nsAutoString title, checkboxMsg, debugButton, msg;
5337 if (isAddonScript
19.1
'isAddonScript' is false
) {
20
Taking false branch
5338 title = getString("KillAddonScriptTitle");
5339 checkboxMsg = getString("KillAddonScriptGlobalMessage");
5340
5341 auto appName =
5342 getString("brandShortName", PropertiesFile::BRAND_PROPERTIES);
5343
5344 nsCOMPtr<nsIAddonPolicyService> aps =
5345 do_GetService("@mozilla.org/addons/policy-service;1");
5346 nsString addonName;
5347 if (!aps || NS_FAILED(aps->GetExtensionName(aAddonId, addonName))((bool)(__builtin_expect(!!(NS_FAILED_impl(aps->GetExtensionName
(aAddonId, addonName))), 0)))
) {
5348 addonName = aAddonId;
5349 }
5350
5351 rv = nsContentUtils::FormatLocalizedString(
5352 msg, PropertiesFile::DOM_PROPERTIES, "KillAddonScriptMessage",
5353 addonName, appName);
5354
5355 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5356 } else {
5357 title = getString("KillScriptTitle");
5358 checkboxMsg = getString("DontAskAgain");
5359
5360 if (showDebugButton
20.1
'showDebugButton' is false
) {
21
Taking false branch
5361 debugButton = getString("DebugScriptButton");
5362 msg = getString("KillScriptWithDebugMessage");
5363 } else {
5364 msg = getString("KillScriptMessage");
5365 }
5366 }
5367
5368 auto stopButton = getString("StopScriptButton");
5369 auto waitButton = getString("WaitForScriptButton");
5370
5371 if (failed) {
22
Assuming 'failed' is false
23
Taking false branch
5372 NS_ERROR("Failed to get localized strings.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Failed to get localized strings."
, "Error", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5372); MOZ_PretendNoReturn(); } while (0)
;
5373 return ContinueSlowScript;
5374 }
5375
5376 // Append file and line number information, if available
5377 if (filename.get()) {
24
Assuming the condition is true
25
Taking true branch
5378 nsAutoString scriptLocation;
5379 // We want to drop the middle part of too-long locations. We'll
5380 // define "too-long" as longer than 60 UTF-16 code units. Just
5381 // have to be a bit careful about unpaired surrogates.
5382 NS_ConvertUTF8toUTF16 filenameUTF16(filename.get());
5383 if (filenameUTF16.Length() > 60) {
26
Assuming the condition is false
27
Taking false branch
5384 // XXXbz Do we need to insert any bidi overrides here?
5385 size_t cutStart = 30;
5386 size_t cutLength = filenameUTF16.Length() - 60;
5387 MOZ_ASSERT(cutLength > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cutLength > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(cutLength > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("cutLength > 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5387
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cutLength > 0"
")"); do { MOZ_CrashSequence(__null, 5387); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5388 if (IsLowSurrogate(filenameUTF16[cutStart])) {
5389 // Don't truncate before the low surrogate, in case it's preceded by a
5390 // high surrogate and forms a single Unicode character. Instead, just
5391 // include the low surrogate.
5392 ++cutStart;
5393 --cutLength;
5394 }
5395 if (IsLowSurrogate(filenameUTF16[cutStart + cutLength])) {
5396 // Likewise, don't drop a trailing low surrogate here. We want to
5397 // increase cutLength, since it might be 0 already so we can't very well
5398 // decrease it.
5399 ++cutLength;
5400 }
5401
5402 // Insert U+2026 HORIZONTAL ELLIPSIS
5403 filenameUTF16.ReplaceLiteral(cutStart, cutLength, u"\x2026");
5404 }
5405 rv = nsContentUtils::FormatLocalizedString(
5406 scriptLocation, PropertiesFile::DOM_PROPERTIES, "KillScriptLocation",
5407 filenameUTF16);
5408
5409 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
28
Assuming the condition is true
29
Taking true branch
5410 msg.AppendLiteral("\n\n");
5411 msg.Append(scriptLocation);
5412 msg.Append(':');
5413 msg.AppendInt(lineno);
30
1st function call argument is an uninitialized value
5414 }
5415 }
5416
5417 uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT +
5418 (nsIPrompt::BUTTON_TITLE_IS_STRING *
5419 (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
5420
5421 // Add a third button if necessary.
5422 if (showDebugButton)
5423 buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
5424
5425 bool checkboxValue = false;
5426 int32_t buttonPressed = 0; // In case the user exits dialog by clicking X.
5427 {
5428 // Null out the operation callback while we're re-entering JS here.
5429 AutoDisableJSInterruptCallback disabler(aCx);
5430
5431 // Open the dialog.
5432 rv = prompt->ConfirmEx(
5433 title.get(), msg.get(), buttonFlags, waitButton.get(), stopButton.get(),
5434 debugButton.get(), checkboxMsg.get(), &checkboxValue, &buttonPressed);
5435 }
5436
5437 if (buttonPressed == 0) {
5438 if (checkboxValue && !isAddonScript && NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))))
5439 return AlwaysContinueSlowScript;
5440 return ContinueSlowScript;
5441 }
5442
5443 if (buttonPressed == 2) {
5444 MOZ_RELEASE_ASSERT(debugCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(debugCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(debugCallback))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("debugCallback",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5444
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "debugCallback"
")"); do { MOZ_CrashSequence(__null, 5444); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5445
5446 rv = debugCallback->HandleSlowScriptDebug(this);
5447 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) ? ContinueSlowScript : KillSlowScript;
5448 }
5449
5450 JS_ClearPendingException(aCx);
5451
5452 return KillSlowScript;
5453}
5454
5455nsresult nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic,
5456 const char16_t* aData) {
5457 if (!nsCRT::strcmp(aTopic, "audio-playback")) {
5458 if (ToSupports(GetOuterWindow()) != aSubject) {
5459 return NS_OK;
5460 }
5461 AUTO_PROFILER_MARKER_UNTYPED("audio-playback", DOM, {})AutoProfilerUntypedMarker raiiObject5461( "audio-playback", ::
mozilla::baseprofiler::category::DOM, {})
;
5462
5463 nsGlobalWindowOuter* outer =
5464 nsGlobalWindowOuter::Cast(nsPIDOMWindowOuter::From(GetOuterWindow())
5465 ->GetInProcessScriptableTop());
5466 nsGlobalWindowInner* topInnerWindow =
5467 outer ? nsGlobalWindowInner::Cast(outer->GetCurrentInnerWindow())
5468 : nullptr;
5469
5470 if (topInnerWindow) {
5471 const bool isPlayingAudio{IsPlayingAudio()};
5472 topInnerWindow->AudioPlaybackChanged(isPlayingAudio);
5473 topInnerWindow->CallOnInProcessDescendants(
5474 &nsGlobalWindowInner::AudioPlaybackChanged, isPlayingAudio);
5475 }
5476
5477 return NS_OK;
5478 }
5479
5480 if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed")) {
5481 if (!IsFrozen()) {
5482 // Fires an offline status event if the offline status has changed
5483 FireOfflineStatusEventIfChanged();
5484 }
5485 return NS_OK;
5486 }
5487
5488 if (!nsCRT::strcmp(aTopic, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure")) {
5489 if (mPerformance) {
5490 mPerformance->MemoryPressure();
5491 }
5492 RemoveReportRecords();
5493 return NS_OK;
5494 }
5495
5496 if (!nsCRT::strcmp(aTopic, PERMISSION_CHANGED_TOPIC"perm-changed") ||
5497 !nsCRT::strcmp(aTopic, "browser-perm-changed")) {
5498 bool isBrowserPerm = !nsCRT::strcmp(aTopic, "browser-perm-changed");
5499
5500 nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject));
5501 if (!perm) {
5502 // Bulk browser permission clear — subject is an nsISupportsPRUint64
5503 // carrying the browserId. Only process if this window belongs to that
5504 // tab.
5505 if (isBrowserPerm) {
5506 nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
5507 if (wrapper) {
5508 uint64_t clearedBrowserId = 0;
5509 wrapper->GetData(&clearedBrowserId);
5510 if (clearedBrowserId) {
5511 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5512 if (!bc || bc->Top()->BrowserId() != clearedBrowserId) {
5513 return NS_OK;
5514 }
5515 }
5516 }
5517 }
5518 UpdatePermissions();
5519 if (mDoc) {
5520 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5521 mDoc->GetPermissionDelegateHandler();
5522 if (permDelegateHandler) {
5523 permDelegateHandler->PopulateAllDelegatedPermissions();
5524 }
5525 }
5526 return NS_OK;
5527 }
5528
5529 if (isBrowserPerm) {
5530 uint64_t permBrowserId = 0;
5531 perm->GetBrowserId(&permBrowserId);
5532 if (!permBrowserId) {
5533 return NS_OK;
5534 }
5535 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5536 if (!bc || bc->Top()->BrowserId() != permBrowserId) {
5537 return NS_OK;
5538 }
5539 }
5540
5541 nsAutoCString type;
5542 perm->GetType(type);
5543 if (type == "autoplay-media"_ns) {
5544 UpdateAutoplayPermission();
5545 } else if (type == "shortcuts"_ns) {
5546 UpdateShortcutsPermission();
5547 } else if (type == "popup"_ns) {
5548 UpdatePopupPermission();
5549 }
5550
5551 if (!mDoc) {
5552 return NS_OK;
5553 }
5554
5555 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5556 mDoc->GetPermissionDelegateHandler();
5557
5558 if (permDelegateHandler) {
5559 permDelegateHandler->UpdateDelegatedPermission(type);
5560 }
5561
5562 return NS_OK;
5563 }
5564
5565 if (!nsCRT::strcmp(aTopic, "screen-information-changed")) {
5566 if (mScreen) {
5567 if (RefPtr<ScreenOrientation> orientation =
5568 mScreen->GetOrientationIfExists()) {
5569 orientation->MaybeChanged();
5570 }
5571 }
5572 if (mHasOrientationChangeListeners) {
5573 int32_t oldAngle = mOrientationAngle;
5574 mOrientationAngle = Orientation(CallerType::System);
5575 if (mOrientationAngle != oldAngle && IsCurrentInnerWindow()) {
5576 nsCOMPtr<nsPIDOMWindowOuter> outer = GetOuterWindow();
5577 outer->DispatchCustomEvent(u"orientationchange"_ns);
5578 }
5579 }
5580 return NS_OK;
5581 }
5582
5583 if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
5584 MOZ_ASSERT(!NS_strcmp(aData, u"intl.accept_languages"))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_strcmp(aData, u"intl.accept_languages"))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!NS_strcmp(aData, u"intl.accept_languages")))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!NS_strcmp(aData, u\"intl.accept_languages\")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5584
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aData, u\"intl.accept_languages\")"
")"); do { MOZ_CrashSequence(__null, 5584); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5585
5586 // The user preferred languages have changed, we need to fire an event on
5587 // Window object and invalidate the cache for navigator.languages. It is
5588 // done for every change which can be a waste of cycles but those should be
5589 // fairly rare.
5590 // We MUST invalidate navigator.languages before sending the event in the
5591 // very likely situation where an event handler will try to read its value.
5592
5593 if (mNavigator) {
5594 Navigator_Binding::ClearCachedLanguageValue(mNavigator);
5595 Navigator_Binding::ClearCachedLanguagesValue(mNavigator);
5596 }
5597
5598 // The event has to be dispatched only to the current inner window.
5599 if (!IsCurrentInnerWindow()) {
5600 return NS_OK;
5601 }
5602
5603 RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
5604 event->InitEvent(u"languagechange"_ns, false, false);
5605 event->SetTrusted(true);
5606
5607 ErrorResult rv;
5608 DispatchEvent(*event, rv);
5609 return rv.StealNSResult();
5610 }
5611
5612 NS_WARNING(nsPrintfCString("unrecognized topic %s", aTopic).get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("unrecognized topic %s"
, aTopic).get(), nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5612)
;
5613 return NS_ERROR_FAILURE;
5614}
5615
5616void nsGlobalWindowInner::ObserveStorageNotification(
5617 StorageEvent* aEvent, const char16_t* aStorageType, bool aPrivateBrowsing) {
5618 MOZ_ASSERT(aEvent)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aEvent)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aEvent))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aEvent", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5618); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEvent" ")"
); do { MOZ_CrashSequence(__null, 5618); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5619
5620 // The private browsing check must be done here again because this window
5621 // could have changed its state before the notification check and now. This
5622 // happens in case this window did have a docShell at that time.
5623 if (aPrivateBrowsing != IsPrivateBrowsing()) {
5624 return;
5625 }
5626
5627 // LocalStorage can only exist on an inner window, and we don't want to
5628 // generate events on frozen or otherwise-navigated-away from windows.
5629 // (Actually, this code used to try and buffer events for frozen windows,
5630 // but it never worked, so we've removed it. See bug 1285898.)
5631 if (!IsCurrentInnerWindow() || IsFrozen()) {
5632 return;
5633 }
5634
5635 nsIPrincipal* principal = GetPrincipal();
5636 if (!principal) {
5637 return;
5638 }
5639
5640 bool fireMozStorageChanged = false;
5641 nsAutoString eventType;
5642 eventType.AssignLiteral("storage");
5643
5644 if (!NS_strcmp(aStorageType, u"sessionStorage")) {
5645 RefPtr<Storage> changingStorage = aEvent->GetStorageArea();
5646 MOZ_ASSERT(changingStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(changingStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(changingStorage))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("changingStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5646
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "changingStorage" ")"
); do { MOZ_CrashSequence(__null, 5646); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5647
5648 bool check = false;
5649
5650 if (const RefPtr<SessionStorageManager> storageManager =
5651 GetBrowsingContext()->GetSessionStorageManager()) {
5652 nsresult rv = storageManager->CheckStorage(GetEffectiveStoragePrincipal(),
5653 changingStorage, &check);
5654 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5655 return;
5656 }
5657 }
5658
5659 if (!check) {
5660 // This storage event is not coming from our storage or is coming
5661 // from a different docshell, i.e. it is a clone, ignore this event.
5662 return;
5663 }
5664
5665 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5666 gDOMLeakPRLogInner, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5667 ("nsGlobalWindowInner %p with sessionStorage %p passing event from %p",do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
5668 this, mSessionStorage.get(), changingStorage.get()))do { const ::mozilla::LogModule* moz_real_module = gDOMLeakPRLogInner
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsGlobalWindowInner %p with sessionStorage %p passing event from %p"
, this, mSessionStorage.get(), changingStorage.get()); } } while
(0)
;
5669
5670 fireMozStorageChanged = mSessionStorage == changingStorage;
5671 if (fireMozStorageChanged) {
5672 eventType.AssignLiteral("MozSessionStorageChanged");
5673 }
5674 }
5675
5676 else {
5677 MOZ_ASSERT(!NS_strcmp(aStorageType, u"localStorage"))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_strcmp(aStorageType, u"localStorage"))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!NS_strcmp(aStorageType, u"localStorage")))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!NS_strcmp(aStorageType, u\"localStorage\")"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5677
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aStorageType, u\"localStorage\")"
")"); do { MOZ_CrashSequence(__null, 5677); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5678
5679 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5680 if (!storagePrincipal) {
5681 return;
5682 }
5683
5684 MOZ_DIAGNOSTIC_ASSERT(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal
(), storagePrincipal))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(StorageUtils::PrincipalsEqual
(aEvent->GetPrincipal(), storagePrincipal)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5685
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5685); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5685 storagePrincipal))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StorageUtils::PrincipalsEqual(aEvent->GetPrincipal
(), storagePrincipal))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(StorageUtils::PrincipalsEqual
(aEvent->GetPrincipal(), storagePrincipal)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5685
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5685); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5686
5687 fireMozStorageChanged =
5688 mLocalStorage && mLocalStorage == aEvent->GetStorageArea();
5689
5690 if (fireMozStorageChanged) {
5691 eventType.AssignLiteral("MozLocalStorageChanged");
5692 }
5693 }
5694
5695 // Clone the storage event included in the observer notification. We want
5696 // to dispatch clones rather than the original event.
5697 IgnoredErrorResult error;
5698 RefPtr<StorageEvent> clonedEvent =
5699 CloneStorageEvent(eventType, aEvent, error);
5700 if (error.Failed() || !clonedEvent) {
5701 return;
5702 }
5703
5704 clonedEvent->SetTrusted(true);
5705
5706 if (fireMozStorageChanged) {
5707 WidgetEvent* internalEvent = clonedEvent->WidgetEventPtr();
5708 internalEvent->mFlags.mOnlyChromeDispatch = true;
5709 }
5710
5711 DispatchEvent(*clonedEvent);
5712}
5713
5714already_AddRefed<StorageEvent> nsGlobalWindowInner::CloneStorageEvent(
5715 const nsAString& aType, const RefPtr<StorageEvent>& aEvent,
5716 ErrorResult& aRv) {
5717 StorageEventInit dict;
5718
5719 dict.mBubbles = aEvent->Bubbles();
5720 dict.mCancelable = aEvent->Cancelable();
5721 aEvent->GetKey(dict.mKey);
5722 aEvent->GetOldValue(dict.mOldValue);
5723 aEvent->GetNewValue(dict.mNewValue);
5724 aEvent->GetUrl(dict.mUrl);
5725
5726 RefPtr<Storage> storageArea = aEvent->GetStorageArea();
5727
5728 RefPtr<Storage> storage;
5729
5730 // If null, this is a localStorage event received by IPC.
5731 if (!storageArea) {
5732 storage = GetLocalStorage(aRv);
5733 if (!NextGenLocalStorageEnabled()) {
5734 if (aRv.Failed() || !storage) {
5735 return nullptr;
5736 }
5737
5738 if (storage->Type() == Storage::eLocalStorage) {
5739 RefPtr<LocalStorage> localStorage =
5740 static_cast<LocalStorage*>(storage.get());
5741
5742 // We must apply the current change to the 'local' localStorage.
5743 localStorage->ApplyEvent(aEvent);
5744 }
5745 }
5746 } else if (storageArea->Type() == Storage::eSessionStorage) {
5747 storage = GetSessionStorage(aRv);
5748 } else {
5749 MOZ_ASSERT(storageArea->Type() == Storage::eLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(storageArea->Type() == Storage::eLocalStorage)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(storageArea->Type() == Storage::eLocalStorage))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("storageArea->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5749
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storageArea->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 5749); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5750 storage = GetLocalStorage(aRv);
5751 }
5752
5753 if (aRv.Failed() || !storage) {
5754 return nullptr;
5755 }
5756
5757 if (storage->Type() == Storage::ePartitionedLocalStorage) {
5758 // This error message is not exposed.
5759 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
5760 return nullptr;
5761 }
5762
5763 MOZ_ASSERT(storage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(storage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(storage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("storage", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5763); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage" ")"
); do { MOZ_CrashSequence(__null, 5763); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5764 MOZ_ASSERT_IF(storageArea, storage->IsForkOf(storageArea))do { if (storageArea) { do { static_assert( mozilla::detail::
AssertionConditionType<decltype(storage->IsForkOf(storageArea
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(storage->IsForkOf(storageArea)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("storage->IsForkOf(storageArea)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5764
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage->IsForkOf(storageArea)"
")"); do { MOZ_CrashSequence(__null, 5764); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5765
5766 dict.mStorageArea = storage;
5767
5768 RefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict);
5769 return event.forget();
5770}
5771
5772void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
5773 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5773
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5773); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5774
5775 // We can only safely suspend windows that are the current inner window. If
5776 // its not the current inner, then we are in one of two different cases.
5777 // Either we are in the bfcache or we are doomed window that is going away.
5778 // When a window becomes inactive we purposely avoid placing already suspended
5779 // windows into the bfcache. It only expects windows suspended due to the
5780 // Freeze() method which occurs while the window is still the current inner.
5781 // So we must not call Suspend() on bfcache windows at this point or this
5782 // invariant will be broken. If the window is doomed there is no point in
5783 // suspending it since it will soon be gone.
5784 if (!IsCurrentInnerWindow()) {
5785 return;
5786 }
5787
5788 // All in-process descendants are also suspended. This ensure mSuspendDepth
5789 // is set properly and the timers are properly canceled for each in-process
5790 // descendant.
5791 if (aIncludeSubWindows) {
5792 CallOnInProcessDescendants(&nsGlobalWindowInner::Suspend, false);
5793 }
5794
5795 mSuspendDepth += 1;
5796 if (mSuspendDepth != 1) {
5797 return;
5798 }
5799
5800 if (mWindowGlobalChild) {
5801 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED);
5802 }
5803
5804 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5805 if (ac) {
5806 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5807 ac->RemoveWindowListener(mEnabledSensors[i], this);
5808 }
5809 DisableGamepadUpdates();
5810 DisableVRUpdates();
5811
5812 SuspendWorkersForWindow(*this);
5813
5814 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5815 mSharedWorkers.ForwardRange()) {
5816 pinnedWorker->Suspend();
5817 }
5818
5819 SuspendIdleRequests();
5820
5821 mTimeoutManager->Suspend();
5822
5823 // Suspend all of the AudioContexts for this window
5824 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5825 mAudioContexts[i]->SuspendFromChrome();
5826 }
5827}
5828
5829void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
5830 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5830
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5830); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5831
5832 // We can only safely resume a window if its the current inner window. If
5833 // its not the current inner, then we are in one of two different cases.
5834 // Either we are in the bfcache or we are doomed window that is going away.
5835 // If a window is suspended when it becomes inactive we purposely do not
5836 // put it in the bfcache, so Resume should never be needed in that case.
5837 // If the window is doomed then there is no point in resuming it.
5838 if (!IsCurrentInnerWindow()) {
5839 return;
5840 }
5841
5842 // Resume all in-process descendants. This restores timers recursively
5843 // canceled in Suspend() and ensures all in-process descendants have the
5844 // correct mSuspendDepth.
5845 if (aIncludeSubWindows) {
5846 CallOnInProcessDescendants(&nsGlobalWindowInner::Resume, false);
5847 }
5848
5849 if (mSuspendDepth == 0) {
5850 // Ignore if the window is not suspended.
5851 return;
5852 }
5853
5854 mSuspendDepth -= 1;
5855
5856 if (mSuspendDepth != 0) {
5857 return;
5858 }
5859
5860 // We should not be able to resume a frozen window. It must be Thaw()'d
5861 // first.
5862 MOZ_ASSERT(mFreezeDepth == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFreezeDepth == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mFreezeDepth == 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mFreezeDepth == 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5862
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth == 0"
")"); do { MOZ_CrashSequence(__null, 5862); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5863
5864 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5865 if (ac) {
5866 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5867 ac->AddWindowListener(mEnabledSensors[i], this);
5868 }
5869 EnableGamepadUpdates();
5870 EnableVRUpdates();
5871
5872 // Resume all of the AudioContexts for this window
5873 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5874 mAudioContexts[i]->ResumeFromChrome();
5875 }
5876
5877 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
5878 devices->WindowResumed();
5879 }
5880
5881 mTimeoutManager->Resume();
5882
5883 ResumeIdleRequests();
5884
5885 // Resume all of the workers for this window. We must do this
5886 // after timeouts since workers may have queued events that can trigger
5887 // a setTimeout().
5888 ResumeWorkersForWindow(*this);
5889
5890 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5891 mSharedWorkers.ForwardRange()) {
5892 pinnedWorker->Resume();
5893 }
5894
5895 if (mWindowGlobalChild) {
5896 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED);
5897 }
5898}
5899
5900bool nsGlobalWindowInner::IsSuspended() const {
5901 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5901
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5901); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5902 return mSuspendDepth != 0;
5903}
5904
5905void nsGlobalWindowInner::Freeze(bool aIncludeSubWindows) {
5906 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5906
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5906); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5907 Suspend(aIncludeSubWindows);
5908 FreezeInternal(aIncludeSubWindows);
5909}
5910
5911void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) {
5912 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5912
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5912); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5913 MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5913
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5913); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5914 MOZ_DIAGNOSTIC_ASSERT(IsSuspended())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5914
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5914); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5915
5916 HintIsLoading(false);
5917
5918 if (aIncludeSubWindows) {
5919 CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal,
5920 aIncludeSubWindows);
5921 }
5922
5923 mFreezeDepth += 1;
5924 MOZ_ASSERT(mSuspendDepth >= mFreezeDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSuspendDepth >= mFreezeDepth)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSuspendDepth >= mFreezeDepth
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mSuspendDepth >= mFreezeDepth", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5924); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5924); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5925 if (mFreezeDepth != 1) {
5926 return;
5927 }
5928
5929 FreezeWorkersForWindow(*this);
5930
5931 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5932 mSharedWorkers.ForwardRange()) {
5933 pinnedWorker->Freeze();
5934 }
5935
5936 mTimeoutManager->Freeze();
5937 if (mClientSource) {
5938 mClientSource->Freeze();
5939 }
5940
5941 NotifyGlobalFrozen();
5942}
5943
5944void nsGlobalWindowInner::Thaw(bool aIncludeSubWindows) {
5945 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5945
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5945); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5946 ThawInternal(aIncludeSubWindows);
5947 Resume(aIncludeSubWindows);
5948}
5949
5950void nsGlobalWindowInner::ThawInternal(bool aIncludeSubWindows) {
5951 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5951
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5951); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5952 MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5952
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5952); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5953 MOZ_DIAGNOSTIC_ASSERT(IsSuspended())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5953
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5953); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5954
5955 if (aIncludeSubWindows) {
5956 CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal,
5957 aIncludeSubWindows);
5958 }
5959
5960 MOZ_ASSERT(mFreezeDepth != 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFreezeDepth != 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mFreezeDepth != 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mFreezeDepth != 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5960
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth != 0"
")"); do { MOZ_CrashSequence(__null, 5960); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5961 mFreezeDepth -= 1;
5962 MOZ_ASSERT(mSuspendDepth >= mFreezeDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSuspendDepth >= mFreezeDepth)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mSuspendDepth >= mFreezeDepth
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mSuspendDepth >= mFreezeDepth", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5962); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5962); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5963 if (mFreezeDepth != 0) {
5964 return;
5965 }
5966
5967 if (mClientSource) {
5968 mClientSource->Thaw();
5969 }
5970 mTimeoutManager->Thaw();
5971
5972 ThawWorkersForWindow(*this);
5973
5974 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5975 mSharedWorkers.ForwardRange()) {
5976 pinnedWorker->Thaw();
5977 }
5978
5979 NotifyGlobalThawed();
5980}
5981
5982bool nsGlobalWindowInner::IsFrozen() const {
5983 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5983
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5983); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5984 bool frozen = mFreezeDepth != 0;
5985 MOZ_ASSERT_IF(frozen, IsSuspended())do { if (frozen) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(IsSuspended())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsSuspended()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("IsSuspended()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5985
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsSuspended()" ")"
); do { MOZ_CrashSequence(__null, 5985); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5986 return frozen;
5987}
5988
5989void nsGlobalWindowInner::SyncStateFromParentWindow() {
5990 // This method should only be called on an inner window that has been
5991 // assigned to an outer window already.
5992 MOZ_ASSERT(IsCurrentInnerWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsCurrentInnerWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsCurrentInnerWindow()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("IsCurrentInnerWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 5992
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5992); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5993 nsPIDOMWindowOuter* outer = GetOuterWindow();
5994 MOZ_ASSERT(outer)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(outer)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(outer))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("outer", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outer" ")")
; do { MOZ_CrashSequence(__null, 5994); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5995
5996 // Attempt to find our parent windows.
5997 nsCOMPtr<Element> frame = outer->GetFrameElementInternal();
5998 nsPIDOMWindowOuter* parentOuter =
5999 frame ? frame->OwnerDoc()->GetWindow() : nullptr;
6000 nsGlobalWindowInner* parentInner =
6001 parentOuter
6002 ? nsGlobalWindowInner::Cast(parentOuter->GetCurrentInnerWindow())
6003 : nullptr;
6004
6005 // If our outer is in a modal state, but our parent is not in a modal
6006 // state, then we must apply the suspend directly. If our parent is
6007 // in a modal state then we should get the suspend automatically
6008 // via the parentSuspendDepth application below.
6009 if ((!parentInner || !parentInner->IsInModalState()) && IsInModalState()) {
6010 Suspend();
6011 }
6012
6013 uint32_t parentFreezeDepth = parentInner ? parentInner->mFreezeDepth : 0;
6014 uint32_t parentSuspendDepth = parentInner ? parentInner->mSuspendDepth : 0;
6015
6016 // Since every Freeze() calls Suspend(), the suspend count must
6017 // be equal or greater to the freeze count.
6018 MOZ_ASSERT(parentFreezeDepth <= parentSuspendDepth)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(parentFreezeDepth <= parentSuspendDepth)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(parentFreezeDepth <= parentSuspendDepth))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("parentFreezeDepth <= parentSuspendDepth"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6018
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "parentFreezeDepth <= parentSuspendDepth"
")"); do { MOZ_CrashSequence(__null, 6018); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6019
6020 // First apply the Freeze() calls.
6021 for (uint32_t i = 0; i < parentFreezeDepth; ++i) {
6022 Freeze();
6023 }
6024
6025 // Now apply only the number of Suspend() calls to reach the target
6026 // suspend count after applying the Freeze() calls.
6027 for (uint32_t i = 0; i < (parentSuspendDepth - parentFreezeDepth); ++i) {
6028 Suspend();
6029 }
6030}
6031
6032void nsGlobalWindowInner::UpdateBackgroundState() {
6033 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
6034 devices->BackgroundStateChanged();
6035 }
6036 mTimeoutManager->UpdateBackgroundState();
6037
6038 UpdateWorkersBackgroundState(*this, IsBackgroundInternal());
6039}
6040
6041template <typename Method, typename... Args>
6042CallState nsGlobalWindowInner::CallOnInProcessDescendantsInternal(
6043 BrowsingContext* aBrowsingContext, bool aChildOnly, Method aMethod,
6044 Args&&... aArgs) {
6045 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6045
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6045); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6046 MOZ_ASSERT(aBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBrowsingContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aBrowsingContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aBrowsingContext"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6046
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 6046); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6047
6048 CallState state = CallState::Continue;
6049 for (const RefPtr<BrowsingContext>& bc : aBrowsingContext->Children()) {
6050 if (nsCOMPtr<nsPIDOMWindowOuter> pWin = bc->GetDOMWindow()) {
6051 auto* win = nsGlobalWindowOuter::Cast(pWin);
6052 if (nsGlobalWindowInner* inner =
6053 nsGlobalWindowInner::Cast(win->GetCurrentInnerWindow())) {
6054 // Call the descendant method using our helper CallDescendant() template
6055 // method. This allows us to handle both void returning methods and
6056 // methods that return CallState explicitly. For void returning methods
6057 // we assume CallState::Continue.
6058 using returnType = decltype((inner->*aMethod)(aArgs...));
6059 state = CallDescendant<returnType>(inner, aMethod, aArgs...);
6060
6061 if (state == CallState::Stop) {
6062 return state;
6063 }
6064 }
6065 }
6066
6067 if (!aChildOnly) {
6068 state = CallOnInProcessDescendantsInternal(bc.get(), aChildOnly, aMethod,
6069 aArgs...);
6070 if (state == CallState::Stop) {
6071 return state;
6072 }
6073 }
6074 }
6075
6076 return state;
6077}
6078
6079nsIURI* nsGlobalWindowInner::GetBaseURI() const { return GetDocBaseURI(); }
6080
6081Maybe<ClientInfo> nsGlobalWindowInner::GetClientInfo() const {
6082 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6082
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6082); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6083 if (mDoc && mDoc->IsStaticDocument()) {
6084 if (Maybe<ClientInfo> info = mDoc->GetOriginalDocument()->GetClientInfo()) {
6085 return info;
6086 }
6087 }
6088
6089 Maybe<ClientInfo> clientInfo;
6090 if (mClientSource) {
6091 clientInfo.emplace(mClientSource->Info());
6092 }
6093 return clientInfo;
6094}
6095
6096Maybe<ClientState> nsGlobalWindowInner::GetClientState() const {
6097 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6097
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6097); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6098 if (mDoc && mDoc->IsStaticDocument()) {
6099 if (Maybe<ClientState> state =
6100 mDoc->GetOriginalDocument()->GetClientState()) {
6101 return state;
6102 }
6103 }
6104
6105 Maybe<ClientState> clientState;
6106 if (mClientSource) {
6107 Result<ClientState, ErrorResult> res = mClientSource->SnapshotState();
6108 if (res.isOk()) {
6109 clientState.emplace(res.unwrap());
6110 } else {
6111 res.unwrapErr().SuppressException();
6112 }
6113 }
6114 return clientState;
6115}
6116
6117Maybe<ServiceWorkerDescriptor> nsGlobalWindowInner::GetController() const {
6118 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6118
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6118); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6119 if (mDoc && mDoc->IsStaticDocument()) {
6120 if (Maybe<ServiceWorkerDescriptor> controller =
6121 mDoc->GetOriginalDocument()->GetController()) {
6122 return controller;
6123 }
6124 }
6125
6126 Maybe<ServiceWorkerDescriptor> controller;
6127 if (mClientSource) {
6128 controller = mClientSource->GetController();
6129 }
6130 return controller;
6131}
6132
6133void nsGlobalWindowInner::SetPolicyContainer(
6134 nsIPolicyContainer* aPolicyContainer) {
6135 if (!mClientSource) {
6136 return;
6137 }
6138 mClientSource->SetPolicyContainer(aPolicyContainer);
6139 // Also cache the PolicyContainer within the document
6140 mDoc->SetPolicyContainer(aPolicyContainer);
6141
6142 if (mWindowGlobalChild) {
6143 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6144 }
6145}
6146
6147nsIPolicyContainer* nsGlobalWindowInner::GetPolicyContainer() {
6148 if (mDoc) {
6149 return mDoc->GetPolicyContainer();
6150 }
6151
6152 // If the window is partially torn down and has its document nulled out,
6153 // we query the policy container we snapshot in FreeInnerObjects.
6154 if (mDocumentPolicyContainer) {
6155 return mDocumentPolicyContainer;
6156 }
6157 return nullptr;
6158}
6159
6160void nsGlobalWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
6161 if (!mClientSource) {
6162 return;
6163 }
6164 mClientSource->SetPreloadCsp(aPreloadCsp);
6165 // Also cache the preload CSP within the document
6166 mDoc->SetPreloadCsp(aPreloadCsp);
6167
6168 if (mWindowGlobalChild) {
6169 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6170 }
6171}
6172
6173already_AddRefed<ServiceWorkerContainer>
6174nsGlobalWindowInner::GetServiceWorkerContainer() {
6175 return Navigator()->ServiceWorker();
6176}
6177
6178RefPtr<ServiceWorker> nsGlobalWindowInner::GetOrCreateServiceWorker(
6179 const ServiceWorkerDescriptor& aDescriptor) {
6180 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6180
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6180); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6181 RefPtr<ServiceWorker> ref;
6182 ForEachGlobalTeardownObserver(
6183 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6184 RefPtr<ServiceWorker> sw = do_QueryObject(aObserver);
6185 if (!sw || !sw->Descriptor().Matches(aDescriptor)) {
6186 return;
6187 }
6188
6189 ref = std::move(sw);
6190 *aDoneOut = true;
6191 });
6192
6193 if (!ref) {
6194 ref = ServiceWorker::Create(this, aDescriptor);
6195 }
6196
6197 return ref;
6198}
6199
6200RefPtr<mozilla::dom::ServiceWorkerRegistration>
6201nsGlobalWindowInner::GetServiceWorkerRegistration(
6202 const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor)
6203 const {
6204 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6204
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6204); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6205 RefPtr<ServiceWorkerRegistration> ref;
6206 ForEachGlobalTeardownObserver(
6207 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6208 RefPtr<ServiceWorkerRegistration> swr = do_QueryObject(aObserver);
6209 if (!swr || !swr->MatchesDescriptor(aDescriptor)) {
6210 return;
6211 }
6212
6213 ref = std::move(swr);
6214 *aDoneOut = true;
6215 });
6216 return ref;
6217}
6218
6219RefPtr<ServiceWorkerRegistration>
6220nsGlobalWindowInner::GetOrCreateServiceWorkerRegistration(
6221 const ServiceWorkerRegistrationDescriptor& aDescriptor) {
6222 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6222
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6222); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6223 RefPtr<ServiceWorkerRegistration> ref =
6224 GetServiceWorkerRegistration(aDescriptor);
6225 if (!ref) {
6226 ref = ServiceWorkerRegistration::CreateForMainThread(this, aDescriptor);
6227 }
6228 return ref;
6229}
6230
6231StorageAccess nsGlobalWindowInner::GetStorageAccess() {
6232 return StorageAllowedForWindow(this);
6233}
6234
6235nsICookieJarSettings* nsGlobalWindowInner::GetCookieJarSettings() {
6236 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6236
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6236); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6237 if (mDoc) {
6238 return mDoc->CookieJarSettings();
6239 }
6240 return nullptr;
6241}
6242
6243nsresult nsGlobalWindowInner::FireDelayedDOMEvents(bool aIncludeSubWindows) {
6244 // Fires an offline status event if the offline status has changed
6245 FireOfflineStatusEventIfChanged();
6246
6247 if (mCookieStore) {
6248 mCookieStore->FireDelayedDOMEvents();
6249 }
6250
6251 if (!aIncludeSubWindows) {
6252 return NS_OK;
6253 }
6254
6255 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
6256 if (docShell) {
6257 int32_t childCount = 0;
6258 docShell->GetInProcessChildCount(&childCount);
6259
6260 // Take a copy of the current children so that modifications to
6261 // the child list don't affect to the iteration.
6262 AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> children;
6263 for (int32_t i = 0; i < childCount; ++i) {
6264 nsCOMPtr<nsIDocShellTreeItem> childShell;
6265 docShell->GetInProcessChildAt(i, getter_AddRefs(childShell));
6266 if (childShell) {
6267 children.AppendElement(childShell);
6268 }
6269 }
6270
6271 for (const nsCOMPtr<nsIDocShellTreeItem>& childShell : children) {
6272 if (const RefPtr<nsGlobalWindowOuter> win =
6273 nsGlobalWindowOuter::Cast(childShell->GetWindow())) {
6274 win->FireDelayedDOMEvents(true);
6275 }
6276 }
6277 }
6278
6279 return NS_OK;
6280}
6281
6282//*****************************************************************************
6283// nsGlobalWindowInner: Window Control Functions
6284//*****************************************************************************
6285
6286nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessParentInternal() {
6287 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6288 if (!outer) {
6289 // No outer window available!
6290 return nullptr;
6291 }
6292 return outer->GetInProcessParentInternal();
6293}
6294
6295nsIPrincipal* nsGlobalWindowInner::GetTopLevelAntiTrackingPrincipal() {
6296 nsPIDOMWindowOuter* outerWindow = GetOuterWindowInternal();
6297 if (!outerWindow) {
6298 return nullptr;
6299 }
6300
6301 nsPIDOMWindowOuter* topLevelOuterWindow =
6302 GetBrowsingContext()->Top()->GetDOMWindow();
6303 if (!topLevelOuterWindow) {
6304 return nullptr;
6305 }
6306
6307 bool stopAtOurLevel =
6308 mDoc && mDoc->CookieJarSettings()->GetCookieBehavior() ==
6309 nsICookieService::BEHAVIOR_REJECT_TRACKER;
6310
6311 if (stopAtOurLevel && topLevelOuterWindow == outerWindow) {
6312 return nullptr;
6313 }
6314
6315 nsPIDOMWindowInner* topLevelInnerWindow =
6316 topLevelOuterWindow->GetCurrentInnerWindow();
6317 if (NS_WARN_IF(!topLevelInnerWindow)NS_warn_if_impl(!topLevelInnerWindow, "!topLevelInnerWindow",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6317
)
) {
6318 return nullptr;
6319 }
6320
6321 nsIPrincipal* topLevelPrincipal =
6322 nsGlobalWindowInner::Cast(topLevelInnerWindow)->GetPrincipal();
6323 if (NS_WARN_IF(!topLevelPrincipal)NS_warn_if_impl(!topLevelPrincipal, "!topLevelPrincipal", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6323)
) {
6324 return nullptr;
6325 }
6326
6327 return topLevelPrincipal;
6328}
6329
6330nsIPrincipal* nsGlobalWindowInner::GetClientPrincipal() {
6331 return mClientSource ? mClientSource->GetPrincipal() : nullptr;
6332}
6333
6334bool nsGlobalWindowInner::IsInFullScreenTransition() {
6335 if (!mIsChrome) {
6336 return false;
6337 }
6338
6339 nsGlobalWindowOuter* outerWindow = GetOuterWindowInternal();
6340 if (!outerWindow) {
6341 return false;
6342 }
6343
6344 return outerWindow->mIsInFullScreenTransition;
6345}
6346
6347//*****************************************************************************
6348// nsGlobalWindowInner: Timeout Functions
6349//*****************************************************************************
6350
6351class WindowScriptTimeoutHandler final : public ScriptTimeoutHandler {
6352 public:
6353 NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override;
6354 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WindowScriptTimeoutHandler,class cycleCollection : public ScriptTimeoutHandler::cycleCollection
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : ScriptTimeoutHandler::cycleCollection(aFlags) {} private:
public: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "WindowScriptTimeoutHandler"; }; static WindowScriptTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<WindowScriptTimeoutHandler
*>(static_cast<ScriptTimeoutHandler*>( ScriptTimeoutHandler
::cycleCollection::Downcast(s))); } virtual void Unlink(void*
p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &WindowScriptTimeoutHandler::
_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() override clang diagnostic pop { nsXPCOMCycleCollectionParticipant
* p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
6355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6355); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6355 ScriptTimeoutHandler)class cycleCollection : public ScriptTimeoutHandler::cycleCollection
{ public: constexpr explicit cycleCollection(Flags aFlags = 0
) : ScriptTimeoutHandler::cycleCollection(aFlags) {} private:
public: virtual nsresult TraverseNative(void* p, nsCycleCollectionTraversalCallback
& cb) override; virtual const char* ClassName() override {
return "WindowScriptTimeoutHandler"; }; static WindowScriptTimeoutHandler
* Downcast(nsISupports* s) { return static_cast<WindowScriptTimeoutHandler
*>(static_cast<ScriptTimeoutHandler*>( ScriptTimeoutHandler
::cycleCollection::Downcast(s))); } virtual void Unlink(void*
p) override; static constexpr nsXPCOMCycleCollectionParticipant
* GetParticipant() { return &WindowScriptTimeoutHandler::
_cycleCollectorGlobal; } }; clang diagnostic push clang diagnostic
ignored "-Wunnecessary-virtual-specifier" virtual void CheckForRightParticipant
() override clang diagnostic pop { nsXPCOMCycleCollectionParticipant
* p; CallQueryInterface(this, &p); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(p == &_cycleCollectorGlobal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(p == &_cycleCollectorGlobal))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("p == &_cycleCollectorGlobal"
" (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
6355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6355); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6356
6357 WindowScriptTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal,
6358 const nsAString& aExpression)
6359 : ScriptTimeoutHandler(aCx, aGlobal, aExpression),
6360 mInitiatingScriptFetchInfo(
6361 ScriptLoader::GetActiveScriptFetchInfo(aCx)) {}
6362
6363 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* aExecutionReason) override;
6364
6365 private:
6366 virtual ~WindowScriptTimeoutHandler() = default;
6367
6368 // Initiating script's referrer info for use when evaluating mExpr on the main
6369 // thread.
6370 RefPtr<JS::loader::ScriptFetchInfo> mInitiatingScriptFetchInfo;
6371};
6372
6373NS_IMPL_CYCLE_COLLECTION_INHERITED(WindowScriptTimeoutHandler,WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6374 ScriptTimeoutHandler,WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6375 mInitiatingScriptFetchInfo)WindowScriptTimeoutHandler::cycleCollection WindowScriptTimeoutHandler
::_cycleCollectorGlobal; void WindowScriptTimeoutHandler::cycleCollection
::Unlink(void* p) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); ScriptTimeoutHandler::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mInitiatingScriptFetchInfo
); (void)tmp; } nsresult WindowScriptTimeoutHandler::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { WindowScriptTimeoutHandler* tmp = DowncastCCParticipant
<WindowScriptTimeoutHandler>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (ScriptTimeoutHandler::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mInitiatingScriptFetchInfo, "mInitiatingScriptFetchInfo"
, 0); (void)tmp; return NS_OK; }
6376
6377NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowScriptTimeoutHandler)nsresult WindowScriptTimeoutHandler::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6377); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= WindowScriptTimeoutHandler::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = WindowScriptTimeoutHandler::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
6378NS_INTERFACE_MAP_END_INHERITING(ScriptTimeoutHandler)foundInterface = 0; nsresult status; if (!foundInterface) status
= ScriptTimeoutHandler::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
6379
6380NS_IMPL_ADDREF_INHERITED(WindowScriptTimeoutHandler, ScriptTimeoutHandler)MozExternalRefCountType WindowScriptTimeoutHandler::AddRef(void
) { static_assert(!std::is_destructible_v<WindowScriptTimeoutHandler
>, "Reference-counted class " "WindowScriptTimeoutHandler"
" should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = ScriptTimeoutHandler::AddRef(); if constexpr (
::mozilla::detail::ShouldLogInheritedRefcnt<WindowScriptTimeoutHandler
>) { NS_LogAddRef((this), (r), ("WindowScriptTimeoutHandler"
), (uint32_t)(sizeof(*this))); } return r; }
6381NS_IMPL_RELEASE_INHERITED(WindowScriptTimeoutHandler, ScriptTimeoutHandler)MozExternalRefCountType WindowScriptTimeoutHandler::Release(void
) { nsrefcnt r = ScriptTimeoutHandler::Release(); if constexpr
(::mozilla::detail::ShouldLogInheritedRefcnt<WindowScriptTimeoutHandler
>) { NS_LogRelease((this), (r), ("WindowScriptTimeoutHandler"
)); } return r; }
6382
6383bool WindowScriptTimeoutHandler::Call(const char* aExecutionReason) {
6384 // New script entry point required, due to the "Create a script" sub-step
6385 // of
6386 // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
6387 nsAutoMicroTask mt;
6388 AutoEntryScript aes(mGlobal, aExecutionReason, true);
6389 JS::CompileOptions options(aes.cx());
6390 options.setFileAndLine(mCaller.FileName().get(), mCaller.mLine);
6391 options.setNoScriptRval(true);
6392 options.setIntroductionType("domTimer");
6393 JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject());
6394 {
6395 if (MOZ_UNLIKELY(!xpc::Scriptability::Get(global).Allowed())(__builtin_expect(!!(!xpc::Scriptability::Get(global).Allowed
()), 0))
) {
6396 return true;
6397 }
6398
6399 IgnoredErrorResult erv;
6400 mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext",
6401 /* dynamicStr */ nullptr,
6402 JS::ProfilingCategoryPair::JS);
6403 JSAutoRealm autoRealm(aes.cx(), global);
6404 RefPtr<JS::Stencil> stencil;
6405 JS::Rooted<JSScript*> script(aes.cx());
6406 Compile(aes.cx(), options, mExpr, stencil, erv);
6407 if (stencil) {
6408 JS::InstantiateOptions instantiateOptions(options);
6409 MOZ_ASSERT(!instantiateOptions.deferDebugMetadata)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!instantiateOptions.deferDebugMetadata)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!instantiateOptions.deferDebugMetadata))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!instantiateOptions.deferDebugMetadata"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6409
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!instantiateOptions.deferDebugMetadata"
")"); do { MOZ_CrashSequence(__null, 6409); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6410 script.set(JS::InstantiateGlobalStencil(aes.cx(), instantiateOptions,
6411 stencil, /* storage */ nullptr));
6412 if (!script) {
6413 erv.NoteJSContextException(aes.cx());
6414 }
6415 }
6416
6417 if (script) {
6418 MOZ_ASSERT(!erv.Failed())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!erv.Failed())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!erv.Failed()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!erv.Failed()",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6418
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!erv.Failed()" ")"
); do { MOZ_CrashSequence(__null, 6418); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6419 if (mInitiatingScriptFetchInfo) {
6420 mInitiatingScriptFetchInfo->AssociateWithScript(script);
6421 }
6422
6423 if (!JS_ExecuteScript(aes.cx(), script)) {
6424 erv.NoteJSContextException(aes.cx());
6425 }
6426 }
6427
6428 if (erv.IsUncatchableException()) {
6429 return false;
6430 }
6431 }
6432
6433 return true;
6434};
6435
6436nsGlobalWindowInner* nsGlobalWindowInner::InnerForSetTimeoutOrInterval(
6437 ErrorResult& aError) {
6438 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6439 nsPIDOMWindowInner* currentInner =
6440 outer ? outer->GetCurrentInnerWindow() : this;
6441
6442 // If forwardTo is not the window with an active document then we want the
6443 // call to setTimeout/Interval to be a noop, so return null but don't set an
6444 // error.
6445 return HasActiveDocument() ? nsGlobalWindowInner::Cast(currentInner)
6446 : nullptr;
6447}
6448
6449int32_t nsGlobalWindowInner::SetTimeout(
6450 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6451 int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6452 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6453 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, false,
6454 aSubjectPrincipal, aError);
6455}
6456
6457int32_t nsGlobalWindowInner::SetInterval(
6458 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6459 const int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6460 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6461 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, true,
6462 aSubjectPrincipal, aError);
6463}
6464
6465int32_t nsGlobalWindowInner::SetTimeoutOrInterval(
6466 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6467 int32_t aTimeout, const Sequence<JS::Value>& aArguments, bool aIsInterval,
6468 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6469 nsGlobalWindowInner* inner = InnerForSetTimeoutOrInterval(aError);
6470 if (!inner) {
6471 return -1;
6472 }
6473
6474 if (inner != this) {
6475 RefPtr<nsGlobalWindowInner> innerRef(inner);
6476 return innerRef->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments,
6477 aIsInterval, aSubjectPrincipal,
6478 aError);
6479 }
6480
6481 DebuggerNotificationDispatch(
6482 this, aIsInterval ? DebuggerNotificationType::SetInterval
6483 : DebuggerNotificationType::SetTimeout);
6484
6485 if (!GetContextInternal() || !HasJSGlobal()) {
6486 // This window was already closed, or never properly initialized,
6487 // don't let a timer be scheduled on such a window.
6488 return 0;
6489 }
6490
6491 if (aHandler.IsFunction()) {
6492 nsTArray<JS::Heap<JS::Value>> args;
6493 if (!args.AppendElements(aArguments, fallible)) {
6494 aError.Throw(NS_ERROR_OUT_OF_MEMORY);
6495 return 0;
6496 }
6497
6498 RefPtr handler = MakeRefPtr<CallbackTimeoutHandler>(
6499 aCx, this, &aHandler.GetAsFunction(), std::move(args));
6500
6501 int32_t result;
6502 aError = mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6503 Timeout::Reason::eTimeoutOrInterval,
6504 &result);
6505 return result;
6506 }
6507
6508 constexpr nsLiteralString sinkSetTimeout = u"Window setTimeout"_ns;
6509 constexpr nsLiteralString sinkSetInterval = u"Window setInterval"_ns;
6510 Maybe<nsAutoString> compliantStringHolder;
6511 nsCOMPtr<nsIGlobalObject> pinnedGlobal = this;
6512 const nsAString* compliantString =
6513 TrustedTypeUtils::GetTrustedTypesCompliantString(
6514 aHandler, aIsInterval ? sinkSetInterval : sinkSetTimeout,
6515 kTrustedTypesOnlySinkGroup, *pinnedGlobal, aSubjectPrincipal,
6516 compliantStringHolder, aError);
6517 if (aError.Failed()) {
6518 return 0;
6519 }
6520
6521 bool allowEval = false;
6522 aError =
6523 CSPEvalChecker::CheckForWindow(aCx, this, *compliantString, &allowEval);
6524 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6524)
|| !allowEval) {
6525 return 0;
6526 }
6527 RefPtr handler =
6528 MakeRefPtr<WindowScriptTimeoutHandler>(aCx, this, *compliantString);
6529 int32_t result;
6530 aError =
6531 mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6532 Timeout::Reason::eTimeoutOrInterval, &result);
6533 return result;
6534}
6535
6536static const char* GetTimeoutReasonString(Timeout* aTimeout) {
6537 switch (aTimeout->mReason) {
6538 case Timeout::Reason::eTimeoutOrInterval:
6539 if (aTimeout->mIsInterval) {
6540 return "setInterval handler";
6541 }
6542 return "setTimeout handler";
6543 case Timeout::Reason::eIdleCallbackTimeout:
6544 return "setIdleCallback handler (timed out)";
6545 case Timeout::Reason::eAbortSignalTimeout:
6546 return "AbortSignal timeout";
6547 case Timeout::Reason::eDelayedWebTaskTimeout:
6548 return "delayedWebTaskCallback handler (timed out)";
6549 case Timeout::Reason::eJSTimeout:
6550 return "JavaScript TimeoutJob (timed out)";
6551 default:
6552 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6552
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6552); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6553 return "";
6554 }
6555 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6555
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6555); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6556 return "";
6557}
6558
6559bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) {
6560 // Hold on to the timeout in case mExpr or mFunObj releases its
6561 // doc.
6562 // XXXbz Our caller guarantees it'll hold on to the timeout (because
6563 // we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that...
6564 RefPtr<Timeout> timeout = aTimeout;
6565 Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
6566 timeout->mRunning = true;
6567
6568 // Push this timeout's popup control state, which should only be
6569 // enabled the first time a timeout fires that was created while
6570 // popups were enabled and with a delay less than
6571 // "dom.disable_open_click_delay".
6572 AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(timeout->mPopupState);
6573
6574 // Clear the timeout's popup state, if any, to prevent interval
6575 // timeouts from repeatedly opening poups.
6576 timeout->mPopupState = PopupBlocker::openAbused;
6577
6578 uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWindow();
6579 mTimeoutManager->SetNestingLevelForWindow(timeout->mNestingLevel);
6580
6581 const char* reason = GetTimeoutReasonString(timeout);
6582
6583 nsCString str;
6584 if (profiler_thread_is_being_profiled_for_markers()) {
6585 TimeDuration originalInterval = timeout->When() - timeout->SubmitTime();
6586 str.Append(reason);
6587 str.Append(" with interval ");
6588 str.AppendInt(int(originalInterval.ToMilliseconds()));
6589 str.Append("ms: ");
6590 nsCString handlerDescription;
6591 timeout->mScriptHandler->GetDescription(handlerDescription);
6592 str.Append(handlerDescription);
6593 }
6594 AUTO_PROFILER_MARKER_TEXT("setTimeout callback", DOM,AutoProfilerTextMarker raiiObject6598( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6595 MarkerOptions(MarkerStack::TakeBacktrace(AutoProfilerTextMarker raiiObject6598( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6596 timeout->TakeProfilerBacktrace()),AutoProfilerTextMarker raiiObject6598( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6597 MarkerInnerWindowId(mWindowID)),AutoProfilerTextMarker raiiObject6598( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6598 str)AutoProfilerTextMarker raiiObject6598( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
;
6599
6600 bool abortIntervalHandler;
6601 {
6602 RefPtr<TimeoutHandler> handler(timeout->mScriptHandler);
6603
6604 CallbackDebuggerNotificationGuard guard(
6605 this, timeout->mIsInterval
6606 ? DebuggerNotificationType::SetIntervalCallback
6607 : DebuggerNotificationType::SetTimeoutCallback);
6608 abortIntervalHandler = !handler->Call(reason);
6609 }
6610
6611 // If we received an uncatchable exception, do not schedule the timeout again.
6612 // This allows the slow script dialog to break easy DoS attacks like
6613 // setInterval(function() { while(1); }, 100);
6614 if (abortIntervalHandler) {
6615 // If it wasn't an interval timer to begin with, this does nothing. If it
6616 // was, we'll treat it as a timeout that we just ran and discard it when
6617 // we return.
6618 timeout->mIsInterval = false;
6619 }
6620
6621 // We ignore any failures from calling EvaluateString() on the context or
6622 // Call() on a Function here since we're in a loop
6623 // where we're likely to be running timeouts whose OS timers
6624 // didn't fire in time and we don't want to not fire those timers
6625 // now just because execution of one timer failed. We can't
6626 // propagate the error to anyone who cares about it from this
6627 // point anyway, and the script context should have already reported
6628 // the script error in the usual way - so we just drop it.
6629
6630 mTimeoutManager->SetNestingLevelForWindow(nestingLevel);
6631
6632 mTimeoutManager->EndRunningTimeout(last_running_timeout);
6633 timeout->mRunning = false;
6634
6635 return timeout->mCleared;
6636}
6637
6638//*****************************************************************************
6639// nsGlobalWindowInner: Helper Functions
6640//*****************************************************************************
6641
6642already_AddRefed<nsIDocShellTreeOwner> nsGlobalWindowInner::GetTreeOwner() {
6643 FORWARD_TO_OUTER(GetTreeOwner, (), nullptr);
6644}
6645
6646already_AddRefed<nsIWebBrowserChrome>
6647nsGlobalWindowInner::GetWebBrowserChrome() {
6648 nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
6649
6650 nsCOMPtr<nsIWebBrowserChrome> browserChrome = do_GetInterface(treeOwner);
6651 return browserChrome.forget();
6652}
6653
6654ScrollContainerFrame* nsGlobalWindowInner::GetScrollContainerFrame() {
6655 FORWARD_TO_OUTER(GetScrollContainerFrame, (), nullptr);
6656}
6657
6658bool nsGlobalWindowInner::IsPrivateBrowsing() {
6659 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(GetDocShell());
6660 return loadContext && loadContext->UsePrivateBrowsing();
6661}
6662
6663void nsGlobalWindowInner::FlushPendingNotifications(FlushType aType) {
6664 if (mDoc) {
6665 mDoc->FlushPendingNotifications(aType);
6666 }
6667}
6668
6669void nsGlobalWindowInner::EnableDeviceSensor(uint32_t aType) {
6670 bool alreadyEnabled = false;
6671 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6672 if (mEnabledSensors[i] == aType) {
6673 alreadyEnabled = true;
6674 break;
6675 }
6676 }
6677
6678 mEnabledSensors.AppendElement(aType);
6679
6680 if (alreadyEnabled) {
6681 return;
6682 }
6683
6684 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6685 if (ac) {
6686 ac->AddWindowListener(aType, this);
6687 }
6688}
6689
6690void nsGlobalWindowInner::DisableDeviceSensor(uint32_t aType) {
6691 int32_t doomedElement = -1;
6692 int32_t listenerCount = 0;
6693 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6694 if (mEnabledSensors[i] == aType) {
6695 doomedElement = i;
6696 listenerCount++;
6697 }
6698 }
6699
6700 if (doomedElement == -1) {
6701 return;
6702 }
6703
6704 mEnabledSensors.RemoveElementAt(doomedElement);
6705
6706 if (listenerCount > 1) {
6707 return;
6708 }
6709
6710 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6711 if (ac) {
6712 ac->RemoveWindowListener(aType, this);
6713 }
6714}
6715
6716#if defined(MOZ_WIDGET_ANDROID)
6717void nsGlobalWindowInner::EnableOrientationChangeListener() {
6718 if (!ShouldResistFingerprinting(RFPTarget::ScreenOrientation)) {
6719 mHasOrientationChangeListeners = true;
6720 mOrientationAngle = Orientation(CallerType::System);
6721 }
6722}
6723
6724void nsGlobalWindowInner::DisableOrientationChangeListener() {
6725 mHasOrientationChangeListeners = false;
6726}
6727#endif
6728
6729void nsGlobalWindowInner::SetHasGamepadEventListener(
6730 bool aHasGamepad /* = true*/) {
6731 mHasGamepad = aHasGamepad;
6732 if (aHasGamepad) {
6733 EnableGamepadUpdates();
6734 }
6735}
6736
6737void nsGlobalWindowInner::NotifyDetectXRRuntimesCompleted() {
6738 if (!mXRRuntimeDetectionInFlight) {
6739 return;
6740 }
6741 mXRRuntimeDetectionInFlight = false;
6742 if (mXRPermissionRequestInFlight) {
6743 return;
6744 }
6745 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6746 bool supported = vm->RuntimeSupportsVR();
6747 if (!supported) {
6748 // A VR runtime was not installed; we can suppress
6749 // the permission prompt
6750 OnXRPermissionRequestCancel();
6751 return;
6752 }
6753 // A VR runtime was found. Display a permission prompt before
6754 // allowing it to be accessed.
6755 // Connect to the VRManager in order to receive the runtime
6756 // detection results.
6757 mXRPermissionRequestInFlight = true;
6758 RefPtr request = MakeRefPtr<XRPermissionRequest>(this, WindowID());
6759 (void)NS_WARN_IF(NS_FAILED(request->Start()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(request
->Start())), 0))), "NS_FAILED(request->Start())", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6759)
;
6760}
6761
6762void nsGlobalWindowInner::RequestXRPermission() {
6763 if (IsDying()) {
6764 // Do not proceed if the window is dying, as that will result
6765 // in leaks of objects that get re-allocated after FreeInnerObjects
6766 // has been called, including mVREventObserver.
6767 return;
6768 }
6769 if (mXRPermissionGranted) {
6770 // Don't prompt redundantly once permission to
6771 // access XR devices has been granted.
6772 OnXRPermissionRequestAllow();
6773 return;
6774 }
6775 if (mXRRuntimeDetectionInFlight || mXRPermissionRequestInFlight) {
6776 // Don't allow multiple simultaneous permissions requests;
6777 return;
6778 }
6779 // Before displaying a permission prompt, detect
6780 // if there is any VR runtime installed.
6781 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6782 mXRRuntimeDetectionInFlight = true;
6783 EnableVRUpdates();
6784 vm->DetectRuntimes();
6785}
6786
6787void nsGlobalWindowInner::OnXRPermissionRequestAllow() {
6788 mXRPermissionRequestInFlight = false;
6789 if (IsDying()) {
6790 // The window may have started dying while the permission request
6791 // is in flight.
6792 // Do not proceed if the window is dying, as that will result
6793 // in leaks of objects that get re-allocated after FreeInnerObjects
6794 // has been called, including mNavigator.
6795 return;
6796 }
6797 mXRPermissionGranted = true;
6798
6799 NotifyHasXRSession();
6800
6801 dom::Navigator* nav = Navigator();
6802 MOZ_ASSERT(nav != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nav != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nav != nullptr))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("nav != nullptr"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6802
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6802); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6803 nav->OnXRPermissionRequestAllow();
6804}
6805
6806void nsGlobalWindowInner::OnXRPermissionRequestCancel() {
6807 mXRPermissionRequestInFlight = false;
6808 if (IsDying()) {
6809 // The window may have started dying while the permission request
6810 // is in flight.
6811 // Do not proceed if the window is dying, as that will result
6812 // in leaks of objects that get re-allocated after FreeInnerObjects
6813 // has been called, including mNavigator.
6814 return;
6815 }
6816 dom::Navigator* nav = Navigator();
6817 MOZ_ASSERT(nav != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nav != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nav != nullptr))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("nav != nullptr"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6817
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6817); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6818 nav->OnXRPermissionRequestCancel();
6819}
6820
6821void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
6822 if (aType == nsGkAtoms::onvrdisplayactivate ||
6823 aType == nsGkAtoms::onvrdisplayconnect ||
6824 aType == nsGkAtoms::onvrdisplaydeactivate ||
6825 aType == nsGkAtoms::onvrdisplaydisconnect ||
6826 aType == nsGkAtoms::onvrdisplaypresentchange) {
6827 RequestXRPermission();
6828 }
6829
6830 if (aType == nsGkAtoms::onvrdisplayactivate) {
6831 mHasVRDisplayActivateEvents = true;
6832 }
6833
6834 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6835 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6836 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6837 }
6838 }
6839
6840 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6841 if (!StaticPrefs::
6842 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6843 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6844 mWindowGlobalChild->BlockBFCacheFor(
6845 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6846 }
6847 }
6848 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6849 mWindowGlobalChild->BeforeUnloadAdded();
6850 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() > 0
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() > 0
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mWindowGlobalChild->BeforeUnloadListeners() > 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6850); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() > 0"
")"); do { MOZ_CrashSequence(__null, 6850); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6851 }
6852 }
6853
6854 // We need to initialize localStorage in order to receive notifications.
6855 if (aType == nsGkAtoms::onstorage) {
6856 ErrorResult rv;
6857 GetLocalStorage(rv);
6858 rv.SuppressException();
6859
6860 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6861 mLocalStorage->Type() == Storage::eLocalStorage) {
6862 auto object = static_cast<LSObject*>(mLocalStorage.get());
6863
6864 (void)NS_WARN_IF(NS_FAILED(object->EnsureObserver()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(object
->EnsureObserver())), 0))), "NS_FAILED(object->EnsureObserver())"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6864
)
;
6865 }
6866 }
6867}
6868
6869void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) {
6870 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6871 MOZ_ASSERT(mUnloadOrBeforeUnloadListenerCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mUnloadOrBeforeUnloadListenerCount > 0)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mUnloadOrBeforeUnloadListenerCount > 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mUnloadOrBeforeUnloadListenerCount > 0"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6871
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mUnloadOrBeforeUnloadListenerCount > 0"
")"); do { MOZ_CrashSequence(__null, 6871); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6872 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6873 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6874 }
6875 }
6876
6877 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6878 if (!StaticPrefs::
6879 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6880 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6881 mWindowGlobalChild->UnblockBFCacheFor(
6882 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6883 }
6884 }
6885 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6886 mWindowGlobalChild->BeforeUnloadRemoved();
6887 MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BeforeUnloadListeners() >=
0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BeforeUnloadListeners() >=
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mWindowGlobalChild->BeforeUnloadListeners() >= 0", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() >= 0"
")"); do { MOZ_CrashSequence(__null, 6887); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6888 }
6889 }
6890
6891 if (aType == nsGkAtoms::onstorage) {
6892 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6893 mLocalStorage->Type() == Storage::eLocalStorage &&
6894 // The remove event is fired even if this isn't the last listener, so
6895 // only remove if there are no other listeners left.
6896 mListenerManager &&
6897 !mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
6898 auto object = static_cast<LSObject*>(mLocalStorage.get());
6899
6900 object->DropObserver();
6901 }
6902 }
6903}
6904
6905void nsGlobalWindowInner::NotifyHasXRSession() {
6906 if (IsDying()) {
6907 // Do not proceed if the window is dying, as that will result
6908 // in leaks of objects that get re-allocated after FreeInnerObjects
6909 // has been called, including mVREventObserver.
6910 return;
6911 }
6912 if (mWindowGlobalChild && !mHasXRSession) {
6913 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR);
6914 }
6915 mHasXRSession = true;
6916 EnableVRUpdates();
6917}
6918
6919bool nsGlobalWindowInner::HasUsedVR() const {
6920 // Returns true only if content has enumerated and activated
6921 // XR devices. Detection of XR runtimes without activation
6922 // will not cause true to be returned.
6923 return mHasXRSession;
6924}
6925
6926bool nsGlobalWindowInner::IsVRContentDetected() const {
6927 // Returns true only if the content will respond to
6928 // the VRDisplayActivate event.
6929 return mHasVRDisplayActivateEvents;
6930}
6931
6932bool nsGlobalWindowInner::IsVRContentPresenting() const {
6933 for (const auto& display : mVRDisplays) {
6934 if (display->IsAnyPresenting(gfx::kVRGroupAll)) {
6935 return true;
6936 }
6937 }
6938 return false;
6939}
6940
6941void nsGlobalWindowInner::AddSizeOfIncludingThis(
6942 nsWindowSizes& aWindowSizes) const {
6943 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6944 aWindowSizes.mState.mMallocSizeOf(this);
6945 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6946 nsIGlobalObject::ShallowSizeOfExcludingThis(
6947 aWindowSizes.mState.mMallocSizeOf);
6948
6949 EventListenerManager* elm = GetExistingListenerManager();
6950 if (elm) {
6951 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6952 elm->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6953 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6954 }
6955 if (mDoc) {
6956 // Multiple global windows can share a document. So only measure the
6957 // document if it (a) doesn't have a global window, or (b) it's the
6958 // primary document for the window.
6959 if (!mDoc->GetInnerWindow() || mDoc->GetInnerWindow() == this) {
6960 mDoc->DocAddSizeOfIncludingThis(aWindowSizes);
6961 }
6962 }
6963
6964 if (mNavigation) {
6965 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6966 aWindowSizes.mState.mMallocSizeOf(mNavigation.get());
6967 }
6968 if (mNavigator) {
6969 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6970 mNavigator->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6971 }
6972
6973 ForEachGlobalTeardownObserver([&](GlobalTeardownObserver* et,
6974 bool* aDoneOut) {
6975 if (nsCOMPtr<nsISizeOfEventTarget> iSizeOf = do_QueryObject(et)) {
6976 aWindowSizes.mDOMSizes.mDOMEventTargetsSize +=
6977 iSizeOf->SizeOfEventTargetIncludingThis(
6978 aWindowSizes.mState.mMallocSizeOf);
6979 }
6980 if (nsCOMPtr<DOMEventTargetHelper> helper = do_QueryObject(et)) {
6981 if (EventListenerManager* elm = helper->GetExistingListenerManager()) {
6982 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6983 }
6984 }
6985 ++aWindowSizes.mDOMEventTargetsCount;
6986 });
6987
6988 if (mPerformance) {
6989 aWindowSizes.mDOMSizes.mDOMPerformanceUserEntries =
6990 mPerformance->SizeOfUserEntries(aWindowSizes.mState.mMallocSizeOf);
6991 aWindowSizes.mDOMSizes.mDOMPerformanceResourceEntries =
6992 mPerformance->SizeOfResourceEntries(aWindowSizes.mState.mMallocSizeOf);
6993 aWindowSizes.mDOMSizes.mDOMPerformanceEventEntries =
6994 mPerformance->SizeOfEventEntries(aWindowSizes.mState.mMallocSizeOf);
6995 }
6996
6997 aWindowSizes.mMediaSourceURLsCount = mMediaSourceURLs.Length();
6998}
6999
7000void nsGlobalWindowInner::RegisterDataDocumentForMemoryReporting(
7001 Document* aDocument) {
7002 aDocument->SetAddedToMemoryReportAsDataDocument();
7003 mDataDocumentsForMemoryReporting.AppendElement(aDocument);
7004}
7005
7006void nsGlobalWindowInner::UnregisterDataDocumentForMemoryReporting(
7007 Document* aDocument) {
7008 DebugOnly<bool> found =
7009 mDataDocumentsForMemoryReporting.RemoveElement(aDocument);
7010 MOZ_ASSERT(found)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(found)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(found))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("found", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7010); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ")")
; do { MOZ_CrashSequence(__null, 7010); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7011}
7012
7013void nsGlobalWindowInner::CollectDOMSizesForDataDocuments(
7014 nsWindowSizes& aSize) const {
7015 for (Document* doc : mDataDocumentsForMemoryReporting) {
7016 if (doc) {
7017 doc->DocAddSizeOfIncludingThis(aSize);
7018 }
7019 }
7020}
7021
7022void nsGlobalWindowInner::AddGamepad(GamepadHandle aHandle, Gamepad* aGamepad) {
7023 // Create the index we will present to content based on which indices are
7024 // already taken, as required by the spec.
7025 // https://w3c.github.io/gamepad/gamepad.html#widl-Gamepad-index
7026 int index = 0;
7027 while (mGamepadIndexSet.Contains(index)) {
7028 ++index;
7029 }
7030 mGamepadIndexSet.Put(index);
7031 aGamepad->SetIndex(index);
7032 mGamepads.InsertOrUpdate(aHandle, RefPtr{aGamepad});
7033}
7034
7035void nsGlobalWindowInner::RemoveGamepad(GamepadHandle aHandle) {
7036 RefPtr<Gamepad> gamepad;
7037 if (!mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7038 return;
7039 }
7040 // Free up the index we were using so it can be reused
7041 mGamepadIndexSet.Remove(gamepad->Index());
7042 mGamepads.Remove(aHandle);
7043}
7044
7045void nsGlobalWindowInner::GetGamepads(nsTArray<RefPtr<Gamepad>>& aGamepads) {
7046 aGamepads.Clear();
7047
7048 // navigator.getGamepads() always returns an empty array when
7049 // privacy.resistFingerprinting is true.
7050 if (ShouldResistFingerprinting(RFPTarget::Gamepad)) {
7051 return;
7052 }
7053
7054 // mGamepads.Count() may not be sufficient, but it's not harmful.
7055 aGamepads.SetCapacity(mGamepads.Count());
7056 for (const auto& entry : mGamepads) {
7057 Gamepad* gamepad = entry.GetWeak();
7058 aGamepads.EnsureLengthAtLeast(gamepad->Index() + 1);
7059 aGamepads[gamepad->Index()] = gamepad;
7060 }
7061}
7062
7063already_AddRefed<mozilla::dom::Promise> nsGlobalWindowInner::RequestAllGamepads(
7064 ErrorResult& aRv) {
7065 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7066
7067 if (!gamepadManager) {
7068 aRv.Throw(NS_ERROR_UNEXPECTED);
7069 return nullptr;
7070 }
7071
7072 return gamepadManager->RequestAllGamepads(this, aRv);
7073}
7074
7075already_AddRefed<Gamepad> nsGlobalWindowInner::GetGamepad(
7076 GamepadHandle aHandle) {
7077 RefPtr<Gamepad> gamepad;
7078
7079 if (mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7080 return gamepad.forget();
7081 }
7082
7083 return nullptr;
7084}
7085
7086void nsGlobalWindowInner::SetHasSeenGamepadInput(bool aHasSeen) {
7087 mHasSeenGamepadInput = aHasSeen;
7088}
7089
7090bool nsGlobalWindowInner::HasSeenGamepadInput() { return mHasSeenGamepadInput; }
7091
7092void nsGlobalWindowInner::SyncGamepadState() {
7093 if (mHasSeenGamepadInput) {
7094 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7095 for (const auto& entry : mGamepads) {
7096 gamepadManager->SyncGamepadState(entry.GetKey(), this, entry.GetWeak());
7097 }
7098 }
7099}
7100
7101void nsGlobalWindowInner::StopGamepadHaptics() {
7102 if (mHasSeenGamepadInput) {
7103 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7104 gamepadManager->StopHaptics();
7105 }
7106}
7107
7108bool nsGlobalWindowInner::UpdateVRDisplays(
7109 nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices) {
7110 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7111 aDevices = mVRDisplays.Clone();
7112 return true;
7113}
7114
7115void nsGlobalWindowInner::NotifyActiveVRDisplaysChanged() {
7116 if (mNavigator) {
7117 mNavigator->NotifyActiveVRDisplaysChanged();
7118 }
7119}
7120
7121void nsGlobalWindowInner::NotifyPresentationGenerationChanged(
7122 uint32_t aDisplayID) {
7123 for (const auto& display : mVRDisplays) {
7124 if (display->DisplayId() == aDisplayID) {
7125 display->OnPresentationGenerationChanged();
7126 }
7127 }
7128}
7129
7130void nsGlobalWindowInner::DispatchVRDisplayActivate(
7131 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7132 // Ensure that our list of displays is up to date
7133 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7134
7135 // Search for the display identified with aDisplayID and fire the
7136 // event if found.
7137 for (const auto& display : mVRDisplays) {
7138 if (display->DisplayId() == aDisplayID) {
7139 if (aReason != VRDisplayEventReason::Navigation &&
7140 display->IsAnyPresenting(gfx::kVRGroupContent)) {
7141 // We only want to trigger this event if nobody is presenting to the
7142 // display already or when a page is loaded by navigating away
7143 // from a page with an active VR Presentation.
7144 continue;
7145 }
7146
7147 VRDisplayEventInit init;
7148 init.mBubbles = false;
7149 init.mCancelable = false;
7150 init.mDisplay = display;
7151 init.mReason.Construct(aReason);
7152
7153 RefPtr<VRDisplayEvent> event =
7154 VRDisplayEvent::Constructor(this, u"vrdisplayactivate"_ns, init);
7155 // vrdisplayactivate is a trusted event, allowing VRDisplay.requestPresent
7156 // to be used in response to link traversal, user request (chrome UX), and
7157 // HMD mounting detection sensors.
7158 event->SetTrusted(true);
7159 // VRDisplay.requestPresent normally requires a user gesture; however, an
7160 // exception is made to allow it to be called in response to
7161 // vrdisplayactivate during VR link traversal.
7162 display->StartHandlingVRNavigationEvent();
7163 DispatchEvent(*event);
7164 display->StopHandlingVRNavigationEvent();
7165 // Once we dispatch the event, we must not access any members as an event
7166 // listener can do anything, including closing windows.
7167 return;
7168 }
7169 }
7170}
7171
7172void nsGlobalWindowInner::DispatchVRDisplayDeactivate(
7173 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7174 // Ensure that our list of displays is up to date
7175 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7176
7177 // Search for the display identified with aDisplayID and fire the
7178 // event if found.
7179 for (const auto& display : mVRDisplays) {
7180 if (display->DisplayId() == aDisplayID && display->IsPresenting()) {
7181 // We only want to trigger this event to content that is presenting to
7182 // the display already.
7183
7184 VRDisplayEventInit init;
7185 init.mBubbles = false;
7186 init.mCancelable = false;
7187 init.mDisplay = display;
7188 init.mReason.Construct(aReason);
7189
7190 RefPtr<VRDisplayEvent> event =
7191 VRDisplayEvent::Constructor(this, u"vrdisplaydeactivate"_ns, init);
7192 event->SetTrusted(true);
7193 DispatchEvent(*event);
7194 // Once we dispatch the event, we must not access any members as an event
7195 // listener can do anything, including closing windows.
7196 return;
7197 }
7198 }
7199}
7200
7201void nsGlobalWindowInner::DispatchVRDisplayConnect(uint32_t aDisplayID) {
7202 // Ensure that our list of displays is up to date
7203 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7204
7205 // Search for the display identified with aDisplayID and fire the
7206 // event if found.
7207 for (const auto& display : mVRDisplays) {
7208 if (display->DisplayId() == aDisplayID) {
7209 // Fire event even if not presenting to the display.
7210 VRDisplayEventInit init;
7211 init.mBubbles = false;
7212 init.mCancelable = false;
7213 init.mDisplay = display;
7214 // VRDisplayEvent.reason is not set for vrdisplayconnect
7215
7216 RefPtr<VRDisplayEvent> event =
7217 VRDisplayEvent::Constructor(this, u"vrdisplayconnect"_ns, init);
7218 event->SetTrusted(true);
7219 DispatchEvent(*event);
7220 // Once we dispatch the event, we must not access any members as an event
7221 // listener can do anything, including closing windows.
7222 return;
7223 }
7224 }
7225}
7226
7227void nsGlobalWindowInner::DispatchVRDisplayDisconnect(uint32_t aDisplayID) {
7228 // Ensure that our list of displays is up to date
7229 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7230
7231 // Search for the display identified with aDisplayID and fire the
7232 // event if found.
7233 for (const auto& display : mVRDisplays) {
7234 if (display->DisplayId() == aDisplayID) {
7235 // Fire event even if not presenting to the display.
7236 VRDisplayEventInit init;
7237 init.mBubbles = false;
7238 init.mCancelable = false;
7239 init.mDisplay = display;
7240 // VRDisplayEvent.reason is not set for vrdisplaydisconnect
7241
7242 RefPtr<VRDisplayEvent> event =
7243 VRDisplayEvent::Constructor(this, u"vrdisplaydisconnect"_ns, init);
7244 event->SetTrusted(true);
7245 DispatchEvent(*event);
7246 // Once we dispatch the event, we must not access any members as an event
7247 // listener can do anything, including closing windows.
7248 return;
7249 }
7250 }
7251}
7252
7253void nsGlobalWindowInner::DispatchVRDisplayPresentChange(uint32_t aDisplayID) {
7254 // Ensure that our list of displays is up to date
7255 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7256
7257 // Search for the display identified with aDisplayID and fire the
7258 // event if found.
7259 for (const auto& display : mVRDisplays) {
7260 if (display->DisplayId() == aDisplayID) {
7261 // Fire event even if not presenting to the display.
7262 VRDisplayEventInit init;
7263 init.mBubbles = false;
7264 init.mCancelable = false;
7265 init.mDisplay = display;
7266 // VRDisplayEvent.reason is not set for vrdisplaypresentchange
7267 RefPtr<VRDisplayEvent> event =
7268 VRDisplayEvent::Constructor(this, u"vrdisplaypresentchange"_ns, init);
7269 event->SetTrusted(true);
7270 DispatchEvent(*event);
7271 // Once we dispatch the event, we must not access any members as an event
7272 // listener can do anything, including closing windows.
7273 return;
7274 }
7275 }
7276}
7277
7278enum WindowState {
7279 // These constants need to match the constants in Window.webidl
7280 STATE_MAXIMIZED = 1,
7281 STATE_MINIMIZED = 2,
7282 STATE_NORMAL = 3,
7283 STATE_FULLSCREEN = 4
7284};
7285
7286uint16_t nsGlobalWindowInner::WindowState() {
7287 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7288
7289 int32_t mode = widget ? widget->SizeMode() : 0;
7290
7291 switch (mode) {
7292 case nsSizeMode_Minimized:
7293 return STATE_MINIMIZED;
7294 case nsSizeMode_Maximized:
7295 return STATE_MAXIMIZED;
7296 case nsSizeMode_Fullscreen:
7297 return STATE_FULLSCREEN;
7298 case nsSizeMode_Normal:
7299 return STATE_NORMAL;
7300 default:
7301 NS_WARNING("Illegal window state for this chrome window")NS_DebugBreak(NS_DEBUG_WARNING, "Illegal window state for this chrome window"
, nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7301)
;
7302 break;
7303 }
7304
7305 return STATE_NORMAL;
7306}
7307
7308bool nsGlobalWindowInner::IsFullyOccluded() {
7309 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7310 return widget && widget->IsFullyOccluded();
7311}
7312
7313void nsGlobalWindowInner::Maximize() {
7314 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7315 widget->SetSizeMode(nsSizeMode_Maximized);
7316 }
7317}
7318
7319void nsGlobalWindowInner::Minimize() {
7320 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7321 widget->SetSizeMode(nsSizeMode_Minimized);
7322 }
7323}
7324
7325void nsGlobalWindowInner::Restore() {
7326 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7327 widget->SetSizeMode(nsSizeMode_Normal);
7328 }
7329}
7330
7331void nsGlobalWindowInner::GetWorkspaceID(nsAString& workspaceID) {
7332 workspaceID.Truncate();
7333 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7334 return widget->GetWorkspaceID(workspaceID);
7335 }
7336}
7337
7338void nsGlobalWindowInner::MoveToWorkspace(const nsAString& workspaceID) {
7339 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7340 widget->MoveToWorkspace(workspaceID);
7341 }
7342}
7343
7344bool nsGlobalWindowInner::IsCloaked() const {
7345 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7346 return widget->IsCloaked();
7347 }
7348 // Assume that it is not, since most windows are not cloaked.
7349 return false;
7350}
7351
7352void nsGlobalWindowInner::GetAttention(ErrorResult& aResult) {
7353 return GetAttentionWithCycleCount(-1, aResult);
7354}
7355
7356void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount,
7357 ErrorResult& aError) {
7358 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7359
7360 if (widget) {
7361 aError = widget->GetAttention(aCycleCount);
7362 }
7363}
7364
7365already_AddRefed<Promise> nsGlobalWindowInner::PromiseDocumentFlushed(
7366 PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) {
7367 MOZ_RELEASE_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7367
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7367); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7368
7369 if (!IsCurrentInnerWindow()) {
7370 aError.ThrowInvalidStateError("Not the current inner window");
7371 return nullptr;
7372 }
7373 if (!mDoc) {
7374 aError.ThrowInvalidStateError("No document");
7375 return nullptr;
7376 }
7377
7378 if (mIteratingDocumentFlushedResolvers) {
7379 aError.ThrowInvalidStateError("Already iterating through resolvers");
7380 return nullptr;
7381 }
7382
7383 PresShell* presShell = mDoc->GetPresShell();
7384 if (!presShell) {
7385 aError.ThrowInvalidStateError("No pres shell");
7386 return nullptr;
7387 }
7388
7389 // We need to associate the lifetime of the Promise to the lifetime
7390 // of the caller's global. That way, if the window we're observing
7391 // refresh driver ticks on goes away before our observer is fired,
7392 // we can still resolve the Promise.
7393 nsIGlobalObject* global = GetIncumbentGlobal();
7394 if (!global) {
7395 aError.ThrowInvalidStateError("No incumbent global");
7396 return nullptr;
7397 }
7398
7399 RefPtr<Promise> resultPromise = Promise::Create(global, aError);
7400 if (aError.Failed()) {
7401 return nullptr;
7402 }
7403
7404 auto flushResolver =
7405 MakeUnique<PromiseDocumentFlushedResolver>(resultPromise, aCallback);
7406
7407 if (!presShell->NeedStyleFlush() && !presShell->NeedLayoutFlush()) {
7408 flushResolver->Call();
7409 return resultPromise.forget();
7410 }
7411
7412 if (!TryToObserveRefresh()) {
7413 aError.ThrowInvalidStateError("Couldn't observe refresh");
7414 return nullptr;
7415 }
7416
7417 mDocumentFlushedResolvers.AppendElement(std::move(flushResolver));
7418 return resultPromise.forget();
7419}
7420
7421bool nsGlobalWindowInner::TryToObserveRefresh() {
7422 if (mObservingRefresh) {
7423 return true;
7424 }
7425
7426 if (!mDoc) {
7427 return false;
7428 }
7429
7430 nsPresContext* pc = mDoc->GetPresContext();
7431 if (!pc) {
7432 return false;
7433 }
7434
7435 mObservingRefresh = true;
7436 auto observer = MakeRefPtr<ManagedPostRefreshObserver>(
7437 pc, [win = RefPtr{this}](bool aWasCanceled) {
7438 if (win->MaybeCallDocumentFlushedResolvers(
7439 /* aUntilExhaustion = */ aWasCanceled)) {
7440 return ManagedPostRefreshObserver::Unregister::No;
7441 }
7442 win->mObservingRefresh = false;
7443 return ManagedPostRefreshObserver::Unregister::Yes;
7444 });
7445 pc->RegisterManagedPostRefreshObserver(observer.get());
7446 return mObservingRefresh;
7447}
7448
7449void nsGlobalWindowInner::CallDocumentFlushedResolvers(bool aUntilExhaustion) {
7450 while (true) {
7451 {
7452 // To coalesce MicroTask checkpoints inside callback call, enclose the
7453 // inner loop with nsAutoMicroTask, and perform a MicroTask checkpoint
7454 // after the loop.
7455 nsAutoMicroTask mt;
7456
7457 mIteratingDocumentFlushedResolvers = true;
7458
7459 auto resolvers = std::move(mDocumentFlushedResolvers);
7460 for (const auto& resolver : resolvers) {
7461 resolver->Call();
7462 }
7463
7464 mIteratingDocumentFlushedResolvers = false;
7465 }
7466
7467 // Leaving nsAutoMicroTask above will perform MicroTask checkpoint, and
7468 // Promise callbacks there may create mDocumentFlushedResolvers items.
7469
7470 // If there's no new resolvers, or we're not exhausting the queue, there's
7471 // nothing to do (we'll keep observing if there's any new observer).
7472 //
7473 // Otherwise, keep looping to call all promises. This case can happen while
7474 // destroying the window. This violates the constraint that the
7475 // promiseDocumentFlushed callback only ever run when no flush is needed,
7476 // but it's necessary to resolve the Promise returned by that.
7477 if (!aUntilExhaustion || mDocumentFlushedResolvers.IsEmpty()) {
7478 break;
7479 }
7480 }
7481}
7482
7483bool nsGlobalWindowInner::MaybeCallDocumentFlushedResolvers(
7484 bool aUntilExhaustion) {
7485 MOZ_ASSERT(mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 7485); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7486
7487 PresShell* presShell = mDoc->GetPresShell();
7488 if (!presShell || aUntilExhaustion) {
7489 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
7490 return false;
7491 }
7492
7493 if (presShell->NeedStyleFlush() || presShell->NeedLayoutFlush()) {
7494 // By the time our observer fired, something has already invalidated
7495 // style or layout - or perhaps we're still in the middle of a flush that
7496 // was interrupted. In either case, we'll wait until the next refresh driver
7497 // tick instead and try again.
7498 return true;
7499 }
7500
7501 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ false);
7502 return !mDocumentFlushedResolvers.IsEmpty();
7503}
7504
7505already_AddRefed<nsWindowRoot> nsGlobalWindowInner::GetWindowRoot(
7506 mozilla::ErrorResult& aError) {
7507 FORWARD_TO_OUTER_OR_THROW(GetWindowRootOuter, (), aError, nullptr);
7508}
7509
7510void nsGlobalWindowInner::SetCursor(const nsACString& aCursor,
7511 ErrorResult& aError) {
7512 FORWARD_TO_OUTER_OR_THROW(SetCursorOuter, (aCursor, aError), aError, );
7513}
7514
7515nsIBrowserDOMWindow* nsGlobalWindowInner::GetBrowserDOMWindow(
7516 ErrorResult& aError) {
7517 FORWARD_TO_OUTER_OR_THROW(GetBrowserDOMWindow, (), aError, nullptr);
7518}
7519
7520void nsGlobalWindowInner::SetBrowserDOMWindow(
7521 nsIBrowserDOMWindow* aBrowserWindow, ErrorResult& aError) {
7522 FORWARD_TO_OUTER_OR_THROW(SetBrowserDOMWindowOuter, (aBrowserWindow),
7523 aError, );
7524}
7525
7526void nsGlobalWindowInner::NotifyDefaultButtonLoaded(Element& aDefaultButton,
7527 ErrorResult& aError) {
7528 // Don't snap to a disabled button.
7529 nsCOMPtr<nsIDOMXULControlElement> xulControl = aDefaultButton.AsXULControl();
7530 if (!xulControl) {
7531 aError.Throw(NS_ERROR_FAILURE);
7532 return;
7533 }
7534 bool disabled;
7535 aError = xulControl->GetDisabled(&disabled);
7536 if (aError.Failed() || disabled) {
7537 return;
7538 }
7539
7540 // Get the button rect in screen coordinates.
7541 nsIFrame* frame = aDefaultButton.GetPrimaryFrame();
7542 if (!frame) {
7543 aError.Throw(NS_ERROR_FAILURE);
7544 return;
7545 }
7546 LayoutDeviceIntRect buttonRect = LayoutDeviceIntRect::FromAppUnitsToNearest(
7547 frame->GetScreenRectInAppUnits(),
7548 frame->PresContext()->AppUnitsPerDevPixel());
7549
7550 // Get the widget rect in screen coordinates.
7551 nsIWidget* widget = GetNearestWidget();
7552 if (!widget) {
7553 aError.Throw(NS_ERROR_FAILURE);
7554 return;
7555 }
7556 LayoutDeviceIntRect widgetRect = widget->GetScreenBounds();
7557
7558 // Convert the buttonRect coordinates from screen to the widget.
7559 buttonRect -= widgetRect.TopLeft();
7560 nsresult rv = widget->OnDefaultButtonLoaded(buttonRect);
7561 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_IMPLEMENTED) {
7562 aError.Throw(rv);
7563 }
7564}
7565
7566ChromeMessageBroadcaster* nsGlobalWindowInner::MessageManager() {
7567 MOZ_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7567
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7567); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7568 if (!mChromeFields.mMessageManager) {
7569 RefPtr<ChromeMessageBroadcaster> globalMM =
7570 nsFrameMessageManager::GetGlobalMessageManager();
7571 mChromeFields.mMessageManager =
7572 MakeRefPtr<ChromeMessageBroadcaster>(globalMM);
7573 }
7574 return mChromeFields.mMessageManager;
7575}
7576
7577ChromeMessageBroadcaster* nsGlobalWindowInner::GetGroupMessageManager(
7578 const nsAString& aGroup) {
7579 MOZ_ASSERT(IsChromeWindow())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsChromeWindow())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsChromeWindow()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsChromeWindow()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7579
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7579); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7580
7581 return mChromeFields.mGroupMessageManagers
7582 .LookupOrInsertWith(
7583 aGroup,
7584 [&] {
7585 return MakeAndAddRef<ChromeMessageBroadcaster>(MessageManager());
7586 })
7587 .get();
7588}
7589
7590void nsGlobalWindowInner::InitWasOffline() { mWasOffline = NS_IsOffline(); }
7591
7592int16_t nsGlobalWindowInner::Orientation(CallerType aCallerType) {
7593 // GetOrientationAngle() returns 0, 90, 180 or 270.
7594 // window.orientation returns -90, 0, 90 or 180.
7595 uint16_t screenAngle = Screen()->GetOrientationAngle();
7596 if (nsIGlobalObject::ShouldResistFingerprinting(
7597 aCallerType, RFPTarget::ScreenOrientation)) {
7598 CSSIntSize size = mBrowsingContext->TopInnerSizeSpoofedForRFP();
7599 screenAngle = nsRFPService::ViewportSizeToAngle(size.width, size.height);
7600 }
7601 int16_t angle = AssertedCast<int16_t>(screenAngle);
7602 return angle <= 180 ? angle : angle - 360;
7603}
7604
7605already_AddRefed<Console> nsGlobalWindowInner::GetConsole(JSContext* aCx,
7606 ErrorResult& aRv) {
7607 if (!mConsole) {
7608 mConsole = Console::Create(aCx, this, aRv);
7609 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7609)
) {
7610 return nullptr;
7611 }
7612 }
7613
7614 RefPtr<Console> console = mConsole;
7615 return console.forget();
7616}
7617
7618already_AddRefed<CookieStore> nsGlobalWindowInner::CookieStore() {
7619 if (!mCookieStore) {
7620 mCookieStore = CookieStore::Create(this);
7621 }
7622
7623 return do_AddRef(mCookieStore);
7624}
7625
7626DocumentPictureInPicture* nsGlobalWindowInner::DocumentPictureInPicture() {
7627 if (!mDocumentPiP) {
7628 mDocumentPiP = MakeRefPtr<class DocumentPictureInPicture>(this);
7629 }
7630
7631 return mDocumentPiP;
7632}
7633
7634mozilla::dom::PushManager* nsGlobalWindowInner::GetPushManager(
7635 JSContext* aCx, ErrorResult& aRv) {
7636 if (!mPushManager) {
7637 mPushManager = PushManager::Create(aCx, this, aRv);
7638 }
7639 return mPushManager;
7640}
7641
7642bool nsGlobalWindowInner::IsSecureContext() const {
7643 JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor());
7644 return JS::GetIsSecureContext(realm);
7645}
7646
7647External* nsGlobalWindowInner::External() {
7648 if (!mExternal) {
7649 mExternal = MakeRefPtr<dom::External>(ToSupports(this));
7650 }
7651
7652 return mExternal;
7653}
7654
7655void nsGlobalWindowInner::ClearDocumentDependentSlots(JSContext* aCx) {
7656 // If JSAPI OOMs here, there is basically nothing we can do to recover safely.
7657 if (!Window_Binding::ClearCachedDocumentValue(aCx, this) ||
7658 !Window_Binding::ClearCachedPerformanceValue(aCx, this)) {
7659 MOZ_CRASH("Unhandlable OOM while clearing document dependent slots.")do { do { } while (false); MOZ_ReportCrash("" "Unhandlable OOM while clearing document dependent slots."
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7659
); AnnotateMozCrashReason("MOZ_CRASH(" "Unhandlable OOM while clearing document dependent slots."
")"); do { MOZ_CrashSequence(__null, 7659); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7660 }
7661}
7662
7663/* static */
7664JSObject* nsGlobalWindowInner::CreateNamedPropertiesObject(
7665 JSContext* aCx, JS::Handle<JSObject*> aProto) {
7666 return WindowNamedPropertiesHandler::Create(aCx, aProto);
7667}
7668
7669void nsGlobalWindowInner::RedefineProperty(JSContext* aCx,
7670 const char* aPropName,
7671 JS::Handle<JS::Value> aValue,
7672 ErrorResult& aError) {
7673 JS::Rooted<JSObject*> thisObj(aCx, GetWrapperPreserveColor());
7674 if (!thisObj) {
7675 aError.Throw(NS_ERROR_UNEXPECTED);
7676 return;
7677 }
7678
7679 if (!JS_WrapObject(aCx, &thisObj) ||
7680 !JS_DefineProperty(aCx, thisObj, aPropName, aValue, JSPROP_ENUMERATE)) {
7681 aError.Throw(NS_ERROR_FAILURE);
7682 }
7683}
7684
7685void nsGlobalWindowInner::FireOnNewGlobalObject() {
7686 // AutoEntryScript required to invoke debugger hook, which is a
7687 // Gecko-specific concept at present.
7688 AutoEntryScript aes(this, "nsGlobalWindowInner report new global");
7689 JS::Rooted<JSObject*> global(aes.cx(), GetWrapper());
7690 JS_FireOnNewGlobalObject(aes.cx(), global);
7691}
7692
7693#if defined(_WINDOWS_) && !defined(MOZ_WRAPPED_WINDOWS_H)
7694# pragma message( \
7695 "wrapper failure reason: " MOZ_WINDOWS_WRAPPER_DISABLED_REASON)
7696# error "Never include unwrapped windows.h in this file!"
7697#endif
7698
7699already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7700 const ImageBitmapSource& aImage, const ImageBitmapOptions& aOptions,
7701 ErrorResult& aRv) {
7702 return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv);
7703}
7704
7705already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7706 const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw,
7707 int32_t aSh, const ImageBitmapOptions& aOptions, ErrorResult& aRv) {
7708 return ImageBitmap::Create(
7709 this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv);
7710}
7711
7712// https://html.spec.whatwg.org/#structured-cloning
7713void nsGlobalWindowInner::StructuredClone(
7714 JSContext* aCx, JS::Handle<JS::Value> aValue,
7715 const StructuredSerializeOptions& aOptions,
7716 JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) {
7717 nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRetval, aError);
7718}
7719
7720nsresult nsGlobalWindowInner::Dispatch(
7721 already_AddRefed<nsIRunnable> aRunnable) const {
7722 MOZ_RELEASE_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7722
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7722); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7723 return NS_DispatchToCurrentThread(std::move(aRunnable));
7724}
7725
7726nsISerialEventTarget* nsGlobalWindowInner::SerialEventTarget() const {
7727 MOZ_RELEASE_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7727
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7727); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7728 return GetMainThreadSerialEventTarget();
7729}
7730
7731Worklet* nsGlobalWindowInner::GetPaintWorklet(ErrorResult& aRv) {
7732 if (!mPaintWorklet) {
7733 nsIPrincipal* principal = GetPrincipal();
7734 if (!principal) {
7735 aRv.Throw(NS_ERROR_FAILURE);
7736 return nullptr;
7737 }
7738
7739 mPaintWorklet = PaintWorkletImpl::CreateWorklet(this, principal);
7740 }
7741
7742 return mPaintWorklet;
7743}
7744
7745void nsGlobalWindowInner::GetWebExposedLocales(nsTArray<nsString>& aLocales) {
7746 MOZ_ASSERT(mozilla::intl::LocaleService::GetInstance())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::intl::LocaleService::GetInstance())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mozilla::intl::LocaleService::GetInstance()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mozilla::intl::LocaleService::GetInstance()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7746
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::intl::LocaleService::GetInstance()"
")"); do { MOZ_CrashSequence(__null, 7746); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7747
7748 AutoTArray<nsCString, 10> rpLocales;
7749 mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(rpLocales);
7750
7751 for (const auto& loc : rpLocales) {
7752 aLocales.AppendElement(NS_ConvertUTF8toUTF16(loc));
7753 }
7754}
7755
7756IntlUtils* nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError) {
7757 if (!mIntlUtils) {
7758 mIntlUtils = MakeRefPtr<IntlUtils>(this);
7759 }
7760
7761 return mIntlUtils;
7762}
7763
7764void nsGlobalWindowInner::StoreSharedWorker(SharedWorker* aSharedWorker) {
7765 MOZ_ASSERT(aSharedWorker)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSharedWorker)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSharedWorker))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSharedWorker",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7765
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7765); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7766 MOZ_ASSERT(!mSharedWorkers.Contains(aSharedWorker))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSharedWorkers.Contains(aSharedWorker))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mSharedWorkers.Contains(aSharedWorker)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mSharedWorkers.Contains(aSharedWorker)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7766
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7766); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7767
7768 mSharedWorkers.AppendElement(aSharedWorker);
7769}
7770
7771void nsGlobalWindowInner::ForgetSharedWorker(SharedWorker* aSharedWorker) {
7772 MOZ_ASSERT(aSharedWorker)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSharedWorker)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSharedWorker))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSharedWorker",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7772
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7772); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7773 MOZ_ASSERT(mSharedWorkers.Contains(aSharedWorker))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSharedWorkers.Contains(aSharedWorker))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mSharedWorkers.Contains(aSharedWorker)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mSharedWorkers.Contains(aSharedWorker)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7773
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7773); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7774
7775 mSharedWorkers.RemoveElement(aSharedWorker);
7776}
7777
7778void nsGlobalWindowInner::UpdateSharedWorkersLanguageOverride(
7779 const nsCString& aLanguageOverride) {
7780 nsTArray<nsString> resolvedLanguages;
7781 Navigator::GetAcceptLanguages(resolvedLanguages, aLanguageOverride.IsEmpty()
7782 ? nullptr
7783 : &aLanguageOverride);
7784
7785 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
7786 mSharedWorkers.ForwardRange()) {
7787 pinnedWorker->UpdateLanguageOverride(aLanguageOverride, resolvedLanguages);
7788 }
7789}
7790
7791void nsGlobalWindowInner::UpdateSharedWorkerTimezoneOverride(
7792 const nsAString& aTimezoneOverride) {
7793 for (RefPtr<SharedWorker> pinnedWorker : mSharedWorkers.ForwardRange()) {
7794 pinnedWorker->UpdateTimezoneOverride(aTimezoneOverride);
7795 }
7796}
7797
7798RefPtr<GenericPromise> nsGlobalWindowInner::StorageAccessPermissionChanged(
7799 bool aGranted) {
7800 // Invalidate cached StorageAllowed field so that calls to GetLocalStorage
7801 // give us the updated localStorage object.
7802 ClearStorageAllowedCache();
7803
7804 // Just reset the active cookie and storage principals
7805 nsCOMPtr<nsICookieJarSettings> cjs;
7806 if (mDoc) {
7807 cjs = mDoc->CookieJarSettings();
7808 }
7809 StorageAccess storageAccess = StorageAllowedForWindow(this);
7810 if (ShouldPartitionStorage(storageAccess) &&
7811 StoragePartitioningEnabled(storageAccess, cjs)) {
7812 if (mDoc) {
7813 mDoc->ClearActiveCookieAndStoragePrincipals();
7814 }
7815 // When storage access is granted the content process needs to request the
7816 // updated cookie list from the parent process. Otherwise the site won't
7817 // have access to unpartitioned cookies via document.cookie without a
7818 // reload.
7819 if (aGranted) {
7820 nsIChannel* channel = mDoc->GetChannel();
7821 if (channel) {
7822 // The promise resolves when the updated cookie list has been received
7823 // from the parent.
7824 return ContentChild::UpdateCookieStatus(channel);
7825 }
7826 }
7827 }
7828
7829 PropagateStorageAccessPermissionGrantedToWorkers(*this);
7830
7831 // If we have a partitioned localStorage, it's time to replace it with a real
7832 // one in order to receive notifications.
7833
7834 if (mLocalStorage) {
7835 IgnoredErrorResult error;
7836 GetLocalStorage(error);
7837 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7837)
) {
7838 return MozPromise<bool, nsresult, true>::CreateAndReject(
7839 error.StealNSResult(), __func__);
7840 }
7841
7842 MOZ_ASSERT(mLocalStorage &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage && mLocalStorage->Type() ==
Storage::eLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage && mLocalStorage
->Type() == Storage::eLocalStorage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7843
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7843); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7843 mLocalStorage->Type() == Storage::eLocalStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLocalStorage && mLocalStorage->Type() ==
Storage::eLocalStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLocalStorage && mLocalStorage
->Type() == Storage::eLocalStorage))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7843
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7843); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7844
7845 if (NextGenLocalStorageEnabled() && mListenerManager &&
7846 mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
7847 auto object = static_cast<LSObject*>(mLocalStorage.get());
7848
7849 object->EnsureObserver();
7850 }
7851 }
7852
7853 // Reset the IndexedDB factory.
7854 mIndexedDB = nullptr;
7855
7856 // Reset DOM Cache
7857 mCacheStorage = nullptr;
7858
7859 // Reset the active cookie and storage principals
7860 if (mDoc) {
7861 mDoc->ClearActiveCookieAndStoragePrincipals();
7862 if (mWindowGlobalChild) {
7863 // Clearing the cookie principal might make us end up with a new effective
7864 // storage principal on the child side than on the parent side, which
7865 // means that we need to sync it. See bug 1705359.
7866 mWindowGlobalChild->SendUpdatePrincipalPartitioning(
7867 !mDoc->UseRegularPrincipal());
7868 }
7869 }
7870
7871 // When storage access is granted the content process needs to request the
7872 // updated cookie list from the parent process. Otherwise the site won't have
7873 // access to unpartitioned cookies via document.cookie without a reload.
7874 if (aGranted) {
7875 nsIChannel* channel = mDoc->GetChannel();
7876 if (channel) {
7877 // The promise resolves when the updated cookie list has been received
7878 // from the parent.
7879 return ContentChild::UpdateCookieStatus(channel);
7880 }
7881 }
7882 return MozPromise<bool, nsresult, true>::CreateAndResolve(true, __func__);
7883}
7884
7885ContentMediaController* nsGlobalWindowInner::GetContentMediaController() {
7886 if (mContentMediaController) {
7887 return mContentMediaController;
7888 }
7889 if (!mBrowsingContext) {
7890 return nullptr;
7891 }
7892
7893 mContentMediaController =
7894 MakeRefPtr<ContentMediaController>(mBrowsingContext->Id());
7895 return mContentMediaController;
7896}
7897
7898void nsGlobalWindowInner::SetScrollMarks(const nsTArray<uint32_t>& aScrollMarks,
7899 bool aOnHScrollbar) {
7900 mScrollMarks.Assign(aScrollMarks);
7901 mScrollMarksOnHScrollbar = aOnHScrollbar;
7902
7903 // Mark the scrollbar for repainting.
7904 if (mDoc) {
7905 PresShell* presShell = mDoc->GetPresShell();
7906 if (presShell) {
7907 ScrollContainerFrame* sf = presShell->GetRootScrollContainerFrame();
7908 if (sf) {
7909 sf->InvalidateScrollbars();
7910 }
7911 }
7912 }
7913}
7914
7915/* static */
7916already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
7917 nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
7918 WindowGlobalChild* aActor) {
7919 RefPtr<nsGlobalWindowInner> window =
7920 new nsGlobalWindowInner(aOuterWindow, aActor);
7921 if (aIsChrome) {
7922 window->mIsChrome = true;
7923 window->mCleanMessageManager = true;
7924 }
7925
7926 if (aActor) {
7927 aActor->InitWindowGlobal(window);
7928 }
7929
7930 window->InitWasOffline();
7931 return window.forget();
7932}
7933
7934JS::loader::ModuleLoaderBase* nsGlobalWindowInner::GetModuleLoader(
7935 JSContext* aCx) {
7936 Document* document = GetDocument();
7937 if (!document) {
7938 return nullptr;
7939 }
7940
7941 ScriptLoader* loader = document->GetScriptLoader();
7942 if (!loader) {
7943 return nullptr;
7944 }
7945
7946 return loader->GetModuleLoader();
7947}
7948
7949void nsGlobalWindowInner::SetCurrentPasteDataTransfer(
7950 DataTransfer* aDataTransfer) {
7951 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->GetEventMessage() == ePaste)do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->GetEventMessage
() == ePaste)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aDataTransfer->GetEventMessage
() == ePaste))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aDataTransfer->GetEventMessage() == ePaste", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7951); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetEventMessage() == ePaste"
")"); do { MOZ_CrashSequence(__null, 7951); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7952 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->ClipboardType() ==do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7953
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7953); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
7953 Some(nsIClipboard::kGlobalClipboard))do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDataTransfer->ClipboardType
() == Some(nsIClipboard::kGlobalClipboard)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7953
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7953); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7954 MOZ_ASSERT_IF(aDataTransfer, aDataTransfer->GetClipboardDataSnapshot())do { if (aDataTransfer) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(aDataTransfer->GetClipboardDataSnapshot
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aDataTransfer->GetClipboardDataSnapshot()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aDataTransfer->GetClipboardDataSnapshot()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 7954
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetClipboardDataSnapshot()"
")"); do { MOZ_CrashSequence(__null, 7954); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7955 mCurrentPasteDataTransfer = aDataTransfer;
7956}
7957
7958DataTransfer* nsGlobalWindowInner::GetCurrentPasteDataTransfer() const {
7959 return mCurrentPasteDataTransfer;
7960}
7961
7962TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() {
7963 if (!mTrustedTypePolicyFactory) {
7964 mTrustedTypePolicyFactory = MakeRefPtr<TrustedTypePolicyFactory>(this);
7965 }
7966
7967 return mTrustedTypePolicyFactory;
7968}
7969
7970void nsGlobalWindowInner::NoteMediaSourceURL(const nsACString& aURL) {
7971 MOZ_ASSERT(!IsDying(), "MediaSourceURL will never be cleaned up")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsDying())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsDying()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!IsDying()" " (" "MediaSourceURL will never be cleaned up"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
7971); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") ("
"MediaSourceURL will never be cleaned up" ")"); do { MOZ_CrashSequence
(__null, 7971); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7972 mMediaSourceURLs.InsertElementSorted(aURL);
7973}
7974
7975void nsGlobalWindowInner::UnnoteMediaSourceURL(const nsACString& aURL) {
7976 DebugOnly<bool> found = mMediaSourceURLs.RemoveElementSorted(aURL);
7977 MOZ_ASSERT(found, "MediaSourceURL should have been noted")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(found)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(found))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("found" " (" "MediaSourceURL should have been noted"
")", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp",
7977); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ") ("
"MediaSourceURL should have been noted" ")"); do { MOZ_CrashSequence
(__null, 7977); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7978}
7979
7980void nsPIDOMWindowInner::MaybeSetHasPointerRawUpdateEventListeners() {
7981 if (HasPointerRawUpdateEventListeners() || !IsSecureContext()) {
7982 return;
7983 }
7984 mMayHavePointerRawUpdateEventListener = true;
7985 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7986 browserChild->OnPointerRawUpdateEventListenerAdded(this);
7987 }
7988}
7989
7990void nsPIDOMWindowInner::ClearHasPointerRawUpdateEventListeners() {
7991 if (!HasPointerRawUpdateEventListeners()) {
7992 return;
7993 }
7994 mMayHavePointerRawUpdateEventListener = false;
7995 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7996 browserChild->OnPointerRawUpdateEventListenerRemoved(this);
7997 }
7998}
7999
8000nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
8001 return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
8002}
8003
8004nsIURI* nsPIDOMWindowInner::GetDocBaseURI() const {
8005 return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
8006}
8007
8008mozilla::dom::WindowContext* nsPIDOMWindowInner::GetWindowContext() const {
8009 return mWindowGlobalChild ? mWindowGlobalChild->WindowContext() : nullptr;
8010}
8011
8012bool nsPIDOMWindowInner::RemoveFromBFCacheSync() {
8013 if (Document* doc = GetExtantDoc()) {
8014 return doc->RemoveFromBFCacheSync();
8015 }
8016 return false;
8017}
8018
8019void nsPIDOMWindowInner::MaybeCreateDoc() {
8020 // XXX: Forward to outer?
8021 MOZ_ASSERT(!mDoc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDoc)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(!mDoc))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("!mDoc", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 8021); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDoc" ")")
; do { MOZ_CrashSequence(__null, 8021); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8022 if (nsIDocShell* docShell = GetDocShell()) {
8023 // Note that |document| here is the same thing as our mDoc, but we
8024 // don't have to explicitly set the member variable because the docshell
8025 // has already called SetNewDocument().
8026 nsCOMPtr<Document> document = docShell->GetDocument();
8027 (void)document;
8028 }
8029}
8030
8031mozilla::dom::DocGroup* nsPIDOMWindowInner::GetDocGroup() const {
8032 Document* doc = GetExtantDoc();
8033 if (doc) {
8034 return doc->GetDocGroup();
8035 }
8036 return nullptr;
8037}
8038
8039mozilla::dom::BrowsingContextGroup*
8040nsPIDOMWindowInner::GetBrowsingContextGroup() const {
8041 return mBrowsingContext ? mBrowsingContext->Group() : nullptr;
8042}
8043
8044nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() {
8045 return nsGlobalWindowInner::Cast(this);
8046}
8047
8048const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const {
8049 return nsGlobalWindowInner::Cast(this);
8050}
8051
8052RefPtr<GenericPromise>
8053nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() {
8054 WindowContext* wc = GetWindowContext();
8055 if (wc) {
8056 (void)wc->SetUsingStorageAccess(true);
8057 }
8058
8059 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(true);
8060}
8061
8062RefPtr<GenericPromise>
8063nsPIDOMWindowInner::SaveStorageAccessPermissionRevoked() {
8064 WindowContext* wc = GetWindowContext();
8065 if (wc) {
8066 (void)wc->SetUsingStorageAccess(false);
8067 }
8068
8069 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(false);
8070}
8071
8072bool nsPIDOMWindowInner::UsingStorageAccess() {
8073 WindowContext* wc = GetWindowContext();
8074 if (!wc) {
8075 return false;
8076 }
8077
8078 return wc->GetUsingStorageAccess();
8079}
8080
8081WebIdentityHandler* nsPIDOMWindowInner::GetOrCreateWebIdentityHandler() {
8082 if (mWebIdentityHandler) {
8083 return mWebIdentityHandler;
8084 }
8085 mWebIdentityHandler = MakeRefPtr<WebIdentityHandler>(this);
8086 bool success = mWebIdentityHandler->MaybeCreateActor();
8087 if (!success) {
8088 mWebIdentityHandler = nullptr;
8089 }
8090 return mWebIdentityHandler;
8091}
8092
8093CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() {
8094 if (!mCloseWatcherManager) {
8095 mCloseWatcherManager = MakeRefPtr<CloseWatcherManager>();
8096 }
8097 return mCloseWatcherManager;
8098}
8099
8100void nsPIDOMWindowInner::NotifyCloseWatcherAdded() {
8101 MOZ_ASSERT(mCloseWatcherManager && !mCloseWatcherManager->IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCloseWatcherManager && !mCloseWatcherManager
->IsEmpty())>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(mCloseWatcherManager &&
!mCloseWatcherManager->IsEmpty()))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8101
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 8101); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8102 if (WindowContext* top = TopWindowContext(*this)) {
8103 (void)top->SetHasActiveCloseWatcher(true);
8104 }
8105}
8106
8107void nsPIDOMWindowInner::NotifyCloseWatcherRemoved() {
8108 MOZ_ASSERT(mCloseWatcherManager)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCloseWatcherManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCloseWatcherManager))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCloseWatcherManager"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8108
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager"
")"); do { MOZ_CrashSequence(__null, 8108); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8109 if (WindowContext* top = TopWindowContext(*this)) {
8110 (void)top->SetHasActiveCloseWatcher(!mCloseWatcherManager->IsEmpty());
8111 }
8112}
8113
8114nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
8115 WindowGlobalChild* aActor)
8116 : mOuterWindow(aOuterWindow), mWindowGlobalChild(aActor) {
8117 MOZ_ASSERT(aOuterWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOuterWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aOuterWindow))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aOuterWindow", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 8117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOuterWindow"
")"); do { MOZ_CrashSequence(__null, 8117); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8118 mBrowsingContext = aOuterWindow->GetBrowsingContext();
8119
8120 if (mWindowGlobalChild) {
8121 mWindowID = aActor->InnerWindowId();
8122
8123 MOZ_ASSERT(mWindowGlobalChild->BrowsingContext() == mBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindowGlobalChild->BrowsingContext() == mBrowsingContext
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mWindowGlobalChild->BrowsingContext() == mBrowsingContext
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mWindowGlobalChild->BrowsingContext() == mBrowsingContext"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 8123
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BrowsingContext() == mBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 8123); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8124 } else {
8125 mWindowID = nsContentUtils::GenerateWindowId();
8126 }
8127}
8128
8129nsPIDOMWindowInner::~nsPIDOMWindowInner() = default;
8130
8131#undef FORWARD_TO_OUTER
8132#undef FORWARD_TO_OUTER_OR_THROW
8133#undef FORWARD_TO_OUTER_VOID