1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/audiochannel/AudioChannelService.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,255 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_audiochannelservice_h__ 1.11 +#define mozilla_dom_audiochannelservice_h__ 1.12 + 1.13 +#include "nsAutoPtr.h" 1.14 +#include "nsIObserver.h" 1.15 +#include "nsTArray.h" 1.16 +#include "nsITimer.h" 1.17 + 1.18 +#include "AudioChannelCommon.h" 1.19 +#include "AudioChannelAgent.h" 1.20 +#include "nsAttrValue.h" 1.21 +#include "nsClassHashtable.h" 1.22 +#include "mozilla/dom/AudioChannelBinding.h" 1.23 + 1.24 +class nsPIDOMWindow; 1.25 + 1.26 +namespace mozilla { 1.27 +namespace dom { 1.28 +#ifdef MOZ_WIDGET_GONK 1.29 +class SpeakerManagerService; 1.30 +#endif 1.31 +class AudioChannelService 1.32 +: public nsIObserver 1.33 +, public nsITimerCallback 1.34 +{ 1.35 +public: 1.36 + NS_DECL_ISUPPORTS 1.37 + NS_DECL_NSIOBSERVER 1.38 + NS_DECL_NSITIMERCALLBACK 1.39 + 1.40 + /** 1.41 + * Returns the AudioChannelServce singleton. Only to be called from main 1.42 + * thread. 1.43 + * 1.44 + * @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise. 1.45 + */ 1.46 + static AudioChannelService* GetAudioChannelService(); 1.47 + 1.48 + /** 1.49 + * Shutdown the singleton. 1.50 + */ 1.51 + static void Shutdown(); 1.52 + 1.53 + /** 1.54 + * Any audio channel agent that starts playing should register itself to 1.55 + * this service, sharing the AudioChannel. 1.56 + */ 1.57 + virtual void RegisterAudioChannelAgent(AudioChannelAgent* aAgent, 1.58 + AudioChannel aChannel, 1.59 + bool aWithVideo); 1.60 + 1.61 + /** 1.62 + * Any audio channel agent that stops playing should unregister itself to 1.63 + * this service. 1.64 + */ 1.65 + virtual void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent); 1.66 + 1.67 + /** 1.68 + * Return the state to indicate this agent should keep playing/ 1.69 + * fading volume/muted. 1.70 + */ 1.71 + virtual AudioChannelState GetState(AudioChannelAgent* aAgent, 1.72 + bool aElementHidden); 1.73 + 1.74 + /** 1.75 + * Return true if there is a content channel active in this process 1.76 + * or one of its subprocesses. 1.77 + */ 1.78 + virtual bool ContentOrNormalChannelIsActive(); 1.79 + 1.80 + /** 1.81 + * Return true if a normal or content channel is active for the given 1.82 + * process ID. 1.83 + */ 1.84 + virtual bool ProcessContentOrNormalChannelIsActive(uint64_t aChildID); 1.85 + 1.86 + /*** 1.87 + * AudioChannelManager calls this function to notify the default channel used 1.88 + * to adjust volume when there is no any active channel. if aChannel is -1, 1.89 + * the default audio channel will be used. Otherwise aChannel is casted to 1.90 + * AudioChannel enum. 1.91 + */ 1.92 + virtual void SetDefaultVolumeControlChannel(int32_t aChannel, 1.93 + bool aHidden); 1.94 + 1.95 + bool AnyAudioChannelIsActive(); 1.96 + 1.97 + void RefreshAgentsVolume(nsPIDOMWindow* aWindow); 1.98 + 1.99 +#ifdef MOZ_WIDGET_GONK 1.100 + void RegisterSpeakerManager(SpeakerManagerService* aSpeakerManager) 1.101 + { 1.102 + if (!mSpeakerManager.Contains(aSpeakerManager)) { 1.103 + mSpeakerManager.AppendElement(aSpeakerManager); 1.104 + } 1.105 + } 1.106 + 1.107 + void UnregisterSpeakerManager(SpeakerManagerService* aSpeakerManager) 1.108 + { 1.109 + mSpeakerManager.RemoveElement(aSpeakerManager); 1.110 + } 1.111 +#endif 1.112 + 1.113 + static const nsAttrValue::EnumTable* GetAudioChannelTable(); 1.114 + static AudioChannel GetAudioChannel(const nsAString& aString); 1.115 + static AudioChannel GetDefaultAudioChannel(); 1.116 + static void GetAudioChannelString(AudioChannel aChannel, nsAString& aString); 1.117 + static void GetDefaultAudioChannelString(nsAString& aString); 1.118 + 1.119 +protected: 1.120 + void Notify(); 1.121 + 1.122 + /** 1.123 + * Send the audio-channel-changed notification for the given process ID if 1.124 + * needed. 1.125 + */ 1.126 + void SendAudioChannelChangedNotification(uint64_t aChildID); 1.127 + 1.128 + /* Register/Unregister IPC types: */ 1.129 + void RegisterType(AudioChannel aChannel, uint64_t aChildID, bool aWithVideo); 1.130 + void UnregisterType(AudioChannel aChannel, bool aElementHidden, 1.131 + uint64_t aChildID, bool aWithVideo); 1.132 + void UnregisterTypeInternal(AudioChannel aChannel, bool aElementHidden, 1.133 + uint64_t aChildID, bool aWithVideo); 1.134 + 1.135 + AudioChannelState GetStateInternal(AudioChannel aChannel, uint64_t aChildID, 1.136 + bool aElementHidden, 1.137 + bool aElementWasHidden); 1.138 + 1.139 + /* Update the internal type value following the visibility changes */ 1.140 + void UpdateChannelType(AudioChannel aChannel, uint64_t aChildID, 1.141 + bool aElementHidden, bool aElementWasHidden); 1.142 + 1.143 + /* Send the default-volume-channel-changed notification */ 1.144 + void SetDefaultVolumeControlChannelInternal(int32_t aChannel, 1.145 + bool aHidden, uint64_t aChildID); 1.146 + 1.147 + AudioChannelService(); 1.148 + virtual ~AudioChannelService(); 1.149 + 1.150 + enum AudioChannelInternalType { 1.151 + AUDIO_CHANNEL_INT_NORMAL = 0, 1.152 + AUDIO_CHANNEL_INT_NORMAL_HIDDEN, 1.153 + AUDIO_CHANNEL_INT_CONTENT, 1.154 + AUDIO_CHANNEL_INT_CONTENT_HIDDEN, 1.155 + AUDIO_CHANNEL_INT_NOTIFICATION, 1.156 + AUDIO_CHANNEL_INT_NOTIFICATION_HIDDEN, 1.157 + AUDIO_CHANNEL_INT_ALARM, 1.158 + AUDIO_CHANNEL_INT_ALARM_HIDDEN, 1.159 + AUDIO_CHANNEL_INT_TELEPHONY, 1.160 + AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN, 1.161 + AUDIO_CHANNEL_INT_RINGER, 1.162 + AUDIO_CHANNEL_INT_RINGER_HIDDEN, 1.163 + AUDIO_CHANNEL_INT_PUBLICNOTIFICATION, 1.164 + AUDIO_CHANNEL_INT_PUBLICNOTIFICATION_HIDDEN, 1.165 + AUDIO_CHANNEL_INT_LAST 1.166 + }; 1.167 + 1.168 + bool ChannelsActiveWithHigherPriorityThan(AudioChannelInternalType aType); 1.169 + 1.170 + bool CheckVolumeFadedCondition(AudioChannelInternalType aType, 1.171 + bool aElementHidden); 1.172 + 1.173 + AudioChannelInternalType GetInternalType(AudioChannel aChannel, 1.174 + bool aElementHidden); 1.175 + 1.176 + class AudioChannelAgentData { 1.177 + public: 1.178 + AudioChannelAgentData(AudioChannel aChannel, 1.179 + bool aElementHidden, 1.180 + AudioChannelState aState, 1.181 + bool aWithVideo) 1.182 + : mChannel(aChannel) 1.183 + , mElementHidden(aElementHidden) 1.184 + , mState(aState) 1.185 + , mWithVideo(aWithVideo) 1.186 + {} 1.187 + 1.188 + AudioChannel mChannel; 1.189 + bool mElementHidden; 1.190 + AudioChannelState mState; 1.191 + const bool mWithVideo; 1.192 + }; 1.193 + 1.194 + static PLDHashOperator 1.195 + NotifyEnumerator(AudioChannelAgent* aAgent, 1.196 + AudioChannelAgentData* aData, void *aUnused); 1.197 + 1.198 + static PLDHashOperator 1.199 + RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent, 1.200 + AudioChannelAgentData* aUnused, 1.201 + void *aPtr); 1.202 + 1.203 + static PLDHashOperator 1.204 + CountWindowEnumerator(AudioChannelAgent* aAgent, 1.205 + AudioChannelAgentData* aUnused, 1.206 + void *aPtr); 1.207 + 1.208 + // This returns the number of agents from this aWindow. 1.209 + uint32_t CountWindow(nsIDOMWindow* aWindow); 1.210 + 1.211 + nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents; 1.212 +#ifdef MOZ_WIDGET_GONK 1.213 + nsTArray<SpeakerManagerService*> mSpeakerManager; 1.214 +#endif 1.215 + nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_INT_LAST]; 1.216 + 1.217 + int32_t mCurrentHigherChannel; 1.218 + int32_t mCurrentVisibleHigherChannel; 1.219 + 1.220 + nsTArray<uint64_t> mWithVideoChildIDs; 1.221 + 1.222 + // mPlayableHiddenContentChildID stores the ChildID of the process which can 1.223 + // play content channel(s) in the background. 1.224 + // A background process contained content channel(s) will become playable: 1.225 + // 1. When this background process registers its content channel(s) in 1.226 + // AudioChannelService and there is no foreground process with registered 1.227 + // content channel(s). 1.228 + // 2. When this process goes from foreground into background and there is 1.229 + // no foreground process with registered content channel(s). 1.230 + // A background process contained content channel(s) will become non-playable: 1.231 + // 1. When there is a foreground process registering its content channel(s) 1.232 + // in AudioChannelService. 1.233 + // ps. Currently this condition is never satisfied because the default value 1.234 + // of visibility status of each channel during registering is hidden = true. 1.235 + // 2. When there is a process with registered content channel(s) goes from 1.236 + // background into foreground. 1.237 + // 3. When this process unregisters all hidden content channels. 1.238 + // 4. When this process shuts down. 1.239 + uint64_t mPlayableHiddenContentChildID; 1.240 + 1.241 + bool mDisabled; 1.242 + 1.243 + nsCOMPtr<nsITimer> mDeferTelChannelTimer; 1.244 + bool mTimerElementHidden; 1.245 + uint64_t mTimerChildID; 1.246 + 1.247 + uint64_t mDefChannelChildID; 1.248 + 1.249 + // This is needed for IPC comunication between 1.250 + // AudioChannelServiceChild and this class. 1.251 + friend class ContentParent; 1.252 + friend class ContentChild; 1.253 +}; 1.254 + 1.255 +} // namespace dom 1.256 +} // namespace mozilla 1.257 + 1.258 +#endif