|
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ |
|
2 /* vim: set ts=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_audiochannelservice_h__ |
|
8 #define mozilla_dom_audiochannelservice_h__ |
|
9 |
|
10 #include "nsAutoPtr.h" |
|
11 #include "nsIObserver.h" |
|
12 #include "nsTArray.h" |
|
13 #include "nsITimer.h" |
|
14 |
|
15 #include "AudioChannelCommon.h" |
|
16 #include "AudioChannelAgent.h" |
|
17 #include "nsAttrValue.h" |
|
18 #include "nsClassHashtable.h" |
|
19 #include "mozilla/dom/AudioChannelBinding.h" |
|
20 |
|
21 class nsPIDOMWindow; |
|
22 |
|
23 namespace mozilla { |
|
24 namespace dom { |
|
25 #ifdef MOZ_WIDGET_GONK |
|
26 class SpeakerManagerService; |
|
27 #endif |
|
28 class AudioChannelService |
|
29 : public nsIObserver |
|
30 , public nsITimerCallback |
|
31 { |
|
32 public: |
|
33 NS_DECL_ISUPPORTS |
|
34 NS_DECL_NSIOBSERVER |
|
35 NS_DECL_NSITIMERCALLBACK |
|
36 |
|
37 /** |
|
38 * Returns the AudioChannelServce singleton. Only to be called from main |
|
39 * thread. |
|
40 * |
|
41 * @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise. |
|
42 */ |
|
43 static AudioChannelService* GetAudioChannelService(); |
|
44 |
|
45 /** |
|
46 * Shutdown the singleton. |
|
47 */ |
|
48 static void Shutdown(); |
|
49 |
|
50 /** |
|
51 * Any audio channel agent that starts playing should register itself to |
|
52 * this service, sharing the AudioChannel. |
|
53 */ |
|
54 virtual void RegisterAudioChannelAgent(AudioChannelAgent* aAgent, |
|
55 AudioChannel aChannel, |
|
56 bool aWithVideo); |
|
57 |
|
58 /** |
|
59 * Any audio channel agent that stops playing should unregister itself to |
|
60 * this service. |
|
61 */ |
|
62 virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent); |
|
63 |
|
64 /** |
|
65 * Return the state to indicate this agent should keep playing/ |
|
66 * fading volume/muted. |
|
67 */ |
|
68 virtual AudioChannelState GetState(AudioChannelAgent* aAgent, |
|
69 bool aElementHidden); |
|
70 |
|
71 /** |
|
72 * Return true if there is a content channel active in this process |
|
73 * or one of its subprocesses. |
|
74 */ |
|
75 virtual bool ContentOrNormalChannelIsActive(); |
|
76 |
|
77 /** |
|
78 * Return true if a normal or content channel is active for the given |
|
79 * process ID. |
|
80 */ |
|
81 virtual bool ProcessContentOrNormalChannelIsActive(uint64_t aChildID); |
|
82 |
|
83 /*** |
|
84 * AudioChannelManager calls this function to notify the default channel used |
|
85 * to adjust volume when there is no any active channel. if aChannel is -1, |
|
86 * the default audio channel will be used. Otherwise aChannel is casted to |
|
87 * AudioChannel enum. |
|
88 */ |
|
89 virtual void SetDefaultVolumeControlChannel(int32_t aChannel, |
|
90 bool aHidden); |
|
91 |
|
92 bool AnyAudioChannelIsActive(); |
|
93 |
|
94 void RefreshAgentsVolume(nsPIDOMWindow* aWindow); |
|
95 |
|
96 #ifdef MOZ_WIDGET_GONK |
|
97 void RegisterSpeakerManager(SpeakerManagerService* aSpeakerManager) |
|
98 { |
|
99 if (!mSpeakerManager.Contains(aSpeakerManager)) { |
|
100 mSpeakerManager.AppendElement(aSpeakerManager); |
|
101 } |
|
102 } |
|
103 |
|
104 void UnregisterSpeakerManager(SpeakerManagerService* aSpeakerManager) |
|
105 { |
|
106 mSpeakerManager.RemoveElement(aSpeakerManager); |
|
107 } |
|
108 #endif |
|
109 |
|
110 static const nsAttrValue::EnumTable* GetAudioChannelTable(); |
|
111 static AudioChannel GetAudioChannel(const nsAString& aString); |
|
112 static AudioChannel GetDefaultAudioChannel(); |
|
113 static void GetAudioChannelString(AudioChannel aChannel, nsAString& aString); |
|
114 static void GetDefaultAudioChannelString(nsAString& aString); |
|
115 |
|
116 protected: |
|
117 void Notify(); |
|
118 |
|
119 /** |
|
120 * Send the audio-channel-changed notification for the given process ID if |
|
121 * needed. |
|
122 */ |
|
123 void SendAudioChannelChangedNotification(uint64_t aChildID); |
|
124 |
|
125 /* Register/Unregister IPC types: */ |
|
126 void RegisterType(AudioChannel aChannel, uint64_t aChildID, bool aWithVideo); |
|
127 void UnregisterType(AudioChannel aChannel, bool aElementHidden, |
|
128 uint64_t aChildID, bool aWithVideo); |
|
129 void UnregisterTypeInternal(AudioChannel aChannel, bool aElementHidden, |
|
130 uint64_t aChildID, bool aWithVideo); |
|
131 |
|
132 AudioChannelState GetStateInternal(AudioChannel aChannel, uint64_t aChildID, |
|
133 bool aElementHidden, |
|
134 bool aElementWasHidden); |
|
135 |
|
136 /* Update the internal type value following the visibility changes */ |
|
137 void UpdateChannelType(AudioChannel aChannel, uint64_t aChildID, |
|
138 bool aElementHidden, bool aElementWasHidden); |
|
139 |
|
140 /* Send the default-volume-channel-changed notification */ |
|
141 void SetDefaultVolumeControlChannelInternal(int32_t aChannel, |
|
142 bool aHidden, uint64_t aChildID); |
|
143 |
|
144 AudioChannelService(); |
|
145 virtual ~AudioChannelService(); |
|
146 |
|
147 enum AudioChannelInternalType { |
|
148 AUDIO_CHANNEL_INT_NORMAL = 0, |
|
149 AUDIO_CHANNEL_INT_NORMAL_HIDDEN, |
|
150 AUDIO_CHANNEL_INT_CONTENT, |
|
151 AUDIO_CHANNEL_INT_CONTENT_HIDDEN, |
|
152 AUDIO_CHANNEL_INT_NOTIFICATION, |
|
153 AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN, |
|
154 AUDIO_CHANNEL_INT_ALARM, |
|
155 AUDIO_CHANNEL_INT_ALARM_HIDDEN, |
|
156 AUDIO_CHANNEL_INT_TELEPHONY, |
|
157 AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN, |
|
158 AUDIO_CHANNEL_INT_RINGER, |
|
159 AUDIO_CHANNEL_INT_RINGER_HIDDEN, |
|
160 AUDIO_CHANNEL_INT_PUBLICNOTIFICATION, |
|
161 AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN, |
|
162 AUDIO_CHANNEL_INT_LAST |
|
163 }; |
|
164 |
|
165 bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType); |
|
166 |
|
167 bool CheckVolumeFadedCondition(AudioChannelInternalType aType, |
|
168 bool aElementHidden); |
|
169 |
|
170 AudioChannelInternalType GetInternalType(AudioChannel aChannel, |
|
171 bool aElementHidden); |
|
172 |
|
173 class AudioChannelAgentData { |
|
174 public: |
|
175 AudioChannelAgentData(AudioChannel aChannel, |
|
176 bool aElementHidden, |
|
177 AudioChannelState aState, |
|
178 bool aWithVideo) |
|
179 : mChannel(aChannel) |
|
180 , mElementHidden(aElementHidden) |
|
181 , mState(aState) |
|
182 , mWithVideo(aWithVideo) |
|
183 {} |
|
184 |
|
185 AudioChannel mChannel; |
|
186 bool mElementHidden; |
|
187 AudioChannelState mState; |
|
188 const bool mWithVideo; |
|
189 }; |
|
190 |
|
191 static PLDHashOperator |
|
192 NotifyEnumerator(AudioChannelAgent* aAgent, |
|
193 AudioChannelAgentData* aData, void *aUnused); |
|
194 |
|
195 static PLDHashOperator |
|
196 RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent, |
|
197 AudioChannelAgentData* aUnused, |
|
198 void *aPtr); |
|
199 |
|
200 static PLDHashOperator |
|
201 CountWindowEnumerator(AudioChannelAgent* aAgent, |
|
202 AudioChannelAgentData* aUnused, |
|
203 void *aPtr); |
|
204 |
|
205 // This returns the number of agents from this aWindow. |
|
206 uint32_t CountWindow(nsIDOMWindow* aWindow); |
|
207 |
|
208 nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents; |
|
209 #ifdef MOZ_WIDGET_GONK |
|
210 nsTArray<SpeakerManagerService*> mSpeakerManager; |
|
211 #endif |
|
212 nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_INT_LAST]; |
|
213 |
|
214 int32_t mCurrentHigherChannel; |
|
215 int32_t mCurrentVisibleHigherChannel; |
|
216 |
|
217 nsTArray<uint64_t> mWithVideoChildIDs; |
|
218 |
|
219 // mPlayableHiddenContentChildID stores the ChildID of the process which can |
|
220 // play content channel(s) in the background. |
|
221 // A background process contained content channel(s) will become playable: |
|
222 // 1. When this background process registers its content channel(s) in |
|
223 // AudioChannelService and there is no foreground process with registered |
|
224 // content channel(s). |
|
225 // 2. When this process goes from foreground into background and there is |
|
226 // no foreground process with registered content channel(s). |
|
227 // A background process contained content channel(s) will become non-playable: |
|
228 // 1. When there is a foreground process registering its content channel(s) |
|
229 // in AudioChannelService. |
|
230 // ps. Currently this condition is never satisfied because the default value |
|
231 // of visibility status of each channel during registering is hidden = true. |
|
232 // 2. When there is a process with registered content channel(s) goes from |
|
233 // background into foreground. |
|
234 // 3. When this process unregisters all hidden content channels. |
|
235 // 4. When this process shuts down. |
|
236 uint64_t mPlayableHiddenContentChildID; |
|
237 |
|
238 bool mDisabled; |
|
239 |
|
240 nsCOMPtr<nsITimer> mDeferTelChannelTimer; |
|
241 bool mTimerElementHidden; |
|
242 uint64_t mTimerChildID; |
|
243 |
|
244 uint64_t mDefChannelChildID; |
|
245 |
|
246 // This is needed for IPC comunication between |
|
247 // AudioChannelServiceChild and this class. |
|
248 friend class ContentParent; |
|
249 friend class ContentChild; |
|
250 }; |
|
251 |
|
252 } // namespace dom |
|
253 } // namespace mozilla |
|
254 |
|
255 #endif |