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_ipc_BlobParent_h 8 #define mozilla_dom_ipc_BlobParent_h 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/StaticPtr.h" 12 #include "mozilla/dom/PBlobParent.h" 13 #include "nsCOMPtr.h" 14 #include "nsTArray.h" 15 16 template <class, class> class nsDataHashtable; 17 class nsIDHashKey; 18 class nsIEventTarget; 19 class nsIRemoteBlob; 20 template <class> class nsRevocableEventPtr; 21 class nsString; 22 23 namespace mozilla { 24 25 class Mutex; 26 27 namespace ipc { 28 29 class PBackgroundParent; 30 31 } // namespace ipc 32 33 namespace dom { 34 35 class ContentParent; 36 class BlobImpl; 37 class nsIContentParent; 38 class PBlobStreamParent; 39 40 class BlobParent final 41 : public PBlobParent 42 { 43 typedef mozilla::ipc::PBackgroundParent PBackgroundParent; 44 45 class IDTableEntry; 46 typedef nsDataHashtable<nsIDHashKey, IDTableEntry*> IDTable; 47 48 class OpenStreamRunnable; 49 friend class OpenStreamRunnable; 50 51 class RemoteBlobImpl; 52 53 struct CreateBlobImplMetadata; 54 55 static StaticAutoPtr<IDTable> sIDTable; 56 static StaticAutoPtr<Mutex> sIDTableMutex; 57 58 BlobImpl* mBlobImpl; 59 RemoteBlobImpl* mRemoteBlobImpl; 60 61 // One of these will be null and the other non-null. 62 PBackgroundParent* mBackgroundManager; 63 nsCOMPtr<nsIContentParent> mContentManager; 64 65 nsCOMPtr<nsIEventTarget> mEventTarget; 66 67 // nsIInputStreams backed by files must ensure that the files are actually 68 // opened and closed on a background thread before we can send their file 69 // handles across to the child. The child process could crash during this 70 // process so we need to make sure we cancel the intended response in such a 71 // case. We do that by holding an array of nsRevocableEventPtr. If the child 72 // crashes then this actor will be destroyed and the nsRevocableEventPtr 73 // destructor will cancel any stream events that are currently in flight. 74 nsTArray<nsRevocableEventPtr<OpenStreamRunnable>> mOpenStreamRunnables; 75 76 RefPtr<IDTableEntry> mIDTableEntry; 77 78 bool mOwnsBlobImpl; 79 80 public: 81 class FriendKey; 82 83 static void 84 Startup(const FriendKey& aKey); 85 86 // These create functions are called on the sending side. 87 static BlobParent* 88 GetOrCreate(nsIContentParent* aManager, BlobImpl* aBlobImpl); 89 90 static BlobParent* 91 GetOrCreate(PBackgroundParent* aManager, BlobImpl* aBlobImpl); 92 93 // These create functions are called on the receiving side. 94 static BlobParent* 95 Create(nsIContentParent* aManager, 96 const ParentBlobConstructorParams& aParams); 97 98 static BlobParent* 99 Create(PBackgroundParent* aManager, 100 const ParentBlobConstructorParams& aParams); 101 102 static void Destroy(PBlobParent * aActor)103 Destroy(PBlobParent* aActor) 104 { 105 delete static_cast<BlobParent*>(aActor); 106 } 107 108 static already_AddRefed<BlobImpl> 109 GetBlobImplForID(const nsID& aID); 110 111 bool HasManager()112 HasManager() const 113 { 114 return mBackgroundManager || mContentManager; 115 } 116 117 PBackgroundParent* GetBackgroundManager()118 GetBackgroundManager() const 119 { 120 return mBackgroundManager; 121 } 122 123 nsIContentParent* GetContentManager()124 GetContentManager() const 125 { 126 return mContentManager; 127 } 128 129 // Get the BlobImpl associated with this actor. 130 already_AddRefed<BlobImpl> 131 GetBlobImpl(); 132 133 void 134 AssertIsOnOwningThread() const 135 #ifdef DEBUG 136 ; 137 #else 138 { } 139 #endif 140 141 private: 142 // These constructors are called on the sending side. 143 BlobParent(nsIContentParent* aManager, IDTableEntry* aIDTableEntry); 144 145 BlobParent(PBackgroundParent* aManager, IDTableEntry* aIDTableEntry); 146 147 // These constructors are called on the receiving side. 148 BlobParent(nsIContentParent* aManager, 149 BlobImpl* aBlobImpl, 150 IDTableEntry* aIDTableEntry); 151 152 BlobParent(PBackgroundParent* aManager, 153 BlobImpl* aBlobImpl, 154 IDTableEntry* aIDTableEntry); 155 156 // Only destroyed by BackgroundParentImpl and ContentParent. 157 ~BlobParent(); 158 159 void 160 CommonInit(IDTableEntry* aIDTableEntry); 161 162 void 163 CommonInit(BlobImpl* aBlobImpl, IDTableEntry* aIDTableEntry); 164 165 template <class ParentManagerType> 166 static BlobParent* 167 GetOrCreateFromImpl(ParentManagerType* aManager, 168 BlobImpl* aBlobImpl); 169 170 template <class ParentManagerType> 171 static BlobParent* 172 CreateFromParams(ParentManagerType* aManager, 173 const ParentBlobConstructorParams& aParams); 174 175 template <class ParentManagerType> 176 static BlobParent* 177 SendSliceConstructor(ParentManagerType* aManager, 178 const ParentBlobConstructorParams& aParams, 179 const ChildBlobConstructorParams& aOtherSideParams); 180 181 static BlobParent* 182 MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob, 183 nsIContentParent* aManager); 184 185 static BlobParent* 186 MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob, 187 PBackgroundParent* aManager); 188 189 void 190 NoteDyingRemoteBlobImpl(); 191 192 void 193 NoteRunnableCompleted(OpenStreamRunnable* aRunnable); 194 195 nsIEventTarget* EventTarget()196 EventTarget() const 197 { 198 return mEventTarget; 199 } 200 201 bool 202 IsOnOwningThread() const; 203 204 // These methods are only called by the IPDL message machinery. 205 virtual void 206 ActorDestroy(ActorDestroyReason aWhy) override; 207 208 virtual PBlobStreamParent* 209 AllocPBlobStreamParent(const uint64_t& aStart, 210 const uint64_t& aLength) override; 211 212 virtual bool 213 RecvPBlobStreamConstructor(PBlobStreamParent* aActor, 214 const uint64_t& aStart, 215 const uint64_t& aLength) override; 216 217 virtual bool 218 DeallocPBlobStreamParent(PBlobStreamParent* aActor) override; 219 220 virtual bool 221 RecvResolveMystery(const ResolveMysteryParams& aParams) override; 222 223 virtual bool 224 RecvBlobStreamSync(const uint64_t& aStart, 225 const uint64_t& aLength, 226 InputStreamParams* aParams, 227 OptionalFileDescriptorSet* aFDs) override; 228 229 virtual bool 230 RecvWaitForSliceCreation() override; 231 232 virtual bool 233 RecvGetFileId(int64_t* aFileId) override; 234 235 virtual bool 236 RecvGetFilePath(nsString* aFilePath) override; 237 }; 238 239 // Only let ContentParent call BlobParent::Startup() and ensure that 240 // ContentParent can't access any other BlobParent internals. 241 class BlobParent::FriendKey final 242 { 243 friend class ContentParent; 244 245 private: FriendKey()246 FriendKey() 247 { } 248 FriendKey(const FriendKey &)249 FriendKey(const FriendKey& /* aOther */) 250 { } 251 252 public: ~FriendKey()253 ~FriendKey() 254 { } 255 }; 256 257 } // namespace dom 258 } // namespace mozilla 259 260 #endif // mozilla_dom_ipc_BlobParent_h 261