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