dom/bluetooth/BluetoothRilListener.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "BluetoothRilListener.h"
michael@0 8
michael@0 9 #include "BluetoothHfpManager.h"
michael@0 10 #include "nsIDOMMobileConnection.h"
michael@0 11 #include "nsIRadioInterfaceLayer.h"
michael@0 12 #include "nsRadioInterfaceLayer.h"
michael@0 13 #include "nsServiceManagerUtils.h"
michael@0 14 #include "nsString.h"
michael@0 15
michael@0 16 USING_BLUETOOTH_NAMESPACE
michael@0 17
michael@0 18 /**
michael@0 19 * IccListener
michael@0 20 */
michael@0 21 NS_IMPL_ISUPPORTS(IccListener, nsIIccListener)
michael@0 22
michael@0 23 NS_IMETHODIMP
michael@0 24 IccListener::NotifyIccInfoChanged()
michael@0 25 {
michael@0 26 // mOwner would be set to nullptr only in the dtor of BluetoothRilListener
michael@0 27 NS_ENSURE_TRUE(mOwner, NS_ERROR_FAILURE);
michael@0 28
michael@0 29 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 30 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
michael@0 31
michael@0 32 hfp->HandleIccInfoChanged(mOwner->mClientId);
michael@0 33
michael@0 34 return NS_OK;
michael@0 35 }
michael@0 36
michael@0 37 NS_IMETHODIMP
michael@0 38 IccListener::NotifyStkCommand(const nsAString & aMessage)
michael@0 39 {
michael@0 40 return NS_OK;
michael@0 41 }
michael@0 42
michael@0 43 NS_IMETHODIMP
michael@0 44 IccListener::NotifyStkSessionEnd()
michael@0 45 {
michael@0 46 return NS_OK;
michael@0 47 }
michael@0 48
michael@0 49 NS_IMETHODIMP
michael@0 50 IccListener::NotifyCardStateChanged()
michael@0 51 {
michael@0 52 return NS_OK;
michael@0 53 }
michael@0 54
michael@0 55 bool
michael@0 56 IccListener::Listen(bool aStart)
michael@0 57 {
michael@0 58 NS_ENSURE_TRUE(mOwner, false);
michael@0 59
michael@0 60 nsCOMPtr<nsIIccProvider> provider =
michael@0 61 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
michael@0 62 NS_ENSURE_TRUE(provider, false);
michael@0 63
michael@0 64 nsresult rv;
michael@0 65 if (aStart) {
michael@0 66 rv = provider->RegisterIccMsg(mOwner->mClientId, this);
michael@0 67 } else {
michael@0 68 rv = provider->UnregisterIccMsg(mOwner->mClientId, this);
michael@0 69 }
michael@0 70
michael@0 71 return NS_SUCCEEDED(rv);
michael@0 72 }
michael@0 73
michael@0 74 void
michael@0 75 IccListener::SetOwner(BluetoothRilListener *aOwner)
michael@0 76 {
michael@0 77 mOwner = aOwner;
michael@0 78 }
michael@0 79
michael@0 80 /**
michael@0 81 * MobileConnectionListener
michael@0 82 */
michael@0 83 NS_IMPL_ISUPPORTS(MobileConnectionListener, nsIMobileConnectionListener)
michael@0 84
michael@0 85 NS_IMETHODIMP
michael@0 86 MobileConnectionListener::NotifyVoiceChanged()
michael@0 87 {
michael@0 88 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 89 NS_ENSURE_TRUE(hfp, NS_OK);
michael@0 90
michael@0 91 hfp->HandleVoiceConnectionChanged(mClientId);
michael@0 92
michael@0 93 return NS_OK;
michael@0 94 }
michael@0 95
michael@0 96 NS_IMETHODIMP
michael@0 97 MobileConnectionListener::NotifyDataChanged()
michael@0 98 {
michael@0 99 return NS_OK;
michael@0 100 }
michael@0 101
michael@0 102 NS_IMETHODIMP
michael@0 103 MobileConnectionListener::NotifyUssdReceived(const nsAString & message,
michael@0 104 bool sessionEnded)
michael@0 105 {
michael@0 106 return NS_OK;
michael@0 107 }
michael@0 108
michael@0 109 NS_IMETHODIMP
michael@0 110 MobileConnectionListener::NotifyDataError(const nsAString & message)
michael@0 111 {
michael@0 112 return NS_OK;
michael@0 113 }
michael@0 114
michael@0 115 NS_IMETHODIMP
michael@0 116 MobileConnectionListener::NotifyCFStateChange(bool success,
michael@0 117 uint16_t action,
michael@0 118 uint16_t reason,
michael@0 119 const nsAString& number,
michael@0 120 uint16_t timeSeconds,
michael@0 121 uint16_t serviceClass)
michael@0 122 {
michael@0 123 return NS_OK;
michael@0 124 }
michael@0 125
michael@0 126 NS_IMETHODIMP
michael@0 127 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
michael@0 128 uint32_t timeoutMs)
michael@0 129 {
michael@0 130 return NS_OK;
michael@0 131 }
michael@0 132
michael@0 133 NS_IMETHODIMP
michael@0 134 MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
michael@0 135 {
michael@0 136 return NS_OK;
michael@0 137 }
michael@0 138
michael@0 139 NS_IMETHODIMP
michael@0 140 MobileConnectionListener::NotifyIccChanged()
michael@0 141 {
michael@0 142 return NS_OK;
michael@0 143 }
michael@0 144
michael@0 145 NS_IMETHODIMP
michael@0 146 MobileConnectionListener::NotifyRadioStateChanged()
michael@0 147 {
michael@0 148 return NS_OK;
michael@0 149 }
michael@0 150
michael@0 151 bool
michael@0 152 MobileConnectionListener::Listen(bool aStart)
michael@0 153 {
michael@0 154 nsCOMPtr<nsIMobileConnectionProvider> provider =
michael@0 155 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
michael@0 156 NS_ENSURE_TRUE(provider, false);
michael@0 157
michael@0 158 nsresult rv;
michael@0 159 if (aStart) {
michael@0 160 rv = provider->RegisterMobileConnectionMsg(mClientId, this);
michael@0 161 } else {
michael@0 162 rv = provider->UnregisterMobileConnectionMsg(mClientId, this);
michael@0 163 }
michael@0 164
michael@0 165 return NS_SUCCEEDED(rv);
michael@0 166 }
michael@0 167
michael@0 168 /**
michael@0 169 * TelephonyListener Implementation
michael@0 170 */
michael@0 171 NS_IMPL_ISUPPORTS(TelephonyListener, nsITelephonyListener)
michael@0 172
michael@0 173 NS_IMETHODIMP
michael@0 174 TelephonyListener::CallStateChanged(uint32_t aServiceId,
michael@0 175 uint32_t aCallIndex,
michael@0 176 uint16_t aCallState,
michael@0 177 const nsAString& aNumber,
michael@0 178 bool aIsActive,
michael@0 179 bool aIsOutgoing,
michael@0 180 bool aIsEmergency,
michael@0 181 bool aIsConference,
michael@0 182 bool aIsSwitchable,
michael@0 183 bool aIsMergeable)
michael@0 184 {
michael@0 185 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 186 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
michael@0 187
michael@0 188 hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
michael@0 189 aIsOutgoing, aIsConference, true);
michael@0 190 return NS_OK;
michael@0 191 }
michael@0 192
michael@0 193 NS_IMETHODIMP
michael@0 194 TelephonyListener::EnumerateCallState(uint32_t aServiceId,
michael@0 195 uint32_t aCallIndex,
michael@0 196 uint16_t aCallState,
michael@0 197 const nsAString_internal& aNumber,
michael@0 198 bool aIsActive,
michael@0 199 bool aIsOutgoing,
michael@0 200 bool aIsEmergency,
michael@0 201 bool aIsConference,
michael@0 202 bool aIsSwitchable,
michael@0 203 bool aIsMergeable)
michael@0 204 {
michael@0 205 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 206 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
michael@0 207
michael@0 208 hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
michael@0 209 aIsOutgoing, aIsConference, false);
michael@0 210 return NS_OK;
michael@0 211 }
michael@0 212
michael@0 213 NS_IMETHODIMP
michael@0 214 TelephonyListener::NotifyError(uint32_t aServiceId,
michael@0 215 int32_t aCallIndex,
michael@0 216 const nsAString& aError)
michael@0 217 {
michael@0 218 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 219 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
michael@0 220
michael@0 221 if (aCallIndex > 0) {
michael@0 222 // In order to not miss any related call state transition.
michael@0 223 // It's possible that 3G network signal lost for unknown reason.
michael@0 224 // If a call is released abnormally, NotifyError() will be called,
michael@0 225 // instead of CallStateChanged(). We need to reset the call array state
michael@0 226 // via setting CALL_STATE_DISCONNECTED
michael@0 227 hfp->HandleCallStateChanged(aCallIndex,
michael@0 228 nsITelephonyProvider::CALL_STATE_DISCONNECTED,
michael@0 229 aError, EmptyString(), false, false, true);
michael@0 230 BT_WARNING("Reset the call state due to call transition ends abnormally");
michael@0 231 }
michael@0 232
michael@0 233 BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
michael@0 234 return NS_OK;
michael@0 235 }
michael@0 236
michael@0 237 NS_IMETHODIMP
michael@0 238 TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
michael@0 239 {
michael@0 240 return NS_OK;
michael@0 241 }
michael@0 242
michael@0 243 NS_IMETHODIMP
michael@0 244 TelephonyListener::EnumerateCallStateComplete()
michael@0 245 {
michael@0 246 return NS_OK;
michael@0 247 }
michael@0 248
michael@0 249 NS_IMETHODIMP
michael@0 250 TelephonyListener::SupplementaryServiceNotification(uint32_t aServiceId,
michael@0 251 int32_t aCallIndex,
michael@0 252 uint16_t aNotification)
michael@0 253 {
michael@0 254 return NS_OK;
michael@0 255 }
michael@0 256
michael@0 257 NS_IMETHODIMP
michael@0 258 TelephonyListener::NotifyConferenceError(const nsAString& aName,
michael@0 259 const nsAString& aMessage)
michael@0 260 {
michael@0 261 BT_WARNING(NS_ConvertUTF16toUTF8(aName).get());
michael@0 262 BT_WARNING(NS_ConvertUTF16toUTF8(aMessage).get());
michael@0 263
michael@0 264 return NS_OK;
michael@0 265 }
michael@0 266
michael@0 267 NS_IMETHODIMP
michael@0 268 TelephonyListener::NotifyCdmaCallWaiting(uint32_t aServiceId,
michael@0 269 const nsAString& aNumber)
michael@0 270 {
michael@0 271 BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
michael@0 272 NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
michael@0 273
michael@0 274 hfp->UpdateSecondNumber(aNumber);
michael@0 275
michael@0 276 return NS_OK;
michael@0 277 }
michael@0 278
michael@0 279 bool
michael@0 280 TelephonyListener::Listen(bool aStart)
michael@0 281 {
michael@0 282 nsCOMPtr<nsITelephonyProvider> provider =
michael@0 283 do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
michael@0 284 NS_ENSURE_TRUE(provider, false);
michael@0 285
michael@0 286 nsresult rv;
michael@0 287 if (aStart) {
michael@0 288 rv = provider->RegisterListener(this);
michael@0 289 } else {
michael@0 290 rv = provider->UnregisterListener(this);
michael@0 291 }
michael@0 292
michael@0 293 return NS_SUCCEEDED(rv);
michael@0 294 }
michael@0 295
michael@0 296 /**
michael@0 297 * BluetoothRilListener
michael@0 298 */
michael@0 299 BluetoothRilListener::BluetoothRilListener()
michael@0 300 {
michael@0 301 // Query number of total clients (sim slots)
michael@0 302 uint32_t numOfClients;
michael@0 303 nsCOMPtr<nsIRadioInterfaceLayer> radioInterfaceLayer =
michael@0 304 do_GetService(NS_RADIOINTERFACELAYER_CONTRACTID);
michael@0 305 NS_ENSURE_TRUE_VOID(radioInterfaceLayer);
michael@0 306
michael@0 307 radioInterfaceLayer->GetNumRadioInterfaces(&numOfClients);
michael@0 308
michael@0 309 // Init MobileConnectionListener array and IccInfoListener
michael@0 310 for (uint32_t i = 0; i < numOfClients; i++) {
michael@0 311 mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
michael@0 312 }
michael@0 313
michael@0 314 mTelephonyListener = new TelephonyListener();
michael@0 315 mIccListener = new IccListener();
michael@0 316 mIccListener->SetOwner(this);
michael@0 317
michael@0 318 // Probe for available client
michael@0 319 SelectClient();
michael@0 320 }
michael@0 321
michael@0 322 BluetoothRilListener::~BluetoothRilListener()
michael@0 323 {
michael@0 324 mIccListener->SetOwner(nullptr);
michael@0 325 }
michael@0 326
michael@0 327 bool
michael@0 328 BluetoothRilListener::Listen(bool aStart)
michael@0 329 {
michael@0 330 NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart), false);
michael@0 331 NS_ENSURE_TRUE(mTelephonyListener->Listen(aStart), false);
michael@0 332
michael@0 333 return true;
michael@0 334 }
michael@0 335
michael@0 336 void
michael@0 337 BluetoothRilListener::SelectClient()
michael@0 338 {
michael@0 339 // Reset mClientId
michael@0 340 mClientId = mMobileConnListeners.Length();
michael@0 341
michael@0 342 nsCOMPtr<nsIMobileConnectionProvider> connection =
michael@0 343 do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
michael@0 344 NS_ENSURE_TRUE_VOID(connection);
michael@0 345
michael@0 346 for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
michael@0 347 nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo;
michael@0 348 connection->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
michael@0 349 if (!voiceInfo) {
michael@0 350 BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
michael@0 351 continue;
michael@0 352 }
michael@0 353
michael@0 354 nsString regState;
michael@0 355 voiceInfo->GetState(regState);
michael@0 356 if (regState.EqualsLiteral("registered")) {
michael@0 357 // Found available client
michael@0 358 mClientId = i;
michael@0 359 return;
michael@0 360 }
michael@0 361 }
michael@0 362 }
michael@0 363
michael@0 364 void
michael@0 365 BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
michael@0 366 {
michael@0 367 // Stop listening
michael@0 368 ListenMobileConnAndIccInfo(false);
michael@0 369
michael@0 370 /**
michael@0 371 * aRegistered:
michael@0 372 * - TRUE: service becomes registered. We were listening to all clients
michael@0 373 * and one of them becomes available. Select it to listen.
michael@0 374 * - FALSE: service becomes un-registered. The client we were listening
michael@0 375 * becomes unavailable. Select another registered one to listen.
michael@0 376 */
michael@0 377 if (aRegistered) {
michael@0 378 mClientId = aClientId;
michael@0 379 } else {
michael@0 380 SelectClient();
michael@0 381 }
michael@0 382
michael@0 383 // Restart listening
michael@0 384 ListenMobileConnAndIccInfo(true);
michael@0 385
michael@0 386 BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
michael@0 387 (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
michael@0 388 }
michael@0 389
michael@0 390 void
michael@0 391 BluetoothRilListener::EnumerateCalls()
michael@0 392 {
michael@0 393 nsCOMPtr<nsITelephonyProvider> provider =
michael@0 394 do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
michael@0 395 NS_ENSURE_TRUE_VOID(provider);
michael@0 396
michael@0 397 nsCOMPtr<nsITelephonyListener> listener(
michael@0 398 do_QueryObject(mTelephonyListener));
michael@0 399
michael@0 400 provider->EnumerateCalls(listener);
michael@0 401 }
michael@0 402
michael@0 403 bool
michael@0 404 BluetoothRilListener::ListenMobileConnAndIccInfo(bool aStart)
michael@0 405 {
michael@0 406 /**
michael@0 407 * mClientId < number of total clients:
michael@0 408 * The client with mClientId is available. Start/Stop listening
michael@0 409 * mobile connection and icc info of this client only.
michael@0 410 *
michael@0 411 * mClientId >= number of total clients:
michael@0 412 * All clients are unavailable. Start/Stop listening mobile
michael@0 413 * connections of all clients.
michael@0 414 */
michael@0 415 if (mClientId < mMobileConnListeners.Length()) {
michael@0 416 NS_ENSURE_TRUE(mMobileConnListeners[mClientId]->Listen(aStart), false);
michael@0 417 NS_ENSURE_TRUE(mIccListener->Listen(aStart), false);
michael@0 418 } else {
michael@0 419 for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
michael@0 420 NS_ENSURE_TRUE(mMobileConnListeners[i]->Listen(aStart), false);
michael@0 421 }
michael@0 422 }
michael@0 423
michael@0 424 return true;
michael@0 425 }

mercurial