dom/audiochannel/AudioChannelAgent.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:8f0c8b78e4b8
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/. */
4
5 #include "AudioChannelAgent.h"
6 #include "AudioChannelCommon.h"
7 #include "AudioChannelService.h"
8 #include "nsIDOMWindow.h"
9 #include "nsPIDOMWindow.h"
10 #include "nsXULAppAPI.h"
11
12 using namespace mozilla::dom;
13
14 NS_IMPL_CYCLE_COLLECTION(AudioChannelAgent, mWindow, mCallback)
15
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
20
21 NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioChannelAgent)
22 NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioChannelAgent)
23
24 AudioChannelAgent::AudioChannelAgent()
25 : mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR)
26 , mIsRegToService(false)
27 , mVisible(true)
28 , mWithVideo(false)
29 {
30 }
31
32 AudioChannelAgent::~AudioChannelAgent()
33 {
34 if (mIsRegToService) {
35 StopPlaying();
36 }
37 }
38
39 /* readonly attribute long audioChannelType; */
40 NS_IMETHODIMP AudioChannelAgent::GetAudioChannelType(int32_t *aAudioChannelType)
41 {
42 *aAudioChannelType = mAudioChannelType;
43 return NS_OK;
44 }
45
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 }
55
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 }
66
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 }
77
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);
85
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");
96
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 }
102
103 mWindow = aWindow;
104 mAudioChannelType = aChannelType;
105
106 if (aUseWeakRef) {
107 mWeakCallback = do_GetWeakReference(aCallback);
108 } else {
109 mCallback = aCallback;
110 }
111
112 mWithVideo = aWithVideo;
113
114 return NS_OK;
115 }
116
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 }
125
126 service->RegisterAudioChannelAgent(this,
127 static_cast<AudioChannel>(mAudioChannelType), mWithVideo);
128 *_retval = service->GetState(this, !mVisible);
129 mIsRegToService = true;
130 return NS_OK;
131 }
132
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 }
140
141 AudioChannelService *service = AudioChannelService::GetAudioChannelService();
142 service->UnregisterAudioChannelAgent(this);
143 mIsRegToService = false;
144 return NS_OK;
145 }
146
147 /* void setVisibilityState (in boolean visible); */
148 NS_IMETHODIMP AudioChannelAgent::SetVisibilityState(bool visible)
149 {
150 bool oldVisibility = mVisible;
151
152 nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
153
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 }
161
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 }
170
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 }
180
181 void
182 AudioChannelAgent::WindowVolumeChanged()
183 {
184 nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
185 if (!callback) {
186 return;
187 }
188
189 callback->WindowVolumeChanged();
190 }
191
192 NS_IMETHODIMP
193 AudioChannelAgent::GetWindowVolume(float* aVolume)
194 {
195 NS_ENSURE_ARG_POINTER(aVolume);
196
197 nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
198 if (!win) {
199 *aVolume = 1.0f;
200 return NS_OK;
201 }
202
203 *aVolume = win->GetAudioGlobalVolume();
204 return NS_OK;
205 }

mercurial