Bug Summary

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