MediaPlaybackDelayPolicy.h (3056B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_mediaplaybackdelaypolicy_h__ 8 #define mozilla_dom_mediaplaybackdelaypolicy_h__ 9 10 #include "AudioChannelAgent.h" 11 #include "AudioChannelService.h" 12 #include "mozilla/MozPromise.h" 13 #include "mozilla/RefPtr.h" 14 #include "nsISupportsImpl.h" 15 16 typedef uint32_t SuspendTypes; 17 18 namespace mozilla::dom { 19 20 class HTMLMediaElement; 21 /** 22 * We usaually start AudioChannelAgent when media starts and stop it when media 23 * stops. However, when we decide to delay media playback for unvisited tab, we 24 * would start AudioChannelAgent even if media doesn't start in order to 25 * register the agent to AudioChannelService, so that the service could notify 26 * us when we are able to resume media playback. Therefore, 27 * ResumeDelayedPlaybackAgent is used to handle this special use case of 28 * AudioChannelAgent. 29 * - Use `GetResumePromise()` to require resume-promise and then do follow-up 30 * resume behavior when promise is resolved. 31 * - Use `UpdateAudibleState()` to update audible state only when media info 32 * changes. As having audio track or not is the only thing for us to decide 33 * whether we would show the delayed media playback icon on the tab bar. 34 */ 35 class ResumeDelayedPlaybackAgent { 36 public: 37 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResumeDelayedPlaybackAgent); 38 ResumeDelayedPlaybackAgent() = default; 39 40 using ResumePromise = MozPromise<bool, bool, true /* IsExclusive */>; 41 RefPtr<ResumePromise> GetResumePromise(); 42 void UpdateAudibleState(const HTMLMediaElement* aElement, bool aIsAudible); 43 44 private: 45 friend class MediaPlaybackDelayPolicy; 46 47 ~ResumeDelayedPlaybackAgent(); 48 bool InitDelegate(const HTMLMediaElement* aElement, bool aIsAudible); 49 50 class ResumePlayDelegate final : public nsIAudioChannelAgentCallback { 51 public: 52 NS_DECL_ISUPPORTS 53 54 ResumePlayDelegate() = default; 55 56 bool Init(const HTMLMediaElement* aElement, bool aIsAudible); 57 void UpdateAudibleState(const HTMLMediaElement* aElement, bool aIsAudible); 58 RefPtr<ResumePromise> GetResumePromise(); 59 void Clear(); 60 61 NS_IMETHODIMP WindowVolumeChanged(float aVolume, bool aMuted) override; 62 NS_IMETHODIMP WindowAudioCaptureChanged(bool aCapture) override; 63 NS_IMETHODIMP WindowSuspendChanged(SuspendTypes aSuspend) override; 64 65 private: 66 virtual ~ResumePlayDelegate(); 67 68 MozPromiseHolder<ResumePromise> mPromise; 69 RefPtr<AudioChannelAgent> mAudioChannelAgent; 70 }; 71 72 RefPtr<ResumePlayDelegate> mDelegate; 73 }; 74 75 class MediaPlaybackDelayPolicy { 76 public: 77 static bool ShouldDelayPlayback(const HTMLMediaElement* aElement); 78 static RefPtr<ResumeDelayedPlaybackAgent> CreateResumeDelayedPlaybackAgent( 79 const HTMLMediaElement* aElement, bool aIsAudible); 80 }; 81 82 } // namespace mozilla::dom 83 84 #endif