Bumping manifests a=b2g-bump
[gecko.git] / dom / bluetooth / BluetoothRilListener.cpp
blob89428461861e521f3e99bfaab6ffa5fb8c7e164f
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 "nsIMobileConnectionInfo.h"
11 #include "nsIRadioInterfaceLayer.h"
12 #include "nsRadioInterfaceLayer.h"
13 #include "nsServiceManagerUtils.h"
14 #include "nsString.h"
16 USING_BLUETOOTH_NAMESPACE
18 /**
19 * IccListener
21 NS_IMPL_ISUPPORTS(IccListener, nsIIccListener)
23 NS_IMETHODIMP
24 IccListener::NotifyIccInfoChanged()
26 // mOwner would be set to nullptr only in the dtor of BluetoothRilListener
27 NS_ENSURE_TRUE(mOwner, NS_ERROR_FAILURE);
29 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
30 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
32 hfp->HandleIccInfoChanged(mOwner->mClientId);
34 return NS_OK;
37 NS_IMETHODIMP
38 IccListener::NotifyStkCommand(const nsAString & aMessage)
40 return NS_OK;
43 NS_IMETHODIMP
44 IccListener::NotifyStkSessionEnd()
46 return NS_OK;
49 NS_IMETHODIMP
50 IccListener::NotifyCardStateChanged()
52 return NS_OK;
55 bool
56 IccListener::Listen(bool aStart)
58 NS_ENSURE_TRUE(mOwner, false);
60 nsCOMPtr<nsIIccProvider> provider =
61 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
62 NS_ENSURE_TRUE(provider, false);
64 nsresult rv;
65 if (aStart) {
66 rv = provider->RegisterIccMsg(mOwner->mClientId, this);
67 } else {
68 rv = provider->UnregisterIccMsg(mOwner->mClientId, this);
71 return NS_SUCCEEDED(rv);
74 void
75 IccListener::SetOwner(BluetoothRilListener *aOwner)
77 mOwner = aOwner;
80 /**
81 * MobileConnectionListener
83 NS_IMPL_ISUPPORTS(MobileConnectionListener, nsIMobileConnectionListener)
85 NS_IMETHODIMP
86 MobileConnectionListener::NotifyVoiceChanged()
88 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
89 NS_ENSURE_TRUE(hfp, NS_OK);
91 hfp->HandleVoiceConnectionChanged(mClientId);
93 return NS_OK;
96 NS_IMETHODIMP
97 MobileConnectionListener::NotifyDataChanged()
99 return NS_OK;
102 NS_IMETHODIMP
103 MobileConnectionListener::NotifyUssdReceived(const nsAString & message,
104 bool sessionEnded)
106 return NS_OK;
109 NS_IMETHODIMP
110 MobileConnectionListener::NotifyDataError(const nsAString & message)
112 return NS_OK;
115 NS_IMETHODIMP
116 MobileConnectionListener::NotifyCFStateChange(bool success,
117 uint16_t action,
118 uint16_t reason,
119 const nsAString& number,
120 uint16_t timeSeconds,
121 uint16_t serviceClass)
123 return NS_OK;
126 NS_IMETHODIMP
127 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
128 uint32_t timeoutMs)
130 return NS_OK;
133 NS_IMETHODIMP
134 MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
136 return NS_OK;
139 NS_IMETHODIMP
140 MobileConnectionListener::NotifyIccChanged()
142 return NS_OK;
145 NS_IMETHODIMP
146 MobileConnectionListener::NotifyRadioStateChanged()
148 return NS_OK;
151 NS_IMETHODIMP
152 MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode)
154 return NS_OK;
157 bool
158 MobileConnectionListener::Listen(bool aStart)
160 nsCOMPtr<nsIMobileConnectionProvider> provider =
161 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
162 NS_ENSURE_TRUE(provider, false);
164 nsresult rv;
165 if (aStart) {
166 rv = provider->RegisterMobileConnectionMsg(mClientId, this);
167 } else {
168 rv = provider->UnregisterMobileConnectionMsg(mClientId, this);
171 return NS_SUCCEEDED(rv);
175 * TelephonyListener Implementation
177 NS_IMPL_ISUPPORTS(TelephonyListener, nsITelephonyListener)
179 NS_IMETHODIMP
180 TelephonyListener::CallStateChanged(uint32_t aServiceId,
181 uint32_t aCallIndex,
182 uint16_t aCallState,
183 const nsAString& aNumber,
184 uint16_t aNumberPresentation,
185 const nsAString& aName,
186 uint16_t aNamePresentation,
187 bool aIsOutgoing,
188 bool aIsEmergency,
189 bool aIsConference,
190 bool aIsSwitchable,
191 bool aIsMergeable)
193 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
194 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
196 hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
197 aIsOutgoing, aIsConference, true);
198 return NS_OK;
201 NS_IMETHODIMP
202 TelephonyListener::EnumerateCallState(uint32_t aServiceId,
203 uint32_t aCallIndex,
204 uint16_t aCallState,
205 const nsAString_internal& aNumber,
206 uint16_t aNumberPresentation,
207 const nsAString& aName,
208 uint16_t aNamePresentation,
209 bool aIsOutgoing,
210 bool aIsEmergency,
211 bool aIsConference,
212 bool aIsSwitchable,
213 bool aIsMergeable)
215 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
216 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
218 hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
219 aIsOutgoing, aIsConference, false);
220 return NS_OK;
223 NS_IMETHODIMP
224 TelephonyListener::NotifyError(uint32_t aServiceId,
225 int32_t aCallIndex,
226 const nsAString& aError)
228 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
229 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
231 if (aCallIndex > 0) {
232 // In order to not miss any related call state transition.
233 // It's possible that 3G network signal lost for unknown reason.
234 // If a call is released abnormally, NotifyError() will be called,
235 // instead of CallStateChanged(). We need to reset the call array state
236 // via setting CALL_STATE_DISCONNECTED
237 hfp->HandleCallStateChanged(aCallIndex,
238 nsITelephonyService::CALL_STATE_DISCONNECTED,
239 aError, EmptyString(), false, false, true);
240 BT_WARNING("Reset the call state due to call transition ends abnormally");
243 BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
244 return NS_OK;
247 NS_IMETHODIMP
248 TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
250 return NS_OK;
253 NS_IMETHODIMP
254 TelephonyListener::EnumerateCallStateComplete()
256 return NS_OK;
259 NS_IMETHODIMP
260 TelephonyListener::SupplementaryServiceNotification(uint32_t aServiceId,
261 int32_t aCallIndex,
262 uint16_t aNotification)
264 return NS_OK;
267 NS_IMETHODIMP
268 TelephonyListener::NotifyConferenceError(const nsAString& aName,
269 const nsAString& aMessage)
271 BT_WARNING(NS_ConvertUTF16toUTF8(aName).get());
272 BT_WARNING(NS_ConvertUTF16toUTF8(aMessage).get());
274 return NS_OK;
277 NS_IMETHODIMP
278 TelephonyListener::NotifyCdmaCallWaiting(uint32_t aServiceId,
279 const nsAString& aNumber,
280 uint16_t aNumberPresentation,
281 const nsAString& aName,
282 uint16_t aNamePresentation)
284 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
285 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
287 hfp->UpdateSecondNumber(aNumber);
289 return NS_OK;
292 bool
293 TelephonyListener::Listen(bool aStart)
295 nsCOMPtr<nsITelephonyService> service =
296 do_GetService(TELEPHONY_SERVICE_CONTRACTID);
297 NS_ENSURE_TRUE(service, false);
299 nsresult rv;
300 if (aStart) {
301 rv = service->RegisterListener(this);
302 } else {
303 rv = service->UnregisterListener(this);
306 return NS_SUCCEEDED(rv);
310 * BluetoothRilListener
312 BluetoothRilListener::BluetoothRilListener()
314 // Query number of total clients (sim slots)
315 uint32_t numOfClients;
316 nsCOMPtr<nsIRadioInterfaceLayer> radioInterfaceLayer =
317 do_GetService(NS_RADIOINTERFACELAYER_CONTRACTID);
318 NS_ENSURE_TRUE_VOID(radioInterfaceLayer);
320 radioInterfaceLayer->GetNumRadioInterfaces(&numOfClients);
322 // Init MobileConnectionListener array and IccInfoListener
323 for (uint32_t i = 0; i < numOfClients; i++) {
324 mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
327 mTelephonyListener = new TelephonyListener();
328 mIccListener = new IccListener();
329 mIccListener->SetOwner(this);
331 // Probe for available client
332 SelectClient();
335 BluetoothRilListener::~BluetoothRilListener()
337 mIccListener->SetOwner(nullptr);
340 bool
341 BluetoothRilListener::Listen(bool aStart)
343 NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart), false);
344 NS_ENSURE_TRUE(mTelephonyListener->Listen(aStart), false);
346 return true;
349 void
350 BluetoothRilListener::SelectClient()
352 // Reset mClientId
353 mClientId = mMobileConnListeners.Length();
355 nsCOMPtr<nsIMobileConnectionProvider> connection =
356 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
357 NS_ENSURE_TRUE_VOID(connection);
359 for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
360 nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
361 connection->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
362 if (!voiceInfo) {
363 BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
364 continue;
367 nsString regState;
368 voiceInfo->GetState(regState);
369 if (regState.EqualsLiteral("registered")) {
370 // Found available client
371 mClientId = i;
372 return;
377 void
378 BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
380 // Stop listening
381 ListenMobileConnAndIccInfo(false);
384 * aRegistered:
385 * - TRUE: service becomes registered. We were listening to all clients
386 * and one of them becomes available. Select it to listen.
387 * - FALSE: service becomes un-registered. The client we were listening
388 * becomes unavailable. Select another registered one to listen.
390 if (aRegistered) {
391 mClientId = aClientId;
392 } else {
393 SelectClient();
396 // Restart listening
397 ListenMobileConnAndIccInfo(true);
399 BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
400 (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
403 void
404 BluetoothRilListener::EnumerateCalls()
406 nsCOMPtr<nsITelephonyService> service =
407 do_GetService(TELEPHONY_SERVICE_CONTRACTID);
408 NS_ENSURE_TRUE_VOID(service);
410 nsCOMPtr<nsITelephonyListener> listener(
411 do_QueryObject(mTelephonyListener));
413 service->EnumerateCalls(listener);
416 bool
417 BluetoothRilListener::ListenMobileConnAndIccInfo(bool aStart)
420 * mClientId < number of total clients:
421 * The client with mClientId is available. Start/Stop listening
422 * mobile connection and icc info of this client only.
424 * mClientId >= number of total clients:
425 * All clients are unavailable. Start/Stop listening mobile
426 * connections of all clients.
428 if (mClientId < mMobileConnListeners.Length()) {
429 NS_ENSURE_TRUE(mMobileConnListeners[mClientId]->Listen(aStart), false);
430 NS_ENSURE_TRUE(mIccListener->Listen(aStart), false);
431 } else {
432 for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
433 NS_ENSURE_TRUE(mMobileConnListeners[i]->Listen(aStart), false);
437 return true;