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