Bumping manifests a=b2g-bump
[gecko.git] / dom / bluetooth2 / BluetoothRilListener.cpp
blobf6237480ecfefb1f880d20d96b9011d78a7e21e4
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"
16 #include "nsString.h"
18 USING_BLUETOOTH_NAMESPACE
20 /**
21 * IccListener
23 NS_IMPL_ISUPPORTS(IccListener, nsIIccListener)
25 NS_IMETHODIMP
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);
36 return NS_OK;
39 NS_IMETHODIMP
40 IccListener::NotifyStkCommand(const nsAString & aMessage)
42 return NS_OK;
45 NS_IMETHODIMP
46 IccListener::NotifyStkSessionEnd()
48 return NS_OK;
51 NS_IMETHODIMP
52 IccListener::NotifyCardStateChanged()
54 return NS_OK;
57 bool
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);
66 nsresult rv;
67 if (aStart) {
68 rv = provider->RegisterIccMsg(mOwner->mClientId, this);
69 } else {
70 rv = provider->UnregisterIccMsg(mOwner->mClientId, this);
73 return NS_SUCCEEDED(rv);
76 void
77 IccListener::SetOwner(BluetoothRilListener *aOwner)
79 mOwner = aOwner;
82 /**
83 * MobileConnectionListener
85 NS_IMPL_ISUPPORTS(MobileConnectionListener, nsIMobileConnectionListener)
87 NS_IMETHODIMP
88 MobileConnectionListener::NotifyVoiceChanged()
90 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
91 NS_ENSURE_TRUE(hfp, NS_OK);
93 hfp->HandleVoiceConnectionChanged(mClientId);
95 return NS_OK;
98 NS_IMETHODIMP
99 MobileConnectionListener::NotifyDataChanged()
101 return NS_OK;
104 NS_IMETHODIMP
105 MobileConnectionListener::NotifyDataError(const nsAString & message)
107 return NS_OK;
110 NS_IMETHODIMP
111 MobileConnectionListener::NotifyCFStateChanged(uint16_t action,
112 uint16_t reason,
113 const nsAString& number,
114 uint16_t timeSeconds,
115 uint16_t serviceClass)
117 return NS_OK;
120 NS_IMETHODIMP
121 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
122 uint32_t timeoutMs)
124 return NS_OK;
127 NS_IMETHODIMP
128 MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
130 return NS_OK;
133 NS_IMETHODIMP
134 MobileConnectionListener::NotifyRadioStateChanged()
136 return NS_OK;
139 NS_IMETHODIMP
140 MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode)
142 return NS_OK;
145 NS_IMETHODIMP
146 MobileConnectionListener::NotifyLastKnownNetworkChanged()
148 return NS_OK;
151 NS_IMETHODIMP
152 MobileConnectionListener::NotifyLastKnownHomeNetworkChanged()
154 return NS_OK;
157 NS_IMETHODIMP
158 MobileConnectionListener::NotifyNetworkSelectionModeChanged()
160 return NS_OK;
163 bool
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);
174 nsresult rv;
175 if (aStart) {
176 rv = connection->RegisterListener(this);
177 } else {
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
192 nsresult
193 TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend)
195 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
196 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
198 uint32_t callIndex;
199 uint16_t callState;
200 nsAutoString number;
201 bool isOutgoing;
202 bool isConference;
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);
212 return NS_OK;
215 NS_IMETHODIMP
216 TelephonyListener::CallStateChanged(nsITelephonyCallInfo* aInfo)
218 return HandleCallInfo(aInfo, true);
221 NS_IMETHODIMP
222 TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo)
224 return HandleCallInfo(aInfo, false);
227 NS_IMETHODIMP
228 TelephonyListener::NotifyError(uint32_t aServiceId,
229 int32_t aCallIndex,
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());
248 return NS_OK;
251 NS_IMETHODIMP
252 TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
254 return NS_OK;
257 NS_IMETHODIMP
258 TelephonyListener::EnumerateCallStateComplete()
260 return NS_OK;
263 NS_IMETHODIMP
264 TelephonyListener::SupplementaryServiceNotification(uint32_t aServiceId,
265 int32_t aCallIndex,
266 uint16_t aNotification)
268 return NS_OK;
271 NS_IMETHODIMP
272 TelephonyListener::NotifyConferenceError(const nsAString& aName,
273 const nsAString& aMessage)
275 BT_WARNING(NS_ConvertUTF16toUTF8(aName).get());
276 BT_WARNING(NS_ConvertUTF16toUTF8(aMessage).get());
278 return NS_OK;
281 NS_IMETHODIMP
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);
293 return NS_OK;
296 bool
297 TelephonyListener::Listen(bool aStart)
299 nsCOMPtr<nsITelephonyService> service =
300 do_GetService(TELEPHONY_SERVICE_CONTRACTID);
301 NS_ENSURE_TRUE(service, false);
303 nsresult rv;
304 if (aStart) {
305 rv = service->RegisterListener(this);
306 } else {
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
336 SelectClient();
339 BluetoothRilListener::~BluetoothRilListener()
341 mIccListener->SetOwner(nullptr);
344 bool
345 BluetoothRilListener::Listen(bool aStart)
347 NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart), false);
348 NS_ENSURE_TRUE(mTelephonyListener->Listen(aStart), false);
350 return true;
353 void
354 BluetoothRilListener::SelectClient()
356 // Reset mClientId
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));
366 if (!connection) {
367 BT_WARNING("%s: Failed to get mobile connection", __FUNCTION__);
368 continue;
371 nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
372 connection->GetVoice(getter_AddRefs(voiceInfo));
373 if (!voiceInfo) {
374 BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
375 continue;
378 nsString regState;
379 voiceInfo->GetState(regState);
380 if (regState.EqualsLiteral("registered")) {
381 // Found available client
382 mClientId = i;
383 return;
388 void
389 BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
391 // Stop listening
392 ListenMobileConnAndIccInfo(false);
395 * aRegistered:
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.
401 if (aRegistered) {
402 mClientId = aClientId;
403 } else {
404 SelectClient();
407 // Restart listening
408 ListenMobileConnAndIccInfo(true);
410 BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
411 (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
414 void
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);
427 bool
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);
442 } else {
443 for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
444 NS_ENSURE_TRUE(mMobileConnListeners[i]->Listen(aStart), false);
448 return true;