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
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_ClientSource_h
#define _mozilla_dom_ClientSource_h
#include "mozilla/ResultVariant.h"
#include "mozilla/Variant.h"
#include "mozilla/dom/ClientInfo.h"
#include "mozilla/dom/ClientOpPromise.h"
#include "mozilla/dom/ClientThing.h"
#include "mozilla/dom/ServiceWorkerDescriptor.h"
#ifdef XP_WIN
# undef PostMessage
#endif
class nsIContentSecurityPolicy;
class nsIPolicyContainer;
class nsIDocShell;
class nsIGlobalObject;
class nsISerialEventTarget;
class nsPIDOMWindowInner;
namespace mozilla {
class ErrorResult;
namespace dom {
class ClientControlledArgs;
class ClientFocusArgs;
class ClientGetInfoAndStateArgs;
class ClientManager;
class ClientPostMessageArgs;
class ClientSourceChild;
class ClientSourceConstructorArgs;
class ClientSourceExecutionReadyArgs;
class ClientState;
class ClientWindowState;
class PClientManagerChild;
class WorkerPrivate;
// ClientSource is an RAII style class that is designed to be held via
// a UniquePtr<>. When created ClientSource will register the existence
// of a client in the cross-process ClientManagerService. When the
// ClientSource is destroyed then client entry will be removed. Code
// that represents globals or browsing environments, such as nsGlobalWindow
// or WorkerPrivate, should use ClientManager to create a ClientSource.
class ClientSource final : public ClientThing<ClientSourceChild> {
friend class ClientManager;
NS_DECL_OWNINGTHREAD
RefPtr<ClientManager> mManager;
nsCOMPtr<nsISerialEventTarget> mEventTarget;
Variant<Nothing, RefPtr<nsPIDOMWindowInner>, nsCOMPtr<nsIDocShell>,
WorkerPrivate*>
mOwner;
ClientInfo mClientInfo;
Maybe<ServiceWorkerDescriptor> mController;
Maybe<nsCOMPtr<nsIPrincipal>> mPrincipal;
// Contained a de-duplicated list of ServiceWorker scope strings
// for which this client has called navigator.serviceWorker.register().
// Typically there will be either be zero or one scope strings, but
// there could be more. We keep this list until the client is closed.
AutoTArray<nsCString, 1> mRegisteringScopeList;
void Shutdown();
void ExecutionReady(const ClientSourceExecutionReadyArgs& aArgs);
WorkerPrivate* GetWorkerPrivate() const;
nsIDocShell* GetDocShell() const;
nsIGlobalObject* GetGlobal() const;
Result<bool, ErrorResult> MaybeCreateInitialDocument();
Result<ClientState, ErrorResult> SnapshotWindowState();
// Private methods called by ClientManager
ClientSource(ClientManager* aManager, nsISerialEventTarget* aEventTarget,
const ClientSourceConstructorArgs& aArgs);
void Activate(PClientManagerChild* aActor);
public:
~ClientSource();
nsPIDOMWindowInner* GetInnerWindow() const;
void WorkerExecutionReady(WorkerPrivate* aWorkerPrivate);
nsresult WindowExecutionReady(nsPIDOMWindowInner* aInnerWindow);
nsresult DocShellExecutionReady(nsIDocShell* aDocShell);
void Freeze();
void Thaw();
void EvictFromBFCache();
RefPtr<ClientOpPromise> EvictFromBFCacheOp();
const ClientInfo& Info() const;
// Trigger a synchronous IPC ping to the parent process to confirm that
// the ClientSource actor has been created. This should only be used
// by the WorkerPrivate startup code to deal with a ClientHandle::Control()
// call racing on the main thread. Do not call this in other circumstances!
void WorkerSyncPing(WorkerPrivate* aWorkerPrivate);
// Synchronously mark the ClientSource as controlled by the given service
// worker. This can happen as a result of a remote operation or directly
// by local code. For example, if a client's initial network load is
// intercepted by a controlling service worker then this should be called
// immediately.
//
// Note, there is no way to clear the controlling service worker because
// the specification does not allow that operation.
void SetController(const ServiceWorkerDescriptor& aServiceWorker);
// Mark the ClientSource as controlled using the remote operation arguments.
// This will in turn call SetController().
RefPtr<ClientOpPromise> Control(const ClientControlledArgs& aArgs);
// Inherit the controller from a local parent client. This requires both
// setting our immediate controller field and also updating the parent-side
// data structure.
void InheritController(const ServiceWorkerDescriptor& aServiceWorker);
// Get the ClientSource's current controlling service worker, if one has
// been set.
const Maybe<ServiceWorkerDescriptor>& GetController() const;
// Note that the client has reached DOMContentLoaded. Only applies to window
// clients.
void NoteDOMContentLoaded();
// TODO: Convert Focus() to MOZ_CAN_RUN_SCRIPT
MOZ_CAN_RUN_SCRIPT_BOUNDARY RefPtr<ClientOpPromise> Focus(
const ClientFocusArgs& aArgs);
RefPtr<ClientOpPromise> PostMessage(const ClientPostMessageArgs& aArgs);
RefPtr<ClientOpPromise> GetInfoAndState(
const ClientGetInfoAndStateArgs& aArgs);
Result<ClientState, ErrorResult> SnapshotState();
nsISerialEventTarget* EventTarget() const;
void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP);
void SetPolicyContainer(nsIPolicyContainer* aPolicyContainer);
void SetPolicyContainerArgs(
const mozilla::ipc::PolicyContainerArgs& aPolicyContainer);
const Maybe<mozilla::ipc::PolicyContainerArgs>& GetPolicyContainerArgs();
void SetAgentClusterId(const nsID& aId) {
mClientInfo.SetAgentClusterId(aId);
}
void Traverse(nsCycleCollectionTraversalCallback& aCallback,
const char* aName, uint32_t aFlags);
void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
bool CalledRegisterForServiceWorkerScope(const nsACString& aScope);
nsIPrincipal* GetPrincipal();
};
inline void ImplCycleCollectionUnlink(UniquePtr<ClientSource>& aField) {
aField.reset();
}
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback,
UniquePtr<ClientSource>& aField, const char* aName, uint32_t aFlags) {
if (aField) {
aField->Traverse(aCallback, aName, aFlags);
}
}
} // namespace dom
} // namespace mozilla
#endif // _mozilla_dom_ClientSource_h
|