Backed out 7 changesets (bug 1942424) for causing frequent crashes. a=backout
[gecko.git] / dom / media / mediacontrol / MediaPlaybackStatus.h
blob7fec48cc35204dbb70d06e27df644dee3244b56a
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_
6 #define DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_
8 #include "mozilla/DefineEnum.h"
9 #include "mozilla/Maybe.h"
10 #include "mozilla/RefPtr.h"
11 #include "mozilla/dom/MediaSession.h"
12 #include "nsID.h"
13 #include "nsISupportsImpl.h"
14 #include "nsTArray.h"
15 #include "nsTHashMap.h"
17 namespace mozilla::dom {
19 /**
20 * This enum is used to update controlled media state to the media controller in
21 * the chrome process.
22 * `eStarted`: media has successfully registered to the content media controller
23 * `ePlayed` : media has started playing
24 * `ePaused` : media has paused playing, but still can be resumed by content
25 * media controller
26 * `eStopped`: media has unregistered from the content media controller, we can
27 * not control it anymore
29 MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING(MediaPlaybackState, uint32_t,
30 (eStarted, ePlayed, ePaused,
31 eStopped));
33 /**
34 * This enum is used to update controlled media audible audible state to the
35 * media controller in the chrome process.
37 MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING(MediaAudibleState, bool,
38 (eInaudible, eAudible));
40 /**
41 * MediaPlaybackStatus is an internal module for the media controller, it
42 * represents a tab's media related status, such like "does the tab contain any
43 * controlled media? is the tab playing? is the tab audible?".
45 * The reason we need this class is that we would like to encapsulate the
46 * details of determining the tab's media status. A tab can contains multiple
47 * browsing contexts, and each browsing context can have different media status.
48 * The final media status would be decided by checking all those context status.
50 * Use `UpdateMediaXXXState()` to update controlled media status, and use
51 * `IsXXX()` methods to acquire the playback status of the tab.
53 * As we know each context's audible state, we can decide which context should
54 * owns the audio focus when multiple contexts are all playing audible media at
55 * the same time. In that cases, the latest context that plays media would own
56 * the audio focus. When the context owning the audio focus is destroyed, we
57 * would see if there is another other context still playing audible media, and
58 * switch the audio focus to another context.
60 class MediaPlaybackStatus final {
61 public:
62 void UpdateMediaPlaybackState(uint64_t aContextId, MediaPlaybackState aState);
63 void UpdateMediaAudibleState(uint64_t aContextId, MediaAudibleState aState);
64 void UpdateGuessedPositionState(uint64_t aContextId, const nsID& aElementId,
65 const Maybe<PositionState>& aState);
67 bool IsPlaying() const;
68 bool IsAudible() const;
69 bool IsAnyMediaBeingControlled() const;
70 Maybe<PositionState> GuessedMediaPositionState(
71 Maybe<uint64_t> aPreferredContextId) const;
73 Maybe<uint64_t> GetAudioFocusOwnerContextId() const;
75 private:
76 /**
77 * This internal class stores detailed media status of controlled media for
78 * a browsing context.
80 class ContextMediaInfo final {
81 public:
82 explicit ContextMediaInfo(uint64_t aContextId) : mContextId(aContextId) {}
83 ~ContextMediaInfo() = default;
85 void IncreaseControlledMediaNum() {
86 #ifndef FUZZING_SNAPSHOT
87 MOZ_DIAGNOSTIC_ASSERT(mControlledMediaNum < UINT_MAX);
88 #endif
89 mControlledMediaNum++;
91 void DecreaseControlledMediaNum() {
92 #ifndef FUZZING_SNAPSHOT
93 MOZ_DIAGNOSTIC_ASSERT(mControlledMediaNum > 0);
94 #endif
95 mControlledMediaNum--;
97 void IncreasePlayingMediaNum() {
98 #ifndef FUZZING_SNAPSHOT
99 MOZ_DIAGNOSTIC_ASSERT(mPlayingMediaNum < mControlledMediaNum);
100 #endif
101 mPlayingMediaNum++;
103 void DecreasePlayingMediaNum() {
104 #ifndef FUZZING_SNAPSHOT
105 MOZ_DIAGNOSTIC_ASSERT(mPlayingMediaNum > 0);
106 #endif
107 mPlayingMediaNum--;
109 void IncreaseAudibleMediaNum() {
110 #ifndef FUZZING_SNAPSHOT
111 MOZ_DIAGNOSTIC_ASSERT(mAudibleMediaNum < mPlayingMediaNum);
112 #endif
113 mAudibleMediaNum++;
115 void DecreaseAudibleMediaNum() {
116 #ifndef FUZZING_SNAPSHOT
117 MOZ_DIAGNOSTIC_ASSERT(mAudibleMediaNum > 0);
118 #endif
119 mAudibleMediaNum--;
121 bool IsPlaying() const { return mPlayingMediaNum > 0; }
122 bool IsAudible() const { return mAudibleMediaNum > 0; }
123 bool IsAnyMediaBeingControlled() const { return mControlledMediaNum > 0; }
124 uint64_t Id() const { return mContextId; }
126 Maybe<PositionState> GuessedPositionState() const;
127 void UpdateGuessedPositionState(const nsID& aElementId,
128 const Maybe<PositionState>& aState);
130 private:
132 * The possible value for those three numbers should follow this rule,
133 * mControlledMediaNum >= mPlayingMediaNum >= mAudibleMediaNum
135 uint32_t mControlledMediaNum = 0;
136 uint32_t mAudibleMediaNum = 0;
137 uint32_t mPlayingMediaNum = 0;
138 uint64_t mContextId = 0;
141 * Contains the guessed position state of all media elements in this
142 * browsing context identified by their ID.
144 nsTHashMap<nsID, PositionState> mGuessedPositionStateMap;
147 ContextMediaInfo& GetNotNullContextInfo(uint64_t aContextId);
148 void DestroyContextInfo(uint64_t aContextId);
150 void ChooseNewContextToOwnAudioFocus();
151 void SetOwningAudioFocusContextId(Maybe<uint64_t>&& aContextId);
152 bool IsContextOwningAudioFocus(uint64_t aContextId) const;
153 bool ShouldRequestAudioFocusForInfo(const ContextMediaInfo& aInfo) const;
154 bool ShouldAbandonAudioFocusForInfo(const ContextMediaInfo& aInfo) const;
156 // This contains all the media status of browsing contexts within a tab.
157 nsTHashMap<uint64_t, UniquePtr<ContextMediaInfo>> mContextInfoMap;
158 Maybe<uint64_t> mOwningAudioFocusContextId;
161 } // namespace mozilla::dom
163 #endif // DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_