reverted: --- b/dom/permission/moz.build +++ a/dom/permission/moz.build @@ -5,17 +5,16 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. with Files("**"): BUG_COMPONENT = ("Core", "DOM") EXPORTS.mozilla.dom += [ 'Permissions.h', 'PermissionStatus.h', - 'PermissionUtils.h', ] UNIFIED_SOURCES += [ 'PermissionObserver.cpp', 'Permissions.cpp', 'PermissionStatus.cpp', 'PermissionUtils.cpp', ] diff -u b/dom/quota/StorageManager.cpp b/dom/quota/StorageManager.cpp --- b/dom/quota/StorageManager.cpp +++ b/dom/quota/StorageManager.cpp @@ -6,7 +6,6 @@ #include "StorageManager.h" -#include "mozilla/dom/PermissionUtils.h" #include "mozilla/dom/PromiseWorkerProxy.h" #include "mozilla/dom/quota/QuotaManagerService.h" #include "mozilla/dom/StorageManagerBinding.h" @@ -89,6 +88,9 @@ private: ~RequestResolver() { } + + nsresult + HandleRequest(); }; // This class is used to return promise on worker thread. @@ -163,7 +165,6 @@ nsCOMPtr mWindow; RefPtr mPromise; nsCOMPtr mRequester; - PermissionState mPermission; public: PersistentStoragePermissionRequest(nsIPrincipal* aPrincipal, @@ -172,7 +173,6 @@ : mPrincipal(aPrincipal) , mWindow(aWindow) , mPromise(aPromise) - , mPermission(PermissionState::Prompt) { MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aWindow); @@ -190,9 +190,6 @@ private: ~PersistentStoragePermissionRequest() { } - - nsresult - ResolvePromise(); }; NS_IMPL_ISUPPORTS(PersistentStoragePermissionRequest, @@ -258,28 +255,12 @@ } nsresult -Persist(nsIPrincipal* aPrincipal, nsIQuotaRequest** aRequest) -{ - MOZ_ASSERT(aPrincipal); - MOZ_ASSERT(aRequest); - - nsCOMPtr qms = QuotaManagerService::GetOrCreate(); - if (NS_WARN_IF(!qms)) { - return NS_ERROR_FAILURE; - } - - nsresult rv = qms->Persist(aPrincipal, aRequest); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; -}; - -nsresult -Persisted(nsIPrincipal* aPrincipal, nsIQuotaRequest** aRequest) +Persisted(nsIPrincipal* aPrincipal, + nsIQuotaCallback* aCallback, + nsIQuotaRequest** aRequest) { MOZ_ASSERT(aPrincipal); + MOZ_ASSERT(aCallback); MOZ_ASSERT(aRequest); nsCOMPtr qms = QuotaManagerService::GetOrCreate(); @@ -292,6 +273,12 @@ return rv; } + // All the methods in nsIQuotaManagerService shouldn't synchronously fire + // any callbacks when they are being executed. Even when a result is ready, + // a new runnable should be dispatched to current thread to fire the callback + // asynchronously. It's safe to set the callback after we call Persisted(). + MOZ_ALWAYS_SUCCEEDS((*aRequest)->SetCallback(aCallback)); + return NS_OK; }; @@ -325,18 +312,13 @@ nsCOMPtr principal = doc->NodePrincipal(); MOZ_ASSERT(principal); - nsresult rv = NS_OK; - switch (aType) { case RequestResolver::Type::Persisted: { RefPtr resolver = new RequestResolver(RequestResolver::Type::Persisted, promise); RefPtr request; - rv = Persisted(principal, getter_AddRefs(request)); - if (NS_SUCCEEDED(rv)) { - request->SetCallback(resolver); - } + aRv = Persisted(principal, resolver, getter_AddRefs(request)); break; } @@ -345,7 +327,7 @@ RefPtr request = new PersistentStoragePermissionRequest(principal, window, promise); - rv = request->Start(); + aRv = request->Start(); break; } @@ -355,7 +337,9 @@ new RequestResolver(RequestResolver::Type::Estimate, promise); RefPtr request; - rv = GetUsageForPrincipal(principal, resolver, getter_AddRefs(request)); + aRv = GetUsageForPrincipal(principal, + resolver, + getter_AddRefs(request)); break; } @@ -364,8 +348,7 @@ MOZ_CRASH("Invalid aRequest type!"); } - if (NS_WARN_IF(NS_FAILED(rv))) { - aRv.Throw(rv); + if (NS_WARN_IF(aRv.Failed())) { return nullptr; } @@ -411,31 +394,6 @@ return promise.forget(); }; -PermissionState -TestPermission(nsIPrincipal* aPrincipal) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aPrincipal); - - uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION; - - nsCOMPtr permissionManager = - services::GetPermissionManager(); - if (!permissionManager) { - return PermissionState::Prompt; - } - - nsresult rv = - permissionManager->TestExactPermissionFromPrincipal(aPrincipal, - "persistent-storage", - &permission); - if (NS_WARN_IF(NS_FAILED(rv))) { - return PermissionState::Denied; - } - - return ActionToPermissionState(permission); -} - } // namespace /******************************************************************************* @@ -470,7 +428,13 @@ mProxy->CleanUp(); } } - } autoCleanUp(proxy); + }; + + // Only clean up for worker. + Maybe autoCleanup; + if (proxy) { + autoCleanup.emplace(proxy); + } if (mType == Type::Estimate) { if (NS_SUCCEEDED(mResultCode)) { @@ -487,22 +451,9 @@ promise->MaybeResolve(mPersisted); } -NS_IMETHODIMP -RequestResolver::OnUsageResult(nsIQuotaUsageRequest *aRequest) +nsresult +RequestResolver::HandleRequest() { - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aRequest); - - nsresult rv = aRequest->GetResultCode(&mResultCode); - if (NS_WARN_IF(NS_FAILED(rv))) { - mResultCode = rv; - } else if (NS_SUCCEEDED(mResultCode)) { - rv = GetStorageEstimate(aRequest, mStorageEstimate); - if (NS_WARN_IF(NS_FAILED(rv))) { - mResultCode = rv; - } - } - // In a main thread request. if (!mProxy) { MOZ_ASSERT(mPromise); @@ -511,35 +462,39 @@ return NS_OK; } - // In a worker thread request. - MutexAutoLock lock(mProxy->Lock()); + { + // In a worker thread request. + MutexAutoLock lock(mProxy->Lock()); - if (NS_WARN_IF(mProxy->CleanedUp())) { - return NS_ERROR_FAILURE; - } + if (NS_WARN_IF(mProxy->CleanedUp())) { + return NS_ERROR_FAILURE; + } - RefPtr runnable = new FinishWorkerRunnable(this); - if (NS_WARN_IF(!runnable->Dispatch())) { - return NS_ERROR_FAILURE; + RefPtr runnable = new FinishWorkerRunnable(this); + if (NS_WARN_IF(!runnable->Dispatch())) { + return NS_ERROR_FAILURE; + } } return NS_OK; } +NS_IMPL_ISUPPORTS(RequestResolver, nsIQuotaUsageCallback, nsIQuotaCallback) + NS_IMETHODIMP RequestResolver::OnComplete(nsIQuotaRequest *aRequest) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aRequest); - // Retrieve the result according to the RequestResolverType + // Retrieve the result according to the RequestResolverType. nsCOMPtr callback; nsresult rv = aRequest->GetCallback(getter_AddRefs(callback)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - RequestResolver* result = static_cast(callback.get()); + auto result = static_cast(callback.get()); Type type = result->GetType(); nsresult resultCode; @@ -567,33 +522,28 @@ MOZ_CRASH("Invalid callback type!"); } - // In a main thread request. - if (!mProxy) { - MOZ_ASSERT(mPromise); - - ResolveOrReject(); - return NS_OK; - } - - { - // In a worker thread request. - MutexAutoLock lock(mProxy->Lock()); + return HandleRequest(); +} - if (NS_WARN_IF(mProxy->CleanedUp())) { - return NS_ERROR_FAILURE; - } +NS_IMETHODIMP +RequestResolver::OnUsageResult(nsIQuotaUsageRequest *aRequest) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aRequest); - RefPtr runnable = new FinishWorkerRunnable(this); - if (NS_WARN_IF(!runnable->Dispatch())) { - return NS_ERROR_FAILURE; + nsresult rv = aRequest->GetResultCode(&mResultCode); + if (NS_WARN_IF(NS_FAILED(rv))) { + mResultCode = rv; + } else if (NS_SUCCEEDED(mResultCode)) { + rv = GetStorageEstimate(aRequest, mStorageEstimate); + if (NS_WARN_IF(NS_FAILED(rv))) { + mResultCode = rv; } } - return NS_OK; + return HandleRequest(); } -NS_IMPL_ISUPPORTS(RequestResolver, nsIQuotaUsageCallback, nsIQuotaCallback) - bool RequestResolver:: FinishWorkerRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) @@ -659,17 +609,11 @@ new RequestResolver(RequestResolver::Type::Persisted, mProxy); RefPtr request; - nsresult rv = Persisted(principal, getter_AddRefs(request)); + nsresult rv = Persisted(principal, resolver, getter_AddRefs(request)); if (NS_WARN_IF(NS_FAILED(rv))) { return false; } - // All the methods in nsIQuotaManagerService shouldn't synchronously fire - // any callbacks when they are being executed. Even when a result is ready, - // a new runnable should be dispatched to current thread to fire the callback - // asynchronously. - request->SetCallback(resolver); - return true; } @@ -682,12 +626,10 @@ if (Preferences::GetBool("dom.storageManager.prompt.testing", false)) { if (Preferences::GetBool("dom.storageManager.prompt.testing.allow", false)) { - mPermission = PermissionState::Granted; return Allow(JS::UndefinedHandleValue); } - mPermission = PermissionState::Denied; - return ResolvePromise(); + return Cancel(); } return nsContentPermissionUtils::AskPermission(this, mWindow); @@ -699,8 +641,8 @@ MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aPrincipal); - NS_ADDREF(*aPrincipal = mPrincipal); MOZ_ASSERT(mPrincipal); + NS_ADDREF(*aPrincipal = mPrincipal); return NS_OK; } @@ -732,13 +674,8 @@ { MOZ_ASSERT(NS_IsMainThread()); - // `Cancel` is called if the user denied permission or dismissed the - // permission request. To distinguish between the two, we set the - // permission to "prompt" and query the permission manager in - // `ResolvePromise`. - mPermission = PermissionState::Prompt; - - return ResolvePromise(); + mPromise->MaybeResolve(false); + return NS_OK; } NS_IMETHODIMP @@ -746,18 +683,24 @@ { MOZ_ASSERT(NS_IsMainThread()); - mPermission = PermissionState::Granted; RefPtr resolver = new RequestResolver(RequestResolver::Type::Persist, mPromise); + nsCOMPtr qms = QuotaManagerService::GetOrCreate(); + if (NS_WARN_IF(!qms)) { + return NS_ERROR_FAILURE; + } + RefPtr request; - nsresult rv = Persist(mPrincipal, getter_AddRefs(request)); - if (NS_SUCCEEDED(rv)) { - request->SetCallback(resolver); + nsresult rv = qms->Persist(mPrincipal, getter_AddRefs(request)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } - return rv; + MOZ_ALWAYS_SUCCEEDS(request->SetCallback(resolver)); + + return NS_OK; } NS_IMETHODIMP @@ -773,23 +716,6 @@ return NS_OK; } -nsresult -PersistentStoragePermissionRequest::ResolvePromise() -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsresult rv = NS_OK; - if (mPermission == PermissionState::Prompt) { - // This will still be "prompt" if the user dismissed the doorhanger, or - // "denied" otherwise. - mPermission = TestPermission(mPrincipal); - } - - mPromise->MaybeResolve(mPermission == PermissionState::Granted); - - return rv; -} - NS_IMETHODIMP PersistentStoragePermissionRequest::GetTypes(nsIArray** aTypes) {