mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
9835a91852
Differential Revision: https://phabricator.services.mozilla.com/D86879
155 lines
5.2 KiB
C++
155 lines
5.2 KiB
C++
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* 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 "BackgroundVideoDecodingPermissionObserver.h"
|
|
|
|
#include "mozilla/AsyncEventDispatcher.h"
|
|
#include "mozilla/dom/BrowsingContext.h"
|
|
#include "mozilla/StaticPrefs_media.h"
|
|
#include "MediaDecoder.h"
|
|
#include "nsContentUtils.h"
|
|
#include "mozilla/dom/Document.h"
|
|
|
|
namespace mozilla {
|
|
|
|
BackgroundVideoDecodingPermissionObserver::
|
|
BackgroundVideoDecodingPermissionObserver(MediaDecoder* aDecoder)
|
|
: mDecoder(aDecoder), mIsRegisteredForEvent(false) {
|
|
MOZ_ASSERT(mDecoder);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BackgroundVideoDecodingPermissionObserver::Observe(nsISupports* aSubject,
|
|
const char* aTopic,
|
|
const char16_t* aData) {
|
|
if (!StaticPrefs::media_resume_bkgnd_video_on_tabhover()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (!IsValidEventSender(aSubject)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (strcmp(aTopic, "unselected-tab-hover") == 0) {
|
|
bool allowed = !NS_strcmp(aData, u"true");
|
|
mDecoder->SetIsBackgroundVideoDecodingAllowed(allowed);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void BackgroundVideoDecodingPermissionObserver::RegisterEvent() {
|
|
MOZ_ASSERT(!mIsRegisteredForEvent);
|
|
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
|
|
if (observerService) {
|
|
observerService->AddObserver(this, "unselected-tab-hover", false);
|
|
mIsRegisteredForEvent = true;
|
|
if (nsContentUtils::IsInStableOrMetaStableState()) {
|
|
// Events shall not be fired synchronously to prevent anything visible
|
|
// from the scripts while we are in stable state.
|
|
if (nsCOMPtr<dom::Document> doc = GetOwnerDoc()) {
|
|
doc->Dispatch(
|
|
TaskCategory::Other,
|
|
NewRunnableMethod(
|
|
"BackgroundVideoDecodingPermissionObserver::"
|
|
"EnableEvent",
|
|
this, &BackgroundVideoDecodingPermissionObserver::EnableEvent));
|
|
}
|
|
} else {
|
|
EnableEvent();
|
|
}
|
|
}
|
|
}
|
|
|
|
void BackgroundVideoDecodingPermissionObserver::UnregisterEvent() {
|
|
MOZ_ASSERT(mIsRegisteredForEvent);
|
|
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
|
|
if (observerService) {
|
|
observerService->RemoveObserver(this, "unselected-tab-hover");
|
|
mIsRegisteredForEvent = false;
|
|
mDecoder->SetIsBackgroundVideoDecodingAllowed(false);
|
|
if (nsContentUtils::IsInStableOrMetaStableState()) {
|
|
// Events shall not be fired synchronously to prevent anything visible
|
|
// from the scripts while we are in stable state.
|
|
if (nsCOMPtr<dom::Document> doc = GetOwnerDoc()) {
|
|
doc->Dispatch(
|
|
TaskCategory::Other,
|
|
NewRunnableMethod(
|
|
"BackgroundVideoDecodingPermissionObserver::"
|
|
"DisableEvent",
|
|
this,
|
|
&BackgroundVideoDecodingPermissionObserver::DisableEvent));
|
|
}
|
|
} else {
|
|
DisableEvent();
|
|
}
|
|
}
|
|
}
|
|
|
|
BackgroundVideoDecodingPermissionObserver::
|
|
~BackgroundVideoDecodingPermissionObserver() {
|
|
MOZ_ASSERT(!mIsRegisteredForEvent);
|
|
}
|
|
|
|
void BackgroundVideoDecodingPermissionObserver::EnableEvent() const {
|
|
// If we can't get document or outer window, then you can't reach the chrome
|
|
// <browser> either, so we don't need want to dispatch the event.
|
|
dom::Document* doc = GetOwnerDoc();
|
|
if (!doc || !doc->GetWindow()) {
|
|
return;
|
|
}
|
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
|
new AsyncEventDispatcher(doc, u"UnselectedTabHover:Enable"_ns,
|
|
CanBubble::eYes, ChromeOnlyDispatch::eYes);
|
|
asyncDispatcher->PostDOMEvent();
|
|
}
|
|
|
|
void BackgroundVideoDecodingPermissionObserver::DisableEvent() const {
|
|
// If we can't get document or outer window, then you can't reach the chrome
|
|
// <browser> either, so we don't need want to dispatch the event.
|
|
dom::Document* doc = GetOwnerDoc();
|
|
if (!doc || !doc->GetWindow()) {
|
|
return;
|
|
}
|
|
|
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
|
new AsyncEventDispatcher(doc, u"UnselectedTabHover:Disable"_ns,
|
|
CanBubble::eYes, ChromeOnlyDispatch::eYes);
|
|
asyncDispatcher->PostDOMEvent();
|
|
}
|
|
|
|
dom::BrowsingContext* BackgroundVideoDecodingPermissionObserver::GetOwnerBC()
|
|
const {
|
|
dom::Document* doc = GetOwnerDoc();
|
|
return doc ? doc->GetBrowsingContext() : nullptr;
|
|
}
|
|
|
|
dom::Document* BackgroundVideoDecodingPermissionObserver::GetOwnerDoc() const {
|
|
if (!mDecoder->GetOwner()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return mDecoder->GetOwner()->GetDocument();
|
|
}
|
|
|
|
bool BackgroundVideoDecodingPermissionObserver::IsValidEventSender(
|
|
nsISupports* aSubject) const {
|
|
nsCOMPtr<nsPIDOMWindowInner> senderInner(do_QueryInterface(aSubject));
|
|
if (!senderInner) {
|
|
return false;
|
|
}
|
|
|
|
RefPtr<dom::BrowsingContext> senderBC = senderInner->GetBrowsingContext();
|
|
if (!senderBC) {
|
|
return false;
|
|
}
|
|
// Valid sender should be in the same browsing context tree as where owner is.
|
|
return GetOwnerBC() ? GetOwnerBC()->Top() == senderBC->Top() : false;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(BackgroundVideoDecodingPermissionObserver, nsIObserver)
|
|
|
|
} // namespace mozilla
|