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