-
JS requets to clear quota usage under one origin through
nsIQuotaManagerService::clearStoragesForPrincipal
api -
QuotaManagerService::ClearStoragesForPrincipal
(api implementation) would receive the call.-
Prepare the Clear Origin request
// Prepare the Clear Origin request RefPtr<Request> request = new Request(aPrincipal); ClearOriginParams params;
-
Initiate the request
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params)); rv = InitiateRequest(info);
-
-
QuotaManagerService::RequestInfo::InitiateRequest
-
Create the requet actor
auto actor = new QuotaRequestChild(request);
-
Send out the requet actor to Parent through IPC
// This is done by `PQuotaChild::SendPQuotaRequestConstructor` aActor->SendPQuotaRequestConstructor(actor, mParams)
-
-
Quota::RecvPQuotaUsageRequestConstructor
- Parent receives the request and runs it
auto* op = static_cast<QuotaUsageRequestBase*>(aActor); // ... ... op->RunImmediately();
- Parent receives the request and runs it
-
NormalOriginOperationBase::RunImmediately
-
OriginOperationBase::Run
OriginOperationBase would do task according the current state as well as advance the state after doing task. For exmaple, as we started at the State_Initializing.
-
OriginOperationBase::Run
case State_Initializing: { rv = InitOnMainThread(); break; }
-
OriginOperationBase::InitOnMainThread
-
nsresult rv = DoInitOnMainThread();
- ClearOriginOp::DoInitOnMainThread
// This step is important. // Our aClearAll flag takes effect here. if (mParams.clearAll()) { mOriginScope.SetFromPrefix(origin); } else { mOriginScope.SetFromOrigin(origin); }
- ClearOriginOp::DoInitOnMainThread
-
After init on the main thread, advance the state from "State_Initializing" to "State_FinishingInit"
AdvanceState(); // Dispatch to the main thread to do `::Run` again MOZ_ALWAYS_SUCCEEDS(mOwningThread->Dispatch(this, NS_DISPATCH_NORMAL));
-
After a series of jobs and the states changes, we would arrive the "State_DirectoryOpenPending" state
-
-
OriginOperationBase::Run
case State_DirectoryOpenPending: { rv = DirectoryOpen(); break; }
-
-
OriginOperationBase::DirectoryOpen
-
Advance to the next state
AdvanceState();
-
OriginOperationBase::AdvanceState
- Advance State_DirectoryOpenPending to State_DirectoryWorkOpen
case State_DirectoryOpenPending: mState = State_DirectoryWorkOpen; return;
- Advance State_DirectoryOpenPending to State_DirectoryWorkOpen
-
Dispatch to the IO thread to handle the new state
nsresult rv = quotaManager->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL);
-
-
OriginOperationBase::Run
case State_DirectoryWorkOpen: { // The same, inside `DirectoryWork` after jobs are done, // the state would be advanced and dispatch to the IO thread to run the new state again. rv = DirectoryWork(); break; }
-
OriginOperationBase::DirectoryWork
After advancing state, it would arrive this metod.
- Ensure storage initialized then do directory work
if (mNeedsQuotaManagerInit) { rv = quotaManager->EnsureStorageIsInitialized(); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } // ... ... rv = DoDirectoryWork(quotaManager);
- Ensure storage initialized then do directory work
-
ClearRequestBase::DoDirectoryWork (How did it know
ClearRequestBase
) -
ClearRequestBase::DeleteFiles
-
Init the path to the storage dir for a particular persistent type
rv = directory->InitWithPath(aQuotaManager->GetStoragePath(aPersistenceType));
-
Get entries under the storage dir
nsCOMPtr<nsISimpleEnumerator> entries; if (NS_WARN_IF(NS_FAILED( directory->GetDirectoryEntries(getter_AddRefs(entries)))) || !entries) { return; }
-
Find the matched origin then remove its storage directory
nsString leafName; rv = file->GetLeafName(leafName); // ... ... if (!isDirectory) { // Unknown files during clearing are allowed. Just warn if we find them. if (!IsOSMetadata(leafName)) { UNKNOWN_FILE_WARNING(leafName); } continue; } // Skip the origin directory if it doesn't match the pattern. if (!originScope.MatchesOrigin(OriginScope::FromOrigin( NS_ConvertUTF16toUTF8(leafName)))) { continue; }
- OriginScope::MatchesOrigin
- Because of the aClearAll flag, OA dosen't matter here. We would continue to clear across OAs
// ... ... else if (IsPrefix()) { MOZ_ASSERT(mPrefix); match = StringBeginsWith(aOther.mOriginAndAttributes->mOrigin, *mPrefix); } // ... ...
- Because of the aClearAll flag, OA dosen't matter here. We would continue to clear across OAs
// ... ... for (uint32_t index = 0; index < 10; index++) { // We can't guarantee that this will always succeed on Windows... if (NS_SUCCEEDED((rv = file->Remove(true)))) { break; } // ... ... } // ... ... aQuotaManager->OriginClearCompleted(aPersistenceType, origin);
- OriginScope::MatchesOrigin
-
-
OriginOperationBase::DirectoryWork
Back to
DirectoryWork
then the state is advacned from "State_DirectoryWorkOpen" to "State_UnblockingOpen" -
OriginOperationBase::Run
- Unblock lock
case State_UnblockingOpen: { UnblockOpen(); return NS_OK; }
- Unblock lock
-
NormalOriginOperationBase::UnblockOpen
-
Send results
SendResults();
-
After sending results, release the lock then advance the state from "State_UnblockingOpen" to "State_Complete"
mDirectoryLock = nullptr; AdvanceState();
-
-
QuotaRequestBase::SendResults (continues from the above
SendResults
)- Send result back to Child through IPC
Unused << PQuotaRequestParent::Send__delete__(this, response);
- Send result back to Child through IPC
-
QuotaRequestChild::Recv__delete__
- Handle response from clearing job
case RequestResponse::TInitResponse: case RequestResponse::TClearOriginResponse: case RequestResponse::TClearDataResponse: case RequestResponse::TClearAllResponse: case RequestResponse::TResetAllResponse: case RequestResponse::TPersistResponse: HandleResponse(); break;
- Handle response from clearing job
-
QuotaRequestChild::HandleResponse
mRequest->SetResult(variant)
-
Request::SetResult
FireCallback();
-
Request::FireCallback
- Fire nsIQuotaRequest::nsIQuotaCallback::onComplete to send result back to JS side
if (mCallback) { mCallback->OnComplete(this); // Clean up. mCallback = nullptr; }
- Fire nsIQuotaRequest::nsIQuotaCallback::onComplete to send result back to JS side