Bug Summary

File:root/firefox-clang/dom/base/nsGlobalWindowInner.cpp
Warning:line 5408, 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-11-12-001017-1011516-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 "nsISupportsPrimitives.h"
280#include "nsISupportsUtils.h"
281#include "nsIThread.h"
282#include "nsITimedChannel.h"
283#include "nsIURI.h"
284#include "nsIWeakReference.h"
285#include "nsIWebBrowserChrome.h"
286#include "nsIWebNavigation.h"
287#include "nsIWebProgressListener.h"
288#include "nsIWidget.h"
289#include "nsIWidgetListener.h"
290#include "nsIXULRuntime.h"
291#include "nsJSPrincipals.h"
292#include "nsJSUtils.h"
293#include "nsLayoutStatics.h"
294#include "nsLiteralString.h"
295#include "nsNetUtil.h"
296#include "nsPIDOMWindow.h"
297#include "nsPIDOMWindowInlines.h"
298#include "nsPIWindowRoot.h"
299#include "nsPoint.h"
300#include "nsPresContext.h"
301#include "nsQueryObject.h"
302#include "nsSandboxFlags.h"
303#include "nsScreen.h"
304#include "nsServiceManagerUtils.h"
305#include "nsString.h"
306#include "nsStringFlags.h"
307#include "nsStringFwd.h"
308#include "nsTArray.h"
309#include "nsTLiteralString.h"
310#include "nsTObserverArray.h"
311#include "nsTStringRepr.h"
312#include "nsThread.h"
313#include "nsThreadManager.h"
314#include "nsThreadUtils.h"
315#include "nsWeakReference.h"
316#include "nsWindowMemoryReporter.h"
317#include "nsWindowSizes.h"
318#include "nsWrapperCache.h"
319#include "nsWrapperCacheInlines.h"
320#include "nsXULAppAPI.h"
321#include "nsrootidl.h"
322#include "prclist.h"
323#include "prtypes.h"
324#include "xpcprivate.h"
325#include "xpcpublic.h"
326
327#ifdef MOZ_WEBSPEECH1
328# include "mozilla/dom/SpeechSynthesis.h"
329#endif
330
331#ifdef ANDROID
332# include <android/log.h>
333#endif
334
335#ifdef XP_WIN
336# include <process.h>
337
338# include "mozilla/Debug.h"
339# define getpid _getpid
340#else
341# include <unistd.h> // for getpid()
342#endif
343
344using namespace mozilla;
345using namespace mozilla::dom;
346using namespace mozilla::dom::ipc;
347using mozilla::TimeDuration;
348using mozilla::TimeStamp;
349using mozilla::dom::GamepadHandle;
350using mozilla::dom::cache::CacheStorage;
351
352#define FORWARD_TO_OUTER(method, args, err_rval) \
353 PR_BEGIN_MACROdo { \
354 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
355 if (!HasActiveDocument()) { \
356 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"
, 357)
357 : "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"
, 357)
; \
358 return err_rval; \
359 } \
360 return outer->method args; \
361 PR_END_MACRO} while (0)
362
363static nsGlobalWindowOuter* GetOuterWindowForForwarding(
364 nsGlobalWindowInner* aInner, ErrorResult& aError) {
365 nsGlobalWindowOuter* outer = aInner->GetOuterWindowInternal();
366 if (MOZ_LIKELY(aInner->HasActiveDocument())(__builtin_expect(!!(aInner->HasActiveDocument()), 1))) {
367 return outer;
368 }
369 if (!outer) {
370 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 370)
;
371 aError.Throw(NS_ERROR_NOT_INITIALIZED);
372 } else {
373 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
374 }
375 return nullptr;
376}
377
378#define FORWARD_TO_OUTER_OR_THROW(method, args, rv, err_rval) \
379 PR_BEGIN_MACROdo { \
380 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowForForwarding(this, rv); \
381 if (MOZ_LIKELY(outer)(__builtin_expect(!!(outer), 1))) { \
382 return outer->method args; \
383 } \
384 return err_rval; \
385 PR_END_MACRO} while (0)
386
387#define FORWARD_TO_OUTER_VOID(method, args) \
388 PR_BEGIN_MACROdo { \
389 RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal(); \
390 if (!HasActiveDocument()) { \
391 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"
, 392)
392 : "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"
, 392)
; \
393 return; \
394 } \
395 outer->method args; \
396 return; \
397 PR_END_MACRO} while (0)
398
399#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)
\
400 PR_BEGIN_MACROdo { \
401 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) { \
402 aError.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); \
403 return err_rval; \
404 } \
405 PR_END_MACRO} while (0)
406
407#define DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added" "dom-touch-listener-added"
408#define MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure" "memory-pressure"
409#define PERMISSION_CHANGED_TOPIC"perm-changed" "perm-changed"
410
411static LazyLogModule gDOMLeakPRLogInner("DOMLeakInner");
412extern mozilla::LazyLogModule gTimeoutLog;
413
414#ifdef DEBUG1
415static LazyLogModule gDocShellAndDOMWindowLeakLogging(
416 "DocShellAndDOMWindowLeak");
417#endif
418
419static FILE* gDumpFile = nullptr;
420
421mozilla::StaticAutoPtr<nsGlobalWindowInner::InnerWindowByIdTable>
422 nsGlobalWindowInner::sInnerWindowsById;
423
424bool nsGlobalWindowInner::sDragServiceDisabled = false;
425bool nsGlobalWindowInner::sMouseDown = false;
426
427/**
428 * An indirect observer object that means we don't have to implement nsIObserver
429 * on nsGlobalWindow, where any script could see it.
430 */
431class nsGlobalWindowObserver final : public nsIObserver,
432 public nsIInterfaceRequestor,
433 public StorageNotificationObserver {
434 public:
435 explicit nsGlobalWindowObserver(nsGlobalWindowInner* aWindow)
436 : mWindow(aWindow) {}
437 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:
438 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODvirtual nsresult
439 Observe(nsISupports* aSubject, const char* aTopic,
440 const char16_t* aData) override {
441 if (!mWindow) return NS_OK;
442 const RefPtr<nsGlobalWindowInner> win = mWindow;
443 return win->Observe(aSubject, aTopic, aData);
444 }
445 void Forget() { mWindow = nullptr; }
446 NS_IMETHODvirtual nsresult GetInterface(const nsIID& aIID, void** aResult) override {
447 if (mWindow && aIID.Equals(NS_GET_IID(nsIDOMWindow)(nsIDOMWindow::kIID)) && mWindow) {
448 return mWindow->QueryInterface(aIID, aResult);
449 }
450 return NS_NOINTERFACE;
451 }
452
453 void ObserveStorageNotification(StorageEvent* aEvent,
454 const char16_t* aStorageType,
455 bool aPrivateBrowsing) override {
456 if (mWindow) {
457 mWindow->ObserveStorageNotification(aEvent, aStorageType,
458 aPrivateBrowsing);
459 }
460 }
461
462 nsIPrincipal* GetEffectiveCookiePrincipal() const override {
463 return mWindow ? mWindow->GetEffectiveCookiePrincipal() : nullptr;
464 }
465
466 nsIPrincipal* GetEffectiveStoragePrincipal() const override {
467 return mWindow ? mWindow->GetEffectiveStoragePrincipal() : nullptr;
468 }
469
470 bool IsPrivateBrowsing() const override {
471 return mWindow ? mWindow->IsPrivateBrowsing() : false;
472 }
473
474 nsIEventTarget* GetEventTarget() const override {
475 return mWindow ? mWindow->SerialEventTarget() : nullptr;
476 }
477
478 private:
479 ~nsGlobalWindowObserver() = default;
480
481 // This reference is non-owning and safe because it's cleared by
482 // nsGlobalWindowInner::FreeInnerObjects().
483 nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
484};
485
486NS_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"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 486
); __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"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 486); __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",
486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 486
); __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"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsGlobalWindowObserver\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 486); __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"
, 486); 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; }
487
488class IdleRequestExecutor;
489
490class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler {
491 public:
492 explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor)
493 : mExecutor(aExecutor) {}
494
495 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:
496 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",
496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutorTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 496); __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
497
498 bool Call(const char* /* unused */) override;
499
500 private:
501 ~IdleRequestExecutorTimeoutHandler() override = default;
502 RefPtr<IdleRequestExecutor> mExecutor;
503};
504
505NS_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; }
506
507NS_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"
, 507); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); 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.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutorTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
508NS_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"
, 508); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 508
); __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); }
509
510NS_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"
, 510); 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
511 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
512NS_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"
, 512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 512); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
513
514class IdleRequestExecutor final : public nsIRunnable,
515 public nsICancelableRunnable,
516 public nsINamed,
517 public nsIIdleRunnable {
518 public:
519 explicit IdleRequestExecutor(nsGlobalWindowInner* aWindow)
520 : mDispatched(false), mDeadline(TimeStamp::Now()), mWindow(aWindow) {
521 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"
, 521); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow"
")"); do { MOZ_CrashSequence(__null, 521); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
522
523 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
524 mDelayedExecutorDispatcher =
525 MakeRefPtr<IdleRequestExecutorTimeoutHandler>(this);
526 }
527
528 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:
529 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",
529); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestExecutor" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 529); __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
530
531 NS_DECL_NSIRUNNABLEvirtual nsresult Run(void) override;
532 NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override;
533 nsresult Cancel() override;
534 void SetDeadline(TimeStamp aDeadline) override;
535
536 bool IsCancelled() const { return !mWindow || mWindow->IsDying(); }
537 // Checks if aRequest shouldn't execute in the current idle period
538 // since it has been queued from a chained call to
539 // requestIdleCallback from within a running idle callback.
540 bool IneligibleForCurrentIdlePeriod(IdleRequest* aRequest) const {
541 return aRequest->Handle() >= mIdlePeriodLimit.mLastRequestIdInIdlePeriod &&
542 TimeStamp::Now() <= mIdlePeriodLimit.mEndOfIdlePeriod;
543 }
544
545 void MaybeUpdateIdlePeriodLimit();
546
547 // Maybe dispatch the IdleRequestExecutor. MabyeDispatch will
548 // schedule a delayed dispatch if the associated window is in the
549 // background or if given a time to wait until dispatching.
550 void MaybeDispatch(TimeStamp aDelayUntil = TimeStamp());
551 void ScheduleDispatch();
552
553 private:
554 struct IdlePeriodLimit {
555 TimeStamp mEndOfIdlePeriod;
556 uint32_t mLastRequestIdInIdlePeriod;
557 };
558
559 void DelayedDispatch(uint32_t aDelay);
560
561 ~IdleRequestExecutor() override = default;
562
563 bool mDispatched;
564 TimeStamp mDeadline;
565 IdlePeriodLimit mIdlePeriodLimit;
566 RefPtr<nsGlobalWindowInner> mWindow;
567 // The timeout handler responsible for dispatching this executor in
568 // the case of immediate dispatch to the idle queue isn't
569 // desirable. This is used if we've dispatched all idle callbacks
570 // that are allowed to run in the current idle period, or if the
571 // associated window is currently in the background.
572 RefPtr<TimeoutHandler> mDelayedExecutorDispatcher;
573 // If not Nothing() then this value is the handle to the currently
574 // scheduled delayed executor dispatcher. This is needed to be able
575 // to cancel the timeout handler in case of the executor being
576 // cancelled.
577 Maybe<int32_t> mDelayedExecutorHandle;
578};
579
580NS_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; }
581 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; }
582
583NS_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"
, 583); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); 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.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestExecutor")
, (uint32_t)(sizeof(*this))); return count; }
584NS_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"
, 584); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 584
); __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); }
585
586NS_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"
, 586); 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
587 NS_INTERFACE_MAP_ENTRY(nsIRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRunnable>)) foundInterface = static_cast
<nsIRunnable*>(this); else
588 NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICancelableRunnable>)) foundInterface
= static_cast<nsICancelableRunnable*>(this); else
589 NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsINamed>)) foundInterface = static_cast
<nsINamed*>(this); else
590 NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdleRunnable>)) foundInterface
= static_cast<nsIIdleRunnable*>(this); else
591 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
592NS_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"
, 592); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 592); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
593
594NS_IMETHODIMPnsresult
595IdleRequestExecutor::GetName(nsACString& aName) {
596 aName.AssignLiteral("IdleRequestExecutor");
597 return NS_OK;
598}
599
600// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT.
601// See bug 1535398.
602MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult IdleRequestExecutor::Run() {
603 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", 603
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 603); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
604
605 mDispatched = false;
606 if (mWindow) {
607 RefPtr<nsGlobalWindowInner> window(mWindow);
608 window->ExecuteIdleRequest(mDeadline);
609 }
610
611 return NS_OK;
612}
613
614nsresult IdleRequestExecutor::Cancel() {
615 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", 615
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 615); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
616
617 if (mDelayedExecutorHandle && mWindow) {
618 mWindow->GetTimeoutManager()->ClearTimeout(
619 mDelayedExecutorHandle.value(), Timeout::Reason::eIdleCallbackTimeout);
620 }
621
622 mWindow = nullptr;
623 return NS_OK;
624}
625
626void IdleRequestExecutor::SetDeadline(TimeStamp aDeadline) {
627 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", 627
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 627); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
628
629 if (!mWindow) {
630 return;
631 }
632
633 mDeadline = aDeadline;
634}
635
636void IdleRequestExecutor::MaybeUpdateIdlePeriodLimit() {
637 if (TimeStamp::Now() > mIdlePeriodLimit.mEndOfIdlePeriod) {
638 mIdlePeriodLimit = {mDeadline, mWindow->LastIdleRequestHandle()};
639 }
640}
641
642void IdleRequestExecutor::MaybeDispatch(TimeStamp aDelayUntil) {
643 // If we've already dispatched the executor we don't want to do it
644 // again. Also, if we've called IdleRequestExecutor::Cancel mWindow
645 // will be null, which indicates that we shouldn't dispatch this
646 // executor either.
647 if (mDispatched || IsCancelled()) {
648 return;
649 }
650
651 mDispatched = true;
652
653 nsPIDOMWindowOuter* outer = mWindow->GetOuterWindow();
654 if (outer && outer->IsBackground()) {
655 // Set a timeout handler with a timeout of 0 ms to throttle idle
656 // callback requests coming from a backround window using
657 // background timeout throttling.
658 DelayedDispatch(0);
659 return;
660 }
661
662 TimeStamp now = TimeStamp::Now();
663 if (!aDelayUntil || aDelayUntil < now) {
664 ScheduleDispatch();
665 return;
666 }
667
668 TimeDuration delay = aDelayUntil - now;
669 DelayedDispatch(static_cast<uint32_t>(delay.ToMilliseconds()));
670}
671
672void IdleRequestExecutor::ScheduleDispatch() {
673 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"
, 673); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 673); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
674 mDelayedExecutorHandle = Nothing();
675 RefPtr<IdleRequestExecutor> request = this;
676 NS_DispatchToCurrentThreadQueue(request.forget(), EventQueuePriority::Idle);
677}
678
679void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) {
680 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"
, 680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 680); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
681 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"
, 681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDelayedExecutorHandle.isNothing()"
")"); do { MOZ_CrashSequence(__null, 681); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
682 int32_t handle;
683 mWindow->GetTimeoutManager()->SetTimeout(
684 mDelayedExecutorDispatcher, aDelay, false,
685 Timeout::Reason::eIdleCallbackTimeout, &handle);
686 mDelayedExecutorHandle = Some(handle);
687}
688
689bool IdleRequestExecutorTimeoutHandler::Call(const char* /* unused */) {
690 if (!mExecutor->IsCancelled()) {
691 mExecutor->ScheduleDispatch();
692 }
693 return true;
694}
695
696void nsGlobalWindowInner::ScheduleIdleRequestDispatch() {
697 AssertIsOnMainThread();
698
699 if (!mIdleRequestExecutor) {
700 mIdleRequestExecutor = MakeRefPtr<IdleRequestExecutor>(this);
701 }
702
703 mIdleRequestExecutor->MaybeDispatch();
704}
705
706void nsGlobalWindowInner::SuspendIdleRequests() {
707 if (mIdleRequestExecutor) {
708 mIdleRequestExecutor->Cancel();
709 mIdleRequestExecutor = nullptr;
710 }
711}
712
713void nsGlobalWindowInner::ResumeIdleRequests() {
714 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", 714
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIdleRequestExecutor"
")"); do { MOZ_CrashSequence(__null, 714); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
715
716 ScheduleIdleRequestDispatch();
717}
718
719void nsGlobalWindowInner::RemoveIdleCallback(
720 mozilla::dom::IdleRequest* aRequest) {
721 AssertIsOnMainThread();
722
723 if (aRequest->HasTimeout()) {
724 mTimeoutManager->ClearTimeout(aRequest->GetTimeoutHandle(),
725 Timeout::Reason::eIdleCallbackTimeout);
726 }
727
728 aRequest->RemoveFromList();
729}
730
731void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
732 DOMHighResTimeStamp aDeadline,
733 bool aDidTimeout) {
734 AssertIsOnMainThread();
735 // XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should
736 // guarantee that caller is holding a strong ref on the stack.
737 RefPtr<IdleRequest> request(aRequest);
738 RemoveIdleCallback(request);
739 request->IdleRun(this, aDeadline, aDidTimeout);
740}
741
742void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
743 AssertIsOnMainThread();
744 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
745
746 if (!request) {
747 // There are no more idle requests, so stop scheduling idle
748 // request callbacks.
749 return;
750 }
751
752 // If the request that we're trying to execute has been queued
753 // during the current idle period, then dispatch it again at the end
754 // of the idle period.
755 if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
756 mIdleRequestExecutor->MaybeDispatch(aDeadline);
757 return;
758 }
759
760 DOMHighResTimeStamp deadline = 0.0;
761
762 if (Performance* perf = GetPerformance()) {
763 deadline = perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline);
764 }
765
766 mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
767 RunIdleRequest(request, deadline, false);
768
769 // Running the idle callback could've suspended the window, in which
770 // case mIdleRequestExecutor will be null.
771 if (mIdleRequestExecutor) {
772 mIdleRequestExecutor->MaybeDispatch();
773 }
774}
775
776class IdleRequestTimeoutHandler final : public TimeoutHandler {
777 public:
778 IdleRequestTimeoutHandler(JSContext* aCx, IdleRequest* aIdleRequest,
779 nsPIDOMWindowInner* aWindow)
780 : TimeoutHandler(aCx), mIdleRequest(aIdleRequest), mWindow(aWindow) {}
781
782 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:
783 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"
, 783); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "IdleRequestTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 783); __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
784
785 MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override {
786 RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow));
787 RefPtr<IdleRequest> request(mIdleRequest);
788 window->RunIdleRequest(request, 0.0, true);
789 return true;
790 }
791
792 private:
793 ~IdleRequestTimeoutHandler() override = default;
794
795 RefPtr<IdleRequest> mIdleRequest;
796 nsCOMPtr<nsPIDOMWindowInner> mWindow;
797};
798
799NS_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;
}
800
801NS_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"
, 801); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); 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.incr
(base); NS_LogAddRef((this), (count), ("IdleRequestTimeoutHandler"
), (uint32_t)(sizeof(*this))); return count; }
802NS_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"
, 802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 802
); __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); }
803
804NS_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"
, 804); 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
805 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
806NS_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"
, 806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 806); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
807
808uint32_t nsGlobalWindowInner::RequestIdleCallback(
809 JSContext* aCx, IdleRequestCallback& aCallback,
810 const IdleRequestOptions& aOptions, ErrorResult& aError) {
811 AssertIsOnMainThread();
812
813 if (IsDying()) {
814 return 0;
815 }
816
817 uint32_t handle = mIdleRequestCallbackCounter++;
818
819 RefPtr request = MakeRefPtr<IdleRequest>(&aCallback, handle);
820
821 if (aOptions.mTimeout.WasPassed()) {
822 int32_t timeoutHandle;
823 RefPtr handler = MakeRefPtr<IdleRequestTimeoutHandler>(aCx, request, this);
824
825 nsresult rv = mTimeoutManager->SetTimeout(
826 handler, aOptions.mTimeout.Value(), false,
827 Timeout::Reason::eIdleCallbackTimeout, &timeoutHandle);
828
829 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"
, 829)
) {
830 return 0;
831 }
832
833 request->SetTimeoutHandle(timeoutHandle);
834 }
835
836 request->SetContainer(mIdleRequestCallbacksByHandle);
837 mIdleRequestCallbacks.insertBack(request);
838
839 if (!IsSuspended()) {
840 ScheduleIdleRequestDispatch();
841 }
842
843 return handle;
844}
845
846void nsGlobalWindowInner::CancelIdleCallback(uint32_t aHandle) {
847 if (IdleRequest* request = mIdleRequestCallbacksByHandle->Get(aHandle)) {
848 RemoveIdleCallback(request);
849 }
850}
851
852void nsGlobalWindowInner::DisableIdleCallbackRequests() {
853 if (mIdleRequestExecutor) {
854 mIdleRequestExecutor->Cancel();
855 mIdleRequestExecutor = nullptr;
856 }
857
858 while (!mIdleRequestCallbacks.isEmpty()) {
859 RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
860 RemoveIdleCallback(request);
861 }
862}
863
864bool nsGlobalWindowInner::IsBackgroundInternal() const {
865 return !mOuterWindow || mOuterWindow->IsBackground();
866}
867
868class PromiseDocumentFlushedResolver final {
869 public:
870 PromiseDocumentFlushedResolver(Promise* aPromise,
871 PromiseDocumentFlushedCallback& aCallback)
872 : mPromise(aPromise), mCallback(&aCallback) {}
873
874 virtual ~PromiseDocumentFlushedResolver() = default;
875
876 void Call() {
877 nsMutationGuard guard;
878 ErrorResult error;
879 JS::Rooted<JS::Value> returnVal(RootingCx());
880 mCallback->Call(&returnVal, error);
881
882 if (error.Failed()) {
883 mPromise->MaybeReject(std::move(error));
884 } else if (guard.Mutated(0)) {
885 // Something within the callback mutated the DOM.
886 mPromise->MaybeRejectWithNoModificationAllowedError(
887 "DOM mutated from promiseDocumentFlushed callbacks");
888 } else {
889 mPromise->MaybeResolve(returnVal);
890 }
891 }
892
893 RefPtr<Promise> mPromise;
894 RefPtr<PromiseDocumentFlushedCallback> mCallback;
895};
896
897//*****************************************************************************
898//*** nsGlobalWindowInner: Object Management
899//*****************************************************************************
900
901nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
902 WindowGlobalChild* aActor)
903 : nsPIDOMWindowInner(aOuterWindow, aActor),
904 mHasOrientationChangeListeners(false),
905 mWasOffline(false),
906 mHasHadSlowScript(false),
907 mIsChrome(false),
908 mCleanMessageManager(false),
909 mNeedsFocus(true),
910 mFocusByKeyOccurred(false),
911 mDidFireDocElemInserted(false),
912 mHasGamepad(false),
913 mHasXRSession(false),
914 mHasVRDisplayActivateEvents(false),
915 mXRRuntimeDetectionInFlight(false),
916 mXRPermissionRequestInFlight(false),
917 mXRPermissionGranted(false),
918 mWasCurrentInnerWindow(false),
919 mHasSeenGamepadInput(false),
920 mHintedWasLoading(false),
921 mHasOpenedExternalProtocolFrame(false),
922 mScrollMarksOnHScrollbar(false),
923 mStorageAllowedReasonCache(0),
924 mSuspendDepth(0),
925 mFreezeDepth(0),
926#ifdef DEBUG1
927 mSerial(0),
928#endif
929 mFocusMethod(0),
930 mIdleRequestCallbackCounter(1),
931 mIdleRequestCallbacksByHandle(new mozilla::dom::IdleRequestMap()),
932 mIdleRequestExecutor(nullptr),
933 mObservingRefresh(false),
934 mIteratingDocumentFlushedResolvers(false),
935 mCanSkipCCGeneration(0) {
936 mIsInnerWindow = true;
937
938 AssertIsOnMainThread();
939 SetIsOnMainThread();
940 nsLayoutStatics::AddRef();
941
942 // Initialize the PRCList (this).
943 PR_INIT_CLIST(this)do {(this)->next = (this); (this)->prev = (this); } while
(0)
;
944
945 // add this inner window to the outer window list of inners.
946 PR_INSERT_AFTER(this, aOuterWindow)do {(this)->next = (aOuterWindow)->next; (this)->prev
= (aOuterWindow); (aOuterWindow)->next->prev = (this);
(aOuterWindow)->next = (this); } while (0)
;
947
948 mTimeoutManager = std::make_unique<dom::TimeoutManager>(
949 *this, StaticPrefs::dom_timeout_max_idle_defer_ms(),
950 static_cast<nsISerialEventTarget*>(nsPIDOMWindowInner::From(this)
951 ->GetBrowsingContextGroup()
952 ->GetTimerEventQueue()));
953
954 mObserver = MakeRefPtr<nsGlobalWindowObserver>(this);
955 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
956 // Watch for online/offline status changes so we can fire events. Use
957 // a strong reference.
958 os->AddObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed", false);
959 os->AddObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure", false);
960 os->AddObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed", false);
961 os->AddObserver(mObserver, "browser-perm-changed", false);
962 os->AddObserver(mObserver, "screen-information-changed", false);
963 os->AddObserver(mObserver, "audio-playback", false);
964 }
965
966 Preferences::AddStrongObserver(mObserver, "intl.accept_languages");
967
968 // Watch for storage notifications so we can fire storage events.
969 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
970 if (sns) {
971 sns->Register(mObserver);
972 }
973
974 if (XRE_IsContentProcess()) {
975 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
976 if (docShell) {
977 mBrowserChild = docShell->GetBrowserChild();
978 }
979 }
980
981 if (gDumpFile == nullptr) {
982 nsAutoCString fname;
983 Preferences::GetCString("browser.dom.window.dump.file", fname);
984 if (!fname.IsEmpty()) {
985 // If this fails to open, Dump() knows to just go to stdout on null.
986 gDumpFile = fopen(fname.get(), "wb+");
987 } else {
988 gDumpFile = stdoutstdout;
989 }
990 }
991
992#ifdef DEBUG1
993 mSerial = nsContentUtils::InnerOrOuterWindowCreated();
994
995 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
996 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)
997 ("++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)
998 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)
999 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)
1000 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)
;
1001
1002 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
1003 if (obs) {
1004 nsString data;
1005 data.AppendPrintf(
1006 "serial=%d address=0x%" PRIxPTR"l" "x" " type=inner outer=0x%" PRIxPTR"l" "x",
1007 mSerial, reinterpret_cast<uintptr_t>(ToCanonicalSupports(this)),
1008 reinterpret_cast<uintptr_t>(ToCanonicalSupports(aOuterWindow)));
1009 obs->NotifyObservers(nullptr, "debug-domwindow-created", data.get());
1010 }
1011 }
1012#endif
1013
1014 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)
1015 ("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)
;
1016
1017 // Add ourselves to the inner windows list.
1018 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"
, 1018); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sInnerWindowsById"
") (" "Inner Windows hash table must be created!" ")"); do {
MOZ_CrashSequence(__null, 1018); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1019 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"
, 1020); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1020); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1020 "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"
, 1020); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!sInnerWindowsById->Contains(mWindowID)"
") (" "This window shouldn't be in the hash table yet!" ")")
; do { MOZ_CrashSequence(__null, 1020); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1021 // We seem to see crashes in release builds because of null
1022 // |sInnerWindowsById|.
1023 if (sInnerWindowsById) {
1024 sInnerWindowsById->InsertOrUpdate(mWindowID, this);
1025 }
1026}
1027
1028#ifdef DEBUG1
1029
1030/* static */
1031void nsGlobalWindowInner::AssertIsOnMainThread() {
1032 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", 1032
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1032); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1033}
1034
1035#endif // DEBUG
1036
1037/* static */
1038void nsGlobalWindowInner::Init() {
1039 AssertIsOnMainThread();
1040
1041 NS_ASSERTION(gDOMLeakPRLogInner,do { if (!(gDOMLeakPRLogInner)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "gDOMLeakPRLogInner should have been initialized!", "gDOMLeakPRLogInner"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 1042
); MOZ_PretendNoReturn(); } } while (0)
1042 "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", 1042
); MOZ_PretendNoReturn(); } } while (0)
;
1043
1044 sInnerWindowsById = new InnerWindowByIdTable();
1045}
1046
1047nsGlobalWindowInner::~nsGlobalWindowInner() {
1048 AssertIsOnMainThread();
1049 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", 1049
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHintedWasLoading"
")"); do { MOZ_CrashSequence(__null, 1049); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1050
1051 if (IsChromeWindow()) {
1052 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", 1053
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1053); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1053 "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", 1053
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCleanMessageManager"
") (" "chrome windows may always disconnect the msg manager"
")"); do { MOZ_CrashSequence(__null, 1053); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1054
1055 DisconnectAndClearGroupMessageManagers();
1056
1057 if (mChromeFields.mMessageManager) {
1058 static_cast<nsFrameMessageManager*>(mChromeFields.mMessageManager.get())
1059 ->Disconnect();
1060 }
1061
1062 mCleanMessageManager = false;
1063 }
1064
1065 // In most cases this should already have been called, but call it again
1066 // here to catch any corner cases.
1067 FreeInnerObjects();
1068
1069 if (sInnerWindowsById) {
1070 sInnerWindowsById->Remove(mWindowID);
1071 }
1072
1073 nsContentUtils::InnerOrOuterWindowDestroyed();
1074
1075#ifdef DEBUG1
1076 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
1077 nsAutoCString url;
1078 if (mLastOpenedURI) {
1079 url = mLastOpenedURI->GetSpecOrDefault();
1080
1081 // Data URLs can be very long, so truncate to avoid flooding the log.
1082 const uint32_t maxURLLength = 1000;
1083 if (url.Length() > maxURLLength) {
1084 url.Truncate(maxURLLength);
1085 }
1086 }
1087
1088 nsGlobalWindowOuter* outer = nsGlobalWindowOuter::Cast(mOuterWindow);
1089 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)
1090 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)
1091 ("--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)
1092 "%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)
1093 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)
1094 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)
1095 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)
;
1096
1097 uint32_t serial = mSerial;
1098 NS_DispatchToMainThread(
1099 NS_NewRunnableFunction(
1100 "TestDOMWindowDestroyed",
1101 [serial, url = std::move(url)] {
1102 nsCOMPtr<nsIObserverService> obs =
1103 mozilla::services::GetObserverService();
1104 if (obs) {
1105 nsString data;
1106 data.AppendPrintf("serial=%d type=inner url=%s", serial,
1107 url.get());
1108 obs->NotifyObservers(nullptr, "debug-domwindow-destroyed",
1109 data.get());
1110 }
1111 }),
1112 NS_DISPATCH_FALLIBLEnsIEventTarget::DISPATCH_FALLIBLE);
1113 }
1114#endif
1115 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)
1116 ("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)
;
1117
1118 // An inner window is destroyed, pull it out of the outer window's
1119 // list if inner windows.
1120
1121 PR_REMOVE_LINK(this)do {(this)->prev->next = (this)->next; (this)->next
->prev = (this)->prev; } while (0)
;
1122
1123 // If our outer window's inner window is this window, null out the
1124 // outer window's reference to this window that's being deleted.
1125 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1126 if (outer) {
1127 outer->MaybeClearInnerWindow(this);
1128 }
1129
1130 // We don't have to leave the tab group if we are an inner window.
1131
1132 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
1133 if (ac) ac->RemoveWindowAsListener(this);
1134
1135 nsLayoutStatics::Release();
1136}
1137
1138// static
1139void nsGlobalWindowInner::ShutDown() {
1140 AssertIsOnMainThread();
1141
1142 if (gDumpFile && gDumpFile != stdoutstdout) {
1143 fclose(gDumpFile);
1144 }
1145 gDumpFile = nullptr;
1146
1147 sInnerWindowsById = nullptr;
1148}
1149
1150void nsGlobalWindowInner::FreeInnerObjects() {
1151 if (IsDying()) {
1152 return;
1153 }
1154 StartDying();
1155
1156 if (JSObject* global = GetWrapperPreserveColor()) {
1157 js::SetRealmIsDyingHint(global);
1158 }
1159
1160 ClearHasPointerRawUpdateEventListeners();
1161
1162 if (mDoc && mDoc->GetWindowContext()) {
1163 // The document is about to lose its window, so this is a good time to send
1164 // our page use counters.
1165 //
1166 // (We also do this in Document::SetScriptGlobalObject(nullptr), which
1167 // catches most cases of documents losing their window, but not all.)
1168 mDoc->SendPageUseCounters();
1169 }
1170
1171 // Make sure that this is called before we null out the document and
1172 // other members that the window destroyed observers could
1173 // re-create.
1174 if (auto* reporter = nsWindowMemoryReporter::Get()) {
1175 reporter->ObserveDOMWindowDetached(this);
1176 }
1177
1178 // Kill all of the workers for this window.
1179 CancelWorkersForWindow(*this);
1180
1181 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
1182 mSharedWorkers.ForwardRange()) {
1183 pinnedWorker->Close();
1184 }
1185
1186 if (mTimeoutManager) {
1187 mTimeoutManager->ClearAllTimeouts();
1188 }
1189
1190 DisableIdleCallbackRequests();
1191
1192 mChromeEventHandler = nullptr;
1193
1194 if (mListenerManager) {
1195 mListenerManager->RemoveAllListeners();
1196 mListenerManager->Disconnect();
1197 mListenerManager = nullptr;
1198 }
1199
1200 mHistory = nullptr;
1201
1202 mNavigation = nullptr;
1203
1204 if (mNavigator) {
1205 mNavigator->OnNavigation();
1206 mNavigator->Invalidate();
1207 mNavigator = nullptr;
1208 }
1209
1210 mScreen = nullptr;
1211
1212 if (mDoc) {
1213 // Remember the document's principal, URI, and policyContainer.
1214 mDocumentPrincipal = mDoc->NodePrincipal();
1215 mDocumentCookiePrincipal = mDoc->EffectiveCookiePrincipal();
1216 mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
1217 mDocumentPartitionedPrincipal = mDoc->PartitionedPrincipal();
1218 mDocumentURI = mDoc->GetDocumentURI();
1219 mDocBaseURI = mDoc->GetDocBaseURI();
1220 mDocumentPolicyContainer = mDoc->GetPolicyContainer();
1221
1222 while (mDoc->EventHandlingSuppressed()) {
1223 mDoc->UnsuppressEventHandlingAndFireEvents(false);
1224 }
1225 }
1226
1227 // Remove our reference to the document and the document principal.
1228 mFocusedElement = nullptr;
1229
1230 // Unregister any remaining media source blob: URLs created by this window.
1231 if (RefPtr<DocGroup> docGroup = GetDocGroup()) {
1232 nsTArray<nsCString> mediaSourceURLs = std::move(mMediaSourceURLs);
1233 for (auto& url : mediaSourceURLs) {
1234 docGroup->UnregisterMediaSourceURL(url, /* aNotifyWindow */ false);
1235 }
1236 }
1237
1238 nsIGlobalObject::UnlinkObjectsInGlobal();
1239
1240 NotifyWindowIDDestroyed("inner-window-destroyed");
1241
1242 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
1243 mAudioContexts[i]->OnWindowDestroy();
1244 }
1245 mAudioContexts.Clear();
1246
1247 for (MediaKeys* mediaKeys : mMediaKeysInstances) {
1248 mediaKeys->OnInnerWindowDestroy();
1249 }
1250 mMediaKeysInstances.Clear();
1251
1252 DisableGamepadUpdates();
1253 mHasGamepad = false;
1254 mGamepads.Clear();
1255 DisableVRUpdates();
1256 mHasXRSession = false;
1257 mHasVRDisplayActivateEvents = false;
1258 mXRRuntimeDetectionInFlight = false;
1259 mXRPermissionRequestInFlight = false;
1260 mXRPermissionGranted = false;
1261 mVRDisplays.Clear();
1262
1263 // This breaks a cycle between the window and the ClientSource object.
1264 mClientSource.reset();
1265
1266 if (mWindowGlobalChild) {
1267 // Remove any remaining listeners.
1268 int64_t nListeners = mWindowGlobalChild->BeforeUnloadListeners();
1269 for (int64_t i = 0; i < nListeners; ++i) {
1270 mWindowGlobalChild->BeforeUnloadRemoved();
1271 }
1272 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", 1272
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() == 0"
")"); do { MOZ_CrashSequence(__null, 1272); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1273 }
1274
1275 // If we have any promiseDocumentFlushed callbacks, fire them now so
1276 // that the Promises can resolve.
1277 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
1278
1279 DisconnectGlobalTeardownObservers();
1280
1281#ifdef MOZ_WIDGET_ANDROID
1282 DisableOrientationChangeListener();
1283#endif
1284
1285 if (mObserver) {
1286 if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) {
1287 os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed");
1288 os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure");
1289 os->RemoveObserver(mObserver, PERMISSION_CHANGED_TOPIC"perm-changed");
1290 os->RemoveObserver(mObserver, "browser-perm-changed");
1291 os->RemoveObserver(mObserver, "screen-information-changed");
1292 os->RemoveObserver(mObserver, "audio-playback");
1293 }
1294
1295 RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
1296 if (sns) {
1297 sns->Unregister(mObserver);
1298 }
1299
1300 Preferences::RemoveObserver(mObserver, "intl.accept_languages");
1301
1302 // Drop its reference to this dying window, in case for some bogus reason
1303 // the object stays around.
1304 mObserver->Forget();
1305 }
1306
1307 mMenubar = nullptr;
1308 mToolbar = nullptr;
1309 mLocationbar = nullptr;
1310 mPersonalbar = nullptr;
1311 mStatusbar = nullptr;
1312 mScrollbars = nullptr;
1313
1314 mConsole = nullptr;
1315 mCookieStore = nullptr;
1316 mDocumentPiP = nullptr;
1317 mPushManager = nullptr;
1318 mCloseWatcherManager = nullptr;
1319
1320 mPaintWorklet = nullptr;
1321
1322 mExternal = nullptr;
1323
1324 if (mLocalStorage) {
1325 mLocalStorage->Disconnect();
1326 mLocalStorage = nullptr;
1327 }
1328 mSessionStorage = nullptr;
1329 if (mPerformance) {
1330 // Since window is dying, nothing is going to be painted with meaningful
1331 // sizes, so the temp data for LCP and container timing is no longer needed.
1332 // Clearing the container timing records also drops their raw element keys.
1333 auto* perf = static_cast<PerformanceMainThread*>(mPerformance.get());
1334 perf->ClearGeneratedTempDataForLCP();
1335 perf->ClearContainerTimingData();
1336 }
1337 mPerformance = nullptr;
1338
1339 mContentMediaController = nullptr;
1340
1341 if (mWebTaskScheduler) {
1342 mWebTaskScheduler->Disconnect();
1343 mWebTaskScheduler = nullptr;
1344 }
1345
1346 mTrustedTypePolicyFactory = nullptr;
1347
1348 mSharedWorkers.Clear();
1349
1350#ifdef MOZ_WEBSPEECH1
1351 mSpeechSynthesis = nullptr;
1352#endif
1353
1354 mGlean = nullptr;
1355 mGleanPings = nullptr;
1356
1357 mParentTarget = nullptr;
1358
1359 if (mCleanMessageManager) {
1360 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",
1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIsChrome" ") ("
"only chrome should have msg manager cleaned" ")"); do { MOZ_CrashSequence
(__null, 1360); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1361 if (mChromeFields.mMessageManager) {
1362 mChromeFields.mMessageManager->Disconnect();
1363 }
1364 }
1365
1366 if (mWindowGlobalChild && !mWindowGlobalChild->IsClosed()) {
1367 mWindowGlobalChild->Destroy();
1368 }
1369
1370 mIntlUtils = nullptr;
1371
1372 HintIsLoading(false);
1373}
1374
1375//*****************************************************************************
1376// nsGlobalWindowInner::nsISupports
1377//*****************************************************************************
1378
1379// QueryInterface implementation for nsGlobalWindowInner
1380NS_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"
, 1380); 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
1381 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRYif (aIID.Equals((nsWrapperCache::kIID))) { *aInstancePtr = static_cast
<nsWrapperCache*>(this); return NS_OK; } else
1382 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
1383 NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDOMWindow>)) foundInterface = static_cast
<nsIDOMWindow*>(this); else
1384 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIGlobalObject>)) foundInterface
= static_cast<nsIGlobalObject*>(this); else
1385 NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptGlobalObject>)) foundInterface
= static_cast<nsIScriptGlobalObject*>(this); else
1386 NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIScriptObjectPrincipal>)) foundInterface
= static_cast<nsIScriptObjectPrincipal*>(this); else
1387 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
1388 NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowInner)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsPIDOMWindowInner>)) foundInterface
= static_cast<nsPIDOMWindowInner*>(this); else
1389 NS_INTERFACE_MAP_ENTRY(mozIDOMWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozIDOMWindow>)) foundInterface =
static_cast<mozIDOMWindow*>(this); else
1390 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
1391 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInterfaceRequestor>)) foundInterface
= static_cast<nsIInterfaceRequestor*>(this); else
1392NS_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"
, 1392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 1392); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1393
1394NS_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"
, 1394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); 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.incr
(base); NS_LogAddRef((this), (count), ("nsGlobalWindowInner")
, (uint32_t)(sizeof(*this))); return count; }
1395NS_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"
, 1395); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1395
); __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); }
1396
1397NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipReal( void*
p, [[maybe_unused]] bool aRemovingAllowed) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1398 if (tmp->IsBlackForCC(false)) {
1399 if (nsCCUncollectableMarker::InGeneration(tmp->mCanSkipCCGeneration)) {
1400 return true;
1401 }
1402 tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration;
1403 if (EventListenerManager* elm = tmp->GetExistingListenerManager()) {
1404 elm->MarkForCC();
1405 }
1406 if (tmp->mTimeoutManager) {
1407 tmp->mTimeoutManager->UnmarkGrayTimers();
1408 }
1409 return true;
1410 }
1411NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END(void)tmp; return false; }
1412
1413NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipInCCReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1414 return tmp->IsBlackForCC(true);
1415NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END(void)tmp; return false; }
1416
1417NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowInner)bool nsGlobalWindowInner::cycleCollection::CanSkipThisReal(void
* p) { nsGlobalWindowInner* tmp = DowncastCCParticipant<nsGlobalWindowInner
>(p);
1418 return tmp->IsBlackForCC(false);
1419NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END(void)tmp; return false; }
1420
1421NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowInner)nsGlobalWindowInner::cycleCollection nsGlobalWindowInner::_cycleCollectorGlobal
;
1422
1423NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)nsresult nsGlobalWindowInner::cycleCollection::TraverseNative
( void* p, nsCycleCollectionTraversalCallback& cb) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1424 if (MOZ_UNLIKELY(cb.WantDebugInfo())(__builtin_expect(!!(cb.WantDebugInfo()), 0))) {
1425 char name[512];
1426 nsAutoCString uri;
1427 if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
1428 uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
1429 }
1430 SprintfLiteral(name, "nsGlobalWindowInner # %" PRIu64"l" "u" " inner %s",
1431 tmp->mWindowID, uri.get());
1432 cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
1433 } else {
1434 NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindowInner, tmp->mRefCnt.get())cb.DescribeRefCountedNode(tmp->mRefCnt.get(), "nsGlobalWindowInner"
);
1435 }
1436
1437 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigation)ImplCycleCollectionTraverse(cb, tmp->mNavigation, "mNavigation"
, 0);
1438
1439 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)ImplCycleCollectionTraverse(cb, tmp->mNavigator, "mNavigator"
, 0);
1440
1441 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)ImplCycleCollectionTraverse(cb, tmp->mPerformance, "mPerformance"
, 0);
1442
1443 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebTaskScheduler)ImplCycleCollectionTraverse(cb, tmp->mWebTaskScheduler, "mWebTaskScheduler"
, 0);
1444
1445 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTrustedTypePolicyFactory)ImplCycleCollectionTraverse(cb, tmp->mTrustedTypePolicyFactory
, "mTrustedTypePolicyFactory", 0);
1446
1447#ifdef MOZ_WEBSPEECH1
1448 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)ImplCycleCollectionTraverse(cb, tmp->mSpeechSynthesis, "mSpeechSynthesis"
, 0);
1449#endif
1450
1451 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlean)ImplCycleCollectionTraverse(cb, tmp->mGlean, "mGlean", 0);
1452 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGleanPings)ImplCycleCollectionTraverse(cb, tmp->mGleanPings, "mGleanPings"
, 0);
1453
1454 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOuterWindow)ImplCycleCollectionTraverse(cb, tmp->mOuterWindow, "mOuterWindow"
, 0);
1455
1456 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopInnerWindow)ImplCycleCollectionTraverse(cb, tmp->mTopInnerWindow, "mTopInnerWindow"
, 0);
1457
1458 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)ImplCycleCollectionTraverse(cb, tmp->mListenerManager, "mListenerManager"
, 0);
1459
1460 if (tmp->mTimeoutManager) {
1461 tmp->mTimeoutManager->ForEachUnorderedTimeout([&cb](Timeout* timeout) {
1462 cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(Timeout)Timeout::cycleCollection::GetParticipant());
1463 });
1464 }
1465
1466 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)ImplCycleCollectionTraverse(cb, tmp->mLocation, "mLocation"
, 0);
1467 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHistory)ImplCycleCollectionTraverse(cb, tmp->mHistory, "mHistory",
0);
1468 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCustomElements)ImplCycleCollectionTraverse(cb, tmp->mCustomElements, "mCustomElements"
, 0);
1469 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSharedWorkers)ImplCycleCollectionTraverse(cb, tmp->mSharedWorkers, "mSharedWorkers"
, 0);
1470 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)ImplCycleCollectionTraverse(cb, tmp->mLocalStorage, "mLocalStorage"
, 0);
1471 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)ImplCycleCollectionTraverse(cb, tmp->mSessionStorage, "mSessionStorage"
, 0);
1472 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)ImplCycleCollectionTraverse(cb, tmp->mIndexedDB, "mIndexedDB"
, 0);
1473 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPrincipal, "mDocumentPrincipal"
, 0);
1474 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentCookiePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentCookiePrincipal
, "mDocumentCookiePrincipal", 0);
1475 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentStoragePrincipal
, "mDocumentStoragePrincipal", 0);
1476 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPartitionedPrincipal)ImplCycleCollectionTraverse(cb, tmp->mDocumentPartitionedPrincipal
, "mDocumentPartitionedPrincipal", 0);
1477 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPolicyContainer)ImplCycleCollectionTraverse(cb, tmp->mDocumentPolicyContainer
, "mDocumentPolicyContainer", 0);
1478 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserChild)ImplCycleCollectionTraverse(cb, tmp->mBrowserChild, "mBrowserChild"
, 0);
1479 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)ImplCycleCollectionTraverse(cb, tmp->mDoc, "mDoc", 0);
1480 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebIdentityHandler)ImplCycleCollectionTraverse(cb, tmp->mWebIdentityHandler, "mWebIdentityHandler"
, 0);
1481
1482 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIdleRequestExecutor)ImplCycleCollectionTraverse(cb, tmp->mIdleRequestExecutor,
"mIdleRequestExecutor", 0);
1483 for (IdleRequest* request : tmp->mIdleRequestCallbacks) {
1484 cb.NoteNativeChild(request, NS_CYCLE_COLLECTION_PARTICIPANT(IdleRequest)IdleRequest::cycleCollection::GetParticipant());
1485 }
1486
1487 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClientSource)ImplCycleCollectionTraverse(cb, tmp->mClientSource, "mClientSource"
, 0);
1488
1489 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)ImplCycleCollectionTraverse(cb, tmp->mGamepads, "mGamepads"
, 0);
1490
1491 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)ImplCycleCollectionTraverse(cb, tmp->mCacheStorage, "mCacheStorage"
, 0);
1492 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)ImplCycleCollectionTraverse(cb, tmp->mVRDisplays, "mVRDisplays"
, 0);
1493
1494 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)ImplCycleCollectionTraverse(cb, tmp->mDebuggerNotificationManager
, "mDebuggerNotificationManager", 0);
1495
1496 // Traverse stuff from nsPIDOMWindow
1497 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler, "mChromeEventHandler"
, 0);
1498 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)ImplCycleCollectionTraverse(cb, tmp->mParentTarget, "mParentTarget"
, 0);
1499 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedElement)ImplCycleCollectionTraverse(cb, tmp->mFocusedElement, "mFocusedElement"
, 0);
1500 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0);
1501 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobalChild)ImplCycleCollectionTraverse(cb, tmp->mWindowGlobalChild, "mWindowGlobalChild"
, 0);
1502 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCloseWatcherManager)ImplCycleCollectionTraverse(cb, tmp->mCloseWatcherManager,
"mCloseWatcherManager", 0);
1503
1504 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenubar)ImplCycleCollectionTraverse(cb, tmp->mMenubar, "mMenubar",
0);
1505 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToolbar)ImplCycleCollectionTraverse(cb, tmp->mToolbar, "mToolbar",
0);
1506 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)ImplCycleCollectionTraverse(cb, tmp->mLocationbar, "mLocationbar"
, 0);
1507 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)ImplCycleCollectionTraverse(cb, tmp->mPersonalbar, "mPersonalbar"
, 0);
1508 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)ImplCycleCollectionTraverse(cb, tmp->mStatusbar, "mStatusbar"
, 0);
1509 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)ImplCycleCollectionTraverse(cb, tmp->mScrollbars, "mScrollbars"
, 0);
1510 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)ImplCycleCollectionTraverse(cb, tmp->mCrypto, "mCrypto", 0
);
1511 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)ImplCycleCollectionTraverse(cb, tmp->mConsole, "mConsole",
0);
1512 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCookieStore)ImplCycleCollectionTraverse(cb, tmp->mCookieStore, "mCookieStore"
, 0);
1513 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPiP)ImplCycleCollectionTraverse(cb, tmp->mDocumentPiP, "mDocumentPiP"
, 0);
1514 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPushManager)ImplCycleCollectionTraverse(cb, tmp->mPushManager, "mPushManager"
, 0);
1515 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)ImplCycleCollectionTraverse(cb, tmp->mPaintWorklet, "mPaintWorklet"
, 0);
1516 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)ImplCycleCollectionTraverse(cb, tmp->mExternal, "mExternal"
, 0);
1517 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)ImplCycleCollectionTraverse(cb, tmp->mIntlUtils, "mIntlUtils"
, 0);
1518 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualViewport)ImplCycleCollectionTraverse(cb, tmp->mVisualViewport, "mVisualViewport"
, 0);
1519 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPasteDataTransfer)ImplCycleCollectionTraverse(cb, tmp->mCurrentPasteDataTransfer
, "mCurrentPasteDataTransfer", 0);
1520
1521 tmp->TraverseObjectsInGlobal(cb);
1522
1523 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mMessageManager
, "mChromeFields.mMessageManager", 0);
1524 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)ImplCycleCollectionTraverse(cb, tmp->mChromeFields.mGroupMessageManagers
, "mChromeFields.mGroupMessageManagers", 0);
1525
1526 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1527 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mPromise, "mDocumentFlushedResolvers[i]->mPromise"
, 0);
;
1528 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionTraverse(cb, tmp->mDocumentFlushedResolvers
[i]->mCallback, "mDocumentFlushedResolvers[i]->mCallback"
, 0);
;
1529 }
1530
1531NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
1532
1533NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)void nsGlobalWindowInner::cycleCollection::Unlink(void* p) { nsGlobalWindowInner
* tmp = DowncastCCParticipant<nsGlobalWindowInner>(p);
1534 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences();
1535 if (sInnerWindowsById) {
1536 sInnerWindowsById->Remove(tmp->mWindowID);
1537 }
1538
1539 JSObject* wrapper = tmp->GetWrapperPreserveColor();
1540 if (wrapper) {
1541 // Mark our realm as dead, so the JS engine won't hand out our
1542 // global after this point.
1543 JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
1544 }
1545
1546 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1547
1548 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)ImplCycleCollectionUnlink(tmp->mNavigator);
1549
1550 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)ImplCycleCollectionUnlink(tmp->mPerformance);
1551
1552 if (tmp->mWebTaskScheduler) {
1553 tmp->mWebTaskScheduler->Disconnect();
1554 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebTaskScheduler)ImplCycleCollectionUnlink(tmp->mWebTaskScheduler);
1555 }
1556
1557 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTrustedTypePolicyFactory)ImplCycleCollectionUnlink(tmp->mTrustedTypePolicyFactory);
1558
1559#ifdef MOZ_WEBSPEECH1
1560 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)ImplCycleCollectionUnlink(tmp->mSpeechSynthesis);
1561#endif
1562
1563 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlean)ImplCycleCollectionUnlink(tmp->mGlean);
1564 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGleanPings)ImplCycleCollectionUnlink(tmp->mGleanPings);
1565
1566 if (tmp->mOuterWindow) {
1567 nsGlobalWindowOuter::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp);
1568 NS_IMPL_CYCLE_COLLECTION_UNLINK(mOuterWindow)ImplCycleCollectionUnlink(tmp->mOuterWindow);
1569 }
1570
1571 if (tmp->mListenerManager) {
1572 tmp->mListenerManager->Disconnect();
1573 NS_IMPL_CYCLE_COLLECTION_UNLINK(mListenerManager)ImplCycleCollectionUnlink(tmp->mListenerManager);
1574 }
1575
1576 // Here the Timeouts list would've been unlinked, but we rely on
1577 // that Timeout objects have been traced and will remove themselves
1578 // while unlinking.
1579
1580 tmp->UpdateTopInnerWindow();
1581 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTopInnerWindow)ImplCycleCollectionUnlink(tmp->mTopInnerWindow);
1582
1583 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)ImplCycleCollectionUnlink(tmp->mLocation);
1584 NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)ImplCycleCollectionUnlink(tmp->mHistory);
1585 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigation)ImplCycleCollectionUnlink(tmp->mNavigation);
1586 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)ImplCycleCollectionUnlink(tmp->mCustomElements);
1587 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSharedWorkers)ImplCycleCollectionUnlink(tmp->mSharedWorkers);
1588 if (tmp->mLocalStorage) {
1589 tmp->mLocalStorage->Disconnect();
1590 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)ImplCycleCollectionUnlink(tmp->mLocalStorage);
1591 }
1592 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)ImplCycleCollectionUnlink(tmp->mSessionStorage);
1593 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)ImplCycleCollectionUnlink(tmp->mIndexedDB);
1594 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPrincipal);
1595 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentCookiePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentCookiePrincipal);
1596 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)ImplCycleCollectionUnlink(tmp->mDocumentStoragePrincipal);
1597 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPartitionedPrincipal)ImplCycleCollectionUnlink(tmp->mDocumentPartitionedPrincipal
);
1598 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPolicyContainer)ImplCycleCollectionUnlink(tmp->mDocumentPolicyContainer);
1599 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserChild)ImplCycleCollectionUnlink(tmp->mBrowserChild);
1600 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)ImplCycleCollectionUnlink(tmp->mDoc);
1601 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebIdentityHandler)ImplCycleCollectionUnlink(tmp->mWebIdentityHandler);
1602
1603 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)ImplCycleCollectionUnlink(tmp->mGamepads);
1604
1605 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)ImplCycleCollectionUnlink(tmp->mCacheStorage);
1606 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)ImplCycleCollectionUnlink(tmp->mVRDisplays);
1607
1608 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)ImplCycleCollectionUnlink(tmp->mDebuggerNotificationManager
);
1609
1610 // Unlink stuff from nsPIDOMWindow
1611 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)ImplCycleCollectionUnlink(tmp->mChromeEventHandler);
1612 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)ImplCycleCollectionUnlink(tmp->mParentTarget);
1613 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedElement)ImplCycleCollectionUnlink(tmp->mFocusedElement);
1614 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)ImplCycleCollectionUnlink(tmp->mBrowsingContext);
1615
1616 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",
1618); 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, 1618); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1617 !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",
1618); 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, 1618); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1618 "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",
1618); 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, 1618); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1619 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobalChild)ImplCycleCollectionUnlink(tmp->mWindowGlobalChild);
1620 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCloseWatcherManager)ImplCycleCollectionUnlink(tmp->mCloseWatcherManager);
1621
1622 NS_IMPL_CYCLE_COLLECTION_UNLINK(mMenubar)ImplCycleCollectionUnlink(tmp->mMenubar);
1623 NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)ImplCycleCollectionUnlink(tmp->mToolbar);
1624 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)ImplCycleCollectionUnlink(tmp->mLocationbar);
1625 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)ImplCycleCollectionUnlink(tmp->mPersonalbar);
1626 NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)ImplCycleCollectionUnlink(tmp->mStatusbar);
1627 NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)ImplCycleCollectionUnlink(tmp->mScrollbars);
1628 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)ImplCycleCollectionUnlink(tmp->mCrypto);
1629 NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)ImplCycleCollectionUnlink(tmp->mConsole);
1630 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCookieStore)ImplCycleCollectionUnlink(tmp->mCookieStore);
1631 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)ImplCycleCollectionUnlink(tmp->mPaintWorklet);
1632 NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)ImplCycleCollectionUnlink(tmp->mExternal);
1633 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)ImplCycleCollectionUnlink(tmp->mIntlUtils);
1634 NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualViewport)ImplCycleCollectionUnlink(tmp->mVisualViewport);
1635 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCurrentPasteDataTransfer)ImplCycleCollectionUnlink(tmp->mCurrentPasteDataTransfer);
1636
1637 tmp->UnlinkObjectsInGlobal();
1638
1639 NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)ImplCycleCollectionUnlink(tmp->mIdleRequestExecutor);
1640
1641 // Here the IdleRequest list would've been unlinked, but we rely on
1642 // that IdleRequest objects have been traced and will remove
1643 // themselves while unlinking.
1644
1645 NS_IMPL_CYCLE_COLLECTION_UNLINK(mClientSource)ImplCycleCollectionUnlink(tmp->mClientSource);
1646
1647 if (tmp->IsChromeWindow()) {
1648 if (tmp->mChromeFields.mMessageManager) {
1649 static_cast<nsFrameMessageManager*>(
1650 tmp->mChromeFields.mMessageManager.get())
1651 ->Disconnect();
1652 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)ImplCycleCollectionUnlink(tmp->mChromeFields.mMessageManager
);
1653 }
1654 tmp->DisconnectAndClearGroupMessageManagers();
1655 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mGroupMessageManagers)ImplCycleCollectionUnlink(tmp->mChromeFields.mGroupMessageManagers
);
1656 }
1657
1658 for (size_t i = 0; i < tmp->mDocumentFlushedResolvers.Length(); i++) {
1659 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mPromise)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mPromise);
;
1660 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentFlushedResolvers[i]->mCallback)ImplCycleCollectionUnlink(tmp->mDocumentFlushedResolvers[i
]->mCallback);
;
1661 }
1662 tmp->mDocumentFlushedResolvers.Clear();
1663
1664 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPERtmp->ReleaseWrapper(p);
1665NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
1666
1667#ifdef DEBUG1
1668void nsGlobalWindowInner::RiskyUnlink() {
1669 NS_CYCLE_COLLECTION_INNERNAME_cycleCollectorGlobal.Unlink(this);
1670}
1671#endif
1672
1673NS_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);
1674 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPERtmp->TraceWrapper(aCallbacks, aClosure);
1675NS_IMPL_CYCLE_COLLECTION_TRACE_END(void)tmp; }
1676
1677bool nsGlobalWindowInner::IsBlackForCC(bool aTracingNeeded) {
1678 if (!nsCCUncollectableMarker::sGeneration) {
1679 return false;
1680 }
1681
1682 return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) ||
1683 HasKnownLiveWrapper()) &&
1684 (!aTracingNeeded || HasNothingToTrace(ToSupports(this)));
1685}
1686
1687//*****************************************************************************
1688// nsGlobalWindowInner::nsIScriptGlobalObject
1689//*****************************************************************************
1690
1691bool nsGlobalWindowInner::ShouldResistFingerprinting(RFPTarget aTarget) const {
1692 if (mDoc) {
1693 return mDoc->ShouldResistFingerprinting(aTarget);
1694 }
1695 return nsContentUtils::ShouldResistFingerprinting(
1696 "If we do not have a document then we do not have any context"
1697 "to make an informed RFP choice, so we fall back to the global pref",
1698 aTarget);
1699}
1700
1701OriginTrials nsGlobalWindowInner::Trials() const {
1702 return OriginTrials::FromWindow(this);
1703}
1704
1705FontFaceSet* nsGlobalWindowInner::GetFonts() {
1706 if (mDoc) {
1707 return mDoc->Fonts();
1708 }
1709 return nullptr;
1710}
1711
1712mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult>
1713nsGlobalWindowInner::GetStorageKey() {
1714 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", 1714
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1714); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1715
1716 nsIPrincipal* principal = GetEffectiveStoragePrincipal();
1717 if (!principal) {
1718 return mozilla::Err(NS_ERROR_FAILURE);
1719 }
1720
1721 mozilla::ipc::PrincipalInfo principalInfo;
1722 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
1723 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1724 return mozilla::Err(rv);
1725 }
1726
1727 // Block expanded and null principals, let content and system through.
1728 if (principalInfo.type() !=
1729 mozilla::ipc::PrincipalInfo::TContentPrincipalInfo &&
1730 principalInfo.type() !=
1731 mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
1732 return Err(NS_ERROR_DOM_SECURITY_ERR);
1733 }
1734
1735 return std::move(principalInfo);
1736}
1737
1738mozilla::dom::StorageManager* nsGlobalWindowInner::GetStorageManager() {
1739 return Navigator()->Storage();
1740}
1741
1742// https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging
1743// * a Window object whose associated Document is fully active
1744bool nsGlobalWindowInner::IsEligibleForMessaging() { return IsFullyActive(); }
1745
1746void nsGlobalWindowInner::ReportToConsole(
1747 uint32_t aErrorFlags, const nsCString& aCategory, PropertiesFile aFile,
1748 const nsCString& aMessageName, const nsTArray<nsString>& aParams,
1749 const mozilla::SourceLocation& aLocation) {
1750 nsContentUtils::ReportToConsole(aErrorFlags, aCategory, mDoc, aFile,
1751 aMessageName.get(), aParams, aLocation);
1752}
1753
1754nsresult nsGlobalWindowInner::EnsureScriptEnvironment() {
1755 // NOTE: We can't use FORWARD_TO_OUTER here because we don't want to fail if
1756 // we're called on an inactive inner window.
1757 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1758 if (!outer) {
1759 NS_WARNING("No outer window available!")NS_DebugBreak(NS_DEBUG_WARNING, "No outer window available!",
nullptr, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 1759)
;
1760 return NS_ERROR_FAILURE;
1761 }
1762 return outer->EnsureScriptEnvironment();
1763}
1764
1765nsIScriptContext* nsGlobalWindowInner::GetScriptContext() {
1766 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1767 if (!outer) {
1768 return nullptr;
1769 }
1770 return outer->GetScriptContext();
1771}
1772
1773void nsGlobalWindowInner::TraceGlobalJSObject(JSTracer* aTrc) {
1774 TraceWrapper(aTrc, "active window global");
1775}
1776
1777void nsGlobalWindowInner::UpdateAutoplayPermission() {
1778 if (!GetWindowContext()) {
1779 return;
1780 }
1781 uint32_t perm =
1782 media::AutoplayPolicy::GetSiteAutoplayPermission(GetPrincipal());
1783 if (GetWindowContext()->GetAutoplayPermission() == perm) {
1784 return;
1785 }
1786
1787 // Setting autoplay permission on a discarded context has no effect.
1788 (void)GetWindowContext()->SetAutoplayPermission(perm);
1789}
1790
1791void nsGlobalWindowInner::UpdateShortcutsPermission() {
1792 if (!GetWindowContext() ||
1793 !GetWindowContext()->GetBrowsingContext()->IsTop()) {
1794 // We only cache the shortcuts permission on top-level WindowContexts
1795 // since we always check the top-level principal for the permission.
1796 return;
1797 }
1798
1799 uint32_t perm = GetShortcutsPermission(GetPrincipal());
1800
1801 if (GetWindowContext()->GetShortcutsPermission() == perm) {
1802 return;
1803 }
1804
1805 // If the WindowContext is discarded this has no effect.
1806 (void)GetWindowContext()->SetShortcutsPermission(perm);
1807}
1808
1809/* static */
1810uint32_t nsGlobalWindowInner::GetShortcutsPermission(nsIPrincipal* aPrincipal) {
1811 uint32_t perm = nsIPermissionManager::DENY_ACTION;
1812 nsCOMPtr<nsIPermissionManager> permMgr =
1813 mozilla::components::PermissionManager::Service();
1814 if (aPrincipal && permMgr) {
1815 permMgr->TestExactPermissionFromPrincipal(aPrincipal, "shortcuts"_ns,
1816 &perm);
1817 }
1818 return perm;
1819}
1820
1821void nsGlobalWindowInner::UpdatePopupPermission() {
1822 if (!GetWindowContext()) {
1823 return;
1824 }
1825
1826 uint32_t perm = PopupBlocker::GetPopupPermission(GetPrincipal());
1827 if (GetWindowContext()->GetPopupPermission() == perm) {
1828 return;
1829 }
1830
1831 // If the WindowContext is discarded this has no effect.
1832 (void)GetWindowContext()->SetPopupPermission(perm);
1833}
1834
1835void nsGlobalWindowInner::UpdatePermissions() {
1836 if (!GetWindowContext()) {
1837 return;
1838 }
1839
1840 nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
1841 RefPtr<WindowContext> windowContext = GetWindowContext();
1842
1843 WindowContext::Transaction txn;
1844 txn.SetAutoplayPermission(
1845 media::AutoplayPolicy::GetSiteAutoplayPermission(principal));
1846 txn.SetPopupPermission(PopupBlocker::GetPopupPermission(principal));
1847
1848 if (windowContext->IsTop()) {
1849 txn.SetShortcutsPermission(GetShortcutsPermission(principal));
1850 }
1851
1852 // Setting permissions on a discarded WindowContext has no effect
1853 (void)txn.Commit(windowContext);
1854}
1855
1856void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
1857 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"
, 1857); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 1857); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1858
1859 if (MOZ_LOG_TEST(gDOMLeakPRLogInner, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gDOMLeakPRLogInner
, LogLevel::Debug)), 0))
) {
1860 nsIURI* uri = mDoc->GetDocumentURI();
1861 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)
1862 ("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)
1863 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)
;
1864 }
1865
1866 mFocusedElement = nullptr;
1867 mLocalStorage = nullptr;
1868 mSessionStorage = nullptr;
1869 mPerformance = nullptr;
1870 if (mWebTaskScheduler) {
1871 mWebTaskScheduler->Disconnect();
1872 mWebTaskScheduler = nullptr;
1873 SetWebTaskSchedulingState(nullptr);
1874 }
1875
1876 // This must be called after nullifying the internal objects because here we
1877 // could recreate them, calling the getter methods, and store them into the JS
1878 // slots. If we nullify them after, the slot values and the objects will be
1879 // out of sync.
1880 ClearDocumentDependentSlots(aCx);
1881
1882 if (!mWindowGlobalChild) {
1883 mWindowGlobalChild = WindowGlobalChild::Create(this);
1884 } else {
1885 // If the window global existed before the window, it must've come from the
1886 // AboutBlankInitializer
1887 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",
1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1888); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1888 "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",
1888); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsAboutBlankAllowQueryAndFragment(GetDocumentURI())"
") (" "AboutBlankInitializer should only be used with about:blank"
")"); do { MOZ_CrashSequence(__null, 1888); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1889 }
1890 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"
, 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1891 "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"
, 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1892 "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"
, 1892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetWindowContext()->HasBeenUserGestureActivated()"
") (" "WindowContext should always not have user gesture activation at "
"this point." ")"); do { MOZ_CrashSequence(__null, 1892); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
1893
1894 UpdatePermissions();
1895
1896 RefPtr<PermissionDelegateHandler> permDelegateHandler =
1897 mDoc->GetPermissionDelegateHandler();
1898
1899 if (permDelegateHandler) {
1900 permDelegateHandler->PopulateAllDelegatedPermissions();
1901 }
1902
1903#if defined(MOZ_WIDGET_ANDROID)
1904 // When we insert the new document to the window in the top-level browsing
1905 // context, we should reset the status of the request which is used for the
1906 // previous document.
1907 if (mWindowGlobalChild && GetBrowsingContext() &&
1908 !GetBrowsingContext()->GetParent()) {
1909 // Return value of setting synced field should be checked. See bug 1656492.
1910 (void)GetBrowsingContext()->ResetGVAutoplayRequestStatus();
1911 }
1912#endif
1913
1914#ifdef DEBUG1
1915 mLastOpenedURI = mDoc->GetDocumentURI();
1916#endif
1917}
1918
1919nsresult nsGlobalWindowInner::EnsureClientSource() {
1920 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"
, 1920); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mDoc"
")"); do { MOZ_CrashSequence(__null, 1920); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1921
1922 bool newClientSource = false;
1923
1924 // Get the load info for the document if we performed a load. Be careful not
1925 // to look at local URLs, though. Local URLs are those that have a scheme of:
1926 // * about:
1927 // * data:
1928 // * blob:
1929 // We also do an additional check here so that we only treat about:blank
1930 // and about:srcdoc as local URLs. Other internal firefox about: URLs should
1931 // not be treated this way.
1932 nsCOMPtr<nsILoadInfo> loadInfo;
1933 nsCOMPtr<nsIChannel> channel = mDoc->GetChannel();
1934 if (channel) {
1935 nsCOMPtr<nsIURI> uri;
1936 (void)channel->GetURI(getter_AddRefs(uri));
1937
1938 bool ignoreLoadInfo = false;
1939
1940 if (uri->SchemeIs("about")) {
1941 ignoreLoadInfo =
1942 NS_IsAboutBlankAllowQueryAndFragment(uri) || NS_IsAboutSrcdoc(uri);
1943 } else {
1944 // Its not an about: URL, so now check for our other URL types.
1945 ignoreLoadInfo = uri->SchemeIs("data") || uri->SchemeIs("blob");
1946 }
1947
1948 if (!ignoreLoadInfo) {
1949 loadInfo = channel->LoadInfo();
1950 }
1951 }
1952
1953 // Take the initial client source from the docshell immediately. Even if we
1954 // don't end up using it here we should consume it.
1955 UniquePtr<ClientSource> initialClientSource;
1956 nsIDocShell* docshell = GetDocShell();
1957 if (docshell) {
1958 initialClientSource = docshell->TakeInitialClientSource();
1959 }
1960
1961 // Try to get the reserved client from the LoadInfo. A Client is
1962 // reserved at the start of the channel load if there is not an
1963 // initial uncommitted about:blank whose window will be reused. It is also
1964 // created if the channel load encounters a cross-origin redirect.
1965 if (loadInfo) {
1966 UniquePtr<ClientSource> reservedClient =
1967 loadInfo->TakeReservedClientSource();
1968 if (reservedClient) {
1969 mClientSource.reset();
1970 mClientSource = std::move(reservedClient);
1971 newClientSource = true;
1972 }
1973 }
1974
1975 // We don't have a LoadInfo reserved client, but maybe we should
1976 // be inheriting an initial one from the docshell. This means
1977 // that the docshell started the channel load before creating the
1978 // initial about:blank document. This is an optimization, though,
1979 // and it created an initial Client as a placeholder for the document.
1980 // In this case we want to inherit this placeholder Client here.
1981 if (!mClientSource) {
1982 mClientSource = std::move(initialClientSource);
1983 if (mClientSource) {
1984 newClientSource = true;
1985 }
1986 }
1987
1988 nsCOMPtr<nsIPrincipal> foreignPartitionedPrincipal;
1989
1990 nsresult rv = StoragePrincipalHelper::GetPrincipal(
1991 this, StoragePrincipalHelper::eForeignPartitionedPrincipal,
1992 getter_AddRefs(foreignPartitionedPrincipal));
1993 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"
, 1993); return rv; } } while (false)
;
1994
1995 // Verify the final ClientSource principal matches the final document
1996 // principal. The ClientChannelHelper handles things like network
1997 // redirects, but there are other ways the document principal can change.
1998 // For example, if something sets the nsIChannel.owner property, then
1999 // the final channel principal can be anything. Unfortunately there is
2000 // no good way to detect this until after the channel completes loading.
2001 //
2002 // For now we handle this just by reseting the ClientSource. This will
2003 // result in a new ClientSource with the correct principal being created.
2004 // To APIs like ServiceWorker and Clients API it will look like there was
2005 // an initial content page created that was then immediately replaced.
2006 // This is pretty close to what we are actually doing.
2007 if (mClientSource) {
2008 auto principalOrErr = mClientSource->Info().GetPrincipal();
2009 nsCOMPtr<nsIPrincipal> clientPrincipal =
2010 principalOrErr.isOk() ? principalOrErr.unwrap() : nullptr;
2011 if (!clientPrincipal ||
2012 !clientPrincipal->Equals(foreignPartitionedPrincipal)) {
2013 mClientSource.reset();
2014 }
2015 }
2016
2017 // If we don't have a reserved client or an initial client, then create
2018 // one now. This can happen in certain cases where we avoid preallocating
2019 // the client in the docshell. This mainly occurs in situations where
2020 // the principal is not clearly inherited from the parent; e.g. sandboxed
2021 // iframes, window.open(), etc.
2022 //
2023 // We also do this late ClientSource creation if the final document ended
2024 // up with a different principal.
2025 //
2026 // TODO: We may not be marking initial about:blank documents created
2027 // this way as controlled by a service worker properly. The
2028 // controller should be coming from the same place as the inheritted
2029 // principal. We do this in docshell, but as mentioned we aren't
2030 // smart enough to handle all cases yet. For example, a
2031 // window.open() with new URL should inherit the controller from
2032 // the opener, but we probably don't handle that yet.
2033 if (!mClientSource) {
2034 mClientSource = ClientManager::CreateSource(
2035 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2036 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", 2036
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2036); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2037 newClientSource = true;
2038
2039 // Note, we don't apply the loadinfo controller below if we create
2040 // the ClientSource here.
2041 }
2042
2043 // The load may have started controlling the Client as well. If
2044 // so, mark it as controlled immediately here. The actor may
2045 // or may not have been notified by the parent side about being
2046 // controlled yet.
2047 //
2048 // Note: We should be careful not to control a client that was created late.
2049 // These clients were not seen by the ServiceWorkerManager when it
2050 // marked the LoadInfo controlled and it won't know about them. Its
2051 // also possible we are creating the client late due to the final
2052 // principal changing and these clients should definitely not be
2053 // controlled by a service worker with a different principal.
2054 else if (loadInfo) {
2055 const Maybe<ServiceWorkerDescriptor> controller = loadInfo->GetController();
2056 if (controller.isSome()) {
2057 mClientSource->SetController(controller.ref());
2058 }
2059
2060 // We also have to handle the case where te initial about:blank is
2061 // controlled due to inheritting the service worker from its parent,
2062 // but the actual nsIChannel load is not covered by any service worker.
2063 // In this case we want the final page to be uncontrolled. There is
2064 // an open spec issue about how exactly this should be handled, but for
2065 // now we just force creation of a new ClientSource to clear the
2066 // controller.
2067 //
2068 // https://github.com/w3c/ServiceWorker/issues/1232
2069 //
2070 else if (mClientSource->GetController().isSome()) {
2071 mClientSource.reset();
2072 mClientSource = ClientManager::CreateSource(
2073 ClientType::Window, SerialEventTarget(), foreignPartitionedPrincipal);
2074 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", 2074
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mClientSource"
")"); do { MOZ_CrashSequence(__null, 2074); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2075 newClientSource = true;
2076 }
2077 }
2078
2079 if (mClientSource) {
2080 // Generally the policyContainer is stored within the Client and cached on
2081 // the document. At the time of policyContainer parsing however, the Client
2082 // has not been created yet, hence we store the policyContainer on the
2083 // document and propagate/sync the policyContainer with Client here when we
2084 // create the Client.
2085 mClientSource->SetPolicyContainer(mDoc->GetPolicyContainer());
2086
2087 DocGroup* docGroup = GetDocGroup();
2088 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"
, 2088); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "docGroup"
")"); do { MOZ_CrashSequence(__null, 2088); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2089 mClientSource->SetAgentClusterId(docGroup->AgentClusterId());
2090
2091 if (mWindowGlobalChild) {
2092 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
2093 }
2094 }
2095
2096 // Its possible that we got a client just after being frozen in
2097 // the bfcache. In that case freeze the client immediately.
2098 if (newClientSource && IsFrozen()) {
2099 mClientSource->Freeze();
2100 }
2101
2102 return NS_OK;
2103}
2104
2105nsresult nsGlobalWindowInner::ExecutionReady() {
2106 nsresult rv = EnsureClientSource();
2107 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"
, 2107); return rv; } } while (false)
;
2108
2109 rv = mClientSource->WindowExecutionReady(this);
2110 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"
, 2110); return rv; } } while (false)
;
2111
2112 return NS_OK;
2113}
2114
2115void nsGlobalWindowInner::UpdateParentTarget() {
2116 // NOTE: This method is identical to
2117 // nsGlobalWindowOuter::UpdateParentTarget(). IF YOU UPDATE THIS METHOD,
2118 // UPDATE THE OTHER ONE TOO!
2119
2120 // Try to get our frame element's tab child global (its in-process message
2121 // manager). If that fails, fall back to the chrome event handler's tab
2122 // child global, and if it doesn't have one, just use the chrome event
2123 // handler itself.
2124
2125 nsPIDOMWindowOuter* outer = GetOuterWindow();
2126 if (!outer) {
2127 return;
2128 }
2129 nsCOMPtr<Element> frameElement = outer->GetFrameElementInternal();
2130 nsCOMPtr<EventTarget> eventTarget =
2131 nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2132
2133 if (!eventTarget) {
2134 nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal();
2135 if (topWin) {
2136 frameElement = topWin->GetFrameElementInternal();
2137 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(frameElement);
2138 }
2139 }
2140
2141 if (!eventTarget) {
2142 eventTarget = nsContentUtils::TryGetBrowserChildGlobal(mChromeEventHandler);
2143 }
2144
2145 if (!eventTarget) {
2146 eventTarget = mChromeEventHandler;
2147 }
2148
2149 mParentTarget = std::move(eventTarget);
2150}
2151
2152EventTarget* nsGlobalWindowInner::GetTargetForDOMEvent() {
2153 return GetOuterWindowInternal();
2154}
2155
2156void nsGlobalWindowInner::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
2157 aVisitor.mCanHandle = true;
2158 aVisitor.mForceContentDispatch = true; // FIXME! Bug 329119
2159 switch (aVisitor.mEvent->mMessage) {
2160 case eResize:
2161 if (aVisitor.mEvent->IsTrusted()) {
2162 // Checking whether the event target is an inner window or not, so we
2163 // can keep the old behavior also in case a child window is handling
2164 // resize.
2165 if (aVisitor.mEvent->mOriginalTarget &&
2166 aVisitor.mEvent->mOriginalTarget->IsInnerWindow()) {
2167 mIsHandlingResizeEvent = true;
2168 }
2169 }
2170 break;
2171 case eMouseDown:
2172 if (aVisitor.mEvent->IsTrusted()) {
2173 sMouseDown = true;
2174 }
2175 break;
2176 case eMouseUp:
2177 case eDragEnd:
2178 if (aVisitor.mEvent->IsTrusted()) {
2179 MouseButtonReleased();
2180 }
2181 break;
2182 default:
2183 break;
2184 }
2185
2186 aVisitor.SetParentTarget(GetParentTarget(), true);
2187}
2188
2189/* static */
2190void nsGlobalWindowInner::MouseButtonReleased() {
2191 if (!sMouseDown) {
2192 return;
2193 }
2194 sMouseDown = false;
2195 if (sDragServiceDisabled) {
2196 nsCOMPtr<nsIDragService> ds =
2197 do_GetService("@mozilla.org/widget/dragservice;1");
2198 if (ds) {
2199 sDragServiceDisabled = false;
2200 ds->Unsuppress();
2201 }
2202 }
2203}
2204
2205// Editor library types for about:blank compat workaround
2206enum class EmptyFrameLibrary {
2207 None,
2208 CKEditor,
2209 GWT,
2210 ZE,
2211};
2212
2213// ckeditor 4 uses UA sniffing to wait for an async load event for its editor
2214// iframe. This patch makes it work by delaying the sync-about:blank's load
2215// event on such frames. See bug 2002481 and:
2216// https://github.com/ckeditor/ckeditor4/blob/c7e59ec199298b6b23f4aa7a7668f18572385bac/plugins/wysiwygarea/plugin.js#L43
2217//
2218// GWT RichTextArea also uses UA sniffing and expects an async `load` event
2219// for its editor iframe. See bug 2020927,
2220// https://github.com/gwtproject/gwt/issues/10292 , and
2221// https://github.com/gwtproject/gwt/blob/4b6a646faf0e9ce579658d78b6acf9fe5c840379/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplMozilla.java#L44
2222// .
2223//
2224// Polarion appears to use the GWT Editor too, but with a different class name.
2225//
2226// Old version of ZE appears to have a similar problem. Newer versions don't,
2227// because they have `srcdoc`. See bug 2020668.
2228MOZ_CAN_RUN_SCRIPT static bool IsDeferredLoadEmptyFrame(Element& aEmbedder) {
2229 const nsAttrValue* classes = aEmbedder.GetClasses();
2230 if (!classes) {
2231 return false;
2232 }
2233 EmptyFrameLibrary lib = EmptyFrameLibrary::None;
2234 if (StaticPrefs::dom_about_blank_ckeditor_hack_enabled() &&
2235 classes->Contains(nsGkAtoms::cke_wysiwyg_frame, eCaseMatters)) {
2236 lib = EmptyFrameLibrary::CKEditor;
2237 } else if (StaticPrefs::dom_about_blank_gwt_hack_enabled() &&
2238 classes->Contains(nsGkAtoms::gwt_RichTextArea, eCaseMatters)) {
2239 lib = EmptyFrameLibrary::GWT;
2240 } else if (StaticPrefs::dom_about_blank_polarion_gwt_hack_enabled() &&
2241 classes->Contains(nsGkAtoms::polarion_rte_RichTextArea,
2242 eCaseMatters)) {
2243 lib = EmptyFrameLibrary::GWT;
2244 } else if (StaticPrefs::dom_about_blank_ze_hack_enabled() &&
2245 classes->Contains(nsGkAtoms::ze_area, eCaseMatters)) {
2246 lib = EmptyFrameLibrary::ZE;
2247 }
2248 if (lib == EmptyFrameLibrary::None) {
2249 return false;
2250 }
2251 if (!aEmbedder.IsHTMLElement(nsGkAtoms::iframe)) {
2252 return false;
2253 }
2254 // We only come here if the initial document is reaching its load event.
2255 // That doesn't happen with `srcdoc`, which is an immediate navigation
2256 // to a non-about:blank document. Newer versions of ZE don't need this
2257 // and don't come here, because they have `srcdoc`.
2258 // Note: We can assert on `srcdoc` only after excluding non-iframe
2259 // element type above!
2260 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", 2260
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aEmbedder.HasAttr(nsGkAtoms::srcdoc)"
")"); do { MOZ_CrashSequence(__null, 2260); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2261 const auto* src = aEmbedder.GetParsedAttr(nsGkAtoms::src);
2262 // Require empty src for CKEditor 4 and no src for GWT and ZE.
2263 switch (lib) {
2264 case EmptyFrameLibrary::CKEditor:
2265 if (!src || !src->IsEmptyString()) {
2266 return false;
2267 }
2268 break;
2269 default:
2270 if (src) {
2271 return false;
2272 }
2273 break;
2274 }
2275 const char* blocklistPref = "";
2276 switch (lib) {
2277 case EmptyFrameLibrary::CKEditor:
2278 blocklistPref = "dom.about-blank-ckeditor-hack.disabled-domains";
2279 break;
2280 case EmptyFrameLibrary::GWT:
2281 blocklistPref = "dom.about-blank-gwt-hack.disabled-domains";
2282 break;
2283 case EmptyFrameLibrary::ZE:
2284 blocklistPref = "dom.about-blank-ze-hack.disabled-domains";
2285 break;
2286 case EmptyFrameLibrary::None:
2287 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",
2287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2287); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2288 return false;
2289 }
2290
2291 // Deal with the blocklist here before properties on the global
2292 // (which is potentially observable via JS getters).
2293 if (aEmbedder.NodePrincipal()->IsURIInPrefList(blocklistPref)) {
2294 return false;
2295 }
2296 // Finally, we also look for an identifying property on the embedder's global
2297 // to be extra sure.
2298 RefPtr global = aEmbedder.GetRelevantGlobal();
2299 if (!global || !global->GetGlobalJSObject()) {
2300 return false;
2301 }
2302 AutoJSAPI jsapi;
2303 if (!jsapi.Init(global)) {
2304 return false;
2305 }
2306 if (lib == EmptyFrameLibrary::GWT) {
2307 JS::Rooted<JSObject*> globalObj(jsapi.cx(), global->GetGlobalJSObject());
2308 JS::Rooted<JS::Value> val(jsapi.cx());
2309 if (!JS_GetProperty(jsapi.cx(), globalObj, "__gwt_stylesLoaded", &val)) {
2310 JS_ClearPendingException(jsapi.cx());
2311 return false;
2312 }
2313 if (!val.isObject()) {
2314 return false;
2315 }
2316 aEmbedder.OwnerDoc()->WarnOnceAbout(
2317 DeprecatedOperations::eGWTRichTextAreaCompatHack);
2318 return true;
2319 }
2320 CkEditorProperty property;
2321 JS::Rooted<JS::Value> v(jsapi.cx(),
2322 JS::ObjectValue(*global->GetGlobalJSObject()));
2323 if (!property.Init(jsapi.cx(), v)) {
2324 JS_ClearPendingException(jsapi.cx());
2325 return false;
2326 }
2327 switch (lib) {
2328 case EmptyFrameLibrary::GWT:
2329 case EmptyFrameLibrary::None:
2330 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",
2330); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 2330); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2331 return false;
2332 case EmptyFrameLibrary::ZE:
2333 if (!property.mZE_Init.WasPassed()) {
2334 return false;
2335 }
2336 // No use counter at least for now.
2337 aEmbedder.OwnerDoc()->WarnOnceAbout(
2338 DeprecatedOperations::eOldZECompatHack);
2339 return true;
2340 case EmptyFrameLibrary::CKEditor:
2341 const auto* version = [&]() -> const CkEditorVersion* {
2342 if (property.mCKEDITOR.WasPassed()) {
2343 return &property.mCKEDITOR.Value();
2344 }
2345 if (property.mJEDITOR.WasPassed()) {
2346 return &property.mJEDITOR.Value();
2347 }
2348 return nullptr;
2349 }();
2350 if (!version) {
2351 return false;
2352 }
2353 // The CKEditor source code has "%VERSION%", which may be left in place
2354 // in deployment if a proper build step is missing.
2355 if (!(StringBeginsWith(version->mVersion, u"4."_ns) ||
2356 version->mVersion.EqualsLiteral(u"%VERSION%"))) {
2357 return false;
2358 }
2359 aEmbedder.OwnerDoc()->WarnOnceAbout(
2360 DeprecatedOperations::eCKEditor4CompatHack);
2361 return true;
2362 }
2363 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"
, 2363); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Every switch case should have returned."
")"); do { MOZ_CrashSequence(__null, 2363); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2364 return false;
2365}
2366
2367MOZ_CAN_RUN_SCRIPT static bool NeedsAsyncLoadEventForInitialDocument(
2368 nsGlobalWindowInner& aInner, Element& aEmbedder) {
2369 if (auto* doc = aInner.GetExtantDoc(); !doc || !doc->IsInitialDocument()) {
2370 return false;
2371 }
2372 return IsDeferredLoadEmptyFrame(aEmbedder);
2373}
2374
2375void nsGlobalWindowInner::FireFrameLoadEvent() {
2376 // If we're not in a content frame, or are at a BrowsingContext tree boundary,
2377 // such as the content-chrome boundary, don't fire the "load" event.
2378 if (GetBrowsingContext()->IsTopContent() ||
2379 GetBrowsingContext()->IsChrome()) {
2380 return;
2381 }
2382
2383 // If embedder is same-process, fire the event on our embedder element.
2384 //
2385 // XXX: Bug 1440212 is looking into potentially changing this behaviour to act
2386 // more like the remote case when in-process.
2387 if (RefPtr<Element> element = GetBrowsingContext()->GetEmbedderElement()) {
2388 if (NeedsAsyncLoadEventForInitialDocument(*this, *element)) {
2389 (new AsyncEventDispatcher(element, eLoad, CanBubble::eNo))
2390 ->PostDOMEvent();
2391 return;
2392 }
2393
2394 nsEventStatus status = nsEventStatus_eIgnore;
2395 WidgetEvent event(/* aIsTrusted = */ true, eLoad);
2396 event.mFlags.mBubbles = false;
2397 event.mFlags.mCancelable = false;
2398
2399 // Most of the time we could get a pres context to pass in here, but not
2400 // always (i.e. if this window is not shown there won't be a pres context
2401 // available). Since we're not firing a GUI event we don't need a pres
2402 // context anyway so we just pass null as the pres context all the time.
2403 EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status);
2404 return;
2405 }
2406
2407 // We don't have an in-process embedder. Try to get our `BrowserChild` actor
2408 // to send a message to that embedder. We want to double-check that our outer
2409 // window is actually the one at the root of this browserChild though, just in
2410 // case.
2411 RefPtr<BrowserChild> browserChild =
2412 BrowserChild::GetFrom(static_cast<nsPIDOMWindowInner*>(this));
2413 if (browserChild &&
2414 !GetBrowsingContext()->GetParentWindowContext()->IsInProcess()) {
2415 // Double-check that our outer window is actually at the root of this
2416 // `BrowserChild`, in case we're in an odd maybe-unhosted situation like a
2417 // print preview dialog.
2418 nsCOMPtr<nsPIDOMWindowOuter> rootOuter =
2419 do_GetInterface(browserChild->WebNavigation());
2420 if (!rootOuter || rootOuter != GetOuterWindow()) {
2421 return;
2422 }
2423
2424 (void)browserChild->SendMaybeFireEmbedderLoadEvents(
2425 EmbedderElementEventType::LoadEvent);
2426 }
2427}
2428
2429nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) {
2430 // Return early if there is nothing to do.
2431 switch (aVisitor.mEvent->mMessage) {
2432 case eResize:
2433 case eUnload:
2434 case eLoad:
2435 break;
2436 default:
2437 return NS_OK;
2438 }
2439
2440 /* mChromeEventHandler and mContext go dangling in the middle of this
2441 function under some circumstances (events that destroy the window)
2442 without this addref. */
2443 RefPtr<EventTarget> kungFuDeathGrip1(mChromeEventHandler);
2444 (void)kungFuDeathGrip1; // These aren't referred to through the function
2445 nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
2446 (void)kungFuDeathGrip2; // These aren't referred to through the function
2447
2448 if (aVisitor.mEvent->mMessage == eResize) {
2449 mIsHandlingResizeEvent = false;
2450 } else if (aVisitor.mEvent->mMessage == eUnload &&
2451 aVisitor.mEvent->IsTrusted()) {
2452 // If any VR display presentation is active at unload, the next page
2453 // will receive a vrdisplayactive event to indicate that it should
2454 // immediately begin vr presentation. This should occur when navigating
2455 // forwards, navigating backwards, and on page reload.
2456 for (const auto& display : mVRDisplays) {
2457 if (display->IsPresenting()) {
2458 display->StartVRNavigation();
2459 // Save this VR display ID to trigger vrdisplayactivate event
2460 // after the next load event.
2461 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2462 if (outer) {
2463 outer->SetAutoActivateVRDisplayID(display->DisplayId());
2464 }
2465
2466 // XXX The WebVR 1.1 spec does not define which of multiple VR
2467 // presenting VR displays will be chosen during navigation.
2468 // As the underlying platform VR API's currently only allow a single
2469 // VR display, it is safe to choose the first VR display for now.
2470 break;
2471 }
2472 }
2473 mIsDocumentLoaded = false;
2474 // Tell the parent process that the document is not loaded.
2475 if (mWindowGlobalChild) {
2476 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2477 mWindowGlobalChild->OnDocumentUnloaded();
2478 }
2479 } else if (aVisitor.mEvent->mMessage == eLoad &&
2480 aVisitor.mEvent->IsTrusted()) {
2481 // This is page load event since load events don't propagate to |window|.
2482 // @see Document::GetEventTargetParent.
2483 mIsDocumentLoaded = true;
2484 // Tell the parent process that the document is loaded.
2485 if (mWindowGlobalChild) {
2486 mWindowGlobalChild->SendUpdateDocumentHasLoaded(mIsDocumentLoaded);
2487 mWindowGlobalChild->OnDocumentLoaded();
2488 }
2489
2490 mTimeoutManager->OnDocumentLoaded();
2491
2492 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"
, 2492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aVisitor.mEvent->IsTrusted()"
")"); do { MOZ_CrashSequence(__null, 2492); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2493 FireFrameLoadEvent();
2494
2495 if (mVREventObserver) {
2496 mVREventObserver->NotifyAfterLoad();
2497 }
2498
2499 uint32_t autoActivateVRDisplayID = 0;
2500 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
2501 if (outer) {
2502 autoActivateVRDisplayID = outer->GetAutoActivateVRDisplayID();
2503 }
2504 if (autoActivateVRDisplayID) {
2505 DispatchVRDisplayActivate(autoActivateVRDisplayID,
2506 VRDisplayEventReason::Navigation);
2507 }
2508 }
2509
2510 return NS_OK;
2511}
2512
2513nsresult nsGlobalWindowInner::DefineArgumentsProperty(nsIArray* aArguments) {
2514 nsIScriptContext* ctx = GetOuterWindowInternal()->mContext;
2515 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"
, 2515); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
2516
2517 JS::Rooted<JSObject*> obj(RootingCx(), GetWrapperPreserveColor());
2518 return ctx->SetProperty(obj, "arguments", aArguments);
2519}
2520
2521//*****************************************************************************
2522// nsGlobalWindowInner::nsIScriptObjectPrincipal
2523//*****************************************************************************
2524
2525nsIPrincipal* nsGlobalWindowInner::GetPrincipal() {
2526 if (mDoc) {
2527 // If we have a document, get the principal from the document
2528 return mDoc->NodePrincipal();
2529 }
2530
2531 if (mDocumentPrincipal) {
2532 return mDocumentPrincipal;
2533 }
2534
2535 // If we don't have a principal and we don't have a document we
2536 // ask the parent window for the principal. This can happen when
2537 // loading a frameset that has a <frame src="javascript:xxx">, in
2538 // that case the global window is used in JS before we've loaded
2539 // a document into the window.
2540
2541 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2542 do_QueryInterface(GetInProcessParentInternal());
2543
2544 if (objPrincipal) {
2545 return objPrincipal->GetPrincipal();
2546 }
2547
2548 return nullptr;
2549}
2550
2551nsIPrincipal* nsGlobalWindowInner::GetEffectiveCookiePrincipal() {
2552 if (mDoc) {
2553 // If we have a document, get the principal from the document
2554 return mDoc->EffectiveCookiePrincipal();
2555 }
2556
2557 if (mDocumentCookiePrincipal) {
2558 return mDocumentCookiePrincipal;
2559 }
2560
2561 // If we don't have a cookie principal and we don't have a document we ask
2562 // the parent window for the cookie principal.
2563
2564 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2565 do_QueryInterface(GetInProcessParentInternal());
2566
2567 if (objPrincipal) {
2568 return objPrincipal->GetEffectiveCookiePrincipal();
2569 }
2570
2571 return nullptr;
2572}
2573
2574nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() {
2575 if (mDoc) {
2576 // If we have a document, get the principal from the document
2577 return mDoc->EffectiveStoragePrincipal();
2578 }
2579
2580 if (mDocumentStoragePrincipal) {
2581 return mDocumentStoragePrincipal;
2582 }
2583
2584 // If we don't have a cookie principal and we don't have a document we ask
2585 // the parent window for the cookie principal.
2586
2587 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2588 do_QueryInterface(GetInProcessParentInternal());
2589
2590 if (objPrincipal) {
2591 return objPrincipal->GetEffectiveStoragePrincipal();
2592 }
2593
2594 return nullptr;
2595}
2596
2597nsIPrincipal* nsGlobalWindowInner::PartitionedPrincipal() {
2598 if (mDoc) {
2599 // If we have a document, get the principal from the document
2600 return mDoc->PartitionedPrincipal();
2601 }
2602
2603 if (mDocumentPartitionedPrincipal) {
2604 return mDocumentPartitionedPrincipal;
2605 }
2606
2607 // If we don't have a partitioned principal and we don't have a document we
2608 // ask the parent window for the partitioned principal.
2609
2610 nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
2611 do_QueryInterface(GetInProcessParentInternal());
2612
2613 if (objPrincipal) {
2614 return objPrincipal->PartitionedPrincipal();
2615 }
2616
2617 return nullptr;
2618}
2619
2620//*****************************************************************************
2621// nsGlobalWindowInner::nsIDOMWindow
2622//*****************************************************************************
2623
2624bool nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext) {
2625 mAudioContexts.AppendElement(aAudioContext);
2626
2627 // Return true if the context should be muted and false if not.
2628 nsIDocShell* docShell = GetDocShell();
2629 return docShell && !docShell->GetAllowMedia() && !aAudioContext->IsOffline();
2630}
2631
2632void nsPIDOMWindowInner::RemoveAudioContext(AudioContext* aAudioContext) {
2633 mAudioContexts.RemoveElement(aAudioContext);
2634}
2635
2636void nsPIDOMWindowInner::MuteAudioContexts() {
2637 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2638 if (!mAudioContexts[i]->IsOffline()) {
2639 mAudioContexts[i]->Mute();
2640 }
2641 }
2642}
2643
2644void nsPIDOMWindowInner::UnmuteAudioContexts() {
2645 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
2646 if (!mAudioContexts[i]->IsOffline()) {
2647 mAudioContexts[i]->Unmute();
2648 }
2649 }
2650}
2651
2652WindowProxyHolder nsGlobalWindowInner::Window() {
2653 return WindowProxyHolder(GetBrowsingContext());
2654}
2655
2656Navigation* nsPIDOMWindowInner::Navigation() {
2657 if (!mNavigation && Navigation::IsAPIEnabled()) {
2658 mNavigation = MakeRefPtr<mozilla::dom::Navigation>(this);
2659 }
2660
2661 return mNavigation;
2662}
2663
2664Navigator* nsPIDOMWindowInner::Navigator() {
2665 if (!mNavigator) {
2666 mNavigator = MakeRefPtr<mozilla::dom::Navigator>(this);
2667 }
2668
2669 return mNavigator;
2670}
2671
2672MediaDevices* nsPIDOMWindowInner::GetExtantMediaDevices() const {
2673 return mNavigator ? mNavigator->GetExtantMediaDevices() : nullptr;
2674}
2675
2676VisualViewport* nsGlobalWindowInner::VisualViewport() {
2677 if (!mVisualViewport) {
2678 mVisualViewport = MakeRefPtr<mozilla::dom::VisualViewport>(this);
2679 }
2680 return mVisualViewport;
2681}
2682
2683nsScreen* nsGlobalWindowInner::Screen() {
2684 if (!mScreen) {
2685 mScreen = nsScreen::Create(this);
2686 }
2687 return mScreen;
2688}
2689
2690nsHistory* nsGlobalWindowInner::GetHistory(ErrorResult& aError) {
2691 if (!mHistory) {
2692 mHistory = MakeRefPtr<nsHistory>(this);
2693 }
2694 return mHistory;
2695}
2696
2697CustomElementRegistry* nsGlobalWindowInner::CustomElements() {
2698 if (!mCustomElements) {
2699 mCustomElements = MakeRefPtr<CustomElementRegistry>(this);
2700 }
2701
2702 return mCustomElements;
2703}
2704
2705CustomElementRegistry* nsGlobalWindowInner::GetExistingCustomElements() {
2706 return mCustomElements;
2707}
2708
2709Performance* nsPIDOMWindowInner::GetPerformance() {
2710 CreatePerformanceObjectIfNeeded();
2711 return mPerformance;
2712}
2713
2714void nsPIDOMWindowInner::QueuePerformanceNavigationTiming() {
2715 CreatePerformanceObjectIfNeeded();
2716 if (mPerformance) {
2717 mPerformance->QueueNavigationTimingEntry();
2718 }
2719}
2720
2721void nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded() {
2722 if (mPerformance || !mDoc) {
2723 return;
2724 }
2725 RefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming();
2726 nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel()));
2727 if (timing) {
2728 mPerformance = Performance::CreateForMainThread(this, mDoc->NodePrincipal(),
2729 timing, timedChannel);
2730 }
2731}
2732
2733bool nsPIDOMWindowInner::IsSecureContext() const {
2734 return nsGlobalWindowInner::Cast(this)->IsSecureContext();
2735}
2736
2737void nsPIDOMWindowInner::Suspend(bool aIncludeSubWindows) {
2738 nsGlobalWindowInner::Cast(this)->Suspend(aIncludeSubWindows);
2739}
2740
2741void nsPIDOMWindowInner::Resume(bool aIncludeSubWindows) {
2742 nsGlobalWindowInner::Cast(this)->Resume(aIncludeSubWindows);
2743}
2744
2745void nsPIDOMWindowInner::SyncStateFromParentWindow() {
2746 nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow();
2747}
2748
2749Maybe<ClientInfo> nsPIDOMWindowInner::GetClientInfo() const {
2750 return nsGlobalWindowInner::Cast(this)->GetClientInfo();
2751}
2752
2753Maybe<ClientState> nsPIDOMWindowInner::GetClientState() const {
2754 return nsGlobalWindowInner::Cast(this)->GetClientState();
2755}
2756
2757Maybe<ServiceWorkerDescriptor> nsPIDOMWindowInner::GetController() const {
2758 return nsGlobalWindowInner::Cast(this)->GetController();
2759}
2760
2761ClientSource* nsPIDOMWindowInner::GetClientSource() const {
2762 return nsGlobalWindowInner::Cast(this)->GetClientSource();
2763}
2764
2765void nsPIDOMWindowInner::SetPolicyContainer(
2766 nsIPolicyContainer* aPolicyContainer) {
2767 return nsGlobalWindowInner::Cast(this)->SetPolicyContainer(aPolicyContainer);
2768}
2769
2770void nsPIDOMWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
2771 return nsGlobalWindowInner::Cast(this)->SetPreloadCsp(aPreloadCsp);
2772}
2773
2774nsIPolicyContainer* nsPIDOMWindowInner::GetPolicyContainer() {
2775 return nsGlobalWindowInner::Cast(this)->GetPolicyContainer();
2776}
2777
2778void nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(
2779 const nsACString& aScope) {
2780 nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope(
2781 aScope);
2782}
2783
2784void nsPIDOMWindowInner::NoteDOMContentLoaded() {
2785 nsGlobalWindowInner::Cast(this)->NoteDOMContentLoaded();
2786}
2787
2788bool nsGlobalWindowInner::ShouldReportForServiceWorkerScope(
2789 const nsAString& aScope) {
2790 bool result = false;
2791
2792 nsPIDOMWindowOuter* topOuter = GetInProcessScriptableTop();
2793 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", 2793
); return false; } } while (false)
;
2794
2795 nsGlobalWindowInner* topInner =
2796 nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
2797 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", 2797
); return false; } } while (false)
;
2798
2799 topInner->ShouldReportForServiceWorkerScopeInternal(
2800 NS_ConvertUTF16toUTF8(aScope), &result);
2801 return result;
2802}
2803
2804void nsGlobalWindowInner::GetInstallTrigger(
2805 JSContext* aCx, JS::MutableHandle<JSObject*> aResult) {
2806 // Return nullptr, to avoid breaking "typeof InstallTrigger !== 'undefined"
2807 // "UA detection" use case.
2808 //
2809 // A pref ("extensions.InstallTrigger.enabled"), associated to this
2810 // property using the [Pref] extended attribute in Window.webidl, hides the
2811 // entire InstallTrigger property.
2812 //
2813 // See Bug 1754441 for more details about this deprecation.
2814 aResult.set(nullptr);
2815}
2816
2817nsIDOMWindowUtils* nsGlobalWindowInner::GetWindowUtils(ErrorResult& aRv) {
2818 FORWARD_TO_OUTER_OR_THROW(WindowUtils, (), aRv, nullptr);
2819}
2820
2821bool nsGlobalWindowInner::SynthesizeMouseEvent(
2822 const nsAString& aType, float aOffsetX, float aOffsetY,
2823 const SynthesizeMouseEventData& aMouseEventData,
2824 const SynthesizeMouseEventOptions& aOptions,
2825 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2826 ErrorResult& aError) {
2827 nsIDocShell* docShell = GetDocShell();
2828 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2829 if (!presShell) {
2830 aError.Throw(NS_ERROR_FAILURE);
2831 return false;
2832 }
2833
2834 nsPoint offset;
2835 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2836 if (!widget) {
2837 aError.Throw(NS_ERROR_FAILURE);
2838 return false;
2839 }
2840
2841 LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint(
2842 CSSPoint(aOffsetX, aOffsetY), offset, presShell->GetPresContext());
2843 auto result = nsContentUtils::SynthesizeMouseEvent(
2844 presShell, widget, aType, refPoint, aMouseEventData, aOptions, aCallback);
2845 if (result.isErr()) {
2846 aError.Throw(result.unwrapErr());
2847 return false;
2848 }
2849
2850 return result.unwrap();
2851}
2852
2853bool nsGlobalWindowInner::SynthesizeTouchEvent(
2854 const nsAString& aType, const nsTArray<SynthesizeTouchEventData>& aTouches,
2855 const int32_t aModifiers, const SynthesizeTouchEventOptions& aOptions,
2856 const Optional<OwningNonNull<VoidFunction>>& aCallback,
2857 mozilla::ErrorResult& aError) {
2858 nsIDocShell* docShell = GetDocShell();
2859 RefPtr<PresShell> presShell = docShell ? docShell->GetPresShell() : nullptr;
2860 if (!presShell) {
2861 aError.Throw(NS_ERROR_FAILURE);
2862 return false;
2863 }
2864
2865 nsPoint offset;
2866 nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &offset);
2867 if (!widget) {
2868 aError.Throw(NS_ERROR_FAILURE);
2869 return false;
2870 }
2871
2872 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
2873 if (!presContext) {
2874 aError.Throw(NS_ERROR_FAILURE);
2875 return false;
2876 }
2877
2878 auto result = nsContentUtils::SynthesizeTouchEvent(
2879 presContext, widget, offset, aType, aTouches, aModifiers, aOptions,
2880 aCallback);
2881 if (result.isErr()) {
2882 aError.Throw(result.unwrapErr());
2883 return false;
2884 }
2885
2886 return result.unwrap();
2887}
2888
2889CallState nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal(
2890 const nsACString& aScope, bool* aResultOut) {
2891 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"
, 2891); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aResultOut"
")"); do { MOZ_CrashSequence(__null, 2891); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2892
2893 // First check to see if this window is controlled. If so, then we have
2894 // found a match and are done.
2895 const Maybe<ServiceWorkerDescriptor> swd = GetController();
2896 if (swd.isSome() && swd.ref().Scope() == aScope) {
2897 *aResultOut = true;
2898 return CallState::Stop;
2899 }
2900
2901 // Next, check to see if this window has called
2902 // navigator.serviceWorker.register() for this scope. If so, then treat this
2903 // as a match so console reports appear in the devtools console.
2904 if (mClientSource &&
2905 mClientSource->CalledRegisterForServiceWorkerScope(aScope)) {
2906 *aResultOut = true;
2907 return CallState::Stop;
2908 }
2909
2910 // Finally check the current docshell nsILoadGroup to see if there are any
2911 // outstanding navigation requests. If so, match the scope against the
2912 // channel's URL. We want to show console reports during the FetchEvent
2913 // intercepting the navigation itself.
2914 nsCOMPtr<nsIDocumentLoader> loader(do_QueryInterface(GetDocShell()));
2915 if (loader) {
2916 nsCOMPtr<nsILoadGroup> loadgroup;
2917 (void)loader->GetLoadGroup(getter_AddRefs(loadgroup));
2918 if (loadgroup) {
2919 nsCOMPtr<nsISimpleEnumerator> iter;
2920 (void)loadgroup->GetRequests(getter_AddRefs(iter));
2921 if (iter) {
2922 nsCOMPtr<nsISupports> tmp;
2923 bool hasMore = true;
2924 // Check each network request in the load group.
2925 while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(iter->HasMoreElements
(&hasMore))), 1)))
&& hasMore) {
2926 iter->GetNext(getter_AddRefs(tmp));
2927 nsCOMPtr<nsIChannel> loadingChannel(do_QueryInterface(tmp));
2928 // Ignore subresource requests. Logging for a subresource
2929 // FetchEvent should be handled above since the client is
2930 // already controlled.
2931 if (!loadingChannel ||
2932 !nsContentUtils::IsNonSubresourceRequest(loadingChannel)) {
2933 continue;
2934 }
2935 nsCOMPtr<nsIURI> loadingURL;
2936 (void)loadingChannel->GetURI(getter_AddRefs(loadingURL));
2937 if (!loadingURL) {
2938 continue;
2939 }
2940 nsAutoCString loadingSpec;
2941 (void)loadingURL->GetSpec(loadingSpec);
2942 // Perform a simple substring comparison to match the scope
2943 // against the channel URL.
2944 if (StringBeginsWith(loadingSpec, aScope)) {
2945 *aResultOut = true;
2946 return CallState::Stop;
2947 }
2948 }
2949 }
2950 }
2951 }
2952
2953 // The current window doesn't care about this service worker, but maybe
2954 // one of our child frames does.
2955 return CallOnInProcessChildren(
2956 &nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal, aScope,
2957 aResultOut);
2958}
2959
2960void nsGlobalWindowInner::NoteCalledRegisterForServiceWorkerScope(
2961 const nsACString& aScope) {
2962 if (!mClientSource) {
2963 return;
2964 }
2965
2966 mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope);
2967}
2968
2969void nsGlobalWindowInner::NoteDOMContentLoaded() {
2970 if (!mClientSource) {
2971 return;
2972 }
2973
2974 mClientSource->NoteDOMContentLoaded();
2975}
2976
2977void nsGlobalWindowInner::UpdateTopInnerWindow() {
2978 if (IsTopInnerWindow() || !mTopInnerWindow) {
2979 return;
2980 }
2981
2982 nsGlobalWindowInner::Cast(mTopInnerWindow)
2983 ->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets);
2984}
2985
2986bool nsGlobalWindowInner::IsInSyncOperation() {
2987 return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
2988}
2989
2990bool nsGlobalWindowInner::IsSharedMemoryAllowedInternal(
2991 nsIPrincipal* aPrincipal) const {
2992 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", 2992
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 2992); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2993
2994 if (StaticPrefs::
2995 dom_postMessage_sharedArrayBuffer_bypassCOOP_COEP_insecure_enabled()) {
2996 return true;
2997 }
2998
2999 if (ExtensionPolicyService::GetSingleton().IsExtensionProcess()) {
3000 if (auto* basePrincipal = BasePrincipal::Cast(aPrincipal)) {
3001 if (auto* policy = basePrincipal->AddonPolicy()) {
3002 return policy->IsPrivileged();
3003 }
3004 }
3005 }
3006
3007 return CrossOriginIsolated();
3008}
3009
3010bool nsGlobalWindowInner::CrossOriginIsolated() const {
3011 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", 3011
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3011); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3012
3013 RefPtr<BrowsingContext> bc = GetBrowsingContext();
3014 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"
, 3014); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "bc"
")"); do { MOZ_CrashSequence(__null, 3014); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3015 return bc->CrossOriginIsolated();
3016}
3017
3018bool nsGlobalWindowInner::OriginAgentCluster() const {
3019 if (DocGroup* docGroup = GetDocGroup()) {
3020 return docGroup->IsOriginKeyed();
3021 }
3022 return false;
3023}
3024
3025WindowContext* TopWindowContext(nsPIDOMWindowInner& aWindow) {
3026 WindowContext* wc = aWindow.GetWindowContext();
3027 if (!wc) {
3028 return nullptr;
3029 }
3030
3031 return wc->TopWindowContext();
3032}
3033
3034void nsPIDOMWindowInner::AddPeerConnection() {
3035 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", 3035
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3035); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3036 ++mActivePeerConnections;
3037 if (mActivePeerConnections == 1 && mWindowGlobalChild) {
3038 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3039 /*aIsAdded*/ true);
3040
3041 // We need to present having active peer connections immediately. If we need
3042 // to wait for the parent process to come back with this information we
3043 // might start throttling.
3044 if (WindowContext* top = TopWindowContext(*this)) {
3045 top->TransientSetHasActivePeerConnections();
3046 }
3047 }
3048}
3049
3050void nsPIDOMWindowInner::RemovePeerConnection() {
3051 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", 3051
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3051); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3052 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"
, 3052); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActivePeerConnections > 0"
")"); do { MOZ_CrashSequence(__null, 3052); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3053 --mActivePeerConnections;
3054 if (mActivePeerConnections == 0 && mWindowGlobalChild) {
3055 mWindowGlobalChild->SendUpdateActivePeerConnectionStatus(
3056 /*aIsAdded*/ false);
3057 }
3058}
3059
3060bool nsGlobalWindowInner::HasActivePeerConnections() {
3061 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", 3061
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3061); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3062
3063 WindowContext* topWindowContext = TopWindowContext(*this);
3064 return topWindowContext && topWindowContext->GetHasActivePeerConnections();
3065}
3066
3067void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) {
3068 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", 3068
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3068); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3069 mMediaKeysInstances.AppendElement(aMediaKeys);
3070 if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) {
3071 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3072 }
3073}
3074
3075void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) {
3076 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", 3076
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3076); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3077 mMediaKeysInstances.RemoveElement(aMediaKeys);
3078 if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) {
3079 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
3080 }
3081}
3082
3083bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() {
3084 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", 3084
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3084); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3085 return !mMediaKeysInstances.IsEmpty();
3086}
3087
3088bool nsGlobalWindowInner::IsPlayingAudio() {
3089 for (uint32_t i = 0; i < mAudioContexts.Length(); i++) {
3090 if (mAudioContexts[i]->IsRunning()) {
3091 return true;
3092 }
3093 }
3094 RefPtr<AudioChannelService> acs = AudioChannelService::Get();
3095 if (!acs) {
3096 return false;
3097 }
3098 auto outer = GetOuterWindow();
3099 if (!outer) {
3100 // We've been unlinked and are about to die. Not a good time to pretend to
3101 // be playing audio.
3102 return false;
3103 }
3104 return acs->IsWindowActive(outer);
3105}
3106
3107bool nsPIDOMWindowInner::IsDocumentLoaded() const { return mIsDocumentLoaded; }
3108
3109mozilla::dom::TimeoutManager* nsGlobalWindowInner::GetTimeoutManager() {
3110 return mTimeoutManager.get();
3111}
3112
3113bool nsGlobalWindowInner::IsRunningTimeout() {
3114 return GetTimeoutManager()->IsRunningTimeout();
3115}
3116
3117void nsPIDOMWindowInner::TryToCacheTopInnerWindow() {
3118 if (mHasTriedToCacheTopInnerWindow) {
3119 return;
3120 }
3121
3122 nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(this);
3123
3124 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", 3124
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!window->IsDying()"
")"); do { MOZ_CrashSequence(__null, 3124); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3125
3126 mHasTriedToCacheTopInnerWindow = true;
3127
3128 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"
, 3128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "window" ")"
); do { MOZ_CrashSequence(__null, 3128); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3129
3130 if (nsCOMPtr<nsPIDOMWindowOuter> topOutter =
3131 window->GetInProcessScriptableTop()) {
3132 mTopInnerWindow = topOutter->GetCurrentInnerWindow();
3133 }
3134}
3135
3136void nsGlobalWindowInner::UpdateActiveIndexedDBDatabaseCount(int32_t aDelta) {
3137 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", 3137
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3137); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3138
3139 if (aDelta == 0) {
3140 return;
3141 }
3142
3143 // We count databases but not transactions because only active databases
3144 // could block throttling.
3145 uint32_t& counter = mTopInnerWindow
3146 ? mTopInnerWindow->mNumOfIndexedDBDatabases
3147 : mNumOfIndexedDBDatabases;
3148
3149 counter += aDelta;
3150}
3151
3152bool nsGlobalWindowInner::HasActiveIndexedDBDatabases() const {
3153 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", 3153
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3153); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3154
3155 return mTopInnerWindow ? mTopInnerWindow->mNumOfIndexedDBDatabases > 0
3156 : mNumOfIndexedDBDatabases > 0;
3157}
3158
3159void nsGlobalWindowInner::UpdateWebSocketCount(int32_t aDelta) {
3160 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", 3160
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3160); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3161
3162 if (aDelta == 0) {
3163 return;
3164 }
3165
3166 if (mTopInnerWindow && !IsTopInnerWindow()) {
3167 nsGlobalWindowInner::Cast(mTopInnerWindow)->UpdateWebSocketCount(aDelta);
3168 }
3169
3170 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", 3171
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3171); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3171 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", 3171
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)"
")"); do { MOZ_CrashSequence(__null, 3171); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3172
3173 mNumOfOpenWebSockets += aDelta;
3174}
3175
3176bool nsGlobalWindowInner::HasOpenWebSockets() const {
3177 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", 3177
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3177); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3178
3179 return mNumOfOpenWebSockets ||
3180 (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
3181}
3182
3183void nsGlobalWindowInner::AudioPlaybackChanged(bool aIsPlayingAudio) {
3184 AUTO_PROFILER_MARKER_UNTYPED("AudioPlaybackChanged", DOM, {})AutoProfilerUntypedMarker raiiObject3184( "AudioPlaybackChanged"
, ::mozilla::baseprofiler::category::DOM, {})
;
3185 UpdateWorkersPlaybackState(*this, aIsPlayingAudio);
3186}
3187
3188bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
3189 if (mBrowsingContext && mBrowsingContext->IsInBFCache()) {
3190 return false;
3191 }
3192
3193 if (!mBrowsingContext || mBrowsingContext->IsDiscarded()) {
3194 // If our BrowsingContext has been discarded, we consider ourselves
3195 // still-current if we were current at the time it was discarded.
3196 return mOuterWindow && WasCurrentInnerWindow();
3197 }
3198
3199 nsPIDOMWindowOuter* outer = mBrowsingContext->GetDOMWindow();
3200 return outer && outer->GetCurrentInnerWindow() == this;
3201}
3202
3203bool nsGlobalWindowInner::HasScheduledNormalOrHighPriorityWebTasks() const {
3204 return gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0;
3205}
3206
3207bool nsPIDOMWindowInner::IsFullyActive() const {
3208 WindowContext* wc = GetWindowContext();
3209 if (!wc || wc->IsDiscarded() || !wc->IsCurrent()) {
3210 return false;
3211 }
3212 return GetBrowsingContext()->AncestorsAreCurrent();
3213}
3214
3215void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
3216 RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
3217 if (service) {
3218 service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
3219 }
3220}
3221
3222void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
3223 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)
3224 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)
3225 ("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)
;
3226 if (GetBrowsingContext()) {
3227 // Setting loading on a discarded context has no effect.
3228 (void)GetBrowsingContext()->SetLoading(aIsLoading);
3229 }
3230
3231 if (StaticPrefs::dom_timeout_defer_during_load() && !IsChromeWindow()) {
3232 nsIPrincipal* principal = GetPrincipal();
3233 if (!principal || !principal->IsURIInPrefList(
3234 "dom.timeout.defer_during_load.force-disable")) {
3235 mTimeoutManager->SetLoading(aIsLoading);
3236 }
3237 }
3238
3239 HintIsLoading(aIsLoading);
3240}
3241
3242void nsGlobalWindowInner::HintIsLoading(bool aIsLoading) {
3243 // Hint to tell the JS GC to use modified triggers during pageload.
3244 if (mHintedWasLoading != aIsLoading) {
3245 using namespace js::gc;
3246 SetPerformanceHint(danger::GetJSContext(), aIsLoading
3247 ? PerformanceHint::InPageLoad
3248 : PerformanceHint::Normal);
3249 mHintedWasLoading = aIsLoading;
3250 }
3251}
3252
3253// nsISpeechSynthesisGetter
3254
3255#ifdef MOZ_WEBSPEECH1
3256SpeechSynthesis* nsGlobalWindowInner::GetSpeechSynthesis(ErrorResult& aError) {
3257 if (!mSpeechSynthesis) {
3258 mSpeechSynthesis = MakeRefPtr<SpeechSynthesis>(this);
3259 }
3260
3261 return mSpeechSynthesis;
3262}
3263
3264bool nsGlobalWindowInner::HasActiveSpeechSynthesis() {
3265 if (mSpeechSynthesis) {
3266 return !mSpeechSynthesis->HasEmptyQueue();
3267 }
3268
3269 return false;
3270}
3271
3272#endif
3273
3274mozilla::glean::Glean* nsGlobalWindowInner::Glean() {
3275 if (!mGlean) {
3276 mGlean = MakeRefPtr<mozilla::glean::Glean>(this);
3277 }
3278
3279 return mGlean;
3280}
3281
3282mozilla::glean::GleanPings* nsGlobalWindowInner::GleanPings() {
3283 if (!mGleanPings) {
3284 mGleanPings = MakeRefPtr<mozilla::glean::GleanPings>();
3285 }
3286
3287 return mGleanPings;
3288}
3289
3290Nullable<WindowProxyHolder> nsGlobalWindowInner::GetParent(
3291 ErrorResult& aError) {
3292 FORWARD_TO_OUTER_OR_THROW(GetParentOuter, (), aError, nullptr);
3293}
3294
3295/**
3296 * GetInProcessScriptableParent used to be called when a script read
3297 * window.parent. Under Fission, that is now handled by
3298 * BrowsingContext::GetParent, and the result is a WindowProxyHolder rather than
3299 * an actual global window. This method still exists for legacy callers which
3300 * relied on the old logic, and require in-process windows. However, it only
3301 * works correctly when no out-of-process frames exist between this window and
3302 * the top-level window, so it should not be used in new code.
3303 *
3304 * In contrast to GetRealParent, GetInProcessScriptableParent respects <iframe
3305 * mozbrowser> boundaries, so if |this| is contained by an <iframe
3306 * mozbrowser>, we will return |this| as its own parent.
3307 */
3308nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableParent() {
3309 FORWARD_TO_OUTER(GetInProcessScriptableParent, (), nullptr);
3310}
3311
3312/**
3313 * GetInProcessScriptableTop used to be called when a script read window.top.
3314 * Under Fission, that is now handled by BrowsingContext::Top, and the result is
3315 * a WindowProxyHolder rather than an actual global window. This method still
3316 * exists for legacy callers which relied on the old logic, and require
3317 * in-process windows. However, it only works correctly when no out-of-process
3318 * frames exist between this window and the top-level window, so it should not
3319 * be used in new code.
3320 *
3321 * In contrast to GetRealTop, GetInProcessScriptableTop respects <iframe
3322 * mozbrowser> boundaries. If we encounter a window owned by an <iframe
3323 * mozbrowser> while walking up the window hierarchy, we'll stop and return that
3324 * window.
3325 */
3326nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessScriptableTop() {
3327 FORWARD_TO_OUTER(GetInProcessScriptableTop, (), nullptr);
3328}
3329
3330void nsGlobalWindowInner::GetContent(JSContext* aCx,
3331 JS::MutableHandle<JSObject*> aRetval,
3332 CallerType aCallerType,
3333 ErrorResult& aError) {
3334 FORWARD_TO_OUTER_OR_THROW(GetContentOuter,
3335 (aCx, aRetval, aCallerType, aError), aError, );
3336}
3337
3338BarProp* nsGlobalWindowInner::GetMenubar(ErrorResult& aError) {
3339 if (!mMenubar) {
3340 mMenubar = MakeRefPtr<MenubarProp>(this);
3341 }
3342
3343 return mMenubar;
3344}
3345
3346BarProp* nsGlobalWindowInner::GetToolbar(ErrorResult& aError) {
3347 if (!mToolbar) {
3348 mToolbar = MakeRefPtr<ToolbarProp>(this);
3349 }
3350
3351 return mToolbar;
3352}
3353
3354BarProp* nsGlobalWindowInner::GetLocationbar(ErrorResult& aError) {
3355 if (!mLocationbar) {
3356 mLocationbar = MakeRefPtr<LocationbarProp>(this);
3357 }
3358 return mLocationbar;
3359}
3360
3361BarProp* nsGlobalWindowInner::GetPersonalbar(ErrorResult& aError) {
3362 if (!mPersonalbar) {
3363 mPersonalbar = MakeRefPtr<PersonalbarProp>(this);
3364 }
3365 return mPersonalbar;
3366}
3367
3368BarProp* nsGlobalWindowInner::GetStatusbar(ErrorResult& aError) {
3369 if (!mStatusbar) {
3370 mStatusbar = MakeRefPtr<StatusbarProp>(this);
3371 }
3372 return mStatusbar;
3373}
3374
3375BarProp* nsGlobalWindowInner::GetScrollbars(ErrorResult& aError) {
3376 if (!mScrollbars) {
3377 mScrollbars = MakeRefPtr<ScrollbarsProp>(this);
3378 }
3379
3380 return mScrollbars;
3381}
3382
3383bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
3384 // If we're called from JS (which is the only way we should be getting called
3385 // here) and we reach this point, that means our JS global is the current
3386 // target of the WindowProxy, which means that we are the "current inner"
3387 // of our outer. So if FORWARD_TO_OUTER fails to forward, that means the
3388 // outer is already torn down, which corresponds to the closed state.
3389 FORWARD_TO_OUTER(GetClosedOuter, (), true);
3390}
3391
3392Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
3393 uint32_t aIndex) {
3394 FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
3395}
3396
3397namespace {
3398
3399struct InterfaceShimEntry {
3400 const char* geckoName;
3401 const char* domName;
3402};
3403
3404} // anonymous namespace
3405
3406// We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
3407// interface that has interface constants that sites might be getting off
3408// of Ci.
3409const InterfaceShimEntry kInterfaceShimMap[] = {
3410 {"nsIXMLHttpRequest", "XMLHttpRequest"},
3411 {"nsIDOMDOMException", "DOMException"},
3412 {"nsIDOMNode", "Node"},
3413 {"nsIDOMCSSRule", "CSSRule"},
3414 {"nsIDOMEvent", "Event"},
3415 {"nsIDOMNSEvent", "Event"},
3416 {"nsIDOMKeyEvent", "KeyEvent"},
3417 {"nsIDOMMouseEvent", "MouseEvent"},
3418 {"nsIDOMMouseScrollEvent", "MouseScrollEvent"},
3419 {"nsIDOMMutationEvent", "MutationEvent"},
3420 {"nsIDOMUIEvent", "UIEvent"},
3421 {"nsIDOMHTMLMediaElement", "HTMLMediaElement"},
3422 {"nsIDOMRange", "Range"},
3423 // Think about whether Ci.nsINodeFilter can just go away for websites!
3424 {"nsIDOMNodeFilter", "NodeFilter"},
3425 {"nsIDOMXPathResult", "XPathResult"}};
3426
3427bool nsGlobalWindowInner::ResolveComponentsShim(
3428 JSContext* aCx, JS::Handle<JSObject*> aGlobal,
3429 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3430 // Warn once.
3431 nsCOMPtr<Document> doc = GetExtantDoc();
3432 if (doc) {
3433 doc->WarnOnceAndReportAbout(
3434 DeprecatedOperations::eComponents, /* asError = */
3435 true);
3436 // Keep track of how often this happens.
3437 doc->SetUseCounter(eUseCounter_custom_ComponentsShimResolved);
3438 }
3439
3440 // Create a fake Components object.
3441 AssertSameCompartment(aCx, aGlobal);
3442 JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx));
3443 if (NS_WARN_IF(!components)NS_warn_if_impl(!components, "!components", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3443)
) {
3444 return false;
3445 }
3446
3447 // Create a fake interfaces object.
3448 JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx));
3449 if (NS_WARN_IF(!interfaces)NS_warn_if_impl(!interfaces, "!interfaces", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3449)
) {
3450 return false;
3451 }
3452 bool ok =
3453 JS_DefineProperty(aCx, components, "interfaces", interfaces,
3454 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3455 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3455)
) {
3456 return false;
3457 }
3458
3459 // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
3460 // interfaces with constants.
3461 for (auto entry : kInterfaceShimMap) {
3462 // Grab the names from the table.
3463 const char* geckoName = entry.geckoName;
3464 const char* domName = entry.domName;
3465
3466 // Look up the appopriate interface object on the global.
3467 JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue());
3468 ok = JS_GetProperty(aCx, aGlobal, domName, &v);
3469 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3469)
) {
3470 return false;
3471 }
3472 if (!v.isObject()) {
3473 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"
, 3473)
;
3474 continue;
3475 }
3476
3477 // Define the shim on the interfaces object.
3478 ok = JS_DefineProperty(
3479 aCx, interfaces, geckoName, v,
3480 JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
3481 if (NS_WARN_IF(!ok)NS_warn_if_impl(!ok, "!ok", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3481)
) {
3482 return false;
3483 }
3484 }
3485
3486 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3487 JS::ObjectValue(*components),
3488 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3489 JS::PropertyAttribute::Writable})));
3490 return true;
3491}
3492
3493#ifdef RELEASE_OR_BETA
3494# define USE_CONTROLLERS_SHIM
3495#endif
3496
3497#ifdef USE_CONTROLLERS_SHIM
3498static const JSClass ControllersShimClass = {"Controllers", 0};
3499static const JSClass XULControllersShimClass = {"XULControllers", 0};
3500#endif
3501
3502bool nsGlobalWindowInner::DoResolve(
3503 JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
3504 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) {
3505 // Note: Keep this in sync with MayResolve.
3506
3507 // Note: The infallibleInit call in GlobalResolve depends on this check.
3508 if (!aId.isString()) {
3509 return true;
3510 }
3511
3512 bool found;
3513 if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) {
3514 return false;
3515 }
3516
3517 if (found) {
3518 return true;
3519 }
3520
3521 // We support a cut-down Components.interfaces in case websites are
3522 // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones
3523 // that have constants.
3524 if (StaticPrefs::dom_use_components_shim() &&
3525 aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3526 return ResolveComponentsShim(aCx, aObj, aDesc);
3527 }
3528
3529 // Bug 2072122: Trusted Types readiness experiment only, to be removed.
3530 // React DOM looks up this global when it loads. A lookup that reaches us
3531 // means the page does not define it; we never resolve it.
3532 if (StaticPrefs::dom_security_trusted_types_readiness_telemetry_enabled() &&
3533 aId == XPCJSRuntime::Get()->GetStringID(
3534 XPCJSContext::IDX_REACT_DEVTOOLS_GLOBAL_HOOK) &&
3535 !xpc::IsXrayWrapper(aObj)) {
3536 if (Document* doc = GetExtantDoc();
3537 doc && !doc->IsDetectingTrustedTypesLibrary()) {
3538 doc->SetTrustedTypesReadinessSignal(
3539 TrustedTypesReadinessSignal::LookedUpReactDevToolsHook);
3540 }
3541 return true;
3542 }
3543
3544 // We also support a "window.controllers" thing; apparently some
3545 // sites use it for browser-sniffing. See bug 1010577.
3546#ifdef USE_CONTROLLERS_SHIM
3547 // Note: We use |aObj| rather than |this| to get the principal here, because
3548 // this is called during Window setup when the Document isn't necessarily
3549 // hooked up yet.
3550 if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3551 aId == XPCJSRuntime::Get()->GetStringID(
3552 XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
3553 !xpc::IsXrayWrapper(aObj) &&
3554 !nsContentUtils::ObjectPrincipal(aObj)->IsSystemPrincipal()) {
3555 if (GetExtantDoc()) {
3556 GetExtantDoc()->WarnOnceAndReportAbout(
3557 DeprecatedOperations::eWindow_Cc_ontrollers);
3558 }
3559 const JSClass* clazz;
3560 if (aId ==
3561 XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
3562 clazz = &XULControllersShimClass;
3563 } else {
3564 clazz = &ControllersShimClass;
3565 }
3566 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", 3566
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(aObj)"
")"); do { MOZ_CrashSequence(__null, 3566); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3567 JS::Rooted<JSObject*> shim(aCx, JS_NewObject(aCx, clazz));
3568 if (NS_WARN_IF(!shim)NS_warn_if_impl(!shim, "!shim", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3568)
) {
3569 return false;
3570 }
3571
3572 aDesc.set(mozilla::Some(JS::PropertyDescriptor::Data(
3573 JS::ObjectValue(*shim),
3574 {JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable,
3575 JS::PropertyAttribute::Writable})));
3576 return true;
3577 }
3578#endif
3579
3580 return true;
3581}
3582
3583/* static */
3584bool nsGlobalWindowInner::MayResolve(jsid aId) {
3585 // Note: This function does not fail and may not have any side-effects.
3586 // Note: Keep this in sync with DoResolve.
3587 if (!aId.isString()) {
3588 return false;
3589 }
3590
3591 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
3592 return true;
3593 }
3594
3595 if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
3596 aId == XPCJSRuntime::Get()->GetStringID(
3597 XPCJSContext::IDX_CONTROLLERS_CLASS)) {
3598 // We only resolve .controllers/.Controllers in release builds and on
3599 // non-chrome windows, but let's not worry about any of that stuff.
3600 return true;
3601 }
3602
3603 // Bug 2072122: Trusted Types readiness experiment only, to be removed.
3604 if (StaticPrefs::dom_security_trusted_types_readiness_telemetry_enabled() &&
3605 aId == XPCJSRuntime::Get()->GetStringID(
3606 XPCJSContext::IDX_REACT_DEVTOOLS_GLOBAL_HOOK)) {
3607 return true;
3608 }
3609
3610 return WebIDLGlobalNameHash::MayResolve(aId);
3611}
3612
3613void nsGlobalWindowInner::GetOwnPropertyNames(
3614 JSContext* aCx, JS::MutableHandleVector<jsid> aNames, bool aEnumerableOnly,
3615 ErrorResult& aRv) {
3616 if (aEnumerableOnly) {
3617 // The names we would return from here get defined on the window via one of
3618 // two codepaths. The ones coming from the WebIDLGlobalNameHash will end up
3619 // in the DefineConstructor function in BindingUtils, which always defines
3620 // things as non-enumerable. The ones coming from the script namespace
3621 // manager get defined by our resolve hook using FillPropertyDescriptor with
3622 // 0 for the property attributes, so non-enumerable as well.
3623 //
3624 // So in the aEnumerableOnly case we have nothing to do.
3625 return;
3626 }
3627
3628 // "Components" is marked as enumerable but only resolved on demand :-/.
3629 // aNames.AppendElement(u"Components"_ns);
3630
3631 JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
3632
3633 // There are actually two ways we can get called here: For normal
3634 // enumeration or for Xray enumeration. In the latter case, we want to
3635 // return all possible WebIDL names, because we don't really support
3636 // deleting these names off our Xray; trying to resolve them will just make
3637 // them come back. In the former case, we want to avoid returning deleted
3638 // names. But the JS engine already knows about the non-deleted
3639 // already-resolved names, so we can just return the so-far-unresolved ones.
3640 //
3641 // We can tell which case we're in by whether aCx is in our wrapper's
3642 // compartment. If not, we're in the Xray case.
3643 WebIDLGlobalNameHash::NameType nameType =
3644 js::IsObjectInContextCompartment(wrapper, aCx)
3645 ? WebIDLGlobalNameHash::UnresolvedNamesOnly
3646 : WebIDLGlobalNameHash::AllNames;
3647 if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) {
3648 aRv.NoteJSContextException(aCx);
3649 }
3650}
3651
3652/* static */
3653bool nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext*, JSObject* aObj) {
3654 // For now, have to deal with XPConnect objects here.
3655 nsGlobalWindowInner* win = xpc::WindowOrNull(aObj);
3656 return win && win->IsChromeWindow() &&
3657 nsContentUtils::ObjectPrincipal(aObj) ==
3658 nsContentUtils::GetSystemPrincipal();
3659}
3660
3661/* static */
3662bool nsGlobalWindowInner::DeviceSensorsEnabled(JSContext*, JSObject*) {
3663 return Preferences::GetBool("device.sensors.enabled");
3664}
3665
3666Crypto* nsGlobalWindowInner::GetCrypto(ErrorResult& aError) {
3667 if (!mCrypto) {
3668 mCrypto = MakeRefPtr<Crypto>(this);
3669 }
3670 return mCrypto;
3671}
3672
3673nsIControllers* nsGlobalWindowInner::GetControllers(ErrorResult& aError) {
3674 FORWARD_TO_OUTER_OR_THROW(GetControllersOuter, (aError), aError, nullptr);
3675}
3676
3677nsresult nsGlobalWindowInner::GetControllers(nsIControllers** aResult) {
3678 ErrorResult rv;
3679 nsCOMPtr<nsIControllers> controllers = GetControllers(rv);
3680 controllers.forget(aResult);
3681
3682 return rv.StealNSResult();
3683}
3684
3685Nullable<WindowProxyHolder> nsGlobalWindowInner::GetOpenerWindow(
3686 ErrorResult& aError) {
3687 FORWARD_TO_OUTER_OR_THROW(GetOpenerWindowOuter, (), aError, nullptr);
3688}
3689
3690void nsGlobalWindowInner::GetOpener(JSContext* aCx,
3691 JS::MutableHandle<JS::Value> aRetval,
3692 ErrorResult& aError) {
3693 Nullable<WindowProxyHolder> opener = GetOpenerWindow(aError);
3694 if (aError.Failed() || opener.IsNull()) {
3695 aRetval.setNull();
3696 return;
3697 }
3698
3699 if (!ToJSValue(aCx, opener.Value(), aRetval)) {
3700 aError.NoteJSContextException(aCx);
3701 }
3702}
3703
3704void nsGlobalWindowInner::SetOpener(JSContext* aCx,
3705 JS::Handle<JS::Value> aOpener,
3706 ErrorResult& aError) {
3707 if (aOpener.isNull()) {
3708 RefPtr<BrowsingContext> bc(GetBrowsingContext());
3709 if (!bc->IsDiscarded()) {
3710 bc->SetOpener(nullptr);
3711 }
3712 return;
3713 }
3714
3715 // If something other than null is passed, just define aOpener on our inner
3716 // window's JS object, wrapped into the current compartment so that for Xrays
3717 // we define on the Xray expando object, but don't set it on the outer window,
3718 // so that it'll get reset on navigation. This is just like replaceable
3719 // properties, but we're not quite readonly.
3720 RedefineProperty(aCx, "opener", aOpener, aError);
3721}
3722
3723void nsGlobalWindowInner::GetEvent(OwningEventOrUndefined& aRetval) {
3724 if (mEvent) {
3725 aRetval.SetAsEvent() = mEvent;
3726 } else {
3727 aRetval.SetUndefined();
3728 }
3729}
3730
3731void nsGlobalWindowInner::GetStatus(nsAString& aStatus, ErrorResult& aError) {
3732 FORWARD_TO_OUTER_OR_THROW(GetStatusOuter, (aStatus), aError, );
3733}
3734
3735void nsGlobalWindowInner::SetStatus(const nsAString& aStatus,
3736 ErrorResult& aError) {
3737 FORWARD_TO_OUTER_OR_THROW(SetStatusOuter, (aStatus), aError, );
3738}
3739
3740void nsGlobalWindowInner::GetName(nsAString& aName, ErrorResult& aError) {
3741 FORWARD_TO_OUTER_OR_THROW(GetNameOuter, (aName), aError, );
3742}
3743
3744void nsGlobalWindowInner::SetName(const nsAString& aName,
3745 mozilla::ErrorResult& aError) {
3746 FORWARD_TO_OUTER_OR_THROW(SetNameOuter, (aName, aError), aError, );
3747}
3748
3749double nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3750 ErrorResult& aError) {
3751 FORWARD_TO_OUTER_OR_THROW(GetInnerWidthOuter, (aCallerType, aError), aError,
3752 0);
3753}
3754
3755nsresult nsGlobalWindowInner::GetInnerWidth(CallerType aCallerType,
3756 double* aWidth) {
3757 ErrorResult rv;
3758 *aWidth = GetInnerWidth(aCallerType, rv);
3759 return rv.StealNSResult();
3760}
3761
3762double nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3763 ErrorResult& aError) {
3764 FORWARD_TO_OUTER_OR_THROW(GetInnerHeightOuter, (aCallerType, aError), aError,
3765 0);
3766}
3767
3768nsresult nsGlobalWindowInner::GetInnerHeight(CallerType aCallerType,
3769 double* aHeight) {
3770 ErrorResult rv;
3771 *aHeight = GetInnerHeight(aCallerType, rv);
3772 return rv.StealNSResult();
3773}
3774
3775int32_t nsGlobalWindowInner::GetOuterWidth(CallerType aCallerType,
3776 ErrorResult& aError) {
3777 FORWARD_TO_OUTER_OR_THROW(GetOuterWidthOuter, (aCallerType, aError), aError,
3778 0);
3779}
3780
3781int32_t nsGlobalWindowInner::GetOuterHeight(CallerType aCallerType,
3782 ErrorResult& aError) {
3783 FORWARD_TO_OUTER_OR_THROW(GetOuterHeightOuter, (aCallerType, aError), aError,
3784 0);
3785}
3786
3787double nsGlobalWindowInner::ScreenEdgeSlopX() const {
3788 FORWARD_TO_OUTER(ScreenEdgeSlopX, (), 0);
3789}
3790
3791double nsGlobalWindowInner::ScreenEdgeSlopY() const {
3792 FORWARD_TO_OUTER(ScreenEdgeSlopY, (), 0);
3793}
3794
3795int32_t nsGlobalWindowInner::GetScreenX(CallerType aCallerType,
3796 ErrorResult& aError) {
3797 FORWARD_TO_OUTER_OR_THROW(GetScreenXOuter, (aCallerType, aError), aError, 0);
3798}
3799
3800int32_t nsGlobalWindowInner::GetScreenY(CallerType aCallerType,
3801 ErrorResult& aError) {
3802 FORWARD_TO_OUTER_OR_THROW(GetScreenYOuter, (aCallerType, aError), aError, 0);
3803}
3804
3805float nsGlobalWindowInner::GetMozInnerScreenX(CallerType aCallerType,
3806 ErrorResult& aError) {
3807 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenXOuter, (aCallerType), aError, 0);
3808}
3809
3810float nsGlobalWindowInner::GetMozInnerScreenY(CallerType aCallerType,
3811 ErrorResult& aError) {
3812 FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenYOuter, (aCallerType), aError, 0);
3813}
3814
3815static nsPresContext* GetPresContextForRatio(Document* aDoc) {
3816 if (nsPresContext* presContext = aDoc->GetPresContext()) {
3817 return presContext;
3818 }
3819 // We're in an undisplayed subdocument... There's not really an awesome way
3820 // to tell what the right DPI is from here, so we try to walk up our parent
3821 // document chain to the extent that the docs can observe each other.
3822 Document* doc = aDoc;
3823 while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
3824 doc = doc->GetInProcessParentDocument();
3825 if (nsPresContext* presContext = doc->GetPresContext()) {
3826 return presContext;
3827 }
3828 }
3829 return nullptr;
3830}
3831
3832double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType,
3833 ErrorResult& aError) {
3834 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)
;
3835
3836 RefPtr<nsPresContext> presContext = GetPresContextForRatio(mDoc);
3837 if (NS_WARN_IF(!presContext)NS_warn_if_impl(!presContext, "!presContext", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 3837)
) {
3838 // Still nothing, oh well.
3839 return 1.0;
3840 }
3841
3842 if (nsIGlobalObject::ShouldResistFingerprinting(
3843 aCallerType, RFPTarget::WindowDevicePixelRatio)) {
3844 return nsRFPService::GetDevicePixelRatioAtZoom(presContext->GetFullZoom());
3845 }
3846
3847 if (aCallerType == CallerType::NonSystem) {
3848 float overrideDPPX = presContext->GetOverrideDPPX();
3849 if (overrideDPPX > 0.0f) {
3850 return overrideDPPX;
3851 }
3852 }
3853
3854 return double(AppUnitsPerCSSPixel()) /
3855 double(presContext->AppUnitsPerDevPixel());
3856}
3857
3858double nsGlobalWindowInner::GetDesktopToDeviceScale(ErrorResult& aError) {
3859 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)
;
3860 nsPresContext* presContext = GetPresContextForRatio(mDoc);
3861 if (!presContext) {
3862 return 1.0;
3863 }
3864 return presContext->DeviceContext()->GetDesktopToDeviceScale().scale;
3865}
3866
3867uint32_t nsGlobalWindowInner::RequestAnimationFrame(
3868 FrameRequestCallback& aCallback, ErrorResult& aError) {
3869 if (!mDoc) {
3870 return 0;
3871 }
3872
3873 if (GetWrapperPreserveColor()) {
3874 js::NotifyAnimationActivity(GetWrapperPreserveColor());
3875 }
3876
3877 DebuggerNotificationDispatch(this,
3878 DebuggerNotificationType::RequestAnimationFrame);
3879
3880 uint32_t handle;
3881 aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
3882 return handle;
3883}
3884
3885void nsGlobalWindowInner::CancelAnimationFrame(uint32_t aHandle,
3886 ErrorResult& aError) {
3887 if (!mDoc) {
3888 return;
3889 }
3890
3891 DebuggerNotificationDispatch(this,
3892 DebuggerNotificationType::CancelAnimationFrame);
3893
3894 mDoc->CancelFrameRequestCallback(aHandle);
3895}
3896
3897already_AddRefed<MediaQueryList> nsGlobalWindowInner::MatchMedia(
3898 const nsACString& aMediaQueryList, CallerType aCallerType,
3899 ErrorResult& aError) {
3900 ENSURE_ACTIVE_DOCUMENT(aError, nullptr)do { if ((__builtin_expect(!!(!HasActiveDocument()), 0))) { aError
.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO); return nullptr; }
} while (0)
;
3901 return mDoc->MatchMedia(aMediaQueryList, aCallerType);
3902}
3903
3904int32_t nsGlobalWindowInner::GetScrollMinX(ErrorResult& aError) {
3905 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, 0);
3906}
3907
3908int32_t nsGlobalWindowInner::GetScrollMinY(ErrorResult& aError) {
3909 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideTop), aError, 0);
3910}
3911
3912int32_t nsGlobalWindowInner::GetScrollMaxX(ErrorResult& aError) {
3913 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideRight), aError, 0);
3914}
3915
3916int32_t nsGlobalWindowInner::GetScrollMaxY(ErrorResult& aError) {
3917 FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0);
3918}
3919
3920double nsGlobalWindowInner::GetScrollX(ErrorResult& aError) {
3921 FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0);
3922}
3923
3924double nsGlobalWindowInner::GetScrollY(ErrorResult& aError) {
3925 FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0);
3926}
3927
3928uint32_t nsGlobalWindowInner::Length() { FORWARD_TO_OUTER(Length, (), 0); }
3929
3930Nullable<WindowProxyHolder> nsGlobalWindowInner::GetTop(
3931 mozilla::ErrorResult& aError) {
3932 FORWARD_TO_OUTER_OR_THROW(GetTopOuter, (), aError, nullptr);
3933}
3934
3935already_AddRefed<BrowsingContext> nsGlobalWindowInner::GetChildWindow(
3936 const nsAString& aName) {
3937 if (GetOuterWindowInternal()) {
3938 return GetOuterWindowInternal()->GetChildWindow(aName);
3939 }
3940 return nullptr;
3941}
3942
3943void nsGlobalWindowInner::RefreshRealmPrincipal() {
3944 JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor());
3945 nsJSPrincipals* existing = nsJSPrincipals::get(JS::GetRealmPrincipals(realm));
3946 nsJSPrincipals* jsPrincipals = nsJSPrincipals::get(mDoc->NodePrincipal());
3947 if (existing != jsPrincipals) {
3948 HoldOldPrincipal(existing);
3949 }
3950 JS::SetRealmPrincipals(realm, jsPrincipals);
3951}
3952
3953void nsGlobalWindowInner::RefreshReduceTimerPrecisionCallerType() {
3954 JS::SetRealmReduceTimerPrecisionCallerType(
3955 js::GetNonCCWObjectRealm(GetWrapperPreserveColor()),
3956 RTPCallerTypeToToken(GetRTPCallerType()));
3957}
3958
3959already_AddRefed<nsIWidget> nsGlobalWindowInner::GetMainWidget() const {
3960 FORWARD_TO_OUTER(GetMainWidget, (), nullptr);
3961}
3962
3963nsIWidget* nsGlobalWindowInner::GetNearestWidget() const {
3964 if (GetOuterWindowInternal()) {
3965 return GetOuterWindowInternal()->GetNearestWidget();
3966 }
3967 return nullptr;
3968}
3969
3970void nsGlobalWindowInner::SetFullScreen(bool aFullscreen,
3971 CallerType aCallerType,
3972 ErrorResult& aError) {
3973 if (aCallerType == CallerType::NonSystem) {
3974 if (Document* doc = GetExtantDoc()) {
3975 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3976 }
3977 }
3978 FORWARD_TO_OUTER_OR_THROW(SetFullscreenOuter, (aFullscreen, aError), aError,
3979 /* void */);
3980}
3981
3982bool nsGlobalWindowInner::GetFullScreen(CallerType aCallerType,
3983 ErrorResult& aError) {
3984 if (aCallerType == CallerType::NonSystem) {
3985 if (Document* doc = GetExtantDoc()) {
3986 doc->WarnOnceAndReportAbout(DeprecatedOperations::eFullscreenAttribute);
3987 }
3988 }
3989 FORWARD_TO_OUTER_OR_THROW(GetFullscreenOuter, (), aError, false);
3990}
3991
3992bool nsGlobalWindowInner::GetFullScreen() {
3993 bool fullscreen = GetFullScreen(CallerType::System, IgnoreErrors());
3994 return fullscreen;
3995}
3996
3997void nsGlobalWindowInner::Dump(const nsAString& aStr) {
3998 if (!nsJSUtils::DumpEnabled()) {
3999 return;
4000 }
4001
4002 char* cstr = ToNewUTF8String(aStr);
4003
4004#if defined(XP_MACOSX)
4005 // have to convert \r to \n so that printing to the console works
4006 char *c = cstr, *cEnd = cstr + strlen(cstr);
4007 while (c < cEnd) {
4008 if (*c == '\r') *c = '\n';
4009 c++;
4010 }
4011#endif
4012
4013 if (cstr) {
4014 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)
4015 ("[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)
;
4016#ifdef XP_WIN
4017 PrintToDebugger(cstr);
4018#endif
4019#ifdef ANDROID
4020 __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
4021#endif
4022 FILE* fp = gDumpFile ? gDumpFile : stdoutstdout;
4023 fputs(cstr, fp);
4024 fflush(fp);
4025 free(cstr);
4026 }
4027}
4028
4029void nsGlobalWindowInner::Alert(nsIPrincipal& aSubjectPrincipal,
4030 ErrorResult& aError) {
4031 Alert(u""_ns, aSubjectPrincipal, aError);
4032}
4033
4034void nsGlobalWindowInner::Alert(const nsAString& aMessage,
4035 nsIPrincipal& aSubjectPrincipal,
4036 ErrorResult& aError) {
4037 FORWARD_TO_OUTER_OR_THROW(AlertOuter, (aMessage, aSubjectPrincipal, aError),
4038 aError, );
4039}
4040
4041bool nsGlobalWindowInner::Confirm(const nsAString& aMessage,
4042 nsIPrincipal& aSubjectPrincipal,
4043 ErrorResult& aError) {
4044 FORWARD_TO_OUTER_OR_THROW(ConfirmOuter, (aMessage, aSubjectPrincipal, aError),
4045 aError, false);
4046}
4047
4048already_AddRefed<Promise> nsGlobalWindowInner::Fetch(
4049 const RequestOrUTF8String& aInput, const RequestInit& aInit,
4050 CallerType aCallerType, ErrorResult& aRv) {
4051 return FetchRequest(this, aInput, aInit, aCallerType, aRv);
4052}
4053
4054void nsGlobalWindowInner::Prompt(const nsAString& aMessage,
4055 const nsAString& aInitial, nsAString& aReturn,
4056 nsIPrincipal& aSubjectPrincipal,
4057 ErrorResult& aError) {
4058 FORWARD_TO_OUTER_OR_THROW(
4059 PromptOuter, (aMessage, aInitial, aReturn, aSubjectPrincipal, aError),
4060 aError, );
4061}
4062
4063void nsGlobalWindowInner::Focus(CallerType aCallerType, ErrorResult& aError) {
4064 FORWARD_TO_OUTER_OR_THROW(FocusOuter,
4065 (aCallerType, /* aFromOtherProcess */ false,
4066 nsFocusManager::GenerateFocusActionId()),
4067 aError, );
4068}
4069
4070nsresult nsGlobalWindowInner::Focus(CallerType aCallerType) {
4071 ErrorResult rv;
4072 Focus(aCallerType, rv);
4073
4074 return rv.StealNSResult();
4075}
4076
4077void nsGlobalWindowInner::Blur(CallerType aCallerType, ErrorResult& aError) {
4078 FORWARD_TO_OUTER_OR_THROW(BlurOuter, (aCallerType), aError, );
4079}
4080
4081void nsGlobalWindowInner::Stop(ErrorResult& aError) {
4082 FORWARD_TO_OUTER_OR_THROW(StopOuter, (aError), aError, );
4083}
4084
4085void nsGlobalWindowInner::Print(ErrorResult& aError) {
4086 FORWARD_TO_OUTER_OR_THROW(PrintOuter, (aError), aError, );
4087}
4088
4089Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview(
4090 nsIPrintSettings* aSettings, nsIWebProgressListener* aListener,
4091 nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) {
4092 FORWARD_TO_OUTER_OR_THROW(
4093 Print,
4094 (aSettings,
4095 /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto,
4096 nsGlobalWindowOuter::IsPreview::Yes,
4097 nsGlobalWindowOuter::IsForWindowDotPrint::No,
4098 /* aPrintPreviewCallback = */ nullptr, nullptr, aError),
4099 aError, nullptr);
4100}
4101
4102void nsGlobalWindowInner::MoveTo(int32_t aXPos, int32_t aYPos,
4103 CallerType aCallerType, ErrorResult& aError) {
4104 FORWARD_TO_OUTER_OR_THROW(MoveToOuter, (aXPos, aYPos, aCallerType, aError),
4105 aError, );
4106}
4107
4108void nsGlobalWindowInner::MoveBy(int32_t aXDif, int32_t aYDif,
4109 CallerType aCallerType, ErrorResult& aError) {
4110 FORWARD_TO_OUTER_OR_THROW(MoveByOuter, (aXDif, aYDif, aCallerType, aError),
4111 aError, );
4112}
4113
4114void nsGlobalWindowInner::ResizeTo(int32_t aWidth, int32_t aHeight,
4115 CallerType aCallerType,
4116 ErrorResult& aError) {
4117 FORWARD_TO_OUTER_OR_THROW(ResizeToOuter,
4118 (aWidth, aHeight, aCallerType, aError), aError, );
4119}
4120
4121void nsGlobalWindowInner::ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
4122 CallerType aCallerType,
4123 ErrorResult& aError) {
4124 FORWARD_TO_OUTER_OR_THROW(
4125 ResizeByOuter, (aWidthDif, aHeightDif, aCallerType, aError), aError, );
4126}
4127
4128void nsGlobalWindowInner::MoveResize(int32_t aX, int32_t aY, int32_t aWidth,
4129 int32_t aHeight, ErrorResult& aError) {
4130 const auto callerType = CallerType::System; // We're ChromeOnly
4131 FORWARD_TO_OUTER_OR_THROW(
4132 MoveResizeOuter, (aX, aY, aWidth, aHeight, callerType, aError), aError, );
4133}
4134
4135void nsGlobalWindowInner::SizeToContent(
4136 const SizeToContentConstraints& aConstraints, ErrorResult& aError) {
4137 FORWARD_TO_OUTER_OR_THROW(SizeToContentOuter, (aConstraints, aError),
4138 aError, );
4139}
4140
4141already_AddRefed<nsPIWindowRoot> nsGlobalWindowInner::GetTopWindowRoot() {
4142 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
4143 if (!outer) {
4144 return nullptr;
4145 }
4146 return outer->GetTopWindowRoot();
4147}
4148
4149void nsGlobalWindowInner::ScrollTo(double aXScroll, double aYScroll) {
4150 ScrollToOptions options;
4151 options.mLeft.Construct(aXScroll);
4152 options.mTop.Construct(aYScroll);
4153 ScrollTo(options);
4154}
4155
4156void nsGlobalWindowInner::ScrollTo(const ScrollToOptions& aOptions) {
4157 Maybe<double> left;
4158 Maybe<double> top;
4159 if (aOptions.mLeft.WasPassed()) {
4160 left.emplace(ToZeroIfNonfinite(aOptions.mLeft.Value()));
4161 }
4162 if (aOptions.mTop.WasPassed()) {
4163 top.emplace(ToZeroIfNonfinite(aOptions.mTop.Value()));
4164 }
4165
4166 // When scrolling to a non-zero offset, we need to determine whether that
4167 // position is within our scrollable range, so we need updated layout
4168 // information.
4169 if ((top && *top != 0) || (left && *left != 0)) {
4170 FlushPendingNotifications(FlushType::Layout);
4171 }
4172
4173 ScrollContainerFrame* sf = GetScrollContainerFrame();
4174 if (!sf) {
4175 return;
4176 }
4177 CSSPoint scrollPos = sf->GetScrollPositionCSSPixels();
4178 if (left) {
4179 scrollPos.x = *left;
4180 }
4181 if (top) {
4182 scrollPos.y = *top;
4183 }
4184 // Here we calculate what the max pixel value is that we can
4185 // scroll to, we do this by dividing maxint with the pixel to
4186 // twips conversion factor, and subtracting 4, the 4 comes from
4187 // experimenting with this value, anything less makes the view
4188 // code not scroll correctly, I have no idea why. -- jst
4189 //
4190 // FIXME(emilio): This seems like if needed it should be done by the
4191 // scrolling code itself...
4192 const double maxpx = CSSPixel::FromAppUnits(0x7fffffff) - 4;
4193 if (scrollPos.x > maxpx) {
4194 scrollPos.x = maxpx;
4195 }
4196 if (scrollPos.y > maxpx) {
4197 scrollPos.y = maxpx;
4198 }
4199 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4200 sf->ScrollToCSSPixels(scrollPos, scrollMode);
4201}
4202
4203void nsGlobalWindowInner::ScrollBy(double aXScrollDif, double aYScrollDif) {
4204 ScrollToOptions options;
4205 options.mLeft.Construct(aXScrollDif);
4206 options.mTop.Construct(aYScrollDif);
4207 // It seems like it would make more sense for ScrollBy to use
4208 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4209 // Perhaps Web content does too.
4210 ScrollBy(options);
4211}
4212
4213void nsGlobalWindowInner::ScrollBy(const ScrollToOptions& aOptions) {
4214 CSSPoint scrollDelta;
4215 if (aOptions.mLeft.WasPassed()) {
4216 scrollDelta.x = ToZeroIfNonfinite(aOptions.mLeft.Value());
4217 }
4218 if (aOptions.mTop.WasPassed()) {
4219 scrollDelta.y = ToZeroIfNonfinite(aOptions.mTop.Value());
4220 }
4221
4222 if (!scrollDelta.x && !scrollDelta.y) {
4223 return;
4224 }
4225
4226 FlushPendingNotifications(FlushType::Layout);
4227 ScrollContainerFrame* sf = GetScrollContainerFrame();
4228 if (!sf) {
4229 return;
4230 }
4231
4232 auto scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4233 sf->ScrollByCSSPixels(scrollDelta, scrollMode);
4234}
4235
4236void nsGlobalWindowInner::ScrollByLines(int32_t numLines,
4237 const ScrollOptions& aOptions) {
4238 if (!numLines) {
4239 return;
4240 }
4241 FlushPendingNotifications(FlushType::Layout);
4242 ScrollContainerFrame* sf = GetScrollContainerFrame();
4243 if (!sf) {
4244 return;
4245 }
4246 // It seems like it would make more sense for ScrollByLines to use
4247 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4248 // Perhaps Web content does too.
4249 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4250 sf->ScrollBy(nsIntPoint(0, numLines), ScrollUnit::LINES, scrollMode);
4251}
4252
4253void nsGlobalWindowInner::ScrollByPages(int32_t numPages,
4254 const ScrollOptions& aOptions) {
4255 if (!numPages) {
4256 return;
4257 }
4258 FlushPendingNotifications(FlushType::Layout);
4259 ScrollContainerFrame* sf = GetScrollContainerFrame();
4260 if (!sf) {
4261 return;
4262 }
4263 // It seems like it would make more sense for ScrollByPages to use
4264 // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
4265 // Perhaps Web content does too.
4266 ScrollMode scrollMode = sf->ScrollModeForScrollBehavior(aOptions.mBehavior);
4267
4268 sf->ScrollBy(nsIntPoint(0, numPages), ScrollUnit::PAGES, scrollMode);
4269}
4270
4271void nsGlobalWindowInner::MozScrollSnap() {
4272 FlushPendingNotifications(FlushType::Layout);
4273 if (ScrollContainerFrame* sf = GetScrollContainerFrame()) {
4274 sf->ScrollSnap();
4275 }
4276}
4277
4278void nsGlobalWindowInner::ClearTimeout(int32_t aHandle) {
4279 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout);
4280
4281 if (aHandle > 0) {
4282 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4283 }
4284}
4285
4286void nsGlobalWindowInner::ClearInterval(int32_t aHandle) {
4287 DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval);
4288
4289 if (aHandle > 0) {
4290 mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
4291 }
4292}
4293
4294void nsGlobalWindowInner::SetResizable(bool aResizable) const {
4295 // nop
4296}
4297
4298void nsGlobalWindowInner::CaptureEvents() {
4299 // Intentionally a no-op, as this API is deprecated.
4300}
4301
4302void nsGlobalWindowInner::ReleaseEvents() {
4303 // Intentionally a no-op, as this API is deprecated.
4304}
4305
4306Nullable<WindowProxyHolder> nsGlobalWindowInner::Open(const nsAString& aUrl,
4307 const nsAString& aName,
4308 const nsAString& aOptions,
4309 ErrorResult& aError) {
4310 FORWARD_TO_OUTER_OR_THROW(OpenOuter, (aUrl, aName, aOptions, aError), aError,
4311 nullptr);
4312}
4313
4314Nullable<WindowProxyHolder> nsGlobalWindowInner::OpenDialog(
4315 JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
4316 const nsAString& aOptions, const Sequence<JS::Value>& aExtraArgument,
4317 ErrorResult& aError) {
4318 FORWARD_TO_OUTER_OR_THROW(
4319 OpenDialogOuter, (aCx, aUrl, aName, aOptions, aExtraArgument, aError),
4320 aError, nullptr);
4321}
4322
4323WindowProxyHolder nsGlobalWindowInner::GetFrames(ErrorResult& aError) {
4324 FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, Window());
4325}
4326
4327void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4328 JS::Handle<JS::Value> aMessage,
4329 const nsAString& aTargetOrigin,
4330 JS::Handle<JS::Value> aTransfer,
4331 nsIPrincipal& aSubjectPrincipal,
4332 ErrorResult& aError) {
4333 FORWARD_TO_OUTER_OR_THROW(
4334 PostMessageMozOuter,
4335 (aCx, aMessage, aTargetOrigin, aTransfer, aSubjectPrincipal, aError),
4336 aError, );
4337}
4338
4339void nsGlobalWindowInner::PostMessageMoz(JSContext* aCx,
4340 JS::Handle<JS::Value> aMessage,
4341 const nsAString& aTargetOrigin,
4342 const Sequence<JSObject*>& aTransfer,
4343 nsIPrincipal& aSubjectPrincipal,
4344 ErrorResult& aRv) {
4345 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4346
4347 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer,
4348 &transferArray);
4349 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4349)
) {
4350 return;
4351 }
4352
4353 PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aSubjectPrincipal,
4354 aRv);
4355}
4356
4357void nsGlobalWindowInner::PostMessageMoz(
4358 JSContext* aCx, JS::Handle<JS::Value> aMessage,
4359 const WindowPostMessageOptions& aOptions, nsIPrincipal& aSubjectPrincipal,
4360 ErrorResult& aRv) {
4361 JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
4362
4363 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(
4364 aCx, aOptions.mTransfer, &transferArray);
4365 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4365)
) {
4366 return;
4367 }
4368
4369 PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, transferArray,
4370 aSubjectPrincipal, aRv);
4371}
4372
4373void nsGlobalWindowInner::Close(CallerType aCallerType, ErrorResult& aError) {
4374 FORWARD_TO_OUTER_OR_THROW(CloseOuter, (aCallerType == CallerType::System),
4375 aError, );
4376}
4377
4378nsresult nsGlobalWindowInner::Close() {
4379 FORWARD_TO_OUTER(Close, (), NS_ERROR_UNEXPECTED);
4380}
4381
4382bool nsGlobalWindowInner::IsInModalState() {
4383 FORWARD_TO_OUTER(IsInModalState, (), false);
4384}
4385
4386void nsGlobalWindowInner::NotifyWindowIDDestroyed(const char* aTopic) {
4387 RefPtr runnable = MakeRefPtr<WindowDestroyedEvent>(this, mWindowID, aTopic);
4388 Dispatch(runnable.forget());
4389}
4390
4391Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
4392 ErrorResult& aError) {
4393 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (aSubjectPrincipal), aError,
4394 nullptr);
4395}
4396
4397Element* nsGlobalWindowInner::GetRealFrameElement(ErrorResult& aError) {
4398 FORWARD_TO_OUTER_OR_THROW(GetFrameElement, (), aError, nullptr);
4399}
4400
4401void nsGlobalWindowInner::UpdateCommands(const nsAString& anAction) {
4402 if (GetOuterWindowInternal()) {
4403 GetOuterWindowInternal()->UpdateCommands(anAction);
4404 }
4405}
4406
4407Selection* nsGlobalWindowInner::GetSelection(ErrorResult& aError) {
4408 FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr);
4409}
4410
4411WebTaskScheduler* nsGlobalWindowInner::Scheduler() {
4412 if (!mWebTaskScheduler) {
4413 mWebTaskScheduler = WebTaskScheduler::CreateForMainThread(this);
4414 }
4415 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", 4415
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWebTaskScheduler"
")"); do { MOZ_CrashSequence(__null, 4415); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4416 return mWebTaskScheduler;
4417}
4418
4419bool nsGlobalWindowInner::Find(const nsAString& aString, bool aCaseSensitive,
4420 bool aBackwards, bool aWrapAround,
4421 bool aWholeWord, bool aSearchInFrames,
4422 bool aShowDialog, ErrorResult& aError) {
4423 FORWARD_TO_OUTER_OR_THROW(FindOuter,
4424 (aString, aCaseSensitive, aBackwards, aWrapAround,
4425 aWholeWord, aSearchInFrames, aShowDialog, aError),
4426 aError, false);
4427}
4428
4429void nsGlobalWindowInner::GetOrigin(nsAString& aOrigin) {
4430 nsContentUtils::GetWebExposedOriginSerialization(GetPrincipal(), aOrigin);
4431}
4432
4433// See also AutoJSAPI::ReportException
4434void nsGlobalWindowInner::ReportError(JSContext* aCx,
4435 JS::Handle<JS::Value> aError,
4436 CallerType aCallerType,
4437 ErrorResult& aRv) {
4438 if (MOZ_UNLIKELY(!HasActiveDocument())(__builtin_expect(!!(!HasActiveDocument()), 0))) {
4439 return aRv.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
4440 }
4441
4442 JS::ErrorReportBuilder jsReport(aCx);
4443 JS::ExceptionStack exnStack(aCx, aError, nullptr);
4444 if (!jsReport.init(aCx, exnStack, JS::ErrorReportBuilder::NoSideEffects)) {
4445 return aRv.NoteJSContextException(aCx);
4446 }
4447
4448 RefPtr xpcReport = MakeRefPtr<xpc::ErrorReport>();
4449 bool isChrome = aCallerType == CallerType::System;
4450 xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
4451 isChrome, WindowID());
4452
4453 JS::RootingContext* rcx = JS::RootingContext::get(aCx);
4454 DispatchScriptErrorEvent(this, rcx, xpcReport, exnStack.exception(),
4455 exnStack.stack());
4456}
4457
4458void nsGlobalWindowInner::Atob(const nsAString& aAsciiBase64String,
4459 nsAString& aBinaryData, ErrorResult& aError) {
4460 aError = nsContentUtils::Atob(aAsciiBase64String, aBinaryData);
4461}
4462
4463void nsGlobalWindowInner::Btoa(const nsAString& aBinaryData,
4464 nsAString& aAsciiBase64String,
4465 ErrorResult& aError) {
4466 aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
4467}
4468
4469//*****************************************************************************
4470// EventTarget
4471//*****************************************************************************
4472
4473bool nsGlobalWindowInner::DispatchEvent(Event& aEvent, CallerType aCallerType,
4474 ErrorResult& aRv) {
4475 if (!IsCurrentInnerWindow()) {
4476 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"
, 4478)
4477 "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"
, 4478)
4478 "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"
, 4478)
;
4479 aRv.Throw(NS_ERROR_FAILURE);
4480 return false;
4481 }
4482
4483 if (!mDoc) {
4484 aRv.Throw(NS_ERROR_FAILURE);
4485 return false;
4486 }
4487
4488 // Obtain a presentation shell
4489 RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
4490
4491 nsEventStatus status = nsEventStatus_eIgnore;
4492 nsresult rv = EventDispatcher::DispatchDOMEvent(this, nullptr, &aEvent,
4493 presContext, &status);
4494 bool retval = !aEvent.DefaultPrevented(aCallerType);
4495 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4496 aRv.Throw(rv);
4497 }
4498 return retval;
4499}
4500
4501mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
4502nsGlobalWindowInner::GetDebuggerNotificationType() const {
4503 return mozilla::Some(
4504 mozilla::dom::EventCallbackDebuggerNotificationType::Global);
4505}
4506
4507bool nsGlobalWindowInner::ComputeDefaultWantsUntrusted(ErrorResult& aRv) {
4508 return !nsContentUtils::IsChromeDoc(mDoc);
4509}
4510
4511EventListenerManager* nsGlobalWindowInner::GetOrCreateListenerManager() {
4512 if (!mListenerManager) {
4513 mListenerManager =
4514 MakeRefPtr<EventListenerManager>(static_cast<EventTarget*>(this));
4515 }
4516
4517 return mListenerManager;
4518}
4519
4520EventListenerManager* nsGlobalWindowInner::GetExistingListenerManager() const {
4521 return mListenerManager;
4522}
4523
4524mozilla::dom::DebuggerNotificationManager*
4525nsGlobalWindowInner::GetOrCreateDebuggerNotificationManager() {
4526 if (!mDebuggerNotificationManager) {
4527 mDebuggerNotificationManager =
4528 MakeRefPtr<DebuggerNotificationManager>(this);
4529 }
4530
4531 return mDebuggerNotificationManager;
4532}
4533
4534mozilla::dom::DebuggerNotificationManager*
4535nsGlobalWindowInner::GetExistingDebuggerNotificationManager() {
4536 return mDebuggerNotificationManager;
4537}
4538
4539//*****************************************************************************
4540// nsGlobalWindowInner::nsPIDOMWindow
4541//*****************************************************************************
4542
4543Location* nsGlobalWindowInner::Location() {
4544 if (!mLocation) {
4545 mLocation = MakeRefPtr<dom::Location>(this);
4546 }
4547
4548 return mLocation;
4549}
4550
4551void nsGlobalWindowInner::MaybeUpdateTouchState() {
4552 if (mMayHaveTouchEventListener) {
4553 nsCOMPtr<nsIObserverService> observerService =
4554 services::GetObserverService();
4555
4556 if (observerService) {
4557 observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
4558 DOM_TOUCH_LISTENER_ADDED"dom-touch-listener-added", nullptr);
4559 }
4560 }
4561}
4562
4563void nsGlobalWindowInner::EnableGamepadUpdates() {
4564 if (mHasGamepad) {
4565 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4566 if (gamepadManager) {
4567 gamepadManager->AddListener(this);
4568 }
4569 }
4570}
4571
4572void nsGlobalWindowInner::DisableGamepadUpdates() {
4573 if (mHasGamepad) {
4574 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
4575 if (gamepadManager) {
4576 gamepadManager->RemoveListener(this);
4577 }
4578 }
4579}
4580
4581void nsGlobalWindowInner::EnableVRUpdates() {
4582 // We need to create a VREventObserver before we can either detect XR runtimes
4583 // or start an XR session
4584 if (!mVREventObserver && (mHasXRSession || mXRRuntimeDetectionInFlight)) {
4585 // Assert that we are not creating the observer while IsDying() as
4586 // that would result in a leak. VREventObserver holds a RefPtr to
4587 // this nsGlobalWindowInner and would prevent it from being deallocated.
4588 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"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4590); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4589 "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"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4590); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
4590 "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"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()"
") (" "Creating a VREventObserver for an nsGlobalWindow that is "
"dying would cause it to leak." ")"); do { MOZ_CrashSequence
(__null, 4590); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4591 mVREventObserver = MakeRefPtr<VREventObserver>(this);
4592 }
4593 // If the content has an XR session, then we need to tell
4594 // VREventObserver that there is VR activity.
4595 if (mHasXRSession) {
4596 nsPIDOMWindowOuter* outer = GetOuterWindow();
4597 if (outer && !outer->IsBackground()) {
4598 StartVRActivity();
4599 }
4600 }
4601}
4602
4603void nsGlobalWindowInner::DisableVRUpdates() {
4604 if (mVREventObserver) {
4605 mVREventObserver->DisconnectFromOwner();
4606 mVREventObserver = nullptr;
4607 }
4608}
4609
4610void nsGlobalWindowInner::StartVRActivity() {
4611 /**
4612 * If the content has an XR session, tell
4613 * the VREventObserver that the window is accessing
4614 * VR devices.
4615 *
4616 * It's possible to have a VREventObserver without
4617 * and XR session, if we are using it to get updates
4618 * about XR runtime enumeration. In this case,
4619 * we would not tell the VREventObserver that
4620 * we are accessing VR devices.
4621 */
4622 if (mVREventObserver && mHasXRSession) {
4623 mVREventObserver->StartActivity();
4624 }
4625}
4626
4627void nsGlobalWindowInner::StopVRActivity() {
4628 /**
4629 * If the content has an XR session, tell
4630 * the VReventObserver that the window is no longer
4631 * accessing VR devices. This does not stop the
4632 * XR session itself, which may be resumed with
4633 * EnableVRUpdates.
4634 * It's possible to have a VREventObserver without
4635 * and XR session, if we are using it to get updates
4636 * about XR runtime enumeration. In this case,
4637 * we would not tell the VREventObserver that
4638 * we ending an activity that accesses VR devices.
4639 */
4640 if (mVREventObserver && mHasXRSession) {
4641 mVREventObserver->StopActivity();
4642 }
4643}
4644
4645void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
4646 uint32_t aFocusMethod,
4647 bool aNeedsFocus) {
4648 if (aElement && aElement->GetComposedDoc() != mDoc) {
4649 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"
, 4649)
;
4650 return;
4651 }
4652
4653 if (IsDying()) {
4654 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"
, 4654); MOZ_PretendNoReturn(); } } while (0)
;
4655 aElement = nullptr;
4656 aNeedsFocus = false;
4657 }
4658 if (mFocusedElement != aElement) {
4659 mFocusedElement = aElement;
4660 // TODO: Maybe this should be set on refocus too?
4661 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4662 }
4663
4664 if (mFocusedElement) {
4665 // if a node was focused by a keypress, turn on focus rings for the
4666 // window.
4667 if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
4668 mUnknownFocusMethodShouldShowOutline = true;
4669 mFocusByKeyOccurred = true;
4670 } else if (nsFocusManager::GetFocusMoveActionCause(mFocusMethod) !=
4671 widget::InputContextAction::CAUSE_UNKNOWN) {
4672 mUnknownFocusMethodShouldShowOutline = false;
4673 } else if (aFocusMethod & nsIFocusManager::FLAG_NOSHOWRING) {
4674 // If we get focused via script, and script has explicitly opted out of
4675 // outlines via FLAG_NOSHOWRING, we don't want to make a refocus start
4676 // showing outlines.
4677 mUnknownFocusMethodShouldShowOutline = false;
4678 }
4679 }
4680
4681 if (aNeedsFocus) {
4682 mNeedsFocus = aNeedsFocus;
4683 }
4684}
4685
4686uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
4687
4688bool nsGlobalWindowInner::ShouldShowFocusRing() {
4689 if (mFocusByKeyOccurred &&
4690 StaticPrefs::browser_display_always_show_rings_after_key_focus()) {
4691 return true;
4692 }
4693 return StaticPrefs::browser_display_show_focus_rings();
4694}
4695
4696bool nsGlobalWindowInner::TakeFocus(bool aFocus, uint32_t aFocusMethod) {
4697 if (IsDying()) {
4698 return false;
4699 }
4700
4701 if (aFocus) {
4702 mFocusMethod = aFocusMethod & nsIFocusManager::METHOD_MASK;
4703 }
4704
4705 // if mNeedsFocus is true, then the document has not yet received a
4706 // document-level focus event. If there is a root content node, then return
4707 // true to tell the calling focus manager that a focus event is expected. If
4708 // there is no root content node, the document hasn't loaded enough yet, or
4709 // there isn't one and there is no point in firing a focus event.
4710 if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement()) {
4711 mNeedsFocus = false;
4712 return true;
4713 }
4714
4715 mNeedsFocus = false;
4716 return false;
4717}
4718
4719void nsGlobalWindowInner::SetReadyForFocus() {
4720 bool oldNeedsFocus = mNeedsFocus;
4721 mNeedsFocus = false;
4722
4723 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4724 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4725 fm->WindowShown(outerWindow, oldNeedsFocus);
4726 }
4727}
4728
4729void nsGlobalWindowInner::PageHidden(bool aIsEnteringBFCacheInParent) {
4730 // the window is being hidden, so tell the focus manager that the frame is
4731 // no longer valid. Use the persisted field to determine if the document
4732 // is being destroyed.
4733
4734 if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
4735 nsCOMPtr<nsPIDOMWindowOuter> outerWindow = GetOuterWindow();
4736 fm->WindowHidden(outerWindow, nsFocusManager::GenerateFocusActionId(),
4737 aIsEnteringBFCacheInParent);
4738 }
4739
4740 mNeedsFocus = true;
4741}
4742
4743class HashchangeCallback : public Runnable {
4744 public:
4745 HashchangeCallback(const nsAString& aOldURL, const nsAString& aNewURL,
4746 nsGlobalWindowInner* aWindow)
4747 : mozilla::Runnable("HashchangeCallback"), mWindow(aWindow) {
4748 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"
, 4748); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindow" ")"
); do { MOZ_CrashSequence(__null, 4748); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4749 mOldURL.Assign(aOldURL);
4750 mNewURL.Assign(aNewURL);
4751 }
4752
4753 NS_IMETHODvirtual nsresult Run() override {
4754 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"
, 4754); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread." ")"); do { MOZ_CrashSequence
(__null, 4754); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4755 return mWindow->FireHashchange(mOldURL, mNewURL);
4756 }
4757
4758 private:
4759 nsString mOldURL;
4760 nsString mNewURL;
4761 RefPtr<nsGlobalWindowInner> mWindow;
4762};
4763
4764nsresult nsGlobalWindowInner::DispatchAsyncHashchange(nsIURI* aOldURI,
4765 nsIURI* aNewURI) {
4766 // Make sure that aOldURI and aNewURI are identical up to the '#', and that
4767 // their hashes are different.
4768 bool equal = false;
4769 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"
, 4770); return NS_ERROR_UNEXPECTED; } } while (false)
4770 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"
, 4770); return NS_ERROR_UNEXPECTED; } } while (false)
;
4771 nsAutoCString oldHash, newHash;
4772 bool oldHasHash, newHasHash;
4773 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"
, 4777); return NS_ERROR_UNEXPECTED; } } while (false)
4774 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"
, 4777); return NS_ERROR_UNEXPECTED; } } while (false)
4775 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"
, 4777); return NS_ERROR_UNEXPECTED; } } while (false)
4776 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"
, 4777); return NS_ERROR_UNEXPECTED; } } while (false)
4777 (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"
, 4777); return NS_ERROR_UNEXPECTED; } } while (false)
;
4778
4779 nsAutoCString oldSpec, newSpec;
4780 nsresult rv = aOldURI->GetSpec(oldSpec);
4781 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"
, 4781); return rv; } } while (false)
;
4782 rv = aNewURI->GetSpec(newSpec);
4783 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"
, 4783); return rv; } } while (false)
;
4784
4785 NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec);
4786 NS_ConvertUTF8toUTF16 newWideSpec(newSpec);
4787
4788 RefPtr callback =
4789 MakeRefPtr<HashchangeCallback>(oldWideSpec, newWideSpec, this);
4790 return Dispatch(callback.forget());
4791}
4792
4793nsresult nsGlobalWindowInner::FireHashchange(const nsAString& aOldURL,
4794 const nsAString& aNewURL) {
4795 // Don't do anything if the window is frozen.
4796 if (IsFrozen()) {
4797 return NS_OK;
4798 }
4799
4800 // Get a presentation shell for use in creating the hashchange event.
4801 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"
, 4801); return NS_ERROR_UNEXPECTED; } } while (false)
;
4802
4803 HashChangeEventInit init;
4804 init.mNewURL = aNewURL;
4805 init.mOldURL = aOldURL;
4806
4807 RefPtr<HashChangeEvent> event =
4808 HashChangeEvent::Constructor(this, u"hashchange"_ns, init);
4809
4810 event->SetTrusted(true);
4811
4812 ErrorResult rv;
4813 DispatchEvent(*event, rv);
4814 return rv.StealNSResult();
4815}
4816
4817nsresult nsGlobalWindowInner::DispatchSyncPopState() {
4818 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", 4819
); MOZ_PretendNoReturn(); } } while (0)
4819 "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", 4819
); MOZ_PretendNoReturn(); } } while (0)
;
4820
4821 // Bail if the window is frozen.
4822 if (IsFrozen()) {
4823 return NS_OK;
4824 }
4825
4826 AutoJSAPI jsapi;
4827 bool result = jsapi.Init(this);
4828 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", 4828
); return NS_ERROR_FAILURE; } } while (false)
;
4829
4830 JSContext* cx = jsapi.cx();
4831
4832 // Get the document's pending state object -- it contains the data we're
4833 // going to send along with the popstate event. The object is serialized
4834 // using structured clone.
4835 JS::Rooted<JS::Value> stateJSValue(cx);
4836 nsresult rv = mDoc->GetStateObject(&stateJSValue);
4837 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"
, 4837); return rv; } } while (false)
;
4838
4839 if (!JS_WrapValue(cx, &stateJSValue)) {
4840 return NS_ERROR_OUT_OF_MEMORY;
4841 }
4842
4843 RootedDictionary<PopStateEventInit> init(cx);
4844 init.mState = stateJSValue;
4845
4846 RefPtr<PopStateEvent> event =
4847 PopStateEvent::Constructor(this, u"popstate"_ns, init);
4848 event->SetTrusted(true);
4849 event->SetTarget(this);
4850
4851 ErrorResult err;
4852 DispatchEvent(*event, err);
4853 return err.StealNSResult();
4854}
4855
4856already_AddRefed<nsDOMCSSDeclaration> nsGlobalWindowInner::GetComputedStyle(
4857 Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) {
4858 return GetComputedStyleHelper(aElt, aPseudoElt, false, aError);
4859}
4860
4861already_AddRefed<nsDOMCSSDeclaration>
4862nsGlobalWindowInner::GetDefaultComputedStyle(Element& aElt,
4863 const nsAString& aPseudoElt,
4864 ErrorResult& aError) {
4865 return GetComputedStyleHelper(aElt, aPseudoElt, true, aError);
4866}
4867
4868already_AddRefed<nsDOMCSSDeclaration>
4869nsGlobalWindowInner::GetComputedStyleHelper(Element& aElt,
4870 const nsAString& aPseudoElt,
4871 bool aDefaultStylesOnly,
4872 ErrorResult& aError) {
4873 FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter,
4874 (aElt, aPseudoElt, aDefaultStylesOnly, aError),
4875 aError, nullptr);
4876}
4877
4878Storage* nsGlobalWindowInner::GetSessionStorage(ErrorResult& aError) {
4879 nsIPrincipal* principal = GetPrincipal();
4880 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
4881 BrowsingContext* browsingContext = GetBrowsingContext();
4882
4883 if (!principal || !storagePrincipal || !browsingContext ||
4884 !Storage::StoragePrefIsEnabled()) {
4885 return nullptr;
4886 }
4887
4888 if (mSessionStorage) {
4889 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)
4890 ("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)
4891 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)
;
4892 bool canAccess =
4893 principal->Subsumes(mSessionStorage->Principal()) &&
4894 storagePrincipal->Subsumes(mSessionStorage->StoragePrincipal());
4895 if (!canAccess) {
4896 mSessionStorage = nullptr;
4897 }
4898 }
4899
4900 if (!mSessionStorage) {
4901 nsString documentURI;
4902 if (mDoc) {
4903 aError = mDoc->GetDocumentURI(documentURI);
4904 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 4904)
) {
4905 return nullptr;
4906 }
4907 }
4908
4909 if (!mDoc) {
4910 aError.Throw(NS_ERROR_FAILURE);
4911 return nullptr;
4912 }
4913
4914 // If the document's sandboxed origin flag is set, then accessing
4915 // sessionStorage is prohibited.
4916 if (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
4917 aError.ThrowSecurityError(
4918 "Forbidden in a sandboxed document without the 'allow-same-origin' "
4919 "flag.");
4920 return nullptr;
4921 }
4922
4923 uint32_t rejectedReason = 0;
4924 StorageAccess access = StorageAllowedForWindow(this, &rejectedReason);
4925
4926 // SessionStorage is an ephemeral per-tab per-origin storage that only lives
4927 // as long as the tab is open, although it may survive browser restarts
4928 // thanks to the session store. So we interpret storage access differently
4929 // than we would for persistent per-origin storage like LocalStorage and so
4930 // it may be okay to provide SessionStorage even when we receive a value of
4931 // eDeny.
4932 //
4933 // ContentBlocking::ShouldAllowAccessFor will return false for 3 main
4934 // reasons.
4935 //
4936 // 1. Cookies are entirely blocked due to a per-origin permission
4937 // (nsICookiePermission::ACCESS_DENY for the top-level principal or this
4938 // window's principal) or the very broad BEHAVIOR_REJECT. This will return
4939 // eDeny with a reason of STATE_COOKIES_BLOCKED_BY_PERMISSION or
4940 // STATE_COOKIES_BLOCKED_ALL.
4941 //
4942 // 2. Third-party cookies are limited via BEHAVIOR_REJECT_FOREIGN and
4943 // BEHAVIOR_LIMIT_FOREIGN and this is a third-party window. This will return
4944 // eDeny with a reason of STATE_COOKIES_BLOCKED_FOREIGN.
4945 //
4946 // 3. Tracking protection (BEHAVIOR_REJECT_TRACKER and
4947 // BEHAVIOR_PARTITION_FOREIGN) is in effect and
4948 // IsThirdPartyTrackingResourceWindow() returned true and there wasn't a
4949 // permission that allows it. This will return ePartitionTrackersOrDeny with
4950 // a reason of STATE_COOKIES_BLOCKED_TRACKER or
4951 // STATE_COOKIES_BLOCKED_SOCIALTRACKER.
4952 // TODO(Bug 2039931): case 3 is out of date.
4953 //
4954 // In the 1st case, the user has explicitly indicated that they don't want
4955 // to allow any storage to the origin or all origins and so we throw an
4956 // error and deny access to SessionStorage. In the 2nd case, a legacy
4957 // decision reasoned that there's no harm in providing SessionStorage
4958 // because the information is not durable and cannot escape the current tab.
4959 // The rationale is similar for the 3rd case.
4960 if (access == StorageAccess::eDeny &&
4961 rejectedReason !=
4962 nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
4963 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
4964 return nullptr;
4965 }
4966
4967 const RefPtr<SessionStorageManager> storageManager =
4968 browsingContext->GetSessionStorageManager();
4969 if (!storageManager) {
4970 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4971 return nullptr;
4972 }
4973
4974 RefPtr<Storage> storage;
4975 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
4976 documentURI, IsPrivateBrowsing(),
4977 getter_AddRefs(storage));
4978 if (aError.Failed()) {
4979 return nullptr;
4980 }
4981
4982 mSessionStorage = storage;
4983 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", 4983
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSessionStorage" ")"
); do { MOZ_CrashSequence(__null, 4983); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4984
4985 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)
4986 ("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)
4987 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)
;
4988
4989 if (!mSessionStorage) {
4990 aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
4991 return nullptr;
4992 }
4993 }
4994
4995 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)
4996 ("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)
4997 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)
;
4998
4999 return mSessionStorage;
5000}
5001
5002Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
5003 if (!Storage::StoragePrefIsEnabled()) {
5004 return nullptr;
5005 }
5006
5007 // If the document's sandboxed origin flag is set, then accessing localStorage
5008 // is prohibited.
5009 if (mDoc && mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
5010 aError.ThrowSecurityError(
5011 "Forbidden in a sandboxed document without the 'allow-same-origin' "
5012 "flag.");
5013 return nullptr;
5014 }
5015
5016 // LocalStorage needs to be exposed in every context except for sandboxes and
5017 // NullPrincipals (data: URLs, for instance). But we need to keep data
5018 // separate in some scenarios: private-browsing and partitioned trackers.
5019 // In private-browsing, LocalStorage keeps data in memory, and it shares
5020 // StorageEvents just with other origins in the same private-browsing
5021 // environment.
5022 // For Partitioned Trackers, we expose a partitioned LocalStorage, which
5023 // doesn't share data with other contexts, and it's just in memory.
5024 // Partitioned localStorage is available only for trackers listed in the
5025 // privacy.restrict3rdpartystorage.partitionedHosts pref. See
5026 // nsContentUtils::IsURIInPrefList to know the syntax for the pref value.
5027 // This is a temporary web-compatibility hack.
5028
5029 StorageAccess access = StorageAllowedForWindow(this);
5030
5031 // We allow partitioned localStorage only to some hosts.
5032 bool isolated = false;
5033 if (ShouldPartitionStorage(access)) {
5034 if (!mDoc) {
5035 access = StorageAccess::eDeny;
5036 } else if (!StoragePartitioningEnabled(access, mDoc->CookieJarSettings())) {
5037 static const char* kPrefName =
5038 "privacy.restrict3rdpartystorage.partitionedHosts";
5039
5040 bool isInList = false;
5041 mDoc->NodePrincipal()->IsURIInPrefList(kPrefName, &isInList);
5042 if (!isInList) {
5043 access = StorageAccess::eDeny;
5044 } else {
5045 isolated = true;
5046 }
5047 }
5048 }
5049
5050 if (access == StorageAccess::eDeny) {
5051 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5052 return nullptr;
5053 }
5054
5055 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
5056 if (mDoc) {
5057 cookieJarSettings = mDoc->CookieJarSettings();
5058 } else {
5059 cookieJarSettings = net::CookieJarSettings::GetBlockingAll(
5060 ShouldResistFingerprinting(RFPTarget::IsAlwaysEnabledForPrecompute));
5061 }
5062
5063 // Note that this behavior is observable: if we grant storage permission to a
5064 // tracker, we pass from the partitioned LocalStorage (or a partitioned cookie
5065 // jar) to the 'normal' one. The previous data is lost and the 2
5066 // window.localStorage objects, before and after the permission granted, will
5067 // be different.
5068 if (mLocalStorage) {
5069 if ((mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage
5070 : Storage::eLocalStorage)) &&
5071 (mLocalStorage->StoragePrincipal() == GetEffectiveStoragePrincipal())) {
5072 return mLocalStorage;
5073 }
5074
5075 // storage needs change
5076 mLocalStorage = nullptr;
5077 }
5078
5079 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", 5079
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5079); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5080
5081 if (!isolated) {
5082 RefPtr<Storage> storage;
5083
5084 if (NextGenLocalStorageEnabled()) {
5085 aError = LSObject::CreateForWindow(this, getter_AddRefs(storage));
5086 } else {
5087 nsresult rv;
5088 nsCOMPtr<nsIDOMStorageManager> storageManager =
5089 do_GetService("@mozilla.org/dom/localStorage-manager;1", &rv);
5090 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5091 aError.Throw(rv);
5092 return nullptr;
5093 }
5094
5095 nsString documentURI;
5096 if (mDoc) {
5097 aError = mDoc->GetDocumentURI(documentURI);
5098 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 5098)
) {
5099 return nullptr;
5100 }
5101 }
5102
5103 nsIPrincipal* principal = GetPrincipal();
5104 if (!principal) {
5105 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5106 return nullptr;
5107 }
5108
5109 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5110 if (!storagePrincipal) {
5111 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5112 return nullptr;
5113 }
5114
5115 aError = storageManager->CreateStorage(this, principal, storagePrincipal,
5116 documentURI, IsPrivateBrowsing(),
5117 getter_AddRefs(storage));
5118 }
5119
5120 if (aError.Failed()) {
5121 return nullptr;
5122 }
5123
5124 mLocalStorage = storage;
5125 } else {
5126 nsresult rv;
5127 nsCOMPtr<nsIDOMSessionStorageManager> storageManager =
5128 do_GetService("@mozilla.org/dom/sessionStorage-manager;1", &rv);
5129 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5130 aError.Throw(rv);
5131 return nullptr;
5132 }
5133
5134 nsIPrincipal* principal = GetPrincipal();
5135 if (!principal) {
5136 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5137 return nullptr;
5138 }
5139
5140 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5141 if (!storagePrincipal) {
5142 aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
5143 return nullptr;
5144 }
5145
5146 RefPtr<SessionStorageCache> cache;
5147 if (isolated) {
5148 cache = MakeRefPtr<SessionStorageCache>();
5149 } else {
5150 // This will clone the session storage if it exists.
5151 rv = storageManager->GetSessionStorageCache(principal, storagePrincipal,
5152 &cache);
5153 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5154 aError.Throw(rv);
5155 return nullptr;
5156 }
5157 }
5158
5159 mLocalStorage = MakeRefPtr<PartitionedLocalStorage>(
5160 this, principal, storagePrincipal, cache);
5161 }
5162
5163 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", 5163
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage" ")"
); do { MOZ_CrashSequence(__null, 5163); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5164 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", 5166
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5165 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", 5166
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5166 (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", 5166
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage->Type() == (isolated ? Storage::ePartitionedLocalStorage : Storage::eLocalStorage)"
")"); do { MOZ_CrashSequence(__null, 5166); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5167 return mLocalStorage;
5168}
5169
5170IDBFactory* nsGlobalWindowInner::GetIndexedDB(JSContext* aCx,
5171 ErrorResult& aError) {
5172 if (!mIndexedDB) {
5173 // This may keep mIndexedDB null without setting an error.
5174 auto res = IDBFactory::CreateForWindow(this);
5175 if (res.isErr()) {
5176 aError = res.unwrapErr();
5177 } else {
5178 mIndexedDB = res.unwrap();
5179 }
5180 }
5181
5182 return mIndexedDB;
5183}
5184
5185//*****************************************************************************
5186// nsGlobalWindowInner::nsIInterfaceRequestor
5187//*****************************************************************************
5188
5189NS_IMETHODIMPnsresult
5190nsGlobalWindowInner::GetInterface(const nsIID& aIID, void** aSink) {
5191 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
5192 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", 5192
); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
5193
5194 nsresult rv = outer->GetInterfaceInternal(aIID, aSink);
5195 if (rv == NS_ERROR_NO_INTERFACE) {
5196 return QueryInterface(aIID, aSink);
5197 }
5198 return rv;
5199}
5200
5201void nsGlobalWindowInner::GetInterface(JSContext* aCx,
5202 JS::Handle<JS::Value> aIID,
5203 JS::MutableHandle<JS::Value> aRetval,
5204 ErrorResult& aError) {
5205 dom::GetInterface(aCx, this, aIID, aRetval, aError);
5206}
5207
5208already_AddRefed<CacheStorage> nsGlobalWindowInner::GetCaches(
5209 ErrorResult& aRv) {
5210 if (!mCacheStorage) {
5211 bool forceTrustedOrigin =
5212 GetBrowsingContext() &&
5213 GetBrowsingContext()->Top()->GetServiceWorkersTestingEnabled();
5214 mCacheStorage = CacheStorage::CreateOnMainThread(
5215 cache::DEFAULT_NAMESPACE, this, GetEffectiveStoragePrincipal(),
5216 forceTrustedOrigin, aRv);
5217 }
5218
5219 RefPtr<CacheStorage> ref = mCacheStorage;
5220 return ref.forget();
5221}
5222
5223void nsGlobalWindowInner::FireOfflineStatusEventIfChanged() {
5224 if (!IsCurrentInnerWindow()) return;
5225
5226 bool isOffline =
5227 NS_IsOffline() ||
5228 (GetBrowsingContext() && GetBrowsingContext()->Top()->GetForceOffline());
5229
5230 // Don't fire an event if the status hasn't changed
5231 if (mWasOffline == isOffline) {
5232 return;
5233 }
5234
5235 if (ShouldResistFingerprinting(RFPTarget::NetworkConnection)) {
5236 // We always report online=true when resistFingerprinting is enabled.
5237 return;
5238 }
5239
5240 mWasOffline = !mWasOffline;
5241
5242 nsAutoString name;
5243 if (mWasOffline) {
5244 name.AssignLiteral("offline");
5245 } else {
5246 name.AssignLiteral("online");
5247 }
5248 nsContentUtils::DispatchTrustedEvent(this, this, name, CanBubble::eNo,
5249 Cancelable::eNo);
5250}
5251
5252nsGlobalWindowInner::SlowScriptResponse
5253nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx,
5254 const nsString& aAddonId,
5255 const double aDuration) {
5256 nsresult rv;
5257
5258 if (Preferences::GetBool("dom.always_stop_slow_scripts")) {
1
Assuming the condition is false
2
Taking false branch
5259 return KillSlowScript;
5260 }
5261
5262 // If it isn't safe to run script, then it isn't safe to bring up the prompt
5263 // (since that spins the event loop). In that (rare) case, we just kill the
5264 // script and report a warning.
5265 if (!nsContentUtils::IsSafeToRunScript()) {
3
Assuming the condition is false
4
Taking false branch
5266 JS::WarnASCII(aCx, "A long running script was terminated");
5267 return KillSlowScript;
5268 }
5269
5270 // If our document is not active, just kill the script: we've been unloaded
5271 if (!HasActiveDocument()) {
5
Assuming the condition is false
6
Taking false branch
5272 return KillSlowScript;
5273 }
5274
5275 // Check if we should offer the option to debug
5276 JS::AutoFilename filename;
5277 uint32_t lineno;
7
'lineno' declared without an initial value
5278 // Computing the line number can be very expensive (see bug 1330231 for
5279 // example), and we don't use the line number anywhere except than in the
5280 // parent process, so we avoid computing it elsewhere. This gives us most of
5281 // the wins we are interested in, since the source of the slowness here is
5282 // minified scripts which is more common in Web content that is loaded in the
5283 // content process.
5284 uint32_t* linenop = XRE_IsParentProcess() ? &lineno : nullptr;
8
Assuming the condition is false
9
'?' condition is false
5285 JS::DescribeScriptedCaller(&filename, aCx, linenop);
5286
5287 // Record the slow script event if we haven't done so already for this inner
5288 // window (which represents a particular page to the user).
5289 if (!mHasHadSlowScript) {
10
Assuming field 'mHasHadSlowScript' is true
11
Taking false branch
5290 glean::dom::slow_script_page_count.Add(1);
5291 }
5292 mHasHadSlowScript = true;
5293
5294 // Override the cursor to something that we're sure the user can see.
5295 SetCursor("auto"_ns, IgnoreErrors());
5296
5297 if (XRE_IsContentProcess() && ProcessHangMonitor::Get()) {
12
Assuming the condition is false
5298 ProcessHangMonitor::SlowScriptAction action;
5299 RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
5300 nsIDocShell* docShell = GetDocShell();
5301 nsCOMPtr<nsIBrowserChild> child =
5302 docShell ? docShell->GetBrowserChild() : nullptr;
5303 action =
5304 monitor->NotifySlowScript(child, filename.get(), aAddonId, aDuration);
5305 if (action == ProcessHangMonitor::Terminate) {
5306 return KillSlowScript;
5307 }
5308
5309 return ContinueSlowScriptAndKeepNotifying;
5310 }
5311
5312 // Reached only on non-e10s - once per slow script dialog.
5313 // On e10s - we probe once at ProcessHangsMonitor.sys.mjs
5314 glean::dom::slow_script_notice_count.Add(1);
5315
5316 // Get the nsIPrompt interface from the docshell
5317 nsCOMPtr<nsIDocShell> ds = GetDocShell();
5318 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"
, 5318); return KillSlowScript; } } while (false)
;
13
Taking false branch
14
Loop condition is false. Exiting loop
5319 nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ds);
5320 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", 5320
); return KillSlowScript; } } while (false)
;
15
Taking false branch
16
Loop condition is false. Exiting loop
5321
5322 bool failed = false;
5323 auto getString = [&](const char* name, PropertiesFile propFile =
5324 PropertiesFile::DOM_PROPERTIES) {
5325 nsAutoString result;
5326 nsresult rv = nsContentUtils::GetLocalizedString(propFile, name, result);
5327
5328 // GetStringFromName can return NS_OK and still give nullptr string
5329 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || result.IsEmpty();
5330 return result;
5331 };
5332
5333 bool isAddonScript = !aAddonId.IsEmpty();
17
Assuming the condition is false
5334
5335 // Get localizable strings
5336
5337 nsAutoString title, checkboxMsg, msg;
5338 if (isAddonScript
17.1
'isAddonScript' is false
) {
18
Taking false branch
5339 title = getString("KillAddonScriptTitle");
5340 checkboxMsg = getString("KillAddonScriptGlobalMessage");
5341
5342 auto appName =
5343 getString("brandShortName", PropertiesFile::BRAND_PROPERTIES);
5344
5345 nsCOMPtr<nsIAddonPolicyService> aps =
5346 do_GetService("@mozilla.org/addons/policy-service;1");
5347 nsString addonName;
5348 if (!aps || NS_FAILED(aps->GetExtensionName(aAddonId, addonName))((bool)(__builtin_expect(!!(NS_FAILED_impl(aps->GetExtensionName
(aAddonId, addonName))), 0)))
) {
5349 addonName = aAddonId;
5350 }
5351
5352 rv = nsContentUtils::FormatLocalizedString(
5353 msg, PropertiesFile::DOM_PROPERTIES, "KillAddonScriptMessage",
5354 addonName, appName);
5355
5356 failed = failed || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5357 } else {
5358 title = getString("KillScriptTitle");
5359 checkboxMsg = getString("DontAskAgain");
5360 msg = getString("KillScriptMessage");
5361 }
5362
5363 auto stopButton = getString("StopScriptButton");
5364 auto waitButton = getString("WaitForScriptButton");
5365
5366 if (failed) {
19
Assuming 'failed' is false
20
Taking false branch
5367 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"
, 5367); MOZ_PretendNoReturn(); } while (0)
;
5368 return ContinueSlowScript;
5369 }
5370
5371 // Append file and line number information, if available
5372 if (filename.get()) {
21
Assuming the condition is true
22
Taking true branch
5373 nsAutoString scriptLocation;
5374 // We want to drop the middle part of too-long locations. We'll
5375 // define "too-long" as longer than 60 UTF-16 code units. Just
5376 // have to be a bit careful about unpaired surrogates.
5377 NS_ConvertUTF8toUTF16 filenameUTF16(filename.get());
5378 if (filenameUTF16.Length() > 60) {
23
Assuming the condition is false
24
Taking false branch
5379 // XXXbz Do we need to insert any bidi overrides here?
5380 size_t cutStart = 30;
5381 size_t cutLength = filenameUTF16.Length() - 60;
5382 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", 5382
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cutLength > 0"
")"); do { MOZ_CrashSequence(__null, 5382); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5383 if (IsLowSurrogate(filenameUTF16[cutStart])) {
5384 // Don't truncate before the low surrogate, in case it's preceded by a
5385 // high surrogate and forms a single Unicode character. Instead, just
5386 // include the low surrogate.
5387 ++cutStart;
5388 --cutLength;
5389 }
5390 if (IsLowSurrogate(filenameUTF16[cutStart + cutLength])) {
5391 // Likewise, don't drop a trailing low surrogate here. We want to
5392 // increase cutLength, since it might be 0 already so we can't very well
5393 // decrease it.
5394 ++cutLength;
5395 }
5396
5397 // Insert U+2026 HORIZONTAL ELLIPSIS
5398 filenameUTF16.ReplaceLiteral(cutStart, cutLength, u"\x2026");
5399 }
5400 rv = nsContentUtils::FormatLocalizedString(
5401 scriptLocation, PropertiesFile::DOM_PROPERTIES, "KillScriptLocation",
5402 filenameUTF16);
5403
5404 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
25
Assuming the condition is true
26
Taking true branch
5405 msg.AppendLiteral("\n\n");
5406 msg.Append(scriptLocation);
5407 msg.Append(':');
5408 msg.AppendInt(lineno);
27
1st function call argument is an uninitialized value
5409 }
5410 }
5411
5412 uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT +
5413 (nsIPrompt::BUTTON_TITLE_IS_STRING *
5414 (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
5415
5416 bool checkboxValue = false;
5417 int32_t buttonPressed = 0; // In case the user exits dialog by clicking X.
5418 {
5419 // Null out the operation callback while we're re-entering JS here.
5420 AutoDisableJSInterruptCallback disabler(aCx);
5421
5422 // Open the dialog.
5423 rv = prompt->ConfirmEx(title.get(), msg.get(), buttonFlags,
5424 waitButton.get(), stopButton.get(), nullptr,
5425 checkboxMsg.get(), &checkboxValue, &buttonPressed);
5426 }
5427
5428 if (buttonPressed == 0) {
5429 if (checkboxValue && !isAddonScript && NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))))
5430 return AlwaysContinueSlowScript;
5431 return ContinueSlowScript;
5432 }
5433
5434 JS_ClearPendingException(aCx);
5435
5436 return KillSlowScript;
5437}
5438
5439nsresult nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic,
5440 const char16_t* aData) {
5441 if (!nsCRT::strcmp(aTopic, "audio-playback")) {
5442 if (ToSupports(GetOuterWindow()) != aSubject) {
5443 return NS_OK;
5444 }
5445 AUTO_PROFILER_MARKER_UNTYPED("audio-playback", DOM, {})AutoProfilerUntypedMarker raiiObject5445( "audio-playback", ::
mozilla::baseprofiler::category::DOM, {})
;
5446
5447 nsGlobalWindowOuter* outer =
5448 nsGlobalWindowOuter::Cast(nsPIDOMWindowOuter::From(GetOuterWindow())
5449 ->GetInProcessScriptableTop());
5450 nsGlobalWindowInner* topInnerWindow =
5451 outer ? nsGlobalWindowInner::Cast(outer->GetCurrentInnerWindow())
5452 : nullptr;
5453
5454 if (topInnerWindow) {
5455 const bool isPlayingAudio{IsPlayingAudio()};
5456 topInnerWindow->AudioPlaybackChanged(isPlayingAudio);
5457 topInnerWindow->CallOnInProcessDescendants(
5458 &nsGlobalWindowInner::AudioPlaybackChanged, isPlayingAudio);
5459 }
5460
5461 return NS_OK;
5462 }
5463
5464 if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC"network:offline-status-changed")) {
5465 if (!IsFrozen()) {
5466 // Fires an offline status event if the offline status has changed
5467 FireOfflineStatusEventIfChanged();
5468 }
5469 return NS_OK;
5470 }
5471
5472 if (!nsCRT::strcmp(aTopic, MEMORY_PRESSURE_OBSERVER_TOPIC"memory-pressure")) {
5473 if (mPerformance) {
5474 mPerformance->MemoryPressure();
5475 }
5476 RemoveReportRecords();
5477 return NS_OK;
5478 }
5479
5480 if (!nsCRT::strcmp(aTopic, PERMISSION_CHANGED_TOPIC"perm-changed") ||
5481 !nsCRT::strcmp(aTopic, "browser-perm-changed")) {
5482 bool isBrowserPerm = !nsCRT::strcmp(aTopic, "browser-perm-changed");
5483
5484 nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject));
5485 if (!perm) {
5486 // Bulk browser permission clear — subject is an nsISupportsPRUint64
5487 // carrying the browserId. Only process if this window belongs to that
5488 // tab.
5489 if (isBrowserPerm) {
5490 nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
5491 if (wrapper) {
5492 uint64_t clearedBrowserId = 0;
5493 wrapper->GetData(&clearedBrowserId);
5494 if (clearedBrowserId) {
5495 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5496 if (!bc || bc->Top()->BrowserId() != clearedBrowserId) {
5497 return NS_OK;
5498 }
5499 }
5500 }
5501 }
5502 UpdatePermissions();
5503 if (mDoc) {
5504 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5505 mDoc->GetPermissionDelegateHandler();
5506 if (permDelegateHandler) {
5507 permDelegateHandler->PopulateAllDelegatedPermissions();
5508 }
5509 }
5510 return NS_OK;
5511 }
5512
5513 if (isBrowserPerm) {
5514 uint64_t permBrowserId = 0;
5515 perm->GetBrowserId(&permBrowserId);
5516 if (!permBrowserId) {
5517 return NS_OK;
5518 }
5519 RefPtr<BrowsingContext> bc = GetBrowsingContext();
5520 if (!bc || bc->Top()->BrowserId() != permBrowserId) {
5521 return NS_OK;
5522 }
5523 }
5524
5525 nsAutoCString type;
5526 perm->GetType(type);
5527 if (type == "autoplay-media"_ns) {
5528 UpdateAutoplayPermission();
5529 } else if (type == "shortcuts"_ns) {
5530 UpdateShortcutsPermission();
5531 } else if (type == "popup"_ns) {
5532 UpdatePopupPermission();
5533 }
5534
5535 if (!mDoc) {
5536 return NS_OK;
5537 }
5538
5539 RefPtr<PermissionDelegateHandler> permDelegateHandler =
5540 mDoc->GetPermissionDelegateHandler();
5541
5542 if (permDelegateHandler) {
5543 permDelegateHandler->UpdateDelegatedPermission(type);
5544 }
5545
5546 return NS_OK;
5547 }
5548
5549 if (!nsCRT::strcmp(aTopic, "screen-information-changed")) {
5550 if (mScreen) {
5551 if (RefPtr<ScreenOrientation> orientation =
5552 mScreen->GetOrientationIfExists()) {
5553 orientation->MaybeChanged();
5554 }
5555 }
5556 if (mHasOrientationChangeListeners) {
5557 int32_t oldAngle = mOrientationAngle;
5558 mOrientationAngle = Orientation(CallerType::System);
5559 if (mOrientationAngle != oldAngle && IsCurrentInnerWindow()) {
5560 nsCOMPtr<nsPIDOMWindowOuter> outer = GetOuterWindow();
5561 outer->DispatchCustomEvent(u"orientationchange"_ns);
5562 }
5563 }
5564 return NS_OK;
5565 }
5566
5567 if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) {
5568 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", 5568
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aData, u\"intl.accept_languages\")"
")"); do { MOZ_CrashSequence(__null, 5568); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5569
5570 // The user preferred languages have changed, we need to fire an event on
5571 // Window object and invalidate the cache for navigator.languages. It is
5572 // done for every change which can be a waste of cycles but those should be
5573 // fairly rare.
5574 // We MUST invalidate navigator.languages before sending the event in the
5575 // very likely situation where an event handler will try to read its value.
5576
5577 if (mNavigator) {
5578 Navigator_Binding::ClearCachedLanguageValue(mNavigator);
5579 Navigator_Binding::ClearCachedLanguagesValue(mNavigator);
5580 }
5581
5582 // The event has to be dispatched only to the current inner window.
5583 if (!IsCurrentInnerWindow()) {
5584 return NS_OK;
5585 }
5586
5587 RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
5588 event->InitEvent(u"languagechange"_ns, false, false);
5589 event->SetTrusted(true);
5590
5591 ErrorResult rv;
5592 DispatchEvent(*event, rv);
5593 return rv.StealNSResult();
5594 }
5595
5596 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"
, 5596)
;
5597 return NS_ERROR_FAILURE;
5598}
5599
5600void nsGlobalWindowInner::ObserveStorageNotification(
5601 StorageEvent* aEvent, const char16_t* aStorageType, bool aPrivateBrowsing) {
5602 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"
, 5602); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEvent" ")"
); do { MOZ_CrashSequence(__null, 5602); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5603
5604 // The private browsing check must be done here again because this window
5605 // could have changed its state before the notification check and now. This
5606 // happens in case this window did have a docShell at that time.
5607 if (aPrivateBrowsing != IsPrivateBrowsing()) {
5608 return;
5609 }
5610
5611 // LocalStorage can only exist on an inner window, and we don't want to
5612 // generate events on frozen or otherwise-navigated-away from windows.
5613 // (Actually, this code used to try and buffer events for frozen windows,
5614 // but it never worked, so we've removed it. See bug 1285898.)
5615 if (!IsCurrentInnerWindow() || IsFrozen()) {
5616 return;
5617 }
5618
5619 nsIPrincipal* principal = GetPrincipal();
5620 if (!principal) {
5621 return;
5622 }
5623
5624 bool fireMozStorageChanged = false;
5625 nsAutoString eventType;
5626 eventType.AssignLiteral("storage");
5627
5628 if (!NS_strcmp(aStorageType, u"sessionStorage")) {
5629 RefPtr<Storage> changingStorage = aEvent->GetStorageArea();
5630 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", 5630
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "changingStorage" ")"
); do { MOZ_CrashSequence(__null, 5630); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5631
5632 bool check = false;
5633
5634 if (const RefPtr<SessionStorageManager> storageManager =
5635 GetBrowsingContext()->GetSessionStorageManager()) {
5636 nsresult rv = storageManager->CheckStorage(GetEffectiveStoragePrincipal(),
5637 changingStorage, &check);
5638 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5639 return;
5640 }
5641 }
5642
5643 if (!check) {
5644 // This storage event is not coming from our storage or is coming
5645 // from a different docshell, i.e. it is a clone, ignore this event.
5646 return;
5647 }
5648
5649 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)
5650 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)
5651 ("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)
5652 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)
;
5653
5654 fireMozStorageChanged = mSessionStorage == changingStorage;
5655 if (fireMozStorageChanged) {
5656 eventType.AssignLiteral("MozSessionStorageChanged");
5657 }
5658 }
5659
5660 else {
5661 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", 5661
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_strcmp(aStorageType, u\"localStorage\")"
")"); do { MOZ_CrashSequence(__null, 5661); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5662
5663 nsIPrincipal* storagePrincipal = GetEffectiveStoragePrincipal();
5664 if (!storagePrincipal) {
5665 return;
5666 }
5667
5668 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", 5669
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5669); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5669 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", 5669
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(), storagePrincipal)"
")"); do { MOZ_CrashSequence(__null, 5669); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5670
5671 fireMozStorageChanged =
5672 mLocalStorage && mLocalStorage == aEvent->GetStorageArea();
5673
5674 if (fireMozStorageChanged) {
5675 eventType.AssignLiteral("MozLocalStorageChanged");
5676 }
5677 }
5678
5679 // Clone the storage event included in the observer notification. We want
5680 // to dispatch clones rather than the original event.
5681 IgnoredErrorResult error;
5682 RefPtr<StorageEvent> clonedEvent =
5683 CloneStorageEvent(eventType, aEvent, error);
5684 if (error.Failed() || !clonedEvent) {
5685 return;
5686 }
5687
5688 clonedEvent->SetTrusted(true);
5689
5690 if (fireMozStorageChanged) {
5691 WidgetEvent* internalEvent = clonedEvent->WidgetEventPtr();
5692 internalEvent->mFlags.mOnlyChromeDispatch = true;
5693 }
5694
5695 DispatchEvent(*clonedEvent);
5696}
5697
5698already_AddRefed<StorageEvent> nsGlobalWindowInner::CloneStorageEvent(
5699 const nsAString& aType, const RefPtr<StorageEvent>& aEvent,
5700 ErrorResult& aRv) {
5701 StorageEventInit dict;
5702
5703 dict.mBubbles = aEvent->Bubbles();
5704 dict.mCancelable = aEvent->Cancelable();
5705 aEvent->GetKey(dict.mKey);
5706 aEvent->GetOldValue(dict.mOldValue);
5707 aEvent->GetNewValue(dict.mNewValue);
5708 aEvent->GetUrl(dict.mUrl);
5709
5710 RefPtr<Storage> storageArea = aEvent->GetStorageArea();
5711
5712 RefPtr<Storage> storage;
5713
5714 // If null, this is a localStorage event received by IPC.
5715 if (!storageArea) {
5716 storage = GetLocalStorage(aRv);
5717 if (!NextGenLocalStorageEnabled()) {
5718 if (aRv.Failed() || !storage) {
5719 return nullptr;
5720 }
5721
5722 if (storage->Type() == Storage::eLocalStorage) {
5723 RefPtr<LocalStorage> localStorage =
5724 static_cast<LocalStorage*>(storage.get());
5725
5726 // We must apply the current change to the 'local' localStorage.
5727 localStorage->ApplyEvent(aEvent);
5728 }
5729 }
5730 } else if (storageArea->Type() == Storage::eSessionStorage) {
5731 storage = GetSessionStorage(aRv);
5732 } else {
5733 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", 5733
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storageArea->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 5733); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5734 storage = GetLocalStorage(aRv);
5735 }
5736
5737 if (aRv.Failed() || !storage) {
5738 return nullptr;
5739 }
5740
5741 if (storage->Type() == Storage::ePartitionedLocalStorage) {
5742 // This error message is not exposed.
5743 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
5744 return nullptr;
5745 }
5746
5747 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"
, 5747); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage" ")"
); do { MOZ_CrashSequence(__null, 5747); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5748 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", 5748
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "storage->IsForkOf(storageArea)"
")"); do { MOZ_CrashSequence(__null, 5748); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5749
5750 dict.mStorageArea = storage;
5751
5752 RefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict);
5753 return event.forget();
5754}
5755
5756void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
5757 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", 5757
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5757); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5758
5759 // We can only safely suspend windows that are the current inner window. If
5760 // its not the current inner, then we are in one of two different cases.
5761 // Either we are in the bfcache or we are doomed window that is going away.
5762 // When a window becomes inactive we purposely avoid placing already suspended
5763 // windows into the bfcache. It only expects windows suspended due to the
5764 // Freeze() method which occurs while the window is still the current inner.
5765 // So we must not call Suspend() on bfcache windows at this point or this
5766 // invariant will be broken. If the window is doomed there is no point in
5767 // suspending it since it will soon be gone.
5768 if (!IsCurrentInnerWindow()) {
5769 return;
5770 }
5771
5772 // All in-process descendants are also suspended. This ensure mSuspendDepth
5773 // is set properly and the timers are properly canceled for each in-process
5774 // descendant.
5775 if (aIncludeSubWindows) {
5776 CallOnInProcessDescendants(&nsGlobalWindowInner::Suspend, false);
5777 }
5778
5779 mSuspendDepth += 1;
5780 if (mSuspendDepth != 1) {
5781 return;
5782 }
5783
5784 if (mWindowGlobalChild) {
5785 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED);
5786 }
5787
5788 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5789 if (ac) {
5790 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5791 ac->RemoveWindowListener(mEnabledSensors[i], this);
5792 }
5793 DisableGamepadUpdates();
5794 DisableVRUpdates();
5795
5796 SuspendWorkersForWindow(*this);
5797
5798 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5799 mSharedWorkers.ForwardRange()) {
5800 pinnedWorker->Suspend();
5801 }
5802
5803 SuspendIdleRequests();
5804
5805 mTimeoutManager->Suspend();
5806
5807 // Suspend all of the AudioContexts for this window
5808 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5809 mAudioContexts[i]->SuspendFromChrome();
5810 }
5811}
5812
5813void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
5814 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", 5814
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5814); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5815
5816 // We can only safely resume a window if its the current inner window. If
5817 // its not the current inner, then we are in one of two different cases.
5818 // Either we are in the bfcache or we are doomed window that is going away.
5819 // If a window is suspended when it becomes inactive we purposely do not
5820 // put it in the bfcache, so Resume should never be needed in that case.
5821 // If the window is doomed then there is no point in resuming it.
5822 if (!IsCurrentInnerWindow()) {
5823 return;
5824 }
5825
5826 // Resume all in-process descendants. This restores timers recursively
5827 // canceled in Suspend() and ensures all in-process descendants have the
5828 // correct mSuspendDepth.
5829 if (aIncludeSubWindows) {
5830 CallOnInProcessDescendants(&nsGlobalWindowInner::Resume, false);
5831 }
5832
5833 if (mSuspendDepth == 0) {
5834 // Ignore if the window is not suspended.
5835 return;
5836 }
5837
5838 mSuspendDepth -= 1;
5839
5840 if (mSuspendDepth != 0) {
5841 return;
5842 }
5843
5844 // We should not be able to resume a frozen window. It must be Thaw()'d
5845 // first.
5846 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", 5846
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth == 0"
")"); do { MOZ_CrashSequence(__null, 5846); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5847
5848 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
5849 if (ac) {
5850 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
5851 ac->AddWindowListener(mEnabledSensors[i], this);
5852 }
5853 EnableGamepadUpdates();
5854 EnableVRUpdates();
5855
5856 // Resume all of the AudioContexts for this window
5857 for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
5858 mAudioContexts[i]->ResumeFromChrome();
5859 }
5860
5861 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
5862 devices->WindowResumed();
5863 }
5864
5865 mTimeoutManager->Resume();
5866
5867 ResumeIdleRequests();
5868
5869 // Resume all of the workers for this window. We must do this
5870 // after timeouts since workers may have queued events that can trigger
5871 // a setTimeout().
5872 ResumeWorkersForWindow(*this);
5873
5874 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5875 mSharedWorkers.ForwardRange()) {
5876 pinnedWorker->Resume();
5877 }
5878
5879 if (mWindowGlobalChild) {
5880 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED);
5881 }
5882}
5883
5884bool nsGlobalWindowInner::IsSuspended() const {
5885 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", 5885
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5885); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5886 return mSuspendDepth != 0;
5887}
5888
5889void nsGlobalWindowInner::Freeze(bool aIncludeSubWindows) {
5890 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", 5890
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5890); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5891 Suspend(aIncludeSubWindows);
5892 FreezeInternal(aIncludeSubWindows);
5893}
5894
5895void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) {
5896 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", 5896
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5896); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5897 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", 5897
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5897); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5898 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", 5898
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5898); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5899
5900 HintIsLoading(false);
5901
5902 if (aIncludeSubWindows) {
5903 CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal,
5904 aIncludeSubWindows);
5905 }
5906
5907 mFreezeDepth += 1;
5908 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"
, 5908); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5908); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5909 if (mFreezeDepth != 1) {
5910 return;
5911 }
5912
5913 FreezeWorkersForWindow(*this);
5914
5915 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5916 mSharedWorkers.ForwardRange()) {
5917 pinnedWorker->Freeze();
5918 }
5919
5920 mTimeoutManager->Freeze();
5921 if (mClientSource) {
5922 mClientSource->Freeze();
5923 }
5924
5925 NotifyGlobalFrozen();
5926}
5927
5928void nsGlobalWindowInner::Thaw(bool aIncludeSubWindows) {
5929 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", 5929
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5929); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5930 ThawInternal(aIncludeSubWindows);
5931 Resume(aIncludeSubWindows);
5932}
5933
5934void nsGlobalWindowInner::ThawInternal(bool aIncludeSubWindows) {
5935 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", 5935
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5935); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5936 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", 5936
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5936); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5937 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", 5937
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "IsSuspended()"
")"); do { MOZ_CrashSequence(__null, 5937); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5938
5939 if (aIncludeSubWindows) {
5940 CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal,
5941 aIncludeSubWindows);
5942 }
5943
5944 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", 5944
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFreezeDepth != 0"
")"); do { MOZ_CrashSequence(__null, 5944); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5945 mFreezeDepth -= 1;
5946 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"
, 5946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSuspendDepth >= mFreezeDepth"
")"); do { MOZ_CrashSequence(__null, 5946); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5947 if (mFreezeDepth != 0) {
5948 return;
5949 }
5950
5951 if (mClientSource) {
5952 mClientSource->Thaw();
5953 }
5954 mTimeoutManager->Thaw();
5955
5956 ThawWorkersForWindow(*this);
5957
5958 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
5959 mSharedWorkers.ForwardRange()) {
5960 pinnedWorker->Thaw();
5961 }
5962
5963 NotifyGlobalThawed();
5964}
5965
5966bool nsGlobalWindowInner::IsFrozen() const {
5967 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", 5967
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 5967); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5968 bool frozen = mFreezeDepth != 0;
5969 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", 5969
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsSuspended()" ")"
); do { MOZ_CrashSequence(__null, 5969); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5970 return frozen;
5971}
5972
5973void nsGlobalWindowInner::SyncStateFromParentWindow() {
5974 // This method should only be called on an inner window that has been
5975 // assigned to an outer window already.
5976 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", 5976
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsCurrentInnerWindow()"
")"); do { MOZ_CrashSequence(__null, 5976); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5977 nsPIDOMWindowOuter* outer = GetOuterWindow();
5978 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"
, 5978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outer" ")")
; do { MOZ_CrashSequence(__null, 5978); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5979
5980 // Attempt to find our parent windows.
5981 nsCOMPtr<Element> frame = outer->GetFrameElementInternal();
5982 nsPIDOMWindowOuter* parentOuter =
5983 frame ? frame->OwnerDoc()->GetWindow() : nullptr;
5984 nsGlobalWindowInner* parentInner =
5985 parentOuter
5986 ? nsGlobalWindowInner::Cast(parentOuter->GetCurrentInnerWindow())
5987 : nullptr;
5988
5989 // If our outer is in a modal state, but our parent is not in a modal
5990 // state, then we must apply the suspend directly. If our parent is
5991 // in a modal state then we should get the suspend automatically
5992 // via the parentSuspendDepth application below.
5993 if ((!parentInner || !parentInner->IsInModalState()) && IsInModalState()) {
5994 Suspend();
5995 }
5996
5997 uint32_t parentFreezeDepth = parentInner ? parentInner->mFreezeDepth : 0;
5998 uint32_t parentSuspendDepth = parentInner ? parentInner->mSuspendDepth : 0;
5999
6000 // Since every Freeze() calls Suspend(), the suspend count must
6001 // be equal or greater to the freeze count.
6002 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", 6002
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "parentFreezeDepth <= parentSuspendDepth"
")"); do { MOZ_CrashSequence(__null, 6002); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6003
6004 // First apply the Freeze() calls.
6005 for (uint32_t i = 0; i < parentFreezeDepth; ++i) {
6006 Freeze();
6007 }
6008
6009 // Now apply only the number of Suspend() calls to reach the target
6010 // suspend count after applying the Freeze() calls.
6011 for (uint32_t i = 0; i < (parentSuspendDepth - parentFreezeDepth); ++i) {
6012 Suspend();
6013 }
6014}
6015
6016void nsGlobalWindowInner::UpdateBackgroundState() {
6017 if (RefPtr<MediaDevices> devices = GetExtantMediaDevices()) {
6018 devices->BackgroundStateChanged();
6019 }
6020 mTimeoutManager->UpdateBackgroundState();
6021
6022 UpdateWorkersBackgroundState(*this, IsBackgroundInternal());
6023}
6024
6025template <typename Method, typename... Args>
6026CallState nsGlobalWindowInner::CallOnInProcessDescendantsInternal(
6027 BrowsingContext* aBrowsingContext, bool aChildOnly, Method aMethod,
6028 Args&&... aArgs) {
6029 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", 6029
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6029); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6030 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", 6030
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 6030); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6031
6032 CallState state = CallState::Continue;
6033 for (const RefPtr<BrowsingContext>& bc : aBrowsingContext->Children()) {
6034 if (nsCOMPtr<nsPIDOMWindowOuter> pWin = bc->GetDOMWindow()) {
6035 auto* win = nsGlobalWindowOuter::Cast(pWin);
6036 if (nsGlobalWindowInner* inner =
6037 nsGlobalWindowInner::Cast(win->GetCurrentInnerWindow())) {
6038 // Call the descendant method using our helper CallDescendant() template
6039 // method. This allows us to handle both void returning methods and
6040 // methods that return CallState explicitly. For void returning methods
6041 // we assume CallState::Continue.
6042 using returnType = decltype((inner->*aMethod)(aArgs...));
6043 state = CallDescendant<returnType>(inner, aMethod, aArgs...);
6044
6045 if (state == CallState::Stop) {
6046 return state;
6047 }
6048 }
6049 }
6050
6051 if (!aChildOnly) {
6052 state = CallOnInProcessDescendantsInternal(bc.get(), aChildOnly, aMethod,
6053 aArgs...);
6054 if (state == CallState::Stop) {
6055 return state;
6056 }
6057 }
6058 }
6059
6060 return state;
6061}
6062
6063nsIURI* nsGlobalWindowInner::GetBaseURI() const { return GetDocBaseURI(); }
6064
6065Maybe<ClientInfo> nsGlobalWindowInner::GetClientInfo() const {
6066 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", 6066
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6066); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6067 if (mDoc && mDoc->IsStaticDocument()) {
6068 if (Maybe<ClientInfo> info = mDoc->GetOriginalDocument()->GetClientInfo()) {
6069 return info;
6070 }
6071 }
6072
6073 Maybe<ClientInfo> clientInfo;
6074 if (mClientSource) {
6075 clientInfo.emplace(mClientSource->Info());
6076 }
6077 return clientInfo;
6078}
6079
6080Maybe<ClientState> nsGlobalWindowInner::GetClientState() const {
6081 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", 6081
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6081); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6082 if (mDoc && mDoc->IsStaticDocument()) {
6083 if (Maybe<ClientState> state =
6084 mDoc->GetOriginalDocument()->GetClientState()) {
6085 return state;
6086 }
6087 }
6088
6089 Maybe<ClientState> clientState;
6090 if (mClientSource) {
6091 Result<ClientState, ErrorResult> res = mClientSource->SnapshotState();
6092 if (res.isOk()) {
6093 clientState.emplace(res.unwrap());
6094 } else {
6095 res.unwrapErr().SuppressException();
6096 }
6097 }
6098 return clientState;
6099}
6100
6101Maybe<ServiceWorkerDescriptor> nsGlobalWindowInner::GetController() const {
6102 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", 6102
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6102); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6103 if (mDoc && mDoc->IsStaticDocument()) {
6104 if (Maybe<ServiceWorkerDescriptor> controller =
6105 mDoc->GetOriginalDocument()->GetController()) {
6106 return controller;
6107 }
6108 }
6109
6110 Maybe<ServiceWorkerDescriptor> controller;
6111 if (mClientSource) {
6112 controller = mClientSource->GetController();
6113 }
6114 return controller;
6115}
6116
6117void nsGlobalWindowInner::SetPolicyContainer(
6118 nsIPolicyContainer* aPolicyContainer) {
6119 if (!mClientSource) {
6120 return;
6121 }
6122 mClientSource->SetPolicyContainer(aPolicyContainer);
6123 // Also cache the PolicyContainer within the document
6124 mDoc->SetPolicyContainer(aPolicyContainer);
6125
6126 if (mWindowGlobalChild) {
6127 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6128 }
6129}
6130
6131nsIPolicyContainer* nsGlobalWindowInner::GetPolicyContainer() {
6132 if (mDoc) {
6133 return mDoc->GetPolicyContainer();
6134 }
6135
6136 // If the window is partially torn down and has its document nulled out,
6137 // we query the policy container we snapshot in FreeInnerObjects.
6138 if (mDocumentPolicyContainer) {
6139 return mDocumentPolicyContainer;
6140 }
6141 return nullptr;
6142}
6143
6144void nsGlobalWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
6145 if (!mClientSource) {
6146 return;
6147 }
6148 mClientSource->SetPreloadCsp(aPreloadCsp);
6149 // Also cache the preload CSP within the document
6150 mDoc->SetPreloadCsp(aPreloadCsp);
6151
6152 if (mWindowGlobalChild) {
6153 mWindowGlobalChild->SendSetClientInfo(mClientSource->Info().ToIPC());
6154 }
6155}
6156
6157already_AddRefed<ServiceWorkerContainer>
6158nsGlobalWindowInner::GetServiceWorkerContainer() {
6159 return Navigator()->ServiceWorker();
6160}
6161
6162RefPtr<ServiceWorker> nsGlobalWindowInner::GetOrCreateServiceWorker(
6163 const ServiceWorkerDescriptor& aDescriptor) {
6164 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", 6164
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6164); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6165 RefPtr<ServiceWorker> ref;
6166 ForEachGlobalTeardownObserver(
6167 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6168 RefPtr<ServiceWorker> sw = do_QueryObject(aObserver);
6169 if (!sw || !sw->Descriptor().Matches(aDescriptor)) {
6170 return;
6171 }
6172
6173 ref = std::move(sw);
6174 *aDoneOut = true;
6175 });
6176
6177 if (!ref) {
6178 ref = ServiceWorker::Create(this, aDescriptor);
6179 }
6180
6181 return ref;
6182}
6183
6184RefPtr<mozilla::dom::ServiceWorkerRegistration>
6185nsGlobalWindowInner::GetServiceWorkerRegistration(
6186 const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor)
6187 const {
6188 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", 6188
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6188); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6189 RefPtr<ServiceWorkerRegistration> ref;
6190 ForEachGlobalTeardownObserver(
6191 [&](GlobalTeardownObserver* aObserver, bool* aDoneOut) {
6192 RefPtr<ServiceWorkerRegistration> swr = do_QueryObject(aObserver);
6193 if (!swr || !swr->MatchesDescriptor(aDescriptor)) {
6194 return;
6195 }
6196
6197 ref = std::move(swr);
6198 *aDoneOut = true;
6199 });
6200 return ref;
6201}
6202
6203RefPtr<ServiceWorkerRegistration>
6204nsGlobalWindowInner::GetOrCreateServiceWorkerRegistration(
6205 const ServiceWorkerRegistrationDescriptor& aDescriptor) {
6206 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", 6206
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6206); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6207 RefPtr<ServiceWorkerRegistration> ref =
6208 GetServiceWorkerRegistration(aDescriptor);
6209 if (!ref) {
6210 ref = ServiceWorkerRegistration::CreateForMainThread(this, aDescriptor);
6211 }
6212 return ref;
6213}
6214
6215StorageAccess nsGlobalWindowInner::GetStorageAccess() {
6216 return StorageAllowedForWindow(this);
6217}
6218
6219nsICookieJarSettings* nsGlobalWindowInner::GetCookieJarSettings() {
6220 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", 6220
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 6220); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6221 if (mDoc) {
6222 return mDoc->CookieJarSettings();
6223 }
6224 return nullptr;
6225}
6226
6227nsresult nsGlobalWindowInner::FireDelayedDOMEvents(bool aIncludeSubWindows) {
6228 // Fires an offline status event if the offline status has changed
6229 FireOfflineStatusEventIfChanged();
6230
6231 if (mCookieStore) {
6232 mCookieStore->FireDelayedDOMEvents();
6233 }
6234
6235 if (!aIncludeSubWindows) {
6236 return NS_OK;
6237 }
6238
6239 nsCOMPtr<nsIDocShell> docShell = GetDocShell();
6240 if (docShell) {
6241 int32_t childCount = 0;
6242 docShell->GetInProcessChildCount(&childCount);
6243
6244 // Take a copy of the current children so that modifications to
6245 // the child list don't affect to the iteration.
6246 AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> children;
6247 for (int32_t i = 0; i < childCount; ++i) {
6248 nsCOMPtr<nsIDocShellTreeItem> childShell;
6249 docShell->GetInProcessChildAt(i, getter_AddRefs(childShell));
6250 if (childShell) {
6251 children.AppendElement(childShell);
6252 }
6253 }
6254
6255 for (const nsCOMPtr<nsIDocShellTreeItem>& childShell : children) {
6256 if (const RefPtr<nsGlobalWindowOuter> win =
6257 nsGlobalWindowOuter::Cast(childShell->GetWindow())) {
6258 win->FireDelayedDOMEvents(true);
6259 }
6260 }
6261 }
6262
6263 return NS_OK;
6264}
6265
6266//*****************************************************************************
6267// nsGlobalWindowInner: Window Control Functions
6268//*****************************************************************************
6269
6270nsPIDOMWindowOuter* nsGlobalWindowInner::GetInProcessParentInternal() {
6271 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6272 if (!outer) {
6273 // No outer window available!
6274 return nullptr;
6275 }
6276 return outer->GetInProcessParentInternal();
6277}
6278
6279nsIPrincipal* nsGlobalWindowInner::GetTopLevelAntiTrackingPrincipal() {
6280 nsPIDOMWindowOuter* outerWindow = GetOuterWindowInternal();
6281 if (!outerWindow) {
6282 return nullptr;
6283 }
6284
6285 nsPIDOMWindowOuter* topLevelOuterWindow =
6286 GetBrowsingContext()->Top()->GetDOMWindow();
6287 if (!topLevelOuterWindow) {
6288 return nullptr;
6289 }
6290
6291 bool stopAtOurLevel =
6292 mDoc && mDoc->CookieJarSettings()->GetCookieBehavior() ==
6293 nsICookieService::BEHAVIOR_REJECT_TRACKER;
6294
6295 if (stopAtOurLevel && topLevelOuterWindow == outerWindow) {
6296 return nullptr;
6297 }
6298
6299 nsPIDOMWindowInner* topLevelInnerWindow =
6300 topLevelOuterWindow->GetCurrentInnerWindow();
6301 if (NS_WARN_IF(!topLevelInnerWindow)NS_warn_if_impl(!topLevelInnerWindow, "!topLevelInnerWindow",
"/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6301
)
) {
6302 return nullptr;
6303 }
6304
6305 nsIPrincipal* topLevelPrincipal =
6306 nsGlobalWindowInner::Cast(topLevelInnerWindow)->GetPrincipal();
6307 if (NS_WARN_IF(!topLevelPrincipal)NS_warn_if_impl(!topLevelPrincipal, "!topLevelPrincipal", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6307)
) {
6308 return nullptr;
6309 }
6310
6311 return topLevelPrincipal;
6312}
6313
6314nsIPrincipal* nsGlobalWindowInner::GetClientPrincipal() {
6315 return mClientSource ? mClientSource->GetPrincipal() : nullptr;
6316}
6317
6318bool nsGlobalWindowInner::IsInFullScreenTransition() {
6319 if (!mIsChrome) {
6320 return false;
6321 }
6322
6323 nsGlobalWindowOuter* outerWindow = GetOuterWindowInternal();
6324 if (!outerWindow) {
6325 return false;
6326 }
6327
6328 return outerWindow->mIsInFullScreenTransition;
6329}
6330
6331//*****************************************************************************
6332// nsGlobalWindowInner: Timeout Functions
6333//*****************************************************************************
6334
6335class WindowScriptTimeoutHandler final : public ScriptTimeoutHandler {
6336 public:
6337 NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override;
6338 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",
6339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6339); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6339 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",
6339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "p == &_cycleCollectorGlobal"
") (" "WindowScriptTimeoutHandler" " should QI to its own CC participant"
")"); do { MOZ_CrashSequence(__null, 6339); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } static cycleCollection
_cycleCollectorGlobal;
6340
6341 WindowScriptTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal,
6342 const nsAString& aExpression)
6343 : ScriptTimeoutHandler(aCx, aGlobal, aExpression),
6344 mInitiatingScriptFetchInfo(
6345 ScriptLoader::GetActiveScriptFetchInfo(aCx)) {}
6346
6347 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* aExecutionReason) override;
6348
6349 private:
6350 virtual ~WindowScriptTimeoutHandler() = default;
6351
6352 // Initiating script's referrer info for use when evaluating mExpr on the main
6353 // thread.
6354 RefPtr<JS::loader::ScriptFetchInfo> mInitiatingScriptFetchInfo;
6355};
6356
6357NS_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; }
6358 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; }
6359 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; }
6360
6361NS_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"
, 6361); 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
6362NS_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; }
6363
6364NS_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; }
6365NS_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; }
6366
6367bool WindowScriptTimeoutHandler::Call(const char* aExecutionReason) {
6368 // New script entry point required, due to the "Create a script" sub-step
6369 // of
6370 // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
6371 nsAutoMicroTask mt;
6372 AutoEntryScript aes(mGlobal, aExecutionReason, true);
6373 JS::CompileOptions options(aes.cx());
6374 options.setFileAndLine(mCaller.FileName().get(), mCaller.mLine);
6375 options.setNoScriptRval(true);
6376 options.setIntroductionType("domTimer");
6377 JS::Rooted<JSObject*> global(aes.cx(), mGlobal->GetGlobalJSObject());
6378 {
6379 if (MOZ_UNLIKELY(!xpc::Scriptability::Get(global).Allowed())(__builtin_expect(!!(!xpc::Scriptability::Get(global).Allowed
()), 0))
) {
6380 return true;
6381 }
6382
6383 IgnoredErrorResult erv;
6384 mozilla::AutoProfilerLabel autoProfilerLabel("JSExecutionContext",
6385 /* dynamicStr */ nullptr,
6386 JS::ProfilingCategoryPair::JS);
6387 JSAutoRealm autoRealm(aes.cx(), global);
6388 RefPtr<JS::Stencil> stencil;
6389 JS::Rooted<JSScript*> script(aes.cx());
6390 Compile(aes.cx(), options, mExpr, stencil, erv);
6391 if (stencil) {
6392 JS::InstantiateOptions instantiateOptions(options);
6393 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", 6393
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!instantiateOptions.deferDebugMetadata"
")"); do { MOZ_CrashSequence(__null, 6393); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6394 script.set(JS::InstantiateGlobalStencil(aes.cx(), instantiateOptions,
6395 stencil, /* storage */ nullptr));
6396 if (!script) {
6397 erv.NoteJSContextException(aes.cx());
6398 }
6399 }
6400
6401 if (script) {
6402 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", 6402
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!erv.Failed()" ")"
); do { MOZ_CrashSequence(__null, 6402); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6403 if (mInitiatingScriptFetchInfo) {
6404 mInitiatingScriptFetchInfo->AssociateWithScript(script);
6405 }
6406
6407 if (!JS_ExecuteScript(aes.cx(), script)) {
6408 erv.NoteJSContextException(aes.cx());
6409 }
6410 }
6411
6412 if (erv.IsUncatchableException()) {
6413 return false;
6414 }
6415 }
6416
6417 return true;
6418};
6419
6420nsGlobalWindowInner* nsGlobalWindowInner::InnerForSetTimeoutOrInterval(
6421 ErrorResult& aError) {
6422 nsGlobalWindowOuter* outer = GetOuterWindowInternal();
6423 nsPIDOMWindowInner* currentInner =
6424 outer ? outer->GetCurrentInnerWindow() : this;
6425
6426 // If forwardTo is not the window with an active document then we want the
6427 // call to setTimeout/Interval to be a noop, so return null but don't set an
6428 // error.
6429 return HasActiveDocument() ? nsGlobalWindowInner::Cast(currentInner)
6430 : nullptr;
6431}
6432
6433int32_t nsGlobalWindowInner::SetTimeout(
6434 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6435 int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6436 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6437 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, false,
6438 aSubjectPrincipal, aError);
6439}
6440
6441int32_t nsGlobalWindowInner::SetInterval(
6442 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6443 const int32_t aTimeout, const Sequence<JS::Value>& aArguments,
6444 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6445 return SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments, true,
6446 aSubjectPrincipal, aError);
6447}
6448
6449int32_t nsGlobalWindowInner::SetTimeoutOrInterval(
6450 JSContext* aCx, const FunctionOrTrustedScriptOrString& aHandler,
6451 int32_t aTimeout, const Sequence<JS::Value>& aArguments, bool aIsInterval,
6452 nsIPrincipal* aSubjectPrincipal, ErrorResult& aError) {
6453 nsGlobalWindowInner* inner = InnerForSetTimeoutOrInterval(aError);
6454 if (!inner) {
6455 return -1;
6456 }
6457
6458 if (inner != this) {
6459 RefPtr<nsGlobalWindowInner> innerRef(inner);
6460 return innerRef->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aArguments,
6461 aIsInterval, aSubjectPrincipal,
6462 aError);
6463 }
6464
6465 DebuggerNotificationDispatch(
6466 this, aIsInterval ? DebuggerNotificationType::SetInterval
6467 : DebuggerNotificationType::SetTimeout);
6468
6469 if (!GetContextInternal() || !HasJSGlobal()) {
6470 // This window was already closed, or never properly initialized,
6471 // don't let a timer be scheduled on such a window.
6472 return 0;
6473 }
6474
6475 if (aHandler.IsFunction()) {
6476 nsTArray<JS::Heap<JS::Value>> args;
6477 if (!args.AppendElements(aArguments, fallible)) {
6478 aError.Throw(NS_ERROR_OUT_OF_MEMORY);
6479 return 0;
6480 }
6481
6482 RefPtr handler = MakeRefPtr<CallbackTimeoutHandler>(
6483 aCx, this, &aHandler.GetAsFunction(), std::move(args));
6484
6485 int32_t result;
6486 aError = mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6487 Timeout::Reason::eTimeoutOrInterval,
6488 &result);
6489 return result;
6490 }
6491
6492 constexpr nsLiteralString sinkSetTimeout = u"Window setTimeout"_ns;
6493 constexpr nsLiteralString sinkSetInterval = u"Window setInterval"_ns;
6494 Maybe<nsAutoString> compliantStringHolder;
6495 nsCOMPtr<nsIGlobalObject> pinnedGlobal = this;
6496 const nsAString* compliantString =
6497 TrustedTypeUtils::GetTrustedTypesCompliantString(
6498 aHandler, aIsInterval ? sinkSetInterval : sinkSetTimeout,
6499 kTrustedTypesOnlySinkGroup, *pinnedGlobal, aSubjectPrincipal,
6500 compliantStringHolder, aError);
6501 if (aError.Failed()) {
6502 return 0;
6503 }
6504
6505 bool allowEval = false;
6506 aError =
6507 CSPEvalChecker::CheckForWindow(aCx, this, *compliantString, &allowEval);
6508 if (NS_WARN_IF(aError.Failed())NS_warn_if_impl(aError.Failed(), "aError.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 6508)
|| !allowEval) {
6509 return 0;
6510 }
6511 RefPtr handler =
6512 MakeRefPtr<WindowScriptTimeoutHandler>(aCx, this, *compliantString);
6513 int32_t result;
6514 aError =
6515 mTimeoutManager->SetTimeout(handler, aTimeout, aIsInterval,
6516 Timeout::Reason::eTimeoutOrInterval, &result);
6517 return result;
6518}
6519
6520static const char* GetTimeoutReasonString(Timeout* aTimeout) {
6521 switch (aTimeout->mReason) {
6522 case Timeout::Reason::eTimeoutOrInterval:
6523 if (aTimeout->mIsInterval) {
6524 return "setInterval handler";
6525 }
6526 return "setTimeout handler";
6527 case Timeout::Reason::eIdleCallbackTimeout:
6528 return "setIdleCallback handler (timed out)";
6529 case Timeout::Reason::eAbortSignalTimeout:
6530 return "AbortSignal timeout";
6531 case Timeout::Reason::eDelayedWebTaskTimeout:
6532 return "delayedWebTaskCallback handler (timed out)";
6533 case Timeout::Reason::eJSTimeout:
6534 return "JavaScript TimeoutJob (timed out)";
6535 default:
6536 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6536
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6536); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6537 return "";
6538 }
6539 MOZ_CRASH("Unexpected enum value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected enum value"
, "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp", 6539
); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected enum value"
")"); do { MOZ_CrashSequence(__null, 6539); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6540 return "";
6541}
6542
6543bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) {
6544 // Hold on to the timeout in case mExpr or mFunObj releases its
6545 // doc.
6546 // XXXbz Our caller guarantees it'll hold on to the timeout (because
6547 // we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that...
6548 RefPtr<Timeout> timeout = aTimeout;
6549 Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
6550 timeout->mRunning = true;
6551
6552 // Push this timeout's popup control state, which should only be
6553 // enabled the first time a timeout fires that was created while
6554 // popups were enabled and with a delay less than
6555 // "dom.disable_open_click_delay".
6556 AutoPopupStatePusherAutoPopupStatePusherInternal popupStatePusher(timeout->mPopupState);
6557
6558 // Clear the timeout's popup state, if any, to prevent interval
6559 // timeouts from repeatedly opening poups.
6560 timeout->mPopupState = PopupBlocker::openAbused;
6561
6562 uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWindow();
6563 mTimeoutManager->SetNestingLevelForWindow(timeout->mNestingLevel);
6564
6565 const char* reason = GetTimeoutReasonString(timeout);
6566
6567 nsCString str;
6568 if (profiler_thread_is_being_profiled_for_markers()) {
6569 TimeDuration originalInterval = timeout->When() - timeout->SubmitTime();
6570 str.Append(reason);
6571 str.Append(" with interval ");
6572 str.AppendInt(int(originalInterval.ToMilliseconds()));
6573 str.Append("ms: ");
6574 nsCString handlerDescription;
6575 timeout->mScriptHandler->GetDescription(handlerDescription);
6576 str.Append(handlerDescription);
6577 }
6578 AUTO_PROFILER_MARKER_TEXT("setTimeout callback", DOM,AutoProfilerTextMarker raiiObject6582( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6579 MarkerOptions(MarkerStack::TakeBacktrace(AutoProfilerTextMarker raiiObject6582( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6580 timeout->TakeProfilerBacktrace()),AutoProfilerTextMarker raiiObject6582( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6581 MarkerInnerWindowId(mWindowID)),AutoProfilerTextMarker raiiObject6582( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
6582 str)AutoProfilerTextMarker raiiObject6582( "setTimeout callback",
::mozilla::baseprofiler::category::DOM, MarkerOptions(MarkerStack
::TakeBacktrace( timeout->TakeProfilerBacktrace()), MarkerInnerWindowId
(mWindowID)), str)
;
6583
6584 bool abortIntervalHandler;
6585 {
6586 RefPtr<TimeoutHandler> handler(timeout->mScriptHandler);
6587
6588 CallbackDebuggerNotificationGuard guard(
6589 this, timeout->mIsInterval
6590 ? DebuggerNotificationType::SetIntervalCallback
6591 : DebuggerNotificationType::SetTimeoutCallback);
6592 abortIntervalHandler = !handler->Call(reason);
6593 }
6594
6595 // If we received an uncatchable exception, do not schedule the timeout again.
6596 // This allows the slow script dialog to break easy DoS attacks like
6597 // setInterval(function() { while(1); }, 100);
6598 if (abortIntervalHandler) {
6599 // If it wasn't an interval timer to begin with, this does nothing. If it
6600 // was, we'll treat it as a timeout that we just ran and discard it when
6601 // we return.
6602 timeout->mIsInterval = false;
6603 }
6604
6605 // We ignore any failures from calling EvaluateString() on the context or
6606 // Call() on a Function here since we're in a loop
6607 // where we're likely to be running timeouts whose OS timers
6608 // didn't fire in time and we don't want to not fire those timers
6609 // now just because execution of one timer failed. We can't
6610 // propagate the error to anyone who cares about it from this
6611 // point anyway, and the script context should have already reported
6612 // the script error in the usual way - so we just drop it.
6613
6614 mTimeoutManager->SetNestingLevelForWindow(nestingLevel);
6615
6616 mTimeoutManager->EndRunningTimeout(last_running_timeout);
6617 timeout->mRunning = false;
6618
6619 return timeout->mCleared;
6620}
6621
6622//*****************************************************************************
6623// nsGlobalWindowInner: Helper Functions
6624//*****************************************************************************
6625
6626already_AddRefed<nsIDocShellTreeOwner> nsGlobalWindowInner::GetTreeOwner() {
6627 FORWARD_TO_OUTER(GetTreeOwner, (), nullptr);
6628}
6629
6630already_AddRefed<nsIWebBrowserChrome>
6631nsGlobalWindowInner::GetWebBrowserChrome() {
6632 nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
6633
6634 nsCOMPtr<nsIWebBrowserChrome> browserChrome = do_GetInterface(treeOwner);
6635 return browserChrome.forget();
6636}
6637
6638ScrollContainerFrame* nsGlobalWindowInner::GetScrollContainerFrame() {
6639 FORWARD_TO_OUTER(GetScrollContainerFrame, (), nullptr);
6640}
6641
6642bool nsGlobalWindowInner::IsPrivateBrowsing() {
6643 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(GetDocShell());
6644 return loadContext && loadContext->UsePrivateBrowsing();
6645}
6646
6647void nsGlobalWindowInner::FlushPendingNotifications(FlushType aType) {
6648 if (mDoc) {
6649 mDoc->FlushPendingNotifications(aType);
6650 }
6651}
6652
6653void nsGlobalWindowInner::EnableDeviceSensor(uint32_t aType) {
6654 bool alreadyEnabled = false;
6655 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6656 if (mEnabledSensors[i] == aType) {
6657 alreadyEnabled = true;
6658 break;
6659 }
6660 }
6661
6662 mEnabledSensors.AppendElement(aType);
6663
6664 if (alreadyEnabled) {
6665 return;
6666 }
6667
6668 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6669 if (ac) {
6670 ac->AddWindowListener(aType, this);
6671 }
6672}
6673
6674void nsGlobalWindowInner::DisableDeviceSensor(uint32_t aType) {
6675 int32_t doomedElement = -1;
6676 int32_t listenerCount = 0;
6677 for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) {
6678 if (mEnabledSensors[i] == aType) {
6679 doomedElement = i;
6680 listenerCount++;
6681 }
6682 }
6683
6684 if (doomedElement == -1) {
6685 return;
6686 }
6687
6688 mEnabledSensors.RemoveElementAt(doomedElement);
6689
6690 if (listenerCount > 1) {
6691 return;
6692 }
6693
6694 nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID"@mozilla.org/devicesensors;1");
6695 if (ac) {
6696 ac->RemoveWindowListener(aType, this);
6697 }
6698}
6699
6700#if defined(MOZ_WIDGET_ANDROID)
6701void nsGlobalWindowInner::EnableOrientationChangeListener() {
6702 if (!ShouldResistFingerprinting(RFPTarget::ScreenOrientation)) {
6703 mHasOrientationChangeListeners = true;
6704 mOrientationAngle = Orientation(CallerType::System);
6705 }
6706}
6707
6708void nsGlobalWindowInner::DisableOrientationChangeListener() {
6709 mHasOrientationChangeListeners = false;
6710}
6711#endif
6712
6713void nsGlobalWindowInner::SetHasGamepadEventListener(
6714 bool aHasGamepad /* = true*/) {
6715 mHasGamepad = aHasGamepad;
6716 if (aHasGamepad) {
6717 EnableGamepadUpdates();
6718 }
6719}
6720
6721void nsGlobalWindowInner::NotifyDetectXRRuntimesCompleted() {
6722 if (!mXRRuntimeDetectionInFlight) {
6723 return;
6724 }
6725 mXRRuntimeDetectionInFlight = false;
6726 if (mXRPermissionRequestInFlight) {
6727 return;
6728 }
6729 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6730 bool supported = vm->RuntimeSupportsVR();
6731 if (!supported) {
6732 // A VR runtime was not installed; we can suppress
6733 // the permission prompt
6734 OnXRPermissionRequestCancel();
6735 return;
6736 }
6737 // A VR runtime was found. Display a permission prompt before
6738 // allowing it to be accessed.
6739 // Connect to the VRManager in order to receive the runtime
6740 // detection results.
6741 mXRPermissionRequestInFlight = true;
6742 RefPtr request = MakeRefPtr<XRPermissionRequest>(this, WindowID());
6743 (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"
, 6743)
;
6744}
6745
6746void nsGlobalWindowInner::RequestXRPermission() {
6747 if (IsDying()) {
6748 // Do not proceed if the window is dying, as that will result
6749 // in leaks of objects that get re-allocated after FreeInnerObjects
6750 // has been called, including mVREventObserver.
6751 return;
6752 }
6753 if (mXRPermissionGranted) {
6754 // Don't prompt redundantly once permission to
6755 // access XR devices has been granted.
6756 OnXRPermissionRequestAllow();
6757 return;
6758 }
6759 if (mXRRuntimeDetectionInFlight || mXRPermissionRequestInFlight) {
6760 // Don't allow multiple simultaneous permissions requests;
6761 return;
6762 }
6763 // Before displaying a permission prompt, detect
6764 // if there is any VR runtime installed.
6765 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
6766 mXRRuntimeDetectionInFlight = true;
6767 EnableVRUpdates();
6768 vm->DetectRuntimes();
6769}
6770
6771void nsGlobalWindowInner::OnXRPermissionRequestAllow() {
6772 mXRPermissionRequestInFlight = false;
6773 if (IsDying()) {
6774 // The window may have started dying while the permission request
6775 // is in flight.
6776 // Do not proceed if the window is dying, as that will result
6777 // in leaks of objects that get re-allocated after FreeInnerObjects
6778 // has been called, including mNavigator.
6779 return;
6780 }
6781 mXRPermissionGranted = true;
6782
6783 NotifyHasXRSession();
6784
6785 dom::Navigator* nav = Navigator();
6786 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", 6786
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6786); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6787 nav->OnXRPermissionRequestAllow();
6788}
6789
6790void nsGlobalWindowInner::OnXRPermissionRequestCancel() {
6791 mXRPermissionRequestInFlight = false;
6792 if (IsDying()) {
6793 // The window may have started dying while the permission request
6794 // is in flight.
6795 // Do not proceed if the window is dying, as that will result
6796 // in leaks of objects that get re-allocated after FreeInnerObjects
6797 // has been called, including mNavigator.
6798 return;
6799 }
6800 dom::Navigator* nav = Navigator();
6801 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", 6801
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nav != nullptr" ")"
); do { MOZ_CrashSequence(__null, 6801); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6802 nav->OnXRPermissionRequestCancel();
6803}
6804
6805void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
6806 if (aType == nsGkAtoms::onvrdisplayactivate ||
6807 aType == nsGkAtoms::onvrdisplayconnect ||
6808 aType == nsGkAtoms::onvrdisplaydeactivate ||
6809 aType == nsGkAtoms::onvrdisplaydisconnect ||
6810 aType == nsGkAtoms::onvrdisplaypresentchange) {
6811 RequestXRPermission();
6812 }
6813
6814 if (aType == nsGkAtoms::onvrdisplayactivate) {
6815 mHasVRDisplayActivateEvents = true;
6816 }
6817
6818 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6819 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6820 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6821 }
6822 }
6823
6824 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6825 if (!StaticPrefs::
6826 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6827 if (++mUnloadOrBeforeUnloadListenerCount == 1) {
6828 mWindowGlobalChild->BlockBFCacheFor(
6829 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6830 }
6831 }
6832 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6833 mWindowGlobalChild->BeforeUnloadAdded();
6834 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"
, 6834); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() > 0"
")"); do { MOZ_CrashSequence(__null, 6834); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6835 }
6836 }
6837
6838 // We need to initialize localStorage in order to receive notifications.
6839 if (aType == nsGkAtoms::onstorage) {
6840 ErrorResult rv;
6841 GetLocalStorage(rv);
6842 rv.SuppressException();
6843
6844 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6845 mLocalStorage->Type() == Storage::eLocalStorage) {
6846 auto object = static_cast<LSObject*>(mLocalStorage.get());
6847
6848 (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", 6848
)
;
6849 }
6850 }
6851}
6852
6853void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) {
6854 if (aType == nsGkAtoms::onunload && mWindowGlobalChild) {
6855 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", 6855
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mUnloadOrBeforeUnloadListenerCount > 0"
")"); do { MOZ_CrashSequence(__null, 6855); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6856 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6857 mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
6858 }
6859 }
6860
6861 if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild) {
6862 if (!StaticPrefs::
6863 docshell_shistory_bfcache_ship_allow_beforeunload_listeners()) {
6864 if (--mUnloadOrBeforeUnloadListenerCount == 0) {
6865 mWindowGlobalChild->UnblockBFCacheFor(
6866 BFCacheStatus::BEFOREUNLOAD_LISTENER);
6867 }
6868 }
6869 if (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS)) {
6870 mWindowGlobalChild->BeforeUnloadRemoved();
6871 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"
, 6871); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BeforeUnloadListeners() >= 0"
")"); do { MOZ_CrashSequence(__null, 6871); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6872 }
6873 }
6874
6875 if (aType == nsGkAtoms::onstorage) {
6876 if (NextGenLocalStorageEnabled() && mLocalStorage &&
6877 mLocalStorage->Type() == Storage::eLocalStorage &&
6878 // The remove event is fired even if this isn't the last listener, so
6879 // only remove if there are no other listeners left.
6880 mListenerManager &&
6881 !mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
6882 auto object = static_cast<LSObject*>(mLocalStorage.get());
6883
6884 object->DropObserver();
6885 }
6886 }
6887}
6888
6889void nsGlobalWindowInner::NotifyHasXRSession() {
6890 if (IsDying()) {
6891 // Do not proceed if the window is dying, as that will result
6892 // in leaks of objects that get re-allocated after FreeInnerObjects
6893 // has been called, including mVREventObserver.
6894 return;
6895 }
6896 if (mWindowGlobalChild && !mHasXRSession) {
6897 mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR);
6898 }
6899 mHasXRSession = true;
6900 EnableVRUpdates();
6901}
6902
6903bool nsGlobalWindowInner::HasUsedVR() const {
6904 // Returns true only if content has enumerated and activated
6905 // XR devices. Detection of XR runtimes without activation
6906 // will not cause true to be returned.
6907 return mHasXRSession;
6908}
6909
6910bool nsGlobalWindowInner::IsVRContentDetected() const {
6911 // Returns true only if the content will respond to
6912 // the VRDisplayActivate event.
6913 return mHasVRDisplayActivateEvents;
6914}
6915
6916bool nsGlobalWindowInner::IsVRContentPresenting() const {
6917 for (const auto& display : mVRDisplays) {
6918 if (display->IsAnyPresenting(gfx::kVRGroupAll)) {
6919 return true;
6920 }
6921 }
6922 return false;
6923}
6924
6925void nsGlobalWindowInner::AddSizeOfIncludingThis(
6926 nsWindowSizes& aWindowSizes) const {
6927 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6928 aWindowSizes.mState.mMallocSizeOf(this);
6929 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6930 nsIGlobalObject::ShallowSizeOfExcludingThis(
6931 aWindowSizes.mState.mMallocSizeOf);
6932
6933 EventListenerManager* elm = GetExistingListenerManager();
6934 if (elm) {
6935 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6936 elm->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6937 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6938 }
6939 if (mDoc) {
6940 // Multiple global windows can share a document. So only measure the
6941 // document if it (a) doesn't have a global window, or (b) it's the
6942 // primary document for the window.
6943 if (!mDoc->GetInnerWindow() || mDoc->GetInnerWindow() == this) {
6944 mDoc->DocAddSizeOfIncludingThis(aWindowSizes);
6945 }
6946 }
6947
6948 if (mNavigation) {
6949 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6950 aWindowSizes.mState.mMallocSizeOf(mNavigation.get());
6951 }
6952 if (mNavigator) {
6953 aWindowSizes.mDOMSizes.mDOMOtherSize +=
6954 mNavigator->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
6955 }
6956
6957 ForEachGlobalTeardownObserver([&](GlobalTeardownObserver* et,
6958 bool* aDoneOut) {
6959 if (nsCOMPtr<nsISizeOfEventTarget> iSizeOf = do_QueryObject(et)) {
6960 aWindowSizes.mDOMSizes.mDOMEventTargetsSize +=
6961 iSizeOf->SizeOfEventTargetIncludingThis(
6962 aWindowSizes.mState.mMallocSizeOf);
6963 }
6964 if (nsCOMPtr<DOMEventTargetHelper> helper = do_QueryObject(et)) {
6965 if (EventListenerManager* elm = helper->GetExistingListenerManager()) {
6966 aWindowSizes.mDOMEventListenersCount += elm->ListenerCount();
6967 }
6968 }
6969 ++aWindowSizes.mDOMEventTargetsCount;
6970 });
6971
6972 if (mPerformance) {
6973 aWindowSizes.mDOMSizes.mDOMPerformanceUserEntries =
6974 mPerformance->SizeOfUserEntries(aWindowSizes.mState.mMallocSizeOf);
6975 aWindowSizes.mDOMSizes.mDOMPerformanceResourceEntries =
6976 mPerformance->SizeOfResourceEntries(aWindowSizes.mState.mMallocSizeOf);
6977 aWindowSizes.mDOMSizes.mDOMPerformanceEventEntries =
6978 mPerformance->SizeOfEventEntries(aWindowSizes.mState.mMallocSizeOf);
6979 }
6980
6981 aWindowSizes.mMediaSourceURLsCount = mMediaSourceURLs.Length();
6982}
6983
6984void nsGlobalWindowInner::RegisterDataDocumentForMemoryReporting(
6985 Document* aDocument) {
6986 aDocument->SetAddedToMemoryReportAsDataDocument();
6987 mDataDocumentsForMemoryReporting.AppendElement(aDocument);
6988}
6989
6990void nsGlobalWindowInner::UnregisterDataDocumentForMemoryReporting(
6991 Document* aDocument) {
6992 DebugOnly<bool> found =
6993 mDataDocumentsForMemoryReporting.RemoveElement(aDocument);
6994 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"
, 6994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ")")
; do { MOZ_CrashSequence(__null, 6994); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6995}
6996
6997void nsGlobalWindowInner::CollectDOMSizesForDataDocuments(
6998 nsWindowSizes& aSize) const {
6999 for (Document* doc : mDataDocumentsForMemoryReporting) {
7000 if (doc) {
7001 doc->DocAddSizeOfIncludingThis(aSize);
7002 }
7003 }
7004}
7005
7006void nsGlobalWindowInner::AddGamepad(GamepadHandle aHandle, Gamepad* aGamepad) {
7007 // Create the index we will present to content based on which indices are
7008 // already taken, as required by the spec.
7009 // https://w3c.github.io/gamepad/gamepad.html#widl-Gamepad-index
7010 int index = 0;
7011 while (mGamepadIndexSet.Contains(index)) {
7012 ++index;
7013 }
7014 mGamepadIndexSet.Put(index);
7015 aGamepad->SetIndex(index);
7016 mGamepads.InsertOrUpdate(aHandle, RefPtr{aGamepad});
7017}
7018
7019void nsGlobalWindowInner::RemoveGamepad(GamepadHandle aHandle) {
7020 RefPtr<Gamepad> gamepad;
7021 if (!mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7022 return;
7023 }
7024 // Free up the index we were using so it can be reused
7025 mGamepadIndexSet.Remove(gamepad->Index());
7026 mGamepads.Remove(aHandle);
7027}
7028
7029void nsGlobalWindowInner::GetGamepads(nsTArray<RefPtr<Gamepad>>& aGamepads) {
7030 aGamepads.Clear();
7031
7032 // navigator.getGamepads() always returns an empty array when
7033 // privacy.resistFingerprinting is true.
7034 if (ShouldResistFingerprinting(RFPTarget::Gamepad)) {
7035 return;
7036 }
7037
7038 // mGamepads.Count() may not be sufficient, but it's not harmful.
7039 aGamepads.SetCapacity(mGamepads.Count());
7040 for (const auto& entry : mGamepads) {
7041 Gamepad* gamepad = entry.GetWeak();
7042 aGamepads.EnsureLengthAtLeast(gamepad->Index() + 1);
7043 aGamepads[gamepad->Index()] = gamepad;
7044 }
7045}
7046
7047already_AddRefed<mozilla::dom::Promise> nsGlobalWindowInner::RequestAllGamepads(
7048 ErrorResult& aRv) {
7049 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7050
7051 if (!gamepadManager) {
7052 aRv.Throw(NS_ERROR_UNEXPECTED);
7053 return nullptr;
7054 }
7055
7056 return gamepadManager->RequestAllGamepads(this, aRv);
7057}
7058
7059already_AddRefed<Gamepad> nsGlobalWindowInner::GetGamepad(
7060 GamepadHandle aHandle) {
7061 RefPtr<Gamepad> gamepad;
7062
7063 if (mGamepads.Get(aHandle, getter_AddRefs(gamepad))) {
7064 return gamepad.forget();
7065 }
7066
7067 return nullptr;
7068}
7069
7070void nsGlobalWindowInner::SetHasSeenGamepadInput(bool aHasSeen) {
7071 mHasSeenGamepadInput = aHasSeen;
7072}
7073
7074bool nsGlobalWindowInner::HasSeenGamepadInput() { return mHasSeenGamepadInput; }
7075
7076void nsGlobalWindowInner::SyncGamepadState() {
7077 if (mHasSeenGamepadInput) {
7078 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7079 for (const auto& entry : mGamepads) {
7080 gamepadManager->SyncGamepadState(entry.GetKey(), this, entry.GetWeak());
7081 }
7082 }
7083}
7084
7085void nsGlobalWindowInner::StopGamepadHaptics() {
7086 if (mHasSeenGamepadInput) {
7087 RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
7088 gamepadManager->StopHaptics();
7089 }
7090}
7091
7092bool nsGlobalWindowInner::UpdateVRDisplays(
7093 nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices) {
7094 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7095 aDevices = mVRDisplays.Clone();
7096 return true;
7097}
7098
7099void nsGlobalWindowInner::NotifyActiveVRDisplaysChanged() {
7100 if (mNavigator) {
7101 mNavigator->NotifyActiveVRDisplaysChanged();
7102 }
7103}
7104
7105void nsGlobalWindowInner::NotifyPresentationGenerationChanged(
7106 uint32_t aDisplayID) {
7107 for (const auto& display : mVRDisplays) {
7108 if (display->DisplayId() == aDisplayID) {
7109 display->OnPresentationGenerationChanged();
7110 }
7111 }
7112}
7113
7114void nsGlobalWindowInner::DispatchVRDisplayActivate(
7115 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7116 // Ensure that our list of displays is up to date
7117 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7118
7119 // Search for the display identified with aDisplayID and fire the
7120 // event if found.
7121 for (const auto& display : mVRDisplays) {
7122 if (display->DisplayId() == aDisplayID) {
7123 if (aReason != VRDisplayEventReason::Navigation &&
7124 display->IsAnyPresenting(gfx::kVRGroupContent)) {
7125 // We only want to trigger this event if nobody is presenting to the
7126 // display already or when a page is loaded by navigating away
7127 // from a page with an active VR Presentation.
7128 continue;
7129 }
7130
7131 VRDisplayEventInit init;
7132 init.mBubbles = false;
7133 init.mCancelable = false;
7134 init.mDisplay = display;
7135 init.mReason.Construct(aReason);
7136
7137 RefPtr<VRDisplayEvent> event =
7138 VRDisplayEvent::Constructor(this, u"vrdisplayactivate"_ns, init);
7139 // vrdisplayactivate is a trusted event, allowing VRDisplay.requestPresent
7140 // to be used in response to link traversal, user request (chrome UX), and
7141 // HMD mounting detection sensors.
7142 event->SetTrusted(true);
7143 // VRDisplay.requestPresent normally requires a user gesture; however, an
7144 // exception is made to allow it to be called in response to
7145 // vrdisplayactivate during VR link traversal.
7146 display->StartHandlingVRNavigationEvent();
7147 DispatchEvent(*event);
7148 display->StopHandlingVRNavigationEvent();
7149 // Once we dispatch the event, we must not access any members as an event
7150 // listener can do anything, including closing windows.
7151 return;
7152 }
7153 }
7154}
7155
7156void nsGlobalWindowInner::DispatchVRDisplayDeactivate(
7157 uint32_t aDisplayID, mozilla::dom::VRDisplayEventReason aReason) {
7158 // Ensure that our list of displays is up to date
7159 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7160
7161 // Search for the display identified with aDisplayID and fire the
7162 // event if found.
7163 for (const auto& display : mVRDisplays) {
7164 if (display->DisplayId() == aDisplayID && display->IsPresenting()) {
7165 // We only want to trigger this event to content that is presenting to
7166 // the display already.
7167
7168 VRDisplayEventInit init;
7169 init.mBubbles = false;
7170 init.mCancelable = false;
7171 init.mDisplay = display;
7172 init.mReason.Construct(aReason);
7173
7174 RefPtr<VRDisplayEvent> event =
7175 VRDisplayEvent::Constructor(this, u"vrdisplaydeactivate"_ns, init);
7176 event->SetTrusted(true);
7177 DispatchEvent(*event);
7178 // Once we dispatch the event, we must not access any members as an event
7179 // listener can do anything, including closing windows.
7180 return;
7181 }
7182 }
7183}
7184
7185void nsGlobalWindowInner::DispatchVRDisplayConnect(uint32_t aDisplayID) {
7186 // Ensure that our list of displays is up to date
7187 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7188
7189 // Search for the display identified with aDisplayID and fire the
7190 // event if found.
7191 for (const auto& display : mVRDisplays) {
7192 if (display->DisplayId() == aDisplayID) {
7193 // Fire event even if not presenting to the display.
7194 VRDisplayEventInit init;
7195 init.mBubbles = false;
7196 init.mCancelable = false;
7197 init.mDisplay = display;
7198 // VRDisplayEvent.reason is not set for vrdisplayconnect
7199
7200 RefPtr<VRDisplayEvent> event =
7201 VRDisplayEvent::Constructor(this, u"vrdisplayconnect"_ns, init);
7202 event->SetTrusted(true);
7203 DispatchEvent(*event);
7204 // Once we dispatch the event, we must not access any members as an event
7205 // listener can do anything, including closing windows.
7206 return;
7207 }
7208 }
7209}
7210
7211void nsGlobalWindowInner::DispatchVRDisplayDisconnect(uint32_t aDisplayID) {
7212 // Ensure that our list of displays is up to date
7213 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7214
7215 // Search for the display identified with aDisplayID and fire the
7216 // event if found.
7217 for (const auto& display : mVRDisplays) {
7218 if (display->DisplayId() == aDisplayID) {
7219 // Fire event even if not presenting to the display.
7220 VRDisplayEventInit init;
7221 init.mBubbles = false;
7222 init.mCancelable = false;
7223 init.mDisplay = display;
7224 // VRDisplayEvent.reason is not set for vrdisplaydisconnect
7225
7226 RefPtr<VRDisplayEvent> event =
7227 VRDisplayEvent::Constructor(this, u"vrdisplaydisconnect"_ns, init);
7228 event->SetTrusted(true);
7229 DispatchEvent(*event);
7230 // Once we dispatch the event, we must not access any members as an event
7231 // listener can do anything, including closing windows.
7232 return;
7233 }
7234 }
7235}
7236
7237void nsGlobalWindowInner::DispatchVRDisplayPresentChange(uint32_t aDisplayID) {
7238 // Ensure that our list of displays is up to date
7239 VRDisplay::UpdateVRDisplays(mVRDisplays, this);
7240
7241 // Search for the display identified with aDisplayID and fire the
7242 // event if found.
7243 for (const auto& display : mVRDisplays) {
7244 if (display->DisplayId() == aDisplayID) {
7245 // Fire event even if not presenting to the display.
7246 VRDisplayEventInit init;
7247 init.mBubbles = false;
7248 init.mCancelable = false;
7249 init.mDisplay = display;
7250 // VRDisplayEvent.reason is not set for vrdisplaypresentchange
7251 RefPtr<VRDisplayEvent> event =
7252 VRDisplayEvent::Constructor(this, u"vrdisplaypresentchange"_ns, init);
7253 event->SetTrusted(true);
7254 DispatchEvent(*event);
7255 // Once we dispatch the event, we must not access any members as an event
7256 // listener can do anything, including closing windows.
7257 return;
7258 }
7259 }
7260}
7261
7262enum WindowState {
7263 // These constants need to match the constants in Window.webidl
7264 STATE_MAXIMIZED = 1,
7265 STATE_MINIMIZED = 2,
7266 STATE_NORMAL = 3,
7267 STATE_FULLSCREEN = 4
7268};
7269
7270uint16_t nsGlobalWindowInner::WindowState() {
7271 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7272
7273 int32_t mode = widget ? widget->SizeMode() : 0;
7274
7275 switch (mode) {
7276 case nsSizeMode_Minimized:
7277 return STATE_MINIMIZED;
7278 case nsSizeMode_Maximized:
7279 return STATE_MAXIMIZED;
7280 case nsSizeMode_Fullscreen:
7281 return STATE_FULLSCREEN;
7282 case nsSizeMode_Normal:
7283 return STATE_NORMAL;
7284 default:
7285 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"
, 7285)
;
7286 break;
7287 }
7288
7289 return STATE_NORMAL;
7290}
7291
7292bool nsGlobalWindowInner::IsFullyOccluded() {
7293 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7294 return widget && widget->IsFullyOccluded();
7295}
7296
7297void nsGlobalWindowInner::Maximize() {
7298 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7299 widget->SetSizeMode(nsSizeMode_Maximized);
7300 }
7301}
7302
7303void nsGlobalWindowInner::Minimize() {
7304 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7305 widget->SetSizeMode(nsSizeMode_Minimized);
7306 }
7307}
7308
7309void nsGlobalWindowInner::Restore() {
7310 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7311 widget->SetSizeMode(nsSizeMode_Normal);
7312 }
7313}
7314
7315void nsGlobalWindowInner::GetWorkspaceID(nsAString& workspaceID) {
7316 workspaceID.Truncate();
7317 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7318 return widget->GetWorkspaceID(workspaceID);
7319 }
7320}
7321
7322void nsGlobalWindowInner::MoveToWorkspace(const nsAString& workspaceID) {
7323 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7324 widget->MoveToWorkspace(workspaceID);
7325 }
7326}
7327
7328bool nsGlobalWindowInner::IsCloaked() const {
7329 if (nsCOMPtr<nsIWidget> widget = GetMainWidget()) {
7330 return widget->IsCloaked();
7331 }
7332 // Assume that it is not, since most windows are not cloaked.
7333 return false;
7334}
7335
7336void nsGlobalWindowInner::GetAttention(ErrorResult& aResult) {
7337 return GetAttentionWithCycleCount(-1, aResult);
7338}
7339
7340void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount,
7341 ErrorResult& aError) {
7342 nsCOMPtr<nsIWidget> widget = GetMainWidget();
7343
7344 if (widget) {
7345 aError = widget->GetAttention(aCycleCount);
7346 }
7347}
7348
7349already_AddRefed<Promise> nsGlobalWindowInner::PromiseDocumentFlushed(
7350 PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) {
7351 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", 7351
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7351); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7352
7353 if (!IsCurrentInnerWindow()) {
7354 aError.ThrowInvalidStateError("Not the current inner window");
7355 return nullptr;
7356 }
7357 if (!mDoc) {
7358 aError.ThrowInvalidStateError("No document");
7359 return nullptr;
7360 }
7361
7362 if (mIteratingDocumentFlushedResolvers) {
7363 aError.ThrowInvalidStateError("Already iterating through resolvers");
7364 return nullptr;
7365 }
7366
7367 PresShell* presShell = mDoc->GetPresShell();
7368 if (!presShell) {
7369 aError.ThrowInvalidStateError("No pres shell");
7370 return nullptr;
7371 }
7372
7373 // We need to associate the lifetime of the Promise to the lifetime
7374 // of the caller's global. That way, if the window we're observing
7375 // refresh driver ticks on goes away before our observer is fired,
7376 // we can still resolve the Promise.
7377 nsIGlobalObject* global = GetIncumbentGlobal();
7378 if (!global) {
7379 aError.ThrowInvalidStateError("No incumbent global");
7380 return nullptr;
7381 }
7382
7383 RefPtr<Promise> resultPromise = Promise::Create(global, aError);
7384 if (aError.Failed()) {
7385 return nullptr;
7386 }
7387
7388 auto flushResolver = std::make_unique<PromiseDocumentFlushedResolver>(
7389 resultPromise, aCallback);
7390
7391 if (!presShell->NeedStyleFlush() && !presShell->NeedLayoutFlush()) {
7392 flushResolver->Call();
7393 return resultPromise.forget();
7394 }
7395
7396 if (!TryToObserveRefresh()) {
7397 aError.ThrowInvalidStateError("Couldn't observe refresh");
7398 return nullptr;
7399 }
7400
7401 mDocumentFlushedResolvers.AppendElement(std::move(flushResolver));
7402 return resultPromise.forget();
7403}
7404
7405bool nsGlobalWindowInner::TryToObserveRefresh() {
7406 if (mObservingRefresh) {
7407 return true;
7408 }
7409
7410 if (!mDoc) {
7411 return false;
7412 }
7413
7414 nsPresContext* pc = mDoc->GetPresContext();
7415 if (!pc) {
7416 return false;
7417 }
7418
7419 mObservingRefresh = true;
7420 auto observer = MakeRefPtr<ManagedPostRefreshObserver>(
7421 pc, [win = RefPtr{this}](bool aWasCanceled) {
7422 if (win->MaybeCallDocumentFlushedResolvers(
7423 /* aUntilExhaustion = */ aWasCanceled)) {
7424 return ManagedPostRefreshObserver::Unregister::No;
7425 }
7426 win->mObservingRefresh = false;
7427 return ManagedPostRefreshObserver::Unregister::Yes;
7428 });
7429 pc->RegisterManagedPostRefreshObserver(observer.get());
7430 return mObservingRefresh;
7431}
7432
7433void nsGlobalWindowInner::CallDocumentFlushedResolvers(bool aUntilExhaustion) {
7434 while (true) {
7435 {
7436 // To coalesce MicroTask checkpoints inside callback call, enclose the
7437 // inner loop with nsAutoMicroTask, and perform a MicroTask checkpoint
7438 // after the loop.
7439 nsAutoMicroTask mt;
7440
7441 mIteratingDocumentFlushedResolvers = true;
7442
7443 auto resolvers = std::move(mDocumentFlushedResolvers);
7444 for (const auto& resolver : resolvers) {
7445 resolver->Call();
7446 }
7447
7448 mIteratingDocumentFlushedResolvers = false;
7449 }
7450
7451 // Leaving nsAutoMicroTask above will perform MicroTask checkpoint, and
7452 // Promise callbacks there may create mDocumentFlushedResolvers items.
7453
7454 // If there's no new resolvers, or we're not exhausting the queue, there's
7455 // nothing to do (we'll keep observing if there's any new observer).
7456 //
7457 // Otherwise, keep looping to call all promises. This case can happen while
7458 // destroying the window. This violates the constraint that the
7459 // promiseDocumentFlushed callback only ever run when no flush is needed,
7460 // but it's necessary to resolve the Promise returned by that.
7461 if (!aUntilExhaustion || mDocumentFlushedResolvers.IsEmpty()) {
7462 break;
7463 }
7464 }
7465}
7466
7467bool nsGlobalWindowInner::MaybeCallDocumentFlushedResolvers(
7468 bool aUntilExhaustion) {
7469 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"
, 7469); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDoc" ")");
do { MOZ_CrashSequence(__null, 7469); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7470
7471 PresShell* presShell = mDoc->GetPresShell();
7472 if (!presShell || aUntilExhaustion) {
7473 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ true);
7474 return false;
7475 }
7476
7477 if (presShell->NeedStyleFlush() || presShell->NeedLayoutFlush()) {
7478 // By the time our observer fired, something has already invalidated
7479 // style or layout - or perhaps we're still in the middle of a flush that
7480 // was interrupted. In either case, we'll wait until the next refresh driver
7481 // tick instead and try again.
7482 return true;
7483 }
7484
7485 CallDocumentFlushedResolvers(/* aUntilExhaustion = */ false);
7486 return !mDocumentFlushedResolvers.IsEmpty();
7487}
7488
7489already_AddRefed<nsWindowRoot> nsGlobalWindowInner::GetWindowRoot(
7490 mozilla::ErrorResult& aError) {
7491 FORWARD_TO_OUTER_OR_THROW(GetWindowRootOuter, (), aError, nullptr);
7492}
7493
7494void nsGlobalWindowInner::SetCursor(const nsACString& aCursor,
7495 ErrorResult& aError) {
7496 FORWARD_TO_OUTER_OR_THROW(SetCursorOuter, (aCursor, aError), aError, );
7497}
7498
7499nsIBrowserDOMWindow* nsGlobalWindowInner::GetBrowserDOMWindow(
7500 ErrorResult& aError) {
7501 FORWARD_TO_OUTER_OR_THROW(GetBrowserDOMWindow, (), aError, nullptr);
7502}
7503
7504void nsGlobalWindowInner::SetBrowserDOMWindow(
7505 nsIBrowserDOMWindow* aBrowserWindow, ErrorResult& aError) {
7506 FORWARD_TO_OUTER_OR_THROW(SetBrowserDOMWindowOuter, (aBrowserWindow),
7507 aError, );
7508}
7509
7510void nsGlobalWindowInner::NotifyDefaultButtonLoaded(Element& aDefaultButton,
7511 ErrorResult& aError) {
7512 // Don't snap to a disabled button.
7513 nsCOMPtr<nsIDOMXULControlElement> xulControl = aDefaultButton.AsXULControl();
7514 if (!xulControl) {
7515 aError.Throw(NS_ERROR_FAILURE);
7516 return;
7517 }
7518 bool disabled;
7519 aError = xulControl->GetDisabled(&disabled);
7520 if (aError.Failed() || disabled) {
7521 return;
7522 }
7523
7524 // Get the button rect in screen coordinates.
7525 nsIFrame* frame = aDefaultButton.GetPrimaryFrame();
7526 if (!frame) {
7527 aError.Throw(NS_ERROR_FAILURE);
7528 return;
7529 }
7530 LayoutDeviceIntRect buttonRect = LayoutDeviceIntRect::FromAppUnitsToNearest(
7531 frame->GetScreenRectInAppUnits(),
7532 frame->PresContext()->AppUnitsPerDevPixel());
7533
7534 // Get the widget rect in screen coordinates.
7535 nsIWidget* widget = GetNearestWidget();
7536 if (!widget) {
7537 aError.Throw(NS_ERROR_FAILURE);
7538 return;
7539 }
7540 LayoutDeviceIntRect widgetRect = widget->GetScreenBounds();
7541
7542 // Convert the buttonRect coordinates from screen to the widget.
7543 buttonRect -= widgetRect.TopLeft();
7544 nsresult rv = widget->OnDefaultButtonLoaded(buttonRect);
7545 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_IMPLEMENTED) {
7546 aError.Throw(rv);
7547 }
7548}
7549
7550ChromeMessageBroadcaster* nsGlobalWindowInner::MessageManager() {
7551 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", 7551
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7551); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7552 if (!mChromeFields.mMessageManager) {
7553 RefPtr<ChromeMessageBroadcaster> globalMM =
7554 nsFrameMessageManager::GetGlobalMessageManager();
7555 mChromeFields.mMessageManager =
7556 MakeRefPtr<ChromeMessageBroadcaster>(globalMM);
7557 }
7558 return mChromeFields.mMessageManager;
7559}
7560
7561ChromeMessageBroadcaster* nsGlobalWindowInner::GetGroupMessageManager(
7562 const nsAString& aGroup) {
7563 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", 7563
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsChromeWindow()"
")"); do { MOZ_CrashSequence(__null, 7563); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7564
7565 return mChromeFields.mGroupMessageManagers
7566 .LookupOrInsertWith(
7567 aGroup,
7568 [&] {
7569 return MakeAndAddRef<ChromeMessageBroadcaster>(MessageManager());
7570 })
7571 .get();
7572}
7573
7574void nsGlobalWindowInner::InitWasOffline() { mWasOffline = NS_IsOffline(); }
7575
7576int16_t nsGlobalWindowInner::Orientation(CallerType aCallerType) {
7577 // GetOrientationAngle() returns 0, 90, 180 or 270.
7578 // window.orientation returns -90, 0, 90 or 180.
7579 uint16_t screenAngle = Screen()->GetOrientationAngle();
7580 if (nsIGlobalObject::ShouldResistFingerprinting(
7581 aCallerType, RFPTarget::ScreenOrientation)) {
7582 CSSIntSize size = mBrowsingContext->TopInnerSizeSpoofedForRFP();
7583 screenAngle = nsRFPService::ViewportSizeToAngle(size.width, size.height);
7584 }
7585 int16_t angle = AssertedCast<int16_t>(screenAngle);
7586 return angle <= 180 ? angle : angle - 360;
7587}
7588
7589already_AddRefed<Console> nsGlobalWindowInner::GetConsole(JSContext* aCx,
7590 ErrorResult& aRv) {
7591 if (!mConsole) {
7592 mConsole = Console::Create(aCx, this, aRv);
7593 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7593)
) {
7594 return nullptr;
7595 }
7596 }
7597
7598 RefPtr<Console> console = mConsole;
7599 return console.forget();
7600}
7601
7602already_AddRefed<CookieStore> nsGlobalWindowInner::CookieStore() {
7603 if (!mCookieStore) {
7604 mCookieStore = CookieStore::Create(this);
7605 }
7606
7607 return do_AddRef(mCookieStore);
7608}
7609
7610DocumentPictureInPicture* nsGlobalWindowInner::DocumentPictureInPicture() {
7611 if (!mDocumentPiP) {
7612 mDocumentPiP = MakeRefPtr<class DocumentPictureInPicture>(this);
7613 }
7614
7615 return mDocumentPiP;
7616}
7617
7618mozilla::dom::PushManager* nsGlobalWindowInner::GetPushManager(
7619 JSContext* aCx, ErrorResult& aRv) {
7620 if (!mPushManager) {
7621 mPushManager = PushManager::Create(aCx, this, aRv);
7622 }
7623 return mPushManager;
7624}
7625
7626bool nsGlobalWindowInner::IsSecureContext() const {
7627 JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor());
7628 return JS::GetIsSecureContext(realm);
7629}
7630
7631External* nsGlobalWindowInner::External() {
7632 if (!mExternal) {
7633 mExternal = MakeRefPtr<dom::External>(ToSupports(this));
7634 }
7635
7636 return mExternal;
7637}
7638
7639void nsGlobalWindowInner::ClearDocumentDependentSlots(JSContext* aCx) {
7640 // If JSAPI OOMs here, there is basically nothing we can do to recover safely.
7641 if (!Window_Binding::ClearCachedDocumentValue(aCx, this) ||
7642 !Window_Binding::ClearCachedPerformanceValue(aCx, this)) {
7643 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", 7643
); AnnotateMozCrashReason("MOZ_CRASH(" "Unhandlable OOM while clearing document dependent slots."
")"); do { MOZ_CrashSequence(__null, 7643); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7644 }
7645}
7646
7647/* static */
7648JSObject* nsGlobalWindowInner::CreateNamedPropertiesObject(
7649 JSContext* aCx, JS::Handle<JSObject*> aProto) {
7650 return WindowNamedPropertiesHandler::Create(aCx, aProto);
7651}
7652
7653void nsGlobalWindowInner::RedefineProperty(JSContext* aCx,
7654 const char* aPropName,
7655 JS::Handle<JS::Value> aValue,
7656 ErrorResult& aError) {
7657 JS::Rooted<JSObject*> thisObj(aCx, GetWrapperPreserveColor());
7658 if (!thisObj) {
7659 aError.Throw(NS_ERROR_UNEXPECTED);
7660 return;
7661 }
7662
7663 if (!JS_WrapObject(aCx, &thisObj) ||
7664 !JS_DefineProperty(aCx, thisObj, aPropName, aValue, JSPROP_ENUMERATE)) {
7665 aError.Throw(NS_ERROR_FAILURE);
7666 }
7667}
7668
7669void nsGlobalWindowInner::FireOnNewGlobalObject() {
7670 // AutoEntryScript required to invoke debugger hook, which is a
7671 // Gecko-specific concept at present.
7672 AutoEntryScript aes(this, "nsGlobalWindowInner report new global");
7673 JS::Rooted<JSObject*> global(aes.cx(), GetWrapper());
7674 JS_FireOnNewGlobalObject(aes.cx(), global);
7675}
7676
7677#if defined(_WINDOWS_) && !defined(MOZ_WRAPPED_WINDOWS_H)
7678# pragma message( \
7679 "wrapper failure reason: " MOZ_WINDOWS_WRAPPER_DISABLED_REASON)
7680# error "Never include unwrapped windows.h in this file!"
7681#endif
7682
7683already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7684 const ImageBitmapSource& aImage, const ImageBitmapOptions& aOptions,
7685 ErrorResult& aRv) {
7686 return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv);
7687}
7688
7689already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
7690 const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw,
7691 int32_t aSh, const ImageBitmapOptions& aOptions, ErrorResult& aRv) {
7692 return ImageBitmap::Create(
7693 this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv);
7694}
7695
7696// https://html.spec.whatwg.org/#structured-cloning
7697void nsGlobalWindowInner::StructuredClone(
7698 JSContext* aCx, JS::Handle<JS::Value> aValue,
7699 const StructuredSerializeOptions& aOptions,
7700 JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) {
7701 nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRetval, aError);
7702}
7703
7704nsresult nsGlobalWindowInner::Dispatch(
7705 already_AddRefed<nsIRunnable> aRunnable) const {
7706 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", 7706
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7706); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7707 return NS_DispatchToCurrentThread(std::move(aRunnable));
7708}
7709
7710nsISerialEventTarget* nsGlobalWindowInner::SerialEventTarget() const {
7711 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", 7711
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7711); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7712 return GetMainThreadSerialEventTarget();
7713}
7714
7715Worklet* nsGlobalWindowInner::GetPaintWorklet(ErrorResult& aRv) {
7716 if (!mPaintWorklet) {
7717 nsIPrincipal* principal = GetPrincipal();
7718 if (!principal) {
7719 aRv.Throw(NS_ERROR_FAILURE);
7720 return nullptr;
7721 }
7722
7723 mPaintWorklet = PaintWorkletImpl::CreateWorklet(this, principal);
7724 }
7725
7726 return mPaintWorklet;
7727}
7728
7729void nsGlobalWindowInner::GetWebExposedLocales(nsTArray<nsString>& aLocales) {
7730 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", 7730
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::intl::LocaleService::GetInstance()"
")"); do { MOZ_CrashSequence(__null, 7730); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7731
7732 AutoTArray<nsCString, 10> rpLocales;
7733 mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(rpLocales);
7734
7735 for (const auto& loc : rpLocales) {
7736 aLocales.AppendElement(NS_ConvertUTF8toUTF16(loc));
7737 }
7738}
7739
7740IntlUtils* nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError) {
7741 if (!mIntlUtils) {
7742 mIntlUtils = MakeRefPtr<IntlUtils>(this);
7743 }
7744
7745 return mIntlUtils;
7746}
7747
7748void nsGlobalWindowInner::StoreSharedWorker(SharedWorker* aSharedWorker) {
7749 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", 7749
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7749); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7750 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", 7750
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7750); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7751
7752 mSharedWorkers.AppendElement(aSharedWorker);
7753}
7754
7755void nsGlobalWindowInner::ForgetSharedWorker(SharedWorker* aSharedWorker) {
7756 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", 7756
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSharedWorker" ")"
); do { MOZ_CrashSequence(__null, 7756); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7757 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", 7757
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSharedWorkers.Contains(aSharedWorker)"
")"); do { MOZ_CrashSequence(__null, 7757); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7758
7759 mSharedWorkers.RemoveElement(aSharedWorker);
7760}
7761
7762void nsGlobalWindowInner::UpdateSharedWorkersLanguageOverride(
7763 const nsCString& aLanguageOverride) {
7764 nsTArray<nsString> resolvedLanguages;
7765 Navigator::GetAcceptLanguages(resolvedLanguages, aLanguageOverride.IsEmpty()
7766 ? nullptr
7767 : &aLanguageOverride);
7768
7769 for (RefPtr<mozilla::dom::SharedWorker> pinnedWorker :
7770 mSharedWorkers.ForwardRange()) {
7771 pinnedWorker->UpdateLanguageOverride(aLanguageOverride, resolvedLanguages);
7772 }
7773}
7774
7775void nsGlobalWindowInner::UpdateSharedWorkerTimezoneOverride(
7776 const nsAString& aTimezoneOverride) {
7777 for (RefPtr<SharedWorker> pinnedWorker : mSharedWorkers.ForwardRange()) {
7778 pinnedWorker->UpdateTimezoneOverride(aTimezoneOverride);
7779 }
7780}
7781
7782RefPtr<GenericPromise> nsGlobalWindowInner::StorageAccessPermissionChanged(
7783 bool aGranted) {
7784 // Invalidate cached StorageAllowed field so that calls to GetLocalStorage
7785 // give us the updated localStorage object.
7786 ClearStorageAllowedCache();
7787
7788 // Just reset the active cookie and storage principals
7789 nsCOMPtr<nsICookieJarSettings> cjs;
7790 if (mDoc) {
7791 cjs = mDoc->CookieJarSettings();
7792 }
7793 StorageAccess storageAccess = StorageAllowedForWindow(this);
7794 if (ShouldPartitionStorage(storageAccess) &&
7795 StoragePartitioningEnabled(storageAccess, cjs)) {
7796 if (mDoc) {
7797 mDoc->ClearActiveCookieAndStoragePrincipals();
7798 }
7799 // When storage access is granted the content process needs to request the
7800 // updated cookie list from the parent process. Otherwise the site won't
7801 // have access to unpartitioned cookies via document.cookie without a
7802 // reload.
7803 if (aGranted) {
7804 nsIChannel* channel = mDoc->GetChannel();
7805 if (channel) {
7806 // The promise resolves when the updated cookie list has been received
7807 // from the parent.
7808 return ContentChild::UpdateCookieStatus(channel);
7809 }
7810 }
7811 }
7812
7813 PropagateStorageAccessPermissionGrantedToWorkers(*this);
7814
7815 // If we have a partitioned localStorage, it's time to replace it with a real
7816 // one in order to receive notifications.
7817
7818 if (mLocalStorage) {
7819 IgnoredErrorResult error;
7820 GetLocalStorage(error);
7821 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/root/firefox-clang/dom/base/nsGlobalWindowInner.cpp"
, 7821)
) {
7822 return MozPromise<bool, nsresult, true>::CreateAndReject(
7823 error.StealNSResult(), __func__);
7824 }
7825
7826 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", 7827
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7827); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7827 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", 7827
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLocalStorage && mLocalStorage->Type() == Storage::eLocalStorage"
")"); do { MOZ_CrashSequence(__null, 7827); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7828
7829 if (NextGenLocalStorageEnabled() && mListenerManager &&
7830 mListenerManager->HasListenersFor(nsGkAtoms::onstorage)) {
7831 auto object = static_cast<LSObject*>(mLocalStorage.get());
7832
7833 object->EnsureObserver();
7834 }
7835 }
7836
7837 // Reset the IndexedDB factory.
7838 mIndexedDB = nullptr;
7839
7840 // Reset DOM Cache
7841 mCacheStorage = nullptr;
7842
7843 // Reset the active cookie and storage principals
7844 if (mDoc) {
7845 mDoc->ClearActiveCookieAndStoragePrincipals();
7846 if (mWindowGlobalChild) {
7847 // Clearing the cookie principal might make us end up with a new effective
7848 // storage principal on the child side than on the parent side, which
7849 // means that we need to sync it. See bug 1705359.
7850 mWindowGlobalChild->SendUpdatePrincipalPartitioning(
7851 !mDoc->UseRegularPrincipal());
7852 }
7853 }
7854
7855 // When storage access is granted the content process needs to request the
7856 // updated cookie list from the parent process. Otherwise the site won't have
7857 // access to unpartitioned cookies via document.cookie without a reload.
7858 if (aGranted) {
7859 nsIChannel* channel = mDoc->GetChannel();
7860 if (channel) {
7861 // The promise resolves when the updated cookie list has been received
7862 // from the parent.
7863 return ContentChild::UpdateCookieStatus(channel);
7864 }
7865 }
7866 return MozPromise<bool, nsresult, true>::CreateAndResolve(true, __func__);
7867}
7868
7869ContentMediaController* nsGlobalWindowInner::GetContentMediaController() {
7870 if (mContentMediaController) {
7871 return mContentMediaController;
7872 }
7873 if (!mBrowsingContext) {
7874 return nullptr;
7875 }
7876
7877 mContentMediaController =
7878 MakeRefPtr<ContentMediaController>(mBrowsingContext->Id());
7879 return mContentMediaController;
7880}
7881
7882void nsGlobalWindowInner::SetScrollMarks(const nsTArray<uint32_t>& aScrollMarks,
7883 bool aOnHScrollbar) {
7884 mScrollMarks.Assign(aScrollMarks);
7885 mScrollMarksOnHScrollbar = aOnHScrollbar;
7886
7887 // Mark the scrollbar for repainting.
7888 if (mDoc) {
7889 PresShell* presShell = mDoc->GetPresShell();
7890 if (presShell) {
7891 ScrollContainerFrame* sf = presShell->GetRootScrollContainerFrame();
7892 if (sf) {
7893 sf->InvalidateScrollbars();
7894 }
7895 }
7896 }
7897}
7898
7899/* static */
7900already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
7901 nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
7902 WindowGlobalChild* aActor) {
7903 RefPtr<nsGlobalWindowInner> window =
7904 new nsGlobalWindowInner(aOuterWindow, aActor);
7905 if (aIsChrome) {
7906 window->mIsChrome = true;
7907 window->mCleanMessageManager = true;
7908 }
7909
7910 if (aActor) {
7911 aActor->InitWindowGlobal(window);
7912 }
7913
7914 window->InitWasOffline();
7915 return window.forget();
7916}
7917
7918JS::loader::ModuleLoaderBase* nsGlobalWindowInner::GetModuleLoader(
7919 JSContext* aCx) {
7920 Document* document = GetDocument();
7921 if (!document) {
7922 return nullptr;
7923 }
7924
7925 ScriptLoader* loader = document->GetScriptLoader();
7926 if (!loader) {
7927 return nullptr;
7928 }
7929
7930 return loader->GetModuleLoader();
7931}
7932
7933void nsGlobalWindowInner::SetCurrentPasteDataTransfer(
7934 DataTransfer* aDataTransfer) {
7935 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"
, 7935); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetEventMessage() == ePaste"
")"); do { MOZ_CrashSequence(__null, 7935); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7936 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", 7937
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7937); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
7937 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", 7937
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->ClipboardType() == Some(nsIClipboard::kGlobalClipboard)"
")"); do { MOZ_CrashSequence(__null, 7937); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7938 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", 7938
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDataTransfer->GetClipboardDataSnapshot()"
")"); do { MOZ_CrashSequence(__null, 7938); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
7939 mCurrentPasteDataTransfer = aDataTransfer;
7940}
7941
7942DataTransfer* nsGlobalWindowInner::GetCurrentPasteDataTransfer() const {
7943 return mCurrentPasteDataTransfer;
7944}
7945
7946TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() {
7947 if (!mTrustedTypePolicyFactory) {
7948 mTrustedTypePolicyFactory = MakeRefPtr<TrustedTypePolicyFactory>(this);
7949 }
7950
7951 return mTrustedTypePolicyFactory;
7952}
7953
7954void nsGlobalWindowInner::NoteMediaSourceURL(const nsACString& aURL) {
7955 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",
7955); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsDying()" ") ("
"MediaSourceURL will never be cleaned up" ")"); do { MOZ_CrashSequence
(__null, 7955); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7956 mMediaSourceURLs.InsertElementSorted(aURL);
7957}
7958
7959void nsGlobalWindowInner::UnnoteMediaSourceURL(const nsACString& aURL) {
7960 DebugOnly<bool> found = mMediaSourceURLs.RemoveElementSorted(aURL);
7961 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",
7961); AnnotateMozCrashReason("MOZ_ASSERT" "(" "found" ") ("
"MediaSourceURL should have been noted" ")"); do { MOZ_CrashSequence
(__null, 7961); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
7962}
7963
7964void nsGlobalWindowInner::HoldOldPrincipal(nsIPrincipal* aPrincipal) {
7965 mOldPrincipals.AppendElement(aPrincipal);
7966 Dispatch(NewRunnableMethod(
7967 "nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop", this,
7968 &nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop));
7969}
7970
7971void nsGlobalWindowInner::ClearOldPrincipalsIfNotNestedEventLoop() {
7972 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", 7972
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 7972); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7973 nsThread* mainThread = nsThreadManager::get().GetCurrentThread();
7974 if (mainThread && mainThread->RecursionDepth() > 1) {
7975 // Not OK to clear old principals from a nested event loop. In order
7976 // to avoid spamming the nested event loop with runnables, just give
7977 // up and leave the old principals around.
7978 return;
7979 }
7980 mOldPrincipals.Clear();
7981}
7982
7983void nsPIDOMWindowInner::MaybeSetHasPointerRawUpdateEventListeners() {
7984 if (HasPointerRawUpdateEventListeners() || !IsSecureContext()) {
7985 return;
7986 }
7987 mMayHavePointerRawUpdateEventListener = true;
7988 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7989 browserChild->OnPointerRawUpdateEventListenerAdded(this);
7990 }
7991}
7992
7993void nsPIDOMWindowInner::ClearHasPointerRawUpdateEventListeners() {
7994 if (!HasPointerRawUpdateEventListeners()) {
7995 return;
7996 }
7997 mMayHavePointerRawUpdateEventListener = false;
7998 if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
7999 browserChild->OnPointerRawUpdateEventListenerRemoved(this);
8000 }
8001}
8002
8003nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
8004 return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
8005}
8006
8007nsIURI* nsPIDOMWindowInner::GetDocBaseURI() const {
8008 return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
8009}
8010
8011mozilla::dom::WindowContext* nsPIDOMWindowInner::GetWindowContext() const {
8012 return mWindowGlobalChild ? mWindowGlobalChild->WindowContext() : nullptr;
8013}
8014
8015bool nsPIDOMWindowInner::RemoveFromBFCacheSync() {
8016 if (Document* doc = GetExtantDoc()) {
8017 return doc->RemoveFromBFCacheSync();
8018 }
8019 return false;
8020}
8021
8022void nsPIDOMWindowInner::MaybeCreateDoc() {
8023 // XXX: Forward to outer?
8024 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"
, 8024); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDoc" ")")
; do { MOZ_CrashSequence(__null, 8024); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8025 if (nsIDocShell* docShell = GetDocShell()) {
8026 // Note that |document| here is the same thing as our mDoc, but we
8027 // don't have to explicitly set the member variable because the docshell
8028 // has already called SetNewDocument().
8029 nsCOMPtr<Document> document = docShell->GetDocument();
8030 (void)document;
8031 }
8032}
8033
8034mozilla::dom::DocGroup* nsPIDOMWindowInner::GetDocGroup() const {
8035 Document* doc = GetExtantDoc();
8036 if (doc) {
8037 return doc->GetDocGroup();
8038 }
8039 return nullptr;
8040}
8041
8042mozilla::dom::BrowsingContextGroup*
8043nsPIDOMWindowInner::GetBrowsingContextGroup() const {
8044 return mBrowsingContext ? mBrowsingContext->Group() : nullptr;
8045}
8046
8047nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() {
8048 return nsGlobalWindowInner::Cast(this);
8049}
8050
8051const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const {
8052 return nsGlobalWindowInner::Cast(this);
8053}
8054
8055RefPtr<GenericPromise>
8056nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() {
8057 WindowContext* wc = GetWindowContext();
8058 if (wc) {
8059 (void)wc->SetUsingStorageAccess(true);
8060 }
8061
8062 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(true);
8063}
8064
8065RefPtr<GenericPromise>
8066nsPIDOMWindowInner::SaveStorageAccessPermissionRevoked() {
8067 WindowContext* wc = GetWindowContext();
8068 if (wc) {
8069 (void)wc->SetUsingStorageAccess(false);
8070 }
8071
8072 return nsGlobalWindowInner::Cast(this)->StorageAccessPermissionChanged(false);
8073}
8074
8075bool nsPIDOMWindowInner::UsingStorageAccess() {
8076 WindowContext* wc = GetWindowContext();
8077 if (!wc) {
8078 return false;
8079 }
8080
8081 return wc->GetUsingStorageAccess();
8082}
8083
8084WebIdentityHandler* nsPIDOMWindowInner::GetOrCreateWebIdentityHandler() {
8085 if (mWebIdentityHandler) {
8086 return mWebIdentityHandler;
8087 }
8088 mWebIdentityHandler = MakeRefPtr<WebIdentityHandler>(this);
8089 bool success = mWebIdentityHandler->MaybeCreateActor();
8090 if (!success) {
8091 mWebIdentityHandler = nullptr;
8092 }
8093 return mWebIdentityHandler;
8094}
8095
8096CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() {
8097 if (!mCloseWatcherManager) {
8098 mCloseWatcherManager = MakeRefPtr<CloseWatcherManager>();
8099 }
8100 return mCloseWatcherManager;
8101}
8102
8103void nsPIDOMWindowInner::NotifyCloseWatcherAdded() {
8104 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", 8104
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager && !mCloseWatcherManager->IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 8104); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8105 if (WindowContext* top = TopWindowContext(*this)) {
8106 (void)top->SetHasActiveCloseWatcher(true);
8107 }
8108}
8109
8110void nsPIDOMWindowInner::NotifyCloseWatcherRemoved() {
8111 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", 8111
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCloseWatcherManager"
")"); do { MOZ_CrashSequence(__null, 8111); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8112 if (WindowContext* top = TopWindowContext(*this)) {
8113 (void)top->SetHasActiveCloseWatcher(!mCloseWatcherManager->IsEmpty());
8114 }
8115}
8116
8117nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
8118 WindowGlobalChild* aActor)
8119 : mOuterWindow(aOuterWindow), mWindowGlobalChild(aActor) {
8120 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"
, 8120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOuterWindow"
")"); do { MOZ_CrashSequence(__null, 8120); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8121 mBrowsingContext = aOuterWindow->GetBrowsingContext();
8122
8123 if (mWindowGlobalChild) {
8124 mWindowID = aActor->InnerWindowId();
8125
8126 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", 8126
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWindowGlobalChild->BrowsingContext() == mBrowsingContext"
")"); do { MOZ_CrashSequence(__null, 8126); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8127 } else {
8128 mWindowID = nsContentUtils::GenerateWindowId();
8129 }
8130}
8131
8132nsPIDOMWindowInner::~nsPIDOMWindowInner() = default;
8133
8134#undef FORWARD_TO_OUTER
8135#undef FORWARD_TO_OUTER_OR_THROW
8136#undef FORWARD_TO_OUTER_VOID