Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "AudioChannelAgent.h"
6 #include "AudioChannelCommon.h"
7 #include "AudioChannelService.h"
8 #include "nsIDOMWindow.h"
9 #include "nsPIDOMWindow.h"
10 #include "nsXULAppAPI.h"
12 using namespace mozilla::dom;
14 NS_IMPL_CYCLE_COLLECTION(AudioChannelAgent, mWindow, mCallback)
16 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioChannelAgent)
17 NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgent)
18 NS_INTERFACE_MAP_ENTRY(nsISupports)
19 NS_INTERFACE_MAP_END
21 NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioChannelAgent)
22 NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioChannelAgent)
24 AudioChannelAgent::AudioChannelAgent()
25 : mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR)
26 , mIsRegToService(false)
27 , mVisible(true)
28 , mWithVideo(false)
29 {
30 }
32 AudioChannelAgent::~AudioChannelAgent()
33 {
34 if (mIsRegToService) {
35 StopPlaying();
36 }
37 }
39 /* readonly attribute long audioChannelType; */
40 NS_IMETHODIMP AudioChannelAgent::GetAudioChannelType(int32_t *aAudioChannelType)
41 {
42 *aAudioChannelType = mAudioChannelType;
43 return NS_OK;
44 }
46 /* boolean init (in nsIDOMWindow window, in long channelType,
47 * in nsIAudioChannelAgentCallback callback); */
48 NS_IMETHODIMP
49 AudioChannelAgent::Init(nsIDOMWindow* aWindow, int32_t aChannelType,
50 nsIAudioChannelAgentCallback *aCallback)
51 {
52 return InitInternal(aWindow, aChannelType, aCallback,
53 /* useWeakRef = */ false);
54 }
56 /* boolean initWithWeakCallback (in nsIDOMWindow window, in long channelType,
57 * in nsIAudioChannelAgentCallback callback); */
58 NS_IMETHODIMP
59 AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow,
60 int32_t aChannelType,
61 nsIAudioChannelAgentCallback *aCallback)
62 {
63 return InitInternal(aWindow, aChannelType, aCallback,
64 /* useWeakRef = */ true);
65 }
67 /* void initWithVideo(in nsIDOMWindow window, in long channelType,
68 * in nsIAudioChannelAgentCallback callback, in boolean weak); */
69 NS_IMETHODIMP
70 AudioChannelAgent::InitWithVideo(nsIDOMWindow* aWindow, int32_t aChannelType,
71 nsIAudioChannelAgentCallback *aCallback,
72 bool aUseWeakRef)
73 {
74 return InitInternal(aWindow, aChannelType, aCallback, aUseWeakRef,
75 /* withVideo = */ true);
76 }
78 nsresult
79 AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
80 nsIAudioChannelAgentCallback *aCallback,
81 bool aUseWeakRef, bool aWithVideo)
82 {
83 // We need the window only for IPC.
84 MOZ_ASSERT(aWindow || XRE_GetProcessType() == GeckoProcessType_Default);
86 // We syncd the enum of channel type between nsIAudioChannelAgent.idl and
87 // AudioChannelBinding.h the same.
88 MOZ_ASSERT(int(AUDIO_AGENT_CHANNEL_NORMAL) == int(AudioChannel::Normal) &&
89 int(AUDIO_AGENT_CHANNEL_CONTENT) == int(AudioChannel::Content) &&
90 int(AUDIO_AGENT_CHANNEL_NOTIFICATION) == int(AudioChannel::Notification) &&
91 int(AUDIO_AGENT_CHANNEL_ALARM) == int(AudioChannel::Alarm) &&
92 int(AUDIO_AGENT_CHANNEL_TELEPHONY) == int(AudioChannel::Telephony) &&
93 int(AUDIO_AGENT_CHANNEL_RINGER) == int(AudioChannel::Ringer) &&
94 int(AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION) == int(AudioChannel::Publicnotification),
95 "Enum of channel on nsIAudioChannelAgent.idl should be the same with AudioChannelBinding.h");
97 if (mAudioChannelType != AUDIO_AGENT_CHANNEL_ERROR ||
98 aChannelType > AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION ||
99 aChannelType < AUDIO_AGENT_CHANNEL_NORMAL) {
100 return NS_ERROR_FAILURE;
101 }
103 mWindow = aWindow;
104 mAudioChannelType = aChannelType;
106 if (aUseWeakRef) {
107 mWeakCallback = do_GetWeakReference(aCallback);
108 } else {
109 mCallback = aCallback;
110 }
112 mWithVideo = aWithVideo;
114 return NS_OK;
115 }
117 /* boolean startPlaying (); */
118 NS_IMETHODIMP AudioChannelAgent::StartPlaying(int32_t *_retval)
119 {
120 AudioChannelService *service = AudioChannelService::GetAudioChannelService();
121 if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
122 service == nullptr || mIsRegToService) {
123 return NS_ERROR_FAILURE;
124 }
126 service->RegisterAudioChannelAgent(this,
127 static_cast<AudioChannel>(mAudioChannelType), mWithVideo);
128 *_retval = service->GetState(this, !mVisible);
129 mIsRegToService = true;
130 return NS_OK;
131 }
133 /* void stopPlaying (); */
134 NS_IMETHODIMP AudioChannelAgent::StopPlaying(void)
135 {
136 if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
137 !mIsRegToService) {
138 return NS_ERROR_FAILURE;
139 }
141 AudioChannelService *service = AudioChannelService::GetAudioChannelService();
142 service->UnregisterAudioChannelAgent(this);
143 mIsRegToService = false;
144 return NS_OK;
145 }
147 /* void setVisibilityState (in boolean visible); */
148 NS_IMETHODIMP AudioChannelAgent::SetVisibilityState(bool visible)
149 {
150 bool oldVisibility = mVisible;
152 nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
154 mVisible = visible;
155 if (mIsRegToService && oldVisibility != mVisible && callback) {
156 AudioChannelService *service = AudioChannelService::GetAudioChannelService();
157 callback->CanPlayChanged(service->GetState(this, !mVisible));
158 }
159 return NS_OK;
160 }
162 void AudioChannelAgent::NotifyAudioChannelStateChanged()
163 {
164 nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
165 if (callback) {
166 AudioChannelService *service = AudioChannelService::GetAudioChannelService();
167 callback->CanPlayChanged(service->GetState(this, !mVisible));
168 }
169 }
171 already_AddRefed<nsIAudioChannelAgentCallback>
172 AudioChannelAgent::GetCallback()
173 {
174 nsCOMPtr<nsIAudioChannelAgentCallback> callback = mCallback;
175 if (!callback) {
176 callback = do_QueryReferent(mWeakCallback);
177 }
178 return callback.forget();
179 }
181 void
182 AudioChannelAgent::WindowVolumeChanged()
183 {
184 nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
185 if (!callback) {
186 return;
187 }
189 callback->WindowVolumeChanged();
190 }
192 NS_IMETHODIMP
193 AudioChannelAgent::GetWindowVolume(float* aVolume)
194 {
195 NS_ENSURE_ARG_POINTER(aVolume);
197 nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
198 if (!win) {
199 *aVolume = 1.0f;
200 return NS_OK;
201 }
203 *aVolume = win->GetAudioGlobalVolume();
204 return NS_OK;
205 }