ImsPhoneCallTracker.java revision 75ba09a17a669f4906268088a769836aa87d8241
1a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/*
2a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Copyright (C) 2013 The Android Open Source Project
3a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
4a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * you may not use this file except in compliance with the License.
6a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * You may obtain a copy of the License at
7a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
8a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
10a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Unless required by applicable law or agreed to in writing, software
11a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * See the License for the specific language governing permissions and
14a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * limitations under the License.
15a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
16a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
17a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepackage com.android.internal.telephony.imsphone;
18a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.io.FileDescriptor;
2004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.io.PrintWriter;
2104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.util.ArrayList;
2204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.util.List;
2304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
24a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.app.PendingIntent;
25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.BroadcastReceiver;
26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Context;
27a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Intent;
28a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.IntentFilter;
29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.SharedPreferences;
30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.AsyncResult;
31df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordonimport android.os.Bundle;
32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Message;
34d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunnimport android.os.PersistableBundle;
35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Registrant;
36a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
37ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport android.os.RemoteException;
38a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.SystemProperties;
39b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganeshimport android.provider.Settings;
40d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunnimport android.telephony.CarrierConfigManager;
41d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunnimport android.text.TextUtils;
42a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.preference.PreferenceManager;
43fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunnimport android.telecom.ConferenceParticipant;
44dc2b5d1c32cad5269106d00fd106bd64097238f4Tyler Gunnimport android.telecom.VideoProfile;
45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.DisconnectCause;
46a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.PhoneNumberUtils;
47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog;
4804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport android.telephony.ServiceState;
498560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunnimport android.telephony.SubscriptionManager;
50a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCall;
5204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCallProfile;
53cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.comimport com.android.ims.ImsConfig;
549746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiakimport com.android.ims.ImsConfigListener;
5504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsConnectionStateListener;
5604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsEcbm;
5704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsException;
5804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsManager;
5904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsReasonInfo;
6004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsServiceClass;
6108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport com.android.ims.ImsSuppServiceNotification;
6204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsUtInterface;
63ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.IImsVideoCallProvider;
64ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.ImsVideoCallProviderWrapper;
65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Call;
66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallStateException;
67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallTracker;
68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandException;
69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandsInterface;
70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Connection;
71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone;
72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants;
735054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiakimport com.android.internal.telephony.TelephonyEventLog;
74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.TelephonyProperties;
7508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport com.android.internal.telephony.gsm.SuppServiceNotification;
76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/**
78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * {@hide}
79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
80f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxupublic class ImsPhoneCallTracker extends CallTracker {
81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final String LOG_TAG = "ImsPhoneCallTracker";
82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final boolean DBG = true;
84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
85707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // When true, dumps the state of ImsPhoneCallTracker after changes to foreground and background
86707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // calls.  This is helpful for debugging.
87707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private static final boolean VERBOSE_STATE_LOGGING = false; /* stopship if true */
88707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
89915b8a421c34b0872c96199d4390a70d5a76ed98Nathan Harold    //Indices map to ImsConfig.FeatureConstants
90164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    private boolean[] mImsFeatureEnabled = {false, false, false, false, false, false};
91164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    private final String[] mImsFeatureStrings = {"VoLTE", "ViLTE", "VoWiFi", "ViWiFi",
92164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati            "UTLTE", "UTWiFi"};
93cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
945054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak    private TelephonyEventLog mEventLog;
955054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak
96a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onReceive(Context context, Intent intent) {
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (intent.getAction().equals(ImsManager.ACTION_IMS_INCOMING_CALL)) {
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (DBG) log("onReceive : incoming call intent");
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mImsManager == null) return;
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mServiceId < 0) return;
105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // Network initiated USSD will be treated by mImsUssdListener
108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    boolean isUssd = intent.getBooleanExtra(ImsManager.EXTRA_USSD, false);
109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (isUssd) {
110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (DBG) log("onReceive : USSD");
111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mUssdSession = mImsManager.takeCall(mServiceId, intent, mImsUssdListener);
112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mUssdSession != null) {
1132999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                            mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        return;
116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
11808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    boolean isUnknown = intent.getBooleanExtra(ImsManager.EXTRA_IS_UNKNOWN_CALL,
11908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            false);
12008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    if (DBG) {
12108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        log("onReceive : isUnknown = " + isUnknown +
12208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                " fg = " + mForegroundCall.getState() +
12308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                " bg = " + mBackgroundCall.getState());
12408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    }
12508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
12608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    // Normal MT/Unknown call
127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCall imsCall = mImsManager.takeCall(mServiceId, intent, mImsCallListener);
1286bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius                    ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall,
12908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            ImsPhoneCallTracker.this,
13008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            (isUnknown? mForegroundCall: mRingingCall), isUnknown);
131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    addConnection(conn);
132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
133288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    setVideoCallProvider(conn, imsCall);
134ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
1355054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallReceive(imsCall.getSession());
1365054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak
13708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    if (isUnknown) {
13808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyUnknownConnection(conn);
13908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    } else {
14008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) ||
14108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE)) {
14208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            conn.update(imsCall, ImsPhoneCall.State.WAITING);
14308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        }
144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
14508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyNewRingingConnection(conn);
14608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyIncomingRing();
14708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    }
148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    updatePhoneState();
150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.notifyPreciseCallStateChanged();
151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (ImsException e) {
152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    loge("onReceive : exception " + e);
153ea8cb63201520592011a92849ad3661d22776c87Andrew Lee                } catch (RemoteException e) {
154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1558560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            } else if (intent.getAction().equals(
1568560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                    CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
1578560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1588560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1598560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                if (subId == mPhone.getSubId()) {
1608560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                    mAllowEmergencyVideoCalls = isEmergencyVtCallAllowed(subId);
1618560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                    log("onReceive : Updating mAllowEmergencyVideoCalls = " +
1628560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                            mAllowEmergencyVideoCalls);
1638560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                }
164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constants
169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS = 7;
171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS_PER_CALL = 5;
172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_HANGUP_PENDINGMO = 18;
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_RESUME_BACKGROUND = 19;
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_DIAL_PENDINGMO = 20;
176e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    private static final int EVENT_EXIT_ECBM_BEFORE_PENDINGMO = 21;
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Variables
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>();
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
18575ba09a17a669f4906268088a769836aa87d8241fionaxu    public final ImsPhoneCall mRingingCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_RINGING);
18675ba09a17a669f4906268088a769836aa87d8241fionaxu    public final ImsPhoneCall mForegroundCall = new ImsPhoneCall(this,
18775ba09a17a669f4906268088a769836aa87d8241fionaxu            ImsPhoneCall.CONTEXT_FOREGROUND);
18875ba09a17a669f4906268088a769836aa87d8241fionaxu    public final ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this,
18975ba09a17a669f4906268088a769836aa87d8241fionaxu            ImsPhoneCall.CONTEXT_BACKGROUND);
19075ba09a17a669f4906268088a769836aa87d8241fionaxu    public final ImsPhoneCall mHandoverCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_HANDOVER);
191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsPhoneConnection mPendingMO;
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mClirMode = CommandsInterface.CLIR_DEFAULT;
194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Object mSyncHold = new Object();
195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall mUssdSession = null;
197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Message mPendingUssd = null;
198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhone mPhone;
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mDesiredMute = false;    // false = mute off
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mOnHoldToneStarted = false;
203ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn    private int mOnHoldToneId = -1;
204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsManager mImsManager;
208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mServiceId = -1;
209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Call.SrvccState mSrvccState = Call.SrvccState.NONE;
211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
21204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean mIsInEmergencyCall = false;
21304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
21404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private int pendingCallClirMode;
215288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private int mPendingCallVideoState;
216c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn    private Bundle mPendingIntentExtras;
21704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean pendingCallInEcm = false;
218276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private boolean mSwitchingFgAndBgCalls = false;
219276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private ImsCall mCallExpectedToResume = null;
2208560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn    private boolean mAllowEmergencyVideoCalls = false;
22104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Events
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constructors
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
22775ba09a17a669f4906268088a769836aa87d8241fionaxu    public ImsPhoneCallTracker(ImsPhone phone) {
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        this.mPhone = phone;
229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2305054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak        mEventLog = TelephonyEventLog.getInstance(mPhone.getContext(), mPhone.getPhoneId());
2315054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IntentFilter intentfilter = new IntentFilter();
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);
2348560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().registerReceiver(mReceiver, intentfilter);
2368560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        mAllowEmergencyVideoCalls = isEmergencyVtCallAllowed(mPhone.getSubId());
237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Thread t = new Thread() {
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            public void run() {
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                getImsService();
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        };
243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        t.start();
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private PendingIntent createIncomingCallPendingIntent() {
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Intent intent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
248a89314bcc94c43512299131609feea0c2c8167cfLibin.Tang@motorola.com        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                PendingIntent.FLAG_UPDATE_CURRENT);
251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void getImsService() {
254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("getImsService");
25553dde7e076954c250e55d156cc1df1202c3a8a9eEtan Cohen        mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    createIncomingCallPendingIntent(),
259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mImsConnectionStateListener);
26004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
2619746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak            mImsManager.setImsConfigListener(mImsConfigListener);
2629746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
26304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            // Get the ECBM interface and set IMSPhone's listener object for notifications
26404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            getEcbmInterface().setEcbmStateListener(mPhone.mImsEcbmStateListener);
26504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if (mPhone.isInEcm()) {
26604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // Call exit ECBM which will invoke onECBMExited
26704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.exitEmergencyCallbackMode();
26804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
269b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            int mPreferredTtyMode = Settings.Secure.getInt(
270b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                mPhone.getContext().getContentResolver(),
271b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Settings.Secure.PREFERRED_TTY_MODE,
272b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Phone.TTY_MODE_OFF);
273f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen           mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, mPreferredTtyMode, null);
274b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("getImsService: " + e);
277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //Leave mImsManager as null, then CallStateException will be thrown when dialing
278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mImsManager = null;
279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dispose() {
283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dispose");
284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.dispose();
285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.dispose();
286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.dispose();
287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.dispose();
288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().unregisterReceiver(mReceiver);
291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void finalize() {
295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("ImsPhoneCallTracker finalized");
296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Methods
299a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Public Methods
301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.add(r);
305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallStarted(Handler h) {
309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.remove(h);
310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.add(r);
316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallEnded(Handler h) {
320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.remove(h);
321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
32375ba09a17a669f4906268088a769836aa87d8241fionaxu    public Connection dial(String dialString, int videoState, Bundle intentExtras) throws
32475ba09a17a669f4906268088a769836aa87d8241fionaxu            CallStateException {
325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        int oirMode = sp.getInt(Phone.CLIR_KEY, CommandsInterface.CLIR_DEFAULT);
327df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon        return dial(dialString, oirMode, videoState, intentExtras);
328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * oirMode is one of the CLIR_ constants
332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    synchronized Connection
334df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon    dial(String dialString, int clirMode, int videoState, Bundle intentExtras)
335df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon            throws CallStateException {
336e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        boolean isPhoneInEcmMode = isPhoneInEcbMode();
33704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString);
33804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dial clirMode=" + clirMode);
340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // note that this triggers call state changed notif
342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("service not available");
346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!canDial()) {
349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot dial in current state");
350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
351a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
35204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (isPhoneInEcmMode && isEmergencyNumber) {
35304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER);
35404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
35504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
3568560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        // If the call is to an emergency number and the carrier does not support video emergency
3578560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        // calls, dial as an audio-only call.
358025c01920e4cf357594379ef35fe89c715e3507eEtan Cohen        if (isEmergencyNumber && VideoProfile.isVideo(videoState) &&
3598560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                !mAllowEmergencyVideoCalls) {
3608560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            loge("dial: carrier does not support video emergency calls; downgrade to audio-only");
3618560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            videoState = VideoProfile.STATE_AUDIO_ONLY;
3628560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        }
3638560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn
364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean holdBeforeDial = false;
365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
366a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // The new call must be assigned to the foreground call.
367a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // That call must be idle, so place anything that's
368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // there on hold
369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
370a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we should have failed in !canDial() above before we get here
372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot dial in current state");
373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // foreground call is empty for the newly dialed connection
375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            holdBeforeDial = true;
376288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache the video state for pending MO call.
377288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
378c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            mPendingIntentExtras = intentExtras;
379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
383a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;
384a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
385a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mClirMode = clirMode;
386a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mSyncHold) {
388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (holdBeforeDial) {
389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                fgState = mForegroundCall.getState();
390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                bgState = mBackgroundCall.getState();
391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call failed
393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (fgState == ImsPhoneCall.State.ACTIVE) {
394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("cannot dial in current state");
395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
397a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call succeeded
398a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (bgState == ImsPhoneCall.State.HOLDING) {
399a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    holdBeforeDial = false;
400a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
401a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
402a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4036bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius            mPendingMO = new ImsPhoneConnection(mPhone,
4048bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                    checkForTestEmergencyNumber(dialString), this, mForegroundCall,
4058bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                    isEmergencyNumber);
406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        addConnection(mPendingMO);
408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!holdBeforeDial) {
41004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
411c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                dialInternal(mPendingMO, clirMode, videoState, intentExtras);
41204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            } else {
41304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                try {
41404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    getEcbmInterface().exitEmergencyCallbackMode();
41504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                } catch (ImsException e) {
41604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    e.printStackTrace();
41704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    throw new CallStateException("service not available");
41804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
41904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
42004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallClirMode = clirMode;
421288268d5528e0df03f348e303954813cb188c55bRekha Kumar                mPendingCallVideoState = videoState;
42204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallInEcm = true;
42304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
427a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
428a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mPendingMO;
430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4328560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn    /**
4338560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     * Determines if the carrier associated with the specified SubId supports making video emergency
4348560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     * calls.
4358560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     *
4368560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     * @param subId The sub id.
4378560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     * @return {@code true} if video emergency calls are supported, {@code false} otherwise.
4388560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn     */
4398560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn    private boolean isEmergencyVtCallAllowed(int subId) {
4408560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
4418560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
4428560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        if (carrierConfigManager == null) {
4438560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            loge("isEmergencyVideoCallsSupported: No carrier config service found.");
4448560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            return false;
4458560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        }
4468560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn
447025c01920e4cf357594379ef35fe89c715e3507eEtan Cohen        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
4488560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        if (carrierConfig == null) {
4498560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            loge("isEmergencyVideoCallsSupported: Empty carrier config.");
4508560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn            return false;
4518560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        }
4528560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn
4538560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn        return carrierConfig.getBoolean(CarrierConfigManager.BOOL_ALLOW_EMERGENCY_VIDEO_CALLS);
4548560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn    }
4558560465c584604ff51ceb4492bb7daca023e7d52Tyler Gunn
45604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private void handleEcmTimer(int action) {
45704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        mPhone.handleTimerInEmergencyCallbackMode(action);
45804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        switch (action) {
45904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.CANCEL_ECM_TIMER:
46004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
46104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.RESTART_ECM_TIMER:
46204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
46304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            default:
46404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                log("handleEcmTimer, unsupported action " + action);
46504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
46604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
46704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
468c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn    private void dialInternal(ImsPhoneConnection conn, int clirMode, int videoState,
469c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            Bundle intentExtras) {
470c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn
471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getAddress()== null || conn.getAddress().length() == 0
476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                || conn.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Phone number is invalid
478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.INVALID_NUMBER);
479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Always unmute when initiating a new call
484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setMute(false);
485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceType = PhoneNumberUtils.isEmergencyNumber(conn.getAddress()) ?
4866bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
48764e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
48864e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
48964e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        conn.setVideoState(videoState);
490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { conn.getAddress() };
493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
4946bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                    serviceType, callType);
495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);
496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
497c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            // Translate call subject intent-extra from Telecom-specific extra key to the
498c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            // ImsCallProfile key.
499c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            if (intentExtras != null) {
500c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                if (intentExtras.containsKey(android.telecom.TelecomManager.EXTRA_CALL_SUBJECT)) {
501c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                    intentExtras.putString(ImsCallProfile.EXTRA_DISPLAY_TEXT,
5025c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn                            cleanseInstantLetteringMessage(intentExtras.getString(
503d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn                                    android.telecom.TelecomManager.EXTRA_CALL_SUBJECT))
504d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn                    );
505c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                }
506c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn
507c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // Pack the OEM-specific call extras.
508c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                profile.mCallExtras.putBundle(ImsCallProfile.EXTRA_OEM_EXTRAS, intentExtras);
509c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn
510c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // NOTE: Extras to be sent over the network are packed into the
511c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // intentExtras individually, with uniquely defined keys.
512c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // These key-value pairs are processed by IMS Service before
513c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // being sent to the lower layers/to the network.
514c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            }
515c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn
516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mImsManager.makeCall(mServiceId, profile,
517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsCallListener);
518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setImsCall(imsCall);
519ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
5205054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallStart(imsCall.getSession(), callees[0]);
5215054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak
522288268d5528e0df03f348e303954813cb188c55bRekha Kumar            setVideoCallProvider(conn, imsCall);
523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
524a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("dialInternal : " + e);
525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
527ea8cb63201520592011a92849ad3661d22776c87Andrew Lee        } catch (RemoteException e) {
528a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
529a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5312999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn    /**
5322999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * Accepts a call with the specified video state.  The video state is the video state that the
5332999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * user has agreed upon in the InCall UI.
5342999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     *
5352999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @param videoState The video State
5362999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @throws CallStateException
5372999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     */
53875ba09a17a669f4906268088a769836aa87d8241fionaxu    public void acceptCall (int videoState) throws CallStateException {
539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("acceptCall");
540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState().isAlive()
542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mBackgroundCall.getState().isAlive()) {
543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot accept call");
544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if ((mRingingCall.getState() == ImsPhoneCall.State.WAITING)
547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mForegroundCall.getState().isAlive()) {
548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
549288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache video state for pending MT call.
550288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mRingingCall.getState().isRinging()) {
553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("acceptCall: incoming...");
554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Always unmute when answering a new call
555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) {
5592999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                    imsCall.accept(ImsCallProfile.getCallTypeFromVideoState(videoState));
5605054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallAccept(imsCall.getSession());
561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else {
562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("no valid ims call");
563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot accept call");
566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
57275ba09a17a669f4906268088a769836aa87d8241fionaxu    public void rejectCall () throws CallStateException {
573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("rejectCall");
574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState().isRinging()) {
576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            hangup(mRingingCall);
577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
582007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
583007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam    private void switchAfterConferenceSuccess() {
584007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        if (DBG) log("switchAfterConferenceSuccess fg =" + mForegroundCall.getState() +
585007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                ", bg = " + mBackgroundCall.getState());
586007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
587007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
588007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            log("switchAfterConferenceSuccess");
589007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            mForegroundCall.switchWith(mBackgroundCall);
590007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        }
591007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam    }
592007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
59375ba09a17a669f4906268088a769836aa87d8241fionaxu    public void switchWaitingOrHoldingAndActive() throws CallStateException {
594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("switchWaitingOrHoldingAndActive");
595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState() == ImsPhoneCall.State.INCOMING) {
597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot be in the incoming state");
598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
599a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
600a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mForegroundCall.getImsCall();
602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == null) {
603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("no ims call");
604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
606276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls.
607276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If hold or resume later fails, we will swap them back.
608276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mSwitchingFgAndBgCalls = true;
609276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mCallExpectedToResume = mBackgroundCall.getImsCall();
610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mForegroundCall.switchWith(mBackgroundCall);
611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
612276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Hold the foreground call; once the foreground call is held, the background call will
613276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // be resumed.
614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
615a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                imsCall.hold();
6165054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                mEventLog.writeOnImsCallHold(imsCall.getSession());
617707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
618707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                // If there is no background call to resume, then don't expect there to be a switch.
619707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (mCallExpectedToResume == null) {
620707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    mSwitchingFgAndBgCalls = false;
621707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mForegroundCall.switchWith(mBackgroundCall);
624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException(e.getMessage());
625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            resumeWaitingOrHolding();
628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    conference() {
633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("conference");
634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall fgImsCall = mForegroundCall.getImsCall();
636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (fgImsCall == null) {
637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no foreground ims call");
638a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall bgImsCall = mBackgroundCall.getImsCall();
642a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (bgImsCall == null) {
643a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no background ims call");
644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
647fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // Keep track of the connect time of the earliest call so that it can be set on the
648fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // {@code ImsConference} when it is created.
6497ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long foregroundConnectTime = mForegroundCall.getEarliestConnectTime();
6507ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long backgroundConnectTime = mBackgroundCall.getEarliestConnectTime();
6517ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long conferenceConnectTime;
6527ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        if (foregroundConnectTime > 0 && backgroundConnectTime > 0) {
6537ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = Math.min(mForegroundCall.getEarliestConnectTime(),
6547ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn                    mBackgroundCall.getEarliestConnectTime());
6557ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - using connect time = " + conferenceConnectTime);
6567ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        } else if (foregroundConnectTime > 0) {
6577ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - bg call connect time is 0; using fg = " + foregroundConnectTime);
6587ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = foregroundConnectTime;
6597ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        } else {
6607ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - fg call connect time is 0; using bg = " + backgroundConnectTime);
6617ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = backgroundConnectTime;
6627ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        }
6637ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn
664fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        ImsPhoneConnection foregroundConnection = mForegroundCall.getFirstConnection();
665fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        if (foregroundConnection != null) {
666fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            foregroundConnection.setConferenceConnectTime(conferenceConnectTime);
667fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        }
668fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn
669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            fgImsCall.merge(bgImsCall);
671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference " + e.getMessage());
673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    explicitCallTransfer() {
678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //TODO : implement
679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    clearDisconnected() {
683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("clearDisconnected");
684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        internalClearDisconnected();
686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canConference() {
693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
694a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING
695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mBackgroundCall.isFull()
696a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mForegroundCall.isFull();
697a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
699a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canDial() {
701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean ret;
702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceState = mPhone.getServiceState().getState();
703a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String disableCall = SystemProperties.get(
704a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
705a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
706a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
707a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mPendingMO == null
708a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mRingingCall.isRinging()
709a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !disableCall.equals("true")
710a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && (!mForegroundCall.getState().isAlive()
711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    || !mBackgroundCall.getState().isAlive());
712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ret;
714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
715a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canTransfer() {
718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING;
720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
722a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Private Instance Methods
723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    internalClearDisconnected() {
726a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.clearDisconnected();
727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.clearDisconnected();
728a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.clearDisconnected();
729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.clearDisconnected();
730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    updatePhoneState() {
734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        PhoneConstants.State oldState = mState;
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.isRinging()) {
737a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.RINGING;
738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mPendingMO != null ||
739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
740a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.OFFHOOK;
741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.IDLE;
743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("updatePhoneState oldState=" + oldState + ", newState=" + mState);
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState != oldState) {
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPhoneStateChanged();
7579746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak            mEventLog.writePhoneState(mState);
758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleRadioNotAvailable() {
763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // handlePollCalls will clear out its
764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // call list when it gets the CommandException
765a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // error result from this
766a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pollCallsWhenSafe();
767a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
768a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
769a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
770a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    dumpState() {
771a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        List l;
772a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
773a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Phone State:" + mState);
774a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
775a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Ringing call: " + mRingingCall.toString());
776a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
777a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mRingingCall.getConnections();
778a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
779a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
780a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
781a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
782a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Foreground call: " + mForegroundCall.toString());
783a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
784a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mForegroundCall.getConnections();
785a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
786a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
787a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
788a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
789a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Background call: " + mBackgroundCall.toString());
790a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mBackgroundCall.getConnections();
792a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
795a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
797a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
798a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhone
799a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
800b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    void setUiTTYMode(int uiTtyMode, Message onComplete) {
801b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        try {
802f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen            mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, uiTtyMode, onComplete);
803b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        } catch (ImsException e) {
804b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            loge("setTTYMode : " + e);
805b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            mPhone.sendErrorResponse(onComplete, e);
806b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        }
807b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    }
808b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
809d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ void setMute(boolean mute) {
810a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDesiredMute = mute;
811a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.setMute(mute);
812a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
813a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
814d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ boolean getMute() {
815a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mDesiredMute;
816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
818f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void sendDtmf(char c, Message result) {
819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendDtmf");
820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imscall = mForegroundCall.getImsCall();
822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imscall != null) {
823d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee            imscall.sendDtmf(c, result);
824a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
826a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
827c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
828c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    startDtmf(char c) {
829c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("startDtmf");
830c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
831c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
832c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
833c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.startDtmf(c);
834c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
835c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("startDtmf : no foreground call");
836c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
837c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
838c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
839c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
840c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    stopDtmf() {
841c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("stopDtmf");
842c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
843c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
844c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
845c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.stopDtmf();
846c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
847c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("stopDtmf : no foreground call");
848c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
849c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
850c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneConnection
852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
853f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void hangup (ImsPhoneConnection conn) throws CallStateException {
854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup connection");
855a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
856a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getOwner() != this) {
857a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException ("ImsPhoneConnection " + conn
858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    + "does not belong to ImsPhoneCallTracker " + this);
859a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
860a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
861a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        hangup(conn.getCall());
862a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
863a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneCall
865a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
866f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void hangup (ImsPhoneCall call) throws CallStateException {
867a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup call");
868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call.getConnections().size() == 0) {
870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("no connections");
871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imsCall = call.getImsCall();
874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean rejectCall = false;
875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call == mRingingCall) {
877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming");
878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            rejectCall = true;
879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mForegroundCall) {
880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (call.isDialingOrAlerting()) {
881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
882a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup dialing or alerting...");
883a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
884a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup foreground");
887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //held call will be resumed by onCallTerminated
889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mBackgroundCall) {
891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) {
892a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("(backgnd) hangup waiting or background");
893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
895ac82d4da0473991006a752e2337ccb93e85f0946Etan Cohen            throw new CallStateException ("ImsPhoneCall " + call +
896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    "does not belong to ImsPhoneCallTracker " + this);
897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        call.onHangupLocal();
900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall != null) {
9035054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                if (rejectCall) {
9045054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    imsCall.reject(ImsReasonInfo.CODE_USER_DECLINE);
9055054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallReject(imsCall.getSession());
9065054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                } else {
9075054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
9085054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallTerminate(imsCall.getSession());
9095054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                }
910a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mPendingMO != null && call == mForegroundCall) {
911a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // is holding a foreground call
912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.update(null, ImsPhoneCall.State.DISCONNECTED);
913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.onDisconnect();
914a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeConnection(mPendingMO);
915a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO = null;
916a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
917a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeMessages(EVENT_DIAL_PENDINGMO);
918a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
919a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
921a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
922a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
923a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
92669e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    void callEndCleanupHandOverCallIfAny() {
92769e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        if (mHandoverCall.mConnections.size() > 0) {
92869e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            if (DBG) log("callEndCleanupHandOverCallIfAny, mHandoverCall.mConnections="
92969e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com                    + mHandoverCall.mConnections);
93069e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mHandoverCall.mConnections.clear();
93169e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mState = PhoneConstants.State.IDLE;
93269e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        }
93369e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    }
93469e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com
935a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void resumeWaitingOrHolding() throws CallStateException {
937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("resumeWaitingOrHolding");
938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mForegroundCall.getState().isAlive()) {
941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //resume foreground call after holding background call
942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //they were switched before holding
943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mForegroundCall.getImsCall();
9445054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                if (imsCall != null) {
9455054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    imsCall.resume();
9465054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallResume(imsCall.getSession());
9475054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                }
948a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING) {
949a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //accept waiting call after holding background call
950a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
951288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (imsCall != null) {
952288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    imsCall.accept(
953288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        ImsCallProfile.getCallTypeFromVideoState(mPendingCallVideoState));
9545054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallAccept(imsCall.getSession());
955288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
956a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
957a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //Just resume background call.
958a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //To distinguish resuming call with swapping calls
959a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we do not switch calls.here
960a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //ImsPhoneConnection.update will chnage the parent when completed
961a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mBackgroundCall.getImsCall();
9625054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                if (imsCall != null) {
9635054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    imsCall.resume();
9645054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    mEventLog.writeOnImsCallResume(imsCall.getSession());
9655054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                }
966a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
967a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
968a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
969a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
970a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
971a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
972a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
973a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void sendUSSD (String ussdString, Message response) {
974a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendUSSD");
975a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
977a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mUssdSession != null) {
978a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession.sendUssd(ussdString);
979a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                AsyncResult.forMessage(response, null, null);
980a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                response.sendToTarget();
981a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return;
982a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
984a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { ussdString };
985a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
986a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.SERVICE_TYPE_NORMAL, ImsCallProfile.CALL_TYPE_VOICE);
987a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_DIALSTRING,
988a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.DIALSTRING_USSD);
989a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
990a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession = mImsManager.makeCall(mServiceId, profile,
991a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsUssdListener);
992a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
993a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("sendUSSD : " + e);
994a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.sendErrorResponse(response, e);
995a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
996a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
997a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
998a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
999a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void cancelUSSD() {
1000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mUssdSession == null) return;
1001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
1003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
1004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
1005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1007a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1008a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1009288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private synchronized ImsPhoneConnection findConnection(final ImsCall imsCall) {
1010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (ImsPhoneConnection conn : mConnections) {
1011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getImsCall() == imsCall) {
1012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return conn;
1013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
1016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1017a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1018a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void removeConnection(ImsPhoneConnection conn) {
1019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.remove(conn);
10208bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        // If not emergency call is remaining, notify emergency call registrants
10218bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        if (mIsInEmergencyCall) {
10228bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            boolean isEmergencyCallInList = false;
10238bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            // if no emergency calls pending, set this to false
10248bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            for (ImsPhoneConnection imsPhoneConnection : mConnections) {
10258bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                if (imsPhoneConnection != null && imsPhoneConnection.isEmergency() == true) {
10268bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                    isEmergencyCallInList = true;
10278bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                    break;
10288bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                }
10298bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            }
10308bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan
1031a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan            if (!isEmergencyCallInList) {
1032a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan                mIsInEmergencyCall = false;
1033a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan                mPhone.sendEmergencyCallStateChange(false);
1034a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan            }
10358bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        }
1036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void addConnection(ImsPhoneConnection conn) {
1039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.add(conn);
10408bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        if (conn.isEmergency()) {
10418bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            mIsInEmergencyCall = true;
1042a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan            mPhone.sendEmergencyCallStateChange(true);
10438bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        }
1044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1046a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void processCallStateChange(ImsCall imsCall, ImsPhoneCall.State state, int cause) {
10470db65ec818e58fb5b83a492e082db4536f3b83e0Tyler Gunn        if (DBG) log("processCallStateChange " + imsCall + " state=" + state + " cause=" + cause);
1048d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // This method is called on onCallUpdate() where there is not necessarily a call state
1049d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // change. In these situations, we'll ignore the state related updates and only process
1050d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // the change in media capabilities (as expected).  The default is to not ignore state
1051d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // changes so we do not change existing behavior.
1052d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        processCallStateChange(imsCall, state, cause, false /* do not ignore state update */);
1053d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati    }
1054d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati
1055d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati    private void processCallStateChange(ImsCall imsCall, ImsPhoneCall.State state, int cause,
1056d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati            boolean ignoreState) {
1057d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        if (DBG) {
1058d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati            log("processCallStateChange state=" + state + " cause=" + cause
1059d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati                    + " ignoreState=" + ignoreState);
1060d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        }
1061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imsCall == null) return;
1063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean changed = false;
1065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneConnection conn = findConnection(imsCall);
1066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
1068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // TODO : what should be done?
1069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
1070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1072d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // processCallStateChange is triggered for onCallUpdated as well.
1073d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // onCallUpdated should not modify the state of the call
1074d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // It should modify only other capabilities of call through updateMediaCapabilities
1075d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // State updates will be triggered through individual callbacks
1076d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // i.e. onCallHeld, onCallResume, etc and conn.update will be responsible for the update
1077d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        if (ignoreState) {
107827e0378194d55fdcb23f4a3a85dc620a234b5855Anju Mathapati            conn.updateAddressDisplay(imsCall);
1079d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            conn.updateMediaCapabilities(imsCall);
108021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar            conn.updateExtras(imsCall);
1081d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            return;
1082d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        }
1083d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn
1084d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        changed = conn.update(imsCall, state);
1085d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        if (state == ImsPhoneCall.State.DISCONNECTED) {
1086d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            changed = conn.onDisconnect(cause) || changed;
1087d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            //detach the disconnected connections
1088d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            conn.getCall().detach(conn);
1089d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            removeConnection(conn);
1090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (changed) {
1093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getCall() == mHandoverCall) return;
1094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            updatePhoneState();
1095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPreciseCallStateChanged();
1096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int getDisconnectCauseFromReasonInfo(ImsReasonInfo reasonInfo) {
1100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int cause = DisconnectCause.ERROR_UNSPECIFIED;
1101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //int type = reasonInfo.getReasonType();
1103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int code = reasonInfo.getCode();
1104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (code) {
1105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_ADDRESS:
1106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_REACHABLE:
1107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NUMBER_UNREACHABLE;
1108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BUSY:
1110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.BUSY;
1111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED:
1113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.LOCAL;
1114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
11153b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com            case ImsReasonInfo.CODE_LOCAL_CALL_DECLINE:
11163b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                return DisconnectCause.INCOMING_REJECTED;
11173b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com
1118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE:
1119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NORMAL;
1120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REDIRECTED:
1122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_REQUEST:
1123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_FORBIDDEN:
1124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE:
1125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_USER_REJECTED:
1126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_GLOBAL_ERROR:
1127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_ERROR;
1128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE:
1130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_FOUND:
1131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVER_ERROR:
1132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_UNREACHABLE;
1133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_ROAMING:
1135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_IP_CHANGED:
1136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN:
1137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE:
1138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED:
1139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE:
1140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE:
1141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_CALL_VCC_ON_PROGRESSING:
1142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.OUT_OF_SERVICE;
1143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT:
1145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_1XX_WAITING:
1146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER:
1147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE:
1148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.TIMED_OUT;
1149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_LOW_BATTERY:
1151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_POWER_OFF:
1152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.POWER_OFF;
1153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
115408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            case ImsReasonInfo.CODE_FDN_BLOCKED:
115508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                return DisconnectCause.FDN_BLOCKED;
1156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            default:
1157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return cause;
1160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1163e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati     * @return true if the phone is in Emergency Callback mode, otherwise false
1164e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati     */
1165e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    private boolean isPhoneInEcbMode() {
1166e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        return SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false);
1167e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    }
1168e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati
1169e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    /**
1170e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati     * Before dialing pending MO request, check for the Emergency Callback mode.
1171e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati     * If device is in Emergency callback mode, then exit the mode before dialing pending MO.
1172e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati     */
1173e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    private void dialPendingMO() {
1174e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        boolean isPhoneInEcmMode = isPhoneInEcbMode();
1175e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        boolean isEmergencyNumber = mPendingMO.isEmergency();
1176e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
1177e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati            sendEmptyMessage(EVENT_DIAL_PENDINGMO);
1178e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        } else {
1179e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati            sendEmptyMessage(EVENT_EXIT_ECBM_BEFORE_PENDINGMO);
1180e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati        }
1181e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    }
1182e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati
1183e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati    /**
1184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
1185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsCallListener = new ImsCall.Listener() {
1187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallProgressing(ImsCall imsCall) {
1189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallProgressing");
1190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
1192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ALERTING,
1193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
11945054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallProgressing(imsCall.getCallSession());
1195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
1199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStarted");
1200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
1202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
1203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
12045054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallStarted(imsCall.getCallSession());
1205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1207288268d5528e0df03f348e303954813cb188c55bRekha Kumar        @Override
1208288268d5528e0df03f348e303954813cb188c55bRekha Kumar        public void onCallUpdated(ImsCall imsCall) {
1209288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (DBG) log("onCallUpdated");
1210288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (imsCall == null) {
1211288268d5528e0df03f348e303954813cb188c55bRekha Kumar                return;
1212288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
1213288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsPhoneConnection conn = findConnection(imsCall);
1214288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (conn != null) {
1215288268d5528e0df03f348e303954813cb188c55bRekha Kumar                processCallStateChange(imsCall, conn.getCall().mState,
1216d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati                        DisconnectCause.NOT_DISCONNECTED, true /*ignore state update*/);
12175054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                mEventLog.writeImsCallState(imsCall.getCallSession(), conn.getCall().mState);
1218288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
1219288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
1220288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /**
1222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * onCallStartFailed will be invoked when:
1223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 1) Dialing fails
1224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 2) Ringing call is disconnected by local or remote user
1225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
1226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStartFailed reasonCode=" + reasonInfo.getCode());
1229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mPendingMO != null) {
1231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // To initiate dialing circuit-switched call
1232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
1233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE
1234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mRingingCall.getState() == ImsPhoneCall.State.IDLE) {
1235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.detach(mPendingMO);
1236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.finalize();
1238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.initiateSilentRedial();
1240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return;
1241990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                } else {
12422770b0f5449670eadab1d68ea8d5fa4788f4704aSantos Cordon                    mPendingMO = null;
1243990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1244990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
1245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
12465054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                mEventLog.writeOnImsCallStartFailed(imsCall.getCallSession(), reasonInfo);
1247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallTerminated reasonCode=" + reasonInfo.getCode());
1253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneCall.State oldState = mForegroundCall.getState();
1255bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1256bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            ImsPhoneConnection conn = findConnection(imsCall);
1257bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            if (DBG) log("cause = " + cause + " conn = " + conn);
1258bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com
1259ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn            if (mOnHoldToneId == System.identityHashCode(conn)) {
1260ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                if (conn != null && mOnHoldToneStarted) {
1261ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                    mPhone.stopOnHoldTone(conn);
1262ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                }
1263ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                mOnHoldToneStarted = false;
1264ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                mOnHoldToneId = -1;
1265ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn            }
126617e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam            if (conn != null && conn.isIncoming() && conn.getConnectTime() == 0) {
12673b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                // Missed
12683b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                if (cause == DisconnectCause.NORMAL) {
1269bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com                    cause = DisconnectCause.INCOMING_MISSED;
127008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                } else {
127108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    cause = DisconnectCause.INCOMING_REJECTED;
127217e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam                }
12735fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                if (DBG) log("Incoming connection of 0 connect time detected - translated cause = "
12745fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                        + cause);
1275f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com
1276bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            }
1277f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
1278f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            if (cause == DisconnectCause.NORMAL && conn != null && conn.getImsCall().isMerged()) {
1279f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                // Call was terminated while it is merged instead of a remote disconnect.
1280f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                cause = DisconnectCause.IMS_MERGED_SUCCESSFULLY;
1281f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            }
1282f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
12839746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak            mEventLog.writeOnImsCallTerminated(imsCall.getCallSession(), reasonInfo);
12849746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
1285bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
128608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            if (mForegroundCall.getState() != ImsPhoneCall.State.ACTIVE) {
128708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                if (mRingingCall.getState().isRinging()) {
128808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    // Drop pending MO. We should address incoming call first
128908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    mPendingMO = null;
129008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                } else if (mPendingMO != null) {
129108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    sendEmptyMessage(EVENT_DIAL_PENDINGMO);
129208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                }
129308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            }
12941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
12951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (mSwitchingFgAndBgCalls) {
12961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (DBG) {
12971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("onCallTerminated: Call terminated in the midst of Switching " +
12981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "Fg and Bg calls.");
12991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If we are the in midst of swapping FG and BG calls and the call that was
13011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // terminated was the one that we expected to resume, we need to swap the FG and
13021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // BG calls back.
13031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (imsCall == mCallExpectedToResume) {
13041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG) {
13051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        log("onCallTerminated: switching " + mForegroundCall + " with "
13061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                + mBackgroundCall);
13071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
13081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mForegroundCall.switchWith(mBackgroundCall);
13091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // This call terminated in the midst of a switch after the other call was held, so
13111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // resume it back to ACTIVE state since the switch failed.
13121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mForegroundCall.getState() == ImsPhoneCall.State.HOLDING) {
13131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    sendEmptyMessage(EVENT_RESUME_BACKGROUND);
13141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mSwitchingFgAndBgCalls = false;
13151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mCallExpectedToResume = null;
13161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
1318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHeld(ImsCall imsCall) {
1322707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            if (DBG) {
1323707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (mForegroundCall.getImsCall() == imsCall) {
1324707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallHeld (fg) " + imsCall);
1325707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                } else if (mBackgroundCall.getImsCall() == imsCall) {
1326707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallHeld (bg) " + imsCall);
1327707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1328707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            }
1329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State oldState = mBackgroundCall.getState();
1332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                processCallStateChange(imsCall, ImsPhoneCall.State.HOLDING,
1333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        DisconnectCause.NOT_DISCONNECTED);
1334c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1335c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // Note: If we're performing a switchWaitingOrHoldingAndActive, the call to
1336c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // processCallStateChange above may have caused the mBackgroundCall and
1337c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // mForegroundCall references below to change meaning.  Watch out for this if you
1338c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // are reading through this code.
1339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (oldState == ImsPhoneCall.State.ACTIVE) {
1340276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // Note: This case comes up when we have just held a call in response to a
1341276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // switchWaitingOrHoldingAndActive.  We now need to resume the background call.
1342276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // The EVENT_RESUME_BACKGROUND causes resumeWaitingOrHolding to be called.
1343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if ((mForegroundCall.getState() == ImsPhoneCall.State.HOLDING)
1344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            || (mRingingCall.getState() == ImsPhoneCall.State.WAITING)) {
1345f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com                            sendEmptyMessage(EVENT_RESUME_BACKGROUND);
1346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    } else {
1347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //when multiple connections belong to background call,
1348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //only the first callback reaches here
1349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //otherwise the oldState is already HOLDING
1350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mPendingMO != null) {
1351e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                            dialPendingMO();
1352a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
1353c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1354c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // In this case there will be no call resumed, so we can assume that we
1355c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // are done switching fg and bg calls now.
1356c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // This may happen if there is no BG call and we are holding a call so that
1357c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // we can dial another one.
1358c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        mSwitchingFgAndBgCalls = false;
1359a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
13601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else if (oldState == ImsPhoneCall.State.IDLE && mSwitchingFgAndBgCalls) {
13611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The other call terminated in the midst of a switch before this call was held,
13621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // so resume the foreground call back to ACTIVE state since the switch failed.
13631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mForegroundCall.getState() == ImsPhoneCall.State.HOLDING) {
13641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        sendEmptyMessage(EVENT_RESUME_BACKGROUND);
13651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mSwitchingFgAndBgCalls = false;
13661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mCallExpectedToResume = null;
13671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
1368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
13705054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallHeld(imsCall.getCallSession());
1371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldFailed reasonCode=" + reasonInfo.getCode());
1376a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1377a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1378a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State bgState = mBackgroundCall.getState();
1379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) {
1380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // disconnected while processing hold
1381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1382e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        dialPendingMO();
1383a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1384a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else if (bgState == ImsPhoneCall.State.ACTIVE) {
1385a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.switchWith(mBackgroundCall);
1386a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
1389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
1390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
13925326ba5f8e9488416fd7160680dc6b6319c6b00eAnju Mathapati                mPhone.notifySuppServiceFailed(Phone.SuppService.HOLD);
1393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
13945054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallHoldFailed(imsCall.getCallSession(), reasonInfo);
1395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1397a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1398a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumed(ImsCall imsCall) {
1399a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumed");
1400a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1401276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are the in midst of swapping FG and BG calls and the call we end up resuming
1402276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // is not the one we expected, we likely had a resume failure and we need to swap the
1403276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // FG and BG calls back.
14040ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn            if (mSwitchingFgAndBgCalls) {
14050ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                if (imsCall != mCallExpectedToResume) {
14060ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    // If the call which resumed isn't as expected, we need to swap back to the
14070ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    // previous configuration; the swap has failed.
14080ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    if (DBG) {
14090ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                        log("onCallResumed : switching " + mForegroundCall + " with "
14100ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                                + mBackgroundCall);
14110ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    }
14120ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    mForegroundCall.switchWith(mBackgroundCall);
14130ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                } else {
14140ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    // The call which resumed is the one we expected to resume, so we can clear out
14150ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    // the mSwitchingFgAndBgCalls flag.
14160ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    if (DBG) {
14170ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                        log("onCallResumed : expected call resumed.");
14180ae749285976deff6f73db0d414f36548c5682b3Tyler Gunn                    }
1419707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1420276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1421276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1422276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1423a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
1424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
14255054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallResumed(imsCall.getCallSession());
1426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1427a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1428a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1430276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are in the midst of swapping the FG and BG calls and we got a resume fail, we
1431276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // need to swap back the FG and BG calls.
1432276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            if (mSwitchingFgAndBgCalls && imsCall == mCallExpectedToResume) {
1433707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (DBG) {
1434707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallResumeFailed : switching " + mForegroundCall + " with "
1435707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                            + mBackgroundCall);
1436707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1437276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mForegroundCall.switchWith(mBackgroundCall);
1438276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1439276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1440276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1441276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mPhone.notifySuppServiceFailed(Phone.SuppService.RESUME);
14425054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallResumeFailed(imsCall.getCallSession(), reasonInfo);
1443a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1444a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1445a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1446a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeReceived(ImsCall imsCall) {
1447a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumeReceived");
1448ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn            ImsPhoneConnection conn = findConnection(imsCall);
1449ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn            if (conn != null && mOnHoldToneStarted) {
1450ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                mPhone.stopOnHoldTone(conn);
1451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOnHoldToneStarted = false;
1452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
145308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
145408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
145508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Type of notification: 0 = MO; 1 = MT
145608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Refer SuppServiceNotification class documentation.
145708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.notificationType = 1;
145808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = SuppServiceNotification.MT_CODE_CALL_RETRIEVED;
145908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
14605054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallResumeReceived(imsCall.getCallSession());
1461a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldReceived(ImsCall imsCall) {
1465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldReceived");
1466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneConnection conn = findConnection(imsCall);
1468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn != null && conn.getState() == ImsPhoneCall.State.ACTIVE) {
1469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!mOnHoldToneStarted && ImsPhoneCall.isLocalTone(imsCall)) {
1470ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                    mPhone.startOnHoldTone(conn);
1471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mOnHoldToneStarted = true;
1472ad03bd3454a9dd0e8edb61b8794f07d8a26f8187Tyler Gunn                    mOnHoldToneId = System.identityHashCode(conn);
1473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
147508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
147608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
147708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Type of notification: 0 = MO; 1 = MT
147808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Refer SuppServiceNotification class documentation.
147908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.notificationType = 1;
148008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD;
148108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
14825054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallHoldReceived(imsCall.getCallSession());
148308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        }
148408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
148508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        @Override
148608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        public void onCallSuppServiceReceived(ImsCall call,
148708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                ImsSuppServiceNotification suppServiceInfo) {
148808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            if (DBG) log("onCallSuppServiceReceived: suppServiceInfo=" + suppServiceInfo);
148908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
149008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
14918762e33ba987774e43aa9f4e216ebdb084d3a03eTyler Gunn            supp.notificationType = suppServiceInfo.notificationType;
149208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = suppServiceInfo.code;
149308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.index = suppServiceInfo.index;
149408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.number = suppServiceInfo.number;
149508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.history = suppServiceInfo.history;
149608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
149708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
1498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1501007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        public void onCallMerged(final ImsCall call, final ImsCall peerCall, boolean swapCalls) {
1502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallMerged");
1503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1504707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            ImsPhoneCall foregroundImsPhoneCall = findConnection(call).getCall();
1505007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            ImsPhoneConnection peerConnection = findConnection(peerCall);
1506707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            ImsPhoneCall peerImsPhoneCall = peerConnection == null ? null
1507707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    : peerConnection.getCall();
1508007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
1509fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            if (swapCalls) {
1510007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                switchAfterConferenceSuccess();
1511fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            }
1512707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            foregroundImsPhoneCall.merge(peerImsPhoneCall, ImsPhoneCall.State.ACTIVE);
1513007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
1514ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade            try {
1515ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                final ImsPhoneConnection conn = findConnection(call);
1516ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                log("onCallMerged: ImsPhoneConnection=" + conn);
1517ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1518ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                setVideoCallProvider(conn, call);
1519ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1520ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade            } catch (Exception e) {
1521ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade                loge("onCallMerged: exception " + e);
1522ee275ae7d45847e3eb84ce7725df3717d3addee3Omkar Kolangade            }
1523288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1524007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // After merge complete, update foreground as Active
1525007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // and background call as Held, if background call exists
1526007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            processCallStateChange(mForegroundCall.getImsCall(), ImsPhoneCall.State.ACTIVE,
1527007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                    DisconnectCause.NOT_DISCONNECTED);
1528007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            if (peerConnection != null) {
1529007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                processCallStateChange(mBackgroundCall.getImsCall(), ImsPhoneCall.State.HOLDING,
1530007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                    DisconnectCause.NOT_DISCONNECTED);
1531007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            }
1532df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon
1533007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // Check if the merge was requested by an existing conference call. In that
1534007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // case, no further action is required.
1535007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            if (!call.isMergeRequestedByConf()) {
1536007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                log("onCallMerged :: calling onMultipartyStateChanged()");
1537007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                onMultipartyStateChanged(call, true);
1538007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            } else {
1539007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                log("onCallMerged :: Merge requested by existing conference.");
1540007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                // Reset the flag.
1541007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                call.resetIsMergeRequestedByConf(false);
1542007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            }
1543707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            logState();
1544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallMergeFailed(ImsCall call, ImsReasonInfo reasonInfo) {
15484e47e27d1d2cbd8e533cdd2081c5bc8e51b79ad9Anthony Lee            if (DBG) log("onCallMergeFailed reasonInfo=" + reasonInfo);
154952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
155052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // TODO: the call to notifySuppServiceFailed throws up the "merge failed" dialog
155152c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // We should move this into the InCallService so that it is handled appropriately
155252c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // based on the user facing UI.
1553bd4d6093314c0d2afc4b4f69f352957d01d9bc58Uma Maheswari Ramalingam            mPhone.notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
155452c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
155552c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // Start plumbing this even through Telecom so other components can take
155652c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // appropriate action.
155752c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            ImsPhoneConnection conn = findConnection(call);
155852c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            if (conn != null) {
155952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee                conn.onConferenceMergeFailed();
156052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            }
1561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1562fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1563fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        /**
1564f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * Called when the state of IMS conference participant(s) has changed.
1565fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         *
1566fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         * @param call the call object that carries out the IMS call.
1567f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * @param participants the participant(s) and their new state information.
1568fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         */
1569fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        @Override
1570f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn        public void onConferenceParticipantsStateChanged(ImsCall call,
1571f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                List<ConferenceParticipant> participants) {
1572f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn            if (DBG) log("onConferenceParticipantsStateChanged");
1573fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1574fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            ImsPhoneConnection conn = findConnection(call);
1575fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            if (conn != null) {
1576f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                conn.updateConferenceParticipants(participants);
1577fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            }
1578fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        }
15796d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak
15806d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        @Override
15816d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        public void onCallSessionTtyModeReceived(ImsCall call, int mode) {
15826d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak            mPhone.onTtyModeReceived(mode);
15836d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        }
15840ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
15850ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
15860ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
15870ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
15880ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
15890ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandover ::  srcAccessTech=" + srcAccessTech + ", targetAccessTech=" +
15900ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    targetAccessTech + ", reasonInfo=" + reasonInfo);
15910ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
15925054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallHandover(imsCall.getCallSession(),
15935054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    srcAccessTech, targetAccessTech, reasonInfo);
15940ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
15950ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
15960ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
15970ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandoverFailed(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
15980ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
15990ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
16000ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandoverFailed :: srcAccessTech=" + srcAccessTech +
16010ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    ", targetAccessTech=" + targetAccessTech + ", reasonInfo=" + reasonInfo);
16020ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
16035054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsCallHandoverFailed(imsCall.getCallSession(),
16045054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    srcAccessTech, targetAccessTech, reasonInfo);
16050ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
1606ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1607ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        /**
1608ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * Handles a change to the multiparty state for an {@code ImsCall}.  Notifies the associated
1609ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * {@link ImsPhoneConnection} of the change.
1610ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *
1611ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param imsCall The IMS call.
1612ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param isMultiParty {@code true} if the call became multiparty, {@code false}
1613ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *      otherwise.
1614ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         */
1615ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        @Override
1616ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        public void onMultipartyStateChanged(ImsCall imsCall, boolean isMultiParty) {
1617ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (DBG) log("onMultipartyStateChanged to " + (isMultiParty ? "Y" : "N"));
1618ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1619ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            ImsPhoneConnection conn = findConnection(imsCall);
1620ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (conn != null) {
1621ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn                conn.updateMultipartyState(isMultiParty);
1622ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            }
1623ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        }
1624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
1628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsUssdListener = new ImsCall.Listener() {
1630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
1632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStarted");
1633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd);
1637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1638a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1642a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1643a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStartFailed reasonCode=" + reasonInfo.getCode());
1646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onCallTerminated(imsCall, reasonInfo);
1648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallTerminated reasonCode=" + reasonInfo.getCode());
1653a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession = null;
1656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    CommandException ex =
1658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            new CommandException(CommandException.Error.GENERIC_FAILURE);
1659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd, null, ex);
1660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            imsCall.close();
1665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1667a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallUssdMessageReceived(ImsCall call,
1669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                int mode, String ussdMessage) {
1670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallUssdMessageReceived mode=" + mode);
1671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            int ussdMode = -1;
1673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switch(mode) {
1675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_REQUEST:
1676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_REQUEST;
1677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_NOTIFY:
1680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_NOTIFY;
1681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.onIncomingUSSD(ussdMode, ussdMessage);
1685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS service state change
1690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *
1691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsConnectionStateListener mImsConnectionStateListener =
1693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        new ImsConnectionStateListener() {
1694a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsConnected() {
1696a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsConnected");
1697a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
1698bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(true);
16995054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsConnectionState(
17005054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    TelephonyEventLog.IMS_CONNECTION_STATE_CONNECTED, null);
1701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1703a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
17040ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
17050ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
1706a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
1707bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(false);
170853f2bb9ba3118ff4c22e20ab3ad46ec97a72ac24Pavel Zhamaitsiak            mPhone.processDisconnectReason(imsReasonInfo);
17095054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsConnectionState(
17105054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    TelephonyEventLog.IMS_CONNECTION_STATE_DISCONNECTED, imsReasonInfo);
1711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
17140ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsProgressing() {
17150ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsProgressing");
171608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
171708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.setImsRegistered(false);
17185054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsConnectionState(
17195054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    TelephonyEventLog.IMS_CONNECTION_STATE_PROGRESSING, null);
17200ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
17210ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
17220ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
1723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsResumed() {
1724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsResumed");
1725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
17265054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsConnectionState(
17275054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    TelephonyEventLog.IMS_CONNECTION_STATE_RESUMED, null);
1728a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsSuspended() {
1732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsSuspended");
1733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
17345054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak            mEventLog.writeOnImsConnectionState(
17355054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                    TelephonyEventLog.IMS_CONNECTION_STATE_SUSPENDED, null);
1736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1737cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1738cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        @Override
1739cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        public void onFeatureCapabilityChanged(int serviceClass,
1740cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                int[] enabledFeatures, int[] disabledFeatures) {
1741cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            if (serviceClass == ImsServiceClass.MMTEL) {
1742288268d5528e0df03f348e303954813cb188c55bRekha Kumar                boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
174304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // Check enabledFeatures to determine capabilities. We ignore disabledFeatures.
1744c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                StringBuilder sb;
1745c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) {
1746c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                    sb = new StringBuilder(120);
1747c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                    sb.append("onFeatureCapabilityChanged: ");
1748c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                }
174962a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                for (int  i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
175008111609eb4e838de7bff4960bbbd7f9c54a060ePavel Zhamaitsiak                        i <= ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI &&
175108111609eb4e838de7bff4960bbbd7f9c54a060ePavel Zhamaitsiak                        i < enabledFeatures.length; i++) {
175262a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    if (enabledFeatures[i] == i) {
175304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // If the feature is set to its own integer value it is enabled.
1754c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                        if (DBG) {
1755c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                            sb.append(mImsFeatureStrings[i]);
1756c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                            sb.append(":true ");
1757c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                        }
1758c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
175962a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = true;
176004b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else if (enabledFeatures[i]
176104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                            == ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
176204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // FEATURE_TYPE_UNKNOWN indicates that a feature is disabled.
1763c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                        if (DBG) {
1764c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                            sb.append(mImsFeatureStrings[i]);
1765c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                            sb.append(":false ");
1766c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                        }
1767c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu
176862a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = false;
176904b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else {
177004b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // Feature has unknown state; it is not its own value or -1.
177104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        if (DBG) {
1772c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                            loge("onFeatureCapabilityChanged(" + i + ", " + mImsFeatureStrings[i]
1773c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                                    + "): unexpectedValue=" + enabledFeatures[i]);
177404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        }
177562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    }
1776cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                }
1777c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                if (DBG) {
1778c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                    log(sb.toString());
1779c1b229b7389e4cd682452c8d662afa1b3af14345Jack Yu                }
1780288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (tmpIsVideoCallEnabled != isVideoCallEnabled()) {
1781288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled());
1782288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
178304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee
178404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // TODO: Use the ImsCallSession or ImsCallProfile to tell the initial Wifi state and
178504b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // {@link ImsCallSession.Listener#callSessionHandover} to listen for changes to
178604b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // wifi capability caused by a handover.
1787164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                if (DBG) log("onFeatureCapabilityChanged: isVolteEnabled=" + isVolteEnabled()
1788164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isVideoCallEnabled=" + isVideoCallEnabled()
1789164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isVowifiEnabled=" + isVowifiEnabled()
1790164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isUtEnabled=" + isUtEnabled());
179104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                for (ImsPhoneConnection connection : mConnections) {
179204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    connection.updateWifiState();
179304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                }
1794e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak
1795e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak                mPhone.onFeatureCapabilityChanged();
17965054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak
17975054dfa7fd9b0520d30a102ed5a2107af11590c8Pavel Zhamaitsiak                mEventLog.writeOnImsCapabilities(mImsFeatureEnabled);
1798cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            }
1799cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        }
180003545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade
180103545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        @Override
180203545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        public void onVoiceMessageCountChanged(int count) {
180303545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade            if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
180403545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade            mPhone.mDefaultPhone.setVoiceMessageCount(count);
180503545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        }
1806a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
18089746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak    private ImsConfigListener.Stub mImsConfigListener = new ImsConfigListener.Stub() {
18099746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        @Override
18109746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        public void onGetFeatureResponse(int feature, int network, int value, int status) {}
18119746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
18129746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        @Override
18139746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        public void onSetFeatureResponse(int feature, int network, int value, int status) {
18149746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak            mEventLog.writeImsSetFeatureValue(feature, network, value, status);
18159746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        }
18169746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
18179746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        @Override
18189746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        public void onGetVideoQuality(int status, int quality) {}
18199746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
18209746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        @Override
18219746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak        public void onSetVideoQuality(int status) {}
18229746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
18239746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak    };
18249746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
1825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1826a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsUtInterface getUtInterface() throws ImsException {
1827a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
1828a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
1829a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1830a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsUtInterface ut = mImsManager.getSupplementaryServiceConfiguration(mServiceId);
1832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ut;
1833a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1834a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
18354be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    private void transferHandoverConnections(ImsPhoneCall call) {
18364be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.mConnections != null) {
18374be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : call.mConnections) {
18384be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                c.mPreHandoverState = call.mState;
18394be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                log ("Connection state before handover is " + c.getStateBeforeHandover());
18404be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
18414be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
18424be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections == null ) {
18434be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections = call.mConnections;
18444be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        } else { // Multi-call SRVCC
18454be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections.addAll(call.mConnections);
18464be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
18474be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections != null) {
18484be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            if (call.getImsCall() != null) {
18494be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                call.getImsCall().close();
18504be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
18514be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : mHandoverCall.mConnections) {
18524be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                ((ImsPhoneConnection)c).changeParent(mHandoverCall);
185352c193f0c615a9153a702ea2597217202613e413Libin.Tang@motorola.com                ((ImsPhoneConnection)c).releaseWakeLock();
18544be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
18554be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
18564be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.getState().isAlive()) {
18574be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            log ("Call is alive and state is " + call.mState);
18584be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mState = call.mState;
18594be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
18604be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mConnections.clear();
18614be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mState = ImsPhoneCall.State.IDLE;
18624be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    }
18634be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam
1864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1865a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void notifySrvccState(Call.SrvccState state) {
1866a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("notifySrvccState state=" + state);
1867a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mSrvccState = state;
1869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mSrvccState == Call.SrvccState.COMPLETED) {
18714be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mForegroundCall);
18724be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mBackgroundCall);
18734be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mRingingCall);
1874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //****** Overridden from Handler
1878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void
1881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleMessage (Message msg) {
1882a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        AsyncResult ar;
1883a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("handleMessage what=" + msg.what);
1884a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (msg.what) {
1886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_HANGUP_PENDINGMO:
1887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingMO != null) {
1888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.onDisconnect();
1889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1892c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                mPendingIntentExtras = null;
1893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
1894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPhone.notifyPreciseCallStateChanged();
1895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_RESUME_BACKGROUND:
1897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
1898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    resumeWaitingOrHolding();
1899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (CallStateException e) {
1900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (Phone.DEBUG_PHONE) {
1901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        loge("handleMessage EVENT_RESUME_BACKGROUND exception=" + e);
1902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_DIAL_PENDINGMO:
1906c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                dialInternal(mPendingMO, mClirMode, mPendingCallVideoState, mPendingIntentExtras);
1907c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                mPendingIntentExtras = null;
1908a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
190904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
1910e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati            case EVENT_EXIT_ECBM_BEFORE_PENDINGMO:
1911e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                if (mPendingMO != null) {
1912e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                    //Send ECBM exit request
1913e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                    try {
1914e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        getEcbmInterface().exitEmergencyCallbackMode();
1915e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
1916e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        pendingCallClirMode = mClirMode;
1917e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        pendingCallInEcm = true;
1918e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                    } catch (ImsException e) {
1919e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        e.printStackTrace();
1920e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
1921e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                        sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
1922e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                    }
1923e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                }
1924e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati                break;
1925e5c2995cec720cb3f0ba6609378574683770108dAnju Mathapati
192604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case EVENT_EXIT_ECM_RESPONSE_CDMA:
192704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // no matter the result, we still do the same here
192804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                if (pendingCallInEcm) {
1929288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    dialInternal(mPendingMO, pendingCallClirMode,
1930c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                            mPendingCallVideoState, mPendingIntentExtras);
1931c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                    mPendingIntentExtras = null;
193204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    pendingCallInEcm = false;
193304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
193404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.unsetOnEcbModeExitResponse(this);
193504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
1936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void log(String msg) {
1941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1944a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void loge(String msg) {
1945a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1946a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1947a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1948707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    /**
1949707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     * Logs the current state of the ImsPhoneCallTracker.  Useful for debugging issues with
1950707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     * call tracking.
1951707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     */
1952707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    /* package */
1953707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    void logState() {
1954707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (!VERBOSE_STATE_LOGGING) {
1955707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            return;
1956707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
1957707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
1958707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        StringBuilder sb = new StringBuilder();
1959707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("Current IMS PhoneCall State:\n");
1960707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Foreground: ");
1961707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mForegroundCall);
1962707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1963707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Background: ");
1964707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mBackgroundCall);
1965707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1966707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Ringing: ");
1967707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mRingingCall);
1968707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1969707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Handover: ");
1970707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mHandoverCall);
1971707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1972707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        Rlog.v(LOG_TAG, sb.toString());
1973707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    }
1974707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
1975a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1977a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println("ImsPhoneCallTracker extends:");
1978a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        super.dump(fd, pw, args);
1979a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
1980a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
1981a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mRingingCall=" + mRingingCall);
1982a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
1983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
1984a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mHandoverCall=" + mHandoverCall);
1985a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPendingMO=" + mPendingMO);
1986a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //pw.println(" mHangupPendingMO=" + mHangupPendingMO);
1987a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPhone=" + mPhone);
1988a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
1989a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mState=" + mState);
1990dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        for (int i = 0; i < mImsFeatureEnabled.length; i++) {
1991dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            pw.println(" " + mImsFeatureStrings[i] + ": "
1992dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu                    + ((mImsFeatureEnabled[i]) ? "enabled" : "disabled"));
1993dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        }
1994dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        pw.flush();
1995dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        pw.println("++++++++++++++++++++++++++++++++");
1996dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu
1997dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        try {
1998dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            if (mImsManager != null) {
1999dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu                mImsManager.dump(fd, pw, args);
2000dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            }
2001dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        } catch (Exception e) {
2002dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            e.printStackTrace();
2003dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        }
2004dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu
2005dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        if (mConnections != null && mConnections.size() > 0) {
2006dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            pw.println("mConnections:");
2007dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            for (int i = 0; i < mConnections.size(); i++) {
2008dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu                pw.println("  [" + i + "]: " + mConnections.get(i));
2009dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu            }
2010dc3b93d59312b84dcfa776f7691f6a87462b45a2Jack Yu        }
2011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
2012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
2014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void handlePollCalls(AsyncResult ar) {
2015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
201604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
201704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    /* package */
201804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    ImsEcbm getEcbmInterface() throws ImsException {
201904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (mImsManager == null) {
202004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
202104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
202204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
202304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        ImsEcbm ecbm = mImsManager.getEcbmInterface(mServiceId);
202404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return ecbm;
202504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
202604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
202704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    public boolean isInEmergencyCall() {
202804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return mIsInEmergencyCall;
202904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
2030cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
2031cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    public boolean isVolteEnabled() {
203262a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE];
203362a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    }
203462a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com
203562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    public boolean isVowifiEnabled() {
203662a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI];
2037cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
2038cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
2039288268d5528e0df03f348e303954813cb188c55bRekha Kumar    public boolean isVideoCallEnabled() {
204062a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE]
204162a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI]);
2042cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
2043288268d5528e0df03f348e303954813cb188c55bRekha Kumar
2044b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
2045b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
2046b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
2047b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
2048288268d5528e0df03f348e303954813cb188c55bRekha Kumar
2049288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private void setVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall)
2050288268d5528e0df03f348e303954813cb188c55bRekha Kumar            throws RemoteException {
2051288268d5528e0df03f348e303954813cb188c55bRekha Kumar        IImsVideoCallProvider imsVideoCallProvider =
2052288268d5528e0df03f348e303954813cb188c55bRekha Kumar                imsCall.getCallSession().getVideoCallProvider();
2053288268d5528e0df03f348e303954813cb188c55bRekha Kumar        if (imsVideoCallProvider != null) {
2054288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsVideoCallProviderWrapper imsVideoCallProviderWrapper =
2055288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    new ImsVideoCallProviderWrapper(imsVideoCallProvider);
2056288268d5528e0df03f348e303954813cb188c55bRekha Kumar            conn.setVideoProvider(imsVideoCallProviderWrapper);
2057288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
2058288268d5528e0df03f348e303954813cb188c55bRekha Kumar    }
2059164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati
2060164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    public boolean isUtEnabled() {
2061164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati        return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_LTE]
2062164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati            || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI]);
2063164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    }
2064d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn
2065d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn    /**
2066d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     * Given a call subject, removes any characters considered by the current carrier to be
20675c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * invalid, as well as escaping (using \) any characters which the carrier requires to be
20685c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * escaped.
2069d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     *
2070d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     * @param callSubject The call subject.
20715c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * @return The call subject with invalid characters removed and escaping applied as required.
2072d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     */
20735c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn    private String cleanseInstantLetteringMessage(String callSubject) {
20744677e1d9088a0cc787112b5daa0b70896021920eTyler Gunn        if (TextUtils.isEmpty(callSubject)) {
20754677e1d9088a0cc787112b5daa0b70896021920eTyler Gunn            return callSubject;
20764677e1d9088a0cc787112b5daa0b70896021920eTyler Gunn        }
20774677e1d9088a0cc787112b5daa0b70896021920eTyler Gunn
20785c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        // Get the carrier config for the current sub.
20795c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        CarrierConfigManager configMgr = (CarrierConfigManager)
20805c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
20815c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        // Bail if we can't find the carrier config service.
20825c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        if (configMgr == null) {
2083d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn            return callSubject;
2084d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn        }
2085d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn
20865c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        PersistableBundle carrierConfig = configMgr.getConfigForSubId(mPhone.getSubId());
20875c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        // Bail if no carrier config found.
20885c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        if (carrierConfig == null) {
20895c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            return callSubject;
20905c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        }
20915c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn
20925c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        // Try to replace invalid characters
20935c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        String invalidCharacters = carrierConfig.getString(
20945c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn                CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING);
20955c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        if (!TextUtils.isEmpty(invalidCharacters)) {
20965c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            callSubject = callSubject.replaceAll(invalidCharacters, "");
20975c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        }
20985c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn
20995c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        // Try to escape characters which need to be escaped.
21005c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        String escapedCharacters = carrierConfig.getString(
21015c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn                CarrierConfigManager.KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING);
21025c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        if (!TextUtils.isEmpty(escapedCharacters)) {
21035c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            callSubject = escapeChars(escapedCharacters, callSubject);
21045c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        }
21055c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        return callSubject;
2106d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn    }
2107d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn
2108d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn    /**
21095c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * Given a source string, return a string where a set of characters are escaped using the
21105c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * backslash character.
2111d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     *
21125c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * @param toEscape The characters to escape with a backslash.
21135c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * @param source The source string.
21145c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn     * @return The source string with characters escaped.
2115d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn     */
21165c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn    private String escapeChars(String toEscape, String source) {
21175c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        StringBuilder escaped = new StringBuilder();
21185c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        for (char c : source.toCharArray()) {
21195c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            if (toEscape.contains(Character.toString(c))) {
21205c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn                escaped.append("\\");
21215c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            }
21225c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn            escaped.append(c);
2123d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn        }
21245c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn
21255c0859c8c66d65f066fedf300ff75eee42114657Tyler Gunn        return escaped.toString();
2126d6345bfe54d2fa3e1e8d6997cef73105be07f660Tyler Gunn    }
2127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}
2128