summaryrefslogtreecommitdiffstats
path: root/dom/ipc/WindowGlobalChild.h
blob: 107b3f471d2df5bed0ccd38690bb84b306a33d28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_WindowGlobalChild_h
#define mozilla_dom_WindowGlobalChild_h

#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/PWindowGlobalChild.h"
#include "nsRefPtrHashtable.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowGlobalActor.h"

class nsGlobalWindowInner;
class nsDocShell;

namespace mozilla::dom {

class BrowsingContext;
class FeaturePolicy;
class WindowContext;
class WindowGlobalParent;
class JSWindowActorChild;
class JSActorMessageMeta;
class BrowserChild;

/**
 * Actor for a single nsGlobalWindowInner. This actor is used to communicate
 * information to the parent process asynchronously.
 */
class WindowGlobalChild final : public WindowGlobalActor,
                                public nsWrapperCache,
                                public PWindowGlobalChild,
                                public SupportsWeakPtr {
  friend class PWindowGlobalChild;

 public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowGlobalChild)

  static already_AddRefed<WindowGlobalChild> GetByInnerWindowId(
      uint64_t aInnerWindowId);

  static already_AddRefed<WindowGlobalChild> GetByInnerWindowId(
      const GlobalObject& aGlobal, uint64_t aInnerWindowId) {
    return GetByInnerWindowId(aInnerWindowId);
  }

  dom::BrowsingContext* BrowsingContext() override;
  dom::WindowContext* WindowContext() const { return mWindowContext; }
  nsGlobalWindowInner* GetWindowGlobal() const { return mWindowGlobal; }

  // Has this actor been shut down
  bool IsClosed() { return !CanSend(); }
  void Destroy();

  // Check if this actor is managed by PInProcess, as-in the document is loaded
  // in the chrome process.
  bool IsInProcess() { return XRE_IsParentProcess(); }

  nsIURI* GetDocumentURI() override { return mDocumentURI; }
  void SetDocumentURI(nsIURI* aDocumentURI);
  // See the corresponding comment for `UpdateDocumentPrincipal` in
  // PWindowGlobal on why and when this is allowed
  void SetDocumentPrincipal(nsIPrincipal* aNewDocumentPrincipal,
                            nsIPrincipal* aNewDocumentStoragePrincipal);

  nsIPrincipal* DocumentPrincipal() { return mDocumentPrincipal; }

  // The Window ID for this WindowGlobal
  uint64_t InnerWindowId();
  uint64_t OuterWindowId();

  uint64_t ContentParentId();

  int64_t BeforeUnloadListeners() { return mBeforeUnloadListeners; }
  void BeforeUnloadAdded();
  void BeforeUnloadRemoved();

  bool IsCurrentGlobal();

  bool IsProcessRoot();

  // Get the other side of this actor if it is an in-process actor. Returns
  // |nullptr| if the actor has been torn down, or is not in-process.
  already_AddRefed<WindowGlobalParent> GetParentActor();

  // Get this actor's manager if it is not an in-process actor. Returns
  // |nullptr| if the actor has been torn down, or is in-process.
  already_AddRefed<BrowserChild> GetBrowserChild();

  // Get a JS actor object by name.
  already_AddRefed<JSWindowActorChild> GetActor(JSContext* aCx,
                                                const nsACString& aName,
                                                ErrorResult& aRv);
  already_AddRefed<JSWindowActorChild> GetExistingActor(
      const nsACString& aName);

  // Create and initialize the WindowGlobalChild object.
  static already_AddRefed<WindowGlobalChild> Create(
      nsGlobalWindowInner* aWindow);
  static already_AddRefed<WindowGlobalChild> CreateDisconnected(
      const WindowGlobalInit& aInit);

  void Init();

  void InitWindowGlobal(nsGlobalWindowInner* aWindow);

  // Called when a new document is loaded in this WindowGlobalChild.
  void OnNewDocument(Document* aNewDocument);

  // Returns true if this WindowGlobal is same-origin with the given
  // WindowContext. Out-of-process WindowContexts are supported, and are assumed
  // to be cross-origin.
  //
  // The given WindowContext must be in the same BrowsingContextGroup as this
  // window global.
  bool IsSameOriginWith(const dom::WindowContext* aOther) const;

  bool SameOriginWithTop();

  // Returns `true` if this WindowGlobal is allowed to navigate the given
  // BrowsingContext. BrowsingContexts which are currently out-of-process are
  // supported, and assumed to be cross-origin.
  //
  // The given BrowsingContext must be in the same BrowsingContextGroup as this
  // WindowGlobal.
  bool CanNavigate(dom::BrowsingContext* aTarget, bool aConsiderOpener = true);

  // Using the rules for choosing a browsing context we try to find
  // the browsing context with the given name in the set of
  // transitively reachable browsing contexts. Performs access control
  // checks with regard to this.
  // See
  // https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name.
  dom::BrowsingContext* FindBrowsingContextWithName(
      const nsAString& aName, bool aUseEntryGlobalForAccessCheck = true);

  nsISupports* GetParentObject();
  JSObject* WrapObject(JSContext* aCx,
                       JS::Handle<JSObject*> aGivenProto) override;

  dom::FeaturePolicy* GetContainerFeaturePolicy() const {
    return mContainerFeaturePolicy;
  }

  void UnblockBFCacheFor(BFCacheStatus aStatus);
  void BlockBFCacheFor(BFCacheStatus aStatus);

 protected:
  const nsACString& GetRemoteType() override;

  already_AddRefed<JSActor> InitJSActor(JS::Handle<JSObject*> aMaybeActor,
                                        const nsACString& aName,
                                        ErrorResult& aRv) override;
  mozilla::ipc::IProtocol* AsNativeActor() override { return this; }

  // IPC messages
  mozilla::ipc::IPCResult RecvRawMessage(
      const JSActorMessageMeta& aMeta, const Maybe<ClonedMessageData>& aData,
      const Maybe<ClonedMessageData>& aStack);

  mozilla::ipc::IPCResult RecvMakeFrameLocal(
      const MaybeDiscarded<dom::BrowsingContext>& aFrameContext,
      uint64_t aPendingSwitchId);

  mozilla::ipc::IPCResult RecvMakeFrameRemote(
      const MaybeDiscarded<dom::BrowsingContext>& aFrameContext,
      ManagedEndpoint<PBrowserBridgeChild>&& aEndpoint, const TabId& aTabId,
      const LayersId& aLayersId, MakeFrameRemoteResolver&& aResolve);

  mozilla::ipc::IPCResult RecvDrawSnapshot(const Maybe<IntRect>& aRect,
                                           const float& aScale,
                                           const nscolor& aBackgroundColor,
                                           const uint32_t& aFlags,
                                           DrawSnapshotResolver&& aResolve);

  mozilla::ipc::IPCResult RecvDispatchSecurityPolicyViolation(
      const nsString& aViolationEventJSON);

  mozilla::ipc::IPCResult RecvSaveStorageAccessPermissionGranted();

  mozilla::ipc::IPCResult RecvAddBlockedFrameNodeByClassifier(
      const MaybeDiscardedBrowsingContext& aNode);

  mozilla::ipc::IPCResult RecvResetScalingZoom();

  mozilla::ipc::IPCResult RecvSetContainerFeaturePolicy(
      dom::FeaturePolicy* aContainerFeaturePolicy);

  mozilla::ipc::IPCResult RecvRestoreDocShellState(
      const dom::sessionstore::DocShellRestoreState& aState,
      RestoreDocShellStateResolver&& aResolve);

  // TODO: Use MOZ_CAN_RUN_SCRIPT when it gains IPDL support (bug 1539864)
  MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvRestoreTabContent(
      dom::SessionStoreRestoreData* aData,
      RestoreTabContentResolver&& aResolve);

  mozilla::ipc::IPCResult RecvNotifyPermissionChange(const nsCString& aType,
                                                     uint32_t aPermission);

  virtual void ActorDestroy(ActorDestroyReason aWhy) override;

 private:
  WindowGlobalChild(dom::WindowContext* aWindowContext,
                    nsIPrincipal* aPrincipal, nsIURI* aURI);

  ~WindowGlobalChild();

  RefPtr<nsGlobalWindowInner> mWindowGlobal;
  RefPtr<dom::WindowContext> mWindowContext;
  nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
  RefPtr<dom::FeaturePolicy> mContainerFeaturePolicy;
  nsCOMPtr<nsIURI> mDocumentURI;
  int64_t mBeforeUnloadListeners = 0;
};

}  // namespace mozilla::dom

#endif  // !defined(mozilla_dom_WindowGlobalChild_h)