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