Source code

Revision control

Other Tools

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
#ifndef mozilla_dom_BrowsingContext_h
8
#define mozilla_dom_BrowsingContext_h
9
10
#include "GVAutoplayRequestUtils.h"
11
#include "mozilla/LinkedList.h"
12
#include "mozilla/Maybe.h"
13
#include "mozilla/RefPtr.h"
14
#include "mozilla/Tuple.h"
15
#include "mozilla/WeakPtr.h"
16
#include "mozilla/dom/BindingDeclarations.h"
17
#include "mozilla/dom/LoadURIOptionsBinding.h"
18
#include "mozilla/dom/LocationBase.h"
19
#include "mozilla/dom/MaybeDiscarded.h"
20
#include "mozilla/dom/FeaturePolicyUtils.h"
21
#include "mozilla/dom/SessionStorageManager.h"
22
#include "mozilla/dom/UserActivation.h"
23
#include "mozilla/dom/SyncedContext.h"
24
#include "nsCOMPtr.h"
25
#include "nsCycleCollectionParticipant.h"
26
#include "nsID.h"
27
#include "nsIDocShell.h"
28
#include "nsString.h"
29
#include "nsTArray.h"
30
#include "nsWrapperCache.h"
31
#include "nsILoadInfo.h"
32
33
class nsDocShellLoadState;
34
class nsGlobalWindowOuter;
35
class nsILoadInfo;
36
class nsIPrincipal;
37
class nsOuterWindowProxy;
38
class PickleIterator;
39
40
namespace IPC {
41
class Message;
42
} // namespace IPC
43
44
namespace mozilla {
45
46
class ErrorResult;
47
class LogModule;
48
49
namespace ipc {
50
class IProtocol;
51
52
template <typename T>
53
struct IPDLParamTraits;
54
} // namespace ipc
55
56
namespace dom {
57
class BrowsingContent;
58
class BrowsingContextGroup;
59
class CanonicalBrowsingContext;
60
class ContentParent;
61
class Element;
62
template <typename>
63
struct Nullable;
64
template <typename T>
65
class Sequence;
66
class StructuredCloneHolder;
67
class WindowContext;
68
struct WindowPostMessageOptions;
69
class WindowProxyHolder;
70
71
// Fields are, by default, settable by any process and readable by any process.
72
// Racy sets will be resolved as-if they occurred in the order the parent
73
// process finds out about them.
74
// This defines the default do-nothing implementations for DidSetXxxx()
75
// and MaySetXxxxx() for all the fields. See below for descriptions
76
// of what these do if overridden.
77
#define MOZ_EACH_BC_FIELD(FIELD) \
78
FIELD(Name, nsString) \
79
FIELD(Closed, bool) \
80
FIELD(IsActive, bool) \
81
FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \
82
FIELD(OpenerPolicy, nsILoadInfo::CrossOriginOpenerPolicy) \
83
/* Current opener for the BrowsingContext. Weak reference */ \
84
FIELD(OpenerId, uint64_t) \
85
FIELD(OnePermittedSandboxedNavigatorId, uint64_t) \
86
/* WindowID of the inner window which embeds this BC */ \
87
FIELD(EmbedderInnerWindowId, uint64_t) \
88
FIELD(CurrentInnerWindowId, uint64_t) \
89
FIELD(HadOriginalOpener, bool) \
90
FIELD(IsPopupSpam, bool) \
91
/* Controls whether the BrowsingContext is currently considered to be \
92
* activated by a gesture */ \
93
FIELD(UserActivationState, UserActivation::State) \
94
/* Hold the audio muted state and should be used on top level browsing \
95
* contexts only */ \
96
FIELD(Muted, bool) \
97
FIELD(FeaturePolicy, RefPtr<mozilla::dom::FeaturePolicy>) \
98
/* See nsSandboxFlags.h for the possible flags. */ \
99
FIELD(SandboxFlags, uint32_t) \
100
FIELD(HistoryID, nsID) \
101
FIELD(InRDMPane, bool) \
102
FIELD(Loading, bool) \
103
FIELD(AncestorLoading, bool) \
104
FIELD(AllowPlugins, bool) \
105
FIELD(AllowContentRetargeting, bool) \
106
FIELD(AllowContentRetargetingOnChildren, bool) \
107
/* These field are used to store the states of autoplay media request on \
108
* GeckoView only, and it would only be modified on the top level browsing \
109
* context. */ \
110
FIELD(GVAudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
111
FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
112
/* ScreenOrientation-related APIs */ \
113
FIELD(CurrentOrientationAngle, float) \
114
FIELD(CurrentOrientationType, mozilla::dom::OrientationType) \
115
FIELD(UserAgentOverride, nsString) \
116
FIELD(EmbedderElementType, Maybe<nsString>) \
117
FIELD(MessageManagerGroup, nsString)
118
119
// BrowsingContext, in this context, is the cross process replicated
120
// environment in which information about documents is stored. In
121
// particular the tree structure of nested browsing contexts is
122
// represented by the tree of BrowsingContexts.
123
//
124
// The tree of BrowsingContexts is created in step with its
125
// corresponding nsDocShell, and when nsDocShells are connected
126
// through a parent/child relationship, so are BrowsingContexts. The
127
// major difference is that BrowsingContexts are replicated (synced)
128
// to the parent process, making it possible to traverse the
129
// BrowsingContext tree for a tab, in both the parent and the child
130
// process.
131
//
132
// Trees of BrowsingContexts should only ever contain nodes of the
133
// same BrowsingContext::Type. This is enforced by asserts in the
134
// BrowsingContext::Create* methods.
135
class BrowsingContext : public nsISupports, public nsWrapperCache {
136
MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD)
137
138
public:
139
enum class Type { Chrome, Content };
140
141
using Children = nsTArray<RefPtr<BrowsingContext>>;
142
143
static void Init();
144
static LogModule* GetLog();
145
static void CleanupContexts(uint64_t aProcessId);
146
147
// Look up a BrowsingContext in the current process by ID.
148
static already_AddRefed<BrowsingContext> Get(uint64_t aId);
149
static already_AddRefed<BrowsingContext> Get(GlobalObject&, uint64_t aId) {
150
return Get(aId);
151
}
152
153
static already_AddRefed<BrowsingContext> GetFromWindow(
154
WindowProxyHolder& aProxy);
155
static already_AddRefed<BrowsingContext> GetFromWindow(
156
GlobalObject&, WindowProxyHolder& aProxy) {
157
return GetFromWindow(aProxy);
158
}
159
160
// Create a brand-new BrowsingContext object.
161
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
162
BrowsingContext* aOpener,
163
const nsAString& aName,
164
Type aType);
165
166
// Same as the above, but does not immediately attach the browsing context.
167
// `EnsureAttached()` must be called before the BrowsingContext is used for a
168
// DocShell, BrowserParent, or BrowserBridgeChild.
169
static already_AddRefed<BrowsingContext> CreateDetached(
170
BrowsingContext* aParent, BrowsingContext* aOpener,
171
const nsAString& aName, Type aType);
172
173
// Same as Create, but for a BrowsingContext which does not belong to a
174
// visible window, and will always be detached by the process that created it.
175
// In contrast, any top-level BrowsingContext created in a content process
176
// using Create() is assumed to belong to a <browser> element in the parent
177
// process, which will be responsible for detaching it.
178
static already_AddRefed<BrowsingContext> CreateWindowless(
179
BrowsingContext* aParent, BrowsingContext* aOpener,
180
const nsAString& aName, Type aType);
181
182
void EnsureAttached();
183
184
bool EverAttached() const { return mEverAttached; }
185
186
// Cast this object to a canonical browsing context, and return it.
187
CanonicalBrowsingContext* Canonical();
188
189
// Is the most recent Document in this BrowsingContext loaded within this
190
// process? This may be true with a null mDocShell after the Window has been
191
// closed.
192
bool IsInProcess() const { return mIsInProcess; }
193
194
// Has this BrowsingContext been discarded. A discarded browsing context has
195
// been destroyed, and may not be available on the other side of an IPC
196
// message.
197
bool IsDiscarded() const { return mIsDiscarded; }
198
199
bool Windowless() const { return mWindowless; }
200
void SetWindowless();
201
202
// Get the DocShell for this BrowsingContext if it is in-process, or
203
// null if it's not.
204
nsIDocShell* GetDocShell() const { return mDocShell; }
205
void SetDocShell(nsIDocShell* aDocShell);
206
void ClearDocShell() { mDocShell = nullptr; }
207
208
// This cleans up remote outer window proxies that might have been left behind
209
// when the browsing context went from being remote to local. It does this by
210
// turning them into cross-compartment wrappers to aOuter. If there is already
211
// a remote proxy in the compartment of aOuter, then aOuter will get swapped
212
// to it and the value of aOuter will be set to the object that used to be the
213
// remote proxy and is now an OuterWindowProxy.
214
void CleanUpDanglingRemoteOuterWindowProxies(
215
JSContext* aCx, JS::MutableHandle<JSObject*> aOuter);
216
217
// Get the embedder element for this BrowsingContext if the embedder is
218
// in-process, or null if it's not.
219
Element* GetEmbedderElement() const { return mEmbedderElement; }
220
void SetEmbedderElement(Element* aEmbedder);
221
222
// Called after the BrowingContext has been embedded in a FrameLoader. This
223
// happens after `SetEmbedderElement` is called on the BrowsingContext and
224
// after the BrowsingContext has been set on the FrameLoader.
225
void Embed();
226
227
// Get the outer window object for this BrowsingContext if it is in-process
228
// and still has a docshell, or null otherwise.
229
nsPIDOMWindowOuter* GetDOMWindow() const {
230
return mDocShell ? mDocShell->GetWindow() : nullptr;
231
}
232
233
// Attach the current BrowsingContext to its parent, in both the child and the
234
// parent process. BrowsingContext objects are created attached by default, so
235
// this method need only be called when restoring cached BrowsingContext
236
// objects.
237
void Attach(bool aFromIPC = false);
238
239
// Detach the current BrowsingContext from its parent, in both the
240
// child and the parent process.
241
void Detach(bool aFromIPC = false);
242
243
// Prepare this BrowsingContext to leave the current process.
244
void PrepareForProcessChange();
245
246
// Remove all children from the current BrowsingContext and cache
247
// them to allow them to be attached again.
248
void CacheChildren(bool aFromIPC = false);
249
250
// Restore cached browsing contexts.
251
void RestoreChildren(Children&& aChildren, bool aFromIPC = false);
252
253
// Triggers a load in the process which currently owns this BrowsingContext.
254
// aAccessor is the context which initiated the load, and may be null only for
255
// in-process BrowsingContexts.
256
nsresult LoadURI(BrowsingContext* aAccessor, nsDocShellLoadState* aLoadState,
257
bool aSetNavigating = false);
258
259
nsresult InternalLoad(BrowsingContext* aAccessor,
260
nsDocShellLoadState* aLoadState,
261
nsIDocShell** aDocShell, nsIRequest** aRequest);
262
263
void DisplayLoadError(const nsAString& aURI);
264
265
// Determine if the current BrowsingContext was 'cached' by the logic in
266
// CacheChildren.
267
bool IsCached();
268
269
// Check that this browsing context is targetable for navigations (i.e. that
270
// it is neither closed, cached, nor discarded).
271
bool IsTargetable();
272
273
const nsString& Name() const { return GetName(); }
274
void GetName(nsAString& aName) { aName = GetName(); }
275
bool NameEquals(const nsAString& aName) { return GetName().Equals(aName); }
276
277
Type GetType() const { return mType; }
278
bool IsContent() const { return mType == Type::Content; }
279
bool IsChrome() const { return !IsContent(); }
280
281
bool IsTop() const { return !GetParent(); }
282
283
bool IsTopContent() const { return IsContent() && !GetParent(); }
284
285
bool IsContentSubframe() const { return IsContent() && GetParent(); }
286
uint64_t Id() const { return mBrowsingContextId; }
287
288
BrowsingContext* GetParent() const {
289
MOZ_ASSERT_IF(mParent, mParent->mType == mType);
290
return mParent;
291
}
292
BrowsingContext* Top();
293
294
already_AddRefed<BrowsingContext> GetOpener() const {
295
RefPtr<BrowsingContext> opener(Get(GetOpenerId()));
296
if (!mIsDiscarded && opener && !opener->mIsDiscarded) {
297
MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
298
return opener.forget();
299
}
300
return nullptr;
301
}
302
void SetOpener(BrowsingContext* aOpener) {
303
MOZ_DIAGNOSTIC_ASSERT(!aOpener || aOpener->Group() == Group());
304
MOZ_DIAGNOSTIC_ASSERT(!aOpener || aOpener->mType == mType);
305
SetOpenerId(aOpener ? aOpener->Id() : 0);
306
}
307
308
bool HasOpener() const;
309
310
bool HadOriginalOpener() const { return GetHadOriginalOpener(); }
311
312
// Returns true if the browsing context and top context are same origin
313
bool SameOriginWithTop();
314
315
/**
316
* When a new browsing context is opened by a sandboxed document, it needs to
317
* keep track of the browsing context that opened it, so that it can be
318
* navigated by it. This is the "one permitted sandboxed navigator".
319
*/
320
already_AddRefed<BrowsingContext> GetOnePermittedSandboxedNavigator() const {
321
return Get(GetOnePermittedSandboxedNavigatorId());
322
}
323
void SetOnePermittedSandboxedNavigator(BrowsingContext* aNavigator) {
324
if (GetOnePermittedSandboxedNavigatorId()) {
325
MOZ_ASSERT(false,
326
"One Permitted Sandboxed Navigator should only be set once.");
327
} else {
328
SetOnePermittedSandboxedNavigatorId(aNavigator ? aNavigator->Id() : 0);
329
}
330
}
331
332
uint32_t SandboxFlags() { return GetSandboxFlags(); }
333
334
void GetChildren(Children& aChildren);
335
336
void GetWindowContexts(nsTArray<RefPtr<WindowContext>>& aWindows);
337
338
void RegisterWindowContext(WindowContext* aWindow);
339
void UnregisterWindowContext(WindowContext* aWindow);
340
WindowContext* GetCurrentWindowContext() const {
341
return mCurrentWindowContext;
342
}
343
344
BrowsingContextGroup* Group() { return mGroup; }
345
346
bool InRDMPane() const { return GetInRDMPane(); }
347
348
bool IsLoading();
349
350
// ScreenOrientation related APIs
351
void SetCurrentOrientation(OrientationType aType, float aAngle) {
352
SetCurrentOrientationType(aType);
353
SetCurrentOrientationAngle(aAngle);
354
}
355
356
void SetRDMPaneOrientation(OrientationType aType, float aAngle) {
357
if (InRDMPane()) {
358
SetCurrentOrientation(aType, aAngle);
359
}
360
}
361
362
void SetAllowContentRetargeting(bool aAllowContentRetargeting);
363
364
// Using the rules for choosing a browsing context we try to find
365
// the browsing context with the given name in the set of
366
// transitively reachable browsing contexts. Performs access control
367
// checks with regard to this.
368
// See
370
//
371
// BrowsingContext::FindWithName(const nsAString&) is equivalent to
372
// calling nsIDocShellTreeItem::FindItemWithName(aName, nullptr,
373
// nullptr, false, <return value>).
374
BrowsingContext* FindWithName(const nsAString& aName,
375
bool aUseEntryGlobalForAccessCheck = true);
376
377
// Find a browsing context in this context's list of
378
// children. Doesn't consider the special names, '_self', '_parent',
379
// '_top', or '_blank'. Performs access control checks with regard to
380
// 'this'.
381
BrowsingContext* FindChildWithName(const nsAString& aName,
382
BrowsingContext& aRequestingContext);
383
384
// Find a browsing context in the subtree rooted at 'this' Doesn't
385
// consider the special names, '_self', '_parent', '_top', or
386
// '_blank'. Performs access control checks with regard to
387
// 'aRequestingContext'.
388
BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
389
BrowsingContext& aRequestingContext);
390
391
nsISupports* GetParentObject() const;
392
JSObject* WrapObject(JSContext* aCx,
393
JS::Handle<JSObject*> aGivenProto) override;
394
395
// This function would be called when its corresponding document is activated
396
// by user gesture, and we would set the flag in the top level browsing
397
// context.
398
void NotifyUserGestureActivation();
399
400
// This function would be called when we want to reset the user gesture
401
// activation flag of the top level browsing context.
402
void NotifyResetUserGestureActivation();
403
404
// Return true if its corresponding document has been activated by user
405
// gesture.
406
bool HasBeenUserGestureActivated();
407
408
// Return true if its corresponding document has transient user gesture
409
// activation and the transient user gesture activation haven't yet timed
410
// out.
411
bool HasValidTransientUserGestureActivation();
412
413
// Return true if the corresponding document has valid transient user gesture
414
// activation and the transient user gesture activation had been consumed
415
// successfully.
416
bool ConsumeTransientUserGestureActivation();
417
418
// Return the window proxy object that corresponds to this browsing context.
419
inline JSObject* GetWindowProxy() const { return mWindowProxy; }
420
inline JSObject* GetUnbarrieredWindowProxy() const {
421
return mWindowProxy.unbarrieredGet();
422
}
423
424
// Set the window proxy object that corresponds to this browsing context.
425
void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) {
426
mWindowProxy = aWindowProxy;
427
}
428
429
Nullable<WindowProxyHolder> GetWindow();
430
431
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext)
432
433
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
434
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BrowsingContext)
435
436
const Children& GetChildren() { return mChildren; }
437
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
438
return mWindowContexts;
439
}
440
441
// Perform a pre-order walk of this BrowsingContext subtree.
442
void PreOrderWalk(const std::function<void(BrowsingContext*)>& aCallback) {
443
aCallback(this);
444
for (auto& child : GetChildren()) {
445
child->PreOrderWalk(aCallback);
446
}
447
}
448
449
// Perform an post-order walk of this BrowsingContext subtree.
450
void PostOrderWalk(const std::function<void(BrowsingContext*)>& aCallback) {
451
for (auto& child : GetChildren()) {
452
child->PostOrderWalk(aCallback);
453
}
454
455
aCallback(this);
456
}
457
458
// Window APIs that are cross-origin-accessible (from the HTML spec).
459
WindowProxyHolder Window();
460
BrowsingContext* Self() { return this; }
461
void Location(JSContext* aCx, JS::MutableHandle<JSObject*> aLocation,
462
ErrorResult& aError);
463
void Close(CallerType aCallerType, ErrorResult& aError);
464
bool GetClosed(ErrorResult&) { return GetClosed(); }
465
void Focus(CallerType aCallerType, ErrorResult& aError);
466
void Blur(ErrorResult& aError);
467
WindowProxyHolder GetFrames(ErrorResult& aError);
468
int32_t Length() const { return mChildren.Length(); }
469
Nullable<WindowProxyHolder> GetTop(ErrorResult& aError);
470
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aOpener,
471
ErrorResult& aError) const;
472
Nullable<WindowProxyHolder> GetParent(ErrorResult& aError);
473
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
474
const nsAString& aTargetOrigin,
475
const Sequence<JSObject*>& aTransfer,
476
nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
477
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
478
const WindowPostMessageOptions& aOptions,
479
nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
480
481
void GetCustomUserAgent(nsString& aUserAgent) {
482
aUserAgent = Top()->GetUserAgentOverride();
483
}
484
void SetCustomUserAgent(const nsAString& aUserAgent);
485
486
JSObject* WrapObject(JSContext* aCx);
487
488
static JSObject* ReadStructuredClone(JSContext* aCx,
489
JSStructuredCloneReader* aReader,
490
StructuredCloneHolder* aHolder);
491
bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
492
StructuredCloneHolder* aHolder);
493
494
void StartDelayedAutoplayMediaComponents();
495
496
void ResetGVAutoplayRequestStatus();
497
498
/**
499
// Every BrowsingContext has a set of GetXxxx() and SetXxxxx() methods for
500
// all the fields defined in mozilla/dom/BrowsingContextFieldList.h.
501
// They all have optional DidSetXxxx() and MaySetXxxx() methods, which
502
// have default inherited do-nothing implementations, but we can override
503
// here. DidSetXxxx() is used to run code in any process that sees the
504
// the value updated (note: even if the value itself didn't change).
505
// MaySetXxxx() is used to verify that the setting is allowed, and will
506
// assert if it fails in Debug builds.
507
* Information required to initialize a BrowsingContext in another process.
508
* This object may be serialized over IPC.
509
*/
510
struct IPCInitializer {
511
uint64_t mId;
512
513
// IDs are used for Parent and Opener to allow for this object to be
514
// deserialized before other BrowsingContext in the BrowsingContextGroup
515
// have been initialized.
516
uint64_t mParentId;
517
already_AddRefed<BrowsingContext> GetParent();
518
already_AddRefed<BrowsingContext> GetOpener();
519
520
uint64_t GetOpenerId() const { return mozilla::Get<IDX_OpenerId>(mFields); }
521
522
bool mCached;
523
bool mWindowless;
524
525
FieldTuple mFields;
526
};
527
528
// Create an IPCInitializer object for this BrowsingContext.
529
IPCInitializer GetIPCInitializer();
530
531
// Create a BrowsingContext object from over IPC.
532
static already_AddRefed<BrowsingContext> CreateFromIPC(
533
IPCInitializer&& aInitializer, BrowsingContextGroup* aGroup,
534
ContentParent* aOriginProcess);
535
536
// Performs access control to check that 'this' can access 'aTarget'.
537
bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
538
539
// The runnable will be called once there is idle time, or the top level
540
// page has been loaded or if a timeout has fired.
541
// Must be called only on the top level BrowsingContext.
542
void AddDeprioritizedLoadRunner(nsIRunnable* aRunner);
543
544
RefPtr<SessionStorageManager> GetSessionStorageManager();
545
546
bool PendingInitialization() const { return mPendingInitialization; };
547
void SetPendingInitialization(bool aVal) { mPendingInitialization = aVal; };
548
549
protected:
550
virtual ~BrowsingContext();
551
BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup,
552
uint64_t aBrowsingContextId, Type aType,
553
FieldTuple&& aFields);
554
555
private:
556
// Find the special browsing context if aName is '_self', '_parent',
557
// '_top', but not '_blank'. The latter is handled in FindWithName
558
BrowsingContext* FindWithSpecialName(const nsAString& aName,
559
BrowsingContext& aRequestingContext);
560
561
friend class ::nsOuterWindowProxy;
562
friend class ::nsGlobalWindowOuter;
563
friend class WindowContext;
564
565
// Update the window proxy object that corresponds to this browsing context.
566
// This should be called from the window proxy object's objectMoved hook, if
567
// the object mWindowProxy points to was moved by the JS GC.
568
void UpdateWindowProxy(JSObject* obj, JSObject* old) {
569
if (mWindowProxy) {
570
MOZ_ASSERT(mWindowProxy == old);
571
mWindowProxy = obj;
572
}
573
}
574
// Clear the window proxy object that corresponds to this browsing context.
575
// This should be called if the window proxy object is finalized, or it can't
576
// reach its browsing context anymore.
577
void ClearWindowProxy() { mWindowProxy = nullptr; }
578
579
friend class Location;
580
friend class RemoteLocationProxy;
581
/**
582
* LocationProxy is the class for the native object stored as a private in a
583
* RemoteLocationProxy proxy representing a Location object in a different
584
* process. It forwards all operations to its BrowsingContext and aggregates
585
* its refcount to that BrowsingContext.
586
*/
587
class LocationProxy final : public LocationBase {
588
public:
589
MozExternalRefCountType AddRef() { return GetBrowsingContext()->AddRef(); }
590
MozExternalRefCountType Release() {
591
return GetBrowsingContext()->Release();
592
}
593
594
protected:
595
friend class RemoteLocationProxy;
596
BrowsingContext* GetBrowsingContext() override {
597
return reinterpret_cast<BrowsingContext*>(
598
uintptr_t(this) - offsetof(BrowsingContext, mLocation));
599
}
600
601
already_AddRefed<nsIDocShell> GetDocShell() override { return nullptr; }
602
};
603
604
// Send a given `BaseTransaction` object to the correct remote.
605
void SendCommitTransaction(ContentParent* aParent,
606
const BaseTransaction& aTxn, uint64_t aEpoch);
607
void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
608
uint64_t aEpoch);
609
610
// Ensure that opener is in the same BrowsingContextGroup.
611
bool CanSet(FieldIndex<IDX_OpenerId>, const uint64_t& aValue,
612
ContentParent* aSource) {
613
if (aValue != 0) {
614
RefPtr<BrowsingContext> opener = Get(aValue);
615
return opener && opener->Group() == Group();
616
}
617
return true;
618
}
619
620
void DidSet(FieldIndex<IDX_UserActivationState>);
621
622
// Ensure that we only set the flag on the top level browsingContext.
623
// And then, we do a pre-order walk in the tree to refresh the
624
// volume of all media elements.
625
void DidSet(FieldIndex<IDX_Muted>);
626
627
bool CanSet(FieldIndex<IDX_EmbedderInnerWindowId>, const uint64_t& aValue,
628
ContentParent* aSource);
629
630
bool CanSet(FieldIndex<IDX_CurrentInnerWindowId>, const uint64_t& aValue,
631
ContentParent* aSource);
632
633
void DidSet(FieldIndex<IDX_CurrentInnerWindowId>);
634
635
bool CanSet(FieldIndex<IDX_IsPopupSpam>, const bool& aValue,
636
ContentParent* aSource);
637
638
void DidSet(FieldIndex<IDX_IsPopupSpam>);
639
640
void DidSet(FieldIndex<IDX_GVAudibleAutoplayRequestStatus>);
641
void DidSet(FieldIndex<IDX_GVInaudibleAutoplayRequestStatus>);
642
643
void DidSet(FieldIndex<IDX_Loading>);
644
645
void DidSet(FieldIndex<IDX_AncestorLoading>);
646
647
void DidSet(FieldIndex<IDX_UserAgentOverride>);
648
bool CanSet(FieldIndex<IDX_UserAgentOverride>, const nsString& aUserAgent,
649
ContentParent* aSource);
650
651
bool CanSet(FieldIndex<IDX_EmbedderElementType>,
652
const Maybe<nsString>& aInitiatorType, ContentParent* aSource);
653
654
bool CanSet(FieldIndex<IDX_MessageManagerGroup>,
655
const nsString& aMessageManagerGroup, ContentParent* aSource);
656
657
bool CanSet(FieldIndex<IDX_AllowContentRetargeting>,
658
const bool& aAllowContentRetargeting, ContentParent* aSource);
659
bool CanSet(FieldIndex<IDX_AllowContentRetargetingOnChildren>,
660
const bool& aAllowContentRetargetingOnChildren,
661
ContentParent* aSource);
662
bool CanSet(FieldIndex<IDX_AllowPlugins>, const bool& aAllowPlugins,
663
ContentParent* aSource);
664
665
template <size_t I, typename T>
666
bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
667
return true;
668
}
669
670
template <size_t I>
671
void DidSet(FieldIndex<I>) {}
672
673
// True if the process attemping to set field is the same as the owning
674
// process.
675
bool CheckOnlyOwningProcessCanSet(ContentParent* aSource);
676
677
// True if the process attempting to set field is the same as the embedder's
678
// process.
679
bool CheckOnlyEmbedderCanSet(ContentParent* aSource);
680
681
// Type of BrowsingContent
682
const Type mType;
683
684
// Unique id identifying BrowsingContext
685
const uint64_t mBrowsingContextId;
686
687
RefPtr<BrowsingContextGroup> mGroup;
688
RefPtr<BrowsingContext> mParent;
689
// Note: BrowsingContext_Binding::ClearCachedChildrenValue must be called any
690
// time this array is mutated to keep the JS-exposed reflection in sync.
691
Children mChildren;
692
nsCOMPtr<nsIDocShell> mDocShell;
693
694
RefPtr<Element> mEmbedderElement;
695
696
nsTArray<RefPtr<WindowContext>> mWindowContexts;
697
RefPtr<WindowContext> mCurrentWindowContext;
698
699
// This is not a strong reference, but using a JS::Heap for that should be
700
// fine. The JSObject stored in here should be a proxy with a
701
// nsOuterWindowProxy handler, which will update the pointer from its
702
// objectMoved hook and clear it from its finalize hook.
703
JS::Heap<JSObject*> mWindowProxy;
704
LocationProxy mLocation;
705
706
// True if Attach() has been called on this BrowsingContext already.
707
bool mEverAttached : 1;
708
709
// Is the most recent Document in this BrowsingContext loaded within this
710
// process? This may be true with a null mDocShell after the Window has been
711
// closed.
712
bool mIsInProcess : 1;
713
714
// Has this browsing context been discarded? BrowsingContexts should
715
// only be discarded once.
716
bool mIsDiscarded : 1;
717
718
// True if this BrowsingContext has no associated visible window, and is owned
719
// by whichever process created it, even if top-level.
720
bool mWindowless : 1;
721
722
// This is true if the BrowsingContext was out of process, but is now in
723
// process, and might have remote window proxies that need to be cleaned up.
724
bool mDanglingRemoteOuterProxies : 1;
725
726
// If true, the docShell has not been fully initialized, and may not be used
727
// as the target of a load.
728
bool mPendingInitialization : 1;
729
730
// True if this BrowsingContext has been embedded in a element in this
731
// process.
732
bool mEmbeddedByThisProcess : 1;
733
734
// The start time of user gesture, this is only available if the browsing
735
// context is in process.
736
TimeStamp mUserGestureStart;
737
738
class DeprioritizedLoadRunner
739
: public mozilla::Runnable,
740
public mozilla::LinkedListElement<DeprioritizedLoadRunner> {
741
public:
742
explicit DeprioritizedLoadRunner(nsIRunnable* aInner)
743
: Runnable("DeprioritizedLoadRunner"), mInner(aInner) {}
744
745
NS_IMETHOD Run() override {
746
if (mInner) {
747
RefPtr<nsIRunnable> inner = std::move(mInner);
748
inner->Run();
749
}
750
751
return NS_OK;
752
}
753
754
private:
755
RefPtr<nsIRunnable> mInner;
756
};
757
758
mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
759
760
RefPtr<dom::SessionStorageManager> mSessionStorageManager;
761
};
762
763
/**
764
* Gets a WindowProxy object for a BrowsingContext that lives in a different
765
* process (creating the object if it doesn't already exist). The WindowProxy
766
* object will be in the compartment that aCx is currently in. This should only
767
* be called if aContext doesn't hold a docshell, otherwise the BrowsingContext
768
* lives in this process, and a same-process WindowProxy should be used (see
769
* nsGlobalWindowOuter). This should only be called by bindings code, ToJSValue
770
* is the right API to get a WindowProxy for a BrowsingContext.
771
*
772
* If aTransplantTo is non-null, then the WindowProxy object will eventually be
773
* transplanted onto it. Therefore it should be used as the value in the remote
774
* proxy map.
775
*/
776
extern bool GetRemoteOuterWindowProxy(JSContext* aCx, BrowsingContext* aContext,
777
JS::Handle<JSObject*> aTransplantTo,
778
JS::MutableHandle<JSObject*> aRetVal);
779
780
using BrowsingContextTransaction = BrowsingContext::BaseTransaction;
781
using BrowsingContextInitializer = BrowsingContext::IPCInitializer;
782
using BrowsingContextChildren = BrowsingContext::Children;
783
using MaybeDiscardedBrowsingContext = MaybeDiscarded<BrowsingContext>;
784
785
// Specialize the transaction object for every translation unit it's used in.
786
extern template class syncedcontext::Transaction<BrowsingContext>;
787
788
} // namespace dom
789
790
// Allow sending BrowsingContext objects over IPC.
791
namespace ipc {
792
template <>
793
struct IPDLParamTraits<dom::MaybeDiscarded<dom::BrowsingContext>> {
794
static void Write(IPC::Message* aMsg, IProtocol* aActor,
795
const dom::MaybeDiscarded<dom::BrowsingContext>& aParam);
796
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
797
IProtocol* aActor,
798
dom::MaybeDiscarded<dom::BrowsingContext>* aResult);
799
};
800
801
template <>
802
struct IPDLParamTraits<dom::BrowsingContext::IPCInitializer> {
803
static void Write(IPC::Message* aMessage, IProtocol* aActor,
804
const dom::BrowsingContext::IPCInitializer& aInitializer);
805
806
static bool Read(const IPC::Message* aMessage, PickleIterator* aIterator,
807
IProtocol* aActor,
808
dom::BrowsingContext::IPCInitializer* aInitializer);
809
};
810
} // namespace ipc
811
} // namespace mozilla
812
813
#endif // !defined(mozilla_dom_BrowsingContext_h)