Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "AutoplayPolicy.h"
8 :
9 : #include "mozilla/EventStateManager.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozilla/dom/AudioContext.h"
12 : #include "mozilla/dom/HTMLMediaElement.h"
13 : #include "mozilla/dom/HTMLMediaElementBinding.h"
14 : #include "nsContentUtils.h"
15 : #include "nsIDocument.h"
16 : #include "MediaManager.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : /* static */ bool
22 3 : AutoplayPolicy::IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement)
23 : {
24 3 : if (Preferences::GetBool("media.autoplay.enabled")) {
25 : return true;
26 : }
27 :
28 : // TODO : this old way would be removed when user-gestures-needed becomes
29 : // as a default option to block autoplay.
30 0 : if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
31 : // If elelement is blessed, it would always be allowed to play().
32 0 : return aElement->IsBlessed() ||
33 0 : EventStateManager::IsHandlingUserInput();
34 : }
35 :
36 : // Pages which have been granted permission to capture WebRTC camera or
37 : // microphone are assumed to be trusted, and are allowed to autoplay.
38 0 : MediaManager* manager = MediaManager::GetIfExists();
39 0 : if (manager) {
40 0 : nsCOMPtr<nsPIDOMWindowInner> window = aElement->OwnerDoc()->GetInnerWindow();
41 0 : if (window && manager->IsActivelyCapturingOrHasAPermission(window->WindowID())) {
42 0 : return true;
43 : }
44 : }
45 :
46 : // Muted content
47 0 : if (aElement->Volume() == 0.0 || aElement->Muted()) {
48 : return true;
49 : }
50 :
51 : // Whitelisted.
52 0 : if (nsContentUtils::IsExactSitePermAllow(
53 0 : aElement->NodePrincipal(), "autoplay-media")) {
54 : return true;
55 : }
56 :
57 : // Activated by user gesture.
58 0 : if (aElement->OwnerDoc()->HasBeenUserActivated()) {
59 : return true;
60 : }
61 :
62 0 : return false;
63 : }
64 :
65 : /* static */ bool
66 0 : AutoplayPolicy::IsAudioContextAllowedToPlay(NotNull<AudioContext*> aContext)
67 : {
68 0 : if (Preferences::GetBool("media.autoplay.enabled")) {
69 : return true;
70 : }
71 :
72 : if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
73 : return true;
74 : }
75 :
76 : // Offline context won't directly output sound to audio devices.
77 : if (aContext->IsOffline()) {
78 : return true;
79 : }
80 :
81 : nsPIDOMWindowInner* window = aContext->GetOwner();
82 : if (!window) {
83 : return false;
84 : }
85 :
86 : // Pages which have been granted permission to capture WebRTC camera or
87 : // microphone are assumed to be trusted, and are allowed to autoplay.
88 : MediaManager* manager = MediaManager::GetIfExists();
89 : if (manager) {
90 : if (manager->IsActivelyCapturingOrHasAPermission(window->WindowID())) {
91 : return true;
92 : }
93 : }
94 :
95 : nsCOMPtr<nsIPrincipal> principal = aContext->GetParentObject()->AsGlobal()->PrincipalOrNull();
96 :
97 : // Whitelisted.
98 : if (principal &&
99 : nsContentUtils::IsExactSitePermAllow(principal, "autoplay-media")) {
100 : return true;
101 : }
102 :
103 : // Activated by user gesture.
104 : if (window->GetExtantDoc()->HasBeenUserActivated()) {
105 : return true;
106 : }
107 :
108 : return false;
109 : }
110 :
111 : } // namespace dom
112 : } // namespace mozilla
|