/src/mozilla-central/dom/media/BackgroundVideoDecodingPermissionObserver.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "BackgroundVideoDecodingPermissionObserver.h" |
7 | | |
8 | | #include "mozilla/AsyncEventDispatcher.h" |
9 | | #include "mozilla/StaticPrefs.h" |
10 | | #include "MediaDecoder.h" |
11 | | #include "nsContentUtils.h" |
12 | | #include "nsIDocument.h" |
13 | | |
14 | | namespace mozilla { |
15 | | |
16 | | BackgroundVideoDecodingPermissionObserver:: |
17 | | BackgroundVideoDecodingPermissionObserver(MediaDecoder* aDecoder) |
18 | | : mDecoder(aDecoder) |
19 | | , mIsRegisteredForEvent(false) |
20 | 0 | { |
21 | 0 | MOZ_ASSERT(mDecoder); |
22 | 0 | } |
23 | | |
24 | | NS_IMETHODIMP |
25 | | BackgroundVideoDecodingPermissionObserver::Observe(nsISupports* aSubject, |
26 | | const char* aTopic, |
27 | | const char16_t* aData) |
28 | 0 | { |
29 | 0 | if (!StaticPrefs::MediaResumeBkgndVideoOnTabhover()) { |
30 | 0 | return NS_OK; |
31 | 0 | } |
32 | 0 | |
33 | 0 | if (!IsValidEventSender(aSubject)) { |
34 | 0 | return NS_OK; |
35 | 0 | } |
36 | 0 | |
37 | 0 | if (strcmp(aTopic, "unselected-tab-hover") == 0) { |
38 | 0 | bool allowed = !NS_strcmp(aData, u"true"); |
39 | 0 | mDecoder->SetIsBackgroundVideoDecodingAllowed(allowed); |
40 | 0 | } |
41 | 0 | return NS_OK; |
42 | 0 | } |
43 | | |
44 | | void |
45 | | BackgroundVideoDecodingPermissionObserver::RegisterEvent() |
46 | 0 | { |
47 | 0 | MOZ_ASSERT(!mIsRegisteredForEvent); |
48 | 0 | nsCOMPtr<nsIObserverService> observerService = services::GetObserverService(); |
49 | 0 | if (observerService) { |
50 | 0 | observerService->AddObserver(this, "unselected-tab-hover", false); |
51 | 0 | mIsRegisteredForEvent = true; |
52 | 0 | if (nsContentUtils::IsInStableOrMetaStableState()) { |
53 | 0 | // Events shall not be fired synchronously to prevent anything visible |
54 | 0 | // from the scripts while we are in stable state. |
55 | 0 | if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) { |
56 | 0 | doc->Dispatch( |
57 | 0 | TaskCategory::Other, |
58 | 0 | NewRunnableMethod( |
59 | 0 | "BackgroundVideoDecodingPermissionObserver::" |
60 | 0 | "EnableEvent", |
61 | 0 | this, |
62 | 0 | &BackgroundVideoDecodingPermissionObserver:: |
63 | 0 | EnableEvent)); |
64 | 0 | } |
65 | 0 | } else { |
66 | 0 | EnableEvent(); |
67 | 0 | } |
68 | 0 | } |
69 | 0 | } |
70 | | |
71 | | void |
72 | | BackgroundVideoDecodingPermissionObserver::UnregisterEvent() |
73 | 0 | { |
74 | 0 | MOZ_ASSERT(mIsRegisteredForEvent); |
75 | 0 | nsCOMPtr<nsIObserverService> observerService = services::GetObserverService(); |
76 | 0 | if (observerService) { |
77 | 0 | observerService->RemoveObserver(this, "unselected-tab-hover"); |
78 | 0 | mIsRegisteredForEvent = false; |
79 | 0 | mDecoder->SetIsBackgroundVideoDecodingAllowed(false); |
80 | 0 | if (nsContentUtils::IsInStableOrMetaStableState()) { |
81 | 0 | // Events shall not be fired synchronously to prevent anything visible |
82 | 0 | // from the scripts while we are in stable state. |
83 | 0 | if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) { |
84 | 0 | doc->Dispatch( |
85 | 0 | TaskCategory::Other, |
86 | 0 | NewRunnableMethod( |
87 | 0 | "BackgroundVideoDecodingPermissionObserver::" |
88 | 0 | "DisableEvent", |
89 | 0 | this, |
90 | 0 | &BackgroundVideoDecodingPermissionObserver:: |
91 | 0 | DisableEvent)); |
92 | 0 | } |
93 | 0 | } else { |
94 | 0 | DisableEvent(); |
95 | 0 | } |
96 | 0 | } |
97 | 0 | } |
98 | | |
99 | | BackgroundVideoDecodingPermissionObserver:: |
100 | | ~BackgroundVideoDecodingPermissionObserver() |
101 | 0 | { |
102 | 0 | MOZ_ASSERT(!mIsRegisteredForEvent); |
103 | 0 | } |
104 | | |
105 | | void |
106 | | BackgroundVideoDecodingPermissionObserver::EnableEvent() const |
107 | 0 | { |
108 | 0 | nsIDocument* doc = GetOwnerDoc(); |
109 | 0 | if (!doc) { |
110 | 0 | return; |
111 | 0 | } |
112 | 0 | |
113 | 0 | nsCOMPtr<nsPIDOMWindowOuter> ownerTop = GetOwnerWindow(); |
114 | 0 | if (!ownerTop) { |
115 | 0 | return; |
116 | 0 | } |
117 | 0 | |
118 | 0 | RefPtr<AsyncEventDispatcher> asyncDispatcher = |
119 | 0 | new AsyncEventDispatcher(doc, |
120 | 0 | NS_LITERAL_STRING("UnselectedTabHover:Enable"), |
121 | 0 | CanBubble::eYes, |
122 | 0 | ChromeOnlyDispatch::eYes); |
123 | 0 | asyncDispatcher->PostDOMEvent(); |
124 | 0 | } |
125 | | |
126 | | void |
127 | | BackgroundVideoDecodingPermissionObserver::DisableEvent() const |
128 | 0 | { |
129 | 0 | nsIDocument* doc = GetOwnerDoc(); |
130 | 0 | if (!doc) { |
131 | 0 | return; |
132 | 0 | } |
133 | 0 | |
134 | 0 | nsCOMPtr<nsPIDOMWindowOuter> ownerTop = GetOwnerWindow(); |
135 | 0 | if (!ownerTop) { |
136 | 0 | return; |
137 | 0 | } |
138 | 0 | |
139 | 0 | RefPtr<AsyncEventDispatcher> asyncDispatcher = |
140 | 0 | new AsyncEventDispatcher(doc, |
141 | 0 | NS_LITERAL_STRING("UnselectedTabHover:Disable"), |
142 | 0 | CanBubble::eYes, |
143 | 0 | ChromeOnlyDispatch::eYes); |
144 | 0 | asyncDispatcher->PostDOMEvent(); |
145 | 0 | } |
146 | | |
147 | | already_AddRefed<nsPIDOMWindowOuter> |
148 | | BackgroundVideoDecodingPermissionObserver::GetOwnerWindow() const |
149 | 0 | { |
150 | 0 | nsIDocument* doc = GetOwnerDoc(); |
151 | 0 | if (!doc) { |
152 | 0 | return nullptr; |
153 | 0 | } |
154 | 0 | |
155 | 0 | nsCOMPtr<nsPIDOMWindowInner> innerWin = doc->GetInnerWindow(); |
156 | 0 | if (!innerWin) { |
157 | 0 | return nullptr; |
158 | 0 | } |
159 | 0 | |
160 | 0 | nsCOMPtr<nsPIDOMWindowOuter> outerWin = innerWin->GetOuterWindow(); |
161 | 0 | if (!outerWin) { |
162 | 0 | return nullptr; |
163 | 0 | } |
164 | 0 | |
165 | 0 | nsCOMPtr<nsPIDOMWindowOuter> topWin = outerWin->GetTop(); |
166 | 0 | return topWin.forget(); |
167 | 0 | } |
168 | | |
169 | | nsIDocument* |
170 | | BackgroundVideoDecodingPermissionObserver::GetOwnerDoc() const |
171 | 0 | { |
172 | 0 | if (!mDecoder->GetOwner()) { |
173 | 0 | return nullptr; |
174 | 0 | } |
175 | 0 | |
176 | 0 | return mDecoder->GetOwner()->GetDocument(); |
177 | 0 | } |
178 | | |
179 | | bool |
180 | | BackgroundVideoDecodingPermissionObserver::IsValidEventSender( |
181 | | nsISupports* aSubject) const |
182 | 0 | { |
183 | 0 | nsCOMPtr<nsPIDOMWindowInner> senderInner(do_QueryInterface(aSubject)); |
184 | 0 | if (!senderInner) { |
185 | 0 | return false; |
186 | 0 | } |
187 | 0 | |
188 | 0 | nsCOMPtr<nsPIDOMWindowOuter> senderOuter = senderInner->GetOuterWindow(); |
189 | 0 | if (!senderOuter) { |
190 | 0 | return false; |
191 | 0 | } |
192 | 0 | |
193 | 0 | nsCOMPtr<nsPIDOMWindowOuter> senderTop = senderOuter->GetTop(); |
194 | 0 | if (!senderTop) { |
195 | 0 | return false; |
196 | 0 | } |
197 | 0 | |
198 | 0 | nsCOMPtr<nsPIDOMWindowOuter> ownerTop = GetOwnerWindow(); |
199 | 0 | if (!ownerTop) { |
200 | 0 | return false; |
201 | 0 | } |
202 | 0 | |
203 | 0 | return ownerTop == senderTop; |
204 | 0 | } |
205 | | |
206 | | NS_IMPL_ISUPPORTS(BackgroundVideoDecodingPermissionObserver, nsIObserver) |
207 | | |
208 | | } // namespace mozilla |