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