1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import android.annotation.UnsupportedAppUsage; 20 import android.content.Context; 21 import android.os.AsyncResult; 22 import android.os.Handler; 23 import android.os.Message; 24 import android.os.Registrant; 25 import android.os.RegistrantList; 26 import android.telephony.PhoneNumberUtils; 27 import android.telephony.PhoneStateListener; 28 import android.telephony.Rlog; 29 import android.telephony.ServiceState; 30 import android.telephony.TelephonyManager; 31 32 import com.android.internal.telephony.sip.SipPhone; 33 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import java.util.HashMap; 37 import java.util.List; 38 39 40 41 /** 42 * @hide 43 * 44 * CallManager class provides an abstract layer for PhoneApp to access 45 * and control calls. It implements Phone interface. 46 * 47 * CallManager provides call and connection control as well as 48 * channel capability. 49 * 50 * There are three categories of APIs CallManager provided 51 * 52 * 1. Call control and operation, such as dial() and hangup() 53 * 2. Channel capabilities, such as CanConference() 54 * 3. Register notification 55 * 56 * 57 */ 58 public class CallManager { 59 60 private static final String LOG_TAG ="CallManager"; 61 private static final boolean DBG = true; 62 private static final boolean VDBG = false; 63 64 private static final int EVENT_DISCONNECT = 100; 65 private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101; 66 private static final int EVENT_NEW_RINGING_CONNECTION = 102; 67 private static final int EVENT_UNKNOWN_CONNECTION = 103; 68 private static final int EVENT_INCOMING_RING = 104; 69 private static final int EVENT_RINGBACK_TONE = 105; 70 private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106; 71 private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107; 72 private static final int EVENT_CALL_WAITING = 108; 73 private static final int EVENT_DISPLAY_INFO = 109; 74 private static final int EVENT_SIGNAL_INFO = 110; 75 private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111; 76 private static final int EVENT_RESEND_INCALL_MUTE = 112; 77 private static final int EVENT_MMI_INITIATE = 113; 78 private static final int EVENT_MMI_COMPLETE = 114; 79 private static final int EVENT_ECM_TIMER_RESET = 115; 80 private static final int EVENT_SUBSCRIPTION_INFO_READY = 116; 81 private static final int EVENT_SUPP_SERVICE_FAILED = 117; 82 private static final int EVENT_SERVICE_STATE_CHANGED = 118; 83 private static final int EVENT_POST_DIAL_CHARACTER = 119; 84 private static final int EVENT_ONHOLD_TONE = 120; 85 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 86 //private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 121; 87 private static final int EVENT_TTY_MODE_RECEIVED = 122; 88 89 // Singleton instance 90 private static final CallManager INSTANCE = new CallManager(); 91 92 // list of registered phones, which are Phone objs 93 @UnsupportedAppUsage 94 private final ArrayList<Phone> mPhones; 95 96 // list of supported ringing calls 97 @UnsupportedAppUsage 98 private final ArrayList<Call> mRingingCalls; 99 100 // list of supported background calls 101 @UnsupportedAppUsage 102 private final ArrayList<Call> mBackgroundCalls; 103 104 // list of supported foreground calls 105 @UnsupportedAppUsage 106 private final ArrayList<Call> mForegroundCalls; 107 108 // empty connection list 109 @UnsupportedAppUsage 110 private final ArrayList<Connection> mEmptyConnections = new ArrayList<Connection>(); 111 112 // mapping of phones to registered handler instances used for callbacks from RIL 113 private final HashMap<Phone, CallManagerHandler> mHandlerMap = new HashMap<>(); 114 115 // default phone as the first phone registered, which is Phone obj 116 private Phone mDefaultPhone; 117 118 private boolean mSpeedUpAudioForMtCall = false; 119 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 120 //private boolean mIsEccDialing = false; 121 122 private Object mRegistrantidentifier = new Object(); 123 124 // state registrants 125 protected final RegistrantList mPreciseCallStateRegistrants 126 = new RegistrantList(); 127 128 protected final RegistrantList mNewRingingConnectionRegistrants 129 = new RegistrantList(); 130 131 protected final RegistrantList mIncomingRingRegistrants 132 = new RegistrantList(); 133 134 protected final RegistrantList mDisconnectRegistrants 135 = new RegistrantList(); 136 137 protected final RegistrantList mMmiRegistrants 138 = new RegistrantList(); 139 140 protected final RegistrantList mUnknownConnectionRegistrants 141 = new RegistrantList(); 142 143 protected final RegistrantList mRingbackToneRegistrants 144 = new RegistrantList(); 145 146 protected final RegistrantList mOnHoldToneRegistrants 147 = new RegistrantList(); 148 149 protected final RegistrantList mInCallVoicePrivacyOnRegistrants 150 = new RegistrantList(); 151 152 protected final RegistrantList mInCallVoicePrivacyOffRegistrants 153 = new RegistrantList(); 154 155 protected final RegistrantList mCallWaitingRegistrants 156 = new RegistrantList(); 157 158 protected final RegistrantList mDisplayInfoRegistrants 159 = new RegistrantList(); 160 161 protected final RegistrantList mSignalInfoRegistrants 162 = new RegistrantList(); 163 164 protected final RegistrantList mCdmaOtaStatusChangeRegistrants 165 = new RegistrantList(); 166 167 protected final RegistrantList mResendIncallMuteRegistrants 168 = new RegistrantList(); 169 170 protected final RegistrantList mMmiInitiateRegistrants 171 = new RegistrantList(); 172 173 protected final RegistrantList mMmiCompleteRegistrants 174 = new RegistrantList(); 175 176 protected final RegistrantList mEcmTimerResetRegistrants 177 = new RegistrantList(); 178 179 protected final RegistrantList mSubscriptionInfoReadyRegistrants 180 = new RegistrantList(); 181 182 protected final RegistrantList mSuppServiceFailedRegistrants 183 = new RegistrantList(); 184 185 protected final RegistrantList mServiceStateChangedRegistrants 186 = new RegistrantList(); 187 188 protected final RegistrantList mPostDialCharacterRegistrants 189 = new RegistrantList(); 190 191 protected final RegistrantList mTtyModeReceivedRegistrants 192 = new RegistrantList(); 193 CallManager()194 private CallManager() { 195 mPhones = new ArrayList<Phone>(); 196 mRingingCalls = new ArrayList<Call>(); 197 mBackgroundCalls = new ArrayList<Call>(); 198 mForegroundCalls = new ArrayList<Call>(); 199 mDefaultPhone = null; 200 } 201 202 /** 203 * get singleton instance of CallManager 204 * @return CallManager 205 */ 206 @UnsupportedAppUsage getInstance()207 public static CallManager getInstance() { 208 return INSTANCE; 209 } 210 211 /** 212 * get Phone object corresponds to subId 213 * @return Phone 214 */ getPhone(int subId)215 private Phone getPhone(int subId) { 216 Phone p = null; 217 for (Phone phone : mPhones) { 218 if (phone.getSubId() == subId && 219 phone.getPhoneType() != PhoneConstants.PHONE_TYPE_IMS) { 220 p = phone; 221 break; 222 } 223 } 224 return p; 225 } 226 227 /** 228 * Get current coarse-grained voice call state. 229 * If the Call Manager has an active call and call waiting occurs, 230 * then the phone state is RINGING not OFFHOOK 231 * 232 */ 233 @UnsupportedAppUsage getState()234 public PhoneConstants.State getState() { 235 PhoneConstants.State s = PhoneConstants.State.IDLE; 236 237 for (Phone phone : mPhones) { 238 if (phone.getState() == PhoneConstants.State.RINGING) { 239 s = PhoneConstants.State.RINGING; 240 } else if (phone.getState() == PhoneConstants.State.OFFHOOK) { 241 if (s == PhoneConstants.State.IDLE) s = PhoneConstants.State.OFFHOOK; 242 } 243 } 244 return s; 245 } 246 247 /** 248 * Get current coarse-grained voice call state on a subId. 249 * If the Call Manager has an active call and call waiting occurs, 250 * then the phone state is RINGING not OFFHOOK 251 * 252 */ 253 @UnsupportedAppUsage getState(int subId)254 public PhoneConstants.State getState(int subId) { 255 PhoneConstants.State s = PhoneConstants.State.IDLE; 256 257 for (Phone phone : mPhones) { 258 if (phone.getSubId() == subId) { 259 if (phone.getState() == PhoneConstants.State.RINGING) { 260 s = PhoneConstants.State.RINGING; 261 } else if (phone.getState() == PhoneConstants.State.OFFHOOK) { 262 if (s == PhoneConstants.State.IDLE) s = PhoneConstants.State.OFFHOOK; 263 } 264 } 265 } 266 return s; 267 } 268 269 /** 270 * @return the service state of CallManager, which represents the 271 * highest priority state of all the service states of phones 272 * 273 * The priority is defined as 274 * 275 * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF 276 * 277 */ 278 getServiceState()279 public int getServiceState() { 280 int resultState = ServiceState.STATE_OUT_OF_SERVICE; 281 282 for (Phone phone : mPhones) { 283 int serviceState = phone.getServiceState().getState(); 284 if (serviceState == ServiceState.STATE_IN_SERVICE) { 285 // IN_SERVICE has the highest priority 286 resultState = serviceState; 287 break; 288 } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { 289 // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF 290 // Note: EMERGENCY_ONLY is not in use at this moment 291 if ( resultState == ServiceState.STATE_EMERGENCY_ONLY || 292 resultState == ServiceState.STATE_POWER_OFF) { 293 resultState = serviceState; 294 } 295 } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) { 296 if (resultState == ServiceState.STATE_POWER_OFF) { 297 resultState = serviceState; 298 } 299 } 300 } 301 return resultState; 302 } 303 304 /** 305 * @return the Phone service state corresponds to subId 306 */ getServiceState(int subId)307 public int getServiceState(int subId) { 308 int resultState = ServiceState.STATE_OUT_OF_SERVICE; 309 310 for (Phone phone : mPhones) { 311 if (phone.getSubId() == subId) { 312 int serviceState = phone.getServiceState().getState(); 313 if (serviceState == ServiceState.STATE_IN_SERVICE) { 314 // IN_SERVICE has the highest priority 315 resultState = serviceState; 316 break; 317 } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { 318 // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF 319 // Note: EMERGENCY_ONLY is not in use at this moment 320 if ( resultState == ServiceState.STATE_EMERGENCY_ONLY || 321 resultState == ServiceState.STATE_POWER_OFF) { 322 resultState = serviceState; 323 } 324 } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) { 325 if (resultState == ServiceState.STATE_POWER_OFF) { 326 resultState = serviceState; 327 } 328 } 329 } 330 } 331 return resultState; 332 } 333 334 /** 335 * @return the phone associated with any call 336 */ 337 @UnsupportedAppUsage getPhoneInCall()338 public Phone getPhoneInCall() { 339 Phone phone = null; 340 if (!getFirstActiveRingingCall().isIdle()) { 341 phone = getFirstActiveRingingCall().getPhone(); 342 } else if (!getActiveFgCall().isIdle()) { 343 phone = getActiveFgCall().getPhone(); 344 } else { 345 // If BG call is idle, we return default phone 346 phone = getFirstActiveBgCall().getPhone(); 347 } 348 return phone; 349 } 350 351 /** 352 * Register phone to CallManager 353 * @param phone to be registered 354 * @return true if register successfully 355 */ 356 @UnsupportedAppUsage registerPhone(Phone phone)357 public boolean registerPhone(Phone phone) { 358 if (phone != null && !mPhones.contains(phone)) { 359 360 if (DBG) { 361 Rlog.d(LOG_TAG, "registerPhone(" + 362 phone.getPhoneName() + " " + phone + ")"); 363 } 364 365 if (mPhones.isEmpty()) { 366 mDefaultPhone = phone; 367 } 368 mPhones.add(phone); 369 mRingingCalls.add(phone.getRingingCall()); 370 mBackgroundCalls.add(phone.getBackgroundCall()); 371 mForegroundCalls.add(phone.getForegroundCall()); 372 registerForPhoneStates(phone); 373 return true; 374 } 375 return false; 376 } 377 378 /** 379 * unregister phone from CallManager 380 * @param phone to be unregistered 381 */ 382 @UnsupportedAppUsage unregisterPhone(Phone phone)383 public void unregisterPhone(Phone phone) { 384 if (phone != null && mPhones.contains(phone)) { 385 386 if (DBG) { 387 Rlog.d(LOG_TAG, "unregisterPhone(" + 388 phone.getPhoneName() + " " + phone + ")"); 389 } 390 391 Phone imsPhone = phone.getImsPhone(); 392 if (imsPhone != null) { 393 unregisterPhone(imsPhone); 394 } 395 396 mPhones.remove(phone); 397 mRingingCalls.remove(phone.getRingingCall()); 398 mBackgroundCalls.remove(phone.getBackgroundCall()); 399 mForegroundCalls.remove(phone.getForegroundCall()); 400 unregisterForPhoneStates(phone); 401 if (phone == mDefaultPhone) { 402 if (mPhones.isEmpty()) { 403 mDefaultPhone = null; 404 } else { 405 mDefaultPhone = mPhones.get(0); 406 } 407 } 408 } 409 } 410 411 /** 412 * return the default phone or null if no phone available 413 */ 414 @UnsupportedAppUsage getDefaultPhone()415 public Phone getDefaultPhone() { 416 return mDefaultPhone; 417 } 418 419 /** 420 * @return the phone associated with the foreground call 421 */ 422 @UnsupportedAppUsage getFgPhone()423 public Phone getFgPhone() { 424 return getActiveFgCall().getPhone(); 425 } 426 427 /** 428 * @return the phone associated with the foreground call 429 * of a particular subId 430 */ 431 @UnsupportedAppUsage getFgPhone(int subId)432 public Phone getFgPhone(int subId) { 433 return getActiveFgCall(subId).getPhone(); 434 } 435 436 /** 437 * @return the phone associated with the background call 438 */ 439 @UnsupportedAppUsage getBgPhone()440 public Phone getBgPhone() { 441 return getFirstActiveBgCall().getPhone(); 442 } 443 444 /** 445 * @return the phone associated with the ringing call 446 */ 447 @UnsupportedAppUsage getRingingPhone()448 public Phone getRingingPhone() { 449 return getFirstActiveRingingCall().getPhone(); 450 } 451 452 /** 453 * @return the phone associated with the ringing call 454 * of a particular subId 455 */ getRingingPhone(int subId)456 public Phone getRingingPhone(int subId) { 457 return getFirstActiveRingingCall(subId).getPhone(); 458 } 459 460 /* FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 461 public void setAudioMode() { 462 Context context = getContext(); 463 if (context == null) return; 464 AudioManager audioManager = (AudioManager) 465 context.getSystemService(Context.AUDIO_SERVICE); 466 467 if (!isServiceStateInService() && !mIsEccDialing) { 468 if (audioManager.getMode() != AudioManager.MODE_NORMAL) { 469 if (VDBG) Rlog.d(LOG_TAG, "abandonAudioFocus"); 470 // abandon audio focus after the mode has been set back to normal 471 audioManager.abandonAudioFocusForCall(); 472 audioManager.setMode(AudioManager.MODE_NORMAL); 473 } 474 return; 475 } 476 477 // change the audio mode and request/abandon audio focus according to phone state, 478 // but only on audio mode transitions 479 switch (getState()) { 480 case RINGING: 481 int curAudioMode = audioManager.getMode(); 482 if (curAudioMode != AudioManager.MODE_RINGTONE) { 483 if (VDBG) Rlog.d(LOG_TAG, "requestAudioFocus on STREAM_RING"); 484 audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, 485 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 486 if(!mSpeedUpAudioForMtCall) { 487 audioManager.setMode(AudioManager.MODE_RINGTONE); 488 } 489 } 490 491 if (mSpeedUpAudioForMtCall && (curAudioMode != AudioManager.MODE_IN_CALL)) { 492 audioManager.setMode(AudioManager.MODE_IN_CALL); 493 } 494 break; 495 case OFFHOOK: 496 Phone offhookPhone = getFgPhone(); 497 if (getActiveFgCallState() == Call.State.IDLE) { 498 // There is no active Fg calls, the OFFHOOK state 499 // is set by the Bg call. So set the phone to bgPhone. 500 offhookPhone = getBgPhone(); 501 } 502 503 int newAudioMode = AudioManager.MODE_IN_CALL; 504 if (offhookPhone instanceof SipPhone) { 505 Rlog.d(LOG_TAG, "setAudioMode Set audio mode for SIP call!"); 506 // enable IN_COMMUNICATION audio mode instead for sipPhone 507 newAudioMode = AudioManager.MODE_IN_COMMUNICATION; 508 } 509 int currMode = audioManager.getMode(); 510 if (currMode != newAudioMode || mSpeedUpAudioForMtCall) { 511 // request audio focus before setting the new mode 512 if (VDBG) Rlog.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL"); 513 audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, 514 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 515 Rlog.d(LOG_TAG, "setAudioMode Setting audio mode from " 516 + currMode + " to " + newAudioMode); 517 audioManager.setMode(newAudioMode); 518 } 519 mSpeedUpAudioForMtCall = false; 520 break; 521 case IDLE: 522 if (audioManager.getMode() != AudioManager.MODE_NORMAL) { 523 audioManager.setMode(AudioManager.MODE_NORMAL); 524 if (VDBG) Rlog.d(LOG_TAG, "abandonAudioFocus"); 525 // abandon audio focus after the mode has been set back to normal 526 audioManager.abandonAudioFocusForCall(); 527 } 528 mSpeedUpAudioForMtCall = false; 529 break; 530 } 531 Rlog.d(LOG_TAG, "setAudioMode state = " + getState()); 532 } 533 */ 534 535 @UnsupportedAppUsage getContext()536 private Context getContext() { 537 Phone defaultPhone = getDefaultPhone(); 538 return ((defaultPhone == null) ? null : defaultPhone.getContext()); 539 } 540 getRegistrantIdentifier()541 public Object getRegistrantIdentifier() { 542 return mRegistrantidentifier; 543 } 544 registerForPhoneStates(Phone phone)545 private void registerForPhoneStates(Phone phone) { 546 // We need to keep a mapping of handler to Phone for proper unregistration. 547 // TODO: Clean up this solution as it is just a work around for each Phone instance 548 // using the same Handler to register with the RIL. When time permits, we should consider 549 // moving the handler (or the reference ot the handler) into the Phone object. 550 // See b/17414427. 551 CallManagerHandler handler = mHandlerMap.get(phone); 552 if (handler != null) { 553 Rlog.d(LOG_TAG, "This phone has already been registered."); 554 return; 555 } 556 557 // New registration, create a new handler instance and register the phone. 558 handler = new CallManagerHandler(); 559 mHandlerMap.put(phone, handler); 560 561 // for common events supported by all phones 562 // The mRegistrantIdentifier passed here, is to identify in the Phone 563 // that the registrants are coming from the CallManager. 564 phone.registerForPreciseCallStateChanged(handler, EVENT_PRECISE_CALL_STATE_CHANGED, 565 mRegistrantidentifier); 566 phone.registerForDisconnect(handler, EVENT_DISCONNECT, 567 mRegistrantidentifier); 568 phone.registerForNewRingingConnection(handler, EVENT_NEW_RINGING_CONNECTION, 569 mRegistrantidentifier); 570 phone.registerForUnknownConnection(handler, EVENT_UNKNOWN_CONNECTION, 571 mRegistrantidentifier); 572 phone.registerForIncomingRing(handler, EVENT_INCOMING_RING, 573 mRegistrantidentifier); 574 phone.registerForRingbackTone(handler, EVENT_RINGBACK_TONE, 575 mRegistrantidentifier); 576 phone.registerForInCallVoicePrivacyOn(handler, EVENT_IN_CALL_VOICE_PRIVACY_ON, 577 mRegistrantidentifier); 578 phone.registerForInCallVoicePrivacyOff(handler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, 579 mRegistrantidentifier); 580 phone.registerForDisplayInfo(handler, EVENT_DISPLAY_INFO, 581 mRegistrantidentifier); 582 phone.registerForSignalInfo(handler, EVENT_SIGNAL_INFO, 583 mRegistrantidentifier); 584 phone.registerForResendIncallMute(handler, EVENT_RESEND_INCALL_MUTE, 585 mRegistrantidentifier); 586 phone.registerForMmiInitiate(handler, EVENT_MMI_INITIATE, 587 mRegistrantidentifier); 588 phone.registerForMmiComplete(handler, EVENT_MMI_COMPLETE, 589 mRegistrantidentifier); 590 phone.registerForSuppServiceFailed(handler, EVENT_SUPP_SERVICE_FAILED, 591 mRegistrantidentifier); 592 phone.registerForServiceStateChanged(handler, EVENT_SERVICE_STATE_CHANGED, 593 mRegistrantidentifier); 594 595 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 596 //phone.registerForRadioOffOrNotAvailable(handler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); 597 598 // for events supported only by GSM, CDMA and IMS phone 599 phone.setOnPostDialCharacter(handler, EVENT_POST_DIAL_CHARACTER, null); 600 601 // for events supported only by CDMA phone 602 phone.registerForCdmaOtaStatusChange(handler, EVENT_CDMA_OTA_STATUS_CHANGE, null); 603 phone.registerForSubscriptionInfoReady(handler, EVENT_SUBSCRIPTION_INFO_READY, null); 604 phone.registerForCallWaiting(handler, EVENT_CALL_WAITING, null); 605 phone.registerForEcmTimerReset(handler, EVENT_ECM_TIMER_RESET, null); 606 607 // for events supported only by IMS phone 608 phone.registerForOnHoldTone(handler, EVENT_ONHOLD_TONE, null); 609 phone.registerForSuppServiceFailed(handler, EVENT_SUPP_SERVICE_FAILED, null); 610 phone.registerForTtyModeReceived(handler, EVENT_TTY_MODE_RECEIVED, null); 611 } 612 unregisterForPhoneStates(Phone phone)613 private void unregisterForPhoneStates(Phone phone) { 614 // Make sure that we clean up our map of handlers to Phones. 615 CallManagerHandler handler = mHandlerMap.get(phone); 616 if (handler == null) { 617 Rlog.e(LOG_TAG, "Could not find Phone handler for unregistration"); 618 return; 619 } 620 mHandlerMap.remove(phone); 621 622 // for common events supported by all phones 623 phone.unregisterForPreciseCallStateChanged(handler); 624 phone.unregisterForDisconnect(handler); 625 phone.unregisterForNewRingingConnection(handler); 626 phone.unregisterForUnknownConnection(handler); 627 phone.unregisterForIncomingRing(handler); 628 phone.unregisterForRingbackTone(handler); 629 phone.unregisterForInCallVoicePrivacyOn(handler); 630 phone.unregisterForInCallVoicePrivacyOff(handler); 631 phone.unregisterForDisplayInfo(handler); 632 phone.unregisterForSignalInfo(handler); 633 phone.unregisterForResendIncallMute(handler); 634 phone.unregisterForMmiInitiate(handler); 635 phone.unregisterForMmiComplete(handler); 636 phone.unregisterForSuppServiceFailed(handler); 637 phone.unregisterForServiceStateChanged(handler); 638 phone.unregisterForTtyModeReceived(handler); 639 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 640 //phone.unregisterForRadioOffOrNotAvailable(handler); 641 642 // for events supported only by GSM, CDMA and IMS phone 643 phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null); 644 645 // for events supported only by CDMA phone 646 phone.unregisterForCdmaOtaStatusChange(handler); 647 phone.unregisterForSubscriptionInfoReady(handler); 648 phone.unregisterForCallWaiting(handler); 649 phone.unregisterForEcmTimerReset(handler); 650 651 // for events supported only by IMS phone 652 phone.unregisterForOnHoldTone(handler); 653 phone.unregisterForSuppServiceFailed(handler); 654 } 655 656 /** 657 * Reject (ignore) a ringing call. In GSM, this means UDUB 658 * (User Determined User Busy). Reject occurs asynchronously, 659 * and final notification occurs via 660 * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, 661 * java.lang.Object) registerForPreciseCallStateChanged()}. 662 * 663 * @exception CallStateException when no call is ringing or waiting 664 */ rejectCall(Call ringingCall)665 public void rejectCall(Call ringingCall) throws CallStateException { 666 if (VDBG) { 667 Rlog.d(LOG_TAG, toString()); 668 } 669 670 Phone ringingPhone = ringingCall.getPhone(); 671 672 ringingPhone.rejectCall(); 673 674 if (VDBG) { 675 Rlog.d(LOG_TAG, "End rejectCall(" +ringingCall + ")"); 676 Rlog.d(LOG_TAG, toString()); 677 } 678 } 679 680 /** 681 * Whether or not the phone can conference in the current phone 682 * state--that is, one call holding and one call active. 683 * @return true if the phone can conference; false otherwise. 684 */ canConference(Call heldCall)685 public boolean canConference(Call heldCall) { 686 Phone activePhone = null; 687 Phone heldPhone = null; 688 689 if (hasActiveFgCall()) { 690 activePhone = getActiveFgCall().getPhone(); 691 } 692 693 if (heldCall != null) { 694 heldPhone = heldCall.getPhone(); 695 } 696 697 return heldPhone.getClass().equals(activePhone.getClass()); 698 } 699 700 /** 701 * Whether or not the phone can conference in the current phone 702 * state--that is, one call holding and one call active. 703 * This method consider the phone object which is specific 704 * to the provided subId. 705 * @return true if the phone can conference; false otherwise. 706 */ 707 @UnsupportedAppUsage canConference(Call heldCall, int subId)708 public boolean canConference(Call heldCall, int subId) { 709 Phone activePhone = null; 710 Phone heldPhone = null; 711 712 if (hasActiveFgCall(subId)) { 713 activePhone = getActiveFgCall(subId).getPhone(); 714 } 715 716 if (heldCall != null) { 717 heldPhone = heldCall.getPhone(); 718 } 719 720 return heldPhone.getClass().equals(activePhone.getClass()); 721 } 722 723 /** 724 * Conferences holding and active. Conference occurs asynchronously 725 * and may fail. Final notification occurs via 726 * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, 727 * java.lang.Object) registerForPreciseCallStateChanged()}. 728 * 729 * @exception CallStateException if canConference() would return false. 730 * In these cases, this operation may not be performed. 731 */ 732 @UnsupportedAppUsage conference(Call heldCall)733 public void conference(Call heldCall) throws CallStateException { 734 int subId = heldCall.getPhone().getSubId(); 735 736 if (VDBG) { 737 Rlog.d(LOG_TAG, "conference(" +heldCall + ")"); 738 Rlog.d(LOG_TAG, toString()); 739 } 740 741 Phone fgPhone = getFgPhone(subId); 742 if (fgPhone != null) { 743 if (fgPhone instanceof SipPhone) { 744 ((SipPhone) fgPhone).conference(heldCall); 745 } else if (canConference(heldCall)) { 746 fgPhone.conference(); 747 } else { 748 throw(new CallStateException("Can't conference foreground and selected background call")); 749 } 750 } else { 751 Rlog.d(LOG_TAG, "conference: fgPhone=null"); 752 } 753 754 if (VDBG) { 755 Rlog.d(LOG_TAG, "End conference(" +heldCall + ")"); 756 Rlog.d(LOG_TAG, toString()); 757 } 758 759 } 760 761 /** 762 * Initiate a new voice connection. This happens asynchronously, so you 763 * cannot assume the audio path is connected (or a call index has been 764 * assigned) until PhoneStateChanged notification has occurred. 765 * 766 * @exception CallStateException if a new outgoing call is not currently 767 * possible because no more call slots exist or a call exists that is 768 * dialing, alerting, ringing, or waiting. Other errors are 769 * handled asynchronously. 770 */ dial(Phone phone, String dialString, int videoState)771 public Connection dial(Phone phone, String dialString, int videoState) 772 throws CallStateException { 773 int subId = phone.getSubId(); 774 Connection result; 775 776 if (VDBG) { 777 Rlog.d(LOG_TAG, " dial(" + phone + ", "+ dialString + ")" + 778 " subId = " + subId); 779 Rlog.d(LOG_TAG, toString()); 780 } 781 782 if (!canDial(phone)) { 783 /* 784 * canDial function only checks whether the phone can make a new call. 785 * InCall MMI commmands are basically supplementary services 786 * within a call eg: call hold, call deflection, explicit call transfer etc. 787 */ 788 String newDialString = PhoneNumberUtils.stripSeparators(dialString); 789 if (phone.handleInCallMmiCommands(newDialString)) { 790 return null; 791 } else { 792 throw new CallStateException("cannot dial in current state"); 793 } 794 } 795 796 if ( hasActiveFgCall(subId) ) { 797 Phone activePhone = getActiveFgCall(subId).getPhone(); 798 boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle()); 799 800 if (DBG) { 801 Rlog.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == phone)); 802 } 803 804 // Manipulation between IMS phone and its owner 805 // will be treated in GSM/CDMA phone. 806 Phone imsPhone = phone.getImsPhone(); 807 if (activePhone != phone 808 && (imsPhone == null || imsPhone != activePhone)) { 809 if (hasBgCall) { 810 Rlog.d(LOG_TAG, "Hangup"); 811 getActiveFgCall(subId).hangup(); 812 } else { 813 Rlog.d(LOG_TAG, "Switch"); 814 activePhone.switchHoldingAndActive(); 815 } 816 } 817 } 818 819 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 820 //mIsEccDialing = PhoneNumberUtils.isEmergencyNumber(dialString); 821 822 result = phone.dial(dialString, new PhoneInternalInterface.DialArgs.Builder<>() 823 .setVideoState(videoState).build()); 824 825 if (VDBG) { 826 Rlog.d(LOG_TAG, "End dial(" + phone + ", "+ dialString + ")"); 827 Rlog.d(LOG_TAG, toString()); 828 } 829 830 return result; 831 } 832 833 /** 834 * Initiate a new voice connection. This happens asynchronously, so you 835 * cannot assume the audio path is connected (or a call index has been 836 * assigned) until PhoneStateChanged notification has occurred. 837 * 838 * @exception CallStateException if a new outgoing call is not currently 839 * possible because no more call slots exist or a call exists that is 840 * dialing, alerting, ringing, or waiting. Other errors are 841 * handled asynchronously. 842 */ dial(Phone phone, String dialString, UUSInfo uusInfo, int videoState)843 public Connection dial(Phone phone, String dialString, UUSInfo uusInfo, int videoState) 844 throws CallStateException { 845 return phone.dial(dialString, 846 new PhoneInternalInterface.DialArgs.Builder<>() 847 .setUusInfo(uusInfo) 848 .setVideoState(videoState).build()); 849 } 850 851 /** 852 * clear disconnect connection for each phone 853 */ clearDisconnected()854 public void clearDisconnected() { 855 for(Phone phone : mPhones) { 856 phone.clearDisconnected(); 857 } 858 } 859 860 /** 861 * clear disconnect connection for a phone specific 862 * to the provided subId 863 */ clearDisconnected(int subId)864 public void clearDisconnected(int subId) { 865 for(Phone phone : mPhones) { 866 if (phone.getSubId() == subId) { 867 phone.clearDisconnected(); 868 } 869 } 870 } 871 872 /** 873 * Phone can make a call only if ALL of the following are true: 874 * - Phone is not powered off 875 * - There's no incoming or waiting call 876 * - The foreground call is ACTIVE or IDLE or DISCONNECTED. 877 * (We mainly need to make sure it *isn't* DIALING or ALERTING.) 878 * @param phone 879 * @return true if the phone can make a new call 880 */ 881 @UnsupportedAppUsage canDial(Phone phone)882 private boolean canDial(Phone phone) { 883 int serviceState = phone.getServiceState().getState(); 884 int subId = phone.getSubId(); 885 boolean hasRingingCall = hasActiveRingingCall(); 886 Call.State fgCallState = getActiveFgCallState(subId); 887 888 boolean result = (serviceState != ServiceState.STATE_POWER_OFF 889 && !hasRingingCall 890 && ((fgCallState == Call.State.ACTIVE) 891 || (fgCallState == Call.State.IDLE) 892 || (fgCallState == Call.State.DISCONNECTED) 893 /*As per 3GPP TS 51.010-1 section 31.13.1.4 894 call should be alowed when the foreground 895 call is in ALERTING state*/ 896 || (fgCallState == Call.State.ALERTING))); 897 898 if (result == false) { 899 Rlog.d(LOG_TAG, "canDial serviceState=" + serviceState 900 + " hasRingingCall=" + hasRingingCall 901 + " fgCallState=" + fgCallState); 902 } 903 return result; 904 } 905 906 /** 907 * Whether or not the phone can do explicit call transfer in the current 908 * phone state--that is, one call holding and one call active. 909 * @return true if the phone can do explicit call transfer; false otherwise. 910 */ canTransfer(Call heldCall)911 public boolean canTransfer(Call heldCall) { 912 Phone activePhone = null; 913 Phone heldPhone = null; 914 915 if (hasActiveFgCall()) { 916 activePhone = getActiveFgCall().getPhone(); 917 } 918 919 if (heldCall != null) { 920 heldPhone = heldCall.getPhone(); 921 } 922 923 return (heldPhone == activePhone && activePhone.canTransfer()); 924 } 925 926 /** 927 * Whether or not the phone specific to subId can do explicit call transfer 928 * in the current phone state--that is, one call holding and one call active. 929 * @return true if the phone can do explicit call transfer; false otherwise. 930 */ canTransfer(Call heldCall, int subId)931 public boolean canTransfer(Call heldCall, int subId) { 932 Phone activePhone = null; 933 Phone heldPhone = null; 934 935 if (hasActiveFgCall(subId)) { 936 activePhone = getActiveFgCall(subId).getPhone(); 937 } 938 939 if (heldCall != null) { 940 heldPhone = heldCall.getPhone(); 941 } 942 943 return (heldPhone == activePhone && activePhone.canTransfer()); 944 } 945 946 /** 947 * Connects the held call and active call 948 * Disconnects the subscriber from both calls 949 * 950 * Explicit Call Transfer occurs asynchronously 951 * and may fail. Final notification occurs via 952 * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, 953 * java.lang.Object) registerForPreciseCallStateChanged()}. 954 * 955 * @exception CallStateException if canTransfer() would return false. 956 * In these cases, this operation may not be performed. 957 */ explicitCallTransfer(Call heldCall)958 public void explicitCallTransfer(Call heldCall) throws CallStateException { 959 if (VDBG) { 960 Rlog.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")"); 961 Rlog.d(LOG_TAG, toString()); 962 } 963 964 if (canTransfer(heldCall)) { 965 heldCall.getPhone().explicitCallTransfer(); 966 } 967 968 if (VDBG) { 969 Rlog.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")"); 970 Rlog.d(LOG_TAG, toString()); 971 } 972 973 } 974 975 /** 976 * Returns a list of MMI codes that are pending for a phone. (They have initiated 977 * but have not yet completed). 978 * Presently there is only ever one. 979 * 980 * Use <code>registerForMmiInitiate</code> 981 * and <code>registerForMmiComplete</code> for change notification. 982 * @return null if phone doesn't have or support mmi code 983 */ getPendingMmiCodes(Phone phone)984 public List<? extends MmiCode> getPendingMmiCodes(Phone phone) { 985 Rlog.e(LOG_TAG, "getPendingMmiCodes not implemented"); 986 return null; 987 } 988 989 /** 990 * Sends user response to a USSD REQUEST message. An MmiCode instance 991 * representing this response is sent to handlers registered with 992 * registerForMmiInitiate. 993 * 994 * @param ussdMessge Message to send in the response. 995 * @return false if phone doesn't support ussd service 996 */ sendUssdResponse(Phone phone, String ussdMessge)997 public boolean sendUssdResponse(Phone phone, String ussdMessge) { 998 Rlog.e(LOG_TAG, "sendUssdResponse not implemented"); 999 return false; 1000 } 1001 1002 /** 1003 * Mutes or unmutes the microphone for the active call. The microphone 1004 * is automatically unmuted if a call is answered, dialed, or resumed 1005 * from a holding state. 1006 * 1007 * @param muted true to mute the microphone, 1008 * false to activate the microphone. 1009 */ 1010 setMute(boolean muted)1011 public void setMute(boolean muted) { 1012 if (VDBG) { 1013 Rlog.d(LOG_TAG, " setMute(" + muted + ")"); 1014 Rlog.d(LOG_TAG, toString()); 1015 } 1016 1017 if (hasActiveFgCall()) { 1018 getActiveFgCall().getPhone().setMute(muted); 1019 } 1020 1021 if (VDBG) { 1022 Rlog.d(LOG_TAG, "End setMute(" + muted + ")"); 1023 Rlog.d(LOG_TAG, toString()); 1024 } 1025 } 1026 1027 /** 1028 * Gets current mute status. Use 1029 * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, 1030 * java.lang.Object) registerForPreciseCallStateChanged()} 1031 * as a change notifcation, although presently phone state changed is not 1032 * fired when setMute() is called. 1033 * 1034 * @return true is muting, false is unmuting 1035 */ getMute()1036 public boolean getMute() { 1037 if (hasActiveFgCall()) { 1038 return getActiveFgCall().getPhone().getMute(); 1039 } else if (hasActiveBgCall()) { 1040 return getFirstActiveBgCall().getPhone().getMute(); 1041 } 1042 return false; 1043 } 1044 1045 /** 1046 * Enables or disables echo suppression. 1047 */ setEchoSuppressionEnabled()1048 public void setEchoSuppressionEnabled() { 1049 if (VDBG) { 1050 Rlog.d(LOG_TAG, " setEchoSuppression()"); 1051 Rlog.d(LOG_TAG, toString()); 1052 } 1053 1054 if (hasActiveFgCall()) { 1055 getActiveFgCall().getPhone().setEchoSuppressionEnabled(); 1056 } 1057 1058 if (VDBG) { 1059 Rlog.d(LOG_TAG, "End setEchoSuppression()"); 1060 Rlog.d(LOG_TAG, toString()); 1061 } 1062 } 1063 1064 /** 1065 * Play a DTMF tone on the active call. 1066 * 1067 * @param c should be one of 0-9, '*' or '#'. Other values will be 1068 * silently ignored. 1069 * @return false if no active call or the active call doesn't support 1070 * dtmf tone 1071 */ sendDtmf(char c)1072 public boolean sendDtmf(char c) { 1073 boolean result = false; 1074 1075 if (VDBG) { 1076 Rlog.d(LOG_TAG, " sendDtmf(" + c + ")"); 1077 Rlog.d(LOG_TAG, toString()); 1078 } 1079 1080 if (hasActiveFgCall()) { 1081 getActiveFgCall().getPhone().sendDtmf(c); 1082 result = true; 1083 } 1084 1085 if (VDBG) { 1086 Rlog.d(LOG_TAG, "End sendDtmf(" + c + ")"); 1087 Rlog.d(LOG_TAG, toString()); 1088 } 1089 return result; 1090 } 1091 1092 /** 1093 * Start to paly a DTMF tone on the active call. 1094 * or there is a playing DTMF tone. 1095 * @param c should be one of 0-9, '*' or '#'. Other values will be 1096 * silently ignored. 1097 * 1098 * @return false if no active call or the active call doesn't support 1099 * dtmf tone 1100 */ startDtmf(char c)1101 public boolean startDtmf(char c) { 1102 boolean result = false; 1103 1104 if (VDBG) { 1105 Rlog.d(LOG_TAG, " startDtmf(" + c + ")"); 1106 Rlog.d(LOG_TAG, toString()); 1107 } 1108 1109 if (hasActiveFgCall()) { 1110 getActiveFgCall().getPhone().startDtmf(c); 1111 result = true; 1112 } 1113 1114 if (VDBG) { 1115 Rlog.d(LOG_TAG, "End startDtmf(" + c + ")"); 1116 Rlog.d(LOG_TAG, toString()); 1117 } 1118 1119 return result; 1120 } 1121 1122 /** 1123 * Stop the playing DTMF tone. Ignored if there is no playing DTMF 1124 * tone or no active call. 1125 */ stopDtmf()1126 public void stopDtmf() { 1127 if (VDBG) { 1128 Rlog.d(LOG_TAG, " stopDtmf()" ); 1129 Rlog.d(LOG_TAG, toString()); 1130 } 1131 1132 if (hasActiveFgCall()) getFgPhone().stopDtmf(); 1133 1134 if (VDBG) { 1135 Rlog.d(LOG_TAG, "End stopDtmf()"); 1136 Rlog.d(LOG_TAG, toString()); 1137 } 1138 } 1139 1140 /** 1141 * send burst DTMF tone, it can send the string as single character or multiple character 1142 * ignore if there is no active call or not valid digits string. 1143 * Valid digit means only includes characters ISO-LATIN characters 0-9, *, # 1144 * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character, 1145 * this api can send single character and multiple character, also, this api has response 1146 * back to caller. 1147 * 1148 * @param dtmfString is string representing the dialing digit(s) in the active call 1149 * @param on the DTMF ON length in milliseconds, or 0 for default 1150 * @param off the DTMF OFF length in milliseconds, or 0 for default 1151 * @param onComplete is the callback message when the action is processed by BP 1152 * 1153 */ sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)1154 public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1155 if (hasActiveFgCall()) { 1156 getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete); 1157 return true; 1158 } 1159 return false; 1160 } 1161 1162 /** 1163 * Notifies when a voice connection has disconnected, either due to local 1164 * or remote hangup or error. 1165 * 1166 * Messages received from this will have the following members:<p> 1167 * <ul><li>Message.obj will be an AsyncResult</li> 1168 * <li>AsyncResult.userObj = obj</li> 1169 * <li>AsyncResult.result = a Connection object that is 1170 * no longer connected.</li></ul> 1171 */ 1172 @UnsupportedAppUsage registerForDisconnect(Handler h, int what, Object obj)1173 public void registerForDisconnect(Handler h, int what, Object obj) { 1174 mDisconnectRegistrants.addUnique(h, what, obj); 1175 } 1176 1177 /** 1178 * Unregisters for voice disconnection notification. 1179 * Extraneous calls are tolerated silently 1180 */ 1181 @UnsupportedAppUsage unregisterForDisconnect(Handler h)1182 public void unregisterForDisconnect(Handler h){ 1183 mDisconnectRegistrants.remove(h); 1184 } 1185 1186 /** 1187 * Register for getting notifications for change in the Call State {@link Call.State} 1188 * This is called PreciseCallState because the call state is more precise than what 1189 * can be obtained using the {@link PhoneStateListener} 1190 * 1191 * Resulting events will have an AsyncResult in <code>Message.obj</code>. 1192 * AsyncResult.userData will be set to the obj argument here. 1193 * The <em>h</em> parameter is held only by a weak reference. 1194 */ 1195 @UnsupportedAppUsage registerForPreciseCallStateChanged(Handler h, int what, Object obj)1196 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){ 1197 mPreciseCallStateRegistrants.addUnique(h, what, obj); 1198 } 1199 1200 /** 1201 * Unregisters for voice call state change notifications. 1202 * Extraneous calls are tolerated silently. 1203 */ 1204 @UnsupportedAppUsage unregisterForPreciseCallStateChanged(Handler h)1205 public void unregisterForPreciseCallStateChanged(Handler h){ 1206 mPreciseCallStateRegistrants.remove(h); 1207 } 1208 1209 /** 1210 * Notifies when a previously untracked non-ringing/waiting connection has appeared. 1211 * This is likely due to some other entity (eg, SIM card application) initiating a call. 1212 */ registerForUnknownConnection(Handler h, int what, Object obj)1213 public void registerForUnknownConnection(Handler h, int what, Object obj){ 1214 mUnknownConnectionRegistrants.addUnique(h, what, obj); 1215 } 1216 1217 /** 1218 * Unregisters for unknown connection notifications. 1219 */ unregisterForUnknownConnection(Handler h)1220 public void unregisterForUnknownConnection(Handler h){ 1221 mUnknownConnectionRegistrants.remove(h); 1222 } 1223 1224 1225 /** 1226 * Notifies when a new ringing or waiting connection has appeared.<p> 1227 * 1228 * Messages received from this: 1229 * Message.obj will be an AsyncResult 1230 * AsyncResult.userObj = obj 1231 * AsyncResult.result = a Connection. <p> 1232 * Please check Connection.isRinging() to make sure the Connection 1233 * has not dropped since this message was posted. 1234 * If Connection.isRinging() is true, then 1235 * Connection.getCall() == Phone.getRingingCall() 1236 */ 1237 @UnsupportedAppUsage registerForNewRingingConnection(Handler h, int what, Object obj)1238 public void registerForNewRingingConnection(Handler h, int what, Object obj){ 1239 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 1240 } 1241 1242 /** 1243 * Unregisters for new ringing connection notification. 1244 * Extraneous calls are tolerated silently 1245 */ 1246 1247 @UnsupportedAppUsage unregisterForNewRingingConnection(Handler h)1248 public void unregisterForNewRingingConnection(Handler h){ 1249 mNewRingingConnectionRegistrants.remove(h); 1250 } 1251 1252 /** 1253 * Notifies when an incoming call rings.<p> 1254 * 1255 * Messages received from this: 1256 * Message.obj will be an AsyncResult 1257 * AsyncResult.userObj = obj 1258 * AsyncResult.result = a Connection. <p> 1259 */ registerForIncomingRing(Handler h, int what, Object obj)1260 public void registerForIncomingRing(Handler h, int what, Object obj){ 1261 mIncomingRingRegistrants.addUnique(h, what, obj); 1262 } 1263 1264 /** 1265 * Unregisters for ring notification. 1266 * Extraneous calls are tolerated silently 1267 */ 1268 unregisterForIncomingRing(Handler h)1269 public void unregisterForIncomingRing(Handler h){ 1270 mIncomingRingRegistrants.remove(h); 1271 } 1272 1273 /** 1274 * Notifies when out-band ringback tone is needed.<p> 1275 * 1276 * Messages received from this: 1277 * Message.obj will be an AsyncResult 1278 * AsyncResult.userObj = obj 1279 * AsyncResult.result = boolean, true to start play ringback tone 1280 * and false to stop. <p> 1281 */ registerForRingbackTone(Handler h, int what, Object obj)1282 public void registerForRingbackTone(Handler h, int what, Object obj){ 1283 mRingbackToneRegistrants.addUnique(h, what, obj); 1284 } 1285 1286 /** 1287 * Unregisters for ringback tone notification. 1288 */ 1289 unregisterForRingbackTone(Handler h)1290 public void unregisterForRingbackTone(Handler h){ 1291 mRingbackToneRegistrants.remove(h); 1292 } 1293 1294 /** 1295 * Notifies when out-band on-hold tone is needed.<p> 1296 * 1297 * Messages received from this: 1298 * Message.obj will be an AsyncResult 1299 * AsyncResult.userObj = obj 1300 * AsyncResult.result = boolean, true to start play on-hold tone 1301 * and false to stop. <p> 1302 */ registerForOnHoldTone(Handler h, int what, Object obj)1303 public void registerForOnHoldTone(Handler h, int what, Object obj){ 1304 mOnHoldToneRegistrants.addUnique(h, what, obj); 1305 } 1306 1307 /** 1308 * Unregisters for on-hold tone notification. 1309 */ 1310 unregisterForOnHoldTone(Handler h)1311 public void unregisterForOnHoldTone(Handler h){ 1312 mOnHoldToneRegistrants.remove(h); 1313 } 1314 1315 /** 1316 * Registers the handler to reset the uplink mute state to get 1317 * uplink audio. 1318 */ registerForResendIncallMute(Handler h, int what, Object obj)1319 public void registerForResendIncallMute(Handler h, int what, Object obj){ 1320 mResendIncallMuteRegistrants.addUnique(h, what, obj); 1321 } 1322 1323 /** 1324 * Unregisters for resend incall mute notifications. 1325 */ unregisterForResendIncallMute(Handler h)1326 public void unregisterForResendIncallMute(Handler h){ 1327 mResendIncallMuteRegistrants.remove(h); 1328 } 1329 1330 /** 1331 * Register for notifications of initiation of a new MMI code request. 1332 * MMI codes for GSM are discussed in 3GPP TS 22.030.<p> 1333 * 1334 * Example: If Phone.dial is called with "*#31#", then the app will 1335 * be notified here.<p> 1336 * 1337 * The returned <code>Message.obj</code> will contain an AsyncResult. 1338 * 1339 * <code>obj.result</code> will be an "MmiCode" object. 1340 */ registerForMmiInitiate(Handler h, int what, Object obj)1341 public void registerForMmiInitiate(Handler h, int what, Object obj){ 1342 mMmiInitiateRegistrants.addUnique(h, what, obj); 1343 } 1344 1345 /** 1346 * Unregisters for new MMI initiate notification. 1347 * Extraneous calls are tolerated silently 1348 */ unregisterForMmiInitiate(Handler h)1349 public void unregisterForMmiInitiate(Handler h){ 1350 mMmiInitiateRegistrants.remove(h); 1351 } 1352 1353 /** 1354 * Register for notifications that an MMI request has completed 1355 * its network activity and is in its final state. This may mean a state 1356 * of COMPLETE, FAILED, or CANCELLED. 1357 * 1358 * <code>Message.obj</code> will contain an AsyncResult. 1359 * <code>obj.result</code> will be an "MmiCode" object 1360 */ registerForMmiComplete(Handler h, int what, Object obj)1361 public void registerForMmiComplete(Handler h, int what, Object obj){ 1362 Rlog.d(LOG_TAG, "registerForMmiComplete"); 1363 mMmiCompleteRegistrants.addUnique(h, what, obj); 1364 } 1365 1366 /** 1367 * Unregisters for MMI complete notification. 1368 * Extraneous calls are tolerated silently 1369 */ unregisterForMmiComplete(Handler h)1370 public void unregisterForMmiComplete(Handler h){ 1371 mMmiCompleteRegistrants.remove(h); 1372 } 1373 1374 /** 1375 * Registration point for Ecm timer reset 1376 * @param h handler to notify 1377 * @param what user-defined message code 1378 * @param obj placed in Message.obj 1379 */ registerForEcmTimerReset(Handler h, int what, Object obj)1380 public void registerForEcmTimerReset(Handler h, int what, Object obj){ 1381 mEcmTimerResetRegistrants.addUnique(h, what, obj); 1382 } 1383 1384 /** 1385 * Unregister for notification for Ecm timer reset 1386 * @param h Handler to be removed from the registrant list. 1387 */ unregisterForEcmTimerReset(Handler h)1388 public void unregisterForEcmTimerReset(Handler h){ 1389 mEcmTimerResetRegistrants.remove(h); 1390 } 1391 1392 /** 1393 * Register for ServiceState changed. 1394 * Message.obj will contain an AsyncResult. 1395 * AsyncResult.result will be a ServiceState instance 1396 */ registerForServiceStateChanged(Handler h, int what, Object obj)1397 public void registerForServiceStateChanged(Handler h, int what, Object obj){ 1398 mServiceStateChangedRegistrants.addUnique(h, what, obj); 1399 } 1400 1401 /** 1402 * Unregisters for ServiceStateChange notification. 1403 * Extraneous calls are tolerated silently 1404 */ unregisterForServiceStateChanged(Handler h)1405 public void unregisterForServiceStateChanged(Handler h){ 1406 mServiceStateChangedRegistrants.remove(h); 1407 } 1408 1409 /** 1410 * Register for notifications when a supplementary service attempt fails. 1411 * Message.obj will contain an AsyncResult. 1412 * 1413 * @param h Handler that receives the notification message. 1414 * @param what User-defined message code. 1415 * @param obj User object. 1416 */ registerForSuppServiceFailed(Handler h, int what, Object obj)1417 public void registerForSuppServiceFailed(Handler h, int what, Object obj){ 1418 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 1419 } 1420 1421 /** 1422 * Unregister for notifications when a supplementary service attempt fails. 1423 * Extraneous calls are tolerated silently 1424 * 1425 * @param h Handler to be removed from the registrant list. 1426 */ unregisterForSuppServiceFailed(Handler h)1427 public void unregisterForSuppServiceFailed(Handler h){ 1428 mSuppServiceFailedRegistrants.remove(h); 1429 } 1430 1431 /** 1432 * Register for notifications when a sInCall VoicePrivacy is enabled 1433 * 1434 * @param h Handler that receives the notification message. 1435 * @param what User-defined message code. 1436 * @param obj User object. 1437 */ registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)1438 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 1439 mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj); 1440 } 1441 1442 /** 1443 * Unregister for notifications when a sInCall VoicePrivacy is enabled 1444 * 1445 * @param h Handler to be removed from the registrant list. 1446 */ unregisterForInCallVoicePrivacyOn(Handler h)1447 public void unregisterForInCallVoicePrivacyOn(Handler h){ 1448 mInCallVoicePrivacyOnRegistrants.remove(h); 1449 } 1450 1451 /** 1452 * Register for notifications when a sInCall VoicePrivacy is disabled 1453 * 1454 * @param h Handler that receives the notification message. 1455 * @param what User-defined message code. 1456 * @param obj User object. 1457 */ registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)1458 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 1459 mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj); 1460 } 1461 1462 /** 1463 * Unregister for notifications when a sInCall VoicePrivacy is disabled 1464 * 1465 * @param h Handler to be removed from the registrant list. 1466 */ unregisterForInCallVoicePrivacyOff(Handler h)1467 public void unregisterForInCallVoicePrivacyOff(Handler h){ 1468 mInCallVoicePrivacyOffRegistrants.remove(h); 1469 } 1470 1471 /** 1472 * Register for notifications when CDMA call waiting comes 1473 * 1474 * @param h Handler that receives the notification message. 1475 * @param what User-defined message code. 1476 * @param obj User object. 1477 */ registerForCallWaiting(Handler h, int what, Object obj)1478 public void registerForCallWaiting(Handler h, int what, Object obj){ 1479 mCallWaitingRegistrants.addUnique(h, what, obj); 1480 } 1481 1482 /** 1483 * Unregister for notifications when CDMA Call waiting comes 1484 * @param h Handler to be removed from the registrant list. 1485 */ unregisterForCallWaiting(Handler h)1486 public void unregisterForCallWaiting(Handler h){ 1487 mCallWaitingRegistrants.remove(h); 1488 } 1489 1490 1491 /** 1492 * Register for signal information notifications from the network. 1493 * Message.obj will contain an AsyncResult. 1494 * AsyncResult.result will be a SuppServiceNotification instance. 1495 * 1496 * @param h Handler that receives the notification message. 1497 * @param what User-defined message code. 1498 * @param obj User object. 1499 */ 1500 registerForSignalInfo(Handler h, int what, Object obj)1501 public void registerForSignalInfo(Handler h, int what, Object obj){ 1502 mSignalInfoRegistrants.addUnique(h, what, obj); 1503 } 1504 1505 /** 1506 * Unregisters for signal information notifications. 1507 * Extraneous calls are tolerated silently 1508 * 1509 * @param h Handler to be removed from the registrant list. 1510 */ unregisterForSignalInfo(Handler h)1511 public void unregisterForSignalInfo(Handler h){ 1512 mSignalInfoRegistrants.remove(h); 1513 } 1514 1515 /** 1516 * Register for display information notifications from the network. 1517 * Message.obj will contain an AsyncResult. 1518 * AsyncResult.result will be a SuppServiceNotification instance. 1519 * 1520 * @param h Handler that receives the notification message. 1521 * @param what User-defined message code. 1522 * @param obj User object. 1523 */ registerForDisplayInfo(Handler h, int what, Object obj)1524 public void registerForDisplayInfo(Handler h, int what, Object obj){ 1525 mDisplayInfoRegistrants.addUnique(h, what, obj); 1526 } 1527 1528 /** 1529 * Unregisters for display information notifications. 1530 * Extraneous calls are tolerated silently 1531 * 1532 * @param h Handler to be removed from the registrant list. 1533 */ unregisterForDisplayInfo(Handler h)1534 public void unregisterForDisplayInfo(Handler h) { 1535 mDisplayInfoRegistrants.remove(h); 1536 } 1537 1538 /** 1539 * Register for notifications when CDMA OTA Provision status change 1540 * 1541 * @param h Handler that receives the notification message. 1542 * @param what User-defined message code. 1543 * @param obj User object. 1544 */ registerForCdmaOtaStatusChange(Handler h, int what, Object obj)1545 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){ 1546 mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj); 1547 } 1548 1549 /** 1550 * Unregister for notifications when CDMA OTA Provision status change 1551 * @param h Handler to be removed from the registrant list. 1552 */ unregisterForCdmaOtaStatusChange(Handler h)1553 public void unregisterForCdmaOtaStatusChange(Handler h){ 1554 mCdmaOtaStatusChangeRegistrants.remove(h); 1555 } 1556 1557 /** 1558 * Registration point for subscription info ready 1559 * @param h handler to notify 1560 * @param what what code of message when delivered 1561 * @param obj placed in Message.obj 1562 */ registerForSubscriptionInfoReady(Handler h, int what, Object obj)1563 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){ 1564 mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj); 1565 } 1566 1567 /** 1568 * Unregister for notifications for subscription info 1569 * @param h Handler to be removed from the registrant list. 1570 */ unregisterForSubscriptionInfoReady(Handler h)1571 public void unregisterForSubscriptionInfoReady(Handler h){ 1572 mSubscriptionInfoReadyRegistrants.remove(h); 1573 } 1574 1575 /** 1576 * Sets an event to be fired when the telephony system processes 1577 * a post-dial character on an outgoing call.<p> 1578 * 1579 * Messages of type <code>what</code> will be sent to <code>h</code>. 1580 * The <code>obj</code> field of these Message's will be instances of 1581 * <code>AsyncResult</code>. <code>Message.obj.result</code> will be 1582 * a Connection object.<p> 1583 * 1584 * Message.arg1 will be the post dial character being processed, 1585 * or 0 ('\0') if end of string.<p> 1586 * 1587 * If Connection.getPostDialState() == WAIT, 1588 * the application must call 1589 * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar() 1590 * Connection.proceedAfterWaitChar()} or 1591 * {@link com.android.internal.telephony.Connection#cancelPostDial() 1592 * Connection.cancelPostDial()} 1593 * for the telephony system to continue playing the post-dial 1594 * DTMF sequence.<p> 1595 * 1596 * If Connection.getPostDialState() == WILD, 1597 * the application must call 1598 * {@link com.android.internal.telephony.Connection#proceedAfterWildChar 1599 * Connection.proceedAfterWildChar()} 1600 * or 1601 * {@link com.android.internal.telephony.Connection#cancelPostDial() 1602 * Connection.cancelPostDial()} 1603 * for the telephony system to continue playing the 1604 * post-dial DTMF sequence.<p> 1605 * 1606 */ registerForPostDialCharacter(Handler h, int what, Object obj)1607 public void registerForPostDialCharacter(Handler h, int what, Object obj){ 1608 mPostDialCharacterRegistrants.addUnique(h, what, obj); 1609 } 1610 unregisterForPostDialCharacter(Handler h)1611 public void unregisterForPostDialCharacter(Handler h){ 1612 mPostDialCharacterRegistrants.remove(h); 1613 } 1614 1615 /** 1616 * Register for TTY mode change notifications from the network. 1617 * Message.obj will contain an AsyncResult. 1618 * AsyncResult.result will be an Integer containing new mode. 1619 * 1620 * @param h Handler that receives the notification message. 1621 * @param what User-defined message code. 1622 * @param obj User object. 1623 */ registerForTtyModeReceived(Handler h, int what, Object obj)1624 public void registerForTtyModeReceived(Handler h, int what, Object obj){ 1625 mTtyModeReceivedRegistrants.addUnique(h, what, obj); 1626 } 1627 1628 /** 1629 * Unregisters for TTY mode change notifications. 1630 * Extraneous calls are tolerated silently 1631 * 1632 * @param h Handler to be removed from the registrant list. 1633 */ unregisterForTtyModeReceived(Handler h)1634 public void unregisterForTtyModeReceived(Handler h) { 1635 mTtyModeReceivedRegistrants.remove(h); 1636 } 1637 1638 /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls 1639 * 1. APIs to access list of calls 1640 * 2. APIs to check if any active call, which has connection other than 1641 * disconnected ones, pleaser refer to Call.isIdle() 1642 * 3. APIs to return first active call 1643 * 4. APIs to return the connections of first active call 1644 * 5. APIs to return other property of first active call 1645 */ 1646 1647 /** 1648 * @return list of all ringing calls 1649 */ 1650 @UnsupportedAppUsage getRingingCalls()1651 public List<Call> getRingingCalls() { 1652 return Collections.unmodifiableList(mRingingCalls); 1653 } 1654 1655 /** 1656 * @return list of all foreground calls 1657 */ getForegroundCalls()1658 public List<Call> getForegroundCalls() { 1659 return Collections.unmodifiableList(mForegroundCalls); 1660 } 1661 1662 /** 1663 * @return list of all background calls 1664 */ 1665 @UnsupportedAppUsage getBackgroundCalls()1666 public List<Call> getBackgroundCalls() { 1667 return Collections.unmodifiableList(mBackgroundCalls); 1668 } 1669 1670 /** 1671 * Return true if there is at least one active foreground call 1672 */ 1673 @UnsupportedAppUsage hasActiveFgCall()1674 public boolean hasActiveFgCall() { 1675 return (getFirstActiveCall(mForegroundCalls) != null); 1676 } 1677 1678 /** 1679 * Return true if there is at least one active foreground call 1680 * on a particular subId or an active sip call 1681 */ 1682 @UnsupportedAppUsage hasActiveFgCall(int subId)1683 public boolean hasActiveFgCall(int subId) { 1684 return (getFirstActiveCall(mForegroundCalls, subId) != null); 1685 } 1686 1687 /** 1688 * Return true if there is at least one active background call 1689 */ 1690 @UnsupportedAppUsage hasActiveBgCall()1691 public boolean hasActiveBgCall() { 1692 // TODO since hasActiveBgCall may get called often 1693 // better to cache it to improve performance 1694 return (getFirstActiveCall(mBackgroundCalls) != null); 1695 } 1696 1697 /** 1698 * Return true if there is at least one active background call 1699 * on a particular subId or an active sip call 1700 */ 1701 @UnsupportedAppUsage hasActiveBgCall(int subId)1702 public boolean hasActiveBgCall(int subId) { 1703 // TODO since hasActiveBgCall may get called often 1704 // better to cache it to improve performance 1705 return (getFirstActiveCall(mBackgroundCalls, subId) != null); 1706 } 1707 1708 /** 1709 * Return true if there is at least one active ringing call 1710 * 1711 */ hasActiveRingingCall()1712 public boolean hasActiveRingingCall() { 1713 return (getFirstActiveCall(mRingingCalls) != null); 1714 } 1715 1716 /** 1717 * Return true if there is at least one active ringing call 1718 */ 1719 @UnsupportedAppUsage hasActiveRingingCall(int subId)1720 public boolean hasActiveRingingCall(int subId) { 1721 return (getFirstActiveCall(mRingingCalls, subId) != null); 1722 } 1723 1724 /** 1725 * return the active foreground call from foreground calls 1726 * 1727 * Active call means the call is NOT in Call.State.IDLE 1728 * 1729 * 1. If there is active foreground call, return it 1730 * 2. If there is no active foreground call, return the 1731 * foreground call associated with default phone, which state is IDLE. 1732 * 3. If there is no phone registered at all, return null. 1733 * 1734 */ getActiveFgCall()1735 public Call getActiveFgCall() { 1736 Call call = getFirstNonIdleCall(mForegroundCalls); 1737 if (call == null) { 1738 call = (mDefaultPhone == null) 1739 ? null 1740 : mDefaultPhone.getForegroundCall(); 1741 } 1742 return call; 1743 } 1744 1745 @UnsupportedAppUsage getActiveFgCall(int subId)1746 public Call getActiveFgCall(int subId) { 1747 Call call = getFirstNonIdleCall(mForegroundCalls, subId); 1748 if (call == null) { 1749 Phone phone = getPhone(subId); 1750 call = (phone == null) 1751 ? null 1752 : phone.getForegroundCall(); 1753 } 1754 return call; 1755 } 1756 1757 // Returns the first call that is not in IDLE state. If both active calls 1758 // and disconnecting/disconnected calls exist, return the first active call. getFirstNonIdleCall(List<Call> calls)1759 private Call getFirstNonIdleCall(List<Call> calls) { 1760 Call result = null; 1761 for (Call call : calls) { 1762 if (!call.isIdle()) { 1763 return call; 1764 } else if (call.getState() != Call.State.IDLE) { 1765 if (result == null) result = call; 1766 } 1767 } 1768 return result; 1769 } 1770 1771 // Returns the first call that is not in IDLE state. If both active calls 1772 // and disconnecting/disconnected calls exist, return the first active call. getFirstNonIdleCall(List<Call> calls, int subId)1773 private Call getFirstNonIdleCall(List<Call> calls, int subId) { 1774 Call result = null; 1775 for (Call call : calls) { 1776 if ((call.getPhone().getSubId() == subId) || 1777 (call.getPhone() instanceof SipPhone)) { 1778 if (!call.isIdle()) { 1779 return call; 1780 } else if (call.getState() != Call.State.IDLE) { 1781 if (result == null) result = call; 1782 } 1783 } 1784 } 1785 return result; 1786 } 1787 1788 /** 1789 * return one active background call from background calls 1790 * 1791 * Active call means the call is NOT idle defined by Call.isIdle() 1792 * 1793 * 1. If there is only one active background call, return it 1794 * 2. If there is more than one active background call, return the first one 1795 * 3. If there is no active background call, return the background call 1796 * associated with default phone, which state is IDLE. 1797 * 4. If there is no background call at all, return null. 1798 * 1799 * Complete background calls list can be get by getBackgroundCalls() 1800 */ 1801 @UnsupportedAppUsage getFirstActiveBgCall()1802 public Call getFirstActiveBgCall() { 1803 Call call = getFirstNonIdleCall(mBackgroundCalls); 1804 if (call == null) { 1805 call = (mDefaultPhone == null) 1806 ? null 1807 : mDefaultPhone.getBackgroundCall(); 1808 } 1809 return call; 1810 } 1811 1812 /** 1813 * return one active background call from background calls of the 1814 * requested subId. 1815 * 1816 * Active call means the call is NOT idle defined by Call.isIdle() 1817 * 1818 * 1. If there is only one active background call on given sub or 1819 * on SIP Phone, return it 1820 * 2. If there is more than one active background call, return the background call 1821 * associated with the active sub. 1822 * 3. If there is no background call at all, return null. 1823 * 1824 * Complete background calls list can be get by getBackgroundCalls() 1825 */ 1826 @UnsupportedAppUsage getFirstActiveBgCall(int subId)1827 public Call getFirstActiveBgCall(int subId) { 1828 Phone phone = getPhone(subId); 1829 if (hasMoreThanOneHoldingCall(subId)) { 1830 return phone.getBackgroundCall(); 1831 } else { 1832 Call call = getFirstNonIdleCall(mBackgroundCalls, subId); 1833 if (call == null) { 1834 call = (phone == null) 1835 ? null 1836 : phone.getBackgroundCall(); 1837 } 1838 return call; 1839 } 1840 } 1841 1842 /** 1843 * return one active ringing call from ringing calls 1844 * 1845 * Active call means the call is NOT idle defined by Call.isIdle() 1846 * 1847 * 1. If there is only one active ringing call, return it 1848 * 2. If there is more than one active ringing call, return the first one 1849 * 3. If there is no active ringing call, return the ringing call 1850 * associated with default phone, which state is IDLE. 1851 * 4. If there is no ringing call at all, return null. 1852 * 1853 * Complete ringing calls list can be get by getRingingCalls() 1854 */ 1855 @UnsupportedAppUsage getFirstActiveRingingCall()1856 public Call getFirstActiveRingingCall() { 1857 Call call = getFirstNonIdleCall(mRingingCalls); 1858 if (call == null) { 1859 call = (mDefaultPhone == null) 1860 ? null 1861 : mDefaultPhone.getRingingCall(); 1862 } 1863 return call; 1864 } 1865 1866 @UnsupportedAppUsage getFirstActiveRingingCall(int subId)1867 public Call getFirstActiveRingingCall(int subId) { 1868 Phone phone = getPhone(subId); 1869 Call call = getFirstNonIdleCall(mRingingCalls, subId); 1870 if (call == null) { 1871 call = (phone == null) 1872 ? null 1873 : phone.getRingingCall(); 1874 } 1875 return call; 1876 } 1877 1878 /** 1879 * @return the state of active foreground call 1880 * return IDLE if there is no active foreground call 1881 */ getActiveFgCallState()1882 public Call.State getActiveFgCallState() { 1883 Call fgCall = getActiveFgCall(); 1884 1885 if (fgCall != null) { 1886 return fgCall.getState(); 1887 } 1888 1889 return Call.State.IDLE; 1890 } 1891 1892 @UnsupportedAppUsage getActiveFgCallState(int subId)1893 public Call.State getActiveFgCallState(int subId) { 1894 Call fgCall = getActiveFgCall(subId); 1895 1896 if (fgCall != null) { 1897 return fgCall.getState(); 1898 } 1899 1900 return Call.State.IDLE; 1901 } 1902 1903 /** 1904 * @return the connections of active foreground call 1905 * return empty list if there is no active foreground call 1906 */ 1907 @UnsupportedAppUsage getFgCallConnections()1908 public List<Connection> getFgCallConnections() { 1909 Call fgCall = getActiveFgCall(); 1910 if ( fgCall != null) { 1911 return fgCall.getConnections(); 1912 } 1913 return mEmptyConnections; 1914 } 1915 1916 /** 1917 * @return the connections of active foreground call 1918 * return empty list if there is no active foreground call 1919 */ getFgCallConnections(int subId)1920 public List<Connection> getFgCallConnections(int subId) { 1921 Call fgCall = getActiveFgCall(subId); 1922 if ( fgCall != null) { 1923 return fgCall.getConnections(); 1924 } 1925 return mEmptyConnections; 1926 } 1927 1928 /** 1929 * @return the connections of active background call 1930 * return empty list if there is no active background call 1931 */ 1932 @UnsupportedAppUsage getBgCallConnections()1933 public List<Connection> getBgCallConnections() { 1934 Call bgCall = getFirstActiveBgCall(); 1935 if ( bgCall != null) { 1936 return bgCall.getConnections(); 1937 } 1938 return mEmptyConnections; 1939 } 1940 1941 /** 1942 * @return true if there is at least one Foreground call in disconnected state 1943 */ hasDisconnectedFgCall()1944 public boolean hasDisconnectedFgCall() { 1945 return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null); 1946 } 1947 1948 /** 1949 * @return true if there is at least one Foreground call in disconnected state 1950 */ hasDisconnectedFgCall(int subId)1951 public boolean hasDisconnectedFgCall(int subId) { 1952 return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED, 1953 subId) != null); 1954 } 1955 1956 /** 1957 * @return true if there is at least one background call in disconnected state 1958 */ hasDisconnectedBgCall()1959 public boolean hasDisconnectedBgCall() { 1960 return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null); 1961 } 1962 1963 /** 1964 * @return true if there is at least one background call in disconnected state 1965 */ hasDisconnectedBgCall(int subId)1966 public boolean hasDisconnectedBgCall(int subId) { 1967 return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED, 1968 subId) != null); 1969 } 1970 1971 1972 /** 1973 * @return the first active call from a call list 1974 */ getFirstActiveCall(ArrayList<Call> calls)1975 private Call getFirstActiveCall(ArrayList<Call> calls) { 1976 for (Call call : calls) { 1977 if (!call.isIdle()) { 1978 return call; 1979 } 1980 } 1981 return null; 1982 } 1983 1984 /** 1985 * @return the first active call from a call list 1986 */ getFirstActiveCall(ArrayList<Call> calls, int subId)1987 private Call getFirstActiveCall(ArrayList<Call> calls, int subId) { 1988 for (Call call : calls) { 1989 if ((!call.isIdle()) && ((call.getPhone().getSubId() == subId) || 1990 (call.getPhone() instanceof SipPhone))) { 1991 return call; 1992 } 1993 } 1994 return null; 1995 } 1996 1997 /** 1998 * @return the first call in a the Call.state from a call list 1999 */ getFirstCallOfState(ArrayList<Call> calls, Call.State state)2000 private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) { 2001 for (Call call : calls) { 2002 if (call.getState() == state) { 2003 return call; 2004 } 2005 } 2006 return null; 2007 } 2008 2009 /** 2010 * @return the first call in a the Call.state from a call list 2011 */ getFirstCallOfState(ArrayList<Call> calls, Call.State state, int subId)2012 private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state, 2013 int subId) { 2014 for (Call call : calls) { 2015 if ((call.getState() == state) || 2016 ((call.getPhone().getSubId() == subId) || 2017 (call.getPhone() instanceof SipPhone))) { 2018 return call; 2019 } 2020 } 2021 return null; 2022 } 2023 2024 @UnsupportedAppUsage hasMoreThanOneRingingCall()2025 private boolean hasMoreThanOneRingingCall() { 2026 int count = 0; 2027 for (Call call : mRingingCalls) { 2028 if (call.getState().isRinging()) { 2029 if (++count > 1) return true; 2030 } 2031 } 2032 return false; 2033 } 2034 2035 /** 2036 * @return true if more than one active ringing call exists on 2037 * the active subId. 2038 * This checks for the active calls on provided 2039 * subId and also active calls on SIP Phone. 2040 * 2041 */ 2042 @UnsupportedAppUsage hasMoreThanOneRingingCall(int subId)2043 private boolean hasMoreThanOneRingingCall(int subId) { 2044 int count = 0; 2045 for (Call call : mRingingCalls) { 2046 if ((call.getState().isRinging()) && 2047 ((call.getPhone().getSubId() == subId) || 2048 (call.getPhone() instanceof SipPhone))) { 2049 if (++count > 1) return true; 2050 } 2051 } 2052 return false; 2053 } 2054 2055 /** 2056 * @return true if more than one active background call exists on 2057 * the provided subId. 2058 * This checks for the background calls on provided 2059 * subId and also background calls on SIP Phone. 2060 * 2061 */ hasMoreThanOneHoldingCall(int subId)2062 private boolean hasMoreThanOneHoldingCall(int subId) { 2063 int count = 0; 2064 for (Call call : mBackgroundCalls) { 2065 if ((call.getState() == Call.State.HOLDING) && 2066 ((call.getPhone().getSubId() == subId) || 2067 (call.getPhone() instanceof SipPhone))) { 2068 if (++count > 1) return true; 2069 } 2070 } 2071 return false; 2072 } 2073 2074 private class CallManagerHandler extends Handler { 2075 @Override handleMessage(Message msg)2076 public void handleMessage(Message msg) { 2077 2078 switch (msg.what) { 2079 case EVENT_DISCONNECT: 2080 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)"); 2081 mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2082 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 2083 //mIsEccDialing = false; 2084 break; 2085 case EVENT_PRECISE_CALL_STATE_CHANGED: 2086 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)"); 2087 mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2088 break; 2089 case EVENT_NEW_RINGING_CONNECTION: 2090 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)"); 2091 Connection c = (Connection) ((AsyncResult) msg.obj).result; 2092 int subId = c.getCall().getPhone().getSubId(); 2093 if (getActiveFgCallState(subId).isDialing() || hasMoreThanOneRingingCall()) { 2094 try { 2095 Rlog.d(LOG_TAG, "silently drop incoming call: " + c.getCall()); 2096 c.getCall().hangup(); 2097 } catch (CallStateException e) { 2098 Rlog.w(LOG_TAG, "new ringing connection", e); 2099 } 2100 } else { 2101 mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2102 } 2103 break; 2104 case EVENT_UNKNOWN_CONNECTION: 2105 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)"); 2106 mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2107 break; 2108 case EVENT_INCOMING_RING: 2109 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)"); 2110 // The event may come from RIL who's not aware of an ongoing fg call 2111 if (!hasActiveFgCall()) { 2112 mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2113 } 2114 break; 2115 case EVENT_RINGBACK_TONE: 2116 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)"); 2117 mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2118 break; 2119 case EVENT_IN_CALL_VOICE_PRIVACY_ON: 2120 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)"); 2121 mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2122 break; 2123 case EVENT_IN_CALL_VOICE_PRIVACY_OFF: 2124 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)"); 2125 mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2126 break; 2127 case EVENT_CALL_WAITING: 2128 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)"); 2129 mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2130 break; 2131 case EVENT_DISPLAY_INFO: 2132 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)"); 2133 mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2134 break; 2135 case EVENT_SIGNAL_INFO: 2136 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)"); 2137 mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2138 break; 2139 case EVENT_CDMA_OTA_STATUS_CHANGE: 2140 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)"); 2141 mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2142 break; 2143 case EVENT_RESEND_INCALL_MUTE: 2144 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)"); 2145 mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2146 break; 2147 case EVENT_MMI_INITIATE: 2148 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)"); 2149 mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2150 break; 2151 case EVENT_MMI_COMPLETE: 2152 Rlog.d(LOG_TAG, "CallManager: handleMessage (EVENT_MMI_COMPLETE)"); 2153 mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2154 break; 2155 case EVENT_ECM_TIMER_RESET: 2156 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)"); 2157 mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2158 break; 2159 case EVENT_SUBSCRIPTION_INFO_READY: 2160 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)"); 2161 mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2162 break; 2163 case EVENT_SUPP_SERVICE_FAILED: 2164 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)"); 2165 mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2166 break; 2167 case EVENT_SERVICE_STATE_CHANGED: 2168 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)"); 2169 mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2170 // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 2171 //setAudioMode(); 2172 break; 2173 case EVENT_POST_DIAL_CHARACTER: 2174 // we need send the character that is being processed in msg.arg1 2175 // so can't use notifyRegistrants() 2176 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)"); 2177 for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) { 2178 Message notifyMsg; 2179 notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant(); 2180 notifyMsg.obj = msg.obj; 2181 notifyMsg.arg1 = msg.arg1; 2182 notifyMsg.sendToTarget(); 2183 } 2184 break; 2185 case EVENT_ONHOLD_TONE: 2186 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_ONHOLD_TONE)"); 2187 mOnHoldToneRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2188 break; 2189 case EVENT_TTY_MODE_RECEIVED: 2190 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_TTY_MODE_RECEIVED)"); 2191 mTtyModeReceivedRegistrants.notifyRegistrants((AsyncResult) msg.obj); 2192 break; 2193 /* FIXME Taken from klp-sprout-dev but setAudioMode was removed in L. 2194 case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: 2195 if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_RADIO_OFF_OR_NOT_AVAILABLE)"); 2196 setAudioMode(); 2197 break; 2198 */ 2199 } 2200 } 2201 }; 2202 } 2203