Backed out changeset f594e6f00208 (bug 1940883) for causing crashes in bug 1941164.
[gecko.git] / dom / media / BackgroundVideoDecodingPermissionObserver.cpp
blobf91629a090ea3f6c06678c63d1aea7a9abc3f624
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"
17 namespace mozilla {
19 BackgroundVideoDecodingPermissionObserver::
20 BackgroundVideoDecodingPermissionObserver(MediaDecoder* aDecoder)
21 : mDecoder(aDecoder), mIsRegisteredForEvent(false) {
22 MOZ_ASSERT(mDecoder);
25 NS_IMETHODIMP
26 BackgroundVideoDecodingPermissionObserver::Observe(nsISupports* aSubject,
27 const char* aTopic,
28 const char16_t* aData) {
29 if (!StaticPrefs::media_resume_background_video_on_tabhover()) {
30 return NS_OK;
33 if (!IsValidEventSender(aSubject)) {
34 return NS_OK;
37 if (strcmp(aTopic, "unselected-tab-hover") == 0) {
38 bool allowed = !NS_strcmp(aData, u"true");
39 mDecoder->SetIsBackgroundVideoDecodingAllowed(allowed);
41 return NS_OK;
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));
58 } else {
59 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));
79 } else {
80 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()) {
95 return;
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()) {
109 return;
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()
119 const {
120 dom::Document* doc = GetOwnerDoc();
121 return doc ? doc->GetBrowsingContext() : nullptr;
124 dom::Document* BackgroundVideoDecodingPermissionObserver::GetOwnerDoc() const {
125 if (!mDecoder->GetOwner()) {
126 return nullptr;
129 return mDecoder->GetOwner()->GetDocument();
132 bool BackgroundVideoDecodingPermissionObserver::IsValidEventSender(
133 nsISupports* aSubject) const {
134 nsCOMPtr<nsPIDOMWindowInner> senderInner(do_QueryInterface(aSubject));
135 if (!senderInner) {
136 return false;
139 RefPtr<dom::BrowsingContext> senderBC = senderInner->GetBrowsingContext();
140 if (!senderBC) {
141 return false;
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