|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "ipc/TelephonyIPCProvider.h" |
|
7 |
|
8 #include "mozilla/dom/ContentChild.h" |
|
9 #include "mozilla/dom/telephony/TelephonyChild.h" |
|
10 #include "mozilla/Preferences.h" |
|
11 |
|
12 USING_TELEPHONY_NAMESPACE |
|
13 using namespace mozilla::dom; |
|
14 |
|
15 namespace { |
|
16 |
|
17 const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces"; |
|
18 #define kPrefDefaultServiceId "dom.telephony.defaultServiceId" |
|
19 const char* kObservedPrefs[] = { |
|
20 kPrefDefaultServiceId, |
|
21 nullptr |
|
22 }; |
|
23 |
|
24 uint32_t |
|
25 getDefaultServiceId() |
|
26 { |
|
27 int32_t id = mozilla::Preferences::GetInt(kPrefDefaultServiceId, 0); |
|
28 int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1); |
|
29 |
|
30 if (id >= numRil || id < 0) { |
|
31 id = 0; |
|
32 } |
|
33 |
|
34 return id; |
|
35 } |
|
36 |
|
37 } // Anonymous namespace |
|
38 |
|
39 NS_IMPL_ISUPPORTS(TelephonyIPCProvider, |
|
40 nsITelephonyProvider, |
|
41 nsITelephonyListener, |
|
42 nsIObserver) |
|
43 |
|
44 TelephonyIPCProvider::TelephonyIPCProvider() |
|
45 { |
|
46 // Deallocated in ContentChild::DeallocPTelephonyChild(). |
|
47 mPTelephonyChild = new TelephonyChild(this); |
|
48 ContentChild::GetSingleton()->SendPTelephonyConstructor(mPTelephonyChild); |
|
49 |
|
50 Preferences::AddStrongObservers(this, kObservedPrefs); |
|
51 mDefaultServiceId = getDefaultServiceId(); |
|
52 } |
|
53 |
|
54 TelephonyIPCProvider::~TelephonyIPCProvider() |
|
55 { |
|
56 mPTelephonyChild->Send__delete__(mPTelephonyChild); |
|
57 mPTelephonyChild = nullptr; |
|
58 } |
|
59 |
|
60 /* |
|
61 * Implementation of nsIObserver. |
|
62 */ |
|
63 |
|
64 NS_IMETHODIMP |
|
65 TelephonyIPCProvider::Observe(nsISupports* aSubject, |
|
66 const char* aTopic, |
|
67 const char16_t* aData) |
|
68 { |
|
69 if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { |
|
70 nsDependentString data(aData); |
|
71 if (data.EqualsLiteral(kPrefDefaultServiceId)) { |
|
72 mDefaultServiceId = getDefaultServiceId(); |
|
73 } |
|
74 return NS_OK; |
|
75 } |
|
76 |
|
77 MOZ_ASSERT(false, "TelephonyIPCProvider got unexpected topic!"); |
|
78 return NS_ERROR_UNEXPECTED; |
|
79 } |
|
80 |
|
81 /* |
|
82 * Implementation of nsITelephonyProvider. |
|
83 */ |
|
84 |
|
85 NS_IMETHODIMP |
|
86 TelephonyIPCProvider::GetDefaultServiceId(uint32_t* aServiceId) |
|
87 { |
|
88 *aServiceId = mDefaultServiceId; |
|
89 return NS_OK; |
|
90 } |
|
91 |
|
92 NS_IMETHODIMP |
|
93 TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener) |
|
94 { |
|
95 MOZ_ASSERT(!mListeners.Contains(aListener)); |
|
96 |
|
97 // nsTArray doesn't fail. |
|
98 mListeners.AppendElement(aListener); |
|
99 |
|
100 if (mListeners.Length() == 1) { |
|
101 mPTelephonyChild->SendRegisterListener(); |
|
102 } |
|
103 return NS_OK; |
|
104 } |
|
105 |
|
106 NS_IMETHODIMP |
|
107 TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener) |
|
108 { |
|
109 MOZ_ASSERT(mListeners.Contains(aListener)); |
|
110 |
|
111 // We always have the element here, so it can't fail. |
|
112 mListeners.RemoveElement(aListener); |
|
113 |
|
114 if (!mListeners.Length()) { |
|
115 mPTelephonyChild->SendUnregisterListener(); |
|
116 } |
|
117 return NS_OK; |
|
118 } |
|
119 |
|
120 nsresult |
|
121 TelephonyIPCProvider::SendRequest(nsITelephonyListener *aListener, |
|
122 nsITelephonyCallback *aCallback, |
|
123 const IPCTelephonyRequest& aRequest) |
|
124 { |
|
125 // Life time of newly allocated TelephonyRequestChild instance is managed by |
|
126 // IPDL itself. |
|
127 TelephonyRequestChild* actor = new TelephonyRequestChild(aListener, aCallback); |
|
128 mPTelephonyChild->SendPTelephonyRequestConstructor(actor, aRequest); |
|
129 return NS_OK; |
|
130 } |
|
131 |
|
132 NS_IMETHODIMP |
|
133 TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener) |
|
134 { |
|
135 return SendRequest(aListener, nullptr, EnumerateCallsRequest()); |
|
136 } |
|
137 |
|
138 NS_IMETHODIMP |
|
139 TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber, |
|
140 bool aIsEmergency, nsITelephonyCallback *aCallback) |
|
141 { |
|
142 return SendRequest(nullptr, aCallback, |
|
143 DialRequest(aClientId, nsString(aNumber), aIsEmergency)); |
|
144 } |
|
145 |
|
146 NS_IMETHODIMP |
|
147 TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex) |
|
148 { |
|
149 mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex); |
|
150 return NS_OK; |
|
151 } |
|
152 |
|
153 NS_IMETHODIMP |
|
154 TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex) |
|
155 { |
|
156 mPTelephonyChild->SendAnswerCall(aClientId, aCallIndex); |
|
157 return NS_OK; |
|
158 } |
|
159 |
|
160 NS_IMETHODIMP |
|
161 TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex) |
|
162 { |
|
163 mPTelephonyChild->SendRejectCall(aClientId, aCallIndex); |
|
164 return NS_OK; |
|
165 } |
|
166 |
|
167 NS_IMETHODIMP |
|
168 TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex) |
|
169 { |
|
170 mPTelephonyChild->SendHoldCall(aClientId, aCallIndex); |
|
171 return NS_OK; |
|
172 } |
|
173 |
|
174 NS_IMETHODIMP |
|
175 TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex) |
|
176 { |
|
177 mPTelephonyChild->SendResumeCall(aClientId, aCallIndex); |
|
178 return NS_OK; |
|
179 } |
|
180 |
|
181 NS_IMETHODIMP |
|
182 TelephonyIPCProvider::ConferenceCall(uint32_t aClientId) |
|
183 { |
|
184 mPTelephonyChild->SendConferenceCall(aClientId); |
|
185 return NS_OK; |
|
186 } |
|
187 |
|
188 NS_IMETHODIMP |
|
189 TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex) |
|
190 { |
|
191 mPTelephonyChild->SendSeparateCall(aClientId, aCallIndex); |
|
192 return NS_OK; |
|
193 } |
|
194 |
|
195 NS_IMETHODIMP |
|
196 TelephonyIPCProvider::HoldConference(uint32_t aClientId) |
|
197 { |
|
198 mPTelephonyChild->SendHoldConference(aClientId); |
|
199 return NS_OK; |
|
200 } |
|
201 |
|
202 NS_IMETHODIMP |
|
203 TelephonyIPCProvider::ResumeConference(uint32_t aClientId) |
|
204 { |
|
205 mPTelephonyChild->SendResumeConference(aClientId); |
|
206 return NS_OK; |
|
207 } |
|
208 |
|
209 NS_IMETHODIMP |
|
210 TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar) |
|
211 { |
|
212 mPTelephonyChild->SendStartTone(aClientId, nsString(aDtmfChar)); |
|
213 return NS_OK; |
|
214 } |
|
215 |
|
216 NS_IMETHODIMP |
|
217 TelephonyIPCProvider::StopTone(uint32_t aClientId) |
|
218 { |
|
219 mPTelephonyChild->SendStopTone(aClientId); |
|
220 return NS_OK; |
|
221 } |
|
222 |
|
223 NS_IMETHODIMP |
|
224 TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted) |
|
225 { |
|
226 mPTelephonyChild->SendGetMicrophoneMuted(aMuted); |
|
227 return NS_OK; |
|
228 } |
|
229 |
|
230 NS_IMETHODIMP |
|
231 TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted) |
|
232 { |
|
233 mPTelephonyChild->SendSetMicrophoneMuted(aMuted); |
|
234 return NS_OK; |
|
235 } |
|
236 |
|
237 NS_IMETHODIMP |
|
238 TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled) |
|
239 { |
|
240 mPTelephonyChild->SendGetSpeakerEnabled(aEnabled); |
|
241 return NS_OK; |
|
242 } |
|
243 |
|
244 NS_IMETHODIMP |
|
245 TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled) |
|
246 { |
|
247 mPTelephonyChild->SendSetSpeakerEnabled(aEnabled); |
|
248 return NS_OK; |
|
249 } |
|
250 |
|
251 // nsITelephonyListener |
|
252 |
|
253 NS_IMETHODIMP |
|
254 TelephonyIPCProvider::CallStateChanged(uint32_t aClientId, |
|
255 uint32_t aCallIndex, |
|
256 uint16_t aCallState, |
|
257 const nsAString& aNumber, |
|
258 bool aIsActive, |
|
259 bool aIsOutgoing, |
|
260 bool aIsEmergency, |
|
261 bool aIsConference, |
|
262 bool aIsSwitchable, |
|
263 bool aIsMergeable) |
|
264 { |
|
265 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
266 mListeners[i]->CallStateChanged(aClientId, aCallIndex, aCallState, aNumber, |
|
267 aIsActive, aIsOutgoing, aIsEmergency, |
|
268 aIsConference, aIsSwitchable, aIsMergeable); |
|
269 } |
|
270 return NS_OK; |
|
271 } |
|
272 |
|
273 NS_IMETHODIMP |
|
274 TelephonyIPCProvider::ConferenceCallStateChanged(uint16_t aCallState) |
|
275 { |
|
276 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
277 mListeners[i]->ConferenceCallStateChanged(aCallState); |
|
278 } |
|
279 return NS_OK; |
|
280 } |
|
281 |
|
282 NS_IMETHODIMP |
|
283 TelephonyIPCProvider::EnumerateCallStateComplete() |
|
284 { |
|
285 MOZ_CRASH("Not a EnumerateCalls request!"); |
|
286 } |
|
287 |
|
288 NS_IMETHODIMP |
|
289 TelephonyIPCProvider::EnumerateCallState(uint32_t aClientId, |
|
290 uint32_t aCallIndex, |
|
291 uint16_t aCallState, |
|
292 const nsAString& aNumber, |
|
293 bool aIsActive, |
|
294 bool aIsOutgoing, |
|
295 bool aIsEmergency, |
|
296 bool aIsConference, |
|
297 bool aIsSwitchable, |
|
298 bool aIsMergeable) |
|
299 { |
|
300 MOZ_CRASH("Not a EnumerateCalls request!"); |
|
301 } |
|
302 |
|
303 NS_IMETHODIMP |
|
304 TelephonyIPCProvider::NotifyCdmaCallWaiting(uint32_t aClientId, |
|
305 const nsAString& aNumber) |
|
306 { |
|
307 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
308 mListeners[i]->NotifyCdmaCallWaiting(aClientId, aNumber); |
|
309 } |
|
310 return NS_OK; |
|
311 } |
|
312 |
|
313 NS_IMETHODIMP |
|
314 TelephonyIPCProvider::NotifyConferenceError(const nsAString& aName, |
|
315 const nsAString& aMessage) |
|
316 { |
|
317 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
318 mListeners[i]->NotifyConferenceError(aName, aMessage); |
|
319 } |
|
320 return NS_OK; |
|
321 } |
|
322 |
|
323 NS_IMETHODIMP |
|
324 TelephonyIPCProvider::NotifyError(uint32_t aClientId, int32_t aCallIndex, |
|
325 const nsAString& aError) |
|
326 { |
|
327 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
328 mListeners[i]->NotifyError(aClientId, aCallIndex, aError); |
|
329 } |
|
330 return NS_OK; |
|
331 } |
|
332 |
|
333 NS_IMETHODIMP |
|
334 TelephonyIPCProvider::SupplementaryServiceNotification(uint32_t aClientId, |
|
335 int32_t aCallIndex, |
|
336 uint16_t aNotification) |
|
337 { |
|
338 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
339 mListeners[i]->SupplementaryServiceNotification(aClientId, aCallIndex, |
|
340 aNotification); |
|
341 } |
|
342 return NS_OK; |
|
343 } |