Bug Summary

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