Bug 1591113 - Remove support for third-party vibrate r=baku,snorp
authorThomas Nguyen <tnguyen@mozilla.com>
Tue, 12 Nov 2019 08:42:02 +0000
changeset 501552 452d9227aee6104ef06b7cb91eb463ca6e6128d8
parent 501551 a4e17e19b2078866776be8a8998aafed47e4aad1
child 501553 cc462b36cf3ff3b17074acc8591abba3b0bedbb3
push id114170
push usermalexandru@mozilla.com
push dateTue, 12 Nov 2019 21:58:32 +0000
treeherdermozilla-inbound@9e3f44e87a1a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, snorp
bugs1591113
milestone72.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 1591113 - Remove support for third-party vibrate r=baku,snorp Differential Revision: https://phabricator.services.mozilla.com/D52531
browser/base/content/test/permissions/browser.ini
browser/base/content/test/permissions/browser_permissions_delegate_vibrate.js
browser/base/content/test/permissions/empty.html
dom/base/Navigator.cpp
extensions/permissions/PermissionDelegateHandler.cpp
--- a/browser/base/content/test/permissions/browser.ini
+++ b/browser/base/content/test/permissions/browser.ini
@@ -1,16 +1,19 @@
 [DEFAULT]
 support-files=
   head.js
   permissions.html
 
 [browser_canvas_fingerprinting_resistance.js]
 skip-if = debug || os == "linux" && asan # Bug 1522069
 [browser_permissions.js]
+[browser_permissions_delegate_vibrate.js]
+support-files=
+  empty.html
 [browser_permissions_event_telemetry.js]
 [browser_permissions_postPrompt.js]
 support-files=
   dummy.js
 [browser_permissions_handling_user_input.js]
 support-files=
   dummy.js
 [browser_reservedkey.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/permissions/browser_permissions_delegate_vibrate.js
@@ -0,0 +1,47 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const TEST_PAGE =
+  "https://example.com/browser/browser/base/content/test/permissions/empty.html";
+
+add_task(async function testNoPermissionPrompt() {
+  info("Creating tab");
+  await BrowserTestUtils.withNewTab(TEST_PAGE, async function(browser) {
+    await new Promise(r => {
+      SpecialPowers.pushPrefEnv(
+        {
+          set: [
+            ["dom.security.featurePolicy.enabled", true],
+            ["permissions.delegation.enable", true],
+            ["dom.vibrator.enabled", true],
+            ["dom.security.featurePolicy.header.enabled", true],
+            ["dom.security.featurePolicy.webidl.enabled", true],
+          ],
+        },
+        r
+      );
+    });
+
+    await ContentTask.spawn(browser, null, async function() {
+      let frame = content.document.createElement("iframe");
+      // Cross origin src
+      frame.src =
+        "https://example.org/browser/browser/base/content/test/permissions/empty.html";
+      await new Promise(resolve => {
+        frame.addEventListener("load", () => {
+          resolve();
+        });
+        content.document.body.appendChild(frame);
+      });
+
+      await content.SpecialPowers.spawn(frame, [], async function() {
+        // Request a permission.
+        let result = this.content.navigator.vibrate([100, 100]);
+        Assert.equal(result, false, "navigator.vibrate has been denied");
+      });
+      content.document.body.removeChild(frame);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/permissions/empty.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Empty file</title>
+</head>
+<body>
+</body>
+</html>
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -72,16 +72,17 @@
 #include "nsIStringStream.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsStreamUtils.h"
 #include "WidgetUtils.h"
 #include "nsIPresentationService.h"
 #include "nsIScriptError.h"
 #include "ReferrerInfo.h"
+#include "PermissionDelegateHandler.h"
 
 #include "nsIExternalProtocolHandler.h"
 #include "BrowserChild.h"
 #include "URIUtils.h"
 
 #include "mozilla/dom/MediaDevices.h"
 #include "MediaManager.h"
 
@@ -766,43 +767,49 @@ bool Navigator::Vibrate(const nsTArray<u
 
   // The spec says we check sVibratorEnabled after we've done the sanity
   // checking on the pattern.
   if (!sVibratorEnabled) {
     return true;
   }
 
   mRequestedVibrationPattern.SwapElements(pattern);
-  nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
-  if (!permMgr) {
+
+  PermissionDelegateHandler* permissionHandler =
+      doc->GetPermissionDelegateHandler();
+  if (NS_WARN_IF(!permissionHandler)) {
     return false;
   }
 
   uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
 
-  permMgr->TestPermissionFromPrincipal(doc->NodePrincipal(),
-                                       kVibrationPermissionType, &permission);
+  permissionHandler->GetPermission(kVibrationPermissionType, &permission,
+                                   false);
+
+  if (permission == nsIPermissionManager::DENY_ACTION) {
+    // Abort without observer service or on denied session permission.
+    SetVibrationPermission(false /* permitted */, false /* persistent */);
+    return false;
+  }
 
   if (permission == nsIPermissionManager::ALLOW_ACTION ||
       mRequestedVibrationPattern.IsEmpty() ||
       (mRequestedVibrationPattern.Length() == 1 &&
        mRequestedVibrationPattern[0] == 0)) {
     // Always allow cancelling vibration and respect session permissions.
     SetVibrationPermission(true /* permitted */, false /* persistent */);
     return true;
   }
 
+  // Request user permission.
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
-  if (!obs || permission == nsIPermissionManager::DENY_ACTION) {
-    // Abort without observer service or on denied session permission.
-    SetVibrationPermission(false /* permitted */, false /* persistent */);
+  if (!obs) {
     return true;
   }
 
-  // Request user permission.
   obs->NotifyObservers(ToSupports(this), "Vibration:Request", nullptr);
 
   return true;
 }
 
 //*****************************************************************************
 //  Pointer Events interface
 //*****************************************************************************
--- a/extensions/permissions/PermissionDelegateHandler.cpp
+++ b/extensions/permissions/PermissionDelegateHandler.cpp
@@ -26,16 +26,17 @@ static const DelegateInfo sPermissionsMa
     // Permissions API map
     {"geo", u"geolocation", DelegatePolicy::eDelegateUseFeaturePolicy},
     // The same with geo, but we support both to save some conversions between
     // "geo" and "geolocation"
     {"geolocation", u"geolocation", DelegatePolicy::eDelegateUseFeaturePolicy},
     {"desktop-notification", nullptr,
      DelegatePolicy::ePersistDeniedCrossOrigin},
     {"persistent-storage", nullptr, DelegatePolicy::ePersistDeniedCrossOrigin},
+    {"vibration", nullptr, DelegatePolicy::ePersistDeniedCrossOrigin},
 };
 
 NS_IMPL_CYCLE_COLLECTION(PermissionDelegateHandler)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(PermissionDelegateHandler)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(PermissionDelegateHandler)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PermissionDelegateHandler)
   NS_INTERFACE_MAP_ENTRY(nsISupports)