mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
199 lines
5.3 KiB
C++
199 lines
5.3 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 "MediaDecoder.h"
|
||
|
#include "MediaPrefs.h"
|
||
|
#include "nsContentUtils.h"
|
||
|
#include "nsIDocument.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 (!MediaPrefs::ResumeVideoDecodingOnTabHover()) {
|
||
|
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<nsIDocument> 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<nsIDocument> doc = GetOwnerDoc()) {
|
||
|
doc->Dispatch(
|
||
|
TaskCategory::Other,
|
||
|
NewRunnableMethod(
|
||
|
"BackgroundVideoDecodingPermissionObserver::"
|
||
|
"DisableEvent",
|
||
|
this,
|
||
|
&BackgroundVideoDecodingPermissionObserver::
|
||
|
DisableEvent));
|
||
|
}
|
||
|
} else {
|
||
|
DisableEvent();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BackgroundVideoDecodingPermissionObserver::
|
||
|
~BackgroundVideoDecodingPermissionObserver()
|
||
|
{
|
||
|
MOZ_ASSERT(!mIsRegisteredForEvent);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
BackgroundVideoDecodingPermissionObserver::EnableEvent() const
|
||
|
{
|
||
|
nsIDocument* doc = GetOwnerDoc();
|
||
|
if (!doc) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||
|
new AsyncEventDispatcher(doc,
|
||
|
NS_LITERAL_STRING("UnselectedTabHover:Enable"),
|
||
|
/* Bubbles */ true,
|
||
|
/* OnlyChromeDispatch */ true);
|
||
|
asyncDispatcher->PostDOMEvent();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
BackgroundVideoDecodingPermissionObserver::DisableEvent() const
|
||
|
{
|
||
|
nsIDocument* doc = GetOwnerDoc();
|
||
|
if (!doc) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||
|
new AsyncEventDispatcher(doc,
|
||
|
NS_LITERAL_STRING("UnselectedTabHover:Disable"),
|
||
|
/* Bubbles */ true,
|
||
|
/* OnlyChromeDispatch */ true);
|
||
|
asyncDispatcher->PostDOMEvent();
|
||
|
}
|
||
|
|
||
|
already_AddRefed<nsPIDOMWindowOuter>
|
||
|
BackgroundVideoDecodingPermissionObserver::GetOwnerWindow() const
|
||
|
{
|
||
|
nsIDocument* doc = GetOwnerDoc();
|
||
|
if (!doc) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowInner> innerWin = doc->GetInnerWindow();
|
||
|
if (!innerWin) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowOuter> outerWin = innerWin->GetOuterWindow();
|
||
|
if (!outerWin) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowOuter> topWin = outerWin->GetTop();
|
||
|
return topWin.forget();
|
||
|
}
|
||
|
|
||
|
nsIDocument*
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowOuter> senderOuter = senderInner->GetOuterWindow();
|
||
|
if (!senderOuter) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowOuter> senderTop = senderOuter->GetTop();
|
||
|
if (!senderTop) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
nsCOMPtr<nsPIDOMWindowOuter> ownerTop = GetOwnerWindow();
|
||
|
if (!ownerTop) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return ownerTop == senderTop;
|
||
|
}
|
||
|
|
||
|
NS_IMPL_ISUPPORTS(BackgroundVideoDecodingPermissionObserver, nsIObserver)
|
||
|
|
||
|
} // namespace mozilla
|