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