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/. */
6 #include "BackgroundVideoDecodingPermissionObserver.h"
8 #include "mozilla/AsyncEventDispatcher.h"
9 #include "mozilla/dom/BrowsingContext.h"
10 #include "mozilla/StaticPrefs_media.h"
11 #include "MediaDecoder.h"
12 #include "nsContentUtils.h"
13 #include "mozilla/dom/Document.h"
14 #include "mozilla/Services.h"
15 #include "nsIObserverService.h"
19 BackgroundVideoDecodingPermissionObserver::
20 BackgroundVideoDecodingPermissionObserver(MediaDecoder
* aDecoder
)
21 : mDecoder(aDecoder
), mIsRegisteredForEvent(false) {
26 BackgroundVideoDecodingPermissionObserver::Observe(nsISupports
* aSubject
,
28 const char16_t
* aData
) {
29 if (!StaticPrefs::media_resume_background_video_on_tabhover()) {
33 if (!IsValidEventSender(aSubject
)) {
37 if (strcmp(aTopic
, "unselected-tab-hover") == 0) {
38 bool allowed
= !NS_strcmp(aData
, u
"true");
39 mDecoder
->SetIsBackgroundVideoDecodingAllowed(allowed
);
44 void BackgroundVideoDecodingPermissionObserver::RegisterEvent() {
45 MOZ_ASSERT(!mIsRegisteredForEvent
);
46 nsCOMPtr
<nsIObserverService
> observerService
= services::GetObserverService();
47 if (observerService
) {
48 observerService
->AddObserver(this, "unselected-tab-hover", false);
49 mIsRegisteredForEvent
= true;
50 if (nsContentUtils::IsInStableOrMetaStableState()) {
51 // Events shall not be fired synchronously to prevent anything visible
52 // from the scripts while we are in stable state.
53 if (nsCOMPtr
<dom::Document
> doc
= GetOwnerDoc()) {
54 doc
->Dispatch(NewRunnableMethod(
55 "BackgroundVideoDecodingPermissionObserver::EnableEvent", this,
56 &BackgroundVideoDecodingPermissionObserver::EnableEvent
));
64 void BackgroundVideoDecodingPermissionObserver::UnregisterEvent() {
65 MOZ_ASSERT(mIsRegisteredForEvent
);
66 nsCOMPtr
<nsIObserverService
> observerService
= services::GetObserverService();
67 if (observerService
) {
68 observerService
->RemoveObserver(this, "unselected-tab-hover");
69 mIsRegisteredForEvent
= false;
70 mDecoder
->SetIsBackgroundVideoDecodingAllowed(false);
71 if (nsContentUtils::IsInStableOrMetaStableState()) {
72 // Events shall not be fired synchronously to prevent anything visible
73 // from the scripts while we are in stable state.
74 if (nsCOMPtr
<dom::Document
> doc
= GetOwnerDoc()) {
75 doc
->Dispatch(NewRunnableMethod(
76 "BackgroundVideoDecodingPermissionObserver::DisableEvent", this,
77 &BackgroundVideoDecodingPermissionObserver::DisableEvent
));
85 BackgroundVideoDecodingPermissionObserver::
86 ~BackgroundVideoDecodingPermissionObserver() {
87 MOZ_ASSERT(!mIsRegisteredForEvent
);
90 void BackgroundVideoDecodingPermissionObserver::EnableEvent() const {
91 // If we can't get document or outer window, then you can't reach the chrome
92 // <browser> either, so we don't need want to dispatch the event.
93 dom::Document
* doc
= GetOwnerDoc();
94 if (!doc
|| !doc
->GetWindow()) {
98 RefPtr
<AsyncEventDispatcher
> asyncDispatcher
=
99 new AsyncEventDispatcher(doc
, u
"UnselectedTabHover:Enable"_ns
,
100 CanBubble::eYes
, ChromeOnlyDispatch::eYes
);
101 asyncDispatcher
->PostDOMEvent();
104 void BackgroundVideoDecodingPermissionObserver::DisableEvent() const {
105 // If we can't get document or outer window, then you can't reach the chrome
106 // <browser> either, so we don't need want to dispatch the event.
107 dom::Document
* doc
= GetOwnerDoc();
108 if (!doc
|| !doc
->GetWindow()) {
112 RefPtr
<AsyncEventDispatcher
> asyncDispatcher
=
113 new AsyncEventDispatcher(doc
, u
"UnselectedTabHover:Disable"_ns
,
114 CanBubble::eYes
, ChromeOnlyDispatch::eYes
);
115 asyncDispatcher
->PostDOMEvent();
118 dom::BrowsingContext
* BackgroundVideoDecodingPermissionObserver::GetOwnerBC()
120 dom::Document
* doc
= GetOwnerDoc();
121 return doc
? doc
->GetBrowsingContext() : nullptr;
124 dom::Document
* BackgroundVideoDecodingPermissionObserver::GetOwnerDoc() const {
125 if (!mDecoder
->GetOwner()) {
129 return mDecoder
->GetOwner()->GetDocument();
132 bool BackgroundVideoDecodingPermissionObserver::IsValidEventSender(
133 nsISupports
* aSubject
) const {
134 nsCOMPtr
<nsPIDOMWindowInner
> senderInner(do_QueryInterface(aSubject
));
139 RefPtr
<dom::BrowsingContext
> senderBC
= senderInner
->GetBrowsingContext();
143 // Valid sender should be in the same browsing context tree as where owner is.
144 return GetOwnerBC() ? GetOwnerBC()->Top() == senderBC
->Top() : false;
147 NS_IMPL_ISUPPORTS(BackgroundVideoDecodingPermissionObserver
, nsIObserver
)
149 } // namespace mozilla