| |
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 "mozilla/dom/telephony/TelephonyParent.h" |
| |
7 #include "nsServiceManagerUtils.h" |
| |
8 |
| |
9 USING_TELEPHONY_NAMESPACE |
| |
10 |
| |
11 /******************************************************************************* |
| |
12 * TelephonyParent |
| |
13 ******************************************************************************/ |
| |
14 |
| |
15 NS_IMPL_ISUPPORTS(TelephonyParent, nsITelephonyListener) |
| |
16 |
| |
17 TelephonyParent::TelephonyParent() |
| |
18 : mActorDestroyed(false) |
| |
19 , mRegistered(false) |
| |
20 { |
| |
21 } |
| |
22 |
| |
23 void |
| |
24 TelephonyParent::ActorDestroy(ActorDestroyReason why) |
| |
25 { |
| |
26 // The child process could die before this asynchronous notification, in which |
| |
27 // case ActorDestroy() was called and mActorDestroyed is set to true. Return |
| |
28 // an error here to avoid sending a message to the dead process. |
| |
29 mActorDestroyed = true; |
| |
30 |
| |
31 // Try to unregister listener if we're still registered. |
| |
32 RecvUnregisterListener(); |
| |
33 } |
| |
34 |
| |
35 bool |
| |
36 TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor, |
| |
37 const IPCTelephonyRequest& aRequest) |
| |
38 { |
| |
39 TelephonyRequestParent* actor = static_cast<TelephonyRequestParent*>(aActor); |
| |
40 |
| |
41 switch (aRequest.type()) { |
| |
42 case IPCTelephonyRequest::TEnumerateCallsRequest: |
| |
43 return actor->DoRequest(aRequest.get_EnumerateCallsRequest()); |
| |
44 case IPCTelephonyRequest::TDialRequest: |
| |
45 return actor->DoRequest(aRequest.get_DialRequest()); |
| |
46 default: |
| |
47 MOZ_CRASH("Unknown type!"); |
| |
48 } |
| |
49 |
| |
50 return false; |
| |
51 } |
| |
52 |
| |
53 PTelephonyRequestParent* |
| |
54 TelephonyParent::AllocPTelephonyRequestParent(const IPCTelephonyRequest& aRequest) |
| |
55 { |
| |
56 TelephonyRequestParent* actor = new TelephonyRequestParent(); |
| |
57 // Add an extra ref for IPDL. Will be released in |
| |
58 // TelephonyParent::DeallocPTelephonyRequestParent(). |
| |
59 NS_ADDREF(actor); |
| |
60 |
| |
61 return actor; |
| |
62 } |
| |
63 |
| |
64 bool |
| |
65 TelephonyParent::DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) |
| |
66 { |
| |
67 // TelephonyRequestParent is refcounted, must not be freed manually. |
| |
68 static_cast<TelephonyRequestParent*>(aActor)->Release(); |
| |
69 return true; |
| |
70 } |
| |
71 |
| |
72 bool |
| |
73 TelephonyParent::Recv__delete__() |
| |
74 { |
| |
75 return true; // Unregister listener in TelephonyParent::ActorDestroy(). |
| |
76 } |
| |
77 |
| |
78 bool |
| |
79 TelephonyParent::RecvRegisterListener() |
| |
80 { |
| |
81 NS_ENSURE_TRUE(!mRegistered, true); |
| |
82 |
| |
83 nsCOMPtr<nsITelephonyProvider> provider = |
| |
84 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
85 NS_ENSURE_TRUE(provider, true); |
| |
86 |
| |
87 mRegistered = NS_SUCCEEDED(provider->RegisterListener(this)); |
| |
88 return true; |
| |
89 } |
| |
90 |
| |
91 bool |
| |
92 TelephonyParent::RecvUnregisterListener() |
| |
93 { |
| |
94 NS_ENSURE_TRUE(mRegistered, true); |
| |
95 |
| |
96 nsCOMPtr<nsITelephonyProvider> provider = |
| |
97 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
98 NS_ENSURE_TRUE(provider, true); |
| |
99 |
| |
100 mRegistered = !NS_SUCCEEDED(provider->UnregisterListener(this)); |
| |
101 return true; |
| |
102 } |
| |
103 |
| |
104 bool |
| |
105 TelephonyParent::RecvHangUpCall(const uint32_t& aClientId, |
| |
106 const uint32_t& aCallIndex) |
| |
107 { |
| |
108 nsCOMPtr<nsITelephonyProvider> provider = |
| |
109 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
110 NS_ENSURE_TRUE(provider, true); |
| |
111 |
| |
112 provider->HangUp(aClientId, aCallIndex); |
| |
113 return true; |
| |
114 } |
| |
115 |
| |
116 bool |
| |
117 TelephonyParent::RecvAnswerCall(const uint32_t& aClientId, |
| |
118 const uint32_t& aCallIndex) |
| |
119 { |
| |
120 nsCOMPtr<nsITelephonyProvider> provider = |
| |
121 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
122 NS_ENSURE_TRUE(provider, true); |
| |
123 |
| |
124 provider->AnswerCall(aClientId, aCallIndex); |
| |
125 return true; |
| |
126 } |
| |
127 |
| |
128 bool |
| |
129 TelephonyParent::RecvRejectCall(const uint32_t& aClientId, |
| |
130 const uint32_t& aCallIndex) |
| |
131 { |
| |
132 nsCOMPtr<nsITelephonyProvider> provider = |
| |
133 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
134 NS_ENSURE_TRUE(provider, true); |
| |
135 |
| |
136 provider->RejectCall(aClientId, aCallIndex); |
| |
137 return true; |
| |
138 } |
| |
139 |
| |
140 bool |
| |
141 TelephonyParent::RecvHoldCall(const uint32_t& aClientId, |
| |
142 const uint32_t& aCallIndex) |
| |
143 { |
| |
144 nsCOMPtr<nsITelephonyProvider> provider = |
| |
145 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
146 NS_ENSURE_TRUE(provider, true); |
| |
147 |
| |
148 provider->HoldCall(aClientId, aCallIndex); |
| |
149 return true; |
| |
150 } |
| |
151 |
| |
152 bool |
| |
153 TelephonyParent::RecvResumeCall(const uint32_t& aClientId, |
| |
154 const uint32_t& aCallIndex) |
| |
155 { |
| |
156 nsCOMPtr<nsITelephonyProvider> provider = |
| |
157 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
158 NS_ENSURE_TRUE(provider, true); |
| |
159 |
| |
160 provider->ResumeCall(aClientId, aCallIndex); |
| |
161 return true; |
| |
162 } |
| |
163 |
| |
164 bool |
| |
165 TelephonyParent::RecvConferenceCall(const uint32_t& aClientId) |
| |
166 { |
| |
167 nsCOMPtr<nsITelephonyProvider> provider = |
| |
168 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
169 NS_ENSURE_TRUE(provider, true); |
| |
170 |
| |
171 provider->ConferenceCall(aClientId); |
| |
172 return true; |
| |
173 } |
| |
174 |
| |
175 bool |
| |
176 TelephonyParent::RecvSeparateCall(const uint32_t& aClientId, |
| |
177 const uint32_t& aCallIndex) |
| |
178 { |
| |
179 nsCOMPtr<nsITelephonyProvider> provider = |
| |
180 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
181 NS_ENSURE_TRUE(provider, true); |
| |
182 |
| |
183 provider->SeparateCall(aClientId, aCallIndex); |
| |
184 return true; |
| |
185 } |
| |
186 |
| |
187 bool |
| |
188 TelephonyParent::RecvHoldConference(const uint32_t& aClientId) |
| |
189 { |
| |
190 nsCOMPtr<nsITelephonyProvider> provider = |
| |
191 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
192 NS_ENSURE_TRUE(provider, true); |
| |
193 |
| |
194 provider->HoldConference(aClientId); |
| |
195 return true; |
| |
196 } |
| |
197 |
| |
198 bool |
| |
199 TelephonyParent::RecvResumeConference(const uint32_t& aClientId) |
| |
200 { |
| |
201 nsCOMPtr<nsITelephonyProvider> provider = |
| |
202 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
203 NS_ENSURE_TRUE(provider, true); |
| |
204 |
| |
205 provider->ResumeConference(aClientId); |
| |
206 return true; |
| |
207 } |
| |
208 |
| |
209 bool |
| |
210 TelephonyParent::RecvStartTone(const uint32_t& aClientId, const nsString& aTone) |
| |
211 { |
| |
212 nsCOMPtr<nsITelephonyProvider> provider = |
| |
213 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
214 NS_ENSURE_TRUE(provider, true); |
| |
215 |
| |
216 provider->StartTone(aClientId, aTone); |
| |
217 return true; |
| |
218 } |
| |
219 |
| |
220 bool |
| |
221 TelephonyParent::RecvStopTone(const uint32_t& aClientId) |
| |
222 { |
| |
223 nsCOMPtr<nsITelephonyProvider> provider = |
| |
224 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
225 NS_ENSURE_TRUE(provider, true); |
| |
226 |
| |
227 provider->StopTone(aClientId); |
| |
228 return true; |
| |
229 } |
| |
230 |
| |
231 bool |
| |
232 TelephonyParent::RecvGetMicrophoneMuted(bool* aMuted) |
| |
233 { |
| |
234 *aMuted = false; |
| |
235 |
| |
236 nsCOMPtr<nsITelephonyProvider> provider = |
| |
237 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
238 NS_ENSURE_TRUE(provider, true); |
| |
239 |
| |
240 provider->GetMicrophoneMuted(aMuted); |
| |
241 return true; |
| |
242 } |
| |
243 |
| |
244 bool |
| |
245 TelephonyParent::RecvSetMicrophoneMuted(const bool& aMuted) |
| |
246 { |
| |
247 nsCOMPtr<nsITelephonyProvider> provider = |
| |
248 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
249 NS_ENSURE_TRUE(provider, true); |
| |
250 |
| |
251 provider->SetMicrophoneMuted(aMuted); |
| |
252 return true; |
| |
253 } |
| |
254 |
| |
255 bool |
| |
256 TelephonyParent::RecvGetSpeakerEnabled(bool* aEnabled) |
| |
257 { |
| |
258 *aEnabled = false; |
| |
259 |
| |
260 nsCOMPtr<nsITelephonyProvider> provider = |
| |
261 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
262 NS_ENSURE_TRUE(provider, true); |
| |
263 |
| |
264 provider->GetSpeakerEnabled(aEnabled); |
| |
265 return true; |
| |
266 } |
| |
267 |
| |
268 bool |
| |
269 TelephonyParent::RecvSetSpeakerEnabled(const bool& aEnabled) |
| |
270 { |
| |
271 nsCOMPtr<nsITelephonyProvider> provider = |
| |
272 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
273 NS_ENSURE_TRUE(provider, true); |
| |
274 |
| |
275 provider->SetSpeakerEnabled(aEnabled); |
| |
276 return true; |
| |
277 } |
| |
278 |
| |
279 // nsITelephonyListener |
| |
280 |
| |
281 NS_IMETHODIMP |
| |
282 TelephonyParent::CallStateChanged(uint32_t aClientId, |
| |
283 uint32_t aCallIndex, |
| |
284 uint16_t aCallState, |
| |
285 const nsAString& aNumber, |
| |
286 bool aIsActive, |
| |
287 bool aIsOutgoing, |
| |
288 bool aIsEmergency, |
| |
289 bool aIsConference, |
| |
290 bool aIsSwitchable, |
| |
291 bool aIsMergeable) |
| |
292 { |
| |
293 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
294 |
| |
295 IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), |
| |
296 aIsActive, aIsOutgoing, aIsEmergency, aIsConference, |
| |
297 aIsSwitchable, aIsMergeable); |
| |
298 return SendNotifyCallStateChanged(aClientId, data) ? NS_OK : NS_ERROR_FAILURE; |
| |
299 } |
| |
300 |
| |
301 NS_IMETHODIMP |
| |
302 TelephonyParent::ConferenceCallStateChanged(uint16_t aCallState) |
| |
303 { |
| |
304 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
305 |
| |
306 return SendNotifyConferenceCallStateChanged(aCallState) ? NS_OK |
| |
307 : NS_ERROR_FAILURE; |
| |
308 } |
| |
309 |
| |
310 NS_IMETHODIMP |
| |
311 TelephonyParent::EnumerateCallStateComplete() |
| |
312 { |
| |
313 MOZ_CRASH("Not a EnumerateCalls request!"); |
| |
314 } |
| |
315 |
| |
316 NS_IMETHODIMP |
| |
317 TelephonyParent::EnumerateCallState(uint32_t aClientId, |
| |
318 uint32_t aCallIndex, |
| |
319 uint16_t aCallState, |
| |
320 const nsAString& aNumber, |
| |
321 bool aIsActive, |
| |
322 bool aIsOutgoing, |
| |
323 bool aIsEmergency, |
| |
324 bool aIsConference, |
| |
325 bool aIsSwitchable, |
| |
326 bool aIsMergeable) |
| |
327 { |
| |
328 MOZ_CRASH("Not a EnumerateCalls request!"); |
| |
329 } |
| |
330 |
| |
331 NS_IMETHODIMP |
| |
332 TelephonyParent::NotifyCdmaCallWaiting(uint32_t aClientId, |
| |
333 const nsAString& aNumber) |
| |
334 { |
| |
335 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
336 |
| |
337 return SendNotifyCdmaCallWaiting(aClientId, nsString(aNumber)) |
| |
338 ? NS_OK : NS_ERROR_FAILURE; |
| |
339 } |
| |
340 |
| |
341 NS_IMETHODIMP |
| |
342 TelephonyParent::NotifyConferenceError(const nsAString& aName, |
| |
343 const nsAString& aMessage) |
| |
344 { |
| |
345 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
346 |
| |
347 return SendNotifyConferenceError(nsString(aName), nsString(aMessage)) ? NS_OK |
| |
348 : NS_ERROR_FAILURE; |
| |
349 } |
| |
350 |
| |
351 NS_IMETHODIMP |
| |
352 TelephonyParent::NotifyError(uint32_t aClientId, |
| |
353 int32_t aCallIndex, |
| |
354 const nsAString& aError) |
| |
355 { |
| |
356 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
357 |
| |
358 return SendNotifyCallError(aClientId, aCallIndex, nsString(aError)) |
| |
359 ? NS_OK : NS_ERROR_FAILURE; |
| |
360 } |
| |
361 |
| |
362 NS_IMETHODIMP |
| |
363 TelephonyParent::SupplementaryServiceNotification(uint32_t aClientId, |
| |
364 int32_t aCallIndex, |
| |
365 uint16_t aNotification) |
| |
366 { |
| |
367 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
368 |
| |
369 return SendNotifySupplementaryService(aClientId, aCallIndex, aNotification) |
| |
370 ? NS_OK : NS_ERROR_FAILURE; |
| |
371 } |
| |
372 |
| |
373 /******************************************************************************* |
| |
374 * TelephonyRequestParent |
| |
375 ******************************************************************************/ |
| |
376 |
| |
377 NS_IMPL_ISUPPORTS(TelephonyRequestParent, |
| |
378 nsITelephonyListener, |
| |
379 nsITelephonyCallback) |
| |
380 |
| |
381 TelephonyRequestParent::TelephonyRequestParent() |
| |
382 : mActorDestroyed(false) |
| |
383 { |
| |
384 } |
| |
385 |
| |
386 void |
| |
387 TelephonyRequestParent::ActorDestroy(ActorDestroyReason why) |
| |
388 { |
| |
389 // The child process could die before this asynchronous notification, in which |
| |
390 // case ActorDestroy() was called and mActorDestroyed is set to true. Return |
| |
391 // an error here to avoid sending a message to the dead process. |
| |
392 mActorDestroyed = true; |
| |
393 } |
| |
394 |
| |
395 bool |
| |
396 TelephonyRequestParent::DoRequest(const EnumerateCallsRequest& aRequest) |
| |
397 { |
| |
398 nsresult rv = NS_ERROR_FAILURE; |
| |
399 |
| |
400 nsCOMPtr<nsITelephonyProvider> provider = |
| |
401 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
402 if (provider) { |
| |
403 rv = provider->EnumerateCalls(this); |
| |
404 } |
| |
405 |
| |
406 if (NS_FAILED(rv)) { |
| |
407 return NS_SUCCEEDED(EnumerateCallStateComplete()); |
| |
408 } |
| |
409 |
| |
410 return true; |
| |
411 } |
| |
412 |
| |
413 bool |
| |
414 TelephonyRequestParent::DoRequest(const DialRequest& aRequest) |
| |
415 { |
| |
416 nsCOMPtr<nsITelephonyProvider> provider = |
| |
417 do_GetService(TELEPHONY_PROVIDER_CONTRACTID); |
| |
418 if (provider) { |
| |
419 provider->Dial(aRequest.clientId(), aRequest.number(), |
| |
420 aRequest.isEmergency(), this); |
| |
421 } else { |
| |
422 return NS_SUCCEEDED(NotifyDialError(NS_LITERAL_STRING("InvalidStateError"))); |
| |
423 } |
| |
424 |
| |
425 return true; |
| |
426 } |
| |
427 |
| |
428 // nsITelephonyListener |
| |
429 |
| |
430 NS_IMETHODIMP |
| |
431 TelephonyRequestParent::CallStateChanged(uint32_t aClientId, |
| |
432 uint32_t aCallIndex, |
| |
433 uint16_t aCallState, |
| |
434 const nsAString& aNumber, |
| |
435 bool aIsActive, |
| |
436 bool aIsOutgoing, |
| |
437 bool aIsEmergency, |
| |
438 bool aIsConference, |
| |
439 bool aIsSwitchable, |
| |
440 bool aIsMergeable) |
| |
441 { |
| |
442 MOZ_CRASH("Not a TelephonyParent!"); |
| |
443 } |
| |
444 |
| |
445 NS_IMETHODIMP |
| |
446 TelephonyRequestParent::ConferenceCallStateChanged(uint16_t aCallState) |
| |
447 { |
| |
448 MOZ_CRASH("Not a TelephonyParent!"); |
| |
449 } |
| |
450 |
| |
451 NS_IMETHODIMP |
| |
452 TelephonyRequestParent::EnumerateCallStateComplete() |
| |
453 { |
| |
454 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
455 |
| |
456 return Send__delete__(this, EnumerateCallsResponse()) ? NS_OK : NS_ERROR_FAILURE; |
| |
457 } |
| |
458 |
| |
459 NS_IMETHODIMP |
| |
460 TelephonyRequestParent::EnumerateCallState(uint32_t aClientId, |
| |
461 uint32_t aCallIndex, |
| |
462 uint16_t aCallState, |
| |
463 const nsAString& aNumber, |
| |
464 bool aIsActive, |
| |
465 bool aIsOutgoing, |
| |
466 bool aIsEmergency, |
| |
467 bool aIsConference, |
| |
468 bool aIsSwitchable, |
| |
469 bool aIsMergeable) |
| |
470 { |
| |
471 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
472 |
| |
473 IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), |
| |
474 aIsActive, aIsOutgoing, aIsEmergency, aIsConference, |
| |
475 aIsSwitchable, aIsMergeable); |
| |
476 return SendNotifyEnumerateCallState(aClientId, data) ? NS_OK |
| |
477 : NS_ERROR_FAILURE; |
| |
478 } |
| |
479 |
| |
480 NS_IMETHODIMP |
| |
481 TelephonyRequestParent::NotifyCdmaCallWaiting(uint32_t aClientId, |
| |
482 const nsAString& aNumber) |
| |
483 { |
| |
484 MOZ_CRASH("Not a TelephonyParent!"); |
| |
485 } |
| |
486 |
| |
487 NS_IMETHODIMP |
| |
488 TelephonyRequestParent::NotifyConferenceError(const nsAString& aName, |
| |
489 const nsAString& aMessage) |
| |
490 { |
| |
491 MOZ_CRASH("Not a TelephonyParent!"); |
| |
492 } |
| |
493 |
| |
494 NS_IMETHODIMP |
| |
495 TelephonyRequestParent::NotifyError(uint32_t aClientId, |
| |
496 int32_t aCallIndex, |
| |
497 const nsAString& aError) |
| |
498 { |
| |
499 MOZ_CRASH("Not a TelephonyParent!"); |
| |
500 } |
| |
501 |
| |
502 NS_IMETHODIMP |
| |
503 TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId, |
| |
504 int32_t aCallIndex, |
| |
505 uint16_t aNotification) |
| |
506 { |
| |
507 MOZ_CRASH("Not a TelephonyParent!"); |
| |
508 } |
| |
509 |
| |
510 // nsITelephonyCallback |
| |
511 |
| |
512 NS_IMETHODIMP |
| |
513 TelephonyRequestParent::NotifyDialError(const nsAString& aError) |
| |
514 { |
| |
515 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
516 |
| |
517 return (SendNotifyDialError(nsString(aError)) && |
| |
518 Send__delete__(this, DialResponse())) ? NS_OK : NS_ERROR_FAILURE; |
| |
519 } |
| |
520 |
| |
521 NS_IMETHODIMP |
| |
522 TelephonyRequestParent::NotifyDialSuccess() |
| |
523 { |
| |
524 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); |
| |
525 |
| |
526 return (SendNotifyDialSuccess() && |
| |
527 Send__delete__(this, DialResponse())) ? NS_OK : NS_ERROR_FAILURE; |
| |
528 } |