Bug 1573236 - Part 2: Make the dom.storage_access.auto_grants.delayed work again with the new setup; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 14 Aug 2019 21:02:59 +0000
changeset 488035 6e1475b54a6f295293465692e81f2b950cca3584
parent 488034 a60edc93a43410f04b771c23f2f1e5e32ae9ea67
child 488036 3cf55b7f12f2cb7dfcdbcbcd817d77e298e76fbd
push id36434
push usercbrindusan@mozilla.com
push dateThu, 15 Aug 2019 09:44:30 +0000
treeherdermozilla-central@144fbfb409b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1573236
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1573236 - Part 2: Make the dom.storage_access.auto_grants.delayed work again with the new setup; r=baku Differential Revision: https://phabricator.services.mozilla.com/D41622
dom/base/Document.cpp
dom/base/StorageAccessPermissionRequest.cpp
dom/base/StorageAccessPermissionRequest.h
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -15452,23 +15452,16 @@ already_AddRefed<mozilla::dom::Promise> 
             StorageAccessPermissionRequest::Create(
                 inner,
                 // Allow
                 [p] {
                   Telemetry::AccumulateCategorical(
                       Telemetry::LABELS_STORAGE_ACCESS_API_UI::Allow);
                   p->Resolve(AntiTrackingCommon::eAllow, __func__);
                 },
-                // Allow auto grant
-                [p] {
-                  Telemetry::AccumulateCategorical(
-                      Telemetry::LABELS_STORAGE_ACCESS_API_UI::
-                          AllowAutomatically);
-                  p->Resolve(AntiTrackingCommon::eAllowAutoGrant, __func__);
-                },
                 // Allow on any site
                 [p] {
                   Telemetry::AccumulateCategorical(
                       Telemetry::LABELS_STORAGE_ACCESS_API_UI::AllowOnAnySite);
                   p->Resolve(AntiTrackingCommon::eAllowOnAnySite, __func__);
                 },
                 // Block
                 [p] {
@@ -15526,17 +15519,24 @@ already_AddRefed<mozilla::dom::Promise> 
                 if (pr2 == PromptResult::Granted) {
                   AntiTrackingCommon::StorageAccessPromptChoices choice =
                       AntiTrackingCommon::eAllow;
                   if (onAnySite) {
                     choice = AntiTrackingCommon::eAllowOnAnySite;
                   } else if (autoGrant) {
                     choice = AntiTrackingCommon::eAllowAutoGrant;
                   }
-                  p->Resolve(choice, __func__);
+                  if (!autoGrant) {
+                    p->Resolve(choice, __func__);
+                  } else {
+                    sapr->MaybeDelayAutomaticGrants()->Then(
+                        GetCurrentThreadSerialEventTarget(), __func__,
+                        [p, choice] { p->Resolve(choice, __func__); },
+                        [p] { p->Reject(false, __func__); });
+                  }
                   return;
                 }
                 p->Reject(false, __func__);
                 return;
               }
 
               sapr->RequestDelayedTask(
                   inner->EventTargetFor(TaskCategory::Other),
--- a/dom/base/StorageAccessPermissionRequest.cpp
+++ b/dom/base/StorageAccessPermissionRequest.cpp
@@ -16,97 +16,113 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(Stora
                                    ContentPermissionRequestBase)
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(StorageAccessPermissionRequest,
                                                ContentPermissionRequestBase)
 
 StorageAccessPermissionRequest::StorageAccessPermissionRequest(
     nsPIDOMWindowInner* aWindow, nsIPrincipal* aNodePrincipal,
     AllowCallback&& aAllowCallback,
-    AllowAutoGrantCallback&& aAllowAutoGrantCallback,
     AllowAnySiteCallback&& aAllowAnySiteCallback,
     CancelCallback&& aCancelCallback)
     : ContentPermissionRequestBase(aNodePrincipal, aWindow,
                                    NS_LITERAL_CSTRING("dom.storage_access"),
                                    NS_LITERAL_CSTRING("storage-access")),
       mAllowCallback(std::move(aAllowCallback)),
-      mAllowAutoGrantCallback(std::move(aAllowAutoGrantCallback)),
       mAllowAnySiteCallback(std::move(aAllowAnySiteCallback)),
       mCancelCallback(std::move(aCancelCallback)),
       mCallbackCalled(false) {
   mPermissionRequests.AppendElement(
       PermissionRequest(mType, nsTArray<nsString>()));
 }
 
 StorageAccessPermissionRequest::~StorageAccessPermissionRequest() { Cancel(); }
 
 NS_IMETHODIMP
 StorageAccessPermissionRequest::Cancel() {
   if (!mCallbackCalled) {
     mCallbackCalled = true;
-    mTimer = nullptr;
     mCancelCallback();
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 StorageAccessPermissionRequest::Allow(JS::HandleValue aChoices) {
   nsTArray<PermissionChoice> choices;
   nsresult rv = TranslateChoices(aChoices, mPermissionRequests, choices);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  // There is no support to allow grants automatically from the prompting code
+  // path.
+
   if (!mCallbackCalled) {
     mCallbackCalled = true;
     if (choices.Length() == 1 &&
         choices[0].choice().EqualsLiteral("allow-on-any-site")) {
       mAllowAnySiteCallback();
     } else if (choices.Length() == 1 &&
-               choices[0].choice().EqualsLiteral("allow-auto-grant")) {
-      unsigned simulatedDelay = CalculateSimulatedDelay();
-      if (simulatedDelay) {
-        MOZ_ASSERT(!mTimer);
-        RefPtr<StorageAccessPermissionRequest> 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 {
+               choices[0].choice().EqualsLiteral("allow")) {
       mAllowCallback();
     }
   }
   return NS_OK;
 }
 
+RefPtr<StorageAccessPermissionRequest::AutoGrantDelayPromise>
+StorageAccessPermissionRequest::MaybeDelayAutomaticGrants() {
+  RefPtr<AutoGrantDelayPromise::Private> p =
+      new AutoGrantDelayPromise::Private(__func__);
+
+  unsigned simulatedDelay = CalculateSimulatedDelay();
+  if (simulatedDelay) {
+    nsCOMPtr<nsITimer> timer;
+    RefPtr<AutoGrantDelayPromise::Private> promise = p;
+    nsresult rv = NS_NewTimerWithFuncCallback(
+        getter_AddRefs(timer),
+        [](nsITimer* aTimer, void* aClosure) -> void {
+          auto* promise =
+              static_cast<AutoGrantDelayPromise::Private*>(aClosure);
+          promise->Resolve(true, __func__);
+          NS_RELEASE(aTimer);
+          NS_RELEASE(promise);
+        },
+        promise, simulatedDelay, nsITimer::TYPE_ONE_SHOT,
+        "DelayedAllowAutoGrantCallback");
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      p->Reject(false, __func__);
+    } else {
+      // Leak the references here! We'll release them inside the callback.
+      Unused << timer.forget();
+      Unused << promise.forget();
+    }
+  } else {
+    p->Resolve(false, __func__);
+  }
+  return p;
+}
+
 already_AddRefed<StorageAccessPermissionRequest>
 StorageAccessPermissionRequest::Create(
     nsPIDOMWindowInner* aWindow, AllowCallback&& aAllowCallback,
-    AllowAutoGrantCallback&& aAllowAutoGrantCallback,
     AllowAnySiteCallback&& aAllowAnySiteCallback,
     CancelCallback&& aCancelCallback) {
   if (!aWindow) {
     return nullptr;
   }
   nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(aWindow);
   if (!win->GetPrincipal()) {
     return nullptr;
   }
   RefPtr<StorageAccessPermissionRequest> request =
       new StorageAccessPermissionRequest(
           aWindow, win->GetPrincipal(), std::move(aAllowCallback),
-          std::move(aAllowAutoGrantCallback), std::move(aAllowAnySiteCallback),
-          std::move(aCancelCallback));
+          std::move(aAllowAnySiteCallback), std::move(aCancelCallback));
   return request.forget();
 }
 
 unsigned StorageAccessPermissionRequest::CalculateSimulatedDelay() {
   if (!StaticPrefs::dom_storage_access_auto_grants_delayed()) {
     return 0;
   }
 
@@ -116,18 +132,10 @@ unsigned StorageAccessPermissionRequest:
 
   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<StorageAccessPermissionRequest*>(aClosure);
-  self->mAllowAutoGrantCallback();
-  self->mTimer = nullptr;
-  NS_RELEASE(self);
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/base/StorageAccessPermissionRequest.h
+++ b/dom/base/StorageAccessPermissionRequest.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef StorageAccessPermissionRequest_h_
 #define StorageAccessPermissionRequest_h_
 
 #include "nsContentPermissionHelper.h"
+#include "mozilla/MozPromise.h"
 
 #include <functional>
 
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace dom {
 
@@ -23,44 +24,40 @@ class StorageAccessPermissionRequest fin
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(StorageAccessPermissionRequest,
                                            ContentPermissionRequestBase)
 
   // nsIContentPermissionRequest
   NS_IMETHOD Cancel(void) override;
   NS_IMETHOD Allow(JS::HandleValue choices) override;
 
   typedef std::function<void()> AllowCallback;
-  typedef std::function<void()> AllowAutoGrantCallback;
   typedef std::function<void()> AllowAnySiteCallback;
   typedef std::function<void()> CancelCallback;
 
   static already_AddRefed<StorageAccessPermissionRequest> Create(
       nsPIDOMWindowInner* aWindow, AllowCallback&& aAllowCallback,
-      AllowAutoGrantCallback&& aAllowAutoGrantCallback,
       AllowAnySiteCallback&& aAllowAnySiteCallback,
       CancelCallback&& aCancelCallback);
 
+  typedef MozPromise<bool, bool, true> AutoGrantDelayPromise;
+  RefPtr<AutoGrantDelayPromise> MaybeDelayAutomaticGrants();
+
  private:
-  StorageAccessPermissionRequest(
-      nsPIDOMWindowInner* aWindow, nsIPrincipal* aNodePrincipal,
-      AllowCallback&& aAllowCallback,
-      AllowAutoGrantCallback&& aAllowAutoGrantCallback,
-      AllowAnySiteCallback&& aAllowAnySiteCallback,
-      CancelCallback&& aCancelCallback);
+  StorageAccessPermissionRequest(nsPIDOMWindowInner* aWindow,
+                                 nsIPrincipal* aNodePrincipal,
+                                 AllowCallback&& aAllowCallback,
+                                 AllowAnySiteCallback&& aAllowAnySiteCallback,
+                                 CancelCallback&& aCancelCallback);
   ~StorageAccessPermissionRequest();
 
   unsigned CalculateSimulatedDelay();
 
-  static void CallAutoGrantCallback(nsITimer* aTimer, void* aClosure);
-
   AllowCallback mAllowCallback;
-  AllowAutoGrantCallback mAllowAutoGrantCallback;
   AllowAnySiteCallback mAllowAnySiteCallback;
   CancelCallback mCancelCallback;
-  nsCOMPtr<nsITimer> mTimer;
   nsTArray<PermissionRequest> mPermissionRequests;
   bool mCallbackCalled;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // StorageAccessPermissionRequest_h_