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