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