ClientSource.h (6492B)
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 #ifndef _mozilla_dom_ClientSource_h 7 #define _mozilla_dom_ClientSource_h 8 9 #include "mozilla/ResultVariant.h" 10 #include "mozilla/Variant.h" 11 #include "mozilla/dom/ClientInfo.h" 12 #include "mozilla/dom/ClientOpPromise.h" 13 #include "mozilla/dom/ClientThing.h" 14 #include "mozilla/dom/ServiceWorkerDescriptor.h" 15 16 #ifdef XP_WIN 17 # undef PostMessage 18 #endif 19 20 class nsIContentSecurityPolicy; 21 class nsIPolicyContainer; 22 class nsIDocShell; 23 class nsIGlobalObject; 24 class nsISerialEventTarget; 25 class nsPIDOMWindowInner; 26 27 namespace mozilla { 28 class ErrorResult; 29 30 namespace dom { 31 32 class ClientControlledArgs; 33 class ClientFocusArgs; 34 class ClientGetInfoAndStateArgs; 35 class ClientManager; 36 class ClientPostMessageArgs; 37 class ClientSourceChild; 38 class ClientSourceConstructorArgs; 39 class ClientSourceExecutionReadyArgs; 40 class ClientState; 41 class ClientWindowState; 42 class PClientManagerChild; 43 class WorkerPrivate; 44 45 // ClientSource is an RAII style class that is designed to be held via 46 // a UniquePtr<>. When created ClientSource will register the existence 47 // of a client in the cross-process ClientManagerService. When the 48 // ClientSource is destroyed then client entry will be removed. Code 49 // that represents globals or browsing environments, such as nsGlobalWindow 50 // or WorkerPrivate, should use ClientManager to create a ClientSource. 51 class ClientSource final : public ClientThing<ClientSourceChild> { 52 friend class ClientManager; 53 54 NS_DECL_OWNINGTHREAD 55 56 RefPtr<ClientManager> mManager; 57 nsCOMPtr<nsISerialEventTarget> mEventTarget; 58 59 Variant<Nothing, RefPtr<nsPIDOMWindowInner>, nsCOMPtr<nsIDocShell>, 60 WorkerPrivate*> 61 mOwner; 62 63 ClientInfo mClientInfo; 64 Maybe<ServiceWorkerDescriptor> mController; 65 Maybe<nsCOMPtr<nsIPrincipal>> mPrincipal; 66 67 // Contained a de-duplicated list of ServiceWorker scope strings 68 // for which this client has called navigator.serviceWorker.register(). 69 // Typically there will be either be zero or one scope strings, but 70 // there could be more. We keep this list until the client is closed. 71 AutoTArray<nsCString, 1> mRegisteringScopeList; 72 73 void Shutdown(); 74 75 void ExecutionReady(const ClientSourceExecutionReadyArgs& aArgs); 76 77 WorkerPrivate* GetWorkerPrivate() const; 78 79 nsIDocShell* GetDocShell() const; 80 81 nsIGlobalObject* GetGlobal() const; 82 83 Result<bool, ErrorResult> MaybeCreateInitialDocument(); 84 85 Result<ClientState, ErrorResult> SnapshotWindowState(); 86 87 // Private methods called by ClientManager 88 ClientSource(ClientManager* aManager, nsISerialEventTarget* aEventTarget, 89 const ClientSourceConstructorArgs& aArgs); 90 91 void Activate(PClientManagerChild* aActor); 92 93 public: 94 ~ClientSource(); 95 96 nsPIDOMWindowInner* GetInnerWindow() const; 97 98 void WorkerExecutionReady(WorkerPrivate* aWorkerPrivate); 99 100 nsresult WindowExecutionReady(nsPIDOMWindowInner* aInnerWindow); 101 102 nsresult DocShellExecutionReady(nsIDocShell* aDocShell); 103 104 void Freeze(); 105 106 void Thaw(); 107 108 void EvictFromBFCache(); 109 110 RefPtr<ClientOpPromise> EvictFromBFCacheOp(); 111 112 const ClientInfo& Info() const; 113 114 // Trigger a synchronous IPC ping to the parent process to confirm that 115 // the ClientSource actor has been created. This should only be used 116 // by the WorkerPrivate startup code to deal with a ClientHandle::Control() 117 // call racing on the main thread. Do not call this in other circumstances! 118 void WorkerSyncPing(WorkerPrivate* aWorkerPrivate); 119 120 // Synchronously mark the ClientSource as controlled by the given service 121 // worker. This can happen as a result of a remote operation or directly 122 // by local code. For example, if a client's initial network load is 123 // intercepted by a controlling service worker then this should be called 124 // immediately. 125 // 126 // Note, there is no way to clear the controlling service worker because 127 // the specification does not allow that operation. 128 void SetController(const ServiceWorkerDescriptor& aServiceWorker); 129 130 // Mark the ClientSource as controlled using the remote operation arguments. 131 // This will in turn call SetController(). 132 RefPtr<ClientOpPromise> Control(const ClientControlledArgs& aArgs); 133 134 // Inherit the controller from a local parent client. This requires both 135 // setting our immediate controller field and also updating the parent-side 136 // data structure. 137 void InheritController(const ServiceWorkerDescriptor& aServiceWorker); 138 139 // Get the ClientSource's current controlling service worker, if one has 140 // been set. 141 const Maybe<ServiceWorkerDescriptor>& GetController() const; 142 143 // Note that the client has reached DOMContentLoaded. Only applies to window 144 // clients. 145 void NoteDOMContentLoaded(); 146 147 // TODO: Convert Focus() to MOZ_CAN_RUN_SCRIPT 148 MOZ_CAN_RUN_SCRIPT_BOUNDARY RefPtr<ClientOpPromise> Focus( 149 const ClientFocusArgs& aArgs); 150 151 RefPtr<ClientOpPromise> PostMessage(const ClientPostMessageArgs& aArgs); 152 153 RefPtr<ClientOpPromise> GetInfoAndState( 154 const ClientGetInfoAndStateArgs& aArgs); 155 156 Result<ClientState, ErrorResult> SnapshotState(); 157 158 nsISerialEventTarget* EventTarget() const; 159 160 void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP); 161 162 void SetPolicyContainer(nsIPolicyContainer* aPolicyContainer); 163 void SetPolicyContainerArgs( 164 const mozilla::ipc::PolicyContainerArgs& aPolicyContainer); 165 const Maybe<mozilla::ipc::PolicyContainerArgs>& GetPolicyContainerArgs(); 166 167 void SetAgentClusterId(const nsID& aId) { 168 mClientInfo.SetAgentClusterId(aId); 169 } 170 171 void Traverse(nsCycleCollectionTraversalCallback& aCallback, 172 const char* aName, uint32_t aFlags); 173 174 void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope); 175 176 bool CalledRegisterForServiceWorkerScope(const nsACString& aScope); 177 178 nsIPrincipal* GetPrincipal(); 179 }; 180 181 inline void ImplCycleCollectionUnlink(UniquePtr<ClientSource>& aField) { 182 aField.reset(); 183 } 184 185 inline void ImplCycleCollectionTraverse( 186 nsCycleCollectionTraversalCallback& aCallback, 187 UniquePtr<ClientSource>& aField, const char* aName, uint32_t aFlags) { 188 if (aField) { 189 aField->Traverse(aCallback, aName, aFlags); 190 } 191 } 192 193 } // namespace dom 194 } // namespace mozilla 195 196 #endif // _mozilla_dom_ClientSource_h