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