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