IDBFactory.h (7108B)
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_idbfactory_h__ 8 #define mozilla_dom_idbfactory_h__ 9 10 #include "mozilla/GlobalTeardownObserver.h" 11 #include "mozilla/UniquePtr.h" 12 #include "mozilla/dom/BindingDeclarations.h" 13 #include "mozilla/dom/quota/PersistenceType.h" 14 #include "nsCOMPtr.h" 15 #include "nsCycleCollectionParticipant.h" 16 #include "nsISupports.h" 17 #include "nsString.h" 18 #include "nsTArray.h" 19 #include "nsWrapperCache.h" 20 21 class nsIGlobalObject; 22 class nsIPrincipal; 23 class nsISerialEventTarget; 24 class nsPIDOMWindowInner; 25 26 namespace mozilla { 27 28 class ErrorResult; 29 30 namespace ipc { 31 32 class PBackgroundChild; 33 class PrincipalInfo; 34 35 } // namespace ipc 36 37 namespace dom { 38 39 struct IDBOpenDBOptions; 40 class IDBOpenDBRequest; 41 template <typename> 42 class Optional; 43 class BrowserChild; 44 enum class CallerType : uint32_t; 45 46 namespace indexedDB { 47 class BackgroundFactoryChild; 48 class FactoryRequestParams; 49 class LoggingInfo; 50 } // namespace indexedDB 51 52 class IDBFactory final : public GlobalTeardownObserver, public nsWrapperCache { 53 using PBackgroundChild = mozilla::ipc::PBackgroundChild; 54 using PrincipalInfo = mozilla::ipc::PrincipalInfo; 55 56 class BackgroundCreateCallback; 57 struct PendingRequestInfo; 58 struct IDBFactoryGuard {}; 59 60 UniquePtr<PrincipalInfo> mPrincipalInfo; 61 62 // This will only be set if the factory belongs to a window in a child 63 // process. 64 RefPtr<BrowserChild> mBrowserChild; 65 66 indexedDB::BackgroundFactoryChild* mBackgroundActor; 67 68 // It is either set to a DocGroup-specific EventTarget if created by 69 // CreateForWindow() or set to GetCurrentSerialEventTarget() otherwise. 70 nsCOMPtr<nsISerialEventTarget> mEventTarget; 71 72 uint64_t mInnerWindowID; 73 uint32_t mActiveTransactionCount; 74 uint32_t mActiveDatabaseCount; 75 76 // When mAllowed is false we throw security errors on all operations. This is 77 // because although we make storage access decisions when we create the 78 // IDBFactory, the spec (and content) expects us to only throw if an attempt 79 // is made to use the resulting IDBFactory. 80 bool mAllowed; 81 bool mBackgroundActorFailed; 82 bool mPrivateBrowsingMode; 83 84 public: 85 IDBFactory(const IDBFactoryGuard&, bool aAllowed); 86 87 static Result<RefPtr<IDBFactory>, nsresult> CreateForWindow( 88 nsPIDOMWindowInner* aWindow); 89 90 static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJS( 91 nsIGlobalObject* aGlobal); 92 93 // mAllowed shall be false for null aPrincipalInfo. 94 static Result<RefPtr<IDBFactory>, nsresult> CreateForWorker( 95 nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo>&& aPrincipalInfo, 96 uint64_t aInnerWindowID); 97 98 static bool AllowedForWindow(nsPIDOMWindowInner* aWindow); 99 100 static bool AllowedForPrincipal(nsIPrincipal* aPrincipal, 101 bool* aIsSystemPrincipal = nullptr); 102 103 static quota::PersistenceType GetPersistenceType( 104 const PrincipalInfo& aPrincipalInfo); 105 106 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBFactory); } 107 108 nsISerialEventTarget* EventTarget() const { 109 AssertIsOnOwningThread(); 110 MOZ_RELEASE_ASSERT(mEventTarget); 111 return mEventTarget; 112 } 113 114 void ClearBackgroundActor() { 115 AssertIsOnOwningThread(); 116 117 mBackgroundActor = nullptr; 118 } 119 120 // Increase/Decrease the number of active transactions for the decision 121 // making of preemption and throttling. 122 // Note: If the state of its actor is not committed or aborted, it could block 123 // IDB operations in other window. 124 void UpdateActiveTransactionCount(int32_t aDelta); 125 126 // Increase/Decrease the number of active databases and IDBOpenRequests for 127 // the decision making of preemption and throttling. 128 // Note: A non-closed database or a pending IDBOpenRequest could block 129 // IDB operations in other window. 130 void UpdateActiveDatabaseCount(int32_t aDelta); 131 132 // BindingUtils.h's FindAssociatedGlobalForNative needs this. 133 nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } 134 135 BrowserChild* GetBrowserChild() const { return mBrowserChild; } 136 137 PrincipalInfo* GetPrincipalInfo() const { 138 AssertIsOnOwningThread(); 139 140 return mPrincipalInfo.get(); 141 } 142 143 uint64_t InnerWindowID() const { 144 AssertIsOnOwningThread(); 145 146 return mInnerWindowID; 147 } 148 149 bool IsChrome() const; 150 151 [[nodiscard]] RefPtr<IDBOpenDBRequest> Open( 152 JSContext* aCx, const nsAString& aName, 153 const Optional<uint64_t>& aVersion, CallerType aCallerType, 154 ErrorResult& aRv); 155 156 [[nodiscard]] RefPtr<IDBOpenDBRequest> DeleteDatabase(JSContext* aCx, 157 const nsAString& aName, 158 CallerType aCallerType, 159 ErrorResult& aRv); 160 161 already_AddRefed<Promise> Databases(JSContext* aCx, ErrorResult& aRv); 162 163 int16_t Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst, 164 JS::Handle<JS::Value> aSecond, ErrorResult& aRv); 165 166 [[nodiscard]] RefPtr<IDBOpenDBRequest> OpenForPrincipal( 167 JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, 168 uint64_t aVersion, SystemCallerGuarantee, ErrorResult& aRv); 169 170 [[nodiscard]] RefPtr<IDBOpenDBRequest> OpenForPrincipal( 171 JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, 172 const IDBOpenDBOptions& aOptions, SystemCallerGuarantee, 173 ErrorResult& aRv); 174 175 [[nodiscard]] RefPtr<IDBOpenDBRequest> DeleteForPrincipal( 176 JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, 177 const IDBOpenDBOptions& aOptions, SystemCallerGuarantee, 178 ErrorResult& aRv); 179 180 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 181 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory) 182 183 // nsWrapperCache 184 virtual JSObject* WrapObject(JSContext* aCx, 185 JS::Handle<JSObject*> aGivenProto) override; 186 187 private: 188 ~IDBFactory(); 189 190 static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJSInternal( 191 nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo); 192 193 static Result<RefPtr<IDBFactory>, nsresult> CreateInternal( 194 nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo, 195 uint64_t aInnerWindowID); 196 197 static nsresult AllowedForWindowInternal(nsPIDOMWindowInner* aWindow, 198 nsCOMPtr<nsIPrincipal>* aPrincipal); 199 200 nsresult EnsureBackgroundActor(); 201 202 [[nodiscard]] RefPtr<IDBOpenDBRequest> OpenInternal( 203 JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, 204 const Optional<uint64_t>& aVersion, bool aDeleting, 205 CallerType aCallerType, ErrorResult& aRv); 206 207 nsresult InitiateRequest(const NotNull<RefPtr<IDBOpenDBRequest>>& aRequest, 208 const indexedDB::FactoryRequestParams& aParams); 209 }; 210 211 } // namespace dom 212 } // namespace mozilla 213 214 #endif // mozilla_dom_idbfactory_h__