|
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 } |