gecko-dev/dom/media/MediaPlaybackDelayPolicy.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

171 строка
5.1 KiB
C++
Исходник Обычный вид История

/* 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 "MediaPlaybackDelayPolicy.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/HTMLMediaElement.h"
Bug 1454998 - Rename streams to tracks. r=padenot,karlt,smaug This renames the following (in alphabetical order, non-exhaustive): AudioCaptureStream -> AudioCaptureTrack AudioNodeStream -> AudioNodeTrack AudioNodeExternalInputStream -> AudioNodeExternalInputTrack DirectMediaStreamTrackListener -> DirectMediaTrackListener MediaStream -> MediaTrack - Note that there's also dom::MediaTrack. Namespaces differentiate them. MediaStreamGraph -> MediaTrackGraph MediaStreamTrackListener -> MediaTrackListener MSG -> MTG (in comments) ProcessedMediaStream -> ProcessedMediaTrack SharedDummyStream -> SharedDummyTrack SourceMediaStream -> SourceMediaTrack StreamTime -> TrackTime TrackUnionStream -> ForwardedInputTrack - Because this no longer takes a union of anything, but only a single track as input. Other minor classes, members and comments have been updated to reflect these name changes. Differential Revision: https://phabricator.services.mozilla.com/D46146 --HG-- rename : dom/media/AudioCaptureStream.cpp => dom/media/AudioCaptureTrack.cpp rename : dom/media/AudioCaptureStream.h => dom/media/AudioCaptureTrack.h rename : dom/media/TrackUnionStream.cpp => dom/media/ForwardedInputTrack.cpp rename : dom/media/TrackUnionStream.h => dom/media/ForwardedInputTrack.h rename : dom/media/MediaStreamGraph.cpp => dom/media/MediaTrackGraph.cpp rename : dom/media/MediaStreamGraph.h => dom/media/MediaTrackGraph.h rename : dom/media/MediaStreamGraphImpl.h => dom/media/MediaTrackGraphImpl.h rename : dom/media/MediaStreamListener.cpp => dom/media/MediaTrackListener.cpp rename : dom/media/MediaStreamListener.h => dom/media/MediaTrackListener.h rename : dom/media/webaudio/AudioNodeExternalInputStream.cpp => dom/media/webaudio/AudioNodeExternalInputTrack.cpp rename : dom/media/webaudio/AudioNodeExternalInputStream.h => dom/media/webaudio/AudioNodeExternalInputTrack.h rename : dom/media/webaudio/AudioNodeStream.cpp => dom/media/webaudio/AudioNodeTrack.cpp rename : dom/media/webaudio/AudioNodeStream.h => dom/media/webaudio/AudioNodeTrack.h extra : moz-landing-system : lando
2019-10-02 13:23:02 +03:00
#include "mozilla/StaticPrefs_media.h"
namespace mozilla {
namespace dom {
using AudibleState = AudioChannelService::AudibleState;
static AudibleState DetermineMediaAudibleState(const HTMLMediaElement* aElement,
bool aIsAudible) {
MOZ_ASSERT(aElement);
if (!aElement->HasAudio()) {
return AudibleState::eNotAudible;
}
// `eMaybeAudible` is used to distinguish if the media has audio track or not,
// because we would only show the delayed media playback icon for media with
// an audio track.
return aIsAudible ? AudibleState::eAudible : AudibleState::eMaybeAudible;
}
ResumeDelayedPlaybackAgent::~ResumeDelayedPlaybackAgent() {
if (mDelegate) {
mDelegate->Clear();
mDelegate = nullptr;
}
}
bool ResumeDelayedPlaybackAgent::InitDelegate(const HTMLMediaElement* aElement,
bool aIsAudible) {
MOZ_ASSERT(!mDelegate, "Delegate has been initialized!");
mDelegate = new ResumePlayDelegate();
if (!mDelegate->Init(aElement, aIsAudible)) {
mDelegate->Clear();
mDelegate = nullptr;
return false;
}
return true;
}
RefPtr<ResumeDelayedPlaybackAgent::ResumePromise>
ResumeDelayedPlaybackAgent::GetResumePromise() {
MOZ_ASSERT(mDelegate);
return mDelegate->GetResumePromise();
}
void ResumeDelayedPlaybackAgent::UpdateAudibleState(
const HTMLMediaElement* aElement, bool aIsAudible) {
MOZ_ASSERT(aElement);
MOZ_ASSERT(mDelegate);
mDelegate->UpdateAudibleState(aElement, aIsAudible);
}
NS_IMPL_ISUPPORTS(ResumeDelayedPlaybackAgent::ResumePlayDelegate,
nsIAudioChannelAgentCallback)
ResumeDelayedPlaybackAgent::ResumePlayDelegate::~ResumePlayDelegate() {
MOZ_ASSERT(!mAudioChannelAgent);
}
bool ResumeDelayedPlaybackAgent::ResumePlayDelegate::Init(
const HTMLMediaElement* aElement, bool aIsAudible) {
MOZ_ASSERT(aElement);
if (!aElement->OwnerDoc()->GetInnerWindow()) {
return false;
}
MOZ_ASSERT(!mAudioChannelAgent);
mAudioChannelAgent = new AudioChannelAgent();
nsresult rv =
mAudioChannelAgent->Init(aElement->OwnerDoc()->GetInnerWindow(), this);
if (NS_WARN_IF(NS_FAILED(rv))) {
Clear();
return false;
}
// Start AudioChannelAgent in order to wait the suspended state change when we
// are able to resume delayed playback.
AudibleState audibleState = DetermineMediaAudibleState(aElement, aIsAudible);
rv = mAudioChannelAgent->NotifyStartedPlaying(audibleState);
if (NS_WARN_IF(NS_FAILED(rv))) {
Clear();
return false;
}
return true;
}
void ResumeDelayedPlaybackAgent::ResumePlayDelegate::Clear() {
if (mAudioChannelAgent) {
mAudioChannelAgent->NotifyStoppedPlaying();
mAudioChannelAgent = nullptr;
}
mPromise.RejectIfExists(true, __func__);
}
RefPtr<ResumeDelayedPlaybackAgent::ResumePromise>
ResumeDelayedPlaybackAgent::ResumePlayDelegate::GetResumePromise() {
return mPromise.Ensure(__func__);
}
void ResumeDelayedPlaybackAgent::ResumePlayDelegate::UpdateAudibleState(
const HTMLMediaElement* aElement, bool aIsAudible) {
MOZ_ASSERT(aElement);
// It's possible for the owner of `ResumeDelayedPlaybackAgent` to call
// `UpdateAudibleState()` after we resolve the promise and clean resource.
if (!mAudioChannelAgent) {
return;
}
AudibleState audibleState = DetermineMediaAudibleState(aElement, aIsAudible);
mAudioChannelAgent->NotifyStartedAudible(
audibleState,
AudioChannelService::AudibleChangedReasons::eDataAudibleChanged);
}
NS_IMETHODIMP
ResumeDelayedPlaybackAgent::ResumePlayDelegate::WindowVolumeChanged(
float aVolume, bool aMuted) {
return NS_OK;
}
NS_IMETHODIMP
ResumeDelayedPlaybackAgent::ResumePlayDelegate::WindowAudioCaptureChanged(
bool aCapture) {
return NS_OK;
}
NS_IMETHODIMP
ResumeDelayedPlaybackAgent::ResumePlayDelegate::WindowSuspendChanged(
SuspendTypes aSuspend) {
if (aSuspend == nsISuspendedTypes::NONE_SUSPENDED) {
mPromise.ResolveIfExists(true, __func__);
Clear();
}
return NS_OK;
}
bool MediaPlaybackDelayPolicy::ShouldDelayPlayback(
const HTMLMediaElement* aElement) {
MOZ_ASSERT(aElement);
if (!StaticPrefs::media_block_autoplay_until_in_foreground()) {
return false;
}
const Document* doc = aElement->OwnerDoc();
nsPIDOMWindowInner* inner = nsPIDOMWindowInner::From(doc->GetInnerWindow());
nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::GetFromCurrentInner(inner);
if (!outer) {
return false;
}
return outer->GetMediaSuspend() == nsISuspendedTypes::SUSPENDED_BLOCK;
}
RefPtr<ResumeDelayedPlaybackAgent>
MediaPlaybackDelayPolicy::CreateResumeDelayedPlaybackAgent(
const HTMLMediaElement* aElement, bool aIsAudible) {
MOZ_ASSERT(aElement);
RefPtr<ResumeDelayedPlaybackAgent> agent = new ResumeDelayedPlaybackAgent();
return agent->InitDelegate(aElement, aIsAudible) ? agent : nullptr;
}
} // namespace dom
} // namespace mozilla