ActorsChild.cpp (8075B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ActorsChild.h" 8 9 #include "ErrorList.h" 10 #include "LSDatabase.h" 11 #include "LSObserver.h" 12 #include "LSSnapshot.h" 13 #include "LocalStorageCommon.h" 14 #include "mozilla/Assertions.h" 15 #include "mozilla/StaticPrefs_dom.h" 16 #include "mozilla/dom/LSValue.h" 17 #include "mozilla/dom/Storage.h" 18 #include "mozilla/dom/quota/QuotaCommon.h" 19 #include "mozilla/dom/quota/ThreadUtils.h" 20 #include "mozilla/ipc/BackgroundUtils.h" 21 #include "nsCOMPtr.h" 22 23 namespace mozilla::dom { 24 25 /******************************************************************************* 26 * LSDatabaseChild 27 ******************************************************************************/ 28 29 LSDatabaseChild::LSDatabaseChild(LSDatabase* aDatabase) : mDatabase(aDatabase) { 30 AssertIsOnOwningThread(); 31 MOZ_ASSERT(aDatabase); 32 33 MOZ_COUNT_CTOR(LSDatabaseChild); 34 } 35 36 LSDatabaseChild::~LSDatabaseChild() { 37 AssertIsOnOwningThread(); 38 39 MOZ_COUNT_DTOR(LSDatabaseChild); 40 } 41 42 void LSDatabaseChild::Shutdown() { 43 AssertIsOnOwningThread(); 44 45 if (mDatabase) { 46 mDatabase->ClearActor(); 47 mDatabase = nullptr; 48 49 Close(); 50 } 51 } 52 53 void LSDatabaseChild::ActorDestroy(ActorDestroyReason aWhy) { 54 AssertIsOnOwningThread(); 55 56 if (mDatabase) { 57 mDatabase->ClearActor(); 58 #ifdef DEBUG 59 mDatabase = nullptr; 60 #endif 61 } 62 } 63 64 mozilla::ipc::IPCResult LSDatabaseChild::RecvRequestAllowToClose() { 65 AssertIsOnOwningThread(); 66 67 if (mDatabase) { 68 mDatabase->RequestAllowToClose(); 69 70 // TODO: A new datastore will be prepared at first LocalStorage API 71 // synchronous call. It would be better to start preparing a new 72 // datastore right here, but asynchronously. 73 // However, we probably shouldn't do that if we are shutting down. 74 } 75 76 return IPC_OK(); 77 } 78 79 PBackgroundLSSnapshotChild* LSDatabaseChild::AllocPBackgroundLSSnapshotChild( 80 const nsAString& aDocumentURI, const nsAString& aKey, 81 const bool& aIncreasePeakUsage, const int64_t& aMinSize, 82 LSSnapshotInitInfo* aInitInfo) { 83 MOZ_CRASH("PBackgroundLSSnapshotChild actor should be manually constructed!"); 84 } 85 86 bool LSDatabaseChild::DeallocPBackgroundLSSnapshotChild( 87 PBackgroundLSSnapshotChild* aActor) { 88 MOZ_ASSERT(aActor); 89 90 delete aActor; 91 return true; 92 } 93 94 /******************************************************************************* 95 * LSObserverChild 96 ******************************************************************************/ 97 98 LSObserverChild::LSObserverChild(LSObserver* aObserver) : mObserver(aObserver) { 99 AssertIsOnOwningThread(); 100 MOZ_ASSERT(aObserver); 101 102 MOZ_COUNT_CTOR(LSObserverChild); 103 } 104 105 LSObserverChild::~LSObserverChild() { 106 AssertIsOnOwningThread(); 107 108 MOZ_COUNT_DTOR(LSObserverChild); 109 } 110 111 void LSObserverChild::SendDeleteMeInternal() { 112 AssertIsOnOwningThread(); 113 114 if (mObserver) { 115 mObserver->ClearActor(); 116 mObserver = nullptr; 117 118 MOZ_ALWAYS_TRUE(PBackgroundLSObserverChild::SendDeleteMe()); 119 } 120 } 121 122 void LSObserverChild::ActorDestroy(ActorDestroyReason aWhy) { 123 AssertIsOnOwningThread(); 124 125 if (mObserver) { 126 mObserver->ClearActor(); 127 #ifdef DEBUG 128 mObserver = nullptr; 129 #endif 130 } 131 } 132 133 mozilla::ipc::IPCResult LSObserverChild::RecvObserve( 134 const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId, 135 const nsAString& aDocumentURI, const nsAString& aKey, 136 const LSValue& aOldValue, const LSValue& aNewValue) { 137 AssertIsOnOwningThread(); 138 139 if (!mObserver) { 140 return IPC_OK(); 141 } 142 143 QM_TRY_INSPECT(const auto& principal, 144 PrincipalInfoToPrincipal(aPrincipalInfo), 145 IPC_FAIL(this, "PrincipalInfoToPrincipal failed!")); 146 147 Storage::NotifyChange(/* aStorage */ nullptr, principal, aKey, 148 aOldValue.AsString(), aNewValue.AsString(), 149 /* aStorageType */ kLocalStorageType, aDocumentURI, 150 /* aIsPrivate */ !!aPrivateBrowsingId, 151 /* aImmediateDispatch */ true); 152 153 return IPC_OK(); 154 } 155 156 /******************************************************************************* 157 * LocalStorageRequestChild 158 ******************************************************************************/ 159 160 LSRequestChild::LSRequestChild() : mFinishing(false) { 161 AssertIsOnOwningThread(); 162 163 MOZ_COUNT_CTOR(LSRequestChild); 164 } 165 166 LSRequestChild::~LSRequestChild() { 167 AssertIsOnOwningThread(); 168 MOZ_ASSERT(!mCallback); 169 170 MOZ_COUNT_DTOR(LSRequestChild); 171 } 172 173 void LSRequestChild::SetCallback(LSRequestChildCallback* aCallback) { 174 AssertIsOnOwningThread(); 175 MOZ_ASSERT(aCallback); 176 MOZ_ASSERT(!mCallback); 177 MOZ_ASSERT(Manager()); 178 179 mCallback = aCallback; 180 } 181 182 bool LSRequestChild::Finishing() const { 183 AssertIsOnOwningThread(); 184 185 return mFinishing; 186 } 187 188 void LSRequestChild::ActorDestroy(ActorDestroyReason aWhy) { 189 AssertIsOnOwningThread(); 190 191 if (mCallback) { 192 MOZ_ASSERT(aWhy != Deletion); 193 194 mCallback->OnResponse(NS_ERROR_FAILURE); 195 196 mCallback = nullptr; 197 } 198 } 199 200 mozilla::ipc::IPCResult LSRequestChild::Recv__delete__( 201 LSRequestResponse&& aResponse) { 202 AssertIsOnOwningThread(); 203 MOZ_ASSERT(mCallback); 204 205 mCallback->OnResponse(std::move(aResponse)); 206 207 mCallback = nullptr; 208 209 return IPC_OK(); 210 } 211 212 mozilla::ipc::IPCResult LSRequestChild::RecvReady() { 213 AssertIsOnOwningThread(); 214 215 mFinishing = true; 216 217 quota::SleepIfEnabled( 218 StaticPrefs::dom_storage_requestFinalization_pauseOnDOMFileThreadMs()); 219 220 // We only expect this to return false if the channel has been closed, but 221 // PBackground's channel never gets shutdown. 222 MOZ_ALWAYS_TRUE(SendFinish()); 223 224 return IPC_OK(); 225 } 226 227 /******************************************************************************* 228 * LSSimpleRequestChild 229 ******************************************************************************/ 230 231 LSSimpleRequestChild::LSSimpleRequestChild() { 232 AssertIsOnOwningThread(); 233 234 MOZ_COUNT_CTOR(LSSimpleRequestChild); 235 } 236 237 LSSimpleRequestChild::~LSSimpleRequestChild() { 238 AssertIsOnOwningThread(); 239 MOZ_ASSERT(!mCallback); 240 241 MOZ_COUNT_DTOR(LSSimpleRequestChild); 242 } 243 244 void LSSimpleRequestChild::SetCallback( 245 LSSimpleRequestChildCallback* aCallback) { 246 AssertIsOnOwningThread(); 247 MOZ_ASSERT(aCallback); 248 MOZ_ASSERT(!mCallback); 249 MOZ_ASSERT(Manager()); 250 251 mCallback = aCallback; 252 } 253 254 void LSSimpleRequestChild::ActorDestroy(ActorDestroyReason aWhy) { 255 AssertIsOnOwningThread(); 256 257 if (mCallback) { 258 MOZ_ASSERT(aWhy != Deletion); 259 260 mCallback->OnResponse(NS_ERROR_FAILURE); 261 262 mCallback = nullptr; 263 } 264 } 265 266 mozilla::ipc::IPCResult LSSimpleRequestChild::Recv__delete__( 267 const LSSimpleRequestResponse& aResponse) { 268 AssertIsOnOwningThread(); 269 MOZ_ASSERT(mCallback); 270 271 mCallback->OnResponse(aResponse); 272 273 mCallback = nullptr; 274 275 return IPC_OK(); 276 } 277 278 /******************************************************************************* 279 * LSSnapshotChild 280 ******************************************************************************/ 281 282 LSSnapshotChild::LSSnapshotChild(LSSnapshot* aSnapshot) : mSnapshot(aSnapshot) { 283 AssertIsOnOwningThread(); 284 MOZ_ASSERT(aSnapshot); 285 286 MOZ_COUNT_CTOR(LSSnapshotChild); 287 } 288 289 LSSnapshotChild::~LSSnapshotChild() { 290 AssertIsOnOwningThread(); 291 292 MOZ_COUNT_DTOR(LSSnapshotChild); 293 } 294 295 void LSSnapshotChild::SendDeleteMeInternal() { 296 AssertIsOnOwningThread(); 297 298 if (mSnapshot) { 299 mSnapshot->ClearActor(); 300 mSnapshot = nullptr; 301 302 MOZ_ALWAYS_TRUE(PBackgroundLSSnapshotChild::SendDeleteMe()); 303 } 304 } 305 306 void LSSnapshotChild::ActorDestroy(ActorDestroyReason aWhy) { 307 AssertIsOnOwningThread(); 308 309 if (mSnapshot) { 310 mSnapshot->ClearActor(); 311 #ifdef DEBUG 312 mSnapshot = nullptr; 313 #endif 314 } 315 } 316 317 mozilla::ipc::IPCResult LSSnapshotChild::RecvMarkDirty() { 318 AssertIsOnOwningThread(); 319 320 if (!mSnapshot) { 321 return IPC_OK(); 322 } 323 324 mSnapshot->MarkDirty(); 325 326 return IPC_OK(); 327 } 328 329 } // namespace mozilla::dom