diff --git a/dom/base/StorageAccessPermissionRequest.cpp b/dom/base/StorageAccessPermissionRequest.cpp index 68186ef9f62c..6ad954f8f464 100644 --- a/dom/base/StorageAccessPermissionRequest.cpp +++ b/dom/base/StorageAccessPermissionRequest.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "StorageAccessPermissionRequest.h" +#include "mozilla/StaticPrefs.h" +#include namespace mozilla { namespace dom { @@ -39,6 +41,7 @@ NS_IMETHODIMP StorageAccessPermissionRequest::Cancel() { if (!mCallbackCalled) { mCallbackCalled = true; + mTimer = nullptr; mCancelCallback(); } return NS_OK; @@ -59,7 +62,20 @@ StorageAccessPermissionRequest::Allow(JS::HandleValue aChoices) { mAllowAnySiteCallback(); } else if (choices.Length() == 1 && choices[0].choice().EqualsLiteral("allow-auto-grant")) { - mAllowAutoGrantCallback(); + unsigned simulatedDelay = CalculateSimulatedDelay(); + if (simulatedDelay) { + MOZ_ASSERT(!mTimer); + RefPtr self = this; + rv = NS_NewTimerWithFuncCallback( + getter_AddRefs(mTimer), CallAutoGrantCallback, this, simulatedDelay, + nsITimer::TYPE_ONE_SHOT, "DelayedAllowAutoGrantCallback"); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + NS_ADDREF(this); + } else { + mAllowAutoGrantCallback(); + } } else { mAllowCallback(); } @@ -88,5 +104,29 @@ StorageAccessPermissionRequest::Create( return request.forget(); } +unsigned StorageAccessPermissionRequest::CalculateSimulatedDelay() { + if (!StaticPrefs::dom_storage_access_auto_grants_delayed()) { + return 0; + } + + // Generate a random time value that is at least 5 seconds and at most 15 + // minutes. + std::srand(static_cast(PR_Now())); + + const unsigned kMin = 5000; + const unsigned kMax = 6000; + const unsigned random = std::abs(std::rand()); + + return kMin + random % (kMax - kMin); +} + +void StorageAccessPermissionRequest::CallAutoGrantCallback(nsITimer* aTimer, + void* aClosure) { + auto self = static_cast(aClosure); + self->mAllowAutoGrantCallback(); + self->mTimer = nullptr; + NS_RELEASE(self); +} + } // namespace dom } // namespace mozilla diff --git a/dom/base/StorageAccessPermissionRequest.h b/dom/base/StorageAccessPermissionRequest.h index d34bc39a0680..6a6c524b12d0 100644 --- a/dom/base/StorageAccessPermissionRequest.h +++ b/dom/base/StorageAccessPermissionRequest.h @@ -47,10 +47,15 @@ class StorageAccessPermissionRequest final CancelCallback&& aCancelCallback); ~StorageAccessPermissionRequest(); + unsigned CalculateSimulatedDelay(); + + static void CallAutoGrantCallback(nsITimer* aTimer, void* aClosure); + AllowCallback mAllowCallback; AllowAutoGrantCallback mAllowAutoGrantCallback; AllowAnySiteCallback mAllowAnySiteCallback; CancelCallback mCancelCallback; + nsCOMPtr mTimer; nsTArray mPermissionRequests; bool mCallbackCalled; }; diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index 10e969a3cb64..6af9ac6297a3 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -520,6 +520,12 @@ VARCACHE_PREF( bool, false ) +VARCACHE_PREF( + "dom.storage_access.auto_grants.delayed", + dom_storage_access_auto_grants_delayed, + bool, true +) + //--------------------------------------------------------------------------- // Extension prefs //--------------------------------------------------------------------------- diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js b/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js index a648691d1565..a77b9c415201 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js @@ -22,6 +22,7 @@ async function testDoorHanger(choice, showPrompt, useEscape, topPage, maxConcurr ["browser.contentblocking.allowlist.storage.enabled", true], [ContentBlocking.prefIntroCount, ContentBlocking.MAX_INTROS], ["dom.storage_access.auto_grants", true], + ["dom.storage_access.auto_grants.delayed", false], ["dom.storage_access.enabled", true], ["dom.storage_access.max_concurrent_auto_grants", maxConcurrent], ["dom.storage_access.prompt.testing", false],