10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2010 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.sip.SipPhone;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.media.AudioManager;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneStateListener;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Collections;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * CallManager class provides an abstract layer for PhoneApp to access
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and control calls. It implements Phone interface.
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * CallManager provides call and connection control as well as
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * channel capability.
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * There are three categories of APIs CallManager provided
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *  1. Call control and operation, such as dial() and hangup()
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *  2. Channel capabilities, such as CanConference()
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *  3. Register notification
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CallManager {
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String LOG_TAG ="CallManager";
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG = true;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean VDBG = false;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_DISCONNECT = 100;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_NEW_RINGING_CONNECTION = 102;
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_UNKNOWN_CONNECTION = 103;
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_INCOMING_RING = 104;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_RINGBACK_TONE = 105;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_CALL_WAITING = 108;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_DISPLAY_INFO = 109;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_SIGNAL_INFO = 110;
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_RESEND_INCALL_MUTE = 112;
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_MMI_INITIATE = 113;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_MMI_COMPLETE = 114;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_ECM_TIMER_RESET = 115;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_SUBSCRIPTION_INFO_READY = 116;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_SUPP_SERVICE_FAILED = 117;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_SERVICE_STATE_CHANGED = 118;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_POST_DIAL_CHARACTER = 119;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Singleton instance
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final CallManager INSTANCE = new CallManager();
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // list of registered phones, which are PhoneBase objs
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final ArrayList<Phone> mPhones;
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // list of supported ringing calls
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final ArrayList<Call> mRingingCalls;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // list of supported background calls
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final ArrayList<Call> mBackgroundCalls;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // list of supported foreground calls
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final ArrayList<Call> mForegroundCalls;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // empty connection list
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // default phone as the first phone registered, which is PhoneBase obj
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Phone mDefaultPhone;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
103f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka    private boolean mSpeedUpAudioForMtCall = false;
104f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // state registrants
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mPreciseCallStateRegistrants
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mNewRingingConnectionRegistrants
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mIncomingRingRegistrants
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mDisconnectRegistrants
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mMmiRegistrants
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mUnknownConnectionRegistrants
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mRingbackToneRegistrants
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mInCallVoicePrivacyOnRegistrants
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mInCallVoicePrivacyOffRegistrants
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mCallWaitingRegistrants
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mDisplayInfoRegistrants
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mSignalInfoRegistrants
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mCdmaOtaStatusChangeRegistrants
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mResendIncallMuteRegistrants
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mMmiInitiateRegistrants
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mMmiCompleteRegistrants
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mEcmTimerResetRegistrants
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mSubscriptionInfoReadyRegistrants
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mSuppServiceFailedRegistrants
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mServiceStateChangedRegistrants
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected final RegistrantList mPostDialCharacterRegistrants
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    = new RegistrantList();
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CallManager() {
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhones = new ArrayList<Phone>();
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRingingCalls = new ArrayList<Call>();
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mBackgroundCalls = new ArrayList<Call>();
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mForegroundCalls = new ArrayList<Call>();
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDefaultPhone = null;
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * get singleton instance of CallManager
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return CallManager
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static CallManager getInstance() {
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return INSTANCE;
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Get the corresponding PhoneBase obj
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phone a Phone object
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the corresponding PhoneBase obj in Phone if Phone
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * is a PhoneProxy obj
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or the Phone itself if Phone is not a PhoneProxy obj
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static Phone getPhoneBase(Phone phone) {
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone instanceof PhoneProxy) {
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return phone.getForegroundCall().getPhone();
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return phone;
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if two phones refer to the same PhoneBase obj
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Both PhoneBase and PhoneProxy implement Phone interface, so
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * they have same phone APIs, such as dial(). The real implementation, for
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * example in GSM,  is in GSMPhone as extend from PhoneBase, so that
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * foregroundCall.getPhone() returns GSMPhone obj. On the other hand,
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * member of GSMPhone.
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * So for phone returned by PhoneFacotry, which is used by PhoneApp,
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        phone.getForegroundCall().getPhone() != phone
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * but
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        isSamePhone(phone, phone.getForegroundCall().getPhone()) == true
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param p1 is the first Phone obj
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param p2 is the second Phone obj
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if p1 and p2 refer to the same phone
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static boolean isSamePhone(Phone p1, Phone p2) {
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getPhoneBase(p1) == getPhoneBase(p2));
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns all the registered phone objects.
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return all the registered phone objects.
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Phone> getAllPhones() {
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Collections.unmodifiableList(mPhones);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Get current coarse-grained voice call state.
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If the Call Manager has an active call and call waiting occurs,
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * then the phone state is RINGING not OFFHOOK
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public PhoneConstants.State getState() {
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PhoneConstants.State s = PhoneConstants.State.IDLE;
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Phone phone : mPhones) {
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (phone.getState() == PhoneConstants.State.RINGING) {
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                s = PhoneConstants.State.RINGING;
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (phone.getState() == PhoneConstants.State.OFFHOOK) {
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (s == PhoneConstants.State.IDLE) s = PhoneConstants.State.OFFHOOK;
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return s;
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the service state of CallManager, which represents the
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * highest priority state of all the service states of phones
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The priority is defined as
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getServiceState() {
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int resultState = ServiceState.STATE_OUT_OF_SERVICE;
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Phone phone : mPhones) {
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int serviceState = phone.getServiceState().getState();
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (serviceState == ServiceState.STATE_IN_SERVICE) {
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // IN_SERVICE has the highest priority
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                resultState = serviceState;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Note: EMERGENCY_ONLY is not in use at this moment
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if ( resultState == ServiceState.STATE_EMERGENCY_ONLY ||
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        resultState == ServiceState.STATE_POWER_OFF) {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    resultState = serviceState;
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (resultState == ServiceState.STATE_POWER_OFF) {
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    resultState = serviceState;
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return resultState;
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register phone to CallManager
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phone to be registered
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if register successfully
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean registerPhone(Phone phone) {
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone basePhone = getPhoneBase(phone);
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (basePhone != null && !mPhones.contains(basePhone)) {
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d(LOG_TAG, "registerPhone(" +
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        phone.getPhoneName() + " " + phone + ")");
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPhones.isEmpty()) {
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mDefaultPhone = basePhone;
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhones.add(basePhone);
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRingingCalls.add(basePhone.getRingingCall());
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mBackgroundCalls.add(basePhone.getBackgroundCall());
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mForegroundCalls.add(basePhone.getForegroundCall());
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            registerForPhoneStates(basePhone);
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * unregister phone from CallManager
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phone to be unregistered
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterPhone(Phone phone) {
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone basePhone = getPhoneBase(phone);
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (basePhone != null && mPhones.contains(basePhone)) {
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d(LOG_TAG, "unregisterPhone(" +
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        phone.getPhoneName() + " " + phone + ")");
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mPhones.remove(basePhone);
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRingingCalls.remove(basePhone.getRingingCall());
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mBackgroundCalls.remove(basePhone.getBackgroundCall());
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mForegroundCalls.remove(basePhone.getForegroundCall());
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            unregisterForPhoneStates(basePhone);
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (basePhone == mDefaultPhone) {
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mPhones.isEmpty()) {
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDefaultPhone = null;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDefaultPhone = mPhones.get(0);
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return the default phone or null if no phone available
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Phone getDefaultPhone() {
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDefaultPhone;
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the phone associated with the foreground call
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Phone getFgPhone() {
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return getActiveFgCall().getPhone();
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the phone associated with the background call
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Phone getBgPhone() {
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return getFirstActiveBgCall().getPhone();
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the phone associated with the ringing call
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Phone getRingingPhone() {
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return getFirstActiveRingingCall().getPhone();
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void setAudioMode() {
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Context context = getContext();
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (context == null) return;
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AudioManager audioManager = (AudioManager)
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                context.getSystemService(Context.AUDIO_SERVICE);
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // change the audio mode and request/abandon audio focus according to phone state,
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // but only on audio mode transitions
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (getState()) {
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RINGING:
382f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                int curAudioMode = audioManager.getMode();
383f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                if (curAudioMode != AudioManager.MODE_RINGTONE) {
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // only request audio focus if the ringtone is going to be heard
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
390f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                    if(!mSpeedUpAudioForMtCall) {
391f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                        audioManager.setMode(AudioManager.MODE_RINGTONE);
392f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                    }
393f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                }
394f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka
395f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                if (mSpeedUpAudioForMtCall && (curAudioMode != AudioManager.MODE_IN_CALL)) {
396f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                    audioManager.setMode(AudioManager.MODE_IN_CALL);
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case OFFHOOK:
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Phone offhookPhone = getFgPhone();
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getActiveFgCallState() == Call.State.IDLE) {
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // There is no active Fg calls, the OFFHOOK state
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // is set by the Bg call. So set the phone to bgPhone.
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    offhookPhone = getBgPhone();
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int newAudioMode = AudioManager.MODE_IN_CALL;
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (offhookPhone instanceof SipPhone) {
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable IN_COMMUNICATION audio mode instead for sipPhone
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
412f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                if (audioManager.getMode() != newAudioMode || mSpeedUpAudioForMtCall) {
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // request audio focus before setting the new mode
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    audioManager.setMode(newAudioMode);
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
419f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                mSpeedUpAudioForMtCall = false;
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case IDLE:
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    audioManager.setMode(AudioManager.MODE_NORMAL);
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // abandon audio focus after the mode has been set back to normal
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    audioManager.abandonAudioFocusForCall();
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
428f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                mSpeedUpAudioForMtCall = false;
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Context getContext() {
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone defaultPhone = getDefaultPhone();
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ((defaultPhone == null) ? null : defaultPhone.getContext());
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void registerForPhoneStates(Phone phone) {
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // for common events supported by all phones
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null);
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null);
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null);
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null);
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null);
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null);
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null);
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null);
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null);
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null);
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // for events supported only by GSM and CDMA phone
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM ||
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null);
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // for events supported only by CDMA phone
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ){
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null);
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null);
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null);
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void unregisterForPhoneStates(Phone phone) {
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //  for common events supported by all phones
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForPreciseCallStateChanged(mHandler);
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForDisconnect(mHandler);
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForNewRingingConnection(mHandler);
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForUnknownConnection(mHandler);
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForIncomingRing(mHandler);
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForRingbackTone(mHandler);
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForInCallVoicePrivacyOn(mHandler);
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForInCallVoicePrivacyOff(mHandler);
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForDisplayInfo(mHandler);
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForSignalInfo(mHandler);
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForResendIncallMute(mHandler);
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForMmiInitiate(mHandler);
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForMmiComplete(mHandler);
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForSuppServiceFailed(mHandler);
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.unregisterForServiceStateChanged(mHandler);
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // for events supported only by GSM and CDMA phone
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM ||
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null);
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // for events supported only by CDMA phone
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ){
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.unregisterForCdmaOtaStatusChange(mHandler);
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.unregisterForSubscriptionInfoReady(mHandler);
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.unregisterForCallWaiting(mHandler);
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.unregisterForEcmTimerReset(mHandler);
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Answers a ringing or waiting call.
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Active call, if any, go on hold.
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If active call can't be held, i.e., a background call of the same channel exists,
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * the active call will be hang up.
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Answering occurs asynchronously, and final notification occurs via
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}.
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException when call is not ringing or waiting
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void acceptCall(Call ringingCall) throws CallStateException {
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone ringingPhone = ringingCall.getPhone();
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( hasActiveFgCall() ) {
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Phone activePhone = getActiveFgCall().getPhone();
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean sameChannel = (activePhone == ringingPhone);
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (VDBG) {
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (sameChannel && hasBgCall) {
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                getActiveFgCall().hangup();
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!sameChannel && !hasBgCall) {
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                activePhone.switchHoldingAndActive();
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!sameChannel && hasBgCall) {
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                getActiveFgCall().hangup();
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
543f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka        Context context = getContext();
544f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka        if (context == null) {
545f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            Log.d(LOG_TAG, "Speedup Audio Path enhancement: Context is null");
546f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka        } else if (context.getResources().getBoolean(
547f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                com.android.internal.R.bool.config_speed_up_audio_on_mt_calls)) {
548f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            Log.d(LOG_TAG, "Speedup Audio Path enhancement");
549f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            AudioManager audioManager = (AudioManager)
550f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                    context.getSystemService(Context.AUDIO_SERVICE);
551f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            int currMode = audioManager.getMode();
552f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            if ((currMode != AudioManager.MODE_IN_CALL) && !(ringingPhone instanceof SipPhone)) {
553f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                Log.d(LOG_TAG, "setAudioMode Setting audio mode from " +
554f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                                currMode + " to " + AudioManager.MODE_IN_CALL);
555f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                audioManager.setMode(AudioManager.MODE_IN_CALL);
556f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka                mSpeedUpAudioForMtCall = true;
557f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka            }
558f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka        }
559f2a22db80d9921fae213c763f08f2800d30b5cd3Alex Yakavenka
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ringingPhone.acceptCall();
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Reject (ignore) a ringing call. In GSM, this means UDUB
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * (User Determined User Busy). Reject occurs asynchronously,
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and final notification occurs via
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}.
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException when no call is ringing or waiting
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void rejectCall(Call ringingCall) throws CallStateException {
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone ringingPhone = ringingCall.getPhone();
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ringingPhone.rejectCall();
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Places active call on hold, and makes held call active.
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Switch occurs asynchronously and may fail.
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * There are 4 scenarios
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 1. only active call but no held call, aka, hold
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 2. no active call but only held call, aka, unhold
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 3. both active and held calls from same phone, aka, swap
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 4. active and held calls from different phones, aka, phone swap
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Final notification occurs via
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}.
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException if active call is ringing, waiting, or
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * dialing/alerting, or heldCall can't be active.
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * In these cases, this operation may not be performed.
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void switchHoldingAndActive(Call heldCall) throws CallStateException {
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone activePhone = null;
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone heldPhone = null;
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            activePhone = getActiveFgCall().getPhone();
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (heldCall != null) {
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            heldPhone = heldCall.getPhone();
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (activePhone != null) {
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            activePhone.switchHoldingAndActive();
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (heldPhone != null && heldPhone != activePhone) {
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            heldPhone.switchHoldingAndActive();
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hangup foreground call and resume the specific background call
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Note: this is noop if there is no foreground call or the heldCall is null
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param heldCall to become foreground
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @throws CallStateException
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone foregroundPhone = null;
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone backgroundPhone = null;
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            foregroundPhone = getFgPhone();
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (heldCall != null) {
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                backgroundPhone = heldCall.getPhone();
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (foregroundPhone == backgroundPhone) {
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    getActiveFgCall().hangup();
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // the call to be hangup and resumed belongs to different phones
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    getActiveFgCall().hangup();
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    switchHoldingAndActive(heldCall);
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Whether or not the phone can conference in the current phone
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * state--that is, one call holding and one call active.
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the phone can conference; false otherwise.
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean canConference(Call heldCall) {
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone activePhone = null;
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone heldPhone = null;
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            activePhone = getActiveFgCall().getPhone();
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (heldCall != null) {
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            heldPhone = heldCall.getPhone();
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return heldPhone.getClass().equals(activePhone.getClass());
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Conferences holding and active. Conference occurs asynchronously
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and may fail. Final notification occurs via
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}.
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException if canConference() would return false.
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * In these cases, this operation may not be performed.
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void conference(Call heldCall) throws CallStateException {
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "conference(" +heldCall + ")");
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone fgPhone = getFgPhone();
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (fgPhone instanceof SipPhone) {
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ((SipPhone) fgPhone).conference(heldCall);
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (canConference(heldCall)) {
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            fgPhone.conference();
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw(new CallStateException("Can't conference foreground and selected background call"));
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End conference(" +heldCall + ")");
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Initiate a new voice connection. This happens asynchronously, so you
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * cannot assume the audio path is connected (or a call index has been
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * assigned) until PhoneStateChanged notification has occurred.
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException if a new outgoing call is not currently
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * possible because no more call slots exist or a call exists that is
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * dialing, alerting, ringing, or waiting.  Other errors are
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handled asynchronously.
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Connection dial(Phone phone, String dialString) throws CallStateException {
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone basePhone = getPhoneBase(phone);
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection result;
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial(phone)) {
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( hasActiveFgCall() ) {
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Phone activePhone = getActiveFgCall().getPhone();
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (activePhone != basePhone) {
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (hasBgCall) {
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.d(LOG_TAG, "Hangup");
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    getActiveFgCall().hangup();
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.d(LOG_TAG, "Switch");
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    activePhone.switchHoldingAndActive();
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        result = basePhone.dial(dialString);
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Initiate a new voice connection. This happens asynchronously, so you
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * cannot assume the audio path is connected (or a call index has been
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * assigned) until PhoneStateChanged notification has occurred.
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException if a new outgoing call is not currently
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * possible because no more call slots exist or a call exists that is
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * dialing, alerting, ringing, or waiting.  Other errors are
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handled asynchronously.
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return phone.dial(dialString, uusInfo);
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clear disconnect connection for each phone
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void clearDisconnected() {
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for(Phone phone : mPhones) {
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.clearDisconnected();
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Phone can make a call only if ALL of the following are true:
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        - Phone is not powered off
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        - There's no incoming or waiting call
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        - There's available call slot in either foreground or background
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        - The foreground call is ACTIVE or IDLE or DISCONNECTED.
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *          (We mainly need to make sure it *isn't* DIALING or ALERTING.)
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phone
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the phone can make a new call
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean canDial(Phone phone) {
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int serviceState = phone.getServiceState().getState();
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRingingCall = hasActiveRingingCall();
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasActiveCall = hasActiveFgCall();
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasHoldingCall = hasActiveBgCall();
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean allLinesTaken = hasActiveCall && hasHoldingCall;
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call.State fgCallState = getActiveFgCallState();
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean result = (serviceState != ServiceState.STATE_POWER_OFF
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !hasRingingCall
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !allLinesTaken
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && ((fgCallState == Call.State.ACTIVE)
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || (fgCallState == Call.State.IDLE)
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || (fgCallState == Call.State.DISCONNECTED)));
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (result == false) {
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " hasRingingCall=" + hasRingingCall
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " hasActiveCall=" + hasActiveCall
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " hasHoldingCall=" + hasHoldingCall
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " allLinesTaken=" + allLinesTaken
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " fgCallState=" + fgCallState);
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Whether or not the phone can do explicit call transfer in the current
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * phone state--that is, one call holding and one call active.
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the phone can do explicit call transfer; false otherwise.
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean canTransfer(Call heldCall) {
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone activePhone = null;
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Phone heldPhone = null;
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            activePhone = getActiveFgCall().getPhone();
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (heldCall != null) {
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            heldPhone = heldCall.getPhone();
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (heldPhone == activePhone && activePhone.canTransfer());
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Connects the held call and active call
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Disconnects the subscriber from both calls
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Explicit Call Transfer occurs asynchronously
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and may fail. Final notification occurs via
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}.
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @exception CallStateException if canTransfer() would return false.
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * In these cases, this operation may not be performed.
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void explicitCallTransfer(Call heldCall) throws CallStateException {
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (canTransfer(heldCall)) {
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            heldCall.getPhone().explicitCallTransfer();
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a list of MMI codes that are pending for a phone. (They have initiated
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * but have not yet completed).
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Presently there is only ever one.
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Use <code>registerForMmiInitiate</code>
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and <code>registerForMmiComplete</code> for change notification.
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return null if phone doesn't have or support mmi code
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sends user response to a USSD REQUEST message.  An MmiCode instance
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * representing this response is sent to handlers registered with
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * registerForMmiInitiate.
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ussdMessge    Message to send in the response.
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if phone doesn't support ussd service
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean sendUssdResponse(Phone phone, String ussdMessge) {
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "sendUssdResponse not implemented");
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mutes or unmutes the microphone for the active call. The microphone
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * is automatically unmuted if a call is answered, dialed, or resumed
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from a holding state.
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param muted true to mute the microphone,
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * false to activate the microphone.
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void setMute(boolean muted) {
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " setMute(" + muted + ")");
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            getActiveFgCall().getPhone().setMute(muted);
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End setMute(" + muted + ")");
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Gets current mute status. Use
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * java.lang.Object) registerForPreciseCallStateChanged()}
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * as a change notifcation, although presently phone state changed is not
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * fired when setMute() is called.
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true is muting, false is unmuting
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getMute() {
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return getActiveFgCall().getPhone().getMute();
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (hasActiveBgCall()) {
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return getFirstActiveBgCall().getPhone().getMute();
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Enables or disables echo suppression.
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void setEchoSuppressionEnabled(boolean enabled) {
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Play a DTMF tone on the active call.
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param c should be one of 0-9, '*' or '#'. Other values will be
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * silently ignored.
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if no active call or the active call doesn't support
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         dtmf tone
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean sendDtmf(char c) {
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean result = false;
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " sendDtmf(" + c + ")");
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            getActiveFgCall().getPhone().sendDtmf(c);
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = true;
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Start to paly a DTMF tone on the active call.
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or there is a playing DTMF tone.
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param c should be one of 0-9, '*' or '#'. Other values will be
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * silently ignored.
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if no active call or the active call doesn't support
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         dtmf tone
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean startDtmf(char c) {
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean result = false;
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " startDtmf(" + c + ")");
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            getActiveFgCall().getPhone().startDtmf(c);
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = true;
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End startDtmf(" + c + ")");
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * tone or no active call.
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void stopDtmf() {
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, " stopDtmf()" );
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) getFgPhone().stopDtmf();
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (VDBG) {
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, "End stopDtmf()");
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG, this.toString());
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * send burst DTMF tone, it can send the string as single character or multiple character
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * ignore if there is no active call or not valid digits string.
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this api can send single character and multiple character, also, this api has response
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * back to caller.
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param dtmfString is string representing the dialing digit(s) in the active call
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param on the DTMF ON length in milliseconds, or 0 for default
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param off the DTMF OFF length in milliseconds, or 0 for default
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is the callback message when the action is processed by BP
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActiveFgCall()) {
10730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Notifies when a voice connection has disconnected, either due to local
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or remote hangup or error.
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Messages received from this will have the following members:<p>
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <ul><li>Message.obj will be an AsyncResult</li>
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <li>AsyncResult.userObj = obj</li>
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <li>AsyncResult.result = a Connection object that is
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  no longer connected.</li></ul>
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDisconnect(Handler h, int what, Object obj) {
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDisconnectRegistrants.addUnique(h, what, obj);
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for voice disconnection notification.
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDisconnect(Handler h){
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDisconnectRegistrants.remove(h);
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for getting notifications for change in the Call State {@link Call.State}
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is called PreciseCallState because the call state is more precise than the
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * AsyncResult.userData will be set to the obj argument here.
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The <em>h</em> parameter is held only by a weak reference.
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPreciseCallStateRegistrants.addUnique(h, what, obj);
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for voice call state change notifications.
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently.
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPreciseCallStateChanged(Handler h){
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPreciseCallStateRegistrants.remove(h);
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is likely due to some other entity (eg, SIM card application) initiating a call.
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForUnknownConnection(Handler h, int what, Object obj){
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mUnknownConnectionRegistrants.addUnique(h, what, obj);
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for unknown connection notifications.
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForUnknownConnection(Handler h){
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mUnknownConnectionRegistrants.remove(h);
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Notifies when a new ringing or waiting connection has appeared.<p>
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Messages received from this:
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Message.obj will be an AsyncResult
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.userObj = obj
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.result = a Connection. <p>
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Please check Connection.isRinging() to make sure the Connection
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  has not dropped since this message was posted.
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  If Connection.isRinging() is true, then
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   Connection.getCall() == Phone.getRingingCall()
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNewRingingConnection(Handler h, int what, Object obj){
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for new ringing connection notification.
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNewRingingConnection(Handler h){
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNewRingingConnectionRegistrants.remove(h);
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Notifies when an incoming call rings.<p>
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Messages received from this:
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Message.obj will be an AsyncResult
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.userObj = obj
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.result = a Connection. <p>
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForIncomingRing(Handler h, int what, Object obj){
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIncomingRingRegistrants.addUnique(h, what, obj);
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for ring notification.
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForIncomingRing(Handler h){
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mIncomingRingRegistrants.remove(h);
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Notifies when out-band ringback tone is needed.<p>
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Messages received from this:
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Message.obj will be an AsyncResult
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.userObj = obj
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  AsyncResult.result = boolean, true to start play ringback tone
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *                       and false to stop. <p>
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForRingbackTone(Handler h, int what, Object obj){
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRingbackToneRegistrants.addUnique(h, what, obj);
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for ringback tone notification.
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForRingbackTone(Handler h){
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRingbackToneRegistrants.remove(h);
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registers the handler to reset the uplink mute state to get
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * uplink audio.
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForResendIncallMute(Handler h, int what, Object obj){
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mResendIncallMuteRegistrants.addUnique(h, what, obj);
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for resend incall mute notifications.
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForResendIncallMute(Handler h){
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mResendIncallMuteRegistrants.remove(h);
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications of initiation of a new MMI code request.
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Example: If Phone.dial is called with "*#31#", then the app will
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * be notified here.<p>
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The returned <code>Message.obj</code> will contain an AsyncResult.
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * <code>obj.result</code> will be an "MmiCode" object.
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForMmiInitiate(Handler h, int what, Object obj){
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMmiInitiateRegistrants.addUnique(h, what, obj);
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for new MMI initiate notification.
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForMmiInitiate(Handler h){
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMmiInitiateRegistrants.remove(h);
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications that an MMI request has completed
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * its network activity and is in its final state. This may mean a state
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * of COMPLETE, FAILED, or CANCELLED.
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * <code>Message.obj</code> will contain an AsyncResult.
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * <code>obj.result</code> will be an "MmiCode" object
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForMmiComplete(Handler h, int what, Object obj){
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMmiCompleteRegistrants.addUnique(h, what, obj);
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for MMI complete notification.
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForMmiComplete(Handler h){
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMmiCompleteRegistrants.remove(h);
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for Ecm timer reset
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what user-defined message code
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForEcmTimerReset(Handler h, int what, Object obj){
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mEcmTimerResetRegistrants.addUnique(h, what, obj);
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notification for Ecm timer reset
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForEcmTimerReset(Handler h){
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mEcmTimerResetRegistrants.remove(h);
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for ServiceState changed.
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Message.obj will contain an AsyncResult.
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * AsyncResult.result will be a ServiceState instance
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForServiceStateChanged(Handler h, int what, Object obj){
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mServiceStateChangedRegistrants.addUnique(h, what, obj);
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for ServiceStateChange notification.
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForServiceStateChanged(Handler h){
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mServiceStateChangedRegistrants.remove(h);
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications when a supplementary service attempt fails.
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Message.obj will contain an AsyncResult.
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForSuppServiceFailed(Handler h, int what, Object obj){
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications when a supplementary service attempt fails.
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForSuppServiceFailed(Handler h){
13170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSuppServiceFailedRegistrants.remove(h);
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications when a sInCall VoicePrivacy is enabled
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
13260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj);
13290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications when a sInCall VoicePrivacy is enabled
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
13350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForInCallVoicePrivacyOn(Handler h){
13370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mInCallVoicePrivacyOnRegistrants.remove(h);
13380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications when a sInCall VoicePrivacy is disabled
13420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
13440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
13450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
13460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
13480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj);
13490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications when a sInCall VoicePrivacy is disabled
13530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
13550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForInCallVoicePrivacyOff(Handler h){
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mInCallVoicePrivacyOffRegistrants.remove(h);
13580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications when CDMA call waiting comes
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj){
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCallWaitingRegistrants.addUnique(h, what, obj);
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications when CDMA Call waiting comes
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForCallWaiting(Handler h){
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCallWaitingRegistrants.remove(h);
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for signal information notifications from the network.
13820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Message.obj will contain an AsyncResult.
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * AsyncResult.result will be a SuppServiceNotification instance.
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
13860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
13870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
13880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForSignalInfo(Handler h, int what, Object obj){
13910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSignalInfoRegistrants.addUnique(h, what, obj);
13920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for signal information notifications.
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
13970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
13990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForSignalInfo(Handler h){
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSignalInfoRegistrants.remove(h);
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for display information notifications from the network.
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Message.obj will contain an AsyncResult.
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * AsyncResult.result will be a SuppServiceNotification instance.
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
14120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDisplayInfo(Handler h, int what, Object obj){
14140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDisplayInfoRegistrants.addUnique(h, what, obj);
14150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for display information notifications.
14190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Extraneous calls are tolerated silently
14200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
14220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDisplayInfo(Handler h) {
14240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDisplayInfoRegistrants.remove(h);
14250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Register for notifications when CDMA OTA Provision status change
14290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler that receives the notification message.
14310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what User-defined message code.
14320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj User object.
14330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj);
14360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications when CDMA OTA Provision status change
14400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
14410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForCdmaOtaStatusChange(Handler h){
14430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCdmaOtaStatusChangeRegistrants.remove(h);
14440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for subscription info ready
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
14490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
14500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
14510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){
14530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj);
14540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregister for notifications for subscription info
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h Handler to be removed from the registrant list.
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForSubscriptionInfoReady(Handler h){
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSubscriptionInfoReadyRegistrants.remove(h);
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sets an event to be fired when the telephony system processes
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * a post-dial character on an outgoing call.<p>
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Messages of type <code>what</code> will be sent to <code>h</code>.
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The <code>obj</code> field of these Message's will be instances of
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * a Connection object.<p>
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Message.arg1 will be the post dial character being processed,
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or 0 ('\0') if end of string.<p>
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If Connection.getPostDialState() == WAIT,
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * the application must call
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Connection.proceedAfterWaitChar()} or
14800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link com.android.internal.telephony.Connection#cancelPostDial()
14810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Connection.cancelPostDial()}
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * for the telephony system to continue playing the post-dial
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * DTMF sequence.<p>
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If Connection.getPostDialState() == WILD,
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * the application must call
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Connection.proceedAfterWildChar()}
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * {@link com.android.internal.telephony.Connection#cancelPostDial()
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Connection.cancelPostDial()}
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * for the telephony system to continue playing the
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * post-dial DTMF sequence.<p>
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPostDialCharacter(Handler h, int what, Object obj){
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPostDialCharacterRegistrants.addUnique(h, what, obj);
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPostDialCharacter(Handler h){
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPostDialCharacterRegistrants.remove(h);
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 1. APIs to access list of calls
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 2. APIs to check if any active call, which has connection other than
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * disconnected ones, pleaser refer to Call.isIdle()
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 3. APIs to return first active call
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 4. APIs to return the connections of first active call
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 5. APIs to return other property of first active call
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return list of all ringing calls
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Call> getRingingCalls() {
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Collections.unmodifiableList(mRingingCalls);
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return list of all foreground calls
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Call> getForegroundCalls() {
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Collections.unmodifiableList(mForegroundCalls);
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return list of all background calls
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Call> getBackgroundCalls() {
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Collections.unmodifiableList(mBackgroundCalls);
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if there is at least one active foreground call
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasActiveFgCall() {
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getFirstActiveCall(mForegroundCalls) != null);
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if there is at least one active background call
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasActiveBgCall() {
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO since hasActiveBgCall may get called often
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // better to cache it to improve performance
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getFirstActiveCall(mBackgroundCalls) != null);
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if there is at least one active ringing call
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasActiveRingingCall() {
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getFirstActiveCall(mRingingCalls) != null);
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return the active foreground call from foreground calls
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Active call means the call is NOT in Call.State.IDLE
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 1. If there is active foreground call, return it
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 2. If there is no active foreground call, return the
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *    foreground call associated with default phone, which state is IDLE.
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 3. If there is no phone registered at all, return null.
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Call getActiveFgCall() {
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call call = getFirstNonIdleCall(mForegroundCalls);
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call == null) {
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            call = (mDefaultPhone == null)
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ? null
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    : mDefaultPhone.getForegroundCall();
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return call;
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Returns the first call that is not in IDLE state. If both active calls
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // and disconnecting/disconnected calls exist, return the first active call.
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Call getFirstNonIdleCall(List<Call> calls) {
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call result = null;
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Call call : calls) {
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!call.isIdle()) {
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return call;
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (call.getState() != Call.State.IDLE) {
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (result == null) result = call;
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return result;
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return one active background call from background calls
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Active call means the call is NOT idle defined by Call.isIdle()
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 1. If there is only one active background call, return it
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 2. If there is more than one active background call, return the first one
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 3. If there is no active background call, return the background call
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *    associated with default phone, which state is IDLE.
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 4. If there is no background call at all, return null.
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Complete background calls list can be get by getBackgroundCalls()
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Call getFirstActiveBgCall() {
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call call = getFirstNonIdleCall(mBackgroundCalls);
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call == null) {
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            call = (mDefaultPhone == null)
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ? null
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    : mDefaultPhone.getBackgroundCall();
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return call;
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return one active ringing call from ringing calls
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Active call means the call is NOT idle defined by Call.isIdle()
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 1. If there is only one active ringing call, return it
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 2. If there is more than one active ringing call, return the first one
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 3. If there is no active ringing call, return the ringing call
16240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *    associated with default phone, which state is IDLE.
16250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * 4. If there is no ringing call at all, return null.
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Complete ringing calls list can be get by getRingingCalls()
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Call getFirstActiveRingingCall() {
16300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call call = getFirstNonIdleCall(mRingingCalls);
16310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call == null) {
16320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            call = (mDefaultPhone == null)
16330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ? null
16340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    : mDefaultPhone.getRingingCall();
16350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return call;
16370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the state of active foreground call
16410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return IDLE if there is no active foreground call
16420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Call.State getActiveFgCallState() {
16440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call fgCall = getActiveFgCall();
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (fgCall != null) {
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return fgCall.getState();
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Call.State.IDLE;
16510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the connections of active foreground call
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return empty list if there is no active foreground call
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Connection> getFgCallConnections() {
16580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call fgCall = getActiveFgCall();
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( fgCall != null) {
16600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return fgCall.getConnections();
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return emptyConnections;
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the connections of active background call
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return empty list if there is no active background call
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<Connection> getBgCallConnections() {
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call bgCall = getFirstActiveBgCall();
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( bgCall != null) {
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return bgCall.getConnections();
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return emptyConnections;
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the latest connection of active foreground call
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return null if there is no active foreground call
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public Connection getFgCallLatestConnection() {
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call fgCall = getActiveFgCall();
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ( fgCall != null) {
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return fgCall.getLatestConnection();
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if there is at least one Foreground call in disconnected state
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasDisconnectedFgCall() {
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if there is at least one background call in disconnected state
16980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasDisconnectedBgCall() {
17000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
17010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
17040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the first active call from a call list
17050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
17060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private  Call getFirstActiveCall(ArrayList<Call> calls) {
17070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Call call : calls) {
17080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!call.isIdle()) {
17090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return call;
17100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
17130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
17160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the first call in a the Call.state from a call list
17170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
17180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
17190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Call call : calls) {
17200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.getState() == state) {
17210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return call;
17220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
17250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean hasMoreThanOneRingingCall() {
17290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = 0;
17300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Call call : mRingingCalls) {
17310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.getState().isRinging()) {
17320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (++count > 1) return true;
17330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
17340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
17360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Handler mHandler = new Handler() {
17390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
17410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void handleMessage(Message msg) {
17420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (msg.what) {
17440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_DISCONNECT:
17450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
17460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_PRECISE_CALL_STATE_CHANGED:
17490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
17500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_NEW_RINGING_CONNECTION:
17530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
17540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
17550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Connection c = (Connection) ((AsyncResult) msg.obj).result;
17560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
17570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
17580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            c.getCall().hangup();
17590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException e) {
17600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Log.w(LOG_TAG, "new ringing connection", e);
17610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
17620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
17630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
17650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_UNKNOWN_CONNECTION:
17670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
17680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_INCOMING_RING:
17710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
17720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // The event may come from RIL who's not aware of an ongoing fg call
17730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (!hasActiveFgCall()) {
17740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
17760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_RINGBACK_TONE:
17780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
17790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_IN_CALL_VOICE_PRIVACY_ON:
17820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
17830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
17860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
17870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_CALL_WAITING:
17900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
17910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_DISPLAY_INFO:
17940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
17950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
17960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
17970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_SIGNAL_INFO:
17980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
17990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_CDMA_OTA_STATUS_CHANGE:
18020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
18030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_RESEND_INCALL_MUTE:
18060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
18070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_MMI_INITIATE:
18100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
18110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_MMI_COMPLETE:
18140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
18150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_ECM_TIMER_RESET:
18180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
18190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_SUBSCRIPTION_INFO_READY:
18220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
18230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_SUPP_SERVICE_FAILED:
18260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
18270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_SERVICE_STATE_CHANGED:
18300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
18310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
18320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_POST_DIAL_CHARACTER:
18340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // we need send the character that is being processed in msg.arg1
18350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // so can't use notifyRegistrants()
18360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
18370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
18380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Message notifyMsg;
18390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
18400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        notifyMsg.obj = msg.obj;
18410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        notifyMsg.arg1 = msg.arg1;
18420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        notifyMsg.sendToTarget();
18430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
18440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
18450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
18480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String toString() {
18510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Call call;
18520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder b = new StringBuilder();
18530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("CallManager {");
18550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\nstate = " + getState());
18560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call = getActiveFgCall();
18570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n- Foreground: " + getActiveFgCallState());
18580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append(" from " + call.getPhone());
18590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n  Conn: ").append(getFgCallConnections());
18600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call = getFirstActiveBgCall();
18610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n- Background: " + call.getState());
18620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append(" from " + call.getPhone());
18630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n  Conn: ").append(getBgCallConnections());
18640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call = getFirstActiveRingingCall();
18650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n- Ringing: " +call.getState());
18660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append(" from " + call.getPhone());
18670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Phone phone : getAllPhones()) {
18690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (phone != null) {
18700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
18710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + ", state = " + phone.getState());
18720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                call = phone.getForegroundCall();
18730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                b.append("\n- Foreground: ").append(call);
18740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                call = phone.getBackgroundCall();
18750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                b.append(" Background: ").append(call);
18760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                call = phone.getRingingCall();
18770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                b.append(" Ringing: ").append(call);
18780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
18790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
18800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b.append("\n}");
18810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return b.toString();
18820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1884