diff options
Diffstat (limited to 'dom/media/MediaPlaybackDelayPolicy.h')
-rw-r--r-- | dom/media/MediaPlaybackDelayPolicy.h | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/dom/media/MediaPlaybackDelayPolicy.h b/dom/media/MediaPlaybackDelayPolicy.h new file mode 100644 index 0000000000..17d9164d3b --- /dev/null +++ b/dom/media/MediaPlaybackDelayPolicy.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_dom_mediaplaybackdelaypolicy_h__ +#define mozilla_dom_mediaplaybackdelaypolicy_h__ + +#include "AudioChannelAgent.h" +#include "AudioChannelService.h" +#include "mozilla/MozPromise.h" +#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" + +typedef uint32_t SuspendTypes; + +namespace mozilla::dom { + +class HTMLMediaElement; +/** + * We usaually start AudioChannelAgent when media starts and stop it when media + * stops. However, when we decide to delay media playback for unvisited tab, we + * would start AudioChannelAgent even if media doesn't start in order to + * register the agent to AudioChannelService, so that the service could notify + * us when we are able to resume media playback. Therefore, + * ResumeDelayedPlaybackAgent is used to handle this special use case of + * AudioChannelAgent. + * - Use `GetResumePromise()` to require resume-promise and then do follow-up + * resume behavior when promise is resolved. + * - Use `UpdateAudibleState()` to update audible state only when media info + * changes. As having audio track or not is the only thing for us to decide + * whether we would show the delayed media playback icon on the tab bar. + */ +class ResumeDelayedPlaybackAgent { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResumeDelayedPlaybackAgent); + ResumeDelayedPlaybackAgent() = default; + + using ResumePromise = MozPromise<bool, bool, true /* IsExclusive */>; + RefPtr<ResumePromise> GetResumePromise(); + void UpdateAudibleState(const HTMLMediaElement* aElement, bool aIsAudible); + + private: + friend class MediaPlaybackDelayPolicy; + + ~ResumeDelayedPlaybackAgent(); + bool InitDelegate(const HTMLMediaElement* aElement, bool aIsAudible); + + class ResumePlayDelegate final : public nsIAudioChannelAgentCallback { + public: + NS_DECL_ISUPPORTS + + ResumePlayDelegate() = default; + + bool Init(const HTMLMediaElement* aElement, bool aIsAudible); + void UpdateAudibleState(const HTMLMediaElement* aElement, bool aIsAudible); + RefPtr<ResumePromise> GetResumePromise(); + void Clear(); + + NS_IMETHODIMP WindowVolumeChanged(float aVolume, bool aMuted) override; + NS_IMETHODIMP WindowAudioCaptureChanged(bool aCapture) override; + NS_IMETHODIMP WindowSuspendChanged(SuspendTypes aSuspend) override; + + private: + virtual ~ResumePlayDelegate(); + + MozPromiseHolder<ResumePromise> mPromise; + RefPtr<AudioChannelAgent> mAudioChannelAgent; + }; + + RefPtr<ResumePlayDelegate> mDelegate; +}; + +class MediaPlaybackDelayPolicy { + public: + static bool ShouldDelayPlayback(const HTMLMediaElement* aElement); + static RefPtr<ResumeDelayedPlaybackAgent> CreateResumeDelayedPlaybackAgent( + const HTMLMediaElement* aElement, bool aIsAudible); +}; + +} // namespace mozilla::dom + +#endif |