Bug 1491403 - Part 4: Call the resolve handler of the promise returned from Document.requestStorageAccess() and Document.hasStorageAccess() preserving the user input event handling state r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 09 Oct 2018 21:42:30 +0000
changeset 496073 ae1629a704aa5cd43caffce144d40623416773e8
parent 496072 18d88d24495acae45a381f8bf95c3ab86fe800ec
child 496074 be3c71747eff927b12bf9a79e8b57331931ef115
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1491403
milestone64.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 1491403 - Part 4: Call the resolve handler of the promise returned from Document.requestStorageAccess() and Document.hasStorageAccess() preserving the user input event handling state r=baku Depends on D7005 Differential Revision: https://phabricator.services.mozilla.com/D7006
dom/base/nsDocument.cpp
toolkit/components/antitracking/test/browser/browser.ini
toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -13722,17 +13722,19 @@ already_AddRefed<mozilla::dom::Promise>
 nsIDocument::RequestStorageAccess(mozilla::ErrorResult& aRv)
 {
   nsIGlobalObject* global = GetScopeObject();
   if (!global) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
-  RefPtr<Promise> promise = Promise::Create(global, aRv);
+  // Propagate user input event handling to the resolve handler
+  RefPtr<Promise> promise = Promise::Create(global, aRv,
+                                            Promise::ePropagateUserInteraction);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   // Step 1. If the document already has been granted access, resolve.
   nsPIDOMWindowInner* inner = GetInnerWindow();
   nsGlobalWindowOuter* outer = nullptr;
   if (inner) {
--- a/toolkit/components/antitracking/test/browser/browser.ini
+++ b/toolkit/components/antitracking/test/browser/browser.ini
@@ -48,11 +48,12 @@ skip-if = serviceworker_e10s
 skip-if = serviceworker_e10s
 [browser_subResources.js]
 support-files = subResources.sjs
 [browser_script.js]
 support-files = tracker.js
 [browser_userInteraction.js]
 [browser_storageAccessPrivateWindow.js]
 skip-if = serviceworker_e10s
+[browser_storageAccessPromiseResolveHandlerUserInteraction.js]
 [browser_storageAccessSandboxed.js]
 skip-if = serviceworker_e10s
 [browser_storageAccessWithHeuristics.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js
@@ -0,0 +1,47 @@
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+AntiTracking.runTest("Storage Access API returns promises that maintain user activation",
+  // blocking callback
+  async _ => {
+    let dwu = SpecialPowers.getDOMWindowUtils(window);
+    let helper = dwu.setHandlingUserInput(true);
+
+    let p;
+    let threw = false;
+    try {
+      p = document.requestStorageAccess();
+    } catch (e) {
+      threw = true;
+    } finally {
+      helper.destruct();
+    }
+    ok(!threw, "requestStorageAccess should not throw");
+    threw = false;
+    await p.then(() => {
+    });
+    threw = false;
+    try {
+      await p.then(() => {
+        ok(dwu.isHandlingUserInput,
+           "Promise handler must run as if we're handling user input");
+      });
+    } catch (e) {
+      threw = true;
+    }
+    ok(!threw, "requestStorageAccess should be available");
+  },
+
+  null, // non-blocking callback
+  // cleanup function
+  async _ => {
+    await new Promise(resolve => {
+      Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
+    });
+  },
+  [["dom.storage_access.enabled", true]], // extra prefs
+  false, // no window open test
+  false, // no user-interaction test
+  true, // expect blocking notifications
+  false, // run in normal window
+  null // iframe sandbox
+);