--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -72,17 +72,18 @@ Preferences.addAll([
{ id: "network.cookie.blockFutureCookies", type: "bool" },
// Clear Private Data
{ id: "privacy.sanitize.sanitizeOnShutdown", type: "bool" },
{ id: "privacy.sanitize.timeSpan", type: "int" },
// Do not track
{ id: "privacy.donottrackheader.enabled", type: "bool" },
// Media
- { id: "media.autoplay.enabled", type: "bool" },
+ { id: "media.autoplay.default", type: "int" },
+ { id: "media.autoplay.enabled.ask-permission", type: "bool" },
{ id: "media.autoplay.enabled.user-gestures-needed", type: "bool" },
// Popups
{ id: "dom.disable_open_during_load", type: "bool" },
// Passwords
{ id: "signon.rememberSignons", type: "bool" },
// Buttons
@@ -253,17 +254,16 @@ var gPrivacyPane = {
init() {
function setEventListener(aId, aEventType, aCallback) {
document.getElementById(aId)
.addEventListener(aEventType, aCallback.bind(gPrivacyPane));
}
this._updateSanitizeSettingsButton();
this.initializeHistoryMode();
- this.updateAutoplayMediaControls();
this.updateAutoplayMediaControlsVisibility();
this.updateHistoryModePane();
this.updatePrivacyMicroControls();
this.initAutoStartPrivateBrowsingReverter();
this._initTrackingProtection();
this._initTrackingProtectionPBM();
this._initTrackingProtectionExtensionControl();
this._initAutocomplete();
@@ -271,18 +271,18 @@ var gPrivacyPane = {
Preferences.get("privacy.sanitize.sanitizeOnShutdown").on("change",
gPrivacyPane._updateSanitizeSettingsButton.bind(gPrivacyPane));
Preferences.get("browser.privatebrowsing.autostart").on("change",
gPrivacyPane.updatePrivacyMicroControls.bind(gPrivacyPane));
Preferences.get("privacy.trackingprotection.enabled").on("change",
gPrivacyPane.trackingProtectionReadPrefs.bind(gPrivacyPane));
Preferences.get("privacy.trackingprotection.pbmode.enabled").on("change",
gPrivacyPane.trackingProtectionReadPrefs.bind(gPrivacyPane));
- Preferences.get("media.autoplay.enabled").on("change",
- gPrivacyPane.updateAutoplayMediaControls.bind(gPrivacyPane));
+ Preferences.get("media.autoplay.enabled.ask-permission").on("change",
+ gPrivacyPane.updateAutoplayMediaControlsVisibility.bind(gPrivacyPane));
Preferences.get("media.autoplay.enabled.user-gestures-needed").on("change",
gPrivacyPane.updateAutoplayMediaControlsVisibility.bind(gPrivacyPane));
setEventListener("historyMode", "command", function() {
gPrivacyPane.updateHistoryModePane();
gPrivacyPane.updateHistoryModePrefs();
gPrivacyPane.updatePrivacyMicroControls();
gPrivacyPane.updateAutostart();
});
@@ -337,20 +337,22 @@ var gPrivacyPane = {
setEventListener("locationSettingsButton", "command",
gPrivacyPane.showLocationExceptions);
setEventListener("cameraSettingsButton", "command",
gPrivacyPane.showCameraExceptions);
setEventListener("microphoneSettingsButton", "command",
gPrivacyPane.showMicrophoneExceptions);
setEventListener("popupPolicyButton", "command",
gPrivacyPane.showPopupExceptions);
- setEventListener("autoplayMediaPolicy", "command",
+ setEventListener("autoplayMediaCheckbox", "command",
gPrivacyPane.toggleAutoplayMedia);
setEventListener("autoplayMediaPolicyButton", "command",
gPrivacyPane.showAutoplayMediaExceptions);
+ setEventListener("autoplayMediaPolicyComboboxButton", "command",
+ gPrivacyPane.showAutoplayMediaExceptions);
setEventListener("notificationsDoNotDisturb", "command",
gPrivacyPane.toggleDoNotDisturbNotifications);
if (AlertsServiceDND) {
let notificationsDoNotDisturbBox =
document.getElementById("notificationsDoNotDisturbBox");
notificationsDoNotDisturbBox.removeAttribute("hidden");
let checkbox = document.getElementById("notificationsDoNotDisturb");
@@ -983,44 +985,53 @@ var gPrivacyPane = {
.getHistogramById("WEB_NOTIFICATION_EXCEPTIONS_OPENED").add();
} catch (e) { }
},
// MEDIA
/**
- * media.autoplay.enabled works the opposite to most of the other preferences.
- * The checkbox enabled sets the pref to false
+ * The checkbox enabled sets the pref to BLOCKED
*/
toggleAutoplayMedia(event) {
- Services.prefs.setBoolPref("media.autoplay.enabled", !event.target.checked);
- },
-
- updateAutoplayMediaControls() {
- let autoPlayEnabled = Preferences.get("media.autoplay.enabled").value;
- document.getElementById("autoplayMediaPolicy").checked = !autoPlayEnabled;
- document.getElementById("autoplayMediaPolicyButton").disabled = autoPlayEnabled;
+ let blocked = event.target.checked ? Ci.nsIAutoplay.BLOCKED : Ci.nsIAutoplay.ALLOWED;
+ Services.prefs.setIntPref("media.autoplay.default", blocked);
},
/**
- * Show the controls for the new media autoplay behaviour behind a pref for now
+ * If user-gestures-needed is false we do not show any UI for configuring autoplay,
+ * if user-gestures-needed is false and ask-permission is false we show a checkbox
+ * which only allows the user to block autoplay
+ * if user-gestures-needed and ask-permission are true we show a combobox that
+ * allows the user to block / allow or prompt for autoplay
+ * We will be performing a shield study to determine the behaviour to be
+ * shipped, at which point we can remove these pref switches.
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1475099
*/
updateAutoplayMediaControlsVisibility() {
- document.getElementById("autoplayMediaBox").hidden =
- !Services.prefs.getBoolPref("media.autoplay.enabled.user-gestures-needed", false);
+ let askPermission =
+ Services.prefs.getBoolPref("media.autoplay.ask-permission", false);
+ let userGestures =
+ Services.prefs.getBoolPref("media.autoplay.enabled.user-gestures-needed", false);
+ // Hide the combobox if we don't let the user ask for permission.
+ document.getElementById("autoplayMediaComboboxWrapper").hidden =
+ !userGestures || !askPermission;
+ // If the user may ask for permission, hide the checkbox instead.
+ document.getElementById("autoplayMediaCheckboxWrapper").hidden =
+ !userGestures || askPermission;
},
/**
* Displays the autoplay exceptions dialog where specific site autoplay preferences
* can be set.
*/
showAutoplayMediaExceptions() {
var params = {
- blockVisible: false, sessionVisible: false, allowVisible: true,
+ blockVisible: true, sessionVisible: false, allowVisible: true,
prefilledHost: "", permissionType: "autoplay-media"
};
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
"resizable=yes", params);
},
// POP-UPS
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -491,18 +491,18 @@
</grid>
<vbox id="notificationsDoNotDisturbBox" hidden="true">
<checkbox id="notificationsDoNotDisturb" class="indent"/>
</vbox>
<separator flex="1"/>
- <hbox align="start" id="autoplayMediaBox" hidden="true">
- <checkbox id="autoplayMediaPolicy"
+ <hbox align="start" id="autoplayMediaCheckboxWrapper" hidden="true">
+ <checkbox id="autoplayMediaCheckbox"
data-l10n-id="permissions-block-autoplay-media"
flex="1" />
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="autoplayMediaPolicyButton"
class="accessory-button"
data-l10n-id="permissions-block-autoplay-media-exceptions"
search-l10n-ids="permissions-address,
@@ -563,16 +563,47 @@
<hbox flex="1" align="center">
<checkbox id="a11yPrivacyCheckbox" class="tail-with-learn-more"
data-l10n-id="permissions-a11y-privacy-checkbox"
oncommand="return gPrivacyPane.updateA11yPrefs(this.checked)"/>
<label id="a11yLearnMoreLink" class="learnMore text-link"
data-l10n-id="permissions-a11y-privacy-link"/>
</hbox>
</vbox>
+
+ <hbox align="center" id="autoplayMediaComboboxWrapper" hidden="true">
+ <hbox align="center" flex="1">
+ <label id="autoplayMediaPolicy"
+ control="autoplayMediaPolicyMenu"
+ data-l10n-id="permissions-block-autoplay-media-menu"/>
+ <menulist id="autoplayMediaPolicyMenu"
+ sizetopopup="always"
+ preference="media.autoplay.default">
+ <menupopup>
+ <!-- Defined in dom/media/nsIAutoplay.idl -->
+ <menuitem data-l10n-id="autoplay-option-allow" value="0"/>
+ <menuitem data-l10n-id="autoplay-option-ask" value="2"/>
+ <menuitem data-l10n-id="autoplay-option-block" value="1"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+
+ <hbox pack="end">
+ <button id="autoplayMediaPolicyComboboxButton"
+ class="accessory-button"
+ data-l10n-id="permissions-block-autoplay-media-exceptions"
+ search-l10n-ids="permissions-address,
+ permissions-button-cancel.label,
+ permissions-button-ok.label,
+ permissions-exceptions-autoplay-media-window.title,
+ permissions-exceptions-autoplay-media-desc
+ " />
+ </hbox>
+ </hbox>
+
</groupbox>
<!-- Firefox Data Collection and Use -->
#ifdef MOZ_DATA_REPORTING
<hbox id="dataCollectionCategory"
class="subcategory"
hidden="true"
data-category="panePrivacy">
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -78,16 +78,17 @@ run-if = nightly_build
[browser_sanitizeOnShutdown_prefLocked.js]
[browser_searchShowSuggestionsFirst.js]
[browser_searchsuggestions.js]
[browser_security-1.js]
[browser_security-2.js]
[browser_spotlight.js]
[browser_site_login_exceptions.js]
[browser_site_autoplay_media_exceptions.js]
+[browser_site_autoplay_media_prompt.js]
[browser_permissions_dialog.js]
[browser_subdialogs.js]
support-files =
subdialog.xul
subdialog2.xul
[browser_sync_sanitize.js]
[browser_telemetry.js]
# Skip this test on Android as FHR and Telemetry are separate systems there.
--- a/browser/components/preferences/in-content/tests/browser_site_autoplay_media_exceptions.js
+++ b/browser/components/preferences/in-content/tests/browser_site_autoplay_media_exceptions.js
@@ -2,58 +2,62 @@
ChromeUtils.import("resource:///modules/SitePermissions.jsm");
const URL = "http://www.example.com";
const PRINCIPAL = Services.scriptSecurityManager
.createCodebasePrincipal(Services.io.newURI(URL), {});
const PERMISSIONS_URL = "chrome://browser/content/preferences/permissions.xul";
-const AUTOPLAY_ENABLED_KEY = "media.autoplay.enabled";
+const AUTOPLAY_ENABLED_KEY = "media.autoplay.default";
const GESTURES_NEEDED_KEY = "media.autoplay.enabled.user-gestures-needed";
+const ASK_PERMISSIONS_KEY = "media.autoplay.enabled.ask-permissions";
var exceptionsDialog;
-Services.prefs.setBoolPref(AUTOPLAY_ENABLED_KEY, true);
+Services.prefs.setIntPref(AUTOPLAY_ENABLED_KEY, Ci.nsIAutoplay.ALLOWED);
Services.prefs.setBoolPref(GESTURES_NEEDED_KEY, false);
+Services.prefs.setBoolPref(ASK_PERMISSIONS_KEY, true);
async function openExceptionsDialog() {
let dialogOpened = promiseLoadSubDialog(PERMISSIONS_URL);
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
let exceptionsButton = content.document.getElementById("autoplayMediaPolicyButton");
exceptionsButton.click();
});
exceptionsDialog = await dialogOpened;
}
add_task(async function ensureCheckboxHidden() {
registerCleanupFunction(async function() {
Services.prefs.clearUserPref(AUTOPLAY_ENABLED_KEY);
Services.prefs.clearUserPref(GESTURES_NEEDED_KEY);
+ Services.prefs.clearUserPref(ASK_PERMISSIONS_KEY);
gBrowser.removeCurrentTab();
});
await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
let win = gBrowser.selectedBrowser.contentWindow;
is_element_hidden(win.document.getElementById("autoplayMediaPolicy"),
"Ensure checkbox is hidden when preffed off");
});
add_task(async function enableBlockingAutoplay() {
Services.prefs.setBoolPref(GESTURES_NEEDED_KEY, true);
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
let doc = content.document;
- let autoplayCheckBox = doc.getElementById("autoplayMediaPolicy");
+ let autoplayCheckBox = doc.getElementById("autoplayMediaCheckbox");
autoplayCheckBox.click();
});
- Assert.equal(Services.prefs.getBoolPref(AUTOPLAY_ENABLED_KEY), false,
+ Assert.equal(Services.prefs.getIntPref(AUTOPLAY_ENABLED_KEY),
+ Ci.nsIAutoplay.BLOCKED,
"Ensure we have set autoplay to false");
});
add_task(async function addException() {
await openExceptionsDialog();
let doc = exceptionsDialog.document;
let richlistbox = doc.getElementById("permissionsBox");
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_site_autoplay_media_prompt.js
@@ -0,0 +1,114 @@
+"use strict";
+
+ChromeUtils.import("resource:///modules/SitePermissions.jsm");
+
+const URL = "http://www.example.com";
+const PRINCIPAL = Services.scriptSecurityManager
+ .createCodebasePrincipal(Services.io.newURI(URL), {});
+
+const PERMISSIONS_URL = "chrome://browser/content/preferences/permissions.xul";
+const AUTOPLAY_ENABLED_KEY = "media.autoplay.default";
+const GESTURES_NEEDED_KEY = "media.autoplay.enabled.user-gestures-needed";
+const ASK_PERMISSIONS_KEY = "media.autoplay.enabled.ask-permissions";
+
+var exceptionsDialog;
+
+Services.prefs.setIntPref(AUTOPLAY_ENABLED_KEY, Ci.nsIAutoplay.ALLOWED);
+Services.prefs.setBoolPref(GESTURES_NEEDED_KEY, false);
+Services.prefs.setBoolPref(ASK_PERMISSIONS_KEY, true);
+
+async function openExceptionsDialog() {
+ let dialogOpened = promiseLoadSubDialog(PERMISSIONS_URL);
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ let exceptionsButton = content.document.getElementById("autoplayMediaPolicyButton");
+ exceptionsButton.click();
+ });
+ exceptionsDialog = await dialogOpened;
+}
+
+add_task(async function ensureMenuHidden() {
+
+ registerCleanupFunction(async function() {
+ Services.prefs.clearUserPref(AUTOPLAY_ENABLED_KEY);
+ Services.prefs.clearUserPref(GESTURES_NEEDED_KEY);
+ Services.prefs.clearUserPref(ASK_PERMISSIONS_KEY);
+ gBrowser.removeCurrentTab();
+ });
+
+ await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
+ let win = gBrowser.selectedBrowser.contentWindow;
+ is_element_hidden(win.document.getElementById("autoplayMediaPolicy"),
+ "Ensure checkbox is hidden when preffed off");
+});
+
+add_task(async function enableBlockingAutoplay() {
+
+ Services.prefs.setBoolPref(GESTURES_NEEDED_KEY, true);
+
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ let doc = content.document;
+ let autoplayMenu = doc.getElementById("autoplayMediaPolicyMenu");
+ autoplayMenu.click();
+ let askMenuItem = autoplayMenu.childNodes[0].childNodes[1];
+ askMenuItem.click();
+ });
+
+ Assert.equal(Services.prefs.getIntPref(AUTOPLAY_ENABLED_KEY),
+ Ci.nsIAutoplay.PROMPT,
+ "Ensure we have set autoplay to false");
+});
+
+add_task(async function addException() {
+ await openExceptionsDialog();
+ let doc = exceptionsDialog.document;
+
+ let richlistbox = doc.getElementById("permissionsBox");
+ Assert.equal(richlistbox.itemCount, 0, "Row count should initially be 0");
+
+ let inputBox = doc.getElementById("url");
+ inputBox.focus();
+
+ EventUtils.sendString(URL, exceptionsDialog);
+
+ let btnAllow = doc.getElementById("btnAllow");
+ btnAllow.click();
+
+ await TestUtils.waitForCondition(() => richlistbox.itemCount == 1);
+ Assert.equal(richlistbox.getItemAtIndex(0).getAttribute("origin"), URL);
+
+ let permChanged = TestUtils.topicObserved("perm-changed");
+ let btnApplyChanges = doc.getElementById("btnApplyChanges");
+ btnApplyChanges.click();
+ await permChanged;
+
+ is(Services.perms.testPermissionFromPrincipal(PRINCIPAL, "autoplay-media"),
+ Ci.nsIPermissionManager.ALLOW_ACTION, "Correctly added the exception");
+});
+
+add_task(async function deleteException() {
+ await openExceptionsDialog();
+ let doc = exceptionsDialog.document;
+
+ let richlistbox = doc.getElementById("permissionsBox");
+ Assert.equal(richlistbox.itemCount, 1, "Row count should initially be 1");
+ richlistbox.focus();
+ richlistbox.selectedIndex = 0;
+
+ if (AppConstants.platform == "macosx") {
+ EventUtils.synthesizeKey("KEY_Backspace");
+ } else {
+ EventUtils.synthesizeKey("KEY_Delete");
+ }
+
+ await TestUtils.waitForCondition(() => richlistbox.itemCount == 0);
+ is_element_visible(content.gSubDialog._dialogs[0]._box,
+ "Subdialog is visible after deleting an element");
+
+ let permChanged = TestUtils.topicObserved("perm-changed");
+ let btnApplyChanges = doc.getElementById("btnApplyChanges");
+ btnApplyChanges.click();
+ await permChanged;
+
+ is(Services.perms.testPermissionFromPrincipal(PRINCIPAL, "autoplay-media"),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION, "Correctly removed the exception");
+});
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -844,20 +844,29 @@ permissions-notification-link = Learn mo
permissions-notification-pause =
.label = Pause notifications until { -brand-short-name } restarts
.accesskey = n
permissions-block-autoplay-media =
.label = Block websites from automatically playing media with sound
.accesskey = B
+permissions-block-autoplay-media-menu = For websites that autoplay sound
+
permissions-block-autoplay-media-exceptions =
.label = Exceptions…
.accesskey = E
+autoplay-option-ask =
+ .label = Always Ask
+autoplay-option-allow =
+ .label = Allow Autoplay
+autoplay-option-block =
+ .label = Block Autoplay
+
permissions-block-popups =
.label = Block pop-up windows
.accesskey = B
permissions-block-popups-exceptions =
.label = Exceptions…
.accesskey = E
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -603,18 +603,22 @@ var gPermissionObject = {
* Defaults to ALLOW, BLOCK and the default state (see getDefault).
* The PROMPT_HIDE state is deliberately excluded from "plugin:flash" since we
* don't want to expose a "Hide Prompt" button to the user through pageinfo.
*/
"autoplay-media": {
exactHostMatch: true,
getDefault() {
- if (Services.prefs.getBoolPref("media.autoplay.enabled")) {
+ let state = Services.prefs.getIntPref("media.autoplay.default",
+ Ci.nsIAutoplay.PROMPT);
+ if (state == Ci.nsIAutoplay.ALLOW) {
return SitePermissions.ALLOW;
+ } if (state == Ci.nsIAutoplay.BLOCK) {
+ return SitePermissions.DENY;
}
return SitePermissions.UNKNOWN;
},
labelID: "autoplay-media"
},
"image": {
states: [ SitePermissions.ALLOW, SitePermissions.BLOCK ],
--- a/browser/modules/test/browser/browser_PermissionUI_prompts.js
+++ b/browser/modules/test/browser/browser_PermissionUI_prompts.js
@@ -27,19 +27,19 @@ add_task(async function test_persistent_
// Tests that MidiPrompt works as expected
add_task(async function test_midi_permission_prompt() {
await testPrompt(PermissionUI.MIDIPermissionPrompt);
});
// Tests that AutoplayPermissionPrompt works as expected
add_task(async function test_autoplay_permission_prompt() {
- Services.prefs.setBoolPref("media.autoplay.enabled", false);
+ Services.prefs.setIntPref("media.autoplay.default", Ci.nsIAutoplay.PROMPT);
await testPrompt(PermissionUI.AutoplayPermissionPrompt);
- Services.prefs.clearUserPref("media.autoplay.enabled");
+ Services.prefs.clearUserPref("media.autoplay.default");
});
async function testPrompt(Prompt) {
await BrowserTestUtils.withNewTab({
gBrowser,
url: "http://example.com",
}, async function(browser) {
let mockRequest = makeMockPermissionRequest(browser);
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -82,16 +82,17 @@
#include "nsContentUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDisplayList.h"
#include "nsDocShell.h"
#include "nsError.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
#include "nsIAsyncVerifyRedirectCallback.h"
+#include "nsIAutoplay.h"
#include "nsICachingChannel.h"
#include "nsICategoryManager.h"
#include "nsIClassOfService.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
@@ -1993,17 +1994,17 @@ HTMLMediaElement::Load()
"ownerDoc=%p (%s) ownerDocUserActivated=%d "
"muted=%d volume=%f",
this,
!!mSrcAttrStream,
HasAttr(kNameSpaceID_None, nsGkAtoms::src),
HasSourceChildren(this),
EventStateManager::IsHandlingUserInput(),
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay),
- AutoplayPolicy::IsAllowedToPlay(*this) == Authorization::Allowed,
+ AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED,
OwnerDoc(),
DocumentOrigin(OwnerDoc()).get(),
OwnerDoc() ? OwnerDoc()->HasBeenUserGestureActivated() : 0,
mMuted,
mVolume));
if (mIsRunningLoadMethod) {
return;
@@ -2515,17 +2516,17 @@ HTMLMediaElement::ResumeLoad(PreloadActi
}
void
HTMLMediaElement::UpdatePreloadAction()
{
PreloadAction nextAction = PRELOAD_UNDEFINED;
// If autoplay is set, or we're playing, we should always preload data,
// as we'll need it to play.
- if ((AutoplayPolicy::IsAllowedToPlay(*this) == Authorization::Allowed &&
+ if ((AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED &&
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
!mPaused) {
nextAction = HTMLMediaElement::PRELOAD_ENOUGH;
} else {
// Find the appropriate preload action by looking at the attribute.
const nsAttrValue* val =
mAttrsAndChildren.GetAttr(nsGkAtoms::preload, kNameSpaceID_None);
// MSE doesn't work if preload is none, so it ignores the pref when src is
@@ -3048,17 +3049,17 @@ HTMLMediaElement::SetMutedInternal(uint3
}
void
HTMLMediaElement::PauseIfShouldNotBePlaying()
{
if (GetPaused()) {
return;
}
- if (AutoplayPolicy::IsAllowedToPlay(*this) != Authorization::Allowed) {
+ if (AutoplayPolicy::IsAllowedToPlay(*this) != nsIAutoplay::ALLOWED) {
ErrorResult rv;
Pause(rv);
}
}
void
HTMLMediaElement::SetVolumeInternal()
{
@@ -4059,31 +4060,31 @@ HTMLMediaElement::Play(ErrorResult& aRv)
if (StaticPrefs::MediaBlockEventEnabled()) {
DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
}
return promise.forget();
}
const bool handlingUserInput = EventStateManager::IsHandlingUserInput();
switch (AutoplayPolicy::IsAllowedToPlay(*this)) {
- case Authorization::Allowed: {
+ case nsIAutoplay::ALLOWED: {
mPendingPlayPromises.AppendElement(promise);
PlayInternal(handlingUserInput);
UpdateCustomPolicyAfterPlayed();
break;
}
- case Authorization::Blocked: {
+ case nsIAutoplay::BLOCKED: {
LOG(LogLevel::Debug, ("%p play not blocked.", this));
promise->MaybeReject(NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR);
if (StaticPrefs::MediaBlockEventEnabled()) {
DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
}
break;
}
- case Authorization::Prompt: {
+ case nsIAutoplay::PROMPT: {
// Prompt the user for permission to play.
mPendingPlayPromises.AppendElement(promise);
EnsureAutoplayRequested(handlingUserInput);
break;
}
}
return promise.forget();
}
@@ -6122,17 +6123,17 @@ HTMLMediaElement::ChangeReadyState(nsMed
mLoadedDataFired = true;
}
if (oldState < HAVE_FUTURE_DATA && mReadyState >= HAVE_FUTURE_DATA) {
DispatchAsyncEvent(NS_LITERAL_STRING("canplay"));
if (!mPaused) {
if (mDecoder && !mPausedForInactiveDocumentOrChannel) {
MOZ_ASSERT(AutoplayPolicy::IsAllowedToPlay(*this) ==
- Authorization::Allowed);
+ nsIAutoplay::ALLOWED);
mDecoder->Play();
}
NotifyAboutPlaying();
}
}
CheckAutoplayDataReady();
@@ -6234,22 +6235,22 @@ HTMLMediaElement::CanActivateAutoplay()
void
HTMLMediaElement::CheckAutoplayDataReady()
{
if (!CanActivateAutoplay()) {
return;
}
switch (AutoplayPolicy::IsAllowedToPlay(*this)) {
- case Authorization::Blocked:
+ case nsIAutoplay::BLOCKED:
return;
- case Authorization::Prompt:
+ case nsIAutoplay::PROMPT:
EnsureAutoplayRequested(false);
return;
- case Authorization::Allowed:
+ case nsIAutoplay::ALLOWED:
break;
}
mPaused = false;
// We changed mPaused which can affect AddRemoveSelfReference
AddRemoveSelfReference();
UpdateSrcMediaStreamPlaying();
UpdateAudioChannelPlayingState();
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -7,16 +7,17 @@
#include "AutoplayPolicy.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/AudioContext.h"
#include "mozilla/AutoplayPermissionManager.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLMediaElementBinding.h"
+#include "nsIAutoplay.h"
#include "nsContentUtils.h"
#include "nsIDocument.h"
#include "MediaManager.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
@@ -83,52 +84,57 @@ AutoplayPolicy::RequestFor(const nsIDocu
}
nsPIDOMWindowInner* window = document->GetInnerWindow();
if (!window) {
return nullptr;
}
return window->GetAutoplayPermissionManager();
}
-/* static */ Authorization
+static uint32_t
+DefaultAutoplayBehaviour()
+{
+ int prefValue = Preferences::GetInt("media.autoplay.default", nsIAutoplay::ALLOWED);
+ if (prefValue < nsIAutoplay::ALLOWED || prefValue > nsIAutoplay::PROMPT) {
+ // Invalid pref values are just converted to ALLOWED.
+ return nsIAutoplay::ALLOWED;
+ }
+ return prefValue;
+}
+
+/* static */ uint32_t
AutoplayPolicy::IsAllowedToPlay(const HTMLMediaElement& aElement)
{
- if (Preferences::GetBool("media.autoplay.enabled")) {
- return Authorization::Allowed;
- }
-
+ const uint32_t autoplayDefault = DefaultAutoplayBehaviour();
// TODO : this old way would be removed when user-gestures-needed becomes
// as a default option to block autoplay.
if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
// If element is blessed, it would always be allowed to play().
- return (aElement.IsBlessed() || EventStateManager::IsHandlingUserInput())
- ? Authorization::Allowed
- : Authorization::Blocked;
+ return (autoplayDefault == nsIAutoplay::ALLOWED ||
+ aElement.IsBlessed() ||
+ EventStateManager::IsHandlingUserInput())
+ ? nsIAutoplay::ALLOWED : nsIAutoplay::BLOCKED;
}
// Muted content
if (aElement.Volume() == 0.0 || aElement.Muted()) {
- return Authorization::Allowed;
+ return nsIAutoplay::ALLOWED;
}
if (IsWindowAllowedToPlay(aElement.OwnerDoc()->GetInnerWindow())) {
- return Authorization::Allowed;
+ return nsIAutoplay::ALLOWED;
}
- if (Preferences::GetBool("media.autoplay.ask-permission", false)) {
- return Authorization::Prompt;
- }
-
- return Authorization::Blocked;
+ return autoplayDefault;
}
/* static */ bool
AutoplayPolicy::IsAudioContextAllowedToPlay(NotNull<AudioContext*> aContext)
{
- if (Preferences::GetBool("media.autoplay.enabled")) {
+ if (DefaultAutoplayBehaviour() == nsIAutoplay::ALLOWED) {
return true;
}
if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
return true;
}
// Offline context won't directly output sound to audio devices.
--- a/dom/media/AutoplayPolicy.h
+++ b/dom/media/AutoplayPolicy.h
@@ -15,40 +15,33 @@ namespace mozilla {
class AutoplayPermissionManager;
namespace dom {
class HTMLMediaElement;
class AudioContext;
-enum class Authorization
-{
- Allowed,
- Blocked,
- Prompt
-};
-
/**
* AutoplayPolicy is used to manage autoplay logic for all kinds of media,
* including MediaElement, Web Audio and Web Speech.
*
- * Autoplay could be disable by turn off the pref "media.autoplay.enabled".
- * Once user disable autoplay, media could only be played if one of following
- * conditions is true.
+ * Autoplay could be disable by setting the pref "media.autoplay.default"
+ * to anything but nsIAutoplay::Allowed. Once user disables autoplay, media
+ * could only be played if one of following conditions is true.
* 1) Owner document is activated by user gestures
* We restrict user gestures to "mouse click", "keyboard press" and "touch".
* 2) Muted media content or video without audio content.
* 3) Document's origin has the "autoplay-media" permission.
*/
class AutoplayPolicy
{
public:
// Returns whether a given media element is allowed to play.
- static Authorization IsAllowedToPlay(const HTMLMediaElement& aElement);
+ static uint32_t IsAllowedToPlay(const HTMLMediaElement& aElement);
// Returns whether a given AudioContext is allowed to play.
static bool IsAudioContextAllowedToPlay(NotNull<AudioContext*> aContext);
// Returns the AutoplayPermissionManager that a given document must request on
// for autoplay permission.
static already_AddRefed<AutoplayPermissionManager> RequestFor(
const nsIDocument& aDocument);
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -76,16 +76,17 @@ MOCHITEST_MANIFESTS += [
if CONFIG['MOZ_WEBRTC']:
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
WEBRTC_SIGNALLING_TEST_MANIFESTS += ['tests/mochitest/steeplechase.ini']
WEBRTC_SIGNALLING_TEST_MANIFESTS += ['tests/mochitest/steeplechase_long/steeplechase_long.ini']
XPIDL_SOURCES += [
'nsIAudioDeviceInfo.idl',
+ 'nsIAutoplay.idl',
'nsIDOMNavigatorUserMedia.idl',
'nsIMediaManager.idl',
]
XPIDL_MODULE = 'dom_media'
EXPORTS += [
'ADTSDecoder.h',
new file mode 100644
--- /dev/null
+++ b/dom/media/nsIAutoplay.idl
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(048a24f6-c4d6-47bc-bea2-f6038d1db80a)]
+interface nsIAutoplay : nsISupports
+{
+ /*
+ * Possible values for the "media.autoplay.default" preference.
+ */
+ const uint32_t ALLOWED = 0;
+ const uint32_t BLOCKED = 1;
+ const uint32_t PROMPT = 2;
+};
--- a/dom/media/test/test_autoplay_policy.html
+++ b/dom/media/test/test_autoplay_policy.html
@@ -9,17 +9,17 @@
</head>
<body>
<pre id="test">
<script>
let manager = new MediaTestManager;
-gTestPrefs.push(["media.autoplay.enabled", false],
+gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
window.info = function(msg, token) {
SimpleTest.info(msg + ", token=" + token);
}
window.is = function(valA, valB, msg, token) {
SimpleTest.is(valA, valB, msg + ", token=" + token);
@@ -66,17 +66,17 @@ function createTestArray()
}
}
return tests;
}
/**
* Main test function for different autoplay cases without user interaction.
*
- * When the pref "media.autoplay.enabled" is false and the pref
+ * When the pref "media.autoplay.default" is 1 and the pref
* "media.autoplay.enabled.user-gestures-needed" is true, we only allow
* audible media to autoplay after the website has been activated by specific
* user gestures. However, inaudible media won't be restricted.
*
* Audible means the volume is non zero and muted is false.
*
* Inaudible means the volume is zero, or the muted is true.
*
@@ -147,9 +147,9 @@ async function testAutoplayKeyword(test,
} else {
await once(element, "play");
ok(!element.paused, `start with 'autoplay' keyword for ${state} media`, token);
}
removeNodeAndSource(element);
}
-</script>
\ No newline at end of file
+</script>
--- a/dom/media/test/test_autoplay_policy_activation.html
+++ b/dom/media/test/test_autoplay_policy_activation.html
@@ -9,17 +9,17 @@
</head>
<body>
<pre id="test">
<script>
// Tests that videos can only play audibly in windows/frames
// which have been activated by same-origin user gesture.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({'set': gTestPrefs}, () => {
runTest();
});
let test_cases = [
{
--- a/dom/media/test/test_autoplay_policy_eventdown_activation.html
+++ b/dom/media/test/test_autoplay_policy_eventdown_activation.html
@@ -10,17 +10,17 @@
</head>
<body>
<pre id="test">
<script>
// Tests that we gesture activate on mousedown and keydown.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({ 'set': gTestPrefs }, () => {
runTest();
});
let child_url = "file_autoplay_policy_eventdown_activation.html";
@@ -47,9 +47,9 @@
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_autoplay_policy_key_blacklist.html
+++ b/dom/media/test/test_autoplay_policy_key_blacklist.html
@@ -13,17 +13,17 @@
<pre id="test">
<script>
// Tests that keypresses for non-printable characters,
// and mouse/keyboard interaction with editable elements,
// don't gesture activate documents, and don't unblock
// audible autoplay.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({ 'set': gTestPrefs }, () => {
runTest();
});
let child_url = "file_autoplay_policy_key_blacklist.html";
@@ -39,9 +39,9 @@
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_autoplay_policy_permission.html
+++ b/dom/media/test/test_autoplay_policy_permission.html
@@ -10,17 +10,17 @@
</head>
<body>
<pre id="test">
<script>
// Tests that origins with "autoplay-media" permission can autoplay.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true],
// Note: permission prompt disabled, as we want immediate
// notification in this test that an origin is blocked.
["media.autoplay.ask-permission", false]);
SpecialPowers.pushPrefEnv({ 'set': gTestPrefs }, () => {
runTest();
});
--- a/dom/media/test/test_autoplay_policy_play_before_loadedmetadata.html
+++ b/dom/media/test/test_autoplay_policy_play_before_loadedmetadata.html
@@ -14,17 +14,17 @@
<script>
window.is = SimpleTest.is;
window.info = SimpleTest.info;
// Tests that videos which have no audio track will play if play()
// is called before the video has reached readyState >= HAVE_METADATA.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({ 'set': gTestPrefs }, () => {
runTest();
});
let testCases = [
{
@@ -65,9 +65,9 @@
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_autoplay_policy_unmute_pauses.html
+++ b/dom/media/test/test_autoplay_policy_unmute_pauses.html
@@ -14,17 +14,17 @@
<script>
window.is = SimpleTest.is;
window.info = SimpleTest.info;
// Tests that videos can only play audibly in windows/frames
// which have been activated by same-origin user gesture.
- gTestPrefs.push(["media.autoplay.enabled", false],
+ gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({ 'set': gTestPrefs }, () => {
runTest();
});
let testCases = [
{
@@ -56,9 +56,9 @@
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -434,17 +434,17 @@ function setupEnvironment() {
const isAndroid = !!navigator.userAgent.includes("Android");
if (isAndroid) {
defaultMochitestPrefs.set.push(
["media.navigator.video.default_width", 320],
["media.navigator.video.default_height", 240],
["media.navigator.video.max_fr", 10],
- ["media.autoplay.enabled", true]
+ ["media.autoplay.default", Ci.nsIAutoplay.ALLOWED]
);
}
// Running as a Mochitest.
SimpleTest.requestFlakyTimeout("WebRTC inherently depends on timeouts");
window.finish = () => SimpleTest.finish();
SpecialPowers.pushPrefEnv(defaultMochitestPrefs, setTestOptions);
--- a/dom/media/webaudio/test/test_notAllowedToStartAudioContextGC.html
+++ b/dom/media/webaudio/test/test_notAllowedToStartAudioContextGC.html
@@ -20,17 +20,17 @@ function observer(subject, topic, data)
ok(id != destId, "dropping another node, not the context's destination");
}
SpecialPowers.addAsyncObserver(observer, "webaudio-node-demise", false);
SimpleTest.registerCleanupFunction(function() {
SpecialPowers.removeAsyncObserver(observer, "webaudio-node-demise");
});
-SpecialPowers.pushPrefEnv({"set": [["media.autoplay.enabled", false],
+SpecialPowers.pushPrefEnv({"set": [["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]]},
startTest);
function startTest() {
info("- create audio context -");
let ac = new AudioContext();
info("- get node Id -");
--- a/mobile/android/app/src/main/res/xml/preferences_advanced.xml
+++ b/mobile/android/app/src/main/res/xml/preferences_advanced.xml
@@ -49,17 +49,17 @@
<SwitchPreference android:key="browser.display.use_document_fonts"
android:title="@string/pref_show_web_fonts"
android:summary="@string/pref_show_web_fonts_summary"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_media">
- <SwitchPreference android:key="media.autoplay.enabled"
+ <SwitchPreference android:key="media.autoplay.default"
android:title="@string/pref_media_autoplay_enabled"
android:summary="@string/pref_media_autoplay_enabled_summary" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_developer_tools">
<SwitchPreference android:key="devtools.remote.usb.enabled"
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -558,22 +558,24 @@ pref("media.encoder.webm.enabled", true)
// Whether to allow recording of AudioNodes with MediaRecorder
pref("media.recorder.audio_node.enabled", false);
// Whether MediaRecorder's video encoder should allow dropping frames in order
// to keep up under load. Useful for tests but beware of memory consumption!
pref("media.recorder.video.frame_drops", true);
-// Whether to autostart a media element with an |autoplay| attribute
-pref("media.autoplay.enabled", true);
-
-// If "media.autoplay.enabled" is false, and this pref is true, then audible media
-// would only be allowed to autoplay after website has been activated by specific
-// user gestures, but the non-audible media won't be restricted.
+// Whether to autostart a media element with an |autoplay| attribute.
+// ALLOWED=0, BLOCKED=1, PROMPT=2, defined in dom/media/Autoplay.idl
+pref("media.autoplay.default", 0);
+
+// If "media.autoplay.default" is not ALLOWED, and this pref is true,
+// then audible media would only be allowed to autoplay after website has
+// been activated by specific user gestures, but non-audible
+// media won't be restricted.
#ifdef NIGHTLY_BUILD
pref("media.autoplay.enabled.user-gestures-needed", false);
#endif
// The default number of decoded video frames that are enqueued in
// MediaDecoderReader's mVideoQueue.
pref("media.video-queue.default-size", 10);
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
@@ -12,17 +12,17 @@
const {escaped} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", {});
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
Cu.importGlobalProperties(["URL"]);
// Make sure media pre-loading is enabled on Android so that our <audio> and
// <video> elements trigger the expected requests.
-Services.prefs.setBoolPref("media.autoplay.enabled", true);
+Services.prefs.setIntPref("media.autoplay.default", Ci.nsIAutoplay.ALLOWED);
Services.prefs.setIntPref("media.preload.default", 3);
// Increase the length of the code samples included in CSP reports so that we
// can correctly validate them.
Services.prefs.setIntPref("security.csp.reporting.script-sample.max-length", 4096);
// ExtensionContent.jsm needs to know when it's running from xpcshell,
// to use the right timeout for content scripts executed at document_idle.
--- a/toolkit/content/tests/browser/browser_autoplay_policy_iframe_hierarchy.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_iframe_hierarchy.js
@@ -19,17 +19,17 @@ const PAGE_A1_B2 = "https://example.com/
const PAGE_A1_B2_C3 = "https://test1.example.org/browser/toolkit/content/tests/browser/file_autoplay_three_layers_frame1.html";
const PAGE_A1_B2_A3 = "https://example.org/browser/toolkit/content/tests/browser/file_autoplay_three_layers_frame1.html";
const PAGE_A1_B2_B3 = "https://example.org/browser/toolkit/content/tests/browser/file_autoplay_three_layers_frame2.html";
const PAGE_A1_A2_A3 = "https://example.com/browser/toolkit/content/tests/browser/file_autoplay_three_layers_frame2.html";
const PAGE_A1_A2_B3 = "https://example.com/browser/toolkit/content/tests/browser/file_autoplay_three_layers_frame1.html";
function setup_test_preference() {
return SpecialPowers.pushPrefEnv({"set": [
- ["media.autoplay.enabled", false],
+ ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true]
]});
}
var frameTestArray = [
{ name: "A1_A2", layersNum: 2, src: PAGE_A1_A2 },
{ name: "A1_B2", layersNum: 2, src: PAGE_A1_B2 },
{ name: "A1_B2_C3", layersNum: 3, src: PAGE_A1_B2_C3 },
--- a/toolkit/content/tests/browser/browser_autoplay_policy_play_twice.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_play_twice.js
@@ -1,15 +1,15 @@
const VIDEO_PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_video.html";
function setup_test_preference(enableUserGesture) {
let state = enableUserGesture ? "enable" : "disable";
info(`- set pref : ${state} user gesture -`);
return SpecialPowers.pushPrefEnv({"set": [
- ["media.autoplay.enabled", false],
+ ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", enableUserGesture]
]});
}
async function allow_play_for_played_video() {
info("- open new tab -");
let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
--- a/toolkit/content/tests/browser/browser_autoplay_policy_request_permission.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_request_permission.js
@@ -5,17 +5,17 @@
"use strict";
ChromeUtils.import("resource:///modules/SitePermissions.jsm", this);
const VIDEO_PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_empty.html";
add_task(() => {
return SpecialPowers.pushPrefEnv({"set": [
- ["media.autoplay.enabled", false],
+ ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.PROMPT],
["media.autoplay.enabled.user-gestures-needed", true],
["media.autoplay.ask-permission", true],
["media.autoplay.block-event.enabled", true],
]});
});
// Runs a content script that creates an autoplay video.
// browser: the browser to run the script in.
--- a/toolkit/content/tests/browser/browser_autoplay_policy_user_gestures.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_user_gestures.js
@@ -11,17 +11,17 @@ var UserGestures = {
var UserGestureTests = [
{type: UserGestures.MOUSE_CLICK, isActivationGesture: true},
{type: UserGestures.MOUSE_MOVE, isActivationGesture: false},
{type: UserGestures.KEYBOARD_PRESS, isActivationGesture: true}
];
function setup_test_preference() {
return SpecialPowers.pushPrefEnv({"set": [
- ["media.autoplay.enabled", false],
+ ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
["media.autoplay.enabled.user-gestures-needed", true],
["media.navigator.permission.fake", true]
]});
}
function simulateUserGesture(gesture, targetBrowser) {
info(`- simulate ${gesture.type} event -`);
switch (gesture.type) {
--- a/toolkit/content/tests/browser/browser_block_autoplay_media.js
+++ b/toolkit/content/tests/browser/browser_block_autoplay_media.js
@@ -79,17 +79,17 @@ add_task(async function block_autoplay_m
//
// Clicking "play" on the audio tab indicator should always start playback
// in that tab, even if it's in an autoplay-blocked origin.
//
// Also test that that this block-autoplay logic override doesn't survive
// a new document being loaded into the tab; the new document should have
// to satisfy the autoplay requirements on its own.
await SpecialPowers.pushPrefEnv({"set": [
- ["media.autoplay.enabled", false],
+ ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.PROMPT],
["media.autoplay.enabled.user-gestures-needed", true],
["media.autoplay.ask-permission", true],
]});
info("- open new background tab4 -");
let tab4 = window.gBrowser.addTab("about:blank");
tab4.linkedBrowser.loadURI(PAGE);
await BrowserTestUtils.browserLoaded(tab4.linkedBrowser);