1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BluetoothRilListener.h"
9 #include "BluetoothHfpManager.h"
10 #include "nsIIccProvider.h"
11 #include "nsIMobileConnectionInfo.h"
12 #include "nsIMobileConnectionService.h"
13 #include "nsITelephonyService.h"
14 #include "nsRadioInterfaceLayer.h" // For NS_RILCONTENTHELPER_CONTRACTID.
15 #include "nsServiceManagerUtils.h"
18 USING_BLUETOOTH_NAMESPACE
23 NS_IMPL_ISUPPORTS(IccListener
, nsIIccListener
)
26 IccListener::NotifyIccInfoChanged()
28 // mOwner would be set to nullptr only in the dtor of BluetoothRilListener
29 NS_ENSURE_TRUE(mOwner
, NS_ERROR_FAILURE
);
31 BluetoothHfpManager
* hfp
= BluetoothHfpManager::Get();
32 NS_ENSURE_TRUE(hfp
, NS_ERROR_FAILURE
);
34 hfp
->HandleIccInfoChanged(mOwner
->mClientId
);
40 IccListener::NotifyStkCommand(const nsAString
& aMessage
)
46 IccListener::NotifyStkSessionEnd()
52 IccListener::NotifyCardStateChanged()
58 IccListener::Listen(bool aStart
)
60 NS_ENSURE_TRUE(mOwner
, false);
62 nsCOMPtr
<nsIIccProvider
> provider
=
63 do_GetService(NS_RILCONTENTHELPER_CONTRACTID
);
64 NS_ENSURE_TRUE(provider
, false);
68 rv
= provider
->RegisterIccMsg(mOwner
->mClientId
, this);
70 rv
= provider
->UnregisterIccMsg(mOwner
->mClientId
, this);
73 return NS_SUCCEEDED(rv
);
77 IccListener::SetOwner(BluetoothRilListener
*aOwner
)
83 * MobileConnectionListener
85 NS_IMPL_ISUPPORTS(MobileConnectionListener
, nsIMobileConnectionListener
)
88 MobileConnectionListener::NotifyVoiceChanged()
90 BluetoothHfpManager
* hfp
= BluetoothHfpManager::Get();
91 NS_ENSURE_TRUE(hfp
, NS_OK
);
93 hfp
->HandleVoiceConnectionChanged(mClientId
);
99 MobileConnectionListener::NotifyDataChanged()
105 MobileConnectionListener::NotifyDataError(const nsAString
& message
)
111 MobileConnectionListener::NotifyCFStateChanged(uint16_t action
,
113 const nsAString
& number
,
114 uint16_t timeSeconds
,
115 uint16_t serviceClass
)
121 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active
,
128 MobileConnectionListener::NotifyOtaStatusChanged(const nsAString
& status
)
134 MobileConnectionListener::NotifyRadioStateChanged()
140 MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode
)
146 MobileConnectionListener::NotifyLastKnownNetworkChanged()
152 MobileConnectionListener::NotifyLastKnownHomeNetworkChanged()
158 MobileConnectionListener::NotifyNetworkSelectionModeChanged()
164 MobileConnectionListener::Listen(bool aStart
)
166 nsCOMPtr
<nsIMobileConnectionService
> service
=
167 do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID
);
168 NS_ENSURE_TRUE(service
, false);
170 nsCOMPtr
<nsIMobileConnection
> connection
;
171 service
->GetItemByServiceId(mClientId
, getter_AddRefs(connection
));
172 NS_ENSURE_TRUE(connection
, false);
176 rv
= connection
->RegisterListener(this);
178 rv
= connection
->UnregisterListener(this);
181 return NS_SUCCEEDED(rv
);
185 * TelephonyListener Implementation
187 NS_IMPL_ISUPPORTS(TelephonyListener
, nsITelephonyListener
)
190 * @param aSend A boolean indicates whether we need to notify headset or not
193 TelephonyListener::HandleCallInfo(nsITelephonyCallInfo
* aInfo
, bool aSend
)
195 BluetoothHfpManager
* hfp
= BluetoothHfpManager::Get();
196 NS_ENSURE_TRUE(hfp
, NS_ERROR_FAILURE
);
204 aInfo
->GetCallIndex(&callIndex
);
205 aInfo
->GetCallState(&callState
);
206 aInfo
->GetNumber(number
);
207 aInfo
->GetIsOutgoing(&isOutgoing
);
208 aInfo
->GetIsConference(&isConference
);
210 hfp
->HandleCallStateChanged(callIndex
, callState
, EmptyString(), number
,
211 isOutgoing
, isConference
, aSend
);
216 TelephonyListener::CallStateChanged(nsITelephonyCallInfo
* aInfo
)
218 return HandleCallInfo(aInfo
, true);
222 TelephonyListener::EnumerateCallState(nsITelephonyCallInfo
* aInfo
)
224 return HandleCallInfo(aInfo
, false);
228 TelephonyListener::NotifyError(uint32_t aServiceId
,
230 const nsAString
& aError
)
232 BluetoothHfpManager
* hfp
= BluetoothHfpManager::Get();
233 NS_ENSURE_TRUE(hfp
, NS_ERROR_FAILURE
);
235 if (aCallIndex
> 0) {
236 // In order to not miss any related call state transition.
237 // It's possible that 3G network signal lost for unknown reason.
238 // If a call is released abnormally, NotifyError() will be called,
239 // instead of CallStateChanged(). We need to reset the call array state
240 // via setting CALL_STATE_DISCONNECTED
241 hfp
->HandleCallStateChanged(aCallIndex
,
242 nsITelephonyService::CALL_STATE_DISCONNECTED
,
243 aError
, EmptyString(), false, false, true);
244 BT_WARNING("Reset the call state due to call transition ends abnormally");
247 BT_WARNING(NS_ConvertUTF16toUTF8(aError
).get());
252 TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState
)
258 TelephonyListener::EnumerateCallStateComplete()
264 TelephonyListener::SupplementaryServiceNotification(uint32_t aServiceId
,
266 uint16_t aNotification
)
272 TelephonyListener::NotifyConferenceError(const nsAString
& aName
,
273 const nsAString
& aMessage
)
275 BT_WARNING(NS_ConvertUTF16toUTF8(aName
).get());
276 BT_WARNING(NS_ConvertUTF16toUTF8(aMessage
).get());
282 TelephonyListener::NotifyCdmaCallWaiting(uint32_t aServiceId
,
283 const nsAString
& aNumber
,
284 uint16_t aNumberPresentation
,
285 const nsAString
& aName
,
286 uint16_t aNamePresentation
)
288 BluetoothHfpManager
* hfp
= BluetoothHfpManager::Get();
289 NS_ENSURE_TRUE(hfp
, NS_ERROR_FAILURE
);
291 hfp
->UpdateSecondNumber(aNumber
);
297 TelephonyListener::Listen(bool aStart
)
299 nsCOMPtr
<nsITelephonyService
> service
=
300 do_GetService(TELEPHONY_SERVICE_CONTRACTID
);
301 NS_ENSURE_TRUE(service
, false);
305 rv
= service
->RegisterListener(this);
307 rv
= service
->UnregisterListener(this);
310 return NS_SUCCEEDED(rv
);
314 * BluetoothRilListener
316 BluetoothRilListener::BluetoothRilListener()
318 nsCOMPtr
<nsIMobileConnectionService
> service
=
319 do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID
);
320 NS_ENSURE_TRUE_VOID(service
);
322 // Query number of total clients (sim slots)
323 uint32_t numItems
= 0;
324 if (NS_SUCCEEDED(service
->GetNumItems(&numItems
))) {
325 // Init MobileConnectionListener array and IccInfoListener
326 for (uint32_t i
= 0; i
< numItems
; i
++) {
327 mMobileConnListeners
.AppendElement(new MobileConnectionListener(i
));
331 mTelephonyListener
= new TelephonyListener();
332 mIccListener
= new IccListener();
333 mIccListener
->SetOwner(this);
335 // Probe for available client
339 BluetoothRilListener::~BluetoothRilListener()
341 mIccListener
->SetOwner(nullptr);
345 BluetoothRilListener::Listen(bool aStart
)
347 NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart
), false);
348 NS_ENSURE_TRUE(mTelephonyListener
->Listen(aStart
), false);
354 BluetoothRilListener::SelectClient()
357 mClientId
= mMobileConnListeners
.Length();
359 nsCOMPtr
<nsIMobileConnectionService
> service
=
360 do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID
);
361 NS_ENSURE_TRUE_VOID(service
);
363 for (uint32_t i
= 0; i
< mMobileConnListeners
.Length(); i
++) {
364 nsCOMPtr
<nsIMobileConnection
> connection
;
365 service
->GetItemByServiceId(i
, getter_AddRefs(connection
));
367 BT_WARNING("%s: Failed to get mobile connection", __FUNCTION__
);
371 nsCOMPtr
<nsIMobileConnectionInfo
> voiceInfo
;
372 connection
->GetVoice(getter_AddRefs(voiceInfo
));
374 BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__
);
379 voiceInfo
->GetState(regState
);
380 if (regState
.EqualsLiteral("registered")) {
381 // Found available client
389 BluetoothRilListener::ServiceChanged(uint32_t aClientId
, bool aRegistered
)
392 ListenMobileConnAndIccInfo(false);
396 * - TRUE: service becomes registered. We were listening to all clients
397 * and one of them becomes available. Select it to listen.
398 * - FALSE: service becomes un-registered. The client we were listening
399 * becomes unavailable. Select another registered one to listen.
402 mClientId
= aClientId
;
408 ListenMobileConnAndIccInfo(true);
410 BT_LOGR("%d client %d. new mClientId %d", aRegistered
, aClientId
,
411 (mClientId
< mMobileConnListeners
.Length()) ? mClientId
: -1);
415 BluetoothRilListener::EnumerateCalls()
417 nsCOMPtr
<nsITelephonyService
> service
=
418 do_GetService(TELEPHONY_SERVICE_CONTRACTID
);
419 NS_ENSURE_TRUE_VOID(service
);
421 nsCOMPtr
<nsITelephonyListener
> listener(
422 do_QueryObject(mTelephonyListener
));
424 service
->EnumerateCalls(listener
);
428 BluetoothRilListener::ListenMobileConnAndIccInfo(bool aStart
)
431 * mClientId < number of total clients:
432 * The client with mClientId is available. Start/Stop listening
433 * mobile connection and icc info of this client only.
435 * mClientId >= number of total clients:
436 * All clients are unavailable. Start/Stop listening mobile
437 * connections of all clients.
439 if (mClientId
< mMobileConnListeners
.Length()) {
440 NS_ENSURE_TRUE(mMobileConnListeners
[mClientId
]->Listen(aStart
), false);
441 NS_ENSURE_TRUE(mIccListener
->Listen(aStart
), false);
443 for (uint32_t i
= 0; i
< mMobileConnListeners
.Length(); i
++) {
444 NS_ENSURE_TRUE(mMobileConnListeners
[i
]->Listen(aStart
), false);